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
, OK_SrcLoc
};
38 struct Query
: llvm::RefCountedBase
<Query
> {
39 Query(QueryKind Kind
) : Kind(Kind
) {}
42 /// Perform the query on \p QS and print output to \p OS.
44 /// \return false if an error occurs, otherwise return true.
45 virtual bool run(llvm::raw_ostream
&OS
, QuerySession
&QS
) const = 0;
47 StringRef RemainingContent
;
51 typedef llvm::IntrusiveRefCntPtr
<Query
> QueryRef
;
53 /// Any query which resulted in a parse error. The error message is in ErrStr.
54 struct InvalidQuery
: Query
{
55 InvalidQuery(const Twine
&ErrStr
) : Query(QK_Invalid
), ErrStr(ErrStr
.str()) {}
56 bool run(llvm::raw_ostream
&OS
, QuerySession
&QS
) const override
;
60 static bool classof(const Query
*Q
) { return Q
->Kind
== QK_Invalid
; }
63 /// No-op query (i.e. a blank line).
64 struct NoOpQuery
: Query
{
65 NoOpQuery() : Query(QK_NoOp
) {}
66 bool run(llvm::raw_ostream
&OS
, QuerySession
&QS
) const override
;
68 static bool classof(const Query
*Q
) { return Q
->Kind
== QK_NoOp
; }
72 struct HelpQuery
: Query
{
73 HelpQuery() : Query(QK_Help
) {}
74 bool run(llvm::raw_ostream
&OS
, QuerySession
&QS
) const override
;
76 static bool classof(const Query
*Q
) { return Q
->Kind
== QK_Help
; }
80 struct QuitQuery
: Query
{
81 QuitQuery() : Query(QK_Quit
) {}
82 bool run(llvm::raw_ostream
&OS
, QuerySession
&QS
) const override
;
84 static bool classof(const Query
*Q
) { return Q
->Kind
== QK_Quit
; }
87 /// Query for "match MATCHER".
88 struct MatchQuery
: Query
{
89 MatchQuery(StringRef Source
,
90 const ast_matchers::dynamic::DynTypedMatcher
&Matcher
)
91 : Query(QK_Match
), Matcher(Matcher
), Source(Source
) {}
92 bool run(llvm::raw_ostream
&OS
, QuerySession
&QS
) const override
;
94 ast_matchers::dynamic::DynTypedMatcher Matcher
;
98 static bool classof(const Query
*Q
) { return Q
->Kind
== QK_Match
; }
101 struct LetQuery
: Query
{
102 LetQuery(StringRef Name
, const ast_matchers::dynamic::VariantValue
&Value
)
103 : Query(QK_Let
), Name(Name
), Value(Value
) {}
104 bool run(llvm::raw_ostream
&OS
, QuerySession
&QS
) const override
;
107 ast_matchers::dynamic::VariantValue Value
;
109 static bool classof(const Query
*Q
) { return Q
->Kind
== QK_Let
; }
112 template <typename T
> struct SetQueryKind
{};
114 template <> struct SetQueryKind
<bool> {
115 static const QueryKind value
= QK_SetBool
;
118 template <> struct SetQueryKind
<OutputKind
> {
119 static const QueryKind value
= QK_SetOutputKind
;
122 template <> struct SetQueryKind
<TraversalKind
> {
123 static const QueryKind value
= QK_SetTraversalKind
;
126 /// Query for "set VAR VALUE".
127 template <typename T
> struct SetQuery
: Query
{
128 SetQuery(T
QuerySession::*Var
, T Value
)
129 : Query(SetQueryKind
<T
>::value
), Var(Var
), Value(Value
) {}
130 bool run(llvm::raw_ostream
&OS
, QuerySession
&QS
) const override
{
135 static bool classof(const Query
*Q
) {
136 return Q
->Kind
== SetQueryKind
<T
>::value
;
139 T
QuerySession::*Var
;
143 // Implements the exclusive 'set output dump|diag|print' options.
144 struct SetExclusiveOutputQuery
: Query
{
145 SetExclusiveOutputQuery(bool QuerySession::*Var
)
146 : Query(QK_SetOutputKind
), Var(Var
) {}
147 bool run(llvm::raw_ostream
&OS
, QuerySession
&QS
) const override
{
148 QS
.DiagOutput
= false;
149 QS
.DetailedASTOutput
= false;
150 QS
.PrintOutput
= false;
151 QS
.SrcLocOutput
= 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
;