blob: af250fbe13ce3fa72e0b3b729392c5447655538e [file] [log] [blame]
Peter Collingbourne8b1265b2013-11-08 00:08:23 +00001//===--- Query.h - clang-query ----------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Peter Collingbourne8b1265b2013-11-08 00:08:23 +00006//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_H
10#define LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_H
11
Stephen Kelly70d77172018-10-24 20:33:55 +000012#include "QuerySession.h"
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000013#include "clang/ASTMatchers/Dynamic/VariantValue.h"
14#include "llvm/ADT/IntrusiveRefCntPtr.h"
Chandler Carruth85e6e872014-01-07 20:05:01 +000015#include <string>
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000016
17namespace clang {
18namespace query {
19
Aaron Ballman371eccd2024-05-17 08:06:46 -040020enum OutputKind { OK_Diag, OK_Print, OK_DetailedAST };
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000021
22enum QueryKind {
23 QK_Invalid,
24 QK_NoOp,
25 QK_Help,
Samuel Benzaquen1f6066c2014-04-23 14:04:52 +000026 QK_Let,
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000027 QK_Match,
28 QK_SetBool,
Samuel Benzaquen1f6066c2014-04-23 14:04:52 +000029 QK_SetOutputKind,
Stephen Kelly10f0f982019-12-29 19:26:11 +000030 QK_SetTraversalKind,
Stephen Kellya49fe5d2018-10-29 18:59:56 +000031 QK_EnableOutputKind,
32 QK_DisableOutputKind,
Chris Warner5e9401c2024-05-13 05:11:39 -070033 QK_Quit,
34 QK_File
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000035};
36
37class QuerySession;
38
39struct 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
Stephen Kellyf0722332019-12-18 22:35:46 +000048 StringRef RemainingContent;
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000049 const QueryKind Kind;
50};
51
52typedef llvm::IntrusiveRefCntPtr<Query> QueryRef;
53
54/// Any query which resulted in a parse error. The error message is in ErrStr.
55struct InvalidQuery : Query {
56 InvalidQuery(const Twine &ErrStr) : Query(QK_Invalid), ErrStr(ErrStr.str()) {}
Craig Toppera3dbe842014-03-02 10:20:11 +000057 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000058
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).
65struct NoOpQuery : Query {
66 NoOpQuery() : Query(QK_NoOp) {}
Craig Toppera3dbe842014-03-02 10:20:11 +000067 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000068
69 static bool classof(const Query *Q) { return Q->Kind == QK_NoOp; }
70};
71
72/// Query for "help".
73struct HelpQuery : Query {
74 HelpQuery() : Query(QK_Help) {}
Craig Toppera3dbe842014-03-02 10:20:11 +000075 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000076
77 static bool classof(const Query *Q) { return Q->Kind == QK_Help; }
78};
79
Aaron Ballman58907172015-08-06 11:56:57 +000080/// Query for "quit".
81struct 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
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000088/// Query for "match MATCHER".
89struct MatchQuery : Query {
Stephen Kelly4a5b01d2018-10-20 09:13:59 +000090 MatchQuery(StringRef Source,
91 const ast_matchers::dynamic::DynTypedMatcher &Matcher)
92 : Query(QK_Match), Matcher(Matcher), Source(Source) {}
Craig Toppera3dbe842014-03-02 10:20:11 +000093 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000094
95 ast_matchers::dynamic::DynTypedMatcher Matcher;
96
Stephen Kelly4a5b01d2018-10-20 09:13:59 +000097 StringRef Source;
98
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000099 static bool classof(const Query *Q) { return Q->Kind == QK_Match; }
100};
101
Samuel Benzaquen1f6066c2014-04-23 14:04:52 +0000102struct 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
Peter Collingbourne8b1265b2013-11-08 00:08:23 +0000113template <typename T> struct SetQueryKind {};
114
115template <> struct SetQueryKind<bool> {
116 static const QueryKind value = QK_SetBool;
117};
118
119template <> struct SetQueryKind<OutputKind> {
120 static const QueryKind value = QK_SetOutputKind;
121};
122
Alexander Kornienko027899d2020-12-11 00:52:35 +0100123template <> struct SetQueryKind<TraversalKind> {
Stephen Kelly10f0f982019-12-29 19:26:11 +0000124 static const QueryKind value = QK_SetTraversalKind;
125};
126
Peter Collingbourne8b1265b2013-11-08 00:08:23 +0000127/// Query for "set VAR VALUE".
128template <typename T> struct SetQuery : Query {
129 SetQuery(T QuerySession::*Var, T Value)
130 : Query(SetQueryKind<T>::value), Var(Var), Value(Value) {}
Craig Toppera3dbe842014-03-02 10:20:11 +0000131 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override {
Peter Collingbourne8b1265b2013-11-08 00:08:23 +0000132 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
Stephen Kelly70d77172018-10-24 20:33:55 +0000144// Implements the exclusive 'set output dump|diag|print' options.
145struct 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;
Stephen Kelly70d77172018-10-24 20:33:55 +0000152 QS.*Var = true;
153 return true;
154 }
155
156 static bool classof(const Query *Q) { return Q->Kind == QK_SetOutputKind; }
157
158 bool QuerySession::*Var;
159};
160
Stephen Kellya49fe5d2018-10-29 18:59:56 +0000161// Implements the non-exclusive 'set output dump|diag|print' options.
162struct SetNonExclusiveOutputQuery : Query {
163 SetNonExclusiveOutputQuery(QueryKind Kind, bool QuerySession::*Var,
164 bool Value)
165 : Query(Kind), Var(Var), Value(Value) {}
166 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override {
167 QS.*Var = Value;
168 return true;
169 }
170
171 bool QuerySession::*Var;
172 bool Value;
173};
174
175struct EnableOutputQuery : SetNonExclusiveOutputQuery {
176 EnableOutputQuery(bool QuerySession::*Var)
177 : SetNonExclusiveOutputQuery(QK_EnableOutputKind, Var, true) {}
178
179 static bool classof(const Query *Q) { return Q->Kind == QK_EnableOutputKind; }
180};
181
182struct DisableOutputQuery : SetNonExclusiveOutputQuery {
183 DisableOutputQuery(bool QuerySession::*Var)
184 : SetNonExclusiveOutputQuery(QK_DisableOutputKind, Var, false) {}
185
186 static bool classof(const Query *Q) {
187 return Q->Kind == QK_DisableOutputKind;
188 }
189};
190
Chris Warner5e9401c2024-05-13 05:11:39 -0700191struct FileQuery : Query {
192 FileQuery(StringRef File, StringRef Prefix = StringRef())
193 : Query(QK_File), File(File),
194 Prefix(!Prefix.empty() ? std::optional<std::string>(Prefix)
195 : std::nullopt) {}
196
197 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
198
199 static bool classof(const Query *Q) { return Q->Kind == QK_File; }
200
201private:
202 std::string File;
203 std::optional<std::string> Prefix;
204};
205
Peter Collingbourne8b1265b2013-11-08 00:08:23 +0000206} // namespace query
207} // namespace clang
208
209#endif