1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
//===--- Query.h - clang-query ----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_H
#include "clang/ASTMatchers/Dynamic/VariantValue.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/Optional.h"
#include <string>
namespace clang {
namespace query {
enum OutputKind { OK_Diag, OK_Print, OK_Dump };
enum QueryKind {
QK_Invalid,
QK_NoOp,
QK_Help,
QK_Let,
QK_Match,
QK_SetBool,
QK_SetOutputKind,
QK_Quit
};
class QuerySession;
struct Query : llvm::RefCountedBase<Query> {
Query(QueryKind Kind) : Kind(Kind) {}
virtual ~Query();
/// Perform the query on \p QS and print output to \p OS.
///
/// \return false if an error occurs, otherwise return true.
virtual bool run(llvm::raw_ostream &OS, QuerySession &QS) const = 0;
const QueryKind Kind;
};
typedef llvm::IntrusiveRefCntPtr<Query> QueryRef;
/// Any query which resulted in a parse error. The error message is in ErrStr.
struct InvalidQuery : Query {
InvalidQuery(const Twine &ErrStr) : Query(QK_Invalid), ErrStr(ErrStr.str()) {}
bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
std::string ErrStr;
static bool classof(const Query *Q) { return Q->Kind == QK_Invalid; }
};
/// No-op query (i.e. a blank line).
struct NoOpQuery : Query {
NoOpQuery() : Query(QK_NoOp) {}
bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
static bool classof(const Query *Q) { return Q->Kind == QK_NoOp; }
};
/// Query for "help".
struct HelpQuery : Query {
HelpQuery() : Query(QK_Help) {}
bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
static bool classof(const Query *Q) { return Q->Kind == QK_Help; }
};
/// Query for "quit".
struct QuitQuery : Query {
QuitQuery() : Query(QK_Quit) {}
bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
static bool classof(const Query *Q) { return Q->Kind == QK_Quit; }
};
/// Query for "match MATCHER".
struct MatchQuery : Query {
MatchQuery(const ast_matchers::dynamic::DynTypedMatcher &Matcher)
: Query(QK_Match), Matcher(Matcher) {}
bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
ast_matchers::dynamic::DynTypedMatcher Matcher;
static bool classof(const Query *Q) { return Q->Kind == QK_Match; }
};
struct LetQuery : Query {
LetQuery(StringRef Name, const ast_matchers::dynamic::VariantValue &Value)
: Query(QK_Let), Name(Name), Value(Value) {}
bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;
std::string Name;
ast_matchers::dynamic::VariantValue Value;
static bool classof(const Query *Q) { return Q->Kind == QK_Let; }
};
template <typename T> struct SetQueryKind {};
template <> struct SetQueryKind<bool> {
static const QueryKind value = QK_SetBool;
};
template <> struct SetQueryKind<OutputKind> {
static const QueryKind value = QK_SetOutputKind;
};
/// Query for "set VAR VALUE".
template <typename T> struct SetQuery : Query {
SetQuery(T QuerySession::*Var, T Value)
: Query(SetQueryKind<T>::value), Var(Var), Value(Value) {}
bool run(llvm::raw_ostream &OS, QuerySession &QS) const override {
QS.*Var = Value;
return true;
}
static bool classof(const Query *Q) {
return Q->Kind == SetQueryKind<T>::value;
}
T QuerySession::*Var;
T Value;
};
} // namespace query
} // namespace clang
#endif
|