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