clang-tools 3.8.0

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

Query.cpp
Go to the documentation of this file.
1 //===---- Query.cpp - clang-query query -----------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "Query.h"
11 #include "QuerySession.h"
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"
16
17 using namespace clang::ast_matchers;
18 using namespace clang::ast_matchers::dynamic;
19
20 namespace clang {
21 namespace query {
22
23 Query::~Query() {}
24
25 bool InvalidQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
26 OS << ErrStr << "\n";
27 return false;
28 }
29
30 bool NoOpQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
31 return true;
32 }
33
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"
40 " "
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"
46 " "
47 "AST pretty prints or AST dumps.\n"
48 " quit "
49 "Terminates the query session.\n\n";
50 return true;
51 }
52
53 bool QuitQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
54 QS.Terminate = true;
55 return true;
56 }
57
58 namespace {
59
60 struct CollectBoundNodes : MatchFinder::MatchCallback {
61 std::vector<BoundNodes> &Bindings;
62 CollectBoundNodes(std::vector<BoundNodes> &Bindings) : Bindings(Bindings) {}
63 void run(const MatchFinder::MatchResult &Result) override {
64 Bindings.push_back(Result.Nodes);
65 }
66 };
67
68 } // namespace
69
70 bool MatchQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
71 unsigned MatchCount = 0;
72
73 for (auto &AST : QS.ASTs) {
74 MatchFinder Finder;
75 std::vector<BoundNodes> Matches;
76 DynTypedMatcher MaybeBoundMatcher = Matcher;
77 if (QS.BindRoot) {
78 llvm::Optional<DynTypedMatcher> M = Matcher.tryBind("root");
79 if (M)
80 MaybeBoundMatcher = *M;
81 }
82 CollectBoundNodes Collect(Matches);
83 if (!Finder.addDynamicMatcher(MaybeBoundMatcher, &Collect)) {
84 OS << "Not a valid top-level matcher.\n";
85 return false;
86 }
87 Finder.matchAST(AST->getASTContext());
88
89 for (std::vector<BoundNodes>::iterator MI = Matches.begin(),
90 ME = Matches.end();
91 MI != ME; ++MI) {
92 OS << "\nMatch #" << ++MatchCount << ":\n\n";
93
94 for (BoundNodes::IDToNodeMap::const_iterator BI = MI->getMap().begin(),
95 BE = MI->getMap().end();
96 BI != BE; ++BI) {
97 switch (QS.OutKind) {
98 case OK_Diag: {
99 clang::SourceRange R = BI->second.getSourceRange();
100 if (R.isValid()) {
101 TextDiagnostic TD(OS, AST->getASTContext().getLangOpts(),
102 &AST->getDiagnostics().getDiagnosticOptions());
103 TD.emitDiagnostic(
104 R.getBegin(), DiagnosticsEngine::Note,
105 "\"" + BI->first + "\" binds here",
106 CharSourceRange::getTokenRange(R),
107 None, &AST->getSourceManager());
108 }
109 break;
110 }
111 case OK_Print: {
112 OS << "Binding for \"" << BI->first << "\":\n";
113 BI->second.print(OS, AST->getASTContext().getPrintingPolicy());
114 OS << "\n";
115 break;
116 }
117 case OK_Dump: {
118 OS << "Binding for \"" << BI->first << "\":\n";
119 BI->second.dump(OS, AST->getSourceManager());
120 OS << "\n";
121 break;
122 }
123 }
124 }
125
126 if (MI->getMap().empty())
127 OS << "No bindings.\n";
128 }
129 }
130
131 OS << MatchCount << (MatchCount == 1 ? " match.\n" : " matches.\n");
132 return true;
133 }
134
135 bool LetQuery::run(llvm::raw_ostream &OS, QuerySession &QS) const {
136 if (Value) {
137 QS.NamedValues[Name] = Value;
138 } else {
139 QS.NamedValues.erase(Name);
140 }
141 return true;
142 }
143
144 #ifndef _MSC_VER
145 const QueryKind SetQueryKind<bool>::value;
146 const QueryKind SetQueryKind<OutputKind>::value;
147 #endif
148
149 } // namespace query
150 } // namespace clang
Name
StringHandle Name
Definition: PreprocessorTracker.cpp:525
Finder
std::unique_ptr< ast_matchers::MatchFinder > Finder
Definition: ClangTidy.cpp:188
clang::query::QuerySession::BindRoot
bool BindRoot
Definition: QuerySession.h:32
clang::query::QuerySession
Represents the state for a particular clang-query session.
Definition: QuerySession.h:25
clang::query::QuerySession::ASTs
llvm::ArrayRef< std::unique_ptr< ASTUnit > > ASTs
Definition: QuerySession.h:30
clang::query::OK_Diag
Definition: Query.h:22
clang::query::QuerySession::Terminate
bool Terminate
Definition: QuerySession.h:33
Query.h
clang::query::QuerySession::NamedValues
llvm::StringMap< ast_matchers::dynamic::VariantValue > NamedValues
Definition: QuerySession.h:34
clang::query::QuerySession::OutKind
OutputKind OutKind
Definition: QuerySession.h:31
QuerySession.h
clang::query::OK_Print
Definition: Query.h:23
clang::query::SetQueryKind
Definition: Query.h:110
Bindings
std::vector< BoundNodes > & Bindings
Definition: Query.cpp:61
clang::query::OK_Dump
Definition: Query.h:24
clang::query::QueryKind
QueryKind
Definition: Query.h:27
Result
const NamedDecl * Result
Definition: USRFinder.cpp:121