blob: a1f9e3f539160348ba47e12ab6601633d4baf891 [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
Chandler Carruth3a022472012-12-04 09:13:33 +000014#include "clang/AST/ASTContext.h"
Stephen Kellyc4933012019-02-03 14:06:54 +000015#include "clang/AST/ASTNodeTraverser.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"
Stephen Kellyd8744a72018-12-05 21:12:39 +000018#include "clang/AST/TextNodeDumper.h"
David Majnemerd9b1a4f2015-11-04 03:40:30 +000019#include "clang/Basic/Builtins.h"
Alexander Kornienko90ff6072012-12-20 02:09:13 +000020#include "clang/Basic/Module.h"
Chris Lattner11e30d32007-08-30 06:17:34 +000021#include "clang/Basic/SourceManager.h"
Daniel Dunbar34a96c82009-12-03 09:13:13 +000022#include "llvm/Support/raw_ostream.h"
Chris Lattnercbe4f772007-08-08 22:51:59 +000023using namespace clang;
Alexander Kornienkoebc17b52013-01-14 14:07:11 +000024using namespace clang::comments;
Chris Lattnercbe4f772007-08-08 22:51:59 +000025
26//===----------------------------------------------------------------------===//
Alexander Kornienko18ec81b2012-12-13 13:59:55 +000027// ASTDumper Visitor
Chris Lattnercbe4f772007-08-08 22:51:59 +000028//===----------------------------------------------------------------------===//
29
30namespace {
Stephen Kelly27e948c2018-11-29 19:30:37 +000031
Stephen Kellyc4933012019-02-03 14:06:54 +000032class ASTDumper : public ASTNodeTraverser<ASTDumper, TextNodeDumper> {
Stephen Kellycdbfb302018-12-02 17:30:40 +000033
Stephen Kellyc4933012019-02-03 14:06:54 +000034 TextNodeDumper NodeDumper;
Stephen Kelly0da68ba2018-12-05 20:53:14 +000035
Stephen Kellyc4933012019-02-03 14:06:54 +000036 raw_ostream &OS;
Mike Stump11289f42009-09-09 15:08:12 +000037
Stephen Kellyc4933012019-02-03 14:06:54 +000038 const bool ShowColors;
Richard Smith3a36ac12017-03-09 22:00:01 +000039
Stephen Kellyc4933012019-02-03 14:06:54 +000040public:
41 ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
42 const SourceManager *SM)
43 : ASTDumper(OS, Traits, SM, SM && SM->getDiagnostics().getShowColors()) {}
Richard Trieud215b8d2013-01-26 01:31:20 +000044
Stephen Kellyc4933012019-02-03 14:06:54 +000045 ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
46 const SourceManager *SM, bool ShowColors)
47 : ASTDumper(OS, Traits, SM, ShowColors, LangOptions()) {}
48 ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
49 const SourceManager *SM, bool ShowColors,
50 const PrintingPolicy &PrintPolicy)
51 : NodeDumper(OS, ShowColors, SM, PrintPolicy, Traits), OS(OS),
52 ShowColors(ShowColors) {}
Richard Trieud215b8d2013-01-26 01:31:20 +000053
Stephen Kellyc4933012019-02-03 14:06:54 +000054 TextNodeDumper &doGetNodeDelegate() { return NodeDumper; }
Richard Smith3a36ac12017-03-09 22:00:01 +000055
Stephen Kellyc4933012019-02-03 14:06:54 +000056 void dumpLookups(const DeclContext *DC, bool DumpDecls);
Mike Stump11289f42009-09-09 15:08:12 +000057
Stephen Kellyc4933012019-02-03 14:06:54 +000058 template <typename SpecializationDecl>
59 void dumpTemplateDeclSpecialization(const SpecializationDecl *D,
60 bool DumpExplicitInst, bool DumpRefOnly);
61 template <typename TemplateDecl>
62 void dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst);
Alexander Kornienko90ff6072012-12-20 02:09:13 +000063
Stephen Kellyc4933012019-02-03 14:06:54 +000064 void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
65 void VisitClassTemplateDecl(const ClassTemplateDecl *D);
66 void VisitVarTemplateDecl(const VarTemplateDecl *D);
67};
Stephen Kellyee7e4cf2019-01-30 21:48:32 +000068} // namespace
Stephen Kelly0808a252019-01-30 20:03:47 +000069
Richard Smith35f986d2014-08-11 22:11:07 +000070void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
Stephen Kellyd8aeb552019-01-30 19:41:04 +000071 NodeDumper.AddChild([=] {
Richard Smithf7514452014-10-30 21:02:37 +000072 OS << "StoredDeclsMap ";
Stephen Kellyd8744a72018-12-05 21:12:39 +000073 NodeDumper.dumpBareDeclRef(cast<Decl>(DC));
Richard Smith33937e72013-06-22 21:49:40 +000074
Richard Smithf7514452014-10-30 21:02:37 +000075 const DeclContext *Primary = DC->getPrimaryContext();
76 if (Primary != DC) {
77 OS << " primary";
Stephen Kellyd8744a72018-12-05 21:12:39 +000078 NodeDumper.dumpPointer(cast<Decl>(Primary));
Richard Smith33937e72013-06-22 21:49:40 +000079 }
80
Richard Smithf7514452014-10-30 21:02:37 +000081 bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage();
Richard Smith35f986d2014-08-11 22:11:07 +000082
Stephen Kellyc4933012019-02-03 14:06:54 +000083 auto Range = getDeserialize()
Sam McCall091b1ef2018-01-16 12:33:46 +000084 ? Primary->lookups()
85 : Primary->noload_lookups(/*PreserveInternalState=*/true);
86 for (auto I = Range.begin(), E = Range.end(); I != E; ++I) {
Richard Smithf7514452014-10-30 21:02:37 +000087 DeclarationName Name = I.getLookupName();
Richard Smith3a36ac12017-03-09 22:00:01 +000088 DeclContextLookupResult R = *I;
Richard Smith35f986d2014-08-11 22:11:07 +000089
Stephen Kellyd8aeb552019-01-30 19:41:04 +000090 NodeDumper.AddChild([=] {
Richard Smithf7514452014-10-30 21:02:37 +000091 OS << "DeclarationName ";
92 {
Stephen Kelly27e948c2018-11-29 19:30:37 +000093 ColorScope Color(OS, ShowColors, DeclNameColor);
Richard Smithf7514452014-10-30 21:02:37 +000094 OS << '\'' << Name << '\'';
95 }
Richard Smith35f986d2014-08-11 22:11:07 +000096
Richard Smithf7514452014-10-30 21:02:37 +000097 for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end();
98 RI != RE; ++RI) {
Stephen Kellyd8aeb552019-01-30 19:41:04 +000099 NodeDumper.AddChild([=] {
Stephen Kellyd8744a72018-12-05 21:12:39 +0000100 NodeDumper.dumpBareDeclRef(*RI);
Richard Smithf7514452014-10-30 21:02:37 +0000101
102 if ((*RI)->isHidden())
103 OS << " hidden";
104
105 // If requested, dump the redecl chain for this lookup.
106 if (DumpDecls) {
107 // Dump earliest decl first.
108 std::function<void(Decl *)> DumpWithPrev = [&](Decl *D) {
109 if (Decl *Prev = D->getPreviousDecl())
110 DumpWithPrev(Prev);
Stephen Kelly6d110d62019-01-30 19:49:49 +0000111 Visit(D);
Richard Smithf7514452014-10-30 21:02:37 +0000112 };
113 DumpWithPrev(*RI);
114 }
115 });
116 }
117 });
Richard Smith33937e72013-06-22 21:49:40 +0000118 }
Richard Smith33937e72013-06-22 21:49:40 +0000119
Richard Smithf7514452014-10-30 21:02:37 +0000120 if (HasUndeserializedLookups) {
Stephen Kellyd8aeb552019-01-30 19:41:04 +0000121 NodeDumper.AddChild([=] {
Stephen Kelly27e948c2018-11-29 19:30:37 +0000122 ColorScope Color(OS, ShowColors, UndeserializedColor);
Richard Smithf7514452014-10-30 21:02:37 +0000123 OS << "<undeserialized lookups>";
124 });
125 }
126 });
Richard Smith33937e72013-06-22 21:49:40 +0000127}
128
Stephen Kelly24136382018-12-09 13:33:30 +0000129template <typename SpecializationDecl>
130void ASTDumper::dumpTemplateDeclSpecialization(const SpecializationDecl *D,
131 bool DumpExplicitInst,
132 bool DumpRefOnly) {
Richard Smithcbdf7332014-03-18 02:07:28 +0000133 bool DumpedAny = false;
Stephen Kellyaaebc5f2019-01-19 09:57:51 +0000134 for (const auto *RedeclWithBadType : D->redecls()) {
Richard Smithcbdf7332014-03-18 02:07:28 +0000135 // FIXME: The redecls() range sometimes has elements of a less-specific
136 // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
137 // us TagDecls, and should give CXXRecordDecls).
138 auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
139 if (!Redecl) {
140 // Found the injected-class-name for a class template. This will be dumped
141 // as part of its surrounding class so we don't need to dump it here.
142 assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
143 "expected an injected-class-name");
144 continue;
145 }
146
147 switch (Redecl->getTemplateSpecializationKind()) {
148 case TSK_ExplicitInstantiationDeclaration:
149 case TSK_ExplicitInstantiationDefinition:
150 if (!DumpExplicitInst)
151 break;
Adrian Prantlf3b3ccd2017-12-19 22:06:11 +0000152 LLVM_FALLTHROUGH;
Richard Smithcbdf7332014-03-18 02:07:28 +0000153 case TSK_Undeclared:
154 case TSK_ImplicitInstantiation:
Richard Smithf7514452014-10-30 21:02:37 +0000155 if (DumpRefOnly)
Stephen Kellyd186dbc2019-01-08 23:11:24 +0000156 NodeDumper.dumpDeclRef(Redecl);
Richard Smithf7514452014-10-30 21:02:37 +0000157 else
Stephen Kelly6d110d62019-01-30 19:49:49 +0000158 Visit(Redecl);
Richard Smithcbdf7332014-03-18 02:07:28 +0000159 DumpedAny = true;
160 break;
161 case TSK_ExplicitSpecialization:
162 break;
163 }
164 }
165
166 // Ensure we dump at least one decl for each specialization.
167 if (!DumpedAny)
Stephen Kellyd186dbc2019-01-08 23:11:24 +0000168 NodeDumper.dumpDeclRef(D);
Richard Smithcbdf7332014-03-18 02:07:28 +0000169}
170
Stephen Kelly24136382018-12-09 13:33:30 +0000171template <typename TemplateDecl>
172void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) {
Alexander Kornienko90ff6072012-12-20 02:09:13 +0000173 dumpTemplateParameters(D->getTemplateParameters());
Richard Smithdcc2c452014-03-17 23:00:06 +0000174
Stephen Kelly6d110d62019-01-30 19:49:49 +0000175 Visit(D->getTemplatedDecl());
Richard Smithdcc2c452014-03-17 23:00:06 +0000176
Stephen Kellyaaebc5f2019-01-19 09:57:51 +0000177 for (const auto *Child : D->specializations())
Stephen Kelly24136382018-12-09 13:33:30 +0000178 dumpTemplateDeclSpecialization(Child, DumpExplicitInst,
179 !D->isCanonicalDecl());
Alexander Kornienko90ff6072012-12-20 02:09:13 +0000180}
181
Richard Smith20ade552014-03-17 23:34:53 +0000182void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
183 // FIXME: We don't add a declaration of a function template specialization
184 // to its context when it's explicitly instantiated, so dump explicit
185 // instantiations when we dump the template itself.
Stephen Kelly24136382018-12-09 13:33:30 +0000186 dumpTemplateDecl(D, true);
Richard Smith20ade552014-03-17 23:34:53 +0000187}
188
Alexander Kornienko540bacb2013-02-01 12:35:51 +0000189void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
Stephen Kelly24136382018-12-09 13:33:30 +0000190 dumpTemplateDecl(D, false);
Alexander Kornienko90ff6072012-12-20 02:09:13 +0000191}
192
Richard Smithd25789a2013-09-18 01:36:02 +0000193void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
Stephen Kelly24136382018-12-09 13:33:30 +0000194 dumpTemplateDecl(D, false);
Richard Smithd25789a2013-09-18 01:36:02 +0000195}
196
Chris Lattnercbe4f772007-08-08 22:51:59 +0000197//===----------------------------------------------------------------------===//
Richard Smithd5e7ff82014-10-31 01:17:45 +0000198// Type method implementations
199//===----------------------------------------------------------------------===//
200
201void QualType::dump(const char *msg) const {
202 if (msg)
203 llvm::errs() << msg << ": ";
204 dump();
205}
206
Richard Smith14d04842016-11-02 23:57:18 +0000207LLVM_DUMP_METHOD void QualType::dump() const { dump(llvm::errs()); }
208
209LLVM_DUMP_METHOD void QualType::dump(llvm::raw_ostream &OS) const {
210 ASTDumper Dumper(OS, nullptr, nullptr);
Stephen Kelly6d110d62019-01-30 19:49:49 +0000211 Dumper.Visit(*this);
Richard Smithd5e7ff82014-10-31 01:17:45 +0000212}
213
Richard Smith14d04842016-11-02 23:57:18 +0000214LLVM_DUMP_METHOD void Type::dump() const { dump(llvm::errs()); }
215
216LLVM_DUMP_METHOD void Type::dump(llvm::raw_ostream &OS) const {
217 QualType(this, 0).dump(OS);
218}
Richard Smithd5e7ff82014-10-31 01:17:45 +0000219
220//===----------------------------------------------------------------------===//
Alexander Kornienko90ff6072012-12-20 02:09:13 +0000221// Decl method implementations
222//===----------------------------------------------------------------------===//
223
Alp Tokeref6b0072014-01-04 13:47:14 +0000224LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); }
Alexander Kornienko90ff6072012-12-20 02:09:13 +0000225
Aaron Ballman2ce598a2019-05-13 21:39:55 +0000226LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize,
227 ASTDumpOutputFormat Format) const {
Aaron Ballman8c208282017-12-21 21:42:42 +0000228 const ASTContext &Ctx = getASTContext();
229 const SourceManager &SM = Ctx.getSourceManager();
Aaron Ballman2ce598a2019-05-13 21:39:55 +0000230
231 if (ADOF_JSON == Format) {
232 JSONDumper P(OS, SM, Ctx.getPrintingPolicy());
233 (void)Deserialize; // FIXME?
234 P.Visit(this);
235 } else {
236 ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &SM,
237 SM.getDiagnostics().getShowColors(), Ctx.getPrintingPolicy());
238 P.setDeserialize(Deserialize);
239 P.Visit(this);
240 }
Alexander Kornienko90ff6072012-12-20 02:09:13 +0000241}
242
Alp Tokeref6b0072014-01-04 13:47:14 +0000243LLVM_DUMP_METHOD void Decl::dumpColor() const {
Aaron Ballman8c208282017-12-21 21:42:42 +0000244 const ASTContext &Ctx = getASTContext();
245 ASTDumper P(llvm::errs(), &Ctx.getCommentCommandTraits(),
246 &Ctx.getSourceManager(), /*ShowColors*/ true,
247 Ctx.getPrintingPolicy());
Stephen Kelly6d110d62019-01-30 19:49:49 +0000248 P.Visit(this);
Richard Trieud215b8d2013-01-26 01:31:20 +0000249}
Richard Smith33937e72013-06-22 21:49:40 +0000250
Alp Tokeref6b0072014-01-04 13:47:14 +0000251LLVM_DUMP_METHOD void DeclContext::dumpLookups() const {
Richard Smith6ea05822013-06-24 01:45:33 +0000252 dumpLookups(llvm::errs());
253}
254
Richard Smith35f986d2014-08-11 22:11:07 +0000255LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS,
Richard Smith3a36ac12017-03-09 22:00:01 +0000256 bool DumpDecls,
257 bool Deserialize) const {
Richard Smith33937e72013-06-22 21:49:40 +0000258 const DeclContext *DC = this;
259 while (!DC->isTranslationUnit())
260 DC = DC->getParent();
261 ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
Aaron Ballman8c208282017-12-21 21:42:42 +0000262 const SourceManager &SM = Ctx.getSourceManager();
263 ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager(),
264 SM.getDiagnostics().getShowColors(), Ctx.getPrintingPolicy());
Richard Smith3a36ac12017-03-09 22:00:01 +0000265 P.setDeserialize(Deserialize);
Richard Smith35f986d2014-08-11 22:11:07 +0000266 P.dumpLookups(this, DumpDecls);
Richard Smith33937e72013-06-22 21:49:40 +0000267}
268
Alexander Kornienko90ff6072012-12-20 02:09:13 +0000269//===----------------------------------------------------------------------===//
Chris Lattnercbe4f772007-08-08 22:51:59 +0000270// Stmt method implementations
271//===----------------------------------------------------------------------===//
272
Alp Tokeref6b0072014-01-04 13:47:14 +0000273LLVM_DUMP_METHOD void Stmt::dump(SourceManager &SM) const {
Argyrios Kyrtzidisc049f752010-08-09 10:54:31 +0000274 dump(llvm::errs(), SM);
275}
276
Alp Tokeref6b0072014-01-04 13:47:14 +0000277LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
Craig Topper36250ad2014-05-12 05:36:57 +0000278 ASTDumper P(OS, nullptr, &SM);
Stephen Kelly6d110d62019-01-30 19:49:49 +0000279 P.Visit(this);
Chris Lattner779d5d92007-08-30 00:40:08 +0000280}
281
Faisal Vali2da8ed92015-03-22 13:35:56 +0000282LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS) const {
283 ASTDumper P(OS, nullptr, nullptr);
Stephen Kelly6d110d62019-01-30 19:49:49 +0000284 P.Visit(this);
Faisal Vali2da8ed92015-03-22 13:35:56 +0000285}
286
Alp Tokeref6b0072014-01-04 13:47:14 +0000287LLVM_DUMP_METHOD void Stmt::dump() const {
Craig Topper36250ad2014-05-12 05:36:57 +0000288 ASTDumper P(llvm::errs(), nullptr, nullptr);
Stephen Kelly6d110d62019-01-30 19:49:49 +0000289 P.Visit(this);
Chris Lattnercbe4f772007-08-08 22:51:59 +0000290}
Alexander Kornienkoebc17b52013-01-14 14:07:11 +0000291
Alp Tokeref6b0072014-01-04 13:47:14 +0000292LLVM_DUMP_METHOD void Stmt::dumpColor() const {
Craig Topper36250ad2014-05-12 05:36:57 +0000293 ASTDumper P(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
Stephen Kelly6d110d62019-01-30 19:49:49 +0000294 P.Visit(this);
Richard Trieud215b8d2013-01-26 01:31:20 +0000295}
296
Alexander Kornienkoebc17b52013-01-14 14:07:11 +0000297//===----------------------------------------------------------------------===//
298// Comment method implementations
299//===----------------------------------------------------------------------===//
300
Craig Topper36250ad2014-05-12 05:36:57 +0000301LLVM_DUMP_METHOD void Comment::dump() const {
302 dump(llvm::errs(), nullptr, nullptr);
303}
Alexander Kornienkoebc17b52013-01-14 14:07:11 +0000304
Alp Tokeref6b0072014-01-04 13:47:14 +0000305LLVM_DUMP_METHOD void Comment::dump(const ASTContext &Context) const {
Alexander Kornienkoebc17b52013-01-14 14:07:11 +0000306 dump(llvm::errs(), &Context.getCommentCommandTraits(),
307 &Context.getSourceManager());
308}
309
Alexander Kornienko00911f12013-01-15 12:20:21 +0000310void Comment::dump(raw_ostream &OS, const CommandTraits *Traits,
Alexander Kornienkoebc17b52013-01-14 14:07:11 +0000311 const SourceManager *SM) const {
312 const FullComment *FC = dyn_cast<FullComment>(this);
Stephen Kelly570b2972018-12-09 13:18:55 +0000313 if (!FC)
314 return;
Alexander Kornienkoebc17b52013-01-14 14:07:11 +0000315 ASTDumper D(OS, Traits, SM);
Stephen Kelly6d110d62019-01-30 19:49:49 +0000316 D.Visit(FC, FC);
Alexander Kornienkoebc17b52013-01-14 14:07:11 +0000317}
Richard Trieud215b8d2013-01-26 01:31:20 +0000318
Alp Tokeref6b0072014-01-04 13:47:14 +0000319LLVM_DUMP_METHOD void Comment::dumpColor() const {
Richard Trieud215b8d2013-01-26 01:31:20 +0000320 const FullComment *FC = dyn_cast<FullComment>(this);
Stephen Kelly570b2972018-12-09 13:18:55 +0000321 if (!FC)
322 return;
Craig Topper36250ad2014-05-12 05:36:57 +0000323 ASTDumper D(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
Stephen Kelly6d110d62019-01-30 19:49:49 +0000324 D.Visit(FC, FC);
Richard Trieud215b8d2013-01-26 01:31:20 +0000325}