]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/clang/lib/AST/ASTDumper.cpp
MFC r355940:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / clang / lib / AST / ASTDumper.cpp
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"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/DeclLookups.h"
17 #include "clang/AST/JSONNodeDumper.h"
18 #include "clang/Basic/Builtins.h"
19 #include "clang/Basic/Module.h"
20 #include "clang/Basic/SourceManager.h"
21 #include "llvm/Support/raw_ostream.h"
22 using namespace clang;
23 using namespace clang::comments;
24
25 void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
26   NodeDumper.AddChild([=] {
27     OS << "StoredDeclsMap ";
28     NodeDumper.dumpBareDeclRef(cast<Decl>(DC));
29
30     const DeclContext *Primary = DC->getPrimaryContext();
31     if (Primary != DC) {
32       OS << " primary";
33       NodeDumper.dumpPointer(cast<Decl>(Primary));
34     }
35
36     bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage();
37
38     auto Range = getDeserialize()
39                      ? Primary->lookups()
40                      : Primary->noload_lookups(/*PreserveInternalState=*/true);
41     for (auto I = Range.begin(), E = Range.end(); I != E; ++I) {
42       DeclarationName Name = I.getLookupName();
43       DeclContextLookupResult R = *I;
44
45       NodeDumper.AddChild([=] {
46         OS << "DeclarationName ";
47         {
48           ColorScope Color(OS, ShowColors, DeclNameColor);
49           OS << '\'' << Name << '\'';
50         }
51
52         for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end();
53              RI != RE; ++RI) {
54           NodeDumper.AddChild([=] {
55             NodeDumper.dumpBareDeclRef(*RI);
56
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);
66                 Visit(D);
67               };
68               DumpWithPrev(*RI);
69             }
70           });
71         }
72       });
73     }
74
75     if (HasUndeserializedLookups) {
76       NodeDumper.AddChild([=] {
77         ColorScope Color(OS, ShowColors, UndeserializedColor);
78         OS << "<undeserialized lookups>";
79       });
80     }
81   });
82 }
83
84 template <typename SpecializationDecl>
85 void ASTDumper::dumpTemplateDeclSpecialization(const SpecializationDecl *D,
86                                                bool DumpExplicitInst,
87                                                bool DumpRefOnly) {
88   bool DumpedAny = false;
89   for (const auto *RedeclWithBadType : D->redecls()) {
90     // 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;
107       LLVM_FALLTHROUGH;
108     case TSK_Undeclared:
109     case TSK_ImplicitInstantiation:
110       if (DumpRefOnly)
111         NodeDumper.dumpDeclRef(Redecl);
112       else
113         Visit(Redecl);
114       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)
123     NodeDumper.dumpDeclRef(D);
124 }
125
126 template <typename TemplateDecl>
127 void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) {
128   dumpTemplateParameters(D->getTemplateParameters());
129
130   Visit(D->getTemplatedDecl());
131
132   for (const auto *Child : D->specializations())
133     dumpTemplateDeclSpecialization(Child, DumpExplicitInst,
134                                    !D->isCanonicalDecl());
135 }
136
137 void 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.
141   dumpTemplateDecl(D, true);
142 }
143
144 void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
145   dumpTemplateDecl(D, false);
146 }
147
148 void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
149   dumpTemplateDecl(D, false);
150 }
151
152 //===----------------------------------------------------------------------===//
153 // Type method implementations
154 //===----------------------------------------------------------------------===//
155
156 void QualType::dump(const char *msg) const {
157   if (msg)
158     llvm::errs() << msg << ": ";
159   dump();
160 }
161
162 LLVM_DUMP_METHOD void QualType::dump() const { dump(llvm::errs()); }
163
164 LLVM_DUMP_METHOD void QualType::dump(llvm::raw_ostream &OS) const {
165   ASTDumper Dumper(OS, nullptr, nullptr);
166   Dumper.Visit(*this);
167 }
168
169 LLVM_DUMP_METHOD void Type::dump() const { dump(llvm::errs()); }
170
171 LLVM_DUMP_METHOD void Type::dump(llvm::raw_ostream &OS) const {
172   QualType(this, 0).dump(OS);
173 }
174
175 //===----------------------------------------------------------------------===//
176 // Decl method implementations
177 //===----------------------------------------------------------------------===//
178
179 LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); }
180
181 LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize,
182                                  ASTDumpOutputFormat Format) const {
183   ASTContext &Ctx = getASTContext();
184   const SourceManager &SM = Ctx.getSourceManager();
185
186   if (ADOF_JSON == Format) {
187     JSONDumper P(OS, SM, Ctx, Ctx.getPrintingPolicy(),
188                  &Ctx.getCommentCommandTraits());
189     (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   }
197 }
198
199 LLVM_DUMP_METHOD void Decl::dumpColor() const {
200   const ASTContext &Ctx = getASTContext();
201   ASTDumper P(llvm::errs(), &Ctx.getCommentCommandTraits(),
202               &Ctx.getSourceManager(), /*ShowColors*/ true,
203               Ctx.getPrintingPolicy());
204   P.Visit(this);
205 }
206
207 LLVM_DUMP_METHOD void DeclContext::dumpLookups() const {
208   dumpLookups(llvm::errs());
209 }
210
211 LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS,
212                                                bool DumpDecls,
213                                                bool Deserialize) const {
214   const DeclContext *DC = this;
215   while (!DC->isTranslationUnit())
216     DC = DC->getParent();
217   ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
218   const SourceManager &SM = Ctx.getSourceManager();
219   ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager(),
220               SM.getDiagnostics().getShowColors(), Ctx.getPrintingPolicy());
221   P.setDeserialize(Deserialize);
222   P.dumpLookups(this, DumpDecls);
223 }
224
225 //===----------------------------------------------------------------------===//
226 // Stmt method implementations
227 //===----------------------------------------------------------------------===//
228
229 LLVM_DUMP_METHOD void Stmt::dump(SourceManager &SM) const {
230   dump(llvm::errs(), SM);
231 }
232
233 LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
234   ASTDumper P(OS, nullptr, &SM);
235   P.Visit(this);
236 }
237
238 LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS) const {
239   ASTDumper P(OS, nullptr, nullptr);
240   P.Visit(this);
241 }
242
243 LLVM_DUMP_METHOD void Stmt::dump() const {
244   ASTDumper P(llvm::errs(), nullptr, nullptr);
245   P.Visit(this);
246 }
247
248 LLVM_DUMP_METHOD void Stmt::dumpColor() const {
249   ASTDumper P(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
250   P.Visit(this);
251 }
252
253 //===----------------------------------------------------------------------===//
254 // Comment method implementations
255 //===----------------------------------------------------------------------===//
256
257 LLVM_DUMP_METHOD void Comment::dump() const {
258   dump(llvm::errs(), nullptr, nullptr);
259 }
260
261 LLVM_DUMP_METHOD void Comment::dump(const ASTContext &Context) const {
262   dump(llvm::errs(), &Context.getCommentCommandTraits(),
263        &Context.getSourceManager());
264 }
265
266 void Comment::dump(raw_ostream &OS, const CommandTraits *Traits,
267                    const SourceManager *SM) const {
268   const FullComment *FC = dyn_cast<FullComment>(this);
269   if (!FC)
270     return;
271   ASTDumper D(OS, Traits, SM);
272   D.Visit(FC, FC);
273 }
274
275 LLVM_DUMP_METHOD void Comment::dumpColor() const {
276   const FullComment *FC = dyn_cast<FullComment>(this);
277   if (!FC)
278     return;
279   ASTDumper D(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
280   D.Visit(FC, FC);
281 }