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