clang  9.0.0svn
ASTDumper.cpp
Go to the documentation of this file.
1 //===--- ASTDumper.cpp - Dumping implementation for ASTs ------------------===//
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 // This file implements the AST dump methods, which dump out the
10 // AST in a form that exposes type details and other fields.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/DeclLookups.h"
18 #include "clang/Basic/Builtins.h"
19 #include "clang/Basic/Module.h"
21 #include "llvm/Support/raw_ostream.h"
22 using namespace clang;
23 using namespace clang::comments;
24 
25 //===----------------------------------------------------------------------===//
26 // ASTDumper Visitor
27 //===----------------------------------------------------------------------===//
28 
29 namespace {
30 
31 class ASTDumper : public ASTNodeTraverser<ASTDumper, TextNodeDumper> {
32 
33  TextNodeDumper NodeDumper;
34 
35  raw_ostream &OS;
36 
37  const bool ShowColors;
38 
39 public:
40  ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
41  const SourceManager *SM)
42  : ASTDumper(OS, Traits, SM, SM && SM->getDiagnostics().getShowColors()) {}
43 
44  ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
45  const SourceManager *SM, bool ShowColors)
46  : ASTDumper(OS, Traits, SM, ShowColors, LangOptions()) {}
47  ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
48  const SourceManager *SM, bool ShowColors,
49  const PrintingPolicy &PrintPolicy)
50  : NodeDumper(OS, ShowColors, SM, PrintPolicy, Traits), OS(OS),
51  ShowColors(ShowColors) {}
52 
53  TextNodeDumper &doGetNodeDelegate() { return NodeDumper; }
54 
55  void dumpLookups(const DeclContext *DC, bool DumpDecls);
56 
57  template <typename SpecializationDecl>
58  void dumpTemplateDeclSpecialization(const SpecializationDecl *D,
59  bool DumpExplicitInst, bool DumpRefOnly);
60  template <typename TemplateDecl>
61  void dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst);
62 
63  void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
64  void VisitClassTemplateDecl(const ClassTemplateDecl *D);
65  void VisitVarTemplateDecl(const VarTemplateDecl *D);
66 };
67 } // namespace
68 
69 void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
70  NodeDumper.AddChild([=] {
71  OS << "StoredDeclsMap ";
72  NodeDumper.dumpBareDeclRef(cast<Decl>(DC));
73 
74  const DeclContext *Primary = DC->getPrimaryContext();
75  if (Primary != DC) {
76  OS << " primary";
77  NodeDumper.dumpPointer(cast<Decl>(Primary));
78  }
79 
80  bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage();
81 
82  auto Range = getDeserialize()
83  ? Primary->lookups()
84  : Primary->noload_lookups(/*PreserveInternalState=*/true);
85  for (auto I = Range.begin(), E = Range.end(); I != E; ++I) {
86  DeclarationName Name = I.getLookupName();
88 
89  NodeDumper.AddChild([=] {
90  OS << "DeclarationName ";
91  {
92  ColorScope Color(OS, ShowColors, DeclNameColor);
93  OS << '\'' << Name << '\'';
94  }
95 
96  for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end();
97  RI != RE; ++RI) {
98  NodeDumper.AddChild([=] {
99  NodeDumper.dumpBareDeclRef(*RI);
100 
101  if ((*RI)->isHidden())
102  OS << " hidden";
103 
104  // If requested, dump the redecl chain for this lookup.
105  if (DumpDecls) {
106  // Dump earliest decl first.
107  std::function<void(Decl *)> DumpWithPrev = [&](Decl *D) {
108  if (Decl *Prev = D->getPreviousDecl())
109  DumpWithPrev(Prev);
110  Visit(D);
111  };
112  DumpWithPrev(*RI);
113  }
114  });
115  }
116  });
117  }
118 
119  if (HasUndeserializedLookups) {
120  NodeDumper.AddChild([=] {
121  ColorScope Color(OS, ShowColors, UndeserializedColor);
122  OS << "<undeserialized lookups>";
123  });
124  }
125  });
126 }
127 
128 template <typename SpecializationDecl>
129 void ASTDumper::dumpTemplateDeclSpecialization(const SpecializationDecl *D,
130  bool DumpExplicitInst,
131  bool DumpRefOnly) {
132  bool DumpedAny = false;
133  for (const auto *RedeclWithBadType : D->redecls()) {
134  // FIXME: The redecls() range sometimes has elements of a less-specific
135  // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
136  // us TagDecls, and should give CXXRecordDecls).
137  auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
138  if (!Redecl) {
139  // Found the injected-class-name for a class template. This will be dumped
140  // as part of its surrounding class so we don't need to dump it here.
141  assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
142  "expected an injected-class-name");
143  continue;
144  }
145 
146  switch (Redecl->getTemplateSpecializationKind()) {
149  if (!DumpExplicitInst)
150  break;
151  LLVM_FALLTHROUGH;
152  case TSK_Undeclared:
154  if (DumpRefOnly)
155  NodeDumper.dumpDeclRef(Redecl);
156  else
157  Visit(Redecl);
158  DumpedAny = true;
159  break;
161  break;
162  }
163  }
164 
165  // Ensure we dump at least one decl for each specialization.
166  if (!DumpedAny)
167  NodeDumper.dumpDeclRef(D);
168 }
169 
170 template <typename TemplateDecl>
171 void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) {
172  dumpTemplateParameters(D->getTemplateParameters());
173 
174  Visit(D->getTemplatedDecl());
175 
176  for (const auto *Child : D->specializations())
177  dumpTemplateDeclSpecialization(Child, DumpExplicitInst,
178  !D->isCanonicalDecl());
179 }
180 
181 void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
182  // FIXME: We don't add a declaration of a function template specialization
183  // to its context when it's explicitly instantiated, so dump explicit
184  // instantiations when we dump the template itself.
185  dumpTemplateDecl(D, true);
186 }
187 
188 void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
189  dumpTemplateDecl(D, false);
190 }
191 
192 void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
193  dumpTemplateDecl(D, false);
194 }
195 
196 //===----------------------------------------------------------------------===//
197 // Type method implementations
198 //===----------------------------------------------------------------------===//
199 
200 void QualType::dump(const char *msg) const {
201  if (msg)
202  llvm::errs() << msg << ": ";
203  dump();
204 }
205 
206 LLVM_DUMP_METHOD void QualType::dump() const { dump(llvm::errs()); }
207 
208 LLVM_DUMP_METHOD void QualType::dump(llvm::raw_ostream &OS) const {
209  ASTDumper Dumper(OS, nullptr, nullptr);
210  Dumper.Visit(*this);
211 }
212 
213 LLVM_DUMP_METHOD void Type::dump() const { dump(llvm::errs()); }
214 
215 LLVM_DUMP_METHOD void Type::dump(llvm::raw_ostream &OS) const {
216  QualType(this, 0).dump(OS);
217 }
218 
219 //===----------------------------------------------------------------------===//
220 // Decl method implementations
221 //===----------------------------------------------------------------------===//
222 
223 LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); }
224 
225 LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize) const {
226  const ASTContext &Ctx = getASTContext();
227  const SourceManager &SM = Ctx.getSourceManager();
228  ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &SM,
230  P.setDeserialize(Deserialize);
231  P.Visit(this);
232 }
233 
234 LLVM_DUMP_METHOD void Decl::dumpColor() const {
235  const ASTContext &Ctx = getASTContext();
236  ASTDumper P(llvm::errs(), &Ctx.getCommentCommandTraits(),
237  &Ctx.getSourceManager(), /*ShowColors*/ true,
238  Ctx.getPrintingPolicy());
239  P.Visit(this);
240 }
241 
242 LLVM_DUMP_METHOD void DeclContext::dumpLookups() const {
243  dumpLookups(llvm::errs());
244 }
245 
246 LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS,
247  bool DumpDecls,
248  bool Deserialize) const {
249  const DeclContext *DC = this;
250  while (!DC->isTranslationUnit())
251  DC = DC->getParent();
252  ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
253  const SourceManager &SM = Ctx.getSourceManager();
254  ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager(),
256  P.setDeserialize(Deserialize);
257  P.dumpLookups(this, DumpDecls);
258 }
259 
260 //===----------------------------------------------------------------------===//
261 // Stmt method implementations
262 //===----------------------------------------------------------------------===//
263 
264 LLVM_DUMP_METHOD void Stmt::dump(SourceManager &SM) const {
265  dump(llvm::errs(), SM);
266 }
267 
268 LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
269  ASTDumper P(OS, nullptr, &SM);
270  P.Visit(this);
271 }
272 
273 LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS) const {
274  ASTDumper P(OS, nullptr, nullptr);
275  P.Visit(this);
276 }
277 
278 LLVM_DUMP_METHOD void Stmt::dump() const {
279  ASTDumper P(llvm::errs(), nullptr, nullptr);
280  P.Visit(this);
281 }
282 
283 LLVM_DUMP_METHOD void Stmt::dumpColor() const {
284  ASTDumper P(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
285  P.Visit(this);
286 }
287 
288 //===----------------------------------------------------------------------===//
289 // Comment method implementations
290 //===----------------------------------------------------------------------===//
291 
292 LLVM_DUMP_METHOD void Comment::dump() const {
293  dump(llvm::errs(), nullptr, nullptr);
294 }
295 
296 LLVM_DUMP_METHOD void Comment::dump(const ASTContext &Context) const {
297  dump(llvm::errs(), &Context.getCommentCommandTraits(),
298  &Context.getSourceManager());
299 }
300 
301 void Comment::dump(raw_ostream &OS, const CommandTraits *Traits,
302  const SourceManager *SM) const {
303  const FullComment *FC = dyn_cast<FullComment>(this);
304  if (!FC)
305  return;
306  ASTDumper D(OS, Traits, SM);
307  D.Visit(FC, FC);
308 }
309 
310 LLVM_DUMP_METHOD void Comment::dumpColor() const {
311  const FullComment *FC = dyn_cast<FullComment>(this);
312  if (!FC)
313  return;
314  ASTDumper D(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
315  D.Visit(FC, FC);
316 }
void dump() const
Definition: ASTDumper.cpp:213
Defines the clang::ASTContext interface.
A (possibly-)qualified type.
Definition: Type.h:639
Defines the SourceManager interface.
Defines the clang::Module class, which describes a module in the source code.
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
StringRef P
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
Definition: DeclTemplate.h:452
Decl * getPreviousDecl()
Retrieve the previous declaration that declares the same entity as this declaration, or NULL if there is no previous declaration.
Definition: DeclBase.h:955
Declaration of a variable template.
bool hasExternalVisibleStorage() const
Whether this DeclContext has external storage containing additional declarations that are visible in ...
Definition: DeclBase.h:2332
lookups_range noload_lookups(bool PreserveInternalState) const
Definition: DeclLookups.h:89
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:37
void dumpColor() const
Definition: ASTDumper.cpp:234
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:154
The results of name lookup within a DeclContext.
Definition: DeclBase.h:1189
void dumpLookups() const
Definition: ASTDumper.cpp:242
void dumpColor() const
dumpColor - same as dump(), but forces color highlighting.
Definition: ASTDumper.cpp:283
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:49
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
const clang::PrintingPolicy & getPrintingPolicy() const
Definition: ASTContext.h:653
static const TerminalColor DeclNameColor
DiagnosticsEngine & getDiagnostics() const
lookups_range lookups() const
Definition: DeclLookups.h:75
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:431
bool isCanonicalDecl() const
Whether this particular Decl is a canonical one.
Definition: DeclBase.h:878
comments::CommandTraits & getCommentCommandTraits() const
Definition: ASTContext.h:874
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1760
This template specialization was implicitly instantiated from a template.
Definition: Specifiers.h:151
const SourceManager & SM
Definition: Format.cpp:1499
This class provides information about commands that can be used in comments.
ASTNodeTraverser traverses the Clang AST for dumping purposes.
This template specialization was instantiated from a template due to an explicit instantiation defini...
Definition: Specifiers.h:163
This template specialization was formed from a template-id but has not yet been declared, defined, or instantiated.
Definition: Specifiers.h:148
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:1265
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:398
void dump() const
Definition: ASTDumper.cpp:206
This template specialization was instantiated from a template due to an explicit instantiation declar...
Definition: Specifiers.h:159
The name of a declaration.
Indicates that the tracking object is a descendant of a referenced-counted OSObject, used in the Darwin kernel.
void dump() const
Dumps the specified AST fragment and all subtrees to llvm::errs().
Definition: ASTDumper.cpp:278
This template specialization was declared or defined by an explicit specialization (C++ [temp...
Definition: Specifiers.h:155
SourceManager & getSourceManager()
Definition: ASTContext.h:661
Declaration of a class template.
void dump(const char *s) const
Definition: ASTDumper.cpp:200
void dump() const
Definition: ASTDumper.cpp:223
DeclContext * getPrimaryContext()
getPrimaryContext - There may be many different declarations of the same entity (including forward de...
Definition: DeclBase.cpp:1161
bool isTranslationUnit() const
Definition: DeclBase.h:1831
This class handles loading and caching of source files into memory.
Defines enum values for all the target-independent builtin functions.
Declaration of a template function.
Definition: DeclTemplate.h:968
A full comment attached to a declaration, contains block content.
Definition: Comment.h:1091
static const TerminalColor UndeserializedColor