150
|
1 //===--- Query.h - clang-query ----------------------------------*- C++ -*-===//
|
|
2 //
|
|
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
4 // See https://llvm.org/LICENSE.txt for license information.
|
|
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
6 //
|
|
7 //===----------------------------------------------------------------------===//
|
|
8
|
|
9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_H
|
|
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_H
|
|
11
|
|
12 #include "QuerySession.h"
|
|
13 #include "clang/ASTMatchers/Dynamic/VariantValue.h"
|
|
14 #include "llvm/ADT/IntrusiveRefCntPtr.h"
|
|
15 #include "llvm/ADT/Optional.h"
|
|
16 #include <string>
|
|
17
|
|
18 namespace clang {
|
|
19 namespace query {
|
|
20
|
221
|
21 enum OutputKind { OK_Diag, OK_Print, OK_DetailedAST, OK_SrcLoc };
|
150
|
22
|
|
23 enum QueryKind {
|
|
24 QK_Invalid,
|
|
25 QK_NoOp,
|
|
26 QK_Help,
|
|
27 QK_Let,
|
|
28 QK_Match,
|
|
29 QK_SetBool,
|
|
30 QK_SetOutputKind,
|
173
|
31 QK_SetTraversalKind,
|
150
|
32 QK_EnableOutputKind,
|
|
33 QK_DisableOutputKind,
|
|
34 QK_Quit
|
|
35 };
|
|
36
|
|
37 class QuerySession;
|
|
38
|
|
39 struct Query : llvm::RefCountedBase<Query> {
|
|
40 Query(QueryKind Kind) : Kind(Kind) {}
|
|
41 virtual ~Query();
|
|
42
|
|
43 /// Perform the query on \p QS and print output to \p OS.
|
|
44 ///
|
|
45 /// \return false if an error occurs, otherwise return true.
|
|
46 virtual bool run(llvm::raw_ostream &OS, QuerySession &QS) const = 0;
|
|
47
|
|
48 StringRef RemainingContent;
|
|
49 const QueryKind Kind;
|
|
50 };
|
|
51
|
|
52 typedef llvm::IntrusiveRefCntPtr<Query> QueryRef;
|
|
53
|
|
54 /// Any query which resulted in a parse error. The error message is in ErrStr.
|
|
55 struct InvalidQuery : Query {
|
|
56 InvalidQuery(const Twine &ErrStr) : Query(QK_Invalid), ErrStr(ErrStr.str()) {}
|
|
57 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
|
|
58
|
|
59 std::string ErrStr;
|
|
60
|
|
61 static bool classof(const Query *Q) { return Q->Kind == QK_Invalid; }
|
|
62 };
|
|
63
|
|
64 /// No-op query (i.e. a blank line).
|
|
65 struct NoOpQuery : Query {
|
|
66 NoOpQuery() : Query(QK_NoOp) {}
|
|
67 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
|
|
68
|
|
69 static bool classof(const Query *Q) { return Q->Kind == QK_NoOp; }
|
|
70 };
|
|
71
|
|
72 /// Query for "help".
|
|
73 struct HelpQuery : Query {
|
|
74 HelpQuery() : Query(QK_Help) {}
|
|
75 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
|
|
76
|
|
77 static bool classof(const Query *Q) { return Q->Kind == QK_Help; }
|
|
78 };
|
|
79
|
|
80 /// Query for "quit".
|
|
81 struct QuitQuery : Query {
|
|
82 QuitQuery() : Query(QK_Quit) {}
|
|
83 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
|
|
84
|
|
85 static bool classof(const Query *Q) { return Q->Kind == QK_Quit; }
|
|
86 };
|
|
87
|
|
88 /// Query for "match MATCHER".
|
|
89 struct MatchQuery : Query {
|
|
90 MatchQuery(StringRef Source,
|
|
91 const ast_matchers::dynamic::DynTypedMatcher &Matcher)
|
|
92 : Query(QK_Match), Matcher(Matcher), Source(Source) {}
|
|
93 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
|
|
94
|
|
95 ast_matchers::dynamic::DynTypedMatcher Matcher;
|
|
96
|
|
97 StringRef Source;
|
|
98
|
|
99 static bool classof(const Query *Q) { return Q->Kind == QK_Match; }
|
|
100 };
|
|
101
|
|
102 struct LetQuery : Query {
|
|
103 LetQuery(StringRef Name, const ast_matchers::dynamic::VariantValue &Value)
|
|
104 : Query(QK_Let), Name(Name), Value(Value) {}
|
|
105 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
|
|
106
|
|
107 std::string Name;
|
|
108 ast_matchers::dynamic::VariantValue Value;
|
|
109
|
|
110 static bool classof(const Query *Q) { return Q->Kind == QK_Let; }
|
|
111 };
|
|
112
|
|
113 template <typename T> struct SetQueryKind {};
|
|
114
|
|
115 template <> struct SetQueryKind<bool> {
|
|
116 static const QueryKind value = QK_SetBool;
|
|
117 };
|
|
118
|
|
119 template <> struct SetQueryKind<OutputKind> {
|
|
120 static const QueryKind value = QK_SetOutputKind;
|
|
121 };
|
|
122
|
221
|
123 template <> struct SetQueryKind<TraversalKind> {
|
173
|
124 static const QueryKind value = QK_SetTraversalKind;
|
|
125 };
|
|
126
|
150
|
127 /// Query for "set VAR VALUE".
|
|
128 template <typename T> struct SetQuery : Query {
|
|
129 SetQuery(T QuerySession::*Var, T Value)
|
|
130 : Query(SetQueryKind<T>::value), Var(Var), Value(Value) {}
|
|
131 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override {
|
|
132 QS.*Var = Value;
|
|
133 return true;
|
|
134 }
|
|
135
|
|
136 static bool classof(const Query *Q) {
|
|
137 return Q->Kind == SetQueryKind<T>::value;
|
|
138 }
|
|
139
|
|
140 T QuerySession::*Var;
|
|
141 T Value;
|
|
142 };
|
|
143
|
|
144 // Implements the exclusive 'set output dump|diag|print' options.
|
|
145 struct SetExclusiveOutputQuery : Query {
|
|
146 SetExclusiveOutputQuery(bool QuerySession::*Var)
|
|
147 : Query(QK_SetOutputKind), Var(Var) {}
|
|
148 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override {
|
|
149 QS.DiagOutput = false;
|
|
150 QS.DetailedASTOutput = false;
|
|
151 QS.PrintOutput = false;
|
221
|
152 QS.SrcLocOutput = false;
|
150
|
153 QS.*Var = true;
|
|
154 return true;
|
|
155 }
|
|
156
|
|
157 static bool classof(const Query *Q) { return Q->Kind == QK_SetOutputKind; }
|
|
158
|
|
159 bool QuerySession::*Var;
|
|
160 };
|
|
161
|
|
162 // Implements the non-exclusive 'set output dump|diag|print' options.
|
|
163 struct SetNonExclusiveOutputQuery : Query {
|
|
164 SetNonExclusiveOutputQuery(QueryKind Kind, bool QuerySession::*Var,
|
|
165 bool Value)
|
|
166 : Query(Kind), Var(Var), Value(Value) {}
|
|
167 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override {
|
|
168 QS.*Var = Value;
|
|
169 return true;
|
|
170 }
|
|
171
|
|
172 bool QuerySession::*Var;
|
|
173 bool Value;
|
|
174 };
|
|
175
|
|
176 struct EnableOutputQuery : SetNonExclusiveOutputQuery {
|
|
177 EnableOutputQuery(bool QuerySession::*Var)
|
|
178 : SetNonExclusiveOutputQuery(QK_EnableOutputKind, Var, true) {}
|
|
179
|
|
180 static bool classof(const Query *Q) { return Q->Kind == QK_EnableOutputKind; }
|
|
181 };
|
|
182
|
|
183 struct DisableOutputQuery : SetNonExclusiveOutputQuery {
|
|
184 DisableOutputQuery(bool QuerySession::*Var)
|
|
185 : SetNonExclusiveOutputQuery(QK_DisableOutputKind, Var, false) {}
|
|
186
|
|
187 static bool classof(const Query *Q) {
|
|
188 return Q->Kind == QK_DisableOutputKind;
|
|
189 }
|
|
190 };
|
|
191
|
|
192 } // namespace query
|
|
193 } // namespace clang
|
|
194
|
|
195 #endif
|