[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / clang-tools-extra / clang-query / Query.h
blobf96bf196a6420f1059f1f76cae2610cf09990a54
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 //===----------------------------------------------------------------------===//
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"
15 #include "llvm/ADT/Optional.h"
16 #include <string>
18 namespace clang {
19 namespace query {
21 enum OutputKind { OK_Diag, OK_Print, OK_DetailedAST, OK_SrcLoc };
23 enum QueryKind {
24 QK_Invalid,
25 QK_NoOp,
26 QK_Help,
27 QK_Let,
28 QK_Match,
29 QK_SetBool,
30 QK_SetOutputKind,
31 QK_SetTraversalKind,
32 QK_EnableOutputKind,
33 QK_DisableOutputKind,
34 QK_Quit
37 class QuerySession;
39 struct Query : llvm::RefCountedBase<Query> {
40 Query(QueryKind Kind) : Kind(Kind) {}
41 virtual ~Query();
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;
48 StringRef RemainingContent;
49 const QueryKind Kind;
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;
59 std::string ErrStr;
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; }
72 /// Query for "help".
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; }
80 /// Query for "quit".
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;
97 StringRef Source;
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;
107 std::string Name;
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 {
132 QS.*Var = Value;
133 return true;
136 static bool classof(const Query *Q) {
137 return Q->Kind == SetQueryKind<T>::value;
140 T QuerySession::*Var;
141 T Value;
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;
152 QS.SrcLocOutput = false;
153 QS.*Var = true;
154 return true;
157 static bool classof(const Query *Q) { return Q->Kind == QK_SetOutputKind; }
159 bool QuerySession::*Var;
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;
172 bool QuerySession::*Var;
173 bool Value;
176 struct EnableOutputQuery : SetNonExclusiveOutputQuery {
177 EnableOutputQuery(bool QuerySession::*Var)
178 : SetNonExclusiveOutputQuery(QK_EnableOutputKind, Var, true) {}
180 static bool classof(const Query *Q) { return Q->Kind == QK_EnableOutputKind; }
183 struct DisableOutputQuery : SetNonExclusiveOutputQuery {
184 DisableOutputQuery(bool QuerySession::*Var)
185 : SetNonExclusiveOutputQuery(QK_DisableOutputKind, Var, false) {}
187 static bool classof(const Query *Q) {
188 return Q->Kind == QK_DisableOutputKind;
192 } // namespace query
193 } // namespace clang
195 #endif