blob: 76be4408fa2443b6a101c5f772fc2e756e116a28 [file] [log] [blame]
Sean Callanan6e74dbb2011-02-01 23:43:26 +00001//===-- ASTDumper.cpp -------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Expression/ASTDumper.h"
11
12using namespace lldb_private;
13using namespace clang;
14
15// MARK: Utility functions
16
17static const char* SfB (bool b)
18{
19 return b ? "True" : "False";
20}
21
22// MARK: DeclVisitor
23
24void ASTDumper::VisitDecl (clang::Decl *decl)
25{
26 m_stream.Indent(); m_stream.Printf("class : Decl\n");
27 m_stream.Indent(); m_stream.Printf("getDeclKindName() : %s\n", decl->getDeclKindName());
28 m_stream.Indent(); m_stream.Printf("getTranslationUnitDecl() : ");
29
30 TranslationUnitDecl *translation_unit_decl = decl->getTranslationUnitDecl();
31
32 if (translation_unit_decl)
33 {
34 if (KeepDumping() && !Visiting(translation_unit_decl))
35 {
36 m_stream.Printf("\n");
37
38 PushIndent();
39 WillVisit(translation_unit_decl);
40 VisitTranslationUnitDecl(translation_unit_decl);
41 DidVisit(translation_unit_decl);
42 PopIndent();
43 }
44 else
45 {
46 m_stream.Printf("capped\n");
47 }
48 }
49 else
50 {
51 m_stream.Printf("~\n");
52 }
53
54 m_stream.Indent(); m_stream.Printf("getAccess() : ");
55 switch (decl->getAccess())
56 {
57 default: m_stream.Printf("~\n");
58 case AS_public: m_stream.Printf("AS_public\n");
59 case AS_protected: m_stream.Printf("AS_protected\n");
60 case AS_private: m_stream.Printf("AS_private\n");
61 case AS_none: m_stream.Printf("AS_none\n");
62 }
63 m_stream.Indent(); m_stream.Printf("getMaxAlignment() : %d\n", decl->getMaxAlignment());
64 m_stream.Indent(); m_stream.Printf("isInvalidDecl() : %s\n", SfB(decl->isInvalidDecl()));
65 m_stream.Indent(); m_stream.Printf("isImplicit() : %s\n", SfB(decl->isImplicit()));
66 m_stream.Indent(); m_stream.Printf("isUsed() : %s\n", SfB(decl->isUsed()));
67 m_stream.Indent(); m_stream.Printf("isOutOfLine() : %s\n", SfB(decl->isOutOfLine()));
68 m_stream.Indent(); m_stream.Printf("isCanonicalDecl() : %s\n", SfB(decl->isCanonicalDecl()));
69 m_stream.Indent(); m_stream.Printf("hasBody() : %s\n", SfB(decl->hasBody()));
70 m_stream.Indent(); m_stream.Printf("isTemplateParameter() : %s\n", SfB(decl->isTemplateParameter()));
71 m_stream.Indent(); m_stream.Printf("isTemplateParameterPack() : %s\n", SfB(decl->isTemplateParameterPack()));
72 m_stream.Indent(); m_stream.Printf("isParameterPack() : %s\n", SfB(decl->isParameterPack()));
73 m_stream.Indent(); m_stream.Printf("isFunctionOrFunctionTemplate() : %s\n", SfB(decl->isFunctionOrFunctionTemplate()));
74 m_stream.Indent(); m_stream.Printf("getFriendObjectKind() : ");
75 switch (decl->getFriendObjectKind())
76 {
77 default: m_stream.Printf("~\n"); break;
78 case Decl::FOK_None: m_stream.Printf("FOK_None\n"); break;
79 case Decl::FOK_Declared: m_stream.Printf("FOK_Declared\n"); break;
80 case Decl::FOK_Undeclared: m_stream.Printf("FOK_Undeclared\n"); break;
81 }
82}
83
84void ASTDumper::VisitTranslationUnitDecl (clang::TranslationUnitDecl *translation_unit_decl)
85{
86 m_stream.Indent(); m_stream.Printf("class : TranslationUnitDecl\n");
87 m_stream.Indent(); m_stream.Printf("getAnonymousNamespace() : ");
88
89 NamespaceDecl *anonymous_namespace = translation_unit_decl->getAnonymousNamespace();
90
91 if (anonymous_namespace)
92 {
93 if (KeepDumping() && !Visiting(anonymous_namespace))
94 {
95 m_stream.Printf("\n");
96
97 PushIndent();
98 WillVisit(anonymous_namespace);
99 VisitNamespaceDecl(anonymous_namespace);
100 DidVisit(anonymous_namespace);
101 PopIndent();
102 }
103 else
104 {
105 m_stream.Printf("capped\n");
106 }
107 }
108 else
109 {
110 m_stream.Printf("~\n");
111 }
112
113 VisitDecl (translation_unit_decl);
114}
115
116void ASTDumper::VisitNamedDecl (clang::NamedDecl *named_decl)
117{
118 m_stream.Indent(); m_stream.Printf("class : NamedDecl\n");
119 m_stream.Indent(); m_stream.Printf("getNameAsString() : %s\n", named_decl->getNameAsString().c_str());
120 m_stream.Indent(); m_stream.Printf("hasLinkage() : %s\n", SfB(named_decl->hasLinkage()));
121 m_stream.Indent(); m_stream.Printf("isCXXClassMember() : %s\n", SfB(named_decl->isCXXClassMember()));
122 m_stream.Indent(); m_stream.Printf("isCXXInstanceMember() : %s\n", SfB(named_decl->isCXXClassMember()));
123 m_stream.Indent(); m_stream.Printf("getVisibility() : ");
124 switch (named_decl->getVisibility())
125 {
126 default: m_stream.Printf("~\n"); break;
127 case HiddenVisibility: m_stream.Printf("HiddenVisibility\n"); break;
128 case ProtectedVisibility: m_stream.Printf("ProtectedVisibility\n"); break;
129 case DefaultVisibility: m_stream.Printf("DefaultVisibility\n"); break;
130 }
131 m_stream.Indent(); m_stream.Printf("getUnderlyingDecl() : ");
132
133 NamedDecl *underlying_decl = named_decl->getUnderlyingDecl();
134
135 if (underlying_decl)
136 {
137 if (KeepDumping() && !Visiting(underlying_decl))
138 {
139 m_stream.Printf("\n");
140
141 PushIndent();
142 WillVisit(underlying_decl);
143 ::clang::DeclVisitor<ASTDumper, void>::Visit(underlying_decl);
144 DidVisit(underlying_decl);
145 PopIndent();
146 }
147 else
148 {
149 m_stream.Printf("capped\n");
150 }
151 }
152 else
153 {
154 m_stream.Printf("~\n");
155 }
156
157 VisitDecl (named_decl);
158}
159
160void ASTDumper::VisitNamespaceDecl (clang::NamespaceDecl *namespace_decl)
161{
162 m_stream.Indent(); m_stream.Printf("class : NamespaceDecl\n");
163 m_stream.Indent(); m_stream.Printf("isAnonymousNamespace() : %s\n", SfB(namespace_decl->isAnonymousNamespace()));
164 m_stream.Indent(); m_stream.Printf("isInline() : %s\n", SfB(namespace_decl->isInline()));
165 m_stream.Indent(); m_stream.Printf("isOriginalNamespace() : %s\n", SfB(namespace_decl->isOriginalNamespace()));
166
167 VisitNamedDecl (namespace_decl);
168}
169
170void ASTDumper::VisitValueDecl (clang::ValueDecl *value_decl)
171{
172 m_stream.Indent(); m_stream.Printf("class : ValueDecl\n");
173 m_stream.Indent(); m_stream.Printf("getType() : ");
174 if (value_decl->getType().getTypePtrOrNull())
175 {
176 const clang::Type *type_ptr = value_decl->getType().getTypePtr();
177
178 if (KeepDumping() && !Visiting(type_ptr))
179 {
180 m_stream.Printf("\n");
181
182 PushIndent();
183 WillVisit(type_ptr);
184 ::clang::TypeVisitor<ASTDumper, void>::Visit(type_ptr);
185 DidVisit(type_ptr);
186 PopIndent();
187 }
188 else
189 {
190 m_stream.Printf("capped\n");
191 }
192 }
193 else
194 {
195 m_stream.Printf("~\n");
196 }
197
198 VisitNamedDecl (value_decl);
199}
200
201void ASTDumper::VisitDeclaratorDecl (clang::DeclaratorDecl *declarator_decl)
202{
203 m_stream.Indent(); m_stream.Printf("class : DeclaratorDecl\n");
204 VisitValueDecl (declarator_decl);
205}
206
207void ASTDumper::VisitVarDecl (clang::VarDecl *var_decl)
208{
209 m_stream.Indent(); m_stream.Printf("class : VarDecl\n");
210 VisitDeclaratorDecl (var_decl);
211}
212
213void ASTDumper::VisitTypeDecl (clang::TypeDecl *type_decl)
214{
215 m_stream.Indent(); m_stream.Printf("class : TypeDecl\n");
216 m_stream.Indent(); m_stream.Printf("getTypeForDecl() : ");
217
218 const clang::Type *type_for_decl = type_decl->getTypeForDecl();
219
220 if (type_for_decl)
221 {
222 if (KeepDumping() && !Visiting(type_for_decl))
223 {
224 m_stream.Printf("\n");
225
226 PushIndent();
227 WillVisit(type_for_decl);
228 ::clang::TypeVisitor<ASTDumper, void>::Visit(type_for_decl);
229 DidVisit(type_for_decl);
230 PopIndent();
231 }
232 else
233 {
234 m_stream.Printf("capped\n");
235 }
236 }
237 else
238 {
239 m_stream.Printf("~\n");
240 }
241
242 VisitNamedDecl (type_decl);
243}
244
245void ASTDumper::VisitTagDecl (clang::TagDecl *tag_decl)
246{
247 m_stream.Indent(); m_stream.Printf("class : TagDecl\n");
248 m_stream.Indent(); m_stream.Printf("isDefinition() : %s\n", SfB(tag_decl->isDefinition()));
249 m_stream.Indent(); m_stream.Printf("isBeingDefined() : %s\n", SfB(tag_decl->isBeingDefined()));
250 m_stream.Indent(); m_stream.Printf("isEmbeddedInDeclarator() : %s\n", SfB(tag_decl->isEmbeddedInDeclarator()));
251 m_stream.Indent(); m_stream.Printf("isDependentType() : %s\n", SfB(tag_decl->isDependentType()));
252 m_stream.Indent(); m_stream.Printf("getDefinition() : ");
253
254 TagDecl *definition = tag_decl->getDefinition();
255
256 if (definition)
257 {
258 if (KeepDumping() && !Visiting(definition))
259 {
260 m_stream.Printf("\n");
261
262 PushIndent();
263 WillVisit(definition);
264 ::clang::DeclVisitor<ASTDumper, void>::Visit(tag_decl->getDefinition());
265 DidVisit(definition);
266 PopIndent();
267 }
268 else
269 {
270 m_stream.Printf("capped\n");
271 }
272 }
273 else
274 {
275 m_stream.Printf("~\n");
276 }
277 m_stream.Indent(); m_stream.Printf("getKindName() : %s\n", tag_decl->getKindName());
278
279 VisitTypeDecl(tag_decl);
280}
281
282void ASTDumper::VisitRecordDecl (clang::RecordDecl *record_decl)
283{
284 m_stream.Indent(); m_stream.Printf("class : RecordDecl\n");
285 m_stream.Indent(); m_stream.Printf("hasFlexibleArrayMember() : %s\n", SfB(record_decl->hasFlexibleArrayMember()));
286 m_stream.Indent(); m_stream.Printf("isAnonymousStructOrUnion() : %s\n", SfB(record_decl->isAnonymousStructOrUnion()));
287 m_stream.Indent(); m_stream.Printf("hasObjectMember() : %s\n", SfB(record_decl->hasObjectMember()));
288 m_stream.Indent(); m_stream.Printf("isInjectedClassName() : %s\n", SfB(record_decl->isInjectedClassName()));
289 m_stream.Indent(); m_stream.Printf("field_begin() ... field_end() : ");
290 if (KeepDumping())
291 {
292 if (record_decl->field_empty())
293 {
294 m_stream.Printf("~\n");
295 }
296 else
297 {
298 m_stream.Printf("\n");
299 PushIndent();
300 for (RecordDecl::field_iterator iter = record_decl->field_begin(), end_iter = record_decl->field_end();
301 iter != end_iter;
302 ++iter)
303 {
304 m_stream.Indent(); m_stream.Printf("- field:\n");
305 PushIndent();
306 if (Visiting (*iter))
307 {
308 m_stream.Indent(); m_stream.Printf("capped\n");
309 }
310 else
311 {
312 WillVisit(*iter);
313 ::clang::DeclVisitor<ASTDumper, void>::Visit(*iter);
314 DidVisit(*iter);
315 }
316 PopIndent();
317 }
318 PopIndent();
319 }
320 }
321 else
322 {
323 m_stream.Printf("capped\n");
324 }
325
326 VisitTagDecl (record_decl);
327}
328
329void ASTDumper::VisitCXXRecordDecl (clang::CXXRecordDecl *cxx_record_decl)
330{
331 m_stream.Indent(); m_stream.Printf("class : CXXRecordDecl\n");
332 m_stream.Indent(); m_stream.Printf("isDynamicClass() : %s\n", SfB(cxx_record_decl->isDynamicClass()));
333 m_stream.Indent(); m_stream.Printf("bases_begin() ... bases_end() : ");
334 if (KeepDumping())
335 {
336 if (cxx_record_decl->bases_begin() == cxx_record_decl->bases_end())
337 {
338 m_stream.Printf("~\n");
339 }
340 else
341 {
342 m_stream.Printf("\n");
343 PushIndent();
344 for (CXXRecordDecl::base_class_iterator iter = cxx_record_decl->bases_begin(), end_iter = cxx_record_decl->bases_end();
345 iter != end_iter;
346 ++iter)
347 {
348 m_stream.Indent(); m_stream.Printf("- CXXBaseSpecifier:\n");
349 PushIndent();
350 m_stream.Indent(); m_stream.Printf("isVirtual() : %s\n", SfB(iter->isVirtual()));
351 m_stream.Indent(); m_stream.Printf("isBaseOfClass() : %s\n", SfB(iter->isBaseOfClass()));
352 m_stream.Indent(); m_stream.Printf("isPackExpansion() : %s\n", SfB(iter->isPackExpansion()));
353 m_stream.Indent(); m_stream.Printf("getAccessSpecifier() : ");
354 switch (iter->getAccessSpecifier())
355 {
356 default: m_stream.Printf("~\n"); break;
357 case clang::AS_none: m_stream.Printf("AS_none\n"); break;
358 case clang::AS_private: m_stream.Printf("AS_private\n"); break;
359 case clang::AS_protected: m_stream.Printf("AS_protected\n"); break;
360 case clang::AS_public: m_stream.Printf("AS_public\n"); break;
361 }
362 m_stream.Indent(); m_stream.Printf("getType() : ");
363 const clang::Type *base_type = iter->getType().getTypePtr();
364
365 if (Visiting(base_type))
366 {
367 m_stream.Printf("capped\n");
368 }
369 else
370 {
371 m_stream.Printf("\n");
372 PushIndent();
373 WillVisit(base_type);
374 ::clang::TypeVisitor<ASTDumper, void>::Visit(base_type);
375 DidVisit(base_type);
376 PopIndent();
377 }
378 PopIndent();
379 }
380 PopIndent();
381 }
382 }
383 else
384 {
385 m_stream.Printf("capped\n");
386 }
387
388 VisitRecordDecl(cxx_record_decl);
389}
390
391// MARK: TypeVisitor
392
393void ASTDumper::VisitType (const clang::Type *type)
394{
395 m_stream.Indent(); m_stream.Printf("class : Type\n");
396 m_stream.Indent(); m_stream.Printf("getTypeClass() : ");
397 switch (type->getTypeClass())
398 {
399 default: m_stream.Printf("~\n"); break;
400#define TYPE(Class, Base) case clang::Type::Class: m_stream.Printf("%s\n", #Class); break;
401#define ABSTRACT_TYPE(Class, Base)
402#include "clang/AST/TypeNodes.def"
403 }
404 m_stream.Indent(); m_stream.Printf("isFromAST() : %s\n", SfB(type->isFromAST()));
405 m_stream.Indent(); m_stream.Printf("containsUnexpandedParameterPack() : %s\n", SfB(type->containsUnexpandedParameterPack()));
406 m_stream.Indent(); m_stream.Printf("isCanonicalUnqualified() : %s\n", SfB(type->isCanonicalUnqualified()));
407 m_stream.Indent(); m_stream.Printf("isIncompleteType() : %s\n", SfB(type->isIncompleteType()));
408 m_stream.Indent(); m_stream.Printf("isObjectType() : %s\n", SfB(type->isObjectType()));
409 m_stream.Indent(); m_stream.Printf("isPODType() : %s\n", SfB(type->isPODType()));
410 m_stream.Indent(); m_stream.Printf("isLiteralType() : %s\n", SfB(type->isLiteralType()));
411 m_stream.Indent(); m_stream.Printf("isBuiltinType() : %s\n", SfB(type->isBuiltinType()));
412 m_stream.Indent(); m_stream.Printf("isPlaceholderType() : %s\n", SfB(type->isPlaceholderType()));
413 m_stream.Indent(); m_stream.Printf("isScalarType() : %s\n", SfB(type->isScalarType()));
414 m_stream.Indent(); m_stream.Printf("getScalarTypeKind() : ");
415 if (type->isScalarType())
416 {
417 switch (type->getScalarTypeKind())
418 {
419 default: m_stream.Printf("~\n"); break;
420 case clang::Type::STK_Pointer: m_stream.Printf("STK_Pointer\n"); break;
421 case clang::Type::STK_MemberPointer: m_stream.Printf("STK_MemberPointer\n"); break;
422 case clang::Type::STK_Bool: m_stream.Printf("STK_Bool\n"); break;
423 case clang::Type::STK_Integral: m_stream.Printf("STK_Integral\n"); break;
424 case clang::Type::STK_Floating: m_stream.Printf("STK_Floating\n"); break;
425 case clang::Type::STK_IntegralComplex: m_stream.Printf("STK_IntegralComplex\n"); break;
426 case clang::Type::STK_FloatingComplex: m_stream.Printf("STK_FloatingComplex\n"); break;
427 }
428 }
429 else
430 {
431 m_stream.Printf("~\n");
432 }
433 // ...
434}
435
436void ASTDumper::VisitReferenceType(const clang::ReferenceType *reference_type)
437{
438 m_stream.Indent(); m_stream.Printf("class : ReferenceType\n");
439 m_stream.Indent(); m_stream.Printf("isSpelledAsLValue() : %s\n", SfB(reference_type->isSpelledAsLValue()));
440 m_stream.Indent(); m_stream.Printf("isInnerRef() : %s\n", SfB(reference_type->isInnerRef()));
441 m_stream.Indent(); m_stream.Printf("getPointeeType() : ");
442
443 const clang::Type *pointee_type = reference_type->getPointeeType().getTypePtrOrNull();
444
445 if (pointee_type)
446 {
447 if (KeepDumping() && !Visiting(pointee_type))
448 {
449 m_stream.Printf("\n");
450
451 PushIndent();
452 WillVisit(pointee_type);
453 ::clang::TypeVisitor<ASTDumper, void>::Visit(pointee_type);
454 DidVisit(pointee_type);
455 PopIndent();
456 }
457 else
458 {
459 m_stream.Printf("capped\n");
460 }
461 }
462 else
463 {
464 m_stream.Printf("~\n");
465 }
466 VisitType(reference_type);
467}
468
469void ASTDumper::VisitLValueReferenceType(const clang::LValueReferenceType *lvalue_reference_type)
470{
471 m_stream.Indent(); m_stream.Printf("class : LValueReferenceType\n");
472 m_stream.Indent(); m_stream.Printf("isSugared() : %s\n", SfB(lvalue_reference_type->isSugared()));
473 VisitReferenceType(lvalue_reference_type);
474}
475
476void ASTDumper::VisitPointerType(const clang::PointerType *pointer_type)
477{
478 m_stream.Indent(); m_stream.Printf("class : PointerType\n");
479 m_stream.Indent(); m_stream.Printf("getPointeeType() : ");
480
481 const clang::Type *pointee_type = pointer_type->getPointeeType().getTypePtrOrNull();
482
483 if (pointee_type)
484 {
485 if (KeepDumping() && !Visiting(pointee_type))
486 {
487 m_stream.Printf("\n");
488
489 PushIndent();
490 WillVisit(pointee_type);
491 ::clang::TypeVisitor<ASTDumper, void>::Visit(pointee_type);
492 DidVisit(pointee_type);
493 PopIndent();
494 }
495 else
496 {
497 m_stream.Printf("capped\n");
498 }
499 }
500 else
501 {
502 m_stream.Printf("~\n");
503 }
504 m_stream.Indent(); m_stream.Printf("isSugared() : %s\n", SfB (pointer_type->isSugared()));
505 VisitType(pointer_type);
506}
507
508void ASTDumper::VisitTagType(const clang::TagType *tag_type)
509{
510 m_stream.Indent(); m_stream.Printf("class : TagType\n");
511 m_stream.Indent(); m_stream.Printf("getDecl() : ");
512
513 Decl *decl = tag_type->getDecl();
514
515 if (decl)
516 {
517 if (KeepDumping() && !Visiting(decl))
518 {
519 m_stream.Printf("\n");
520
521 PushIndent();
522 WillVisit(decl);
523 ::clang::DeclVisitor<ASTDumper, void>::Visit(decl);
524 DidVisit(decl);
525 PopIndent();
526 }
527 else
528 {
529 m_stream.Printf("capped\n");
530 }
531 }
532 else
533 {
534 m_stream.Printf("~\n");
535 }
536 m_stream.Indent(); m_stream.Printf("isBeingDefined() : %s\n", SfB(tag_type->isBeingDefined()));
537 VisitType(tag_type);
538}
539
540void ASTDumper::VisitRecordType(const clang::RecordType *record_type)
541{
542 m_stream.Indent(); m_stream.Printf("class : RecordType\n");
543 m_stream.Indent(); m_stream.Printf("hasConstFields() : %s\n", SfB(record_type->hasConstFields()));
544 VisitTagType(record_type);
545}