clang  14.0.0git
ASTConsumers.cpp
Go to the documentation of this file.
1 //===--- ASTConsumers.cpp - ASTConsumer implementations -------------------===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // AST Consumer Implementations.
10 //
11 //===----------------------------------------------------------------------===//
12 
14 #include "clang/AST/AST.h"
15 #include "clang/AST/ASTConsumer.h"
16 #include "clang/AST/ASTContext.h"
18 #include "clang/AST/RecordLayout.h"
20 #include "clang/Basic/Diagnostic.h"
22 #include "llvm/Support/Path.h"
23 #include "llvm/Support/Timer.h"
24 #include "llvm/Support/raw_ostream.h"
25 using namespace clang;
26 
27 //===----------------------------------------------------------------------===//
28 /// ASTPrinter - Pretty-printer and dumper of ASTs
29 
30 namespace {
31  class ASTPrinter : public ASTConsumer,
32  public RecursiveASTVisitor<ASTPrinter> {
34 
35  public:
36  enum Kind { DumpFull, Dump, Print, None };
37  ASTPrinter(std::unique_ptr<raw_ostream> Out, Kind K,
38  ASTDumpOutputFormat Format, StringRef FilterString,
39  bool DumpLookups = false, bool DumpDeclTypes = false)
40  : Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)),
41  OutputKind(K), OutputFormat(Format), FilterString(FilterString),
42  DumpLookups(DumpLookups), DumpDeclTypes(DumpDeclTypes) {}
43 
44  void HandleTranslationUnit(ASTContext &Context) override {
46 
47  if (FilterString.empty())
48  return print(D);
49 
50  TraverseDecl(D);
51  }
52 
53  bool shouldWalkTypesOfTypeLocs() const { return false; }
54 
55  bool TraverseDecl(Decl *D) {
56  if (D && filterMatches(D)) {
57  bool ShowColors = Out.has_colors();
58  if (ShowColors)
59  Out.changeColor(raw_ostream::BLUE);
60 
61  if (OutputFormat == ADOF_Default)
62  Out << (OutputKind != Print ? "Dumping " : "Printing ") << getName(D)
63  << ":\n";
64 
65  if (ShowColors)
66  Out.resetColor();
67  print(D);
68  Out << "\n";
69  // Don't traverse child nodes to avoid output duplication.
70  return true;
71  }
72  return base::TraverseDecl(D);
73  }
74 
75  private:
77  if (isa<NamedDecl>(D))
78  return cast<NamedDecl>(D)->getQualifiedNameAsString();
79  return "";
80  }
81  bool filterMatches(Decl *D) {
82  return getName(D).find(FilterString) != std::string::npos;
83  }
84  void print(Decl *D) {
85  if (DumpLookups) {
86  if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
87  if (DC == DC->getPrimaryContext())
88  DC->dumpLookups(Out, OutputKind != None, OutputKind == DumpFull);
89  else
90  Out << "Lookup map is in primary DeclContext "
91  << DC->getPrimaryContext() << "\n";
92  } else
93  Out << "Not a DeclContext\n";
94  } else if (OutputKind == Print) {
96  D->print(Out, Policy, /*Indentation=*/0, /*PrintInstantiation=*/true);
97  } else if (OutputKind != None) {
98  D->dump(Out, OutputKind == DumpFull, OutputFormat);
99  }
100 
101  if (DumpDeclTypes) {
102  Decl *InnerD = D;
103  if (auto *TD = dyn_cast<TemplateDecl>(D))
104  InnerD = TD->getTemplatedDecl();
105 
106  // FIXME: Support OutputFormat in type dumping.
107  // FIXME: Support combining -ast-dump-decl-types with -ast-dump-lookups.
108  if (auto *VD = dyn_cast<ValueDecl>(InnerD))
109  VD->getType().dump(Out, VD->getASTContext());
110  if (auto *TD = dyn_cast<TypeDecl>(InnerD))
111  TD->getTypeForDecl()->dump(Out, TD->getASTContext());
112  }
113  }
114 
115  raw_ostream &Out;
116  std::unique_ptr<raw_ostream> OwnedOut;
117 
118  /// How to output individual declarations.
119  Kind OutputKind;
120 
121  /// What format should the output take?
122  ASTDumpOutputFormat OutputFormat;
123 
124  /// Which declarations or DeclContexts to display.
125  std::string FilterString;
126 
127  /// Whether the primary output is lookup results or declarations. Individual
128  /// results will be output with a format determined by OutputKind. This is
129  /// incompatible with OutputKind == Print.
130  bool DumpLookups;
131 
132  /// Whether to dump the type for each declaration dumped.
133  bool DumpDeclTypes;
134  };
135 
136  class ASTDeclNodeLister : public ASTConsumer,
137  public RecursiveASTVisitor<ASTDeclNodeLister> {
138  public:
139  ASTDeclNodeLister(raw_ostream *Out = nullptr)
140  : Out(Out ? *Out : llvm::outs()) {}
141 
142  void HandleTranslationUnit(ASTContext &Context) override {
143  TraverseDecl(Context.getTranslationUnitDecl());
144  }
145 
146  bool shouldWalkTypesOfTypeLocs() const { return false; }
147 
148  bool VisitNamedDecl(NamedDecl *D) {
149  D->printQualifiedName(Out);
150  Out << '\n';
151  return true;
152  }
153 
154  private:
155  raw_ostream &Out;
156  };
157 } // end anonymous namespace
158 
159 std::unique_ptr<ASTConsumer>
160 clang::CreateASTPrinter(std::unique_ptr<raw_ostream> Out,
161  StringRef FilterString) {
162  return std::make_unique<ASTPrinter>(std::move(Out), ASTPrinter::Print,
163  ADOF_Default, FilterString);
164 }
165 
166 std::unique_ptr<ASTConsumer>
167 clang::CreateASTDumper(std::unique_ptr<raw_ostream> Out, StringRef FilterString,
168  bool DumpDecls, bool Deserialize, bool DumpLookups,
169  bool DumpDeclTypes, ASTDumpOutputFormat Format) {
170  assert((DumpDecls || Deserialize || DumpLookups) && "nothing to dump");
171  return std::make_unique<ASTPrinter>(
172  std::move(Out),
173  Deserialize ? ASTPrinter::DumpFull
174  : DumpDecls ? ASTPrinter::Dump : ASTPrinter::None,
175  Format, FilterString, DumpLookups, DumpDeclTypes);
176 }
177 
178 std::unique_ptr<ASTConsumer> clang::CreateASTDeclNodeLister() {
179  return std::make_unique<ASTDeclNodeLister>(nullptr);
180 }
181 
182 //===----------------------------------------------------------------------===//
183 /// ASTViewer - AST Visualization
184 
185 namespace {
186  class ASTViewer : public ASTConsumer {
187  ASTContext *Context;
188  public:
189  void Initialize(ASTContext &Context) override {
190  this->Context = &Context;
191  }
192 
193  bool HandleTopLevelDecl(DeclGroupRef D) override {
194  for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
195  HandleTopLevelSingleDecl(*I);
196  return true;
197  }
198 
199  void HandleTopLevelSingleDecl(Decl *D);
200  };
201 }
202 
203 void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
204  if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
205  D->print(llvm::errs());
206 
207  if (Stmt *Body = D->getBody()) {
208  llvm::errs() << '\n';
209  Body->viewAST();
210  llvm::errs() << '\n';
211  }
212  }
213 }
214 
215 std::unique_ptr<ASTConsumer> clang::CreateASTViewer() {
216  return std::make_unique<ASTViewer>();
217 }
clang::Decl::getASTContext
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:414
llvm
Definition: Dominators.h:30
clang::CreateASTViewer
std::unique_ptr< ASTConsumer > CreateASTViewer()
Definition: ASTConsumers.cpp:215
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
clang::DeclContext
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1347
clang::NamedDecl
This represents a decl that may have a name.
Definition: Decl.h:249
clang::DeclGroupRef::begin
iterator begin()
Definition: DeclGroup.h:99
SourceManager.h
clang::PrintingPolicy
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:59
clang::DeclGroupRef::end
iterator end()
Definition: DeclGroup.h:105
print
void print(llvm::raw_ostream &OS, const Pointer &P, ASTContext &Ctx, QualType Ty)
Definition: InterpFrame.cpp:62
clang::ASTContext::getTranslationUnitDecl
TranslationUnitDecl * getTranslationUnitDecl() const
Definition: ASTContext.h:1057
PrettyPrinter.h
clang::TranslationUnitDecl
The top declaration context.
Definition: Decl.h:82
clang::XRayInstrKind::None
constexpr XRayInstrMask None
Definition: XRayInstr.h:38
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:212
Diagnostic.h
clang::RecursiveASTVisitor
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
Definition: RecursiveASTVisitor.h:164
clang::ASTDumpOutputFormat
ASTDumpOutputFormat
Used to specify the format for printing AST dump information.
Definition: ASTDumperUtils.h:21
clang::ASTConsumer
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs.
Definition: ASTConsumer.h:33
ASTContext.h
clang::CreateASTPrinter
std::unique_ptr< ASTConsumer > CreateASTPrinter(std::unique_ptr< raw_ostream > OS, StringRef FilterString)
Definition: ASTConsumers.cpp:160
clang::Decl::dump
void dump() const
Definition: ASTDumper.cpp:186
getName
static std::string getName(const CallEvent &Call)
Definition: ReturnValueChecker.cpp:60
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:89
clang::DeclGroupRef
Definition: DeclGroup.h:51
ASTConsumer.h
clang::CreateASTDumper
std::unique_ptr< ASTConsumer > CreateASTDumper(std::unique_ptr< raw_ostream > OS, StringRef FilterString, bool DumpDecls, bool Deserialize, bool DumpLookups, bool DumpDeclTypes, ASTDumpOutputFormat Format)
Definition: ASTConsumers.cpp:167
clang::ObjCPropertyAttribute::Kind
Kind
Definition: DeclObjCCommon.h:22
clang::Decl::getBody
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
Definition: DeclBase.h:1010
std
Definition: Format.h:4034
clang
Definition: CalledOnceCheck.h:17
RecursiveASTVisitor.h
clang::Stmt
Stmt - This represents one statement.
Definition: Stmt.h:69
clang::Decl::print
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
Definition: DeclPrinter.cpp:126
clang::ADOF_Default
@ ADOF_Default
Definition: ASTDumperUtils.h:22
clang::CreateASTDeclNodeLister
std::unique_ptr< ASTConsumer > CreateASTDeclNodeLister()
Definition: ASTConsumers.cpp:178
clang::NamedDecl::printQualifiedName
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
Definition: Decl.cpp:1589
clang::ASTContext::getLangOpts
const LangOptions & getLangOpts() const
Definition: ASTContext.h:765
RecordLayout.h
AST.h
ASTConsumers.h