brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.8 KiB · af250fb Raw
210 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_H10#define LLVM_CLANG_TOOLS_EXTRA_CLANG_QUERY_QUERY_H11 12#include "QuerySession.h"13#include "clang/ASTMatchers/Dynamic/VariantValue.h"14#include "llvm/ADT/IntrusiveRefCntPtr.h"15#include <string>16 17namespace clang {18namespace query {19 20enum OutputKind { OK_Diag, OK_Print, OK_DetailedAST };21 22enum QueryKind {23  QK_Invalid,24  QK_NoOp,25  QK_Help,26  QK_Let,27  QK_Match,28  QK_SetBool,29  QK_SetOutputKind,30  QK_SetTraversalKind,31  QK_EnableOutputKind,32  QK_DisableOutputKind,33  QK_Quit,34  QK_File35};36 37class QuerySession;38 39struct Query : llvm::RefCountedBase<Query> {40  Query(QueryKind Kind) : Kind(Kind) {}41  virtual ~Query();42 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;47 48  StringRef RemainingContent;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()) {}57  bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;58 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) {}67  bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;68 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) {}75  bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;76 77  static bool classof(const Query *Q) { return Q->Kind == QK_Help; }78};79 80/// 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 88/// Query for "match MATCHER".89struct 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;94 95  ast_matchers::dynamic::DynTypedMatcher Matcher;96 97  StringRef Source;98 99  static bool classof(const Query *Q) { return Q->Kind == QK_Match; }100};101 102struct 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;106 107  std::string Name;108  ast_matchers::dynamic::VariantValue Value;109 110  static bool classof(const Query *Q) { return Q->Kind == QK_Let; }111};112 113template <typename T> struct SetQueryKind {};114 115template <> struct SetQueryKind<bool> {116  static const QueryKind value = QK_SetBool;117};118 119template <> struct SetQueryKind<OutputKind> {120  static const QueryKind value = QK_SetOutputKind;121};122 123template <> struct SetQueryKind<TraversalKind> {124  static const QueryKind value = QK_SetTraversalKind;125};126 127/// Query for "set VAR VALUE".128template <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;134  }135 136  static bool classof(const Query *Q) {137    return Q->Kind == SetQueryKind<T>::value;138  }139 140  T QuerySession::*Var;141  T Value;142};143 144// Implements the exclusive 'set output dump|diag|print' options.145struct 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.*Var = true;153    return true;154  }155 156  static bool classof(const Query *Q) { return Q->Kind == QK_SetOutputKind; }157 158  bool QuerySession::*Var;159};160 161// Implements the non-exclusive 'set output dump|diag|print' options.162struct SetNonExclusiveOutputQuery : Query {163  SetNonExclusiveOutputQuery(QueryKind Kind, bool QuerySession::*Var,164                             bool Value)165      : Query(Kind), Var(Var), Value(Value) {}166  bool run(llvm::raw_ostream &OS, QuerySession &QS) const override {167    QS.*Var = Value;168    return true;169  }170 171  bool QuerySession::*Var;172  bool Value;173};174 175struct EnableOutputQuery : SetNonExclusiveOutputQuery {176  EnableOutputQuery(bool QuerySession::*Var)177      : SetNonExclusiveOutputQuery(QK_EnableOutputKind, Var, true) {}178 179  static bool classof(const Query *Q) { return Q->Kind == QK_EnableOutputKind; }180};181 182struct DisableOutputQuery : SetNonExclusiveOutputQuery {183  DisableOutputQuery(bool QuerySession::*Var)184      : SetNonExclusiveOutputQuery(QK_DisableOutputKind, Var, false) {}185 186  static bool classof(const Query *Q) {187    return Q->Kind == QK_DisableOutputKind;188  }189};190 191struct FileQuery : Query {192  FileQuery(StringRef File, StringRef Prefix = StringRef())193      : Query(QK_File), File(File),194        Prefix(!Prefix.empty() ? std::optional<std::string>(Prefix)195                               : std::nullopt) {}196 197  bool run(llvm::raw_ostream &OS, QuerySession &QS) const override;198 199  static bool classof(const Query *Q) { return Q->Kind == QK_File; }200 201private:202  std::string File;203  std::optional<std::string> Prefix;204};205 206} // namespace query207} // namespace clang208 209#endif210