blob: b8c59cb35182b5a7c5da12477eafcee8208d0876 [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
Mandeep Singh Grang7c7ea7d2016-11-08 07:50:19 +000021enum OutputKind { OK_Diag, OK_Print, OK_Dump };
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000022
23enum QueryKind {
24 QK_Invalid,
25 QK_NoOp,
26 QK_Help,
Samuel Benzaquen1f6066c2014-04-23 14:04:52 +000027 QK_Let,
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000028 QK_Match,
29 QK_SetBool,
Samuel Benzaquen1f6066c2014-04-23 14:04:52 +000030 QK_SetOutputKind,
Aaron Ballman58907172015-08-06 11:56:57 +000031 QK_Quit
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000032};
33
34class QuerySession;
35
36struct Query : llvm::RefCountedBase<Query> {
37 Query(QueryKind Kind) : Kind(Kind) {}
38 virtual ~Query();
39
40 /// Perform the query on \p QS and print output to \p OS.
41 ///
42 /// \return false if an error occurs, otherwise return true.
43 virtual bool run(llvm::raw_ostream &OS, QuerySession &QS) const = 0;
44
45 const QueryKind Kind;
46};
47
48typedef llvm::IntrusiveRefCntPtr<Query> QueryRef;
49
50/// Any query which resulted in a parse error. The error message is in ErrStr.
51struct InvalidQuery : Query {
52 InvalidQuery(const Twine &ErrStr) : Query(QK_Invalid), ErrStr(ErrStr.str()) {}
Craig Toppera3dbe842014-03-02 10:20:11 +000053 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000054
55 std::string ErrStr;
56
57 static bool classof(const Query *Q) { return Q->Kind == QK_Invalid; }
58};
59
60/// No-op query (i.e. a blank line).
61struct NoOpQuery : Query {
62 NoOpQuery() : Query(QK_NoOp) {}
Craig Toppera3dbe842014-03-02 10:20:11 +000063 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000064
65 static bool classof(const Query *Q) { return Q->Kind == QK_NoOp; }
66};
67
68/// Query for "help".
69struct HelpQuery : Query {
70 HelpQuery() : Query(QK_Help) {}
Craig Toppera3dbe842014-03-02 10:20:11 +000071 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000072
73 static bool classof(const Query *Q) { return Q->Kind == QK_Help; }
74};
75
Aaron Ballman58907172015-08-06 11:56:57 +000076/// Query for "quit".
77struct QuitQuery : Query {
78 QuitQuery() : Query(QK_Quit) {}
79 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
80
81 static bool classof(const Query *Q) { return Q->Kind == QK_Quit; }
82};
83
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000084/// Query for "match MATCHER".
85struct MatchQuery : Query {
86 MatchQuery(const ast_matchers::dynamic::DynTypedMatcher &Matcher)
87 : Query(QK_Match), Matcher(Matcher) {}
Craig Toppera3dbe842014-03-02 10:20:11 +000088 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
Peter Collingbourne8b1265b2013-11-08 00:08:23 +000089
90 ast_matchers::dynamic::DynTypedMatcher Matcher;
91
92 static bool classof(const Query *Q) { return Q->Kind == QK_Match; }
93};
94
Samuel Benzaquen1f6066c2014-04-23 14:04:52 +000095struct LetQuery : Query {
96 LetQuery(StringRef Name, const ast_matchers::dynamic::VariantValue &Value)
97 : Query(QK_Let), Name(Name), Value(Value) {}
98 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
99
100 std::string Name;
101 ast_matchers::dynamic::VariantValue Value;
102
103 static bool classof(const Query *Q) { return Q->Kind == QK_Let; }
104};
105
Peter Collingbourne8b1265b2013-11-08 00:08:23 +0000106template <typename T> struct SetQueryKind {};
107
108template <> struct SetQueryKind<bool> {
109 static const QueryKind value = QK_SetBool;
110};
111
112template <> struct SetQueryKind<OutputKind> {
113 static const QueryKind value = QK_SetOutputKind;
114};
115
116/// Query for "set VAR VALUE".
117template <typename T> struct SetQuery : Query {
118 SetQuery(T QuerySession::*Var, T Value)
119 : Query(SetQueryKind<T>::value), Var(Var), Value(Value) {}
Craig Toppera3dbe842014-03-02 10:20:11 +0000120 bool run(llvm::raw_ostream &OS, QuerySession &QS) const override {
Peter Collingbourne8b1265b2013-11-08 00:08:23 +0000121 QS.*Var = Value;
122 return true;
123 }
124
125 static bool classof(const Query *Q) {
126 return Q->Kind == SetQueryKind<T>::value;
127 }
128
129 T QuerySession::*Var;
130 T Value;
131};
132
133} // namespace query
134} // namespace clang
135
136#endif