11 #include "clang/ASTMatchers/ASTMatchFinder.h" 12 #include "clang/Frontend/ASTUnit.h" 13 #include "clang/Frontend/TextDiagnostic.h" 14 #include "llvm/Support/raw_ostream.h" 24 bool InvalidQuery::run(llvm::raw_ostream &OS,
QuerySession &QS)
const {
29 bool NoOpQuery::run(llvm::raw_ostream &OS,
QuerySession &QS)
const {
33 bool HelpQuery::run(llvm::raw_ostream &OS,
QuerySession &QS)
const {
34 OS <<
"Available commands:\n\n" 35 " match MATCHER, m MATCHER " 36 "Match the loaded ASTs against the given matcher.\n" 37 " let NAME MATCHER, l NAME MATCHER " 38 "Give a matcher expression a name, to be used later\n" 40 "as part of other expressions.\n" 41 " set bind-root (true|false) " 42 "Set whether to bind the root matcher to \"root\".\n" 43 " set print-matcher (true|false) " 44 "Set whether to print the current matcher,\n" 45 " set output <feature> " 46 "Set whether to output only <feature> content.\n" 47 " enable output <feature> " 48 "Enable <feature> content non-exclusively.\n" 49 " disable output <feature> " 50 "Disable <feature> content non-exclusively.\n" 52 "Terminates the query session.\n\n" 53 "Several commands accept a <feature> parameter. The available features " 56 "Pretty-print bound nodes.\n" 58 "Diagnostic location for bound nodes.\n" 60 "Detailed AST output for bound nodes.\n" 62 "Detailed AST output for bound nodes (alias of detailed-ast).\n\n";
66 bool QuitQuery::run(llvm::raw_ostream &OS,
QuerySession &QS)
const {
73 struct CollectBoundNodes : MatchFinder::MatchCallback {
75 CollectBoundNodes(std::vector<BoundNodes> &Bindings) : Bindings(Bindings) {}
76 void run(
const MatchFinder::MatchResult &
Result)
override {
77 Bindings.push_back(Result.Nodes);
83 bool MatchQuery::run(llvm::raw_ostream &OS,
QuerySession &QS)
const {
84 unsigned MatchCount = 0;
86 for (
auto &AST : QS.
ASTs) {
88 std::vector<BoundNodes> Matches;
89 DynTypedMatcher MaybeBoundMatcher = Matcher;
91 llvm::Optional<DynTypedMatcher> M = Matcher.tryBind(
"root");
93 MaybeBoundMatcher = *M;
95 CollectBoundNodes Collect(Matches);
96 if (!Finder.addDynamicMatcher(MaybeBoundMatcher, &Collect)) {
97 OS <<
"Not a valid top-level matcher.\n";
100 Finder.matchAST(AST->getASTContext());
103 std::string prefixText =
"Matcher: ";
104 OS <<
"\n " << prefixText << Source <<
"\n";
105 OS <<
" " << std::string(prefixText.size() + Source.size(),
'=') <<
'\n';
108 for (
auto MI = Matches.begin(), ME = Matches.end(); MI != ME; ++MI) {
109 OS <<
"\nMatch #" << ++MatchCount <<
":\n\n";
111 for (
auto BI = MI->getMap().begin(), BE = MI->getMap().end(); BI != BE;
114 clang::SourceRange R = BI->second.getSourceRange();
116 TextDiagnostic TD(OS, AST->getASTContext().getLangOpts(),
117 &AST->getDiagnostics().getDiagnosticOptions());
119 FullSourceLoc(R.getBegin(), AST->getSourceManager()),
120 DiagnosticsEngine::Note,
"\"" + BI->first +
"\" binds here",
125 OS <<
"Binding for \"" << BI->first <<
"\":\n";
126 BI->second.print(OS, AST->getASTContext().getPrintingPolicy());
130 OS <<
"Binding for \"" << BI->first <<
"\":\n";
131 BI->second.dump(OS, AST->getSourceManager());
136 if (MI->getMap().empty())
137 OS <<
"No bindings.\n";
141 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
static constexpr llvm::StringLiteral Name
llvm::Optional< Range > getTokenRange(const SourceManager &SM, const LangOptions &LangOpts, SourceLocation TokLoc)
Returns the taken range at TokLoc.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
std::vector< BoundNodes > & Bindings
llvm::Optional< llvm::Expected< tooling::AtomicChanges > > Result