blob: 109336a9ddc42502a9e1a7a83c3ec45264d680c3 [file] [log] [blame]
Peter Collingbourne8b1265b2013-11-08 00:08:23 +00001//===--- Query.h - clang-query ----------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_H
11#define LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_H
12
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000013#include "clang/ASTMatchers/Dynamic/VariantValue.h"
14#include "llvm/ADT/IntrusiveRefCntPtr.h"
15#include "llvm/ADT/Optional.h"
Chandler Carruth85e6e872014-01-07 20:05:01 +000016#include <string>
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000017
18namespace clang {
19namespace query {
20
21enum OutputKind {
22 OK_Diag,
23 OK_Print,
24 OK_Dump
25};
26
27enum QueryKind {
28 QK_Invalid,
29 QK_NoOp,
30 QK_Help,
Samuel Benzaquen1f6066c2014-04-23 14:04:52 +000031 QK_Let,
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000032 QK_Match,
33 QK_SetBool,
Samuel Benzaquen1f6066c2014-04-23 14:04:52 +000034 QK_SetOutputKind,
Aaron Ballman58907172015-08-06 11:56:57 +000035 QK_Quit
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000036};
37
38class QuerySession;
39
40struct Query : llvm::RefCountedBase<Query> {
41 Query(QueryKind Kind) : Kind(Kind) {}
42 virtual ~Query();
43
44 /// Perform the query on \p QS and print output to \p OS.
45 ///
46 /// \return false if an error occurs, otherwise return true.
47 virtual bool run(llvm::raw_ostream &OS, QuerySession &QS) const = 0;
48
49 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 {
90 MatchQuery(const ast_matchers::dynamic::DynTypedMatcher &Matcher)
91 : Query(QK_Match), Matcher(Matcher) {}
Craig Toppera3dbe842014-03-02 10:20:11 +000092 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000093
94 ast_matchers::dynamic::DynTypedMatcher Matcher;
95
96 static bool classof(const Query *Q) { return Q->Kind == QK_Match; }
97};
98
Samuel Benzaquen1f6066c2014-04-23 14:04:52 +000099struct LetQuery : Query {
100 LetQuery(StringRef Name, const ast_matchers::dynamic::VariantValue &Value)
101 : Query(QK_Let), Name(Name), Value(Value) {}
102 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
103
104 std::string Name;
105 ast_matchers::dynamic::VariantValue Value;
106
107 static bool classof(const Query *Q) { return Q->Kind == QK_Let; }
108};
109
Peter Collingbourne8b1265b2013-11-08 00:08:23 +0000110template <typename T> struct SetQueryKind {};
111
112template <> struct SetQueryKind<bool> {
113 static const QueryKind value = QK_SetBool;
114};
115
116template <> struct SetQueryKind<OutputKind> {
117 static const QueryKind value = QK_SetOutputKind;
118};
119
120/// Query for "set VAR VALUE".
121template <typename T> struct SetQuery : Query {
122 SetQuery(T QuerySession::*Var, T Value)
123 : Query(SetQueryKind<T>::value), Var(Var), Value(Value) {}
Craig Toppera3dbe842014-03-02 10:20:11 +0000124 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override {
Peter Collingbourne8b1265b2013-11-08 00:08:23 +0000125 QS.*Var = Value;
126 return true;
127 }
128
129 static bool classof(const Query *Q) {
130 return Q->Kind == SetQueryKind<T>::value;
131 }
132
133 T QuerySession::*Var;
134 T Value;
135};
136
137} // namespace query
138} // namespace clang
139
140#endif