clang 23.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, ASTDumpColor::Null);
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, ASTDumpColor::DeclKindName);
40 OS << "DeclContext";
41 }
42 NodeDumper.dumpPointer(DC);
43 OS << " <";
44 {
45 ColorScope Color(OS, ShowColors, ASTDumpColor::DeclName);
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, ASTDumpColor::DeclName);
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, ASTDumpColor::Undeserialized);
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;
139 break;
140 }
141 }
142
143 // Ensure we dump at least one decl for each specialization.
144 if (!DumpedAny)
145 NodeDumper.dumpDeclRef(D);
146}
147
148template <typename TemplateDecl>
149void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) {
151
153
154 if (GetTraversalKind() == TK_AsIs) {
155 for (const auto *Child : D->specializations())
156 dumpTemplateDeclSpecialization(Child, DumpExplicitInst,
157 !D->isCanonicalDecl());
158 }
159}
160
162 // FIXME: We don't add a declaration of a function template specialization
163 // to its context when it's explicitly instantiated, so dump explicit
164 // instantiations when we dump the template itself.
165 dumpTemplateDecl(D, true);
166}
167
171
175
176//===----------------------------------------------------------------------===//
177// Type method implementations
178//===----------------------------------------------------------------------===//
179
180void QualType::dump(const char *msg) const {
181 if (msg)
182 llvm::errs() << msg << ": ";
183 dump();
184}
185
186LLVM_DUMP_METHOD void QualType::dump() const {
187 ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
188 Dumper.Visit(*this);
189}
190
191LLVM_DUMP_METHOD void QualType::dump(llvm::raw_ostream &OS,
192 const ASTContext &Context) const {
193 ASTDumper Dumper(OS, Context, Context.getDiagnostics().getShowColors());
194 Dumper.Visit(*this);
195}
196
197LLVM_DUMP_METHOD void Type::dump() const { QualType(this, 0).dump(); }
198
199LLVM_DUMP_METHOD void Type::dump(llvm::raw_ostream &OS,
200 const ASTContext &Context) const {
201 QualType(this, 0).dump(OS, Context);
202}
203
204//===----------------------------------------------------------------------===//
205// TypeLoc method implementations
206//===----------------------------------------------------------------------===//
207
208LLVM_DUMP_METHOD void TypeLoc::dump() const {
209 ASTDumper(llvm::errs(), /*ShowColors=*/false).Visit(*this);
210}
211
212LLVM_DUMP_METHOD void TypeLoc::dump(llvm::raw_ostream &OS,
213 const ASTContext &Context) const {
214 ASTDumper(OS, Context, Context.getDiagnostics().getShowColors()).Visit(*this);
215}
216
217//===----------------------------------------------------------------------===//
218// Decl method implementations
219//===----------------------------------------------------------------------===//
220
221LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); }
222
223LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize,
224 ASTDumpOutputFormat Format) const {
225 ASTContext &Ctx = getASTContext();
226 const SourceManager &SM = Ctx.getSourceManager();
227
228 if (ADOF_JSON == Format) {
229 JSONDumper P(OS, SM, Ctx, Ctx.getPrintingPolicy(),
231 (void)Deserialize; // FIXME?
232 P.Visit(this);
233 } else {
234 ASTDumper P(OS, Ctx, Ctx.getDiagnostics().getShowColors());
235 P.setDeserialize(Deserialize);
236 P.Visit(this);
237 }
238}
239
240LLVM_DUMP_METHOD void Decl::dumpColor() const {
241 const ASTContext &Ctx = getASTContext();
242 ASTDumper P(llvm::errs(), Ctx, /*ShowColors=*/true);
243 P.Visit(this);
244}
245
246LLVM_DUMP_METHOD void DeclContext::dumpAsDecl() const {
247 dumpAsDecl(nullptr);
248}
249
250LLVM_DUMP_METHOD void DeclContext::dumpAsDecl(const ASTContext *Ctx) const {
251 // By design, DeclContext is required to be a base class of some class that
252 // derives from Decl. Thus, it should always be possible to dyn_cast() from
253 // a DeclContext pointer to a Decl pointer and Decl::castFromDeclContext()
254 // asserts that to be the case. Since this function is intended for use in a
255 // debugger, it performs an additional check in order to prevent a failed
256 // cast and assertion. If that check fails, then the (invalid) DeclContext
257 // is dumped with an indication of its invalidity.
258 if (hasValidDeclKind()) {
259 const auto *D = cast<Decl>(this);
260 D->dump();
261 } else {
262 // If an ASTContext is not available, a less capable ASTDumper is
263 // constructed for which color diagnostics are, regrettably, disabled.
264 ASTDumper P = Ctx ? ASTDumper(llvm::errs(), *Ctx,
266 : ASTDumper(llvm::errs(), /*ShowColors*/ false);
268 }
269}
270
271LLVM_DUMP_METHOD void DeclContext::dumpLookups() const {
272 dumpLookups(llvm::errs());
273}
274
275LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS,
276 bool DumpDecls,
277 bool Deserialize) const {
278 const DeclContext *DC = this;
279 while (!DC->isTranslationUnit())
280 DC = DC->getParent();
281 const ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
282 ASTDumper P(OS, Ctx, Ctx.getDiagnostics().getShowColors());
283 P.setDeserialize(Deserialize);
284 P.dumpLookups(this, DumpDecls);
285}
286
287//===----------------------------------------------------------------------===//
288// Stmt method implementations
289//===----------------------------------------------------------------------===//
290
291LLVM_DUMP_METHOD void Stmt::dump() const {
292 ASTDumper P(llvm::errs(), /*ShowColors=*/false);
293 P.Visit(this);
294}
295
296LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS,
297 const ASTContext &Context) const {
298 ASTDumper P(OS, Context, Context.getDiagnostics().getShowColors());
299 P.Visit(this);
300}
301
302LLVM_DUMP_METHOD void Stmt::dumpColor() const {
303 ASTDumper P(llvm::errs(), /*ShowColors=*/true);
304 P.Visit(this);
305}
306
307//===----------------------------------------------------------------------===//
308// Comment method implementations
309//===----------------------------------------------------------------------===//
310
311LLVM_DUMP_METHOD void Comment::dump() const {
312 const auto *FC = dyn_cast<FullComment>(this);
313 if (!FC)
314 return;
315 ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
316 Dumper.Visit(FC, FC);
317}
318
319LLVM_DUMP_METHOD void Comment::dump(raw_ostream &OS,
320 const ASTContext &Context) const {
321 const auto *FC = dyn_cast<FullComment>(this);
322 if (!FC)
323 return;
324 ASTDumper Dumper(OS, Context, Context.getDiagnostics().getShowColors());
325 Dumper.Visit(FC, FC);
326}
327
328LLVM_DUMP_METHOD void Comment::dumpColor() const {
329 const auto *FC = dyn_cast<FullComment>(this);
330 if (!FC)
331 return;
332 ASTDumper Dumper(llvm::errs(), /*ShowColors=*/true);
333 Dumper.Visit(FC, FC);
334}
335
336//===----------------------------------------------------------------------===//
337// APValue method implementations
338//===----------------------------------------------------------------------===//
339
340LLVM_DUMP_METHOD void APValue::dump() const {
341 ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
342 Dumper.Visit(*this, /*Ty=*/QualType());
343}
344
345LLVM_DUMP_METHOD void APValue::dump(raw_ostream &OS,
346 const ASTContext &Context) const {
347 ASTDumper Dumper(OS, Context, 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}
364
365//===----------------------------------------------------------------------===//
366// TemplateName method implementations
367//===----------------------------------------------------------------------===//
368
369// FIXME: These are actually using the TemplateArgument dumper, through
370// an implicit conversion. The dump will claim this is a template argument,
371// which is misleading.
372
373LLVM_DUMP_METHOD void TemplateName::dump() const {
374 ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
375 Dumper.Visit(*this);
376}
377
378LLVM_DUMP_METHOD void TemplateName::dump(llvm::raw_ostream &OS,
379 const ASTContext &Context) const {
380 ASTDumper Dumper(OS, Context, Context.getDiagnostics().getShowColors());
381 Dumper.Visit(*this);
382}
383
384//===----------------------------------------------------------------------===//
385// TemplateArgument method implementations
386//===----------------------------------------------------------------------===//
387
388LLVM_DUMP_METHOD void TemplateArgument::dump() const {
389 ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
390 Dumper.Visit(*this);
391}
392
393LLVM_DUMP_METHOD void TemplateArgument::dump(llvm::raw_ostream &OS,
394 const ASTContext &Context) const {
395 ASTDumper Dumper(OS, Context, Context.getDiagnostics().getShowColors());
396 Dumper.Visit(*this);
397}
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:223
SourceManager & getSourceManager()
Definition ASTContext.h:863
comments::CommandTraits & getCommentCommandTraits() const
const clang::PrintingPolicy & getPrintingPolicy() const
Definition ASTContext.h:855
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:201
The results of name lookup within a DeclContext.
Definition DeclBase.h:1395
DeclListNode::iterator iterator
Definition DeclBase.h:1405
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1462
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2122
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:2713
bool isTranslationUnit() const
Definition DeclBase.h:2198
lookups_range lookups() const
Definition DeclLookups.h:75
bool hasValidDeclKind() const
Definition DeclBase.cpp:201
DeclContext * getPrimaryContext()
getPrimaryContext - There may be many different declarations of the same entity (including forward de...
Decl::Kind getDeclKind() const
Definition DeclBase.h:2115
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:1074
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:547
void dumpColor() const
bool isCanonicalDecl() const
Whether this particular Decl is a canonical one.
Definition DeclBase.h:997
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:2407
void dump() const
Declaration of a variable template.
The JSON file list parser is used to communicate input to InstallAPI.
ASTDumpOutputFormat
Used to specify the format for printing AST dump information.
@ TK_AsIs
Will traverse all child nodes.
@ TSK_FriendDeclaration
This template is a friend declaration.
Definition Specifiers.h:197
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
Definition Specifiers.h:209
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
Definition Specifiers.h:205
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition Specifiers.h:201
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
Definition Specifiers.h:195
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition Specifiers.h:192
U cast(CodeGen::Address addr)
Definition Address.h:327
int const char * function
Definition c++config.h:31
static constexpr TerminalColor DeclKindName
static constexpr TerminalColor Null
static constexpr TerminalColor DeclName
static constexpr TerminalColor Undeserialized