blob: 22196a1a260049d400f3fcec9fcd760597b5bbd2 [file] [log] [blame]
Alexander Kornienko18ec81b2012-12-13 13:59:55 +00001//===--- ASTDumper.cpp - Dumping implementation for ASTs ------------------===//
Chris Lattnercbe4f772007-08-08 22:51:59 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Chris Lattnercbe4f772007-08-08 22:51:59 +00006//
7//===----------------------------------------------------------------------===//
8//
Alexander Kornienko18ec81b2012-12-13 13:59:55 +00009// This file implements the AST dump methods, which dump out the
Chris Lattnercbe4f772007-08-08 22:51:59 +000010// AST in a form that exposes type details and other fields.
11//
12//===----------------------------------------------------------------------===//
13
Stephen Kellyc8dcbed2019-05-17 13:59:15 +000014#include "clang/AST/ASTDumper.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000015#include "clang/AST/ASTContext.h"
Richard Smith33937e72013-06-22 21:49:40 +000016#include "clang/AST/DeclLookups.h"
Aaron Ballman2ce598a2019-05-13 21:39:55 +000017#include "clang/AST/JSONNodeDumper.h"
David Majnemerd9b1a4f2015-11-04 03:40:30 +000018#include "clang/Basic/Builtins.h"
Alexander Kornienko90ff6072012-12-20 02:09:13 +000019#include "clang/Basic/Module.h"
Chris Lattner11e30d32007-08-30 06:17:34 +000020#include "clang/Basic/SourceManager.h"
Daniel Dunbar34a96c82009-12-03 09:13:13 +000021#include "llvm/Support/raw_ostream.h"
Chris Lattnercbe4f772007-08-08 22:51:59 +000022using namespace clang;
Alexander Kornienkoebc17b52013-01-14 14:07:11 +000023using namespace clang::comments;
Chris Lattnercbe4f772007-08-08 22:51:59 +000024
Richard Smith35f986d2014-08-11 22:11:07 +000025void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
Stephen Kellyd8aeb552019-01-30 19:41:04 +000026 NodeDumper.AddChild([=] {
Richard Smithf7514452014-10-30 21:02:37 +000027 OS << "StoredDeclsMap ";
Stephen Kellyd8744a72018-12-05 21:12:39 +000028 NodeDumper.dumpBareDeclRef(cast<Decl>(DC));
Richard Smith33937e72013-06-22 21:49:40 +000029
Richard Smithf7514452014-10-30 21:02:37 +000030 const DeclContext *Primary = DC->getPrimaryContext();
31 if (Primary != DC) {
32 OS << " primary";
Stephen Kellyd8744a72018-12-05 21:12:39 +000033 NodeDumper.dumpPointer(cast<Decl>(Primary));
Richard Smith33937e72013-06-22 21:49:40 +000034 }
35
Richard Smithf7514452014-10-30 21:02:37 +000036 bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage();
Richard Smith35f986d2014-08-11 22:11:07 +000037
Stephen Kellyc4933012019-02-03 14:06:54 +000038 auto Range = getDeserialize()
Sam McCall091b1ef2018-01-16 12:33:46 +000039 ? Primary->lookups()
40 : Primary->noload_lookups(/*PreserveInternalState=*/true);
41 for (auto I = Range.begin(), E = Range.end(); I != E; ++I) {
Richard Smithf7514452014-10-30 21:02:37 +000042 DeclarationName Name = I.getLookupName();
Richard Smith3a36ac12017-03-09 22:00:01 +000043 DeclContextLookupResult R = *I;
Richard Smith35f986d2014-08-11 22:11:07 +000044
Stephen Kellyd8aeb552019-01-30 19:41:04 +000045 NodeDumper.AddChild([=] {
Richard Smithf7514452014-10-30 21:02:37 +000046 OS << "DeclarationName ";
47 {
Stephen Kelly27e948c2018-11-29 19:30:37 +000048 ColorScope Color(OS, ShowColors, DeclNameColor);
Richard Smithf7514452014-10-30 21:02:37 +000049 OS << '\'' << Name << '\'';
50 }
Richard Smith35f986d2014-08-11 22:11:07 +000051
Richard Smithf7514452014-10-30 21:02:37 +000052 for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end();
53 RI != RE; ++RI) {
Stephen Kellyd8aeb552019-01-30 19:41:04 +000054 NodeDumper.AddChild([=] {
Stephen Kellyd8744a72018-12-05 21:12:39 +000055 NodeDumper.dumpBareDeclRef(*RI);
Richard Smithf7514452014-10-30 21:02:37 +000056
57 if ((*RI)->isHidden())
58 OS << " hidden";
59
60 // If requested, dump the redecl chain for this lookup.
61 if (DumpDecls) {
62 // Dump earliest decl first.
63 std::function<void(Decl *)> DumpWithPrev = [&](Decl *D) {
64 if (Decl *Prev = D->getPreviousDecl())
65 DumpWithPrev(Prev);
Stephen Kelly6d110d62019-01-30 19:49:49 +000066 Visit(D);
Richard Smithf7514452014-10-30 21:02:37 +000067 };
68 DumpWithPrev(*RI);
69 }
70 });
71 }
72 });
Richard Smith33937e72013-06-22 21:49:40 +000073 }
Richard Smith33937e72013-06-22 21:49:40 +000074
Richard Smithf7514452014-10-30 21:02:37 +000075 if (HasUndeserializedLookups) {
Stephen Kellyd8aeb552019-01-30 19:41:04 +000076 NodeDumper.AddChild([=] {
Stephen Kelly27e948c2018-11-29 19:30:37 +000077 ColorScope Color(OS, ShowColors, UndeserializedColor);
Richard Smithf7514452014-10-30 21:02:37 +000078 OS << "<undeserialized lookups>";
79 });
80 }
81 });
Richard Smith33937e72013-06-22 21:49:40 +000082}
83
Stephen Kelly24136382018-12-09 13:33:30 +000084template <typename SpecializationDecl>
85void ASTDumper::dumpTemplateDeclSpecialization(const SpecializationDecl *D,
86 bool DumpExplicitInst,
87 bool DumpRefOnly) {
Richard Smithcbdf7332014-03-18 02:07:28 +000088 bool DumpedAny = false;
Stephen Kellyaaebc5f2019-01-19 09:57:51 +000089 for (const auto *RedeclWithBadType : D->redecls()) {
Richard Smithcbdf7332014-03-18 02:07:28 +000090 // FIXME: The redecls() range sometimes has elements of a less-specific
91 // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
92 // us TagDecls, and should give CXXRecordDecls).
93 auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
94 if (!Redecl) {
95 // Found the injected-class-name for a class template. This will be dumped
96 // as part of its surrounding class so we don't need to dump it here.
97 assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
98 "expected an injected-class-name");
99 continue;
100 }
101
102 switch (Redecl->getTemplateSpecializationKind()) {
103 case TSK_ExplicitInstantiationDeclaration:
104 case TSK_ExplicitInstantiationDefinition:
105 if (!DumpExplicitInst)
106 break;
Adrian Prantlf3b3ccd2017-12-19 22:06:11 +0000107 LLVM_FALLTHROUGH;
Richard Smithcbdf7332014-03-18 02:07:28 +0000108 case TSK_Undeclared:
109 case TSK_ImplicitInstantiation:
Richard Smithf7514452014-10-30 21:02:37 +0000110 if (DumpRefOnly)
Stephen Kellyd186dbc2019-01-08 23:11:24 +0000111 NodeDumper.dumpDeclRef(Redecl);
Richard Smithf7514452014-10-30 21:02:37 +0000112 else
Stephen Kelly6d110d62019-01-30 19:49:49 +0000113 Visit(Redecl);
Richard Smithcbdf7332014-03-18 02:07:28 +0000114 DumpedAny = true;
115 break;
116 case TSK_ExplicitSpecialization:
117 break;
118 }
119 }
120
121 // Ensure we dump at least one decl for each specialization.
122 if (!DumpedAny)
Stephen Kellyd186dbc2019-01-08 23:11:24 +0000123 NodeDumper.dumpDeclRef(D);
Richard Smithcbdf7332014-03-18 02:07:28 +0000124}
125
Stephen Kelly24136382018-12-09 13:33:30 +0000126template <typename TemplateDecl>
127void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) {
Alexander Kornienko90ff6072012-12-20 02:09:13 +0000128 dumpTemplateParameters(D->getTemplateParameters());
Richard Smithdcc2c452014-03-17 23:00:06 +0000129
Stephen Kelly6d110d62019-01-30 19:49:49 +0000130 Visit(D->getTemplatedDecl());
Richard Smithdcc2c452014-03-17 23:00:06 +0000131
Stephen Kellyaaebc5f2019-01-19 09:57:51 +0000132 for (const auto *Child : D->specializations())
Stephen Kelly24136382018-12-09 13:33:30 +0000133 dumpTemplateDeclSpecialization(Child, DumpExplicitInst,
134 !D->isCanonicalDecl());
Alexander Kornienko90ff6072012-12-20 02:09:13 +0000135}
136
Richard Smith20ade552014-03-17 23:34:53 +0000137void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
138 // FIXME: We don't add a declaration of a function template specialization
139 // to its context when it's explicitly instantiated, so dump explicit
140 // instantiations when we dump the template itself.
Stephen Kelly24136382018-12-09 13:33:30 +0000141 dumpTemplateDecl(D, true);
Richard Smith20ade552014-03-17 23:34:53 +0000142}
143
Alexander Kornienko540bacb2013-02-01 12:35:51 +0000144void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
Stephen Kelly24136382018-12-09 13:33:30 +0000145 dumpTemplateDecl(D, false);
Alexander Kornienko90ff6072012-12-20 02:09:13 +0000146}
147
Richard Smithd25789a2013-09-18 01:36:02 +0000148void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
Stephen Kelly24136382018-12-09 13:33:30 +0000149 dumpTemplateDecl(D, false);
Richard Smithd25789a2013-09-18 01:36:02 +0000150}
151
Chris Lattnercbe4f772007-08-08 22:51:59 +0000152//===----------------------------------------------------------------------===//
Richard Smithd5e7ff82014-10-31 01:17:45 +0000153// Type method implementations
154//===----------------------------------------------------------------------===//
155
156void QualType::dump(const char *msg) const {
157 if (msg)
158 llvm::errs() << msg << ": ";
159 dump();
160}
161
Richard Smith14d04842016-11-02 23:57:18 +0000162LLVM_DUMP_METHOD void QualType::dump() const { dump(llvm::errs()); }
163
164LLVM_DUMP_METHOD void QualType::dump(llvm::raw_ostream &OS) const {
165 ASTDumper Dumper(OS, nullptr, nullptr);
Stephen Kelly6d110d62019-01-30 19:49:49 +0000166 Dumper.Visit(*this);
Richard Smithd5e7ff82014-10-31 01:17:45 +0000167}
168
Richard Smith14d04842016-11-02 23:57:18 +0000169LLVM_DUMP_METHOD void Type::dump() const { dump(llvm::errs()); }
170
171LLVM_DUMP_METHOD void Type::dump(llvm::raw_ostream &OS) const {
172 QualType(this, 0).dump(OS);
173}
Richard Smithd5e7ff82014-10-31 01:17:45 +0000174
175//===----------------------------------------------------------------------===//
Alexander Kornienko90ff6072012-12-20 02:09:13 +0000176// Decl method implementations
177//===----------------------------------------------------------------------===//
178
Alp Tokeref6b0072014-01-04 13:47:14 +0000179LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); }
Alexander Kornienko90ff6072012-12-20 02:09:13 +0000180
Aaron Ballman2ce598a2019-05-13 21:39:55 +0000181LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize,
182 ASTDumpOutputFormat Format) const {
Aaron Ballmane091ab12019-05-27 14:34:31 +0000183 ASTContext &Ctx = getASTContext();
Aaron Ballman8c208282017-12-21 21:42:42 +0000184 const SourceManager &SM = Ctx.getSourceManager();
Aaron Ballman2ce598a2019-05-13 21:39:55 +0000185
186 if (ADOF_JSON == Format) {
Aaron Ballmane091ab12019-05-27 14:34:31 +0000187 JSONDumper P(OS, SM, Ctx, Ctx.getPrintingPolicy(),
Aaron Ballman86abee82019-05-21 14:38:29 +0000188 &Ctx.getCommentCommandTraits());
Aaron Ballman2ce598a2019-05-13 21:39:55 +0000189 (void)Deserialize; // FIXME?
190 P.Visit(this);
191 } else {
192 ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &SM,
193 SM.getDiagnostics().getShowColors(), Ctx.getPrintingPolicy());
194 P.setDeserialize(Deserialize);
195 P.Visit(this);
196 }
Alexander Kornienko90ff6072012-12-20 02:09:13 +0000197}
198
Alp Tokeref6b0072014-01-04 13:47:14 +0000199LLVM_DUMP_METHOD void Decl::dumpColor() const {
Aaron Ballman8c208282017-12-21 21:42:42 +0000200 const ASTContext &Ctx = getASTContext();
201 ASTDumper P(llvm::errs(), &Ctx.getCommentCommandTraits(),
202 &Ctx.getSourceManager(), /*ShowColors*/ true,
203 Ctx.getPrintingPolicy());
Stephen Kelly6d110d62019-01-30 19:49:49 +0000204 P.Visit(this);
Richard Trieud215b8d2013-01-26 01:31:20 +0000205}
Richard Smith33937e72013-06-22 21:49:40 +0000206
Alp Tokeref6b0072014-01-04 13:47:14 +0000207LLVM_DUMP_METHOD void DeclContext::dumpLookups() const {
Richard Smith6ea05822013-06-24 01:45:33 +0000208 dumpLookups(llvm::errs());
209}
210
Richard Smith35f986d2014-08-11 22:11:07 +0000211LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS,
Richard Smith3a36ac12017-03-09 22:00:01 +0000212 bool DumpDecls,
213 bool Deserialize) const {
Richard Smith33937e72013-06-22 21:49:40 +0000214 const DeclContext *DC = this;
215 while (!DC->isTranslationUnit())
216 DC = DC->getParent();
217 ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
Aaron Ballman8c208282017-12-21 21:42:42 +0000218 const SourceManager &SM = Ctx.getSourceManager();
219 ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager(),
220 SM.getDiagnostics().getShowColors(), Ctx.getPrintingPolicy());
Richard Smith3a36ac12017-03-09 22:00:01 +0000221 P.setDeserialize(Deserialize);
Richard Smith35f986d2014-08-11 22:11:07 +0000222 P.dumpLookups(this, DumpDecls);
Richard Smith33937e72013-06-22 21:49:40 +0000223}
224
Alexander Kornienko90ff6072012-12-20 02:09:13 +0000225//===----------------------------------------------------------------------===//
Chris Lattnercbe4f772007-08-08 22:51:59 +0000226// Stmt method implementations
227//===----------------------------------------------------------------------===//
228
Alp Tokeref6b0072014-01-04 13:47:14 +0000229LLVM_DUMP_METHOD void Stmt::dump(SourceManager &SM) const {
Argyrios Kyrtzidisc049f752010-08-09 10:54:31 +0000230 dump(llvm::errs(), SM);
231}
232
Alp Tokeref6b0072014-01-04 13:47:14 +0000233LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
Craig Topper36250ad2014-05-12 05:36:57 +0000234 ASTDumper P(OS, nullptr, &SM);
Stephen Kelly6d110d62019-01-30 19:49:49 +0000235 P.Visit(this);
Chris Lattner779d5d92007-08-30 00:40:08 +0000236}
237
Faisal Vali2da8ed92015-03-22 13:35:56 +0000238LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS) const {
239 ASTDumper P(OS, nullptr, nullptr);
Stephen Kelly6d110d62019-01-30 19:49:49 +0000240 P.Visit(this);
Faisal Vali2da8ed92015-03-22 13:35:56 +0000241}
242
Alp Tokeref6b0072014-01-04 13:47:14 +0000243LLVM_DUMP_METHOD void Stmt::dump() const {
Craig Topper36250ad2014-05-12 05:36:57 +0000244 ASTDumper P(llvm::errs(), nullptr, nullptr);
Stephen Kelly6d110d62019-01-30 19:49:49 +0000245 P.Visit(this);
Chris Lattnercbe4f772007-08-08 22:51:59 +0000246}
Alexander Kornienkoebc17b52013-01-14 14:07:11 +0000247
Alp Tokeref6b0072014-01-04 13:47:14 +0000248LLVM_DUMP_METHOD void Stmt::dumpColor() const {
Craig Topper36250ad2014-05-12 05:36:57 +0000249 ASTDumper P(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
Stephen Kelly6d110d62019-01-30 19:49:49 +0000250 P.Visit(this);
Richard Trieud215b8d2013-01-26 01:31:20 +0000251}
252
Alexander Kornienkoebc17b52013-01-14 14:07:11 +0000253//===----------------------------------------------------------------------===//
254// Comment method implementations
255//===----------------------------------------------------------------------===//
256
Craig Topper36250ad2014-05-12 05:36:57 +0000257LLVM_DUMP_METHOD void Comment::dump() const {
258 dump(llvm::errs(), nullptr, nullptr);
259}
Alexander Kornienkoebc17b52013-01-14 14:07:11 +0000260
Alp Tokeref6b0072014-01-04 13:47:14 +0000261LLVM_DUMP_METHOD void Comment::dump(const ASTContext &Context) const {
Alexander Kornienkoebc17b52013-01-14 14:07:11 +0000262 dump(llvm::errs(), &Context.getCommentCommandTraits(),
263 &Context.getSourceManager());
264}
265
Alexander Kornienko00911f12013-01-15 12:20:21 +0000266void Comment::dump(raw_ostream &OS, const CommandTraits *Traits,
Alexander Kornienkoebc17b52013-01-14 14:07:11 +0000267 const SourceManager *SM) const {
268 const FullComment *FC = dyn_cast<FullComment>(this);
Stephen Kelly570b2972018-12-09 13:18:55 +0000269 if (!FC)
270 return;
Alexander Kornienkoebc17b52013-01-14 14:07:11 +0000271 ASTDumper D(OS, Traits, SM);
Stephen Kelly6d110d62019-01-30 19:49:49 +0000272 D.Visit(FC, FC);
Alexander Kornienkoebc17b52013-01-14 14:07:11 +0000273}
Richard Trieud215b8d2013-01-26 01:31:20 +0000274
Alp Tokeref6b0072014-01-04 13:47:14 +0000275LLVM_DUMP_METHOD void Comment::dumpColor() const {
Richard Trieud215b8d2013-01-26 01:31:20 +0000276 const FullComment *FC = dyn_cast<FullComment>(this);
Stephen Kelly570b2972018-12-09 13:18:55 +0000277 if (!FC)
278 return;
Craig Topper36250ad2014-05-12 05:36:57 +0000279 ASTDumper D(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
Stephen Kelly6d110d62019-01-30 19:49:49 +0000280 D.Visit(FC, FC);
Richard Trieud215b8d2013-01-26 01:31:20 +0000281}