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