12 #include "clang/ASTMatchers/ASTMatchFinder.h" 13 #include "clang/Frontend/ASTUnit.h" 14 #include "clang/Frontend/TextDiagnostic.h" 15 #include "llvm/Support/raw_ostream.h" 25 bool InvalidQuery::run(llvm::raw_ostream &OS,
QuerySession &QS)
const {
30 bool NoOpQuery::run(llvm::raw_ostream &OS,
QuerySession &QS)
const {
34 bool HelpQuery::run(llvm::raw_ostream &OS,
QuerySession &QS)
const {
35 OS <<
"Available commands:\n\n" 36 " match MATCHER, m MATCHER " 37 "Match the loaded ASTs against the given matcher.\n" 38 " let NAME MATCHER, l NAME MATCHER " 39 "Give a matcher expression a name, to be used later\n" 41 "as part of other expressions.\n" 42 " set bind-root (true|false) " 43 "Set whether to bind the root matcher to \"root\".\n" 44 " set output (diag|print|dump) " 45 "Set whether to print bindings as diagnostics,\n" 47 "AST pretty prints or AST dumps.\n" 49 "Terminates the query session.\n\n";
53 bool QuitQuery::run(llvm::raw_ostream &OS,
QuerySession &QS)
const {
60 struct CollectBoundNodes : MatchFinder::MatchCallback {
62 CollectBoundNodes(std::vector<BoundNodes> &Bindings) : Bindings(Bindings) {}
63 void run(
const MatchFinder::MatchResult &Result)
override {
64 Bindings.push_back(Result.Nodes);
70 bool MatchQuery::run(llvm::raw_ostream &OS,
QuerySession &QS)
const {
71 unsigned MatchCount = 0;
73 for (
auto &AST : QS.
ASTs) {
75 std::vector<BoundNodes> Matches;
76 DynTypedMatcher MaybeBoundMatcher = Matcher;
78 llvm::Optional<DynTypedMatcher> M = Matcher.tryBind(
"root");
80 MaybeBoundMatcher = *M;
82 CollectBoundNodes Collect(Matches);
83 if (!Finder.addDynamicMatcher(MaybeBoundMatcher, &Collect)) {
84 OS <<
"Not a valid top-level matcher.\n";
87 Finder.matchAST(AST->getASTContext());
89 for (
auto MI = Matches.begin(), ME = Matches.end(); MI != ME; ++MI) {
90 OS <<
"\nMatch #" << ++MatchCount <<
":\n\n";
92 for (
auto BI = MI->getMap().begin(), BE = MI->getMap().end(); BI != BE;
96 clang::SourceRange R = BI->second.getSourceRange();
98 TextDiagnostic TD(OS, AST->getASTContext().getLangOpts(),
99 &AST->getDiagnostics().getDiagnosticOptions());
101 FullSourceLoc(R.getBegin(), AST->getSourceManager()),
102 DiagnosticsEngine::Note,
"\"" + BI->first +
"\" binds here",
103 CharSourceRange::getTokenRange(R), None);
108 OS <<
"Binding for \"" << BI->first <<
"\":\n";
109 BI->second.print(OS, AST->getASTContext().getPrintingPolicy());
114 OS <<
"Binding for \"" << BI->first <<
"\":\n";
115 BI->second.dump(OS, AST->getSourceManager());
122 if (MI->getMap().empty())
123 OS <<
"No bindings.\n";
127 OS << MatchCount << (MatchCount == 1 ?
" match.\n" :
" matches.\n");
Represents the state for a particular clang-query session.
llvm::ArrayRef< std::unique_ptr< ASTUnit > > ASTs
llvm::StringMap< ast_matchers::dynamic::VariantValue > NamedValues
std::vector< BoundNodes > & Bindings