clang 19.0.0git
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/ASTDumper.h"
21#include "llvm/Support/raw_ostream.h"
22
23using namespace clang;
24using namespace clang::comments;
25
27 NodeDumper.AddChild([=] {
28 if (!DC) {
29 ColorScope Color(OS, ShowColors, NullColor);
30 OS << "<<<NULL>>>";
31 return;
32 }
33 // An invalid DeclContext is one for which a dyn_cast() from a DeclContext
34 // pointer to a Decl pointer would fail an assertion or otherwise fall prey
35 // to undefined behavior as a result of an invalid associated DeclKind.
36 // Such invalidity is not supposed to happen of course, but, when it does,
37 // the information provided below is intended to provide some hints about
38 // what might have gone awry.
39 {
40 ColorScope Color(OS, ShowColors, DeclKindNameColor);
41 OS << "DeclContext";
42 }
43 NodeDumper.dumpPointer(DC);
44 OS << " <";
45 {
46 ColorScope Color(OS, ShowColors, DeclNameColor);
47 OS << "unrecognized Decl kind " << (unsigned)DC->getDeclKind();
48 }
49 OS << ">";
50 });
51}
52
53void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
54 NodeDumper.AddChild([=] {
55 OS << "StoredDeclsMap ";
56 NodeDumper.dumpBareDeclRef(cast<Decl>(DC));
57
58 const DeclContext *Primary = DC->getPrimaryContext();
59 if (Primary != DC) {
60 OS << " primary";
61 NodeDumper.dumpPointer(cast<Decl>(Primary));
62 }
63
64 bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage();
65
66 auto Range = getDeserialize()
67 ? Primary->lookups()
68 : Primary->noload_lookups(/*PreserveInternalState=*/true);
69 for (auto I = Range.begin(), E = Range.end(); I != E; ++I) {
70 DeclarationName Name = I.getLookupName();
72
73 NodeDumper.AddChild([=] {
74 OS << "DeclarationName ";
75 {
76 ColorScope Color(OS, ShowColors, DeclNameColor);
77 OS << '\'' << Name << '\'';
78 }
79
80 for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end();
81 RI != RE; ++RI) {
82 NodeDumper.AddChild([=] {
83 NodeDumper.dumpBareDeclRef(*RI);
84
85 if (!(*RI)->isUnconditionallyVisible())
86 OS << " hidden";
87
88 // If requested, dump the redecl chain for this lookup.
89 if (DumpDecls) {
90 // Dump earliest decl first.
91 std::function<void(Decl *)> DumpWithPrev = [&](Decl *D) {
92 if (Decl *Prev = D->getPreviousDecl())
93 DumpWithPrev(Prev);
94 Visit(D);
95 };
96 DumpWithPrev(*RI);
97 }
98 });
99 }
100 });
101 }
102
103 if (HasUndeserializedLookups) {
104 NodeDumper.AddChild([=] {
105 ColorScope Color(OS, ShowColors, UndeserializedColor);
106 OS << "<undeserialized lookups>";
107 });
108 }
109 });
110}
111
112template <typename SpecializationDecl>
113void ASTDumper::dumpTemplateDeclSpecialization(const SpecializationDecl *D,
114 bool DumpExplicitInst,
115 bool DumpRefOnly) {
116 bool DumpedAny = false;
117 for (const auto *RedeclWithBadType : D->redecls()) {
118 // FIXME: The redecls() range sometimes has elements of a less-specific
119 // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
120 // us TagDecls, and should give CXXRecordDecls).
121 auto *Redecl = cast<SpecializationDecl>(RedeclWithBadType);
122 switch (Redecl->getTemplateSpecializationKind()) {
125 if (!DumpExplicitInst)
126 break;
127 [[fallthrough]];
128 case TSK_Undeclared:
130 if (DumpRefOnly)
131 NodeDumper.dumpDeclRef(Redecl);
132 else
133 Visit(Redecl);
134 DumpedAny = true;
135 break;
137 break;
138 }
139 }
140
141 // Ensure we dump at least one decl for each specialization.
142 if (!DumpedAny)
143 NodeDumper.dumpDeclRef(D);
144}
145
146template <typename TemplateDecl>
147void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) {
149
151
152 if (GetTraversalKind() == TK_AsIs) {
153 for (const auto *Child : D->specializations())
154 dumpTemplateDeclSpecialization(Child, DumpExplicitInst,
155 !D->isCanonicalDecl());
156 }
157}
158
160 // FIXME: We don't add a declaration of a function template specialization
161 // to its context when it's explicitly instantiated, so dump explicit
162 // instantiations when we dump the template itself.
163 dumpTemplateDecl(D, true);
164}
165
167 dumpTemplateDecl(D, false);
168}
169
171 dumpTemplateDecl(D, false);
172}
173
174//===----------------------------------------------------------------------===//
175// Type method implementations
176//===----------------------------------------------------------------------===//
177
178void QualType::dump(const char *msg) const {
179 if (msg)
180 llvm::errs() << msg << ": ";
181 dump();
182}
183
184LLVM_DUMP_METHOD void QualType::dump() const {
185 ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
186 Dumper.Visit(*this);
187}
188
189LLVM_DUMP_METHOD void QualType::dump(llvm::raw_ostream &OS,
190 const ASTContext &Context) const {
191 ASTDumper Dumper(OS, Context, Context.getDiagnostics().getShowColors());
192 Dumper.Visit(*this);
193}
194
195LLVM_DUMP_METHOD void Type::dump() const { QualType(this, 0).dump(); }
196
197LLVM_DUMP_METHOD void Type::dump(llvm::raw_ostream &OS,
198 const ASTContext &Context) const {
199 QualType(this, 0).dump(OS, Context);
200}
201
202//===----------------------------------------------------------------------===//
203// TypeLoc method implementations
204//===----------------------------------------------------------------------===//
205
206LLVM_DUMP_METHOD void TypeLoc::dump() const {
207 ASTDumper(llvm::errs(), /*ShowColors=*/false).Visit(*this);
208}
209
210LLVM_DUMP_METHOD void TypeLoc::dump(llvm::raw_ostream &OS,
211 const ASTContext &Context) const {
212 ASTDumper(OS, Context, Context.getDiagnostics().getShowColors()).Visit(*this);
213}
214
215//===----------------------------------------------------------------------===//
216// Decl method implementations
217//===----------------------------------------------------------------------===//
218
219LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); }
220
221LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize,
222 ASTDumpOutputFormat Format) const {
223 ASTContext &Ctx = getASTContext();
224 const SourceManager &SM = Ctx.getSourceManager();
225
226 if (ADOF_JSON == Format) {
227 JSONDumper P(OS, SM, Ctx, Ctx.getPrintingPolicy(),
229 (void)Deserialize; // FIXME?
230 P.Visit(this);
231 } else {
232 ASTDumper P(OS, Ctx, Ctx.getDiagnostics().getShowColors());
233 P.setDeserialize(Deserialize);
234 P.Visit(this);
235 }
236}
237
238LLVM_DUMP_METHOD void Decl::dumpColor() const {
239 const ASTContext &Ctx = getASTContext();
240 ASTDumper P(llvm::errs(), Ctx, /*ShowColors=*/true);
241 P.Visit(this);
242}
243
244LLVM_DUMP_METHOD void DeclContext::dumpAsDecl() const {
245 dumpAsDecl(nullptr);
246}
247
248LLVM_DUMP_METHOD void DeclContext::dumpAsDecl(const ASTContext *Ctx) const {
249 // By design, DeclContext is required to be a base class of some class that
250 // derives from Decl. Thus, it should always be possible to dyn_cast() from
251 // a DeclContext pointer to a Decl pointer and Decl::castFromDeclContext()
252 // asserts that to be the case. Since this function is intended for use in a
253 // debugger, it performs an additional check in order to prevent a failed
254 // cast and assertion. If that check fails, then the (invalid) DeclContext
255 // is dumped with an indication of its invalidity.
256 if (hasValidDeclKind()) {
257 const auto *D = cast<Decl>(this);
258 D->dump();
259 } else {
260 // If an ASTContext is not available, a less capable ASTDumper is
261 // constructed for which color diagnostics are, regrettably, disabled.
262 ASTDumper P = Ctx ? ASTDumper(llvm::errs(), *Ctx,
264 : ASTDumper(llvm::errs(), /*ShowColors*/ false);
265 P.dumpInvalidDeclContext(this);
266 }
267}
268
269LLVM_DUMP_METHOD void DeclContext::dumpLookups() const {
270 dumpLookups(llvm::errs());
271}
272
273LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS,
274 bool DumpDecls,
275 bool Deserialize) const {
276 const DeclContext *DC = this;
277 while (!DC->isTranslationUnit())
278 DC = DC->getParent();
279 const ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
280 ASTDumper P(OS, Ctx, Ctx.getDiagnostics().getShowColors());
281 P.setDeserialize(Deserialize);
282 P.dumpLookups(this, DumpDecls);
283}
284
285//===----------------------------------------------------------------------===//
286// Stmt method implementations
287//===----------------------------------------------------------------------===//
288
289LLVM_DUMP_METHOD void Stmt::dump() const {
290 ASTDumper P(llvm::errs(), /*ShowColors=*/false);
291 P.Visit(this);
292}
293
294LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS,
295 const ASTContext &Context) const {
296 ASTDumper P(OS, Context, Context.getDiagnostics().getShowColors());
297 P.Visit(this);
298}
299
300LLVM_DUMP_METHOD void Stmt::dumpColor() const {
301 ASTDumper P(llvm::errs(), /*ShowColors=*/true);
302 P.Visit(this);
303}
304
305//===----------------------------------------------------------------------===//
306// Comment method implementations
307//===----------------------------------------------------------------------===//
308
309LLVM_DUMP_METHOD void Comment::dump() const {
310 const auto *FC = dyn_cast<FullComment>(this);
311 if (!FC)
312 return;
313 ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
314 Dumper.Visit(FC, FC);
315}
316
317LLVM_DUMP_METHOD void Comment::dump(raw_ostream &OS,
318 const ASTContext &Context) const {
319 const auto *FC = dyn_cast<FullComment>(this);
320 if (!FC)
321 return;
322 ASTDumper Dumper(OS, Context, Context.getDiagnostics().getShowColors());
323 Dumper.Visit(FC, FC);
324}
325
326LLVM_DUMP_METHOD void Comment::dumpColor() const {
327 const auto *FC = dyn_cast<FullComment>(this);
328 if (!FC)
329 return;
330 ASTDumper Dumper(llvm::errs(), /*ShowColors=*/true);
331 Dumper.Visit(FC, FC);
332}
333
334//===----------------------------------------------------------------------===//
335// APValue method implementations
336//===----------------------------------------------------------------------===//
337
338LLVM_DUMP_METHOD void APValue::dump() const {
339 ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
340 Dumper.Visit(*this, /*Ty=*/QualType());
341}
342
343LLVM_DUMP_METHOD void APValue::dump(raw_ostream &OS,
344 const ASTContext &Context) const {
345 ASTDumper Dumper(llvm::errs(), Context,
346 Context.getDiagnostics().getShowColors());
347 Dumper.Visit(*this, /*Ty=*/Context.getPointerType(Context.CharTy));
348}
349
350//===----------------------------------------------------------------------===//
351// ConceptReference method implementations
352//===----------------------------------------------------------------------===//
353
354LLVM_DUMP_METHOD void ConceptReference::dump() const {
355 dump(llvm::errs());
356}
357
358LLVM_DUMP_METHOD void ConceptReference::dump(raw_ostream &OS) const {
359 auto &Ctx = getNamedConcept()->getASTContext();
360 ASTDumper P(OS, Ctx, Ctx.getDiagnostics().getShowColors());
361 P.Visit(this);
362}
363
364//===----------------------------------------------------------------------===//
365// TemplateName method implementations
366//===----------------------------------------------------------------------===//
367
368// FIXME: These are actually using the TemplateArgument dumper, through
369// an implicit conversion. The dump will claim this is a template argument,
370// which is misleading.
371
372LLVM_DUMP_METHOD void TemplateName::dump() const {
373 ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
374 Dumper.Visit(*this);
375}
376
377LLVM_DUMP_METHOD void TemplateName::dump(llvm::raw_ostream &OS,
378 const ASTContext &Context) const {
379 ASTDumper Dumper(OS, Context, Context.getDiagnostics().getShowColors());
380 Dumper.Visit(*this);
381}
382
383//===----------------------------------------------------------------------===//
384// TemplateArgument method implementations
385//===----------------------------------------------------------------------===//
386
387LLVM_DUMP_METHOD void TemplateArgument::dump() const {
388 ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
389 Dumper.Visit(*this);
390}
391
392LLVM_DUMP_METHOD void TemplateArgument::dump(llvm::raw_ostream &OS,
393 const ASTContext &Context) const {
394 ASTDumper Dumper(OS, Context, Context.getDiagnostics().getShowColors());
395 Dumper.Visit(*this);
396}
This file provides AST data structures related to concepts.
Defines the clang::ASTContext interface.
StringRef P
#define SM(sm)
Definition: Cuda.cpp:84
Defines enum values for all the target-independent builtin functions.
SourceRange Range
Definition: SemaObjC.cpp:757
Defines the SourceManager interface.
void dump() const
Definition: ASTDumper.cpp:338
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:185
SourceManager & getSourceManager()
Definition: ASTContext.h:708
comments::CommandTraits & getCommentCommandTraits() const
Definition: ASTContext.h:939
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
CanQualType CharTy
Definition: ASTContext.h:1096
const clang::PrintingPolicy & getPrintingPolicy() const
Definition: ASTContext.h:700
DiagnosticsEngine & getDiagnostics() const
void dumpTemplateDeclSpecialization(const SpecializationDecl *D, bool DumpExplicitInst, bool DumpRefOnly)
Definition: ASTDumper.cpp:113
void dumpLookups(const DeclContext *DC, bool DumpDecls)
Definition: ASTDumper.cpp:53
void dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst)
Definition: ASTDumper.cpp:147
void dumpInvalidDeclContext(const DeclContext *DC)
Definition: ASTDumper.cpp:26
void VisitVarTemplateDecl(const VarTemplateDecl *D)
Definition: ASTDumper.cpp:170
void VisitClassTemplateDecl(const ClassTemplateDecl *D)
Definition: ASTDumper.cpp:166
void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D)
Definition: ASTDumper.cpp:159
void Visit(const Decl *D, bool VisitLocs=false)
void dumpTemplateParameters(const TemplateParameterList *TPL)
Declaration of a class template.
ConceptDecl * getNamedConcept() const
Definition: ASTConcept.h:203
The results of name lookup within a DeclContext.
Definition: DeclBase.h:1368
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1435
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2065
void dumpAsDecl() const
Definition: ASTDumper.cpp:244
lookups_range noload_lookups(bool PreserveInternalState) const
Definition: DeclLookups.h:89
void dumpLookups() const
Definition: ASTDumper.cpp:269
bool hasExternalVisibleStorage() const
Whether this DeclContext has external storage containing additional declarations that are visible in ...
Definition: DeclBase.h:2652
bool isTranslationUnit() const
Definition: DeclBase.h:2141
lookups_range lookups() const
Definition: DeclLookups.h:75
bool hasValidDeclKind() const
Definition: DeclBase.cpp:177
DeclContext * getPrimaryContext()
getPrimaryContext - There may be many different declarations of the same entity (including forward de...
Definition: DeclBase.cpp:1403
Decl::Kind getDeclKind() const
Definition: DeclBase.h:2058
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
Decl * getPreviousDecl()
Retrieve the previous declaration that declares the same entity as this declaration,...
Definition: DeclBase.h:1050
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:523
void dumpColor() const
Definition: ASTDumper.cpp:238
bool isCanonicalDecl() const
Whether this particular Decl is a canonical one.
Definition: DeclBase.h:973
void dump() const
Definition: ASTDumper.cpp:219
The name of a declaration.
Declaration of a template function.
Definition: DeclTemplate.h:957
A (possibly-)qualified type.
Definition: Type.h:940
void dump() const
Definition: ASTDumper.cpp:184
This class handles loading and caching of source files into memory.
void dump() const
Dumps the specified AST fragment and all subtrees to llvm::errs().
Definition: ASTDumper.cpp:289
void dumpColor() const
dumpColor - same as dump(), but forces color highlighting.
Definition: ASTDumper.cpp:300
void dump() const
Debugging aid that dumps the template argument to standard error.
Definition: ASTDumper.cpp:387
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:394
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
Definition: DeclTemplate.h:426
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:413
void dump() const
Debugging aid that dumps the template name to standard error.
Definition: ASTDumper.cpp:372
void dumpPointer(const void *Ptr)
void dumpDeclRef(const Decl *D, StringRef Label={})
void dumpBareDeclRef(const Decl *D)
void AddChild(Fn DoAddChild)
Add a child of the current node. Calls DoAddChild without arguments.
void dump() const
Definition: ASTDumper.cpp:206
void dump() const
Definition: ASTDumper.cpp:195
Declaration of a variable template.
The JSON file list parser is used to communicate input to InstallAPI.
static const TerminalColor NullColor
ASTDumpOutputFormat
Used to specify the format for printing AST dump information.
static const TerminalColor DeclNameColor
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
static const TerminalColor UndeserializedColor
static const TerminalColor DeclKindNameColor
@ TK_AsIs
Will traverse all child nodes.
Definition: ASTTypeTraits.h:40
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
Definition: Specifiers.h:203
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
Definition: Specifiers.h:199
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition: Specifiers.h:195
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
Definition: Specifiers.h:191
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition: Specifiers.h:188