1 //===--- Query.h - clang-query ----------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_H
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_H
12 #include "QuerySession.h"
13 #include "clang/ASTMatchers/Dynamic/VariantValue.h"
14 #include "llvm/ADT/IntrusiveRefCntPtr.h"
20 enum OutputKind
{ OK_Diag
, OK_Print
, OK_DetailedAST
};
39 struct Query
: llvm::RefCountedBase
<Query
> {
40 Query(QueryKind Kind
) : Kind(Kind
) {}
43 /// Perform the query on \p QS and print output to \p OS.
45 /// \return false if an error occurs, otherwise return true.
46 virtual bool run(llvm::raw_ostream
&OS
, QuerySession
&QS
) const = 0;
48 StringRef RemainingContent
;
52 typedef llvm::IntrusiveRefCntPtr
<Query
> QueryRef
;
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
;
61 static bool classof(const Query
*Q
) { return Q
->Kind
== QK_Invalid
; }
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
;
69 static bool classof(const Query
*Q
) { return Q
->Kind
== QK_NoOp
; }
73 struct HelpQuery
: Query
{
74 HelpQuery() : Query(QK_Help
) {}
75 bool run(llvm::raw_ostream
&OS
, QuerySession
&QS
) const override
;
77 static bool classof(const Query
*Q
) { return Q
->Kind
== QK_Help
; }
81 struct QuitQuery
: Query
{
82 QuitQuery() : Query(QK_Quit
) {}
83 bool run(llvm::raw_ostream
&OS
, QuerySession
&QS
) const override
;
85 static bool classof(const Query
*Q
) { return Q
->Kind
== QK_Quit
; }
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
;
95 ast_matchers::dynamic::DynTypedMatcher Matcher
;
99 static bool classof(const Query
*Q
) { return Q
->Kind
== QK_Match
; }
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
;
108 ast_matchers::dynamic::VariantValue Value
;
110 static bool classof(const Query
*Q
) { return Q
->Kind
== QK_Let
; }
113 template <typename T
> struct SetQueryKind
{};
115 template <> struct SetQueryKind
<bool> {
116 static const QueryKind value
= QK_SetBool
;
119 template <> struct SetQueryKind
<OutputKind
> {
120 static const QueryKind value
= QK_SetOutputKind
;
123 template <> struct SetQueryKind
<TraversalKind
> {
124 static const QueryKind value
= QK_SetTraversalKind
;
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
{
136 static bool classof(const Query
*Q
) {
137 return Q
->Kind
== SetQueryKind
<T
>::value
;
140 T
QuerySession::*Var
;
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;
156 static bool classof(const Query
*Q
) { return Q
->Kind
== QK_SetOutputKind
; }
158 bool QuerySession::*Var
;
161 // Implements the non-exclusive 'set output dump|diag|print' options.
162 struct SetNonExclusiveOutputQuery
: Query
{
163 SetNonExclusiveOutputQuery(QueryKind Kind
, bool QuerySession::*Var
,
165 : Query(Kind
), Var(Var
), Value(Value
) {}
166 bool run(llvm::raw_ostream
&OS
, QuerySession
&QS
) const override
{
171 bool QuerySession::*Var
;
175 struct EnableOutputQuery
: SetNonExclusiveOutputQuery
{
176 EnableOutputQuery(bool QuerySession::*Var
)
177 : SetNonExclusiveOutputQuery(QK_EnableOutputKind
, Var
, true) {}
179 static bool classof(const Query
*Q
) { return Q
->Kind
== QK_EnableOutputKind
; }
182 struct DisableOutputQuery
: SetNonExclusiveOutputQuery
{
183 DisableOutputQuery(bool QuerySession::*Var
)
184 : SetNonExclusiveOutputQuery(QK_DisableOutputKind
, Var
, false) {}
186 static bool classof(const Query
*Q
) {
187 return Q
->Kind
== QK_DisableOutputKind
;
191 struct FileQuery
: Query
{
192 FileQuery(StringRef File
, StringRef Prefix
= StringRef())
193 : Query(QK_File
), File(File
),
194 Prefix(!Prefix
.empty() ? std::optional
<std::string
>(Prefix
)
197 bool run(llvm::raw_ostream
&OS
, QuerySession
&QS
) const override
;
199 static bool classof(const Query
*Q
) { return Q
->Kind
== QK_File
; }
203 std::optional
<std::string
> Prefix
;