clang 20.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) {
148 dumpTemplateParameters(D->getTemplateParameters());
149
150 Visit(D->getTemplatedDecl());
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(OS, Context, Context.getDiagnostics().getShowColors());
346 Dumper.Visit(*this, /*Ty=*/Context.getPointerType(Context.CharTy));
347}
348
349//===----------------------------------------------------------------------===//
350// ConceptReference method implementations
351//===----------------------------------------------------------------------===//
352
353LLVM_DUMP_METHOD void ConceptReference::dump() const {
354 dump(llvm::errs());
355}
356
357LLVM_DUMP_METHOD void ConceptReference::dump(raw_ostream &OS) const {
358 auto &Ctx = getNamedConcept()->getASTContext();
359 ASTDumper P(OS, Ctx, Ctx.getDiagnostics().getShowColors());
360 P.Visit(this);
361}
362
363//===----------------------------------------------------------------------===//
364// TemplateName method implementations
365//===----------------------------------------------------------------------===//
366
367// FIXME: These are actually using the TemplateArgument dumper, through
368// an implicit conversion. The dump will claim this is a template argument,
369// which is misleading.
370
371LLVM_DUMP_METHOD void TemplateName::dump() const {
372 ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
373 Dumper.Visit(*this);
374}
375
376LLVM_DUMP_METHOD void TemplateName::dump(llvm::raw_ostream &OS,
377 const ASTContext &Context) const {
378 ASTDumper Dumper(OS, Context, Context.getDiagnostics().getShowColors());
379 Dumper.Visit(*this);
380}
381
382//===----------------------------------------------------------------------===//
383// TemplateArgument method implementations
384//===----------------------------------------------------------------------===//
385
386LLVM_DUMP_METHOD void TemplateArgument::dump() const {
387 ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
388 Dumper.Visit(*this);
389}
390
391LLVM_DUMP_METHOD void TemplateArgument::dump(llvm::raw_ostream &OS,
392 const ASTContext &Context) const {
393 ASTDumper Dumper(OS, Context, Context.getDiagnostics().getShowColors());
394 Dumper.Visit(*this);
395}
This file provides AST data structures related to concepts.
Defines the clang::ASTContext interface.
StringRef P
#define SM(sm)
Definition: Cuda.cpp:83
Defines enum values for all the target-independent builtin functions.
const Decl * D
Expr * E
SourceRange Range
Definition: SemaObjC.cpp:758
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:187
SourceManager & getSourceManager()
Definition: ASTContext.h:721
comments::CommandTraits & getCommentCommandTraits() const
Definition: ASTContext.h:958
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
CanQualType CharTy
Definition: ASTContext.h:1121
const clang::PrintingPolicy & getPrintingPolicy() const
Definition: ASTContext.h:713
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:199
The results of name lookup within a DeclContext.
Definition: DeclBase.h:1369
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1436
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2090
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:2677
bool isTranslationUnit() const
Definition: DeclBase.h:2166
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:1423
Decl::Kind getDeclKind() const
Definition: DeclBase.h:2083
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:1051
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:974
void dump() const
Definition: ASTDumper.cpp:219
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
Definition: DeclBase.h:1039
The name of a declaration.
Declaration of a template function.
Definition: DeclTemplate.h:957
A (possibly-)qualified type.
Definition: Type.h:941
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:386
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:394
void dump() const
Debugging aid that dumps the template name to standard error.
Definition: ASTDumper.cpp:371
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:206
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
Definition: Specifiers.h:202
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition: Specifiers.h:198
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
Definition: Specifiers.h:194
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition: Specifiers.h:191