clang 18.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// Decl method implementations
205//===----------------------------------------------------------------------===//
206
207LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); }
208
209LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize,
210 ASTDumpOutputFormat Format) const {
211 ASTContext &Ctx = getASTContext();
212 const SourceManager &SM = Ctx.getSourceManager();
213
214 if (ADOF_JSON == Format) {
215 JSONDumper P(OS, SM, Ctx, Ctx.getPrintingPolicy(),
217 (void)Deserialize; // FIXME?
218 P.Visit(this);
219 } else {
220 ASTDumper P(OS, Ctx, Ctx.getDiagnostics().getShowColors());
221 P.setDeserialize(Deserialize);
222 P.Visit(this);
223 }
224}
225
226LLVM_DUMP_METHOD void Decl::dumpColor() const {
227 const ASTContext &Ctx = getASTContext();
228 ASTDumper P(llvm::errs(), Ctx, /*ShowColors=*/true);
229 P.Visit(this);
230}
231
232LLVM_DUMP_METHOD void DeclContext::dumpAsDecl() const {
233 dumpAsDecl(nullptr);
234}
235
236LLVM_DUMP_METHOD void DeclContext::dumpAsDecl(const ASTContext *Ctx) const {
237 // By design, DeclContext is required to be a base class of some class that
238 // derives from Decl. Thus, it should always be possible to dyn_cast() from
239 // a DeclContext pointer to a Decl pointer and Decl::castFromDeclContext()
240 // asserts that to be the case. Since this function is intended for use in a
241 // debugger, it performs an additional check in order to prevent a failed
242 // cast and assertion. If that check fails, then the (invalid) DeclContext
243 // is dumped with an indication of its invalidity.
244 if (hasValidDeclKind()) {
245 const auto *D = cast<Decl>(this);
246 D->dump();
247 } else {
248 // If an ASTContext is not available, a less capable ASTDumper is
249 // constructed for which color diagnostics are, regrettably, disabled.
250 ASTDumper P = Ctx ? ASTDumper(llvm::errs(), *Ctx,
252 : ASTDumper(llvm::errs(), /*ShowColors*/ false);
253 P.dumpInvalidDeclContext(this);
254 }
255}
256
257LLVM_DUMP_METHOD void DeclContext::dumpLookups() const {
258 dumpLookups(llvm::errs());
259}
260
261LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS,
262 bool DumpDecls,
263 bool Deserialize) const {
264 const DeclContext *DC = this;
265 while (!DC->isTranslationUnit())
266 DC = DC->getParent();
267 const ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
268 ASTDumper P(OS, Ctx, Ctx.getDiagnostics().getShowColors());
269 P.setDeserialize(Deserialize);
270 P.dumpLookups(this, DumpDecls);
271}
272
273//===----------------------------------------------------------------------===//
274// Stmt method implementations
275//===----------------------------------------------------------------------===//
276
277LLVM_DUMP_METHOD void Stmt::dump() const {
278 ASTDumper P(llvm::errs(), /*ShowColors=*/false);
279 P.Visit(this);
280}
281
282LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS,
283 const ASTContext &Context) const {
284 ASTDumper P(OS, Context, Context.getDiagnostics().getShowColors());
285 P.Visit(this);
286}
287
288LLVM_DUMP_METHOD void Stmt::dumpColor() const {
289 ASTDumper P(llvm::errs(), /*ShowColors=*/true);
290 P.Visit(this);
291}
292
293//===----------------------------------------------------------------------===//
294// Comment method implementations
295//===----------------------------------------------------------------------===//
296
297LLVM_DUMP_METHOD void Comment::dump() const {
298 const auto *FC = dyn_cast<FullComment>(this);
299 if (!FC)
300 return;
301 ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
302 Dumper.Visit(FC, FC);
303}
304
305LLVM_DUMP_METHOD void Comment::dump(raw_ostream &OS,
306 const ASTContext &Context) const {
307 const auto *FC = dyn_cast<FullComment>(this);
308 if (!FC)
309 return;
310 ASTDumper Dumper(OS, Context, Context.getDiagnostics().getShowColors());
311 Dumper.Visit(FC, FC);
312}
313
314LLVM_DUMP_METHOD void Comment::dumpColor() const {
315 const auto *FC = dyn_cast<FullComment>(this);
316 if (!FC)
317 return;
318 ASTDumper Dumper(llvm::errs(), /*ShowColors=*/true);
319 Dumper.Visit(FC, FC);
320}
321
322//===----------------------------------------------------------------------===//
323// APValue method implementations
324//===----------------------------------------------------------------------===//
325
326LLVM_DUMP_METHOD void APValue::dump() const {
327 ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
328 Dumper.Visit(*this, /*Ty=*/QualType());
329}
330
331LLVM_DUMP_METHOD void APValue::dump(raw_ostream &OS,
332 const ASTContext &Context) const {
333 ASTDumper Dumper(llvm::errs(), Context,
334 Context.getDiagnostics().getShowColors());
335 Dumper.Visit(*this, /*Ty=*/Context.getPointerType(Context.CharTy));
336}
337
338//===----------------------------------------------------------------------===//
339// ConceptReference method implementations
340//===----------------------------------------------------------------------===//
341
342LLVM_DUMP_METHOD void ConceptReference::dump() const {
343 dump(llvm::errs());
344}
345
346LLVM_DUMP_METHOD void ConceptReference::dump(raw_ostream &OS) const {
347 auto &Ctx = getNamedConcept()->getASTContext();
348 ASTDumper P(OS, Ctx, Ctx.getDiagnostics().getShowColors());
349 P.Visit(this);
350}
This file provides AST data structures related to concepts.
Defines the clang::ASTContext interface.
StringRef P
#define SM(sm)
Definition: Cuda.cpp:80
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:326
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:691
comments::CommandTraits & getCommentCommandTraits() const
Definition: ASTContext.h:922
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
CanQualType CharTy
Definition: ASTContext.h:1079
const clang::PrintingPolicy & getPrintingPolicy() const
Definition: ASTContext.h:683
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 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:1347
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1409
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1951
void dumpAsDecl() const
Definition: ASTDumper.cpp:232
lookups_range noload_lookups(bool PreserveInternalState) const
Definition: DeclLookups.h:89
void dumpLookups() const
Definition: ASTDumper.cpp:257
bool hasExternalVisibleStorage() const
Whether this DeclContext has external storage containing additional declarations that are visible in ...
Definition: DeclBase.h:2533
bool isTranslationUnit() const
Definition: DeclBase.h:2026
lookups_range lookups() const
Definition: DeclLookups.h:75
bool hasValidDeclKind() const
Definition: DeclBase.cpp:156
DeclContext * getPrimaryContext()
getPrimaryContext - There may be many different declarations of the same entity (including forward de...
Definition: DeclBase.cpp:1299
Decl::Kind getDeclKind() const
Definition: DeclBase.h:1944
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
Decl * getPreviousDecl()
Retrieve the previous declaration that declares the same entity as this declaration,...
Definition: DeclBase.h:1029
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:429
void dumpColor() const
Definition: ASTDumper.cpp:226
bool isCanonicalDecl() const
Whether this particular Decl is a canonical one.
Definition: DeclBase.h:952
void dump() const
Definition: ASTDumper.cpp:207
The name of a declaration.
Declaration of a template function.
A (possibly-)qualified type.
Definition: Type.h:736
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:277
void dumpColor() const
dumpColor - same as dump(), but forces color highlighting.
Definition: ASTDumper.cpp:288
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:410
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
Definition: DeclTemplate.h:442
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:429
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:196
Declaration of a variable template.
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:197
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
Definition: Specifiers.h:193
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition: Specifiers.h:189
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
Definition: Specifiers.h:185
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition: Specifiers.h:182