clang  9.0.0svn
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, StringRef FilterString,
38  bool DumpLookups = false)
39  : Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)),
40  OutputKind(K), FilterString(FilterString), DumpLookups(DumpLookups) {}
41 
42  void HandleTranslationUnit(ASTContext &Context) override {
44 
45  if (FilterString.empty())
46  return print(D);
47 
48  TraverseDecl(D);
49  }
50 
51  bool shouldWalkTypesOfTypeLocs() const { return false; }
52 
53  bool TraverseDecl(Decl *D) {
54  if (D && filterMatches(D)) {
55  bool ShowColors = Out.has_colors();
56  if (ShowColors)
57  Out.changeColor(raw_ostream::BLUE);
58  Out << (OutputKind != Print ? "Dumping " : "Printing ") << getName(D)
59  << ":\n";
60  if (ShowColors)
61  Out.resetColor();
62  print(D);
63  Out << "\n";
64  // Don't traverse child nodes to avoid output duplication.
65  return true;
66  }
67  return base::TraverseDecl(D);
68  }
69 
70  private:
71  std::string getName(Decl *D) {
72  if (isa<NamedDecl>(D))
73  return cast<NamedDecl>(D)->getQualifiedNameAsString();
74  return "";
75  }
76  bool filterMatches(Decl *D) {
77  return getName(D).find(FilterString) != std::string::npos;
78  }
79  void print(Decl *D) {
80  if (DumpLookups) {
81  if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
82  if (DC == DC->getPrimaryContext())
83  DC->dumpLookups(Out, OutputKind != None, OutputKind == DumpFull);
84  else
85  Out << "Lookup map is in primary DeclContext "
86  << DC->getPrimaryContext() << "\n";
87  } else
88  Out << "Not a DeclContext\n";
89  } else if (OutputKind == Print) {
91  D->print(Out, Policy, /*Indentation=*/0, /*PrintInstantiation=*/true);
92  } else if (OutputKind != None)
93  D->dump(Out, OutputKind == DumpFull);
94  }
95 
96  raw_ostream &Out;
97  std::unique_ptr<raw_ostream> OwnedOut;
98 
99  /// How to output individual declarations.
100  Kind OutputKind;
101 
102  /// Which declarations or DeclContexts to display.
103  std::string FilterString;
104 
105  /// Whether the primary output is lookup results or declarations. Individual
106  /// results will be output with a format determined by OutputKind. This is
107  /// incompatible with OutputKind == Print.
108  bool DumpLookups;
109  };
110 
111  class ASTDeclNodeLister : public ASTConsumer,
112  public RecursiveASTVisitor<ASTDeclNodeLister> {
113  public:
114  ASTDeclNodeLister(raw_ostream *Out = nullptr)
115  : Out(Out ? *Out : llvm::outs()) {}
116 
117  void HandleTranslationUnit(ASTContext &Context) override {
118  TraverseDecl(Context.getTranslationUnitDecl());
119  }
120 
121  bool shouldWalkTypesOfTypeLocs() const { return false; }
122 
123  bool VisitNamedDecl(NamedDecl *D) {
124  D->printQualifiedName(Out);
125  Out << '\n';
126  return true;
127  }
128 
129  private:
130  raw_ostream &Out;
131  };
132 } // end anonymous namespace
133 
134 std::unique_ptr<ASTConsumer>
135 clang::CreateASTPrinter(std::unique_ptr<raw_ostream> Out,
136  StringRef FilterString) {
137  return llvm::make_unique<ASTPrinter>(std::move(Out), ASTPrinter::Print,
138  FilterString);
139 }
140 
141 std::unique_ptr<ASTConsumer>
142 clang::CreateASTDumper(std::unique_ptr<raw_ostream> Out,
143  StringRef FilterString,
144  bool DumpDecls,
145  bool Deserialize,
146  bool DumpLookups) {
147  assert((DumpDecls || Deserialize || DumpLookups) && "nothing to dump");
148  return llvm::make_unique<ASTPrinter>(std::move(Out),
149  Deserialize ? ASTPrinter::DumpFull :
150  DumpDecls ? ASTPrinter::Dump :
152  FilterString, DumpLookups);
153 }
154 
155 std::unique_ptr<ASTConsumer> clang::CreateASTDeclNodeLister() {
156  return llvm::make_unique<ASTDeclNodeLister>(nullptr);
157 }
158 
159 //===----------------------------------------------------------------------===//
160 /// ASTViewer - AST Visualization
161 
162 namespace {
163  class ASTViewer : public ASTConsumer {
164  ASTContext *Context;
165  public:
166  void Initialize(ASTContext &Context) override {
167  this->Context = &Context;
168  }
169 
170  bool HandleTopLevelDecl(DeclGroupRef D) override {
171  for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
172  HandleTopLevelSingleDecl(*I);
173  return true;
174  }
175 
176  void HandleTopLevelSingleDecl(Decl *D);
177  };
178 }
179 
180 void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
181  if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
182  D->print(llvm::errs());
183 
184  if (Stmt *Body = D->getBody()) {
185  llvm::errs() << '\n';
186  Body->viewAST();
187  llvm::errs() << '\n';
188  }
189  }
190 }
191 
192 std::unique_ptr<ASTConsumer> clang::CreateASTViewer() {
193  return llvm::make_unique<ASTViewer>();
194 }
Defines the clang::ASTContext interface.
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs...
Definition: ASTConsumer.h:33
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:982
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
Definition: Dominators.h:29
Stmt - This represents one statement.
Definition: Stmt.h:65
Defines the SourceManager interface.
iterator end()
Definition: DeclGroup.h:105
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:87
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:37
std::string getName(ArrayRef< StringRef > Parts) const
Get the platform-specific name separator.
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:154
Definition: Format.h:2222
iterator begin()
Definition: DeclGroup.h:99
Defines the Diagnostic-related interfaces.
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
std::unique_ptr< ASTConsumer > CreateASTDumper(std::unique_ptr< raw_ostream > OS, StringRef FilterString, bool DumpDecls, bool Deserialize, bool DumpLookups)
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:1526
Kind
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:375
Dataflow Directional Tag Classes.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1266
std::unique_ptr< ASTConsumer > CreateASTViewer()
std::unique_ptr< ASTConsumer > CreateASTDeclNodeLister()
TranslationUnitDecl * getTranslationUnitDecl() const
Definition: ASTContext.h:1008
void dump() const
Definition: ASTDumper.cpp:223
The top declaration context.
Definition: Decl.h:107
std::unique_ptr< ASTConsumer > CreateASTPrinter(std::unique_ptr< raw_ostream > OS, StringRef FilterString)
This represents a decl that may have a name.
Definition: Decl.h:248
const LangOptions & getLangOpts() const
Definition: ASTContext.h:706