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"
21#include "llvm/Support/raw_ostream.h"
22
23using namespace clang;
24using namespace clang::comments;
25
26static bool showColorsForStream(const ASTContext &Ctx, raw_ostream &OS) {
28 OS.has_colors());
29}
30
32 NodeDumper.AddChild([=] {
33 if (!DC) {
34 ColorScope Color(OS, ShowColors, ASTDumpColor::Null);
35 OS << "<<<NULL>>>";
36 return;
37 }
38 // An invalid DeclContext is one for which a dyn_cast() from a DeclContext
39 // pointer to a Decl pointer would fail an assertion or otherwise fall prey
40 // to undefined behavior as a result of an invalid associated DeclKind.
41 // Such invalidity is not supposed to happen of course, but, when it does,
42 // the information provided below is intended to provide some hints about
43 // what might have gone awry.
44 {
45 ColorScope Color(OS, ShowColors, ASTDumpColor::DeclKindName);
46 OS << "DeclContext";
47 }
48 NodeDumper.dumpPointer(DC);
49 OS << " <";
50 {
51 ColorScope Color(OS, ShowColors, ASTDumpColor::DeclName);
52 OS << "unrecognized Decl kind " << (unsigned)DC->getDeclKind();
53 }
54 OS << ">";
55 });
56}
57
58void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
59 NodeDumper.AddChild([=] {
60 OS << "StoredDeclsMap ";
61 NodeDumper.dumpBareDeclRef(cast<Decl>(DC));
62
63 const DeclContext *Primary = DC->getPrimaryContext();
64 if (Primary != DC) {
65 OS << " primary";
66 NodeDumper.dumpPointer(cast<Decl>(Primary));
67 }
68
69 bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage();
70
71 auto Range = getDeserialize()
72 ? Primary->lookups()
73 : Primary->noload_lookups(/*PreserveInternalState=*/true);
74 for (auto I = Range.begin(), E = Range.end(); I != E; ++I) {
75 DeclarationName Name = I.getLookupName();
77
78 NodeDumper.AddChild([=] {
79 OS << "DeclarationName ";
80 {
81 ColorScope Color(OS, ShowColors, ASTDumpColor::DeclName);
82 OS << '\'' << Name << '\'';
83 }
84
85 for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end();
86 RI != RE; ++RI) {
87 NodeDumper.AddChild([=] {
88 NodeDumper.dumpBareDeclRef(*RI);
89
90 if (!(*RI)->isUnconditionallyVisible())
91 OS << " hidden";
92
93 // If requested, dump the redecl chain for this lookup.
94 if (DumpDecls) {
95 // Dump earliest decl first.
96 std::function<void(Decl *)> DumpWithPrev = [&](Decl *D) {
97 if (Decl *Prev = D->getPreviousDecl())
98 DumpWithPrev(Prev);
99 Visit(D);
100 };
101 DumpWithPrev(*RI);
102 }
103 });
104 }
105 });
106 }
107
108 if (HasUndeserializedLookups) {
109 NodeDumper.AddChild([=] {
110 ColorScope Color(OS, ShowColors, ASTDumpColor::Undeserialized);
111 OS << "<undeserialized lookups>";
112 });
113 }
114 });
115}
116
117template <typename SpecializationDecl>
118void ASTDumper::dumpTemplateDeclSpecialization(const SpecializationDecl *D,
119 bool DumpExplicitInst,
120 bool DumpRefOnly) {
121 bool DumpedAny = false;
122 for (const auto *RedeclWithBadType : D->redecls()) {
123 // FIXME: The redecls() range sometimes has elements of a less-specific
124 // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
125 // us TagDecls, and should give CXXRecordDecls).
126 auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
127 if (!Redecl)
128 continue;
129 switch (Redecl->getTemplateSpecializationKind()) {
132 if (!DumpExplicitInst)
133 break;
134 [[fallthrough]];
135 case TSK_Undeclared:
137 if (DumpRefOnly)
138 NodeDumper.dumpDeclRef(Redecl);
139 else
140 Visit(Redecl);
141 DumpedAny = true;
142 break;
144 break;
145 }
146 }
147
148 // Ensure we dump at least one decl for each specialization.
149 if (!DumpedAny)
150 NodeDumper.dumpDeclRef(D);
151}
152
153template <typename TemplateDecl>
154void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) {
156
158
159 if (GetTraversalKind() == TK_AsIs) {
160 for (const auto *Child : D->specializations())
161 dumpTemplateDeclSpecialization(Child, DumpExplicitInst,
162 !D->isCanonicalDecl());
163 }
164}
165
167 // FIXME: We don't add a declaration of a function template specialization
168 // to its context when it's explicitly instantiated, so dump explicit
169 // instantiations when we dump the template itself.
170 dumpTemplateDecl(D, true);
171}
172
176
180
181//===----------------------------------------------------------------------===//
182// Type method implementations
183//===----------------------------------------------------------------------===//
184
185void QualType::dump(const char *msg) const {
186 if (msg)
187 llvm::errs() << msg << ": ";
188 dump();
189}
190
191LLVM_DUMP_METHOD void QualType::dump() const {
192 ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
193 Dumper.Visit(*this);
194}
195
196LLVM_DUMP_METHOD void QualType::dump(llvm::raw_ostream &OS,
197 const ASTContext &Context) const {
198 ASTDumper Dumper(OS, Context, showColorsForStream(Context, OS));
199 Dumper.Visit(*this);
200}
201
202LLVM_DUMP_METHOD void Type::dump() const { QualType(this, 0).dump(); }
203
204LLVM_DUMP_METHOD void Type::dump(llvm::raw_ostream &OS,
205 const ASTContext &Context) const {
206 QualType(this, 0).dump(OS, Context);
207}
208
209//===----------------------------------------------------------------------===//
210// TypeLoc method implementations
211//===----------------------------------------------------------------------===//
212
213LLVM_DUMP_METHOD void TypeLoc::dump() const {
214 ASTDumper(llvm::errs(), /*ShowColors=*/false).Visit(*this);
215}
216
217LLVM_DUMP_METHOD void TypeLoc::dump(llvm::raw_ostream &OS,
218 const ASTContext &Context) const {
219 ASTDumper(OS, Context, showColorsForStream(Context, OS)).Visit(*this);
220}
221
222//===----------------------------------------------------------------------===//
223// Decl method implementations
224//===----------------------------------------------------------------------===//
225
226LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); }
227
228LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize,
229 ASTDumpOutputFormat Format) const {
230 ASTContext &Ctx = getASTContext();
231 const SourceManager &SM = Ctx.getSourceManager();
232
233 if (ADOF_JSON == Format) {
234 JSONDumper P(OS, SM, Ctx, Ctx.getPrintingPolicy(),
236 (void)Deserialize; // FIXME?
237 P.Visit(this);
238 } else {
239 ASTDumper P(OS, Ctx, showColorsForStream(Ctx, OS));
240 P.setDeserialize(Deserialize);
241 P.Visit(this);
242 }
243}
244
245LLVM_DUMP_METHOD void Decl::dumpColor() const {
246 const ASTContext &Ctx = getASTContext();
247 ASTDumper P(llvm::errs(), Ctx, /*ShowColors=*/true);
248 P.Visit(this);
249}
250
251LLVM_DUMP_METHOD void DeclContext::dumpAsDecl() const {
252 dumpAsDecl(nullptr);
253}
254
255LLVM_DUMP_METHOD void DeclContext::dumpAsDecl(const ASTContext *Ctx) const {
256 // By design, DeclContext is required to be a base class of some class that
257 // derives from Decl. Thus, it should always be possible to dyn_cast() from
258 // a DeclContext pointer to a Decl pointer and Decl::castFromDeclContext()
259 // asserts that to be the case. Since this function is intended for use in a
260 // debugger, it performs an additional check in order to prevent a failed
261 // cast and assertion. If that check fails, then the (invalid) DeclContext
262 // is dumped with an indication of its invalidity.
263 if (hasValidDeclKind()) {
264 const auto *D = cast<Decl>(this);
265 D->dump();
266 } else {
267 // If an ASTContext is not available, a less capable ASTDumper is
268 // constructed for which color diagnostics are, regrettably, disabled.
269 ASTDumper P = Ctx ? ASTDumper(llvm::errs(), *Ctx,
270 showColorsForStream(*Ctx, llvm::errs()))
271 : ASTDumper(llvm::errs(), /*ShowColors*/ false);
273 }
274}
275
276LLVM_DUMP_METHOD void DeclContext::dumpLookups() const {
277 dumpLookups(llvm::errs());
278}
279
280LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS,
281 bool DumpDecls,
282 bool Deserialize) const {
283 const DeclContext *DC = this;
284 while (!DC->isTranslationUnit())
285 DC = DC->getParent();
286 const ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
287 ASTDumper P(OS, Ctx, showColorsForStream(Ctx, OS));
288 P.setDeserialize(Deserialize);
289 P.dumpLookups(this, DumpDecls);
290}
291
292//===----------------------------------------------------------------------===//
293// Stmt method implementations
294//===----------------------------------------------------------------------===//
295
296LLVM_DUMP_METHOD void Stmt::dump() const {
297 ASTDumper P(llvm::errs(), /*ShowColors=*/false);
298 P.Visit(this);
299}
300
301LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS,
302 const ASTContext &Context) const {
303 ASTDumper P(OS, Context, showColorsForStream(Context, OS));
304 P.Visit(this);
305}
306
307LLVM_DUMP_METHOD void Stmt::dumpColor() const {
308 ASTDumper P(llvm::errs(), /*ShowColors=*/true);
309 P.Visit(this);
310}
311
312//===----------------------------------------------------------------------===//
313// Comment method implementations
314//===----------------------------------------------------------------------===//
315
316LLVM_DUMP_METHOD void Comment::dump() const {
317 const auto *FC = dyn_cast<FullComment>(this);
318 if (!FC)
319 return;
320 ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
321 Dumper.Visit(FC, FC);
322}
323
324LLVM_DUMP_METHOD void Comment::dump(raw_ostream &OS,
325 const ASTContext &Context) const {
326 const auto *FC = dyn_cast<FullComment>(this);
327 if (!FC)
328 return;
329 ASTDumper Dumper(OS, Context, showColorsForStream(Context, OS));
330 Dumper.Visit(FC, FC);
331}
332
333LLVM_DUMP_METHOD void Comment::dumpColor() const {
334 const auto *FC = dyn_cast<FullComment>(this);
335 if (!FC)
336 return;
337 ASTDumper Dumper(llvm::errs(), /*ShowColors=*/true);
338 Dumper.Visit(FC, FC);
339}
340
341//===----------------------------------------------------------------------===//
342// APValue method implementations
343//===----------------------------------------------------------------------===//
344
345LLVM_DUMP_METHOD void APValue::dump() const {
346 ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
347 Dumper.Visit(*this, /*Ty=*/QualType());
348}
349
350LLVM_DUMP_METHOD void APValue::dump(raw_ostream &OS,
351 const ASTContext &Context) const {
352 ASTDumper Dumper(OS, Context, showColorsForStream(Context, OS));
353 Dumper.Visit(*this, /*Ty=*/Context.getPointerType(Context.CharTy));
354}
355
356//===----------------------------------------------------------------------===//
357// ConceptReference method implementations
358//===----------------------------------------------------------------------===//
359
360LLVM_DUMP_METHOD void ConceptReference::dump() const {
361 dump(llvm::errs());
362}
363
364LLVM_DUMP_METHOD void ConceptReference::dump(raw_ostream &OS) const {
365 auto &Ctx = getNamedConcept()->getASTContext();
366 ASTDumper P(OS, Ctx, showColorsForStream(Ctx, OS));
367 P.Visit(this);
368}
369
370//===----------------------------------------------------------------------===//
371// TemplateName method implementations
372//===----------------------------------------------------------------------===//
373
374// FIXME: These are actually using the TemplateArgument dumper, through
375// an implicit conversion. The dump will claim this is a template argument,
376// which is misleading.
377
378LLVM_DUMP_METHOD void TemplateName::dump() const {
379 ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
380 Dumper.Visit(*this);
381}
382
383LLVM_DUMP_METHOD void TemplateName::dump(llvm::raw_ostream &OS,
384 const ASTContext &Context) const {
385 ASTDumper Dumper(OS, Context, showColorsForStream(Context, OS));
386 Dumper.Visit(*this);
387}
388
389//===----------------------------------------------------------------------===//
390// TemplateArgument method implementations
391//===----------------------------------------------------------------------===//
392
393LLVM_DUMP_METHOD void TemplateArgument::dump() const {
394 ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
395 Dumper.Visit(*this);
396}
397
398LLVM_DUMP_METHOD void TemplateArgument::dump(llvm::raw_ostream &OS,
399 const ASTContext &Context) const {
400 ASTDumper Dumper(OS, Context, showColorsForStream(Context, OS));
401 Dumper.Visit(*this);
402}
This file provides AST data structures related to concepts.
Defines the clang::ASTContext interface.
static bool showColorsForStream(const ASTContext &Ctx, raw_ostream &OS)
Definition ASTDumper.cpp:26
Defines the Diagnostic-related interfaces.
#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:58
void dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst)
void dumpInvalidDeclContext(const DeclContext *DC)
Definition ASTDumper.cpp:31
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:1399
DeclListNode::iterator iterator
Definition DeclBase.h:1409
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1466
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2126
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:2717
bool isTranslationUnit() const
Definition DeclBase.h:2202
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:2119
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:1078
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:1001
void dump() const
The name of a declaration.
bool showColors(bool StreamHasColors) const
Resolve the color mode against a stream's capability.
DiagnosticOptions & getDiagnosticOptions() const
Retrieve the diagnostic options.
Definition Diagnostic.h:604
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_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
Definition Specifiers.h:207
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
Definition Specifiers.h:203
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition Specifiers.h:199
@ 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