clang  8.0.0svn
ASTConsumers.cpp
Go to the documentation of this file.
1 //===--- ASTConsumers.cpp - ASTConsumer implementations -------------------===//
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 // AST Consumer Implementations.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "clang/AST/AST.h"
16 #include "clang/AST/ASTConsumer.h"
17 #include "clang/AST/ASTContext.h"
19 #include "clang/AST/RecordLayout.h"
21 #include "clang/Basic/Diagnostic.h"
23 #include "llvm/Support/Path.h"
24 #include "llvm/Support/Timer.h"
25 #include "llvm/Support/raw_ostream.h"
26 using namespace clang;
27 
28 //===----------------------------------------------------------------------===//
29 /// ASTPrinter - Pretty-printer and dumper of ASTs
30 
31 namespace {
32  class ASTPrinter : public ASTConsumer,
33  public RecursiveASTVisitor<ASTPrinter> {
35 
36  public:
37  enum Kind { DumpFull, Dump, Print, None };
38  ASTPrinter(std::unique_ptr<raw_ostream> Out, Kind K, StringRef FilterString,
39  bool DumpLookups = false)
40  : Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)),
41  OutputKind(K), FilterString(FilterString), DumpLookups(DumpLookups) {}
42 
43  void HandleTranslationUnit(ASTContext &Context) override {
45 
46  if (FilterString.empty())
47  return print(D);
48 
49  TraverseDecl(D);
50  }
51 
52  bool shouldWalkTypesOfTypeLocs() const { return false; }
53 
54  bool TraverseDecl(Decl *D) {
55  if (D && filterMatches(D)) {
56  bool ShowColors = Out.has_colors();
57  if (ShowColors)
58  Out.changeColor(raw_ostream::BLUE);
59  Out << (OutputKind != Print ? "Dumping " : "Printing ") << getName(D)
60  << ":\n";
61  if (ShowColors)
62  Out.resetColor();
63  print(D);
64  Out << "\n";
65  // Don't traverse child nodes to avoid output duplication.
66  return true;
67  }
68  return base::TraverseDecl(D);
69  }
70 
71  private:
72  std::string getName(Decl *D) {
73  if (isa<NamedDecl>(D))
74  return cast<NamedDecl>(D)->getQualifiedNameAsString();
75  return "";
76  }
77  bool filterMatches(Decl *D) {
78  return getName(D).find(FilterString) != std::string::npos;
79  }
80  void print(Decl *D) {
81  if (DumpLookups) {
82  if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
83  if (DC == DC->getPrimaryContext())
84  DC->dumpLookups(Out, OutputKind != None, OutputKind == DumpFull);
85  else
86  Out << "Lookup map is in primary DeclContext "
87  << DC->getPrimaryContext() << "\n";
88  } else
89  Out << "Not a DeclContext\n";
90  } else if (OutputKind == Print) {
92  D->print(Out, Policy, /*Indentation=*/0, /*PrintInstantiation=*/true);
93  } else if (OutputKind != None)
94  D->dump(Out, OutputKind == DumpFull);
95  }
96 
97  raw_ostream &Out;
98  std::unique_ptr<raw_ostream> OwnedOut;
99 
100  /// How to output individual declarations.
101  Kind OutputKind;
102 
103  /// Which declarations or DeclContexts to display.
104  std::string FilterString;
105 
106  /// Whether the primary output is lookup results or declarations. Individual
107  /// results will be output with a format determined by OutputKind. This is
108  /// incompatible with OutputKind == Print.
109  bool DumpLookups;
110  };
111 
112  class ASTDeclNodeLister : public ASTConsumer,
113  public RecursiveASTVisitor<ASTDeclNodeLister> {
114  public:
115  ASTDeclNodeLister(raw_ostream *Out = nullptr)
116  : Out(Out ? *Out : llvm::outs()) {}
117 
118  void HandleTranslationUnit(ASTContext &Context) override {
119  TraverseDecl(Context.getTranslationUnitDecl());
120  }
121 
122  bool shouldWalkTypesOfTypeLocs() const { return false; }
123 
124  bool VisitNamedDecl(NamedDecl *D) {
125  D->printQualifiedName(Out);
126  Out << '\n';
127  return true;
128  }
129 
130  private:
131  raw_ostream &Out;
132  };
133 } // end anonymous namespace
134 
135 std::unique_ptr<ASTConsumer>
136 clang::CreateASTPrinter(std::unique_ptr<raw_ostream> Out,
137  StringRef FilterString) {
138  return llvm::make_unique<ASTPrinter>(std::move(Out), ASTPrinter::Print,
139  FilterString);
140 }
141 
142 std::unique_ptr<ASTConsumer>
143 clang::CreateASTDumper(std::unique_ptr<raw_ostream> Out,
144  StringRef FilterString,
145  bool DumpDecls,
146  bool Deserialize,
147  bool DumpLookups) {
148  assert((DumpDecls || Deserialize || DumpLookups) && "nothing to dump");
149  return llvm::make_unique<ASTPrinter>(std::move(Out),
150  Deserialize ? ASTPrinter::DumpFull :
151  DumpDecls ? ASTPrinter::Dump :
153  FilterString, DumpLookups);
154 }
155 
156 std::unique_ptr<ASTConsumer> clang::CreateASTDeclNodeLister() {
157  return llvm::make_unique<ASTDeclNodeLister>(nullptr);
158 }
159 
160 //===----------------------------------------------------------------------===//
161 /// ASTViewer - AST Visualization
162 
163 namespace {
164  class ASTViewer : public ASTConsumer {
165  ASTContext *Context;
166  public:
167  void Initialize(ASTContext &Context) override {
168  this->Context = &Context;
169  }
170 
171  bool HandleTopLevelDecl(DeclGroupRef D) override {
172  for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
173  HandleTopLevelSingleDecl(*I);
174  return true;
175  }
176 
177  void HandleTopLevelSingleDecl(Decl *D);
178  };
179 }
180 
181 void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
182  if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
183  D->print(llvm::errs());
184 
185  if (Stmt *Body = D->getBody()) {
186  llvm::errs() << '\n';
187  Body->viewAST();
188  llvm::errs() << '\n';
189  }
190  }
191 }
192 
193 std::unique_ptr<ASTConsumer> clang::CreateASTViewer() {
194  return llvm::make_unique<ASTViewer>();
195 }
Defines the clang::ASTContext interface.
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs...
Definition: ASTConsumer.h:34
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:979
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
Definition: Dominators.h:30
Stmt - This represents one statement.
Definition: Stmt.h:66
Defines the SourceManager interface.
iterator end()
Definition: DeclGroup.h:106
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:38
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:2072
iterator begin()
Definition: DeclGroup.h:100
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:1527
Kind
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:376
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:1262
std::unique_ptr< ASTConsumer > CreateASTViewer()
std::unique_ptr< ASTConsumer > CreateASTDeclNodeLister()
TranslationUnitDecl * getTranslationUnitDecl() const
Definition: ASTContext.h:1008
void dump() const
Definition: ASTDumper.cpp:2318
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