1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | #include "clang/AST/ASTContext.h" |
15 | #include "clang/AST/ASTNodeTraverser.h" |
16 | #include "clang/AST/DeclLookups.h" |
17 | #include "clang/AST/TextNodeDumper.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 | |
26 | |
27 | |
28 | |
29 | namespace { |
30 | |
31 | class ASTDumper : public ASTNodeTraverser<ASTDumper, TextNodeDumper> { |
32 | |
33 | TextNodeDumper NodeDumper; |
34 | |
35 | raw_ostream &OS; |
36 | |
37 | const bool ShowColors; |
38 | |
39 | public: |
40 | ASTDumper(raw_ostream &OS, const CommandTraits *Traits, |
41 | const SourceManager *SM) |
42 | : ASTDumper(OS, Traits, SM, SM && SM->getDiagnostics().getShowColors()) {} |
43 | |
44 | ASTDumper(raw_ostream &OS, const CommandTraits *Traits, |
45 | const SourceManager *SM, bool ShowColors) |
46 | : ASTDumper(OS, Traits, SM, ShowColors, LangOptions()) {} |
47 | ASTDumper(raw_ostream &OS, const CommandTraits *Traits, |
48 | const SourceManager *SM, bool ShowColors, |
49 | const PrintingPolicy &PrintPolicy) |
50 | : NodeDumper(OS, ShowColors, SM, PrintPolicy, Traits), OS(OS), |
51 | ShowColors(ShowColors) {} |
52 | |
53 | TextNodeDumper &doGetNodeDelegate() { return NodeDumper; } |
54 | |
55 | void dumpLookups(const DeclContext *DC, bool DumpDecls); |
56 | |
57 | template <typename SpecializationDecl> |
58 | void dumpTemplateDeclSpecialization(const SpecializationDecl *D, |
59 | bool DumpExplicitInst, bool DumpRefOnly); |
60 | template <typename TemplateDecl> |
61 | void dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst); |
62 | |
63 | void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D); |
64 | void VisitClassTemplateDecl(const ClassTemplateDecl *D); |
65 | void VisitVarTemplateDecl(const VarTemplateDecl *D); |
66 | }; |
67 | } |
68 | |
69 | void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) { |
70 | NodeDumper.AddChild([=] { |
71 | OS << "StoredDeclsMap "; |
72 | NodeDumper.dumpBareDeclRef(cast<Decl>(DC)); |
73 | |
74 | const DeclContext *Primary = DC->getPrimaryContext(); |
75 | if (Primary != DC) { |
76 | OS << " primary"; |
77 | NodeDumper.dumpPointer(cast<Decl>(Primary)); |
78 | } |
79 | |
80 | bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage(); |
81 | |
82 | auto Range = getDeserialize() |
83 | ? Primary->lookups() |
84 | : Primary->noload_lookups(); |
85 | for (auto I = Range.begin(), E = Range.end(); I != E; ++I) { |
86 | DeclarationName Name = I.getLookupName(); |
87 | DeclContextLookupResult R = *I; |
88 | |
89 | NodeDumper.AddChild([=] { |
90 | OS << "DeclarationName "; |
91 | { |
92 | ColorScope Color(OS, ShowColors, DeclNameColor); |
93 | OS << '\'' << Name << '\''; |
94 | } |
95 | |
96 | for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end(); |
97 | RI != RE; ++RI) { |
98 | NodeDumper.AddChild([=] { |
99 | NodeDumper.dumpBareDeclRef(*RI); |
100 | |
101 | if ((*RI)->isHidden()) |
102 | OS << " hidden"; |
103 | |
104 | |
105 | if (DumpDecls) { |
106 | |
107 | std::function<void(Decl *)> DumpWithPrev = [&](Decl *D) { |
108 | if (Decl *Prev = D->getPreviousDecl()) |
109 | DumpWithPrev(Prev); |
110 | Visit(D); |
111 | }; |
112 | DumpWithPrev(*RI); |
113 | } |
114 | }); |
115 | } |
116 | }); |
117 | } |
118 | |
119 | if (HasUndeserializedLookups) { |
120 | NodeDumper.AddChild([=] { |
121 | ColorScope Color(OS, ShowColors, UndeserializedColor); |
122 | OS << "<undeserialized lookups>"; |
123 | }); |
124 | } |
125 | }); |
126 | } |
127 | |
128 | template <typename SpecializationDecl> |
129 | void ASTDumper::dumpTemplateDeclSpecialization(const SpecializationDecl *D, |
130 | bool DumpExplicitInst, |
131 | bool DumpRefOnly) { |
132 | bool DumpedAny = false; |
133 | for (const auto *RedeclWithBadType : D->redecls()) { |
134 | |
135 | |
136 | |
137 | auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType); |
138 | if (!Redecl) { |
139 | |
140 | |
141 | (0) . __assert_fail ("isa(RedeclWithBadType) && \"expected an injected-class-name\"", "/home/seafit/code_projects/clang_source/clang/lib/AST/ASTDumper.cpp", 142, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(isa<CXXRecordDecl>(RedeclWithBadType) && |
142 | (0) . __assert_fail ("isa(RedeclWithBadType) && \"expected an injected-class-name\"", "/home/seafit/code_projects/clang_source/clang/lib/AST/ASTDumper.cpp", 142, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true"> "expected an injected-class-name"); |
143 | continue; |
144 | } |
145 | |
146 | switch (Redecl->getTemplateSpecializationKind()) { |
147 | case TSK_ExplicitInstantiationDeclaration: |
148 | case TSK_ExplicitInstantiationDefinition: |
149 | if (!DumpExplicitInst) |
150 | break; |
151 | LLVM_FALLTHROUGH; |
152 | case TSK_Undeclared: |
153 | case TSK_ImplicitInstantiation: |
154 | if (DumpRefOnly) |
155 | NodeDumper.dumpDeclRef(Redecl); |
156 | else |
157 | Visit(Redecl); |
158 | DumpedAny = true; |
159 | break; |
160 | case TSK_ExplicitSpecialization: |
161 | break; |
162 | } |
163 | } |
164 | |
165 | |
166 | if (!DumpedAny) |
167 | NodeDumper.dumpDeclRef(D); |
168 | } |
169 | |
170 | template <typename TemplateDecl> |
171 | void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) { |
172 | dumpTemplateParameters(D->getTemplateParameters()); |
173 | |
174 | Visit(D->getTemplatedDecl()); |
175 | |
176 | for (const auto *Child : D->specializations()) |
177 | dumpTemplateDeclSpecialization(Child, DumpExplicitInst, |
178 | !D->isCanonicalDecl()); |
179 | } |
180 | |
181 | void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) { |
182 | |
183 | |
184 | |
185 | dumpTemplateDecl(D, true); |
186 | } |
187 | |
188 | void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) { |
189 | dumpTemplateDecl(D, false); |
190 | } |
191 | |
192 | void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) { |
193 | dumpTemplateDecl(D, false); |
194 | } |
195 | |
196 | |
197 | |
198 | |
199 | |
200 | void QualType::dump(const char *msg) const { |
201 | if (msg) |
202 | llvm::errs() << msg << ": "; |
203 | dump(); |
204 | } |
205 | |
206 | LLVM_DUMP_METHOD void QualType::dump() const { dump(llvm::errs()); } |
207 | |
208 | LLVM_DUMP_METHOD void QualType::dump(llvm::raw_ostream &OS) const { |
209 | ASTDumper Dumper(OS, nullptr, nullptr); |
210 | Dumper.Visit(*this); |
211 | } |
212 | |
213 | LLVM_DUMP_METHOD void Type::dump() const { dump(llvm::errs()); } |
214 | |
215 | LLVM_DUMP_METHOD void Type::dump(llvm::raw_ostream &OS) const { |
216 | QualType(this, 0).dump(OS); |
217 | } |
218 | |
219 | |
220 | |
221 | |
222 | |
223 | LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); } |
224 | |
225 | LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize) const { |
226 | const ASTContext &Ctx = getASTContext(); |
227 | const SourceManager &SM = Ctx.getSourceManager(); |
228 | ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &SM, |
229 | SM.getDiagnostics().getShowColors(), Ctx.getPrintingPolicy()); |
230 | P.setDeserialize(Deserialize); |
231 | P.Visit(this); |
232 | } |
233 | |
234 | LLVM_DUMP_METHOD void Decl::dumpColor() const { |
235 | const ASTContext &Ctx = getASTContext(); |
236 | ASTDumper P(llvm::errs(), &Ctx.getCommentCommandTraits(), |
237 | &Ctx.getSourceManager(), true, |
238 | Ctx.getPrintingPolicy()); |
239 | P.Visit(this); |
240 | } |
241 | |
242 | LLVM_DUMP_METHOD void DeclContext::dumpLookups() const { |
243 | dumpLookups(llvm::errs()); |
244 | } |
245 | |
246 | LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS, |
247 | bool DumpDecls, |
248 | bool Deserialize) const { |
249 | const DeclContext *DC = this; |
250 | while (!DC->isTranslationUnit()) |
251 | DC = DC->getParent(); |
252 | ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext(); |
253 | const SourceManager &SM = Ctx.getSourceManager(); |
254 | ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager(), |
255 | SM.getDiagnostics().getShowColors(), Ctx.getPrintingPolicy()); |
256 | P.setDeserialize(Deserialize); |
257 | P.dumpLookups(this, DumpDecls); |
258 | } |
259 | |
260 | |
261 | |
262 | |
263 | |
264 | LLVM_DUMP_METHOD void Stmt::dump(SourceManager &SM) const { |
265 | dump(llvm::errs(), SM); |
266 | } |
267 | |
268 | LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS, SourceManager &SM) const { |
269 | ASTDumper P(OS, nullptr, &SM); |
270 | P.Visit(this); |
271 | } |
272 | |
273 | LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS) const { |
274 | ASTDumper P(OS, nullptr, nullptr); |
275 | P.Visit(this); |
276 | } |
277 | |
278 | LLVM_DUMP_METHOD void Stmt::dump() const { |
279 | ASTDumper P(llvm::errs(), nullptr, nullptr); |
280 | P.Visit(this); |
281 | } |
282 | |
283 | LLVM_DUMP_METHOD void Stmt::dumpColor() const { |
284 | ASTDumper P(llvm::errs(), nullptr, nullptr, ); |
285 | P.Visit(this); |
286 | } |
287 | |
288 | |
289 | |
290 | |
291 | |
292 | LLVM_DUMP_METHOD void Comment::() const { |
293 | dump(llvm::errs(), nullptr, nullptr); |
294 | } |
295 | |
296 | LLVM_DUMP_METHOD void Comment::(const ASTContext &Context) const { |
297 | dump(llvm::errs(), &Context.getCommentCommandTraits(), |
298 | &Context.getSourceManager()); |
299 | } |
300 | |
301 | void Comment::dump(raw_ostream &OS, const CommandTraits *Traits, |
302 | const SourceManager *SM) const { |
303 | const FullComment *FC = dyn_cast<FullComment>(this); |
304 | if (!FC) |
305 | return; |
306 | ASTDumper D(OS, Traits, SM); |
307 | D.Visit(FC, FC); |
308 | } |
309 | |
310 | LLVM_DUMP_METHOD void Comment::() const { |
311 | const FullComment *FC = dyn_cast<FullComment>(this); |
312 | if (!FC) |
313 | return; |
314 | ASTDumper D(llvm::errs(), nullptr, nullptr, ); |
315 | D.Visit(FC, FC); |
316 | } |
317 | |