• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===--- ASTDumper.cpp - Dumping implementation for ASTs ------------------===//
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 // This file implements the AST dump methods, which dump out the
11 // AST in a form that exposes type details and other fields.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/Attr.h"
17 #include "clang/AST/CommentVisitor.h"
18 #include "clang/AST/DeclCXX.h"
19 #include "clang/AST/DeclLookups.h"
20 #include "clang/AST/DeclObjC.h"
21 #include "clang/AST/DeclVisitor.h"
22 #include "clang/AST/StmtVisitor.h"
23 #include "clang/Basic/Module.h"
24 #include "clang/Basic/SourceManager.h"
25 #include "llvm/Support/raw_ostream.h"
26 using namespace clang;
27 using namespace clang::comments;
28 
29 //===----------------------------------------------------------------------===//
30 // ASTDumper Visitor
31 //===----------------------------------------------------------------------===//
32 
33 namespace  {
34   // Colors used for various parts of the AST dump
35 
36   struct TerminalColor {
37     raw_ostream::Colors Color;
38     bool Bold;
39   };
40 
41   // Decl kind names (VarDecl, FunctionDecl, etc)
42   static const TerminalColor DeclKindNameColor = { raw_ostream::GREEN, true };
43   // Attr names (CleanupAttr, GuardedByAttr, etc)
44   static const TerminalColor AttrColor = { raw_ostream::BLUE, true };
45   // Statement names (DeclStmt, ImplicitCastExpr, etc)
46   static const TerminalColor StmtColor = { raw_ostream::MAGENTA, true };
47   // Comment names (FullComment, ParagraphComment, TextComment, etc)
48   static const TerminalColor CommentColor = { raw_ostream::YELLOW, true };
49 
50   // Type names (int, float, etc, plus user defined types)
51   static const TerminalColor TypeColor = { raw_ostream::GREEN, false };
52 
53   // Pointer address
54   static const TerminalColor AddressColor = { raw_ostream::YELLOW, false };
55   // Source locations
56   static const TerminalColor LocationColor = { raw_ostream::YELLOW, false };
57 
58   // lvalue/xvalue
59   static const TerminalColor ValueKindColor = { raw_ostream::CYAN, false };
60   // bitfield/objcproperty/objcsubscript/vectorcomponent
61   static const TerminalColor ObjectKindColor = { raw_ostream::CYAN, false };
62 
63   // Null statements
64   static const TerminalColor NullColor = { raw_ostream::BLUE, false };
65 
66   // Undeserialized entities
67   static const TerminalColor UndeserializedColor = { raw_ostream::GREEN, true };
68 
69   // CastKind from CastExpr's
70   static const TerminalColor CastColor = { raw_ostream::RED, false };
71 
72   // Value of the statement
73   static const TerminalColor ValueColor = { raw_ostream::CYAN, true };
74   // Decl names
75   static const TerminalColor DeclNameColor = { raw_ostream::CYAN, true };
76 
77   // Indents ( `, -. | )
78   static const TerminalColor IndentColor = { raw_ostream::BLUE, false };
79 
80   class ASTDumper
81       : public ConstDeclVisitor<ASTDumper>, public ConstStmtVisitor<ASTDumper>,
82         public ConstCommentVisitor<ASTDumper> {
83     raw_ostream &OS;
84     const CommandTraits *Traits;
85     const SourceManager *SM;
86     bool IsFirstLine;
87 
88     // Indicates whether more child are expected at the current tree depth
89     enum IndentType { IT_Child, IT_LastChild };
90 
91     /// Indents[i] indicates if another child exists at level i.
92     /// Used by Indent() to print the tree structure.
93     llvm::SmallVector<IndentType, 32> Indents;
94 
95     /// Indicates that more children will be needed at this indent level.
96     /// If true, prevents lastChild() from marking the node as the last child.
97     /// This is used when there are multiple collections of children to be
98     /// dumped as well as during conditional node dumping.
99     bool MoreChildren;
100 
101     /// Keep track of the last location we print out so that we can
102     /// print out deltas from then on out.
103     const char *LastLocFilename;
104     unsigned LastLocLine;
105 
106     /// The \c FullComment parent of the comment being dumped.
107     const FullComment *FC;
108 
109     bool ShowColors;
110 
111     class IndentScope {
112       ASTDumper &Dumper;
113       // Preserve the Dumper's MoreChildren value from the previous IndentScope
114       bool MoreChildren;
115     public:
IndentScope(ASTDumper & Dumper)116       IndentScope(ASTDumper &Dumper) : Dumper(Dumper) {
117         MoreChildren = Dumper.hasMoreChildren();
118         Dumper.setMoreChildren(false);
119         Dumper.indent();
120       }
~IndentScope()121       ~IndentScope() {
122         Dumper.setMoreChildren(MoreChildren);
123         Dumper.unindent();
124       }
125     };
126 
127     class ColorScope {
128       ASTDumper &Dumper;
129     public:
ColorScope(ASTDumper & Dumper,TerminalColor Color)130       ColorScope(ASTDumper &Dumper, TerminalColor Color)
131         : Dumper(Dumper) {
132         if (Dumper.ShowColors)
133           Dumper.OS.changeColor(Color.Color, Color.Bold);
134       }
~ColorScope()135       ~ColorScope() {
136         if (Dumper.ShowColors)
137           Dumper.OS.resetColor();
138       }
139     };
140 
141   public:
ASTDumper(raw_ostream & OS,const CommandTraits * Traits,const SourceManager * SM)142     ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
143               const SourceManager *SM)
144       : OS(OS), Traits(Traits), SM(SM), IsFirstLine(true), MoreChildren(false),
145         LastLocFilename(""), LastLocLine(~0U), FC(0),
146         ShowColors(SM && SM->getDiagnostics().getShowColors()) { }
147 
ASTDumper(raw_ostream & OS,const CommandTraits * Traits,const SourceManager * SM,bool ShowColors)148     ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
149               const SourceManager *SM, bool ShowColors)
150       : OS(OS), Traits(Traits), SM(SM), IsFirstLine(true), MoreChildren(false),
151         LastLocFilename(""), LastLocLine(~0U),
152         ShowColors(ShowColors) { }
153 
~ASTDumper()154     ~ASTDumper() {
155       OS << "\n";
156     }
157 
158     void dumpDecl(const Decl *D);
159     void dumpStmt(const Stmt *S);
160     void dumpFullComment(const FullComment *C);
161 
162     // Formatting
163     void indent();
164     void unindent();
165     void lastChild();
166     bool hasMoreChildren();
167     void setMoreChildren(bool Value);
168 
169     // Utilities
170     void dumpPointer(const void *Ptr);
171     void dumpSourceRange(SourceRange R);
172     void dumpLocation(SourceLocation Loc);
173     void dumpBareType(QualType T);
174     void dumpType(QualType T);
175     void dumpBareDeclRef(const Decl *Node);
176     void dumpDeclRef(const Decl *Node, const char *Label = 0);
177     void dumpName(const NamedDecl *D);
178     bool hasNodes(const DeclContext *DC);
179     void dumpDeclContext(const DeclContext *DC);
180     void dumpLookups(const DeclContext *DC);
181     void dumpAttr(const Attr *A);
182 
183     // C++ Utilities
184     void dumpAccessSpecifier(AccessSpecifier AS);
185     void dumpCXXCtorInitializer(const CXXCtorInitializer *Init);
186     void dumpTemplateParameters(const TemplateParameterList *TPL);
187     void dumpTemplateArgumentListInfo(const TemplateArgumentListInfo &TALI);
188     void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A);
189     void dumpTemplateArgumentList(const TemplateArgumentList &TAL);
190     void dumpTemplateArgument(const TemplateArgument &A,
191                               SourceRange R = SourceRange());
192 
193     // Decls
194     void VisitLabelDecl(const LabelDecl *D);
195     void VisitTypedefDecl(const TypedefDecl *D);
196     void VisitEnumDecl(const EnumDecl *D);
197     void VisitRecordDecl(const RecordDecl *D);
198     void VisitEnumConstantDecl(const EnumConstantDecl *D);
199     void VisitIndirectFieldDecl(const IndirectFieldDecl *D);
200     void VisitFunctionDecl(const FunctionDecl *D);
201     void VisitFieldDecl(const FieldDecl *D);
202     void VisitVarDecl(const VarDecl *D);
203     void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D);
204     void VisitImportDecl(const ImportDecl *D);
205 
206     // C++ Decls
207     void VisitNamespaceDecl(const NamespaceDecl *D);
208     void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D);
209     void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D);
210     void VisitTypeAliasDecl(const TypeAliasDecl *D);
211     void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D);
212     void VisitCXXRecordDecl(const CXXRecordDecl *D);
213     void VisitStaticAssertDecl(const StaticAssertDecl *D);
214     void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
215     void VisitClassTemplateDecl(const ClassTemplateDecl *D);
216     void VisitClassTemplateSpecializationDecl(
217         const ClassTemplateSpecializationDecl *D);
218     void VisitClassTemplatePartialSpecializationDecl(
219         const ClassTemplatePartialSpecializationDecl *D);
220     void VisitClassScopeFunctionSpecializationDecl(
221         const ClassScopeFunctionSpecializationDecl *D);
222     void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
223     void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
224     void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
225     void VisitUsingDecl(const UsingDecl *D);
226     void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D);
227     void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D);
228     void VisitUsingShadowDecl(const UsingShadowDecl *D);
229     void VisitLinkageSpecDecl(const LinkageSpecDecl *D);
230     void VisitAccessSpecDecl(const AccessSpecDecl *D);
231     void VisitFriendDecl(const FriendDecl *D);
232 
233     // ObjC Decls
234     void VisitObjCIvarDecl(const ObjCIvarDecl *D);
235     void VisitObjCMethodDecl(const ObjCMethodDecl *D);
236     void VisitObjCCategoryDecl(const ObjCCategoryDecl *D);
237     void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D);
238     void VisitObjCProtocolDecl(const ObjCProtocolDecl *D);
239     void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D);
240     void VisitObjCImplementationDecl(const ObjCImplementationDecl *D);
241     void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D);
242     void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
243     void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
244     void VisitBlockDecl(const BlockDecl *D);
245 
246     // Stmts.
247     void VisitStmt(const Stmt *Node);
248     void VisitDeclStmt(const DeclStmt *Node);
249     void VisitAttributedStmt(const AttributedStmt *Node);
250     void VisitLabelStmt(const LabelStmt *Node);
251     void VisitGotoStmt(const GotoStmt *Node);
252 
253     // Exprs
254     void VisitExpr(const Expr *Node);
255     void VisitCastExpr(const CastExpr *Node);
256     void VisitDeclRefExpr(const DeclRefExpr *Node);
257     void VisitPredefinedExpr(const PredefinedExpr *Node);
258     void VisitCharacterLiteral(const CharacterLiteral *Node);
259     void VisitIntegerLiteral(const IntegerLiteral *Node);
260     void VisitFloatingLiteral(const FloatingLiteral *Node);
261     void VisitStringLiteral(const StringLiteral *Str);
262     void VisitUnaryOperator(const UnaryOperator *Node);
263     void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node);
264     void VisitMemberExpr(const MemberExpr *Node);
265     void VisitExtVectorElementExpr(const ExtVectorElementExpr *Node);
266     void VisitBinaryOperator(const BinaryOperator *Node);
267     void VisitCompoundAssignOperator(const CompoundAssignOperator *Node);
268     void VisitAddrLabelExpr(const AddrLabelExpr *Node);
269     void VisitBlockExpr(const BlockExpr *Node);
270     void VisitOpaqueValueExpr(const OpaqueValueExpr *Node);
271 
272     // C++
273     void VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node);
274     void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node);
275     void VisitCXXThisExpr(const CXXThisExpr *Node);
276     void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node);
277     void VisitCXXConstructExpr(const CXXConstructExpr *Node);
278     void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node);
279     void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node);
280     void VisitExprWithCleanups(const ExprWithCleanups *Node);
281     void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node);
282     void dumpCXXTemporary(const CXXTemporary *Temporary);
283 
284     // ObjC
285     void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node);
286     void VisitObjCEncodeExpr(const ObjCEncodeExpr *Node);
287     void VisitObjCMessageExpr(const ObjCMessageExpr *Node);
288     void VisitObjCBoxedExpr(const ObjCBoxedExpr *Node);
289     void VisitObjCSelectorExpr(const ObjCSelectorExpr *Node);
290     void VisitObjCProtocolExpr(const ObjCProtocolExpr *Node);
291     void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node);
292     void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node);
293     void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node);
294     void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node);
295 
296     // Comments.
297     const char *getCommandName(unsigned CommandID);
298     void dumpComment(const Comment *C);
299 
300     // Inline comments.
301     void visitTextComment(const TextComment *C);
302     void visitInlineCommandComment(const InlineCommandComment *C);
303     void visitHTMLStartTagComment(const HTMLStartTagComment *C);
304     void visitHTMLEndTagComment(const HTMLEndTagComment *C);
305 
306     // Block comments.
307     void visitBlockCommandComment(const BlockCommandComment *C);
308     void visitParamCommandComment(const ParamCommandComment *C);
309     void visitTParamCommandComment(const TParamCommandComment *C);
310     void visitVerbatimBlockComment(const VerbatimBlockComment *C);
311     void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
312     void visitVerbatimLineComment(const VerbatimLineComment *C);
313   };
314 }
315 
316 //===----------------------------------------------------------------------===//
317 //  Utilities
318 //===----------------------------------------------------------------------===//
319 
320 // Print out the appropriate tree structure using the Indents vector.
321 // Example of tree and the Indents vector at each level.
322 // A        { }
323 // |-B      { IT_Child }
324 // | `-C    { IT_Child,     IT_LastChild }
325 // `-D      { IT_LastChild }
326 //   |-E    { IT_LastChild, IT_Child }
327 //   `-F    { IT_LastChild, IT_LastChild }
328 // Type            non-last element, last element
329 // IT_Child        "| "              "|-"
330 // IT_LastChild    "  "              "`-"
indent()331 void ASTDumper::indent() {
332   if (IsFirstLine)
333     IsFirstLine = false;
334   else
335     OS << "\n";
336 
337   ColorScope Color(*this, IndentColor);
338   for (SmallVectorImpl<IndentType>::const_iterator I = Indents.begin(),
339                                                    E = Indents.end();
340        I != E; ++I) {
341     switch (*I) {
342     case IT_Child:
343       if (I == E - 1)
344         OS << "|-";
345       else
346         OS << "| ";
347       continue;
348     case IT_LastChild:
349       if (I == E - 1)
350         OS << "`-";
351       else
352         OS << "  ";
353       continue;
354     }
355     llvm_unreachable("Invalid IndentType");
356   }
357   Indents.push_back(IT_Child);
358 }
359 
unindent()360 void ASTDumper::unindent() {
361   Indents.pop_back();
362 }
363 
364 // Call before each potential last child node is to be dumped.  If MoreChildren
365 // is false, then this is the last child, otherwise treat as a regular node.
lastChild()366 void ASTDumper::lastChild() {
367   if (!hasMoreChildren())
368     Indents.back() = IT_LastChild;
369 }
370 
371 // MoreChildren should be set before calling another function that may print
372 // additional nodes to prevent conflicting final child nodes.
hasMoreChildren()373 bool ASTDumper::hasMoreChildren() {
374   return MoreChildren;
375 }
376 
setMoreChildren(bool Value)377 void ASTDumper::setMoreChildren(bool Value) {
378   MoreChildren = Value;
379 }
380 
dumpPointer(const void * Ptr)381 void ASTDumper::dumpPointer(const void *Ptr) {
382   ColorScope Color(*this, AddressColor);
383   OS << ' ' << Ptr;
384 }
385 
dumpLocation(SourceLocation Loc)386 void ASTDumper::dumpLocation(SourceLocation Loc) {
387   ColorScope Color(*this, LocationColor);
388   SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
389 
390   // The general format we print out is filename:line:col, but we drop pieces
391   // that haven't changed since the last loc printed.
392   PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
393 
394   if (PLoc.isInvalid()) {
395     OS << "<invalid sloc>";
396     return;
397   }
398 
399   if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
400     OS << PLoc.getFilename() << ':' << PLoc.getLine()
401        << ':' << PLoc.getColumn();
402     LastLocFilename = PLoc.getFilename();
403     LastLocLine = PLoc.getLine();
404   } else if (PLoc.getLine() != LastLocLine) {
405     OS << "line" << ':' << PLoc.getLine()
406        << ':' << PLoc.getColumn();
407     LastLocLine = PLoc.getLine();
408   } else {
409     OS << "col" << ':' << PLoc.getColumn();
410   }
411 }
412 
dumpSourceRange(SourceRange R)413 void ASTDumper::dumpSourceRange(SourceRange R) {
414   // Can't translate locations if a SourceManager isn't available.
415   if (!SM)
416     return;
417 
418   OS << " <";
419   dumpLocation(R.getBegin());
420   if (R.getBegin() != R.getEnd()) {
421     OS << ", ";
422     dumpLocation(R.getEnd());
423   }
424   OS << ">";
425 
426   // <t2.c:123:421[blah], t2.c:412:321>
427 
428 }
429 
dumpBareType(QualType T)430 void ASTDumper::dumpBareType(QualType T) {
431   ColorScope Color(*this, TypeColor);
432 
433   SplitQualType T_split = T.split();
434   OS << "'" << QualType::getAsString(T_split) << "'";
435 
436   if (!T.isNull()) {
437     // If the type is sugared, also dump a (shallow) desugared type.
438     SplitQualType D_split = T.getSplitDesugaredType();
439     if (T_split != D_split)
440       OS << ":'" << QualType::getAsString(D_split) << "'";
441   }
442 }
443 
dumpType(QualType T)444 void ASTDumper::dumpType(QualType T) {
445   OS << ' ';
446   dumpBareType(T);
447 }
448 
dumpBareDeclRef(const Decl * D)449 void ASTDumper::dumpBareDeclRef(const Decl *D) {
450   {
451     ColorScope Color(*this, DeclKindNameColor);
452     OS << D->getDeclKindName();
453   }
454   dumpPointer(D);
455 
456   if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
457     ColorScope Color(*this, DeclNameColor);
458     OS << " '" << ND->getDeclName() << '\'';
459   }
460 
461   if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
462     dumpType(VD->getType());
463 }
464 
dumpDeclRef(const Decl * D,const char * Label)465 void ASTDumper::dumpDeclRef(const Decl *D, const char *Label) {
466   if (!D)
467     return;
468 
469   IndentScope Indent(*this);
470   if (Label)
471     OS << Label << ' ';
472   dumpBareDeclRef(D);
473 }
474 
dumpName(const NamedDecl * ND)475 void ASTDumper::dumpName(const NamedDecl *ND) {
476   if (ND->getDeclName()) {
477     ColorScope Color(*this, DeclNameColor);
478     OS << ' ' << ND->getNameAsString();
479   }
480 }
481 
hasNodes(const DeclContext * DC)482 bool ASTDumper::hasNodes(const DeclContext *DC) {
483   if (!DC)
484     return false;
485 
486   return DC->hasExternalLexicalStorage() ||
487          DC->noload_decls_begin() != DC->noload_decls_end();
488 }
489 
dumpDeclContext(const DeclContext * DC)490 void ASTDumper::dumpDeclContext(const DeclContext *DC) {
491   if (!DC)
492     return;
493   bool HasUndeserializedDecls = DC->hasExternalLexicalStorage();
494   for (DeclContext::decl_iterator I = DC->noload_decls_begin(), E = DC->noload_decls_end();
495        I != E; ++I) {
496     DeclContext::decl_iterator Next = I;
497     ++Next;
498     if (Next == E && !HasUndeserializedDecls)
499       lastChild();
500     dumpDecl(*I);
501   }
502   if (HasUndeserializedDecls) {
503     lastChild();
504     IndentScope Indent(*this);
505     ColorScope Color(*this, UndeserializedColor);
506     OS << "<undeserialized declarations>";
507   }
508 }
509 
dumpLookups(const DeclContext * DC)510 void ASTDumper::dumpLookups(const DeclContext *DC) {
511   IndentScope Indent(*this);
512 
513   OS << "StoredDeclsMap ";
514   dumpBareDeclRef(cast<Decl>(DC));
515 
516   const DeclContext *Primary = DC->getPrimaryContext();
517   if (Primary != DC) {
518     OS << " primary";
519     dumpPointer(cast<Decl>(Primary));
520   }
521 
522   bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage();
523 
524   DeclContext::all_lookups_iterator I = Primary->noload_lookups_begin(),
525                                     E = Primary->noload_lookups_end();
526   while (I != E) {
527     DeclarationName Name = I.getLookupName();
528     DeclContextLookupResult R = *I++;
529     if (I == E && !HasUndeserializedLookups)
530       lastChild();
531 
532     IndentScope Indent(*this);
533     OS << "DeclarationName ";
534     {
535       ColorScope Color(*this, DeclNameColor);
536       OS << '\'' << Name << '\'';
537     }
538 
539     for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end();
540          RI != RE; ++RI) {
541       if (RI + 1 == RE)
542         lastChild();
543       dumpDeclRef(*RI);
544     }
545   }
546 
547   if (HasUndeserializedLookups) {
548     lastChild();
549     IndentScope Indent(*this);
550     ColorScope Color(*this, UndeserializedColor);
551     OS << "<undeserialized lookups>";
552   }
553 }
554 
dumpAttr(const Attr * A)555 void ASTDumper::dumpAttr(const Attr *A) {
556   IndentScope Indent(*this);
557   {
558     ColorScope Color(*this, AttrColor);
559     switch (A->getKind()) {
560 #define ATTR(X) case attr::X: OS << #X; break;
561 #include "clang/Basic/AttrList.inc"
562     default: llvm_unreachable("unexpected attribute kind");
563     }
564     OS << "Attr";
565   }
566   dumpPointer(A);
567   dumpSourceRange(A->getRange());
568 #include "clang/AST/AttrDump.inc"
569 }
570 
getPreviousDeclImpl(...)571 static Decl *getPreviousDeclImpl(...) {
572   return 0;
573 }
574 
575 template<typename T>
getPreviousDeclImpl(const Redeclarable<T> * D)576 static const Decl *getPreviousDeclImpl(const Redeclarable<T> *D) {
577   return D->getPreviousDecl();
578 }
579 
580 /// Get the previous declaration in the redeclaration chain for a declaration.
getPreviousDecl(const Decl * D)581 static const Decl *getPreviousDecl(const Decl *D) {
582   switch (D->getKind()) {
583 #define DECL(DERIVED, BASE) \
584   case Decl::DERIVED: \
585     return getPreviousDeclImpl(cast<DERIVED##Decl>(D));
586 #define ABSTRACT_DECL(DECL)
587 #include "clang/AST/DeclNodes.inc"
588   }
589   llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
590 }
591 
592 //===----------------------------------------------------------------------===//
593 //  C++ Utilities
594 //===----------------------------------------------------------------------===//
595 
dumpAccessSpecifier(AccessSpecifier AS)596 void ASTDumper::dumpAccessSpecifier(AccessSpecifier AS) {
597   switch (AS) {
598   case AS_none:
599     break;
600   case AS_public:
601     OS << "public";
602     break;
603   case AS_protected:
604     OS << "protected";
605     break;
606   case AS_private:
607     OS << "private";
608     break;
609   }
610 }
611 
dumpCXXCtorInitializer(const CXXCtorInitializer * Init)612 void ASTDumper::dumpCXXCtorInitializer(const CXXCtorInitializer *Init) {
613   IndentScope Indent(*this);
614   OS << "CXXCtorInitializer";
615   if (Init->isAnyMemberInitializer()) {
616     OS << ' ';
617     dumpBareDeclRef(Init->getAnyMember());
618   } else {
619     dumpType(QualType(Init->getBaseClass(), 0));
620   }
621   dumpStmt(Init->getInit());
622 }
623 
dumpTemplateParameters(const TemplateParameterList * TPL)624 void ASTDumper::dumpTemplateParameters(const TemplateParameterList *TPL) {
625   if (!TPL)
626     return;
627 
628   for (TemplateParameterList::const_iterator I = TPL->begin(), E = TPL->end();
629        I != E; ++I)
630     dumpDecl(*I);
631 }
632 
dumpTemplateArgumentListInfo(const TemplateArgumentListInfo & TALI)633 void ASTDumper::dumpTemplateArgumentListInfo(
634     const TemplateArgumentListInfo &TALI) {
635   for (unsigned i = 0, e = TALI.size(); i < e; ++i) {
636     if (i + 1 == e)
637       lastChild();
638     dumpTemplateArgumentLoc(TALI[i]);
639   }
640 }
641 
dumpTemplateArgumentLoc(const TemplateArgumentLoc & A)642 void ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A) {
643   dumpTemplateArgument(A.getArgument(), A.getSourceRange());
644 }
645 
dumpTemplateArgumentList(const TemplateArgumentList & TAL)646 void ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) {
647   for (unsigned i = 0, e = TAL.size(); i < e; ++i)
648     dumpTemplateArgument(TAL[i]);
649 }
650 
dumpTemplateArgument(const TemplateArgument & A,SourceRange R)651 void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R) {
652   IndentScope Indent(*this);
653   OS << "TemplateArgument";
654   if (R.isValid())
655     dumpSourceRange(R);
656 
657   switch (A.getKind()) {
658   case TemplateArgument::Null:
659     OS << " null";
660     break;
661   case TemplateArgument::Type:
662     OS << " type";
663     lastChild();
664     dumpType(A.getAsType());
665     break;
666   case TemplateArgument::Declaration:
667     OS << " decl";
668     lastChild();
669     dumpDeclRef(A.getAsDecl());
670     break;
671   case TemplateArgument::NullPtr:
672     OS << " nullptr";
673     break;
674   case TemplateArgument::Integral:
675     OS << " integral " << A.getAsIntegral();
676     break;
677   case TemplateArgument::Template:
678     OS << " template ";
679     A.getAsTemplate().dump(OS);
680     break;
681   case TemplateArgument::TemplateExpansion:
682     OS << " template expansion";
683     A.getAsTemplateOrTemplatePattern().dump(OS);
684     break;
685   case TemplateArgument::Expression:
686     OS << " expr";
687     lastChild();
688     dumpStmt(A.getAsExpr());
689     break;
690   case TemplateArgument::Pack:
691     OS << " pack";
692     for (TemplateArgument::pack_iterator I = A.pack_begin(), E = A.pack_end();
693          I != E; ++I) {
694       if (I + 1 == E)
695         lastChild();
696       dumpTemplateArgument(*I);
697     }
698     break;
699   }
700 }
701 
702 //===----------------------------------------------------------------------===//
703 //  Decl dumping methods.
704 //===----------------------------------------------------------------------===//
705 
dumpDecl(const Decl * D)706 void ASTDumper::dumpDecl(const Decl *D) {
707   IndentScope Indent(*this);
708 
709   if (!D) {
710     ColorScope Color(*this, NullColor);
711     OS << "<<<NULL>>>";
712     return;
713   }
714 
715   {
716     ColorScope Color(*this, DeclKindNameColor);
717     OS << D->getDeclKindName() << "Decl";
718   }
719   dumpPointer(D);
720   if (D->getLexicalDeclContext() != D->getDeclContext())
721     OS << " parent " << cast<Decl>(D->getDeclContext());
722   if (const Decl *Prev = getPreviousDecl(D))
723     OS << " prev " << Prev;
724   dumpSourceRange(D->getSourceRange());
725 
726   bool HasAttrs = D->attr_begin() != D->attr_end();
727   const FullComment *Comment =
728       D->getASTContext().getLocalCommentForDeclUncached(D);
729   // Decls within functions are visited by the body
730   bool HasDeclContext = !isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D) &&
731                          hasNodes(dyn_cast<DeclContext>(D));
732 
733   setMoreChildren(HasAttrs || Comment || HasDeclContext);
734   ConstDeclVisitor<ASTDumper>::Visit(D);
735 
736   setMoreChildren(Comment || HasDeclContext);
737   for (Decl::attr_iterator I = D->attr_begin(), E = D->attr_end();
738        I != E; ++I) {
739     if (I + 1 == E)
740       lastChild();
741     dumpAttr(*I);
742   }
743 
744   setMoreChildren(HasDeclContext);
745   lastChild();
746   dumpFullComment(Comment);
747 
748   setMoreChildren(false);
749   if (HasDeclContext)
750     dumpDeclContext(cast<DeclContext>(D));
751 }
752 
VisitLabelDecl(const LabelDecl * D)753 void ASTDumper::VisitLabelDecl(const LabelDecl *D) {
754   dumpName(D);
755 }
756 
VisitTypedefDecl(const TypedefDecl * D)757 void ASTDumper::VisitTypedefDecl(const TypedefDecl *D) {
758   dumpName(D);
759   dumpType(D->getUnderlyingType());
760   if (D->isModulePrivate())
761     OS << " __module_private__";
762 }
763 
VisitEnumDecl(const EnumDecl * D)764 void ASTDumper::VisitEnumDecl(const EnumDecl *D) {
765   if (D->isScoped()) {
766     if (D->isScopedUsingClassTag())
767       OS << " class";
768     else
769       OS << " struct";
770   }
771   dumpName(D);
772   if (D->isModulePrivate())
773     OS << " __module_private__";
774   if (D->isFixed())
775     dumpType(D->getIntegerType());
776 }
777 
VisitRecordDecl(const RecordDecl * D)778 void ASTDumper::VisitRecordDecl(const RecordDecl *D) {
779   OS << ' ' << D->getKindName();
780   dumpName(D);
781   if (D->isModulePrivate())
782     OS << " __module_private__";
783 }
784 
VisitEnumConstantDecl(const EnumConstantDecl * D)785 void ASTDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
786   dumpName(D);
787   dumpType(D->getType());
788   if (const Expr *Init = D->getInitExpr()) {
789     lastChild();
790     dumpStmt(Init);
791   }
792 }
793 
VisitIndirectFieldDecl(const IndirectFieldDecl * D)794 void ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
795   dumpName(D);
796   dumpType(D->getType());
797   for (IndirectFieldDecl::chain_iterator I = D->chain_begin(),
798                                          E = D->chain_end();
799        I != E; ++I) {
800     if (I + 1 == E)
801       lastChild();
802     dumpDeclRef(*I);
803   }
804 }
805 
VisitFunctionDecl(const FunctionDecl * D)806 void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) {
807   dumpName(D);
808   dumpType(D->getType());
809 
810   StorageClass SC = D->getStorageClass();
811   if (SC != SC_None)
812     OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
813   if (D->isInlineSpecified())
814     OS << " inline";
815   if (D->isVirtualAsWritten())
816     OS << " virtual";
817   if (D->isModulePrivate())
818     OS << " __module_private__";
819 
820   if (D->isPure())
821     OS << " pure";
822   else if (D->isDeletedAsWritten())
823     OS << " delete";
824 
825   if (const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>()) {
826     FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
827     switch (EPI.ExceptionSpecType) {
828     default: break;
829     case EST_Unevaluated:
830       OS << " noexcept-unevaluated " << EPI.ExceptionSpecDecl;
831       break;
832     case EST_Uninstantiated:
833       OS << " noexcept-uninstantiated " << EPI.ExceptionSpecTemplate;
834       break;
835     }
836   }
837 
838   bool OldMoreChildren = hasMoreChildren();
839   const FunctionTemplateSpecializationInfo *FTSI =
840       D->getTemplateSpecializationInfo();
841   bool HasTemplateSpecialization = FTSI;
842 
843   bool HasNamedDecls = D->getDeclsInPrototypeScope().begin() !=
844                        D->getDeclsInPrototypeScope().end();
845 
846   bool HasFunctionDecls = D->param_begin() != D->param_end();
847 
848   const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(D);
849   bool HasCtorInitializers = C && C->init_begin() != C->init_end();
850 
851   bool HasDeclarationBody = D->doesThisDeclarationHaveABody();
852 
853   setMoreChildren(OldMoreChildren || HasNamedDecls || HasFunctionDecls ||
854                   HasCtorInitializers || HasDeclarationBody);
855   if (HasTemplateSpecialization) {
856     lastChild();
857     dumpTemplateArgumentList(*FTSI->TemplateArguments);
858   }
859 
860   setMoreChildren(OldMoreChildren || HasFunctionDecls ||
861                   HasCtorInitializers || HasDeclarationBody);
862   for (ArrayRef<NamedDecl *>::iterator
863        I = D->getDeclsInPrototypeScope().begin(),
864        E = D->getDeclsInPrototypeScope().end(); I != E; ++I) {
865     if (I + 1 == E)
866       lastChild();
867     dumpDecl(*I);
868   }
869 
870   setMoreChildren(OldMoreChildren || HasCtorInitializers || HasDeclarationBody);
871   for (FunctionDecl::param_const_iterator I = D->param_begin(),
872                                           E = D->param_end();
873        I != E; ++I) {
874     if (I + 1 == E)
875       lastChild();
876     dumpDecl(*I);
877   }
878 
879   setMoreChildren(OldMoreChildren || HasDeclarationBody);
880   if (HasCtorInitializers)
881     for (CXXConstructorDecl::init_const_iterator I = C->init_begin(),
882                                                  E = C->init_end();
883          I != E; ++I) {
884       if (I + 1 == E)
885         lastChild();
886       dumpCXXCtorInitializer(*I);
887   }
888 
889   setMoreChildren(OldMoreChildren);
890   if (HasDeclarationBody) {
891     lastChild();
892     dumpStmt(D->getBody());
893   }
894 }
895 
VisitFieldDecl(const FieldDecl * D)896 void ASTDumper::VisitFieldDecl(const FieldDecl *D) {
897   dumpName(D);
898   dumpType(D->getType());
899   if (D->isMutable())
900     OS << " mutable";
901   if (D->isModulePrivate())
902     OS << " __module_private__";
903 
904   bool OldMoreChildren = hasMoreChildren();
905   bool IsBitField = D->isBitField();
906   Expr *Init = D->getInClassInitializer();
907   bool HasInit = Init;
908 
909   setMoreChildren(OldMoreChildren || HasInit);
910   if (IsBitField) {
911     lastChild();
912     dumpStmt(D->getBitWidth());
913   }
914   setMoreChildren(OldMoreChildren);
915   if (HasInit) {
916     lastChild();
917     dumpStmt(Init);
918   }
919 }
920 
VisitVarDecl(const VarDecl * D)921 void ASTDumper::VisitVarDecl(const VarDecl *D) {
922   dumpName(D);
923   dumpType(D->getType());
924   StorageClass SC = D->getStorageClass();
925   if (SC != SC_None)
926     OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
927   switch (D->getTLSKind()) {
928   case VarDecl::TLS_None: break;
929   case VarDecl::TLS_Static: OS << " tls"; break;
930   case VarDecl::TLS_Dynamic: OS << " tls_dynamic"; break;
931   }
932   if (D->isModulePrivate())
933     OS << " __module_private__";
934   if (D->isNRVOVariable())
935     OS << " nrvo";
936   if (D->hasInit()) {
937     lastChild();
938     dumpStmt(D->getInit());
939   }
940 }
941 
VisitFileScopeAsmDecl(const FileScopeAsmDecl * D)942 void ASTDumper::VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) {
943   lastChild();
944   dumpStmt(D->getAsmString());
945 }
946 
VisitImportDecl(const ImportDecl * D)947 void ASTDumper::VisitImportDecl(const ImportDecl *D) {
948   OS << ' ' << D->getImportedModule()->getFullModuleName();
949 }
950 
951 //===----------------------------------------------------------------------===//
952 // C++ Declarations
953 //===----------------------------------------------------------------------===//
954 
VisitNamespaceDecl(const NamespaceDecl * D)955 void ASTDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
956   dumpName(D);
957   if (D->isInline())
958     OS << " inline";
959   if (!D->isOriginalNamespace())
960     dumpDeclRef(D->getOriginalNamespace(), "original");
961 }
962 
VisitUsingDirectiveDecl(const UsingDirectiveDecl * D)963 void ASTDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
964   OS << ' ';
965   dumpBareDeclRef(D->getNominatedNamespace());
966 }
967 
VisitNamespaceAliasDecl(const NamespaceAliasDecl * D)968 void ASTDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
969   dumpName(D);
970   dumpDeclRef(D->getAliasedNamespace());
971 }
972 
VisitTypeAliasDecl(const TypeAliasDecl * D)973 void ASTDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
974   dumpName(D);
975   dumpType(D->getUnderlyingType());
976 }
977 
VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl * D)978 void ASTDumper::VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {
979   dumpName(D);
980   dumpTemplateParameters(D->getTemplateParameters());
981   dumpDecl(D->getTemplatedDecl());
982 }
983 
VisitCXXRecordDecl(const CXXRecordDecl * D)984 void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
985   VisitRecordDecl(D);
986   if (!D->isCompleteDefinition())
987     return;
988 
989   for (CXXRecordDecl::base_class_const_iterator I = D->bases_begin(),
990                                                 E = D->bases_end();
991        I != E; ++I) {
992     IndentScope Indent(*this);
993     if (I->isVirtual())
994       OS << "virtual ";
995     dumpAccessSpecifier(I->getAccessSpecifier());
996     dumpType(I->getType());
997     if (I->isPackExpansion())
998       OS << "...";
999   }
1000 }
1001 
VisitStaticAssertDecl(const StaticAssertDecl * D)1002 void ASTDumper::VisitStaticAssertDecl(const StaticAssertDecl *D) {
1003   dumpStmt(D->getAssertExpr());
1004   lastChild();
1005   dumpStmt(D->getMessage());
1006 }
1007 
VisitFunctionTemplateDecl(const FunctionTemplateDecl * D)1008 void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
1009   dumpName(D);
1010   dumpTemplateParameters(D->getTemplateParameters());
1011   dumpDecl(D->getTemplatedDecl());
1012   for (FunctionTemplateDecl::spec_iterator I = D->spec_begin(),
1013                                            E = D->spec_end();
1014        I != E; ++I) {
1015     FunctionTemplateDecl::spec_iterator Next = I;
1016     ++Next;
1017     if (Next == E)
1018       lastChild();
1019     switch (I->getTemplateSpecializationKind()) {
1020     case TSK_Undeclared:
1021     case TSK_ImplicitInstantiation:
1022     case TSK_ExplicitInstantiationDeclaration:
1023     case TSK_ExplicitInstantiationDefinition:
1024       if (D == D->getCanonicalDecl())
1025         dumpDecl(*I);
1026       else
1027         dumpDeclRef(*I);
1028       break;
1029     case TSK_ExplicitSpecialization:
1030       dumpDeclRef(*I);
1031       break;
1032     }
1033   }
1034 }
1035 
VisitClassTemplateDecl(const ClassTemplateDecl * D)1036 void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
1037   dumpName(D);
1038   dumpTemplateParameters(D->getTemplateParameters());
1039 
1040   ClassTemplateDecl::spec_iterator I = D->spec_begin();
1041   ClassTemplateDecl::spec_iterator E = D->spec_end();
1042   if (I == E)
1043     lastChild();
1044   dumpDecl(D->getTemplatedDecl());
1045   for (; I != E; ++I) {
1046     ClassTemplateDecl::spec_iterator Next = I;
1047     ++Next;
1048     if (Next == E)
1049       lastChild();
1050     switch (I->getTemplateSpecializationKind()) {
1051     case TSK_Undeclared:
1052     case TSK_ImplicitInstantiation:
1053       if (D == D->getCanonicalDecl())
1054         dumpDecl(*I);
1055       else
1056         dumpDeclRef(*I);
1057       break;
1058     case TSK_ExplicitSpecialization:
1059     case TSK_ExplicitInstantiationDeclaration:
1060     case TSK_ExplicitInstantiationDefinition:
1061       dumpDeclRef(*I);
1062       break;
1063     }
1064   }
1065 }
1066 
VisitClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl * D)1067 void ASTDumper::VisitClassTemplateSpecializationDecl(
1068     const ClassTemplateSpecializationDecl *D) {
1069   VisitCXXRecordDecl(D);
1070   dumpTemplateArgumentList(D->getTemplateArgs());
1071 }
1072 
VisitClassTemplatePartialSpecializationDecl(const ClassTemplatePartialSpecializationDecl * D)1073 void ASTDumper::VisitClassTemplatePartialSpecializationDecl(
1074     const ClassTemplatePartialSpecializationDecl *D) {
1075   VisitClassTemplateSpecializationDecl(D);
1076   dumpTemplateParameters(D->getTemplateParameters());
1077 }
1078 
VisitClassScopeFunctionSpecializationDecl(const ClassScopeFunctionSpecializationDecl * D)1079 void ASTDumper::VisitClassScopeFunctionSpecializationDecl(
1080     const ClassScopeFunctionSpecializationDecl *D) {
1081   dumpDeclRef(D->getSpecialization());
1082   if (D->hasExplicitTemplateArgs())
1083     dumpTemplateArgumentListInfo(D->templateArgs());
1084 }
1085 
VisitTemplateTypeParmDecl(const TemplateTypeParmDecl * D)1086 void ASTDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
1087   if (D->wasDeclaredWithTypename())
1088     OS << " typename";
1089   else
1090     OS << " class";
1091   if (D->isParameterPack())
1092     OS << " ...";
1093   dumpName(D);
1094   if (D->hasDefaultArgument())
1095     dumpType(D->getDefaultArgument());
1096 }
1097 
VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl * D)1098 void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
1099   dumpType(D->getType());
1100   if (D->isParameterPack())
1101     OS << " ...";
1102   dumpName(D);
1103   if (D->hasDefaultArgument())
1104     dumpStmt(D->getDefaultArgument());
1105 }
1106 
VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl * D)1107 void ASTDumper::VisitTemplateTemplateParmDecl(
1108     const TemplateTemplateParmDecl *D) {
1109   if (D->isParameterPack())
1110     OS << " ...";
1111   dumpName(D);
1112   dumpTemplateParameters(D->getTemplateParameters());
1113   if (D->hasDefaultArgument())
1114     dumpTemplateArgumentLoc(D->getDefaultArgument());
1115 }
1116 
VisitUsingDecl(const UsingDecl * D)1117 void ASTDumper::VisitUsingDecl(const UsingDecl *D) {
1118   OS << ' ';
1119   D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
1120   OS << D->getNameAsString();
1121 }
1122 
VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl * D)1123 void ASTDumper::VisitUnresolvedUsingTypenameDecl(
1124     const UnresolvedUsingTypenameDecl *D) {
1125   OS << ' ';
1126   D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
1127   OS << D->getNameAsString();
1128 }
1129 
VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl * D)1130 void ASTDumper::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
1131   OS << ' ';
1132   D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
1133   OS << D->getNameAsString();
1134   dumpType(D->getType());
1135 }
1136 
VisitUsingShadowDecl(const UsingShadowDecl * D)1137 void ASTDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
1138   OS << ' ';
1139   dumpBareDeclRef(D->getTargetDecl());
1140 }
1141 
VisitLinkageSpecDecl(const LinkageSpecDecl * D)1142 void ASTDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
1143   switch (D->getLanguage()) {
1144   case LinkageSpecDecl::lang_c: OS << " C"; break;
1145   case LinkageSpecDecl::lang_cxx: OS << " C++"; break;
1146   }
1147 }
1148 
VisitAccessSpecDecl(const AccessSpecDecl * D)1149 void ASTDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
1150   OS << ' ';
1151   dumpAccessSpecifier(D->getAccess());
1152 }
1153 
VisitFriendDecl(const FriendDecl * D)1154 void ASTDumper::VisitFriendDecl(const FriendDecl *D) {
1155   lastChild();
1156   if (TypeSourceInfo *T = D->getFriendType())
1157     dumpType(T->getType());
1158   else
1159     dumpDecl(D->getFriendDecl());
1160 }
1161 
1162 //===----------------------------------------------------------------------===//
1163 // Obj-C Declarations
1164 //===----------------------------------------------------------------------===//
1165 
VisitObjCIvarDecl(const ObjCIvarDecl * D)1166 void ASTDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
1167   dumpName(D);
1168   dumpType(D->getType());
1169   if (D->getSynthesize())
1170     OS << " synthesize";
1171 
1172   switch (D->getAccessControl()) {
1173   case ObjCIvarDecl::None:
1174     OS << " none";
1175     break;
1176   case ObjCIvarDecl::Private:
1177     OS << " private";
1178     break;
1179   case ObjCIvarDecl::Protected:
1180     OS << " protected";
1181     break;
1182   case ObjCIvarDecl::Public:
1183     OS << " public";
1184     break;
1185   case ObjCIvarDecl::Package:
1186     OS << " package";
1187     break;
1188   }
1189 }
1190 
VisitObjCMethodDecl(const ObjCMethodDecl * D)1191 void ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
1192   if (D->isInstanceMethod())
1193     OS << " -";
1194   else
1195     OS << " +";
1196   dumpName(D);
1197   dumpType(D->getResultType());
1198 
1199   bool OldMoreChildren = hasMoreChildren();
1200   bool IsVariadic = D->isVariadic();
1201   bool HasBody = D->hasBody();
1202 
1203   setMoreChildren(OldMoreChildren || IsVariadic || HasBody);
1204   if (D->isThisDeclarationADefinition()) {
1205     lastChild();
1206     dumpDeclContext(D);
1207   } else {
1208     for (ObjCMethodDecl::param_const_iterator I = D->param_begin(),
1209                                               E = D->param_end();
1210          I != E; ++I) {
1211       if (I + 1 == E)
1212         lastChild();
1213       dumpDecl(*I);
1214     }
1215   }
1216 
1217   setMoreChildren(OldMoreChildren || HasBody);
1218   if (IsVariadic) {
1219     lastChild();
1220     IndentScope Indent(*this);
1221     OS << "...";
1222   }
1223 
1224   setMoreChildren(OldMoreChildren);
1225   if (HasBody) {
1226     lastChild();
1227     dumpStmt(D->getBody());
1228   }
1229 }
1230 
VisitObjCCategoryDecl(const ObjCCategoryDecl * D)1231 void ASTDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
1232   dumpName(D);
1233   dumpDeclRef(D->getClassInterface());
1234   if (D->protocol_begin() == D->protocol_end())
1235     lastChild();
1236   dumpDeclRef(D->getImplementation());
1237   for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(),
1238                                            E = D->protocol_end();
1239        I != E; ++I) {
1240     if (I + 1 == E)
1241       lastChild();
1242     dumpDeclRef(*I);
1243   }
1244 }
1245 
VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl * D)1246 void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
1247   dumpName(D);
1248   dumpDeclRef(D->getClassInterface());
1249   lastChild();
1250   dumpDeclRef(D->getCategoryDecl());
1251 }
1252 
VisitObjCProtocolDecl(const ObjCProtocolDecl * D)1253 void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
1254   dumpName(D);
1255   for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(),
1256                                            E = D->protocol_end();
1257        I != E; ++I) {
1258     if (I + 1 == E)
1259       lastChild();
1260     dumpDeclRef(*I);
1261   }
1262 }
1263 
VisitObjCInterfaceDecl(const ObjCInterfaceDecl * D)1264 void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
1265   dumpName(D);
1266   dumpDeclRef(D->getSuperClass(), "super");
1267   if (D->protocol_begin() == D->protocol_end())
1268     lastChild();
1269   dumpDeclRef(D->getImplementation());
1270   for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1271                                             E = D->protocol_end();
1272        I != E; ++I) {
1273     if (I + 1 == E)
1274       lastChild();
1275     dumpDeclRef(*I);
1276   }
1277 }
1278 
VisitObjCImplementationDecl(const ObjCImplementationDecl * D)1279 void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
1280   dumpName(D);
1281   dumpDeclRef(D->getSuperClass(), "super");
1282   if (D->init_begin() == D->init_end())
1283     lastChild();
1284   dumpDeclRef(D->getClassInterface());
1285   for (ObjCImplementationDecl::init_const_iterator I = D->init_begin(),
1286                                                    E = D->init_end();
1287        I != E; ++I) {
1288     if (I + 1 == E)
1289       lastChild();
1290     dumpCXXCtorInitializer(*I);
1291   }
1292 }
1293 
VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl * D)1294 void ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) {
1295   dumpName(D);
1296   lastChild();
1297   dumpDeclRef(D->getClassInterface());
1298 }
1299 
VisitObjCPropertyDecl(const ObjCPropertyDecl * D)1300 void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
1301   dumpName(D);
1302   dumpType(D->getType());
1303 
1304   if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
1305     OS << " required";
1306   else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
1307     OS << " optional";
1308 
1309   ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes();
1310   if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) {
1311     if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly)
1312       OS << " readonly";
1313     if (Attrs & ObjCPropertyDecl::OBJC_PR_assign)
1314       OS << " assign";
1315     if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite)
1316       OS << " readwrite";
1317     if (Attrs & ObjCPropertyDecl::OBJC_PR_retain)
1318       OS << " retain";
1319     if (Attrs & ObjCPropertyDecl::OBJC_PR_copy)
1320       OS << " copy";
1321     if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic)
1322       OS << " nonatomic";
1323     if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic)
1324       OS << " atomic";
1325     if (Attrs & ObjCPropertyDecl::OBJC_PR_weak)
1326       OS << " weak";
1327     if (Attrs & ObjCPropertyDecl::OBJC_PR_strong)
1328       OS << " strong";
1329     if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained)
1330       OS << " unsafe_unretained";
1331     if (Attrs & ObjCPropertyDecl::OBJC_PR_getter) {
1332       if (!(Attrs & ObjCPropertyDecl::OBJC_PR_setter))
1333         lastChild();
1334       dumpDeclRef(D->getGetterMethodDecl(), "getter");
1335     }
1336     if (Attrs & ObjCPropertyDecl::OBJC_PR_setter) {
1337       lastChild();
1338       dumpDeclRef(D->getSetterMethodDecl(), "setter");
1339     }
1340   }
1341 }
1342 
VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl * D)1343 void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
1344   dumpName(D->getPropertyDecl());
1345   if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
1346     OS << " synthesize";
1347   else
1348     OS << " dynamic";
1349   dumpDeclRef(D->getPropertyDecl());
1350   lastChild();
1351   dumpDeclRef(D->getPropertyIvarDecl());
1352 }
1353 
VisitBlockDecl(const BlockDecl * D)1354 void ASTDumper::VisitBlockDecl(const BlockDecl *D) {
1355   for (BlockDecl::param_const_iterator I = D->param_begin(), E = D->param_end();
1356        I != E; ++I)
1357     dumpDecl(*I);
1358 
1359   if (D->isVariadic()) {
1360     IndentScope Indent(*this);
1361     OS << "...";
1362   }
1363 
1364   if (D->capturesCXXThis()) {
1365     IndentScope Indent(*this);
1366     OS << "capture this";
1367   }
1368   for (BlockDecl::capture_iterator I = D->capture_begin(), E = D->capture_end();
1369        I != E; ++I) {
1370     IndentScope Indent(*this);
1371     OS << "capture";
1372     if (I->isByRef())
1373       OS << " byref";
1374     if (I->isNested())
1375       OS << " nested";
1376     if (I->getVariable()) {
1377       OS << ' ';
1378       dumpBareDeclRef(I->getVariable());
1379     }
1380     if (I->hasCopyExpr())
1381       dumpStmt(I->getCopyExpr());
1382   }
1383   lastChild();
1384   dumpStmt(D->getBody());
1385 }
1386 
1387 //===----------------------------------------------------------------------===//
1388 //  Stmt dumping methods.
1389 //===----------------------------------------------------------------------===//
1390 
dumpStmt(const Stmt * S)1391 void ASTDumper::dumpStmt(const Stmt *S) {
1392   IndentScope Indent(*this);
1393 
1394   if (!S) {
1395     ColorScope Color(*this, NullColor);
1396     OS << "<<<NULL>>>";
1397     return;
1398   }
1399 
1400   if (const DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
1401     VisitDeclStmt(DS);
1402     return;
1403   }
1404 
1405   setMoreChildren(!S->children().empty());
1406   ConstStmtVisitor<ASTDumper>::Visit(S);
1407   setMoreChildren(false);
1408   for (Stmt::const_child_range CI = S->children(); CI; ++CI) {
1409     Stmt::const_child_range Next = CI;
1410     ++Next;
1411     if (!Next)
1412       lastChild();
1413     dumpStmt(*CI);
1414   }
1415 }
1416 
VisitStmt(const Stmt * Node)1417 void ASTDumper::VisitStmt(const Stmt *Node) {
1418   {
1419     ColorScope Color(*this, StmtColor);
1420     OS << Node->getStmtClassName();
1421   }
1422   dumpPointer(Node);
1423   dumpSourceRange(Node->getSourceRange());
1424 }
1425 
VisitDeclStmt(const DeclStmt * Node)1426 void ASTDumper::VisitDeclStmt(const DeclStmt *Node) {
1427   VisitStmt(Node);
1428   for (DeclStmt::const_decl_iterator I = Node->decl_begin(),
1429                                      E = Node->decl_end();
1430        I != E; ++I) {
1431     if (I + 1 == E)
1432       lastChild();
1433     dumpDecl(*I);
1434   }
1435 }
1436 
VisitAttributedStmt(const AttributedStmt * Node)1437 void ASTDumper::VisitAttributedStmt(const AttributedStmt *Node) {
1438   VisitStmt(Node);
1439   for (ArrayRef<const Attr *>::iterator I = Node->getAttrs().begin(),
1440                                         E = Node->getAttrs().end();
1441        I != E; ++I) {
1442     if (I + 1 == E)
1443       lastChild();
1444     dumpAttr(*I);
1445   }
1446 }
1447 
VisitLabelStmt(const LabelStmt * Node)1448 void ASTDumper::VisitLabelStmt(const LabelStmt *Node) {
1449   VisitStmt(Node);
1450   OS << " '" << Node->getName() << "'";
1451 }
1452 
VisitGotoStmt(const GotoStmt * Node)1453 void ASTDumper::VisitGotoStmt(const GotoStmt *Node) {
1454   VisitStmt(Node);
1455   OS << " '" << Node->getLabel()->getName() << "'";
1456   dumpPointer(Node->getLabel());
1457 }
1458 
1459 //===----------------------------------------------------------------------===//
1460 //  Expr dumping methods.
1461 //===----------------------------------------------------------------------===//
1462 
VisitExpr(const Expr * Node)1463 void ASTDumper::VisitExpr(const Expr *Node) {
1464   VisitStmt(Node);
1465   dumpType(Node->getType());
1466 
1467   {
1468     ColorScope Color(*this, ValueKindColor);
1469     switch (Node->getValueKind()) {
1470     case VK_RValue:
1471       break;
1472     case VK_LValue:
1473       OS << " lvalue";
1474       break;
1475     case VK_XValue:
1476       OS << " xvalue";
1477       break;
1478     }
1479   }
1480 
1481   {
1482     ColorScope Color(*this, ObjectKindColor);
1483     switch (Node->getObjectKind()) {
1484     case OK_Ordinary:
1485       break;
1486     case OK_BitField:
1487       OS << " bitfield";
1488       break;
1489     case OK_ObjCProperty:
1490       OS << " objcproperty";
1491       break;
1492     case OK_ObjCSubscript:
1493       OS << " objcsubscript";
1494       break;
1495     case OK_VectorComponent:
1496       OS << " vectorcomponent";
1497       break;
1498     }
1499   }
1500 }
1501 
dumpBasePath(raw_ostream & OS,const CastExpr * Node)1502 static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
1503   if (Node->path_empty())
1504     return;
1505 
1506   OS << " (";
1507   bool First = true;
1508   for (CastExpr::path_const_iterator I = Node->path_begin(),
1509                                      E = Node->path_end();
1510        I != E; ++I) {
1511     const CXXBaseSpecifier *Base = *I;
1512     if (!First)
1513       OS << " -> ";
1514 
1515     const CXXRecordDecl *RD =
1516     cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
1517 
1518     if (Base->isVirtual())
1519       OS << "virtual ";
1520     OS << RD->getName();
1521     First = false;
1522   }
1523 
1524   OS << ')';
1525 }
1526 
VisitCastExpr(const CastExpr * Node)1527 void ASTDumper::VisitCastExpr(const CastExpr *Node) {
1528   VisitExpr(Node);
1529   OS << " <";
1530   {
1531     ColorScope Color(*this, CastColor);
1532     OS << Node->getCastKindName();
1533   }
1534   dumpBasePath(OS, Node);
1535   OS << ">";
1536 }
1537 
VisitDeclRefExpr(const DeclRefExpr * Node)1538 void ASTDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
1539   VisitExpr(Node);
1540 
1541   OS << " ";
1542   dumpBareDeclRef(Node->getDecl());
1543   if (Node->getDecl() != Node->getFoundDecl()) {
1544     OS << " (";
1545     dumpBareDeclRef(Node->getFoundDecl());
1546     OS << ")";
1547   }
1548 }
1549 
VisitUnresolvedLookupExpr(const UnresolvedLookupExpr * Node)1550 void ASTDumper::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node) {
1551   VisitExpr(Node);
1552   OS << " (";
1553   if (!Node->requiresADL())
1554     OS << "no ";
1555   OS << "ADL) = '" << Node->getName() << '\'';
1556 
1557   UnresolvedLookupExpr::decls_iterator
1558     I = Node->decls_begin(), E = Node->decls_end();
1559   if (I == E)
1560     OS << " empty";
1561   for (; I != E; ++I)
1562     dumpPointer(*I);
1563 }
1564 
VisitObjCIvarRefExpr(const ObjCIvarRefExpr * Node)1565 void ASTDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) {
1566   VisitExpr(Node);
1567 
1568   {
1569     ColorScope Color(*this, DeclKindNameColor);
1570     OS << " " << Node->getDecl()->getDeclKindName() << "Decl";
1571   }
1572   OS << "='" << *Node->getDecl() << "'";
1573   dumpPointer(Node->getDecl());
1574   if (Node->isFreeIvar())
1575     OS << " isFreeIvar";
1576 }
1577 
VisitPredefinedExpr(const PredefinedExpr * Node)1578 void ASTDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
1579   VisitExpr(Node);
1580   switch (Node->getIdentType()) {
1581   default: llvm_unreachable("unknown case");
1582   case PredefinedExpr::Func:           OS <<  " __func__"; break;
1583   case PredefinedExpr::Function:       OS <<  " __FUNCTION__"; break;
1584   case PredefinedExpr::LFunction:      OS <<  " L__FUNCTION__"; break;
1585   case PredefinedExpr::PrettyFunction: OS <<  " __PRETTY_FUNCTION__";break;
1586   }
1587 }
1588 
VisitCharacterLiteral(const CharacterLiteral * Node)1589 void ASTDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
1590   VisitExpr(Node);
1591   ColorScope Color(*this, ValueColor);
1592   OS << " " << Node->getValue();
1593 }
1594 
VisitIntegerLiteral(const IntegerLiteral * Node)1595 void ASTDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
1596   VisitExpr(Node);
1597 
1598   bool isSigned = Node->getType()->isSignedIntegerType();
1599   ColorScope Color(*this, ValueColor);
1600   OS << " " << Node->getValue().toString(10, isSigned);
1601 }
1602 
VisitFloatingLiteral(const FloatingLiteral * Node)1603 void ASTDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
1604   VisitExpr(Node);
1605   ColorScope Color(*this, ValueColor);
1606   OS << " " << Node->getValueAsApproximateDouble();
1607 }
1608 
VisitStringLiteral(const StringLiteral * Str)1609 void ASTDumper::VisitStringLiteral(const StringLiteral *Str) {
1610   VisitExpr(Str);
1611   ColorScope Color(*this, ValueColor);
1612   OS << " ";
1613   Str->outputString(OS);
1614 }
1615 
VisitUnaryOperator(const UnaryOperator * Node)1616 void ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) {
1617   VisitExpr(Node);
1618   OS << " " << (Node->isPostfix() ? "postfix" : "prefix")
1619      << " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1620 }
1621 
VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr * Node)1622 void ASTDumper::VisitUnaryExprOrTypeTraitExpr(
1623     const UnaryExprOrTypeTraitExpr *Node) {
1624   VisitExpr(Node);
1625   switch(Node->getKind()) {
1626   case UETT_SizeOf:
1627     OS << " sizeof";
1628     break;
1629   case UETT_AlignOf:
1630     OS << " alignof";
1631     break;
1632   case UETT_VecStep:
1633     OS << " vec_step";
1634     break;
1635   }
1636   if (Node->isArgumentType())
1637     dumpType(Node->getArgumentType());
1638 }
1639 
VisitMemberExpr(const MemberExpr * Node)1640 void ASTDumper::VisitMemberExpr(const MemberExpr *Node) {
1641   VisitExpr(Node);
1642   OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
1643   dumpPointer(Node->getMemberDecl());
1644 }
1645 
VisitExtVectorElementExpr(const ExtVectorElementExpr * Node)1646 void ASTDumper::VisitExtVectorElementExpr(const ExtVectorElementExpr *Node) {
1647   VisitExpr(Node);
1648   OS << " " << Node->getAccessor().getNameStart();
1649 }
1650 
VisitBinaryOperator(const BinaryOperator * Node)1651 void ASTDumper::VisitBinaryOperator(const BinaryOperator *Node) {
1652   VisitExpr(Node);
1653   OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1654 }
1655 
VisitCompoundAssignOperator(const CompoundAssignOperator * Node)1656 void ASTDumper::VisitCompoundAssignOperator(
1657     const CompoundAssignOperator *Node) {
1658   VisitExpr(Node);
1659   OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
1660      << "' ComputeLHSTy=";
1661   dumpBareType(Node->getComputationLHSType());
1662   OS << " ComputeResultTy=";
1663   dumpBareType(Node->getComputationResultType());
1664 }
1665 
VisitBlockExpr(const BlockExpr * Node)1666 void ASTDumper::VisitBlockExpr(const BlockExpr *Node) {
1667   VisitExpr(Node);
1668   dumpDecl(Node->getBlockDecl());
1669 }
1670 
VisitOpaqueValueExpr(const OpaqueValueExpr * Node)1671 void ASTDumper::VisitOpaqueValueExpr(const OpaqueValueExpr *Node) {
1672   VisitExpr(Node);
1673 
1674   if (Expr *Source = Node->getSourceExpr()) {
1675     lastChild();
1676     dumpStmt(Source);
1677   }
1678 }
1679 
1680 // GNU extensions.
1681 
VisitAddrLabelExpr(const AddrLabelExpr * Node)1682 void ASTDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
1683   VisitExpr(Node);
1684   OS << " " << Node->getLabel()->getName();
1685   dumpPointer(Node->getLabel());
1686 }
1687 
1688 //===----------------------------------------------------------------------===//
1689 // C++ Expressions
1690 //===----------------------------------------------------------------------===//
1691 
VisitCXXNamedCastExpr(const CXXNamedCastExpr * Node)1692 void ASTDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) {
1693   VisitExpr(Node);
1694   OS << " " << Node->getCastName()
1695      << "<" << Node->getTypeAsWritten().getAsString() << ">"
1696      << " <" << Node->getCastKindName();
1697   dumpBasePath(OS, Node);
1698   OS << ">";
1699 }
1700 
VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr * Node)1701 void ASTDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
1702   VisitExpr(Node);
1703   OS << " " << (Node->getValue() ? "true" : "false");
1704 }
1705 
VisitCXXThisExpr(const CXXThisExpr * Node)1706 void ASTDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
1707   VisitExpr(Node);
1708   OS << " this";
1709 }
1710 
VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr * Node)1711 void ASTDumper::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node) {
1712   VisitExpr(Node);
1713   OS << " functional cast to " << Node->getTypeAsWritten().getAsString()
1714      << " <" << Node->getCastKindName() << ">";
1715 }
1716 
VisitCXXConstructExpr(const CXXConstructExpr * Node)1717 void ASTDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
1718   VisitExpr(Node);
1719   CXXConstructorDecl *Ctor = Node->getConstructor();
1720   dumpType(Ctor->getType());
1721   if (Node->isElidable())
1722     OS << " elidable";
1723   if (Node->requiresZeroInitialization())
1724     OS << " zeroing";
1725 }
1726 
VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr * Node)1727 void ASTDumper::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node) {
1728   VisitExpr(Node);
1729   OS << " ";
1730   dumpCXXTemporary(Node->getTemporary());
1731 }
1732 
1733 void
VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr * Node)1734 ASTDumper::VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node) {
1735   VisitExpr(Node);
1736   if (const ValueDecl *VD = Node->getExtendingDecl()) {
1737     OS << " extended by ";
1738     dumpBareDeclRef(VD);
1739   }
1740 }
1741 
VisitExprWithCleanups(const ExprWithCleanups * Node)1742 void ASTDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
1743   VisitExpr(Node);
1744   for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
1745     dumpDeclRef(Node->getObject(i), "cleanup");
1746 }
1747 
dumpCXXTemporary(const CXXTemporary * Temporary)1748 void ASTDumper::dumpCXXTemporary(const CXXTemporary *Temporary) {
1749   OS << "(CXXTemporary";
1750   dumpPointer(Temporary);
1751   OS << ")";
1752 }
1753 
1754 //===----------------------------------------------------------------------===//
1755 // Obj-C Expressions
1756 //===----------------------------------------------------------------------===//
1757 
VisitObjCMessageExpr(const ObjCMessageExpr * Node)1758 void ASTDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
1759   VisitExpr(Node);
1760   OS << " selector=" << Node->getSelector().getAsString();
1761   switch (Node->getReceiverKind()) {
1762   case ObjCMessageExpr::Instance:
1763     break;
1764 
1765   case ObjCMessageExpr::Class:
1766     OS << " class=";
1767     dumpBareType(Node->getClassReceiver());
1768     break;
1769 
1770   case ObjCMessageExpr::SuperInstance:
1771     OS << " super (instance)";
1772     break;
1773 
1774   case ObjCMessageExpr::SuperClass:
1775     OS << " super (class)";
1776     break;
1777   }
1778 }
1779 
VisitObjCBoxedExpr(const ObjCBoxedExpr * Node)1780 void ASTDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
1781   VisitExpr(Node);
1782   OS << " selector=" << Node->getBoxingMethod()->getSelector().getAsString();
1783 }
1784 
VisitObjCAtCatchStmt(const ObjCAtCatchStmt * Node)1785 void ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
1786   VisitStmt(Node);
1787   if (const VarDecl *CatchParam = Node->getCatchParamDecl())
1788     dumpDecl(CatchParam);
1789   else
1790     OS << " catch all";
1791 }
1792 
VisitObjCEncodeExpr(const ObjCEncodeExpr * Node)1793 void ASTDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
1794   VisitExpr(Node);
1795   dumpType(Node->getEncodedType());
1796 }
1797 
VisitObjCSelectorExpr(const ObjCSelectorExpr * Node)1798 void ASTDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
1799   VisitExpr(Node);
1800 
1801   OS << " " << Node->getSelector().getAsString();
1802 }
1803 
VisitObjCProtocolExpr(const ObjCProtocolExpr * Node)1804 void ASTDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
1805   VisitExpr(Node);
1806 
1807   OS << ' ' << *Node->getProtocol();
1808 }
1809 
VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr * Node)1810 void ASTDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
1811   VisitExpr(Node);
1812   if (Node->isImplicitProperty()) {
1813     OS << " Kind=MethodRef Getter=\"";
1814     if (Node->getImplicitPropertyGetter())
1815       OS << Node->getImplicitPropertyGetter()->getSelector().getAsString();
1816     else
1817       OS << "(null)";
1818 
1819     OS << "\" Setter=\"";
1820     if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
1821       OS << Setter->getSelector().getAsString();
1822     else
1823       OS << "(null)";
1824     OS << "\"";
1825   } else {
1826     OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty() <<'"';
1827   }
1828 
1829   if (Node->isSuperReceiver())
1830     OS << " super";
1831 
1832   OS << " Messaging=";
1833   if (Node->isMessagingGetter() && Node->isMessagingSetter())
1834     OS << "Getter&Setter";
1835   else if (Node->isMessagingGetter())
1836     OS << "Getter";
1837   else if (Node->isMessagingSetter())
1838     OS << "Setter";
1839 }
1840 
VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr * Node)1841 void ASTDumper::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node) {
1842   VisitExpr(Node);
1843   if (Node->isArraySubscriptRefExpr())
1844     OS << " Kind=ArraySubscript GetterForArray=\"";
1845   else
1846     OS << " Kind=DictionarySubscript GetterForDictionary=\"";
1847   if (Node->getAtIndexMethodDecl())
1848     OS << Node->getAtIndexMethodDecl()->getSelector().getAsString();
1849   else
1850     OS << "(null)";
1851 
1852   if (Node->isArraySubscriptRefExpr())
1853     OS << "\" SetterForArray=\"";
1854   else
1855     OS << "\" SetterForDictionary=\"";
1856   if (Node->setAtIndexMethodDecl())
1857     OS << Node->setAtIndexMethodDecl()->getSelector().getAsString();
1858   else
1859     OS << "(null)";
1860 }
1861 
VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr * Node)1862 void ASTDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) {
1863   VisitExpr(Node);
1864   OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
1865 }
1866 
1867 //===----------------------------------------------------------------------===//
1868 // Comments
1869 //===----------------------------------------------------------------------===//
1870 
getCommandName(unsigned CommandID)1871 const char *ASTDumper::getCommandName(unsigned CommandID) {
1872   if (Traits)
1873     return Traits->getCommandInfo(CommandID)->Name;
1874   const CommandInfo *Info = CommandTraits::getBuiltinCommandInfo(CommandID);
1875   if (Info)
1876     return Info->Name;
1877   return "<not a builtin command>";
1878 }
1879 
dumpFullComment(const FullComment * C)1880 void ASTDumper::dumpFullComment(const FullComment *C) {
1881   if (!C)
1882     return;
1883 
1884   FC = C;
1885   dumpComment(C);
1886   FC = 0;
1887 }
1888 
dumpComment(const Comment * C)1889 void ASTDumper::dumpComment(const Comment *C) {
1890   IndentScope Indent(*this);
1891 
1892   if (!C) {
1893     ColorScope Color(*this, NullColor);
1894     OS << "<<<NULL>>>";
1895     return;
1896   }
1897 
1898   {
1899     ColorScope Color(*this, CommentColor);
1900     OS << C->getCommentKindName();
1901   }
1902   dumpPointer(C);
1903   dumpSourceRange(C->getSourceRange());
1904   ConstCommentVisitor<ASTDumper>::visit(C);
1905   for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
1906        I != E; ++I) {
1907     if (I + 1 == E)
1908       lastChild();
1909     dumpComment(*I);
1910   }
1911 }
1912 
visitTextComment(const TextComment * C)1913 void ASTDumper::visitTextComment(const TextComment *C) {
1914   OS << " Text=\"" << C->getText() << "\"";
1915 }
1916 
visitInlineCommandComment(const InlineCommandComment * C)1917 void ASTDumper::visitInlineCommandComment(const InlineCommandComment *C) {
1918   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
1919   switch (C->getRenderKind()) {
1920   case InlineCommandComment::RenderNormal:
1921     OS << " RenderNormal";
1922     break;
1923   case InlineCommandComment::RenderBold:
1924     OS << " RenderBold";
1925     break;
1926   case InlineCommandComment::RenderMonospaced:
1927     OS << " RenderMonospaced";
1928     break;
1929   case InlineCommandComment::RenderEmphasized:
1930     OS << " RenderEmphasized";
1931     break;
1932   }
1933 
1934   for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
1935     OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
1936 }
1937 
visitHTMLStartTagComment(const HTMLStartTagComment * C)1938 void ASTDumper::visitHTMLStartTagComment(const HTMLStartTagComment *C) {
1939   OS << " Name=\"" << C->getTagName() << "\"";
1940   if (C->getNumAttrs() != 0) {
1941     OS << " Attrs: ";
1942     for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
1943       const HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
1944       OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
1945     }
1946   }
1947   if (C->isSelfClosing())
1948     OS << " SelfClosing";
1949 }
1950 
visitHTMLEndTagComment(const HTMLEndTagComment * C)1951 void ASTDumper::visitHTMLEndTagComment(const HTMLEndTagComment *C) {
1952   OS << " Name=\"" << C->getTagName() << "\"";
1953 }
1954 
visitBlockCommandComment(const BlockCommandComment * C)1955 void ASTDumper::visitBlockCommandComment(const BlockCommandComment *C) {
1956   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
1957   for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
1958     OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
1959 }
1960 
visitParamCommandComment(const ParamCommandComment * C)1961 void ASTDumper::visitParamCommandComment(const ParamCommandComment *C) {
1962   OS << " " << ParamCommandComment::getDirectionAsString(C->getDirection());
1963 
1964   if (C->isDirectionExplicit())
1965     OS << " explicitly";
1966   else
1967     OS << " implicitly";
1968 
1969   if (C->hasParamName()) {
1970     if (C->isParamIndexValid())
1971       OS << " Param=\"" << C->getParamName(FC) << "\"";
1972     else
1973       OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
1974   }
1975 
1976   if (C->isParamIndexValid())
1977     OS << " ParamIndex=" << C->getParamIndex();
1978 }
1979 
visitTParamCommandComment(const TParamCommandComment * C)1980 void ASTDumper::visitTParamCommandComment(const TParamCommandComment *C) {
1981   if (C->hasParamName()) {
1982     if (C->isPositionValid())
1983       OS << " Param=\"" << C->getParamName(FC) << "\"";
1984     else
1985       OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
1986   }
1987 
1988   if (C->isPositionValid()) {
1989     OS << " Position=<";
1990     for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
1991       OS << C->getIndex(i);
1992       if (i != e - 1)
1993         OS << ", ";
1994     }
1995     OS << ">";
1996   }
1997 }
1998 
visitVerbatimBlockComment(const VerbatimBlockComment * C)1999 void ASTDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) {
2000   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""
2001         " CloseName=\"" << C->getCloseName() << "\"";
2002 }
2003 
visitVerbatimBlockLineComment(const VerbatimBlockLineComment * C)2004 void ASTDumper::visitVerbatimBlockLineComment(
2005     const VerbatimBlockLineComment *C) {
2006   OS << " Text=\"" << C->getText() << "\"";
2007 }
2008 
visitVerbatimLineComment(const VerbatimLineComment * C)2009 void ASTDumper::visitVerbatimLineComment(const VerbatimLineComment *C) {
2010   OS << " Text=\"" << C->getText() << "\"";
2011 }
2012 
2013 //===----------------------------------------------------------------------===//
2014 // Decl method implementations
2015 //===----------------------------------------------------------------------===//
2016 
dump() const2017 void Decl::dump() const {
2018   dump(llvm::errs());
2019 }
2020 
dump(raw_ostream & OS) const2021 void Decl::dump(raw_ostream &OS) const {
2022   ASTDumper P(OS, &getASTContext().getCommentCommandTraits(),
2023               &getASTContext().getSourceManager());
2024   P.dumpDecl(this);
2025 }
2026 
dumpColor() const2027 void Decl::dumpColor() const {
2028   ASTDumper P(llvm::errs(), &getASTContext().getCommentCommandTraits(),
2029               &getASTContext().getSourceManager(), /*ShowColors*/true);
2030   P.dumpDecl(this);
2031 }
2032 
dumpLookups() const2033 void DeclContext::dumpLookups() const {
2034   dumpLookups(llvm::errs());
2035 }
2036 
dumpLookups(raw_ostream & OS) const2037 void DeclContext::dumpLookups(raw_ostream &OS) const {
2038   const DeclContext *DC = this;
2039   while (!DC->isTranslationUnit())
2040     DC = DC->getParent();
2041   ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
2042   ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager());
2043   P.dumpLookups(this);
2044 }
2045 
2046 //===----------------------------------------------------------------------===//
2047 // Stmt method implementations
2048 //===----------------------------------------------------------------------===//
2049 
dump(SourceManager & SM) const2050 void Stmt::dump(SourceManager &SM) const {
2051   dump(llvm::errs(), SM);
2052 }
2053 
dump(raw_ostream & OS,SourceManager & SM) const2054 void Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
2055   ASTDumper P(OS, 0, &SM);
2056   P.dumpStmt(this);
2057 }
2058 
dump() const2059 void Stmt::dump() const {
2060   ASTDumper P(llvm::errs(), 0, 0);
2061   P.dumpStmt(this);
2062 }
2063 
dumpColor() const2064 void Stmt::dumpColor() const {
2065   ASTDumper P(llvm::errs(), 0, 0, /*ShowColors*/true);
2066   P.dumpStmt(this);
2067 }
2068 
2069 //===----------------------------------------------------------------------===//
2070 // Comment method implementations
2071 //===----------------------------------------------------------------------===//
2072 
dump() const2073 void Comment::dump() const {
2074   dump(llvm::errs(), 0, 0);
2075 }
2076 
dump(const ASTContext & Context) const2077 void Comment::dump(const ASTContext &Context) const {
2078   dump(llvm::errs(), &Context.getCommentCommandTraits(),
2079        &Context.getSourceManager());
2080 }
2081 
dump(raw_ostream & OS,const CommandTraits * Traits,const SourceManager * SM) const2082 void Comment::dump(raw_ostream &OS, const CommandTraits *Traits,
2083                    const SourceManager *SM) const {
2084   const FullComment *FC = dyn_cast<FullComment>(this);
2085   ASTDumper D(OS, Traits, SM);
2086   D.dumpFullComment(FC);
2087 }
2088 
dumpColor() const2089 void Comment::dumpColor() const {
2090   const FullComment *FC = dyn_cast<FullComment>(this);
2091   ASTDumper D(llvm::errs(), 0, 0, /*ShowColors*/true);
2092   D.dumpFullComment(FC);
2093 }
2094