clang 22.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 = dyn_cast<SpecializationDecl>(RedeclWithBadType);
121 if (!Redecl)
122 continue;
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
170
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);
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(OS, Context, 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.
#define SM(sm)
Defines the SourceManager interface.
void dump() const
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:798
comments::CommandTraits & getCommentCommandTraits() const
const clang::PrintingPolicy & getPrintingPolicy() const
Definition ASTContext.h:790
DiagnosticsEngine & getDiagnostics() const
void dumpTemplateDeclSpecialization(const SpecializationDecl *D, bool DumpExplicitInst, bool DumpRefOnly)
void dumpLookups(const DeclContext *DC, bool DumpDecls)
Definition ASTDumper.cpp:52
void dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst)
void dumpInvalidDeclContext(const DeclContext *DC)
Definition ASTDumper.cpp:25
void VisitVarTemplateDecl(const VarTemplateDecl *D)
void VisitClassTemplateDecl(const ClassTemplateDecl *D)
void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D)
void Visit(const Decl *D, bool VisitLocs=false)
void dumpTemplateParameters(const TemplateParameterList *TPL)
Declaration of a class template.
TemplateDecl * getNamedConcept() const
Definition ASTConcept.h:197
The results of name lookup within a DeclContext.
Definition DeclBase.h:1382
DeclListNode::iterator iterator
Definition DeclBase.h:1392
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1449
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2109
void dumpAsDecl() const
lookups_range noload_lookups(bool PreserveInternalState) const
Definition DeclLookups.h:89
void dumpLookups() const
bool hasExternalVisibleStorage() const
Whether this DeclContext has external storage containing additional declarations that are visible in ...
Definition DeclBase.h:2700
bool isTranslationUnit() const
Definition DeclBase.h:2185
lookups_range lookups() const
Definition DeclLookups.h:75
bool hasValidDeclKind() const
Definition DeclBase.cpp:179
DeclContext * getPrimaryContext()
getPrimaryContext - There may be many different declarations of the same entity (including forward de...
Decl::Kind getDeclKind() const
Definition DeclBase.h:2102
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:1061
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:524
void dumpColor() const
bool isCanonicalDecl() const
Whether this particular Decl is a canonical one.
Definition DeclBase.h:984
void dump() const
The name of a declaration.
Declaration of a template function.
A (possibly-)qualified type.
Definition TypeBase.h:937
void dump() const
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().
void dumpColor() const
dumpColor - same as dump(), but forces color highlighting.
void dump() const
Debugging aid that dumps the template argument to standard error.
The base class of all kinds of template declarations (e.g., class, function, etc.).
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
void dump() const
Debugging aid that dumps the template name to standard error.
void dump() const
friend class ASTContext
Definition TypeBase.h:2347
void dump() const
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.
@ 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
U cast(CodeGen::Address addr)
Definition Address.h:327
int const char * function
Definition c++config.h:31