blob: eeeb1b95988efa69a2401d23911fe2939d84048a [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,
31 QK_Match,
32 QK_SetBool,
33 QK_SetOutputKind
34};
35
36class QuerySession;
37
38struct Query : llvm::RefCountedBase<Query> {
39 Query(QueryKind Kind) : Kind(Kind) {}
40 virtual ~Query();
41
42 /// Perform the query on \p QS and print output to \p OS.
43 ///
44 /// \return false if an error occurs, otherwise return true.
45 virtual bool run(llvm::raw_ostream &OS, QuerySession &QS) const = 0;
46
47 const QueryKind Kind;
48};
49
50typedef llvm::IntrusiveRefCntPtr<Query> QueryRef;
51
52/// Any query which resulted in a parse error. The error message is in ErrStr.
53struct InvalidQuery : Query {
54 InvalidQuery(const Twine &ErrStr) : Query(QK_Invalid), ErrStr(ErrStr.str()) {}
55 bool run(llvm::raw_ostream &OS, QuerySession &QS) const LLVM_OVERRIDE;
56
57 std::string ErrStr;
58
59 static bool classof(const Query *Q) { return Q->Kind == QK_Invalid; }
60};
61
62/// No-op query (i.e. a blank line).
63struct NoOpQuery : Query {
64 NoOpQuery() : Query(QK_NoOp) {}
65 bool run(llvm::raw_ostream &OS, QuerySession &QS) const LLVM_OVERRIDE;
66
67 static bool classof(const Query *Q) { return Q->Kind == QK_NoOp; }
68};
69
70/// Query for "help".
71struct HelpQuery : Query {
72 HelpQuery() : Query(QK_Help) {}
73 bool run(llvm::raw_ostream &OS, QuerySession &QS) const LLVM_OVERRIDE;
74
75 static bool classof(const Query *Q) { return Q->Kind == QK_Help; }
76};
77
78/// Query for "match MATCHER".
79struct MatchQuery : Query {
80 MatchQuery(const ast_matchers::dynamic::DynTypedMatcher &Matcher)
81 : Query(QK_Match), Matcher(Matcher) {}
82 bool run(llvm::raw_ostream &OS, QuerySession &QS) const LLVM_OVERRIDE;
83
84 ast_matchers::dynamic::DynTypedMatcher Matcher;
85
86 static bool classof(const Query *Q) { return Q->Kind == QK_Match; }
87};
88
89template <typename T> struct SetQueryKind {};
90
91template <> struct SetQueryKind<bool> {
92 static const QueryKind value = QK_SetBool;
93};
94
95template <> struct SetQueryKind<OutputKind> {
96 static const QueryKind value = QK_SetOutputKind;
97};
98
99/// Query for "set VAR VALUE".
100template <typename T> struct SetQuery : Query {
101 SetQuery(T QuerySession::*Var, T Value)
102 : Query(SetQueryKind<T>::value), Var(Var), Value(Value) {}
103 bool run(llvm::raw_ostream &OS, QuerySession &QS) const LLVM_OVERRIDE {
104 QS.*Var = Value;
105 return true;
106 }
107
108 static bool classof(const Query *Q) {
109 return Q->Kind == SetQueryKind<T>::value;
110 }
111
112 T QuerySession::*Var;
113 T Value;
114};
115
116} // namespace query
117} // namespace clang
118
119#endif