]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/AST/ASTDumper.cpp
4478 dtrace_dof_maxsize is far too small
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / AST / ASTDumper.cpp
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   if (D->getBackingIvarReferencedInAccessor())
1245     OS << " BackingIvarReferencedInAccessor";
1246
1247   switch (D->getAccessControl()) {
1248   case ObjCIvarDecl::None:
1249     OS << " none";
1250     break;
1251   case ObjCIvarDecl::Private:
1252     OS << " private";
1253     break;
1254   case ObjCIvarDecl::Protected:
1255     OS << " protected";
1256     break;
1257   case ObjCIvarDecl::Public:
1258     OS << " public";
1259     break;
1260   case ObjCIvarDecl::Package:
1261     OS << " package";
1262     break;
1263   }
1264 }
1265
1266 void ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
1267   if (D->isInstanceMethod())
1268     OS << " -";
1269   else
1270     OS << " +";
1271   dumpName(D);
1272   dumpType(D->getResultType());
1273
1274   bool OldMoreChildren = hasMoreChildren();
1275   bool IsVariadic = D->isVariadic();
1276   bool HasBody = D->hasBody();
1277
1278   setMoreChildren(OldMoreChildren || IsVariadic || HasBody);
1279   if (D->isThisDeclarationADefinition()) {
1280     lastChild();
1281     dumpDeclContext(D);
1282   } else {
1283     for (ObjCMethodDecl::param_const_iterator I = D->param_begin(),
1284                                               E = D->param_end();
1285          I != E; ++I) {
1286       if (I + 1 == E)
1287         lastChild();
1288       dumpDecl(*I);
1289     }
1290   }
1291
1292   setMoreChildren(OldMoreChildren || HasBody);
1293   if (IsVariadic) {
1294     lastChild();
1295     IndentScope Indent(*this);
1296     OS << "...";
1297   }
1298
1299   setMoreChildren(OldMoreChildren);
1300   if (HasBody) {
1301     lastChild();
1302     dumpStmt(D->getBody());
1303   }
1304 }
1305
1306 void ASTDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
1307   dumpName(D);
1308   dumpDeclRef(D->getClassInterface());
1309   if (D->protocol_begin() == D->protocol_end())
1310     lastChild();
1311   dumpDeclRef(D->getImplementation());
1312   for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(),
1313                                            E = D->protocol_end();
1314        I != E; ++I) {
1315     if (I + 1 == E)
1316       lastChild();
1317     dumpDeclRef(*I);
1318   }
1319 }
1320
1321 void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
1322   dumpName(D);
1323   dumpDeclRef(D->getClassInterface());
1324   lastChild();
1325   dumpDeclRef(D->getCategoryDecl());
1326 }
1327
1328 void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
1329   dumpName(D);
1330   for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(),
1331                                            E = D->protocol_end();
1332        I != E; ++I) {
1333     if (I + 1 == E)
1334       lastChild();
1335     dumpDeclRef(*I);
1336   }
1337 }
1338
1339 void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
1340   dumpName(D);
1341   dumpDeclRef(D->getSuperClass(), "super");
1342   if (D->protocol_begin() == D->protocol_end())
1343     lastChild();
1344   dumpDeclRef(D->getImplementation());
1345   for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1346                                             E = D->protocol_end();
1347        I != E; ++I) {
1348     if (I + 1 == E)
1349       lastChild();
1350     dumpDeclRef(*I);
1351   }
1352 }
1353
1354 void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
1355   dumpName(D);
1356   dumpDeclRef(D->getSuperClass(), "super");
1357   if (D->init_begin() == D->init_end())
1358     lastChild();
1359   dumpDeclRef(D->getClassInterface());
1360   for (ObjCImplementationDecl::init_const_iterator I = D->init_begin(),
1361                                                    E = D->init_end();
1362        I != E; ++I) {
1363     if (I + 1 == E)
1364       lastChild();
1365     dumpCXXCtorInitializer(*I);
1366   }
1367 }
1368
1369 void ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) {
1370   dumpName(D);
1371   lastChild();
1372   dumpDeclRef(D->getClassInterface());
1373 }
1374
1375 void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
1376   dumpName(D);
1377   dumpType(D->getType());
1378
1379   if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
1380     OS << " required";
1381   else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
1382     OS << " optional";
1383
1384   ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes();
1385   if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) {
1386     if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly)
1387       OS << " readonly";
1388     if (Attrs & ObjCPropertyDecl::OBJC_PR_assign)
1389       OS << " assign";
1390     if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite)
1391       OS << " readwrite";
1392     if (Attrs & ObjCPropertyDecl::OBJC_PR_retain)
1393       OS << " retain";
1394     if (Attrs & ObjCPropertyDecl::OBJC_PR_copy)
1395       OS << " copy";
1396     if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic)
1397       OS << " nonatomic";
1398     if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic)
1399       OS << " atomic";
1400     if (Attrs & ObjCPropertyDecl::OBJC_PR_weak)
1401       OS << " weak";
1402     if (Attrs & ObjCPropertyDecl::OBJC_PR_strong)
1403       OS << " strong";
1404     if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained)
1405       OS << " unsafe_unretained";
1406     if (Attrs & ObjCPropertyDecl::OBJC_PR_getter) {
1407       if (!(Attrs & ObjCPropertyDecl::OBJC_PR_setter))
1408         lastChild();
1409       dumpDeclRef(D->getGetterMethodDecl(), "getter");
1410     }
1411     if (Attrs & ObjCPropertyDecl::OBJC_PR_setter) {
1412       lastChild();
1413       dumpDeclRef(D->getSetterMethodDecl(), "setter");
1414     }
1415   }
1416 }
1417
1418 void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
1419   dumpName(D->getPropertyDecl());
1420   if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
1421     OS << " synthesize";
1422   else
1423     OS << " dynamic";
1424   dumpDeclRef(D->getPropertyDecl());
1425   lastChild();
1426   dumpDeclRef(D->getPropertyIvarDecl());
1427 }
1428
1429 void ASTDumper::VisitBlockDecl(const BlockDecl *D) {
1430   for (BlockDecl::param_const_iterator I = D->param_begin(), E = D->param_end();
1431        I != E; ++I)
1432     dumpDecl(*I);
1433
1434   if (D->isVariadic()) {
1435     IndentScope Indent(*this);
1436     OS << "...";
1437   }
1438
1439   if (D->capturesCXXThis()) {
1440     IndentScope Indent(*this);
1441     OS << "capture this";
1442   }
1443   for (BlockDecl::capture_iterator I = D->capture_begin(), E = D->capture_end();
1444        I != E; ++I) {
1445     IndentScope Indent(*this);
1446     OS << "capture";
1447     if (I->isByRef())
1448       OS << " byref";
1449     if (I->isNested())
1450       OS << " nested";
1451     if (I->getVariable()) {
1452       OS << ' ';
1453       dumpBareDeclRef(I->getVariable());
1454     }
1455     if (I->hasCopyExpr())
1456       dumpStmt(I->getCopyExpr());
1457   }
1458   lastChild();
1459   dumpStmt(D->getBody());
1460 }
1461
1462 //===----------------------------------------------------------------------===//
1463 //  Stmt dumping methods.
1464 //===----------------------------------------------------------------------===//
1465
1466 void ASTDumper::dumpStmt(const Stmt *S) {
1467   IndentScope Indent(*this);
1468
1469   if (!S) {
1470     ColorScope Color(*this, NullColor);
1471     OS << "<<<NULL>>>";
1472     return;
1473   }
1474
1475   if (const DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
1476     VisitDeclStmt(DS);
1477     return;
1478   }
1479
1480   setMoreChildren(!S->children().empty());
1481   ConstStmtVisitor<ASTDumper>::Visit(S);
1482   setMoreChildren(false);
1483   for (Stmt::const_child_range CI = S->children(); CI; ++CI) {
1484     Stmt::const_child_range Next = CI;
1485     ++Next;
1486     if (!Next)
1487       lastChild();
1488     dumpStmt(*CI);
1489   }
1490 }
1491
1492 void ASTDumper::VisitStmt(const Stmt *Node) {
1493   {   
1494     ColorScope Color(*this, StmtColor);
1495     OS << Node->getStmtClassName();
1496   }
1497   dumpPointer(Node);
1498   dumpSourceRange(Node->getSourceRange());
1499 }
1500
1501 void ASTDumper::VisitDeclStmt(const DeclStmt *Node) {
1502   VisitStmt(Node);
1503   for (DeclStmt::const_decl_iterator I = Node->decl_begin(),
1504                                      E = Node->decl_end();
1505        I != E; ++I) {
1506     if (I + 1 == E)
1507       lastChild();
1508     dumpDecl(*I);
1509   }
1510 }
1511
1512 void ASTDumper::VisitAttributedStmt(const AttributedStmt *Node) {
1513   VisitStmt(Node);
1514   for (ArrayRef<const Attr *>::iterator I = Node->getAttrs().begin(),
1515                                         E = Node->getAttrs().end();
1516        I != E; ++I) {
1517     if (I + 1 == E)
1518       lastChild();
1519     dumpAttr(*I);
1520   }
1521 }
1522
1523 void ASTDumper::VisitLabelStmt(const LabelStmt *Node) {
1524   VisitStmt(Node);
1525   OS << " '" << Node->getName() << "'";
1526 }
1527
1528 void ASTDumper::VisitGotoStmt(const GotoStmt *Node) {
1529   VisitStmt(Node);
1530   OS << " '" << Node->getLabel()->getName() << "'";
1531   dumpPointer(Node->getLabel());
1532 }
1533
1534 void ASTDumper::VisitCXXCatchStmt(const CXXCatchStmt *Node) {
1535   VisitStmt(Node);
1536   dumpDecl(Node->getExceptionDecl());
1537 }
1538
1539 //===----------------------------------------------------------------------===//
1540 //  Expr dumping methods.
1541 //===----------------------------------------------------------------------===//
1542
1543 void ASTDumper::VisitExpr(const Expr *Node) {
1544   VisitStmt(Node);
1545   dumpType(Node->getType());
1546
1547   {
1548     ColorScope Color(*this, ValueKindColor);
1549     switch (Node->getValueKind()) {
1550     case VK_RValue:
1551       break;
1552     case VK_LValue:
1553       OS << " lvalue";
1554       break;
1555     case VK_XValue:
1556       OS << " xvalue";
1557       break;
1558     }
1559   }
1560
1561   {
1562     ColorScope Color(*this, ObjectKindColor);
1563     switch (Node->getObjectKind()) {
1564     case OK_Ordinary:
1565       break;
1566     case OK_BitField:
1567       OS << " bitfield";
1568       break;
1569     case OK_ObjCProperty:
1570       OS << " objcproperty";
1571       break;
1572     case OK_ObjCSubscript:
1573       OS << " objcsubscript";
1574       break;
1575     case OK_VectorComponent:
1576       OS << " vectorcomponent";
1577       break;
1578     }
1579   }
1580 }
1581
1582 static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
1583   if (Node->path_empty())
1584     return;
1585
1586   OS << " (";
1587   bool First = true;
1588   for (CastExpr::path_const_iterator I = Node->path_begin(),
1589                                      E = Node->path_end();
1590        I != E; ++I) {
1591     const CXXBaseSpecifier *Base = *I;
1592     if (!First)
1593       OS << " -> ";
1594
1595     const CXXRecordDecl *RD =
1596     cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
1597
1598     if (Base->isVirtual())
1599       OS << "virtual ";
1600     OS << RD->getName();
1601     First = false;
1602   }
1603
1604   OS << ')';
1605 }
1606
1607 void ASTDumper::VisitCastExpr(const CastExpr *Node) {
1608   VisitExpr(Node);
1609   OS << " <";
1610   {
1611     ColorScope Color(*this, CastColor);
1612     OS << Node->getCastKindName();
1613   }
1614   dumpBasePath(OS, Node);
1615   OS << ">";
1616 }
1617
1618 void ASTDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
1619   VisitExpr(Node);
1620
1621   OS << " ";
1622   dumpBareDeclRef(Node->getDecl());
1623   if (Node->getDecl() != Node->getFoundDecl()) {
1624     OS << " (";
1625     dumpBareDeclRef(Node->getFoundDecl());
1626     OS << ")";
1627   }
1628 }
1629
1630 void ASTDumper::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node) {
1631   VisitExpr(Node);
1632   OS << " (";
1633   if (!Node->requiresADL())
1634     OS << "no ";
1635   OS << "ADL) = '" << Node->getName() << '\'';
1636
1637   UnresolvedLookupExpr::decls_iterator
1638     I = Node->decls_begin(), E = Node->decls_end();
1639   if (I == E)
1640     OS << " empty";
1641   for (; I != E; ++I)
1642     dumpPointer(*I);
1643 }
1644
1645 void ASTDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) {
1646   VisitExpr(Node);
1647
1648   {
1649     ColorScope Color(*this, DeclKindNameColor);
1650     OS << " " << Node->getDecl()->getDeclKindName() << "Decl";
1651   }
1652   OS << "='" << *Node->getDecl() << "'";
1653   dumpPointer(Node->getDecl());
1654   if (Node->isFreeIvar())
1655     OS << " isFreeIvar";
1656 }
1657
1658 void ASTDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
1659   VisitExpr(Node);
1660   switch (Node->getIdentType()) {
1661   default: llvm_unreachable("unknown case");
1662   case PredefinedExpr::Func:           OS <<  " __func__"; break;
1663   case PredefinedExpr::Function:       OS <<  " __FUNCTION__"; break;
1664   case PredefinedExpr::FuncDName:      OS <<  " __FUNCDNAME__"; break;
1665   case PredefinedExpr::LFunction:      OS <<  " L__FUNCTION__"; break;
1666   case PredefinedExpr::PrettyFunction: OS <<  " __PRETTY_FUNCTION__";break;
1667   }
1668 }
1669
1670 void ASTDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
1671   VisitExpr(Node);
1672   ColorScope Color(*this, ValueColor);
1673   OS << " " << Node->getValue();
1674 }
1675
1676 void ASTDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
1677   VisitExpr(Node);
1678
1679   bool isSigned = Node->getType()->isSignedIntegerType();
1680   ColorScope Color(*this, ValueColor);
1681   OS << " " << Node->getValue().toString(10, isSigned);
1682 }
1683
1684 void ASTDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
1685   VisitExpr(Node);
1686   ColorScope Color(*this, ValueColor);
1687   OS << " " << Node->getValueAsApproximateDouble();
1688 }
1689
1690 void ASTDumper::VisitStringLiteral(const StringLiteral *Str) {
1691   VisitExpr(Str);
1692   ColorScope Color(*this, ValueColor);
1693   OS << " ";
1694   Str->outputString(OS);
1695 }
1696
1697 void ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) {
1698   VisitExpr(Node);
1699   OS << " " << (Node->isPostfix() ? "postfix" : "prefix")
1700      << " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1701 }
1702
1703 void ASTDumper::VisitUnaryExprOrTypeTraitExpr(
1704     const UnaryExprOrTypeTraitExpr *Node) {
1705   VisitExpr(Node);
1706   switch(Node->getKind()) {
1707   case UETT_SizeOf:
1708     OS << " sizeof";
1709     break;
1710   case UETT_AlignOf:
1711     OS << " alignof";
1712     break;
1713   case UETT_VecStep:
1714     OS << " vec_step";
1715     break;
1716   }
1717   if (Node->isArgumentType())
1718     dumpType(Node->getArgumentType());
1719 }
1720
1721 void ASTDumper::VisitMemberExpr(const MemberExpr *Node) {
1722   VisitExpr(Node);
1723   OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
1724   dumpPointer(Node->getMemberDecl());
1725 }
1726
1727 void ASTDumper::VisitExtVectorElementExpr(const ExtVectorElementExpr *Node) {
1728   VisitExpr(Node);
1729   OS << " " << Node->getAccessor().getNameStart();
1730 }
1731
1732 void ASTDumper::VisitBinaryOperator(const BinaryOperator *Node) {
1733   VisitExpr(Node);
1734   OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1735 }
1736
1737 void ASTDumper::VisitCompoundAssignOperator(
1738     const CompoundAssignOperator *Node) {
1739   VisitExpr(Node);
1740   OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
1741      << "' ComputeLHSTy=";
1742   dumpBareType(Node->getComputationLHSType());
1743   OS << " ComputeResultTy=";
1744   dumpBareType(Node->getComputationResultType());
1745 }
1746
1747 void ASTDumper::VisitBlockExpr(const BlockExpr *Node) {
1748   VisitExpr(Node);
1749   dumpDecl(Node->getBlockDecl());
1750 }
1751
1752 void ASTDumper::VisitOpaqueValueExpr(const OpaqueValueExpr *Node) {
1753   VisitExpr(Node);
1754
1755   if (Expr *Source = Node->getSourceExpr()) {
1756     lastChild();
1757     dumpStmt(Source);
1758   }
1759 }
1760
1761 // GNU extensions.
1762
1763 void ASTDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
1764   VisitExpr(Node);
1765   OS << " " << Node->getLabel()->getName();
1766   dumpPointer(Node->getLabel());
1767 }
1768
1769 //===----------------------------------------------------------------------===//
1770 // C++ Expressions
1771 //===----------------------------------------------------------------------===//
1772
1773 void ASTDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) {
1774   VisitExpr(Node);
1775   OS << " " << Node->getCastName()
1776      << "<" << Node->getTypeAsWritten().getAsString() << ">"
1777      << " <" << Node->getCastKindName();
1778   dumpBasePath(OS, Node);
1779   OS << ">";
1780 }
1781
1782 void ASTDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
1783   VisitExpr(Node);
1784   OS << " " << (Node->getValue() ? "true" : "false");
1785 }
1786
1787 void ASTDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
1788   VisitExpr(Node);
1789   OS << " this";
1790 }
1791
1792 void ASTDumper::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node) {
1793   VisitExpr(Node);
1794   OS << " functional cast to " << Node->getTypeAsWritten().getAsString()
1795      << " <" << Node->getCastKindName() << ">";
1796 }
1797
1798 void ASTDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
1799   VisitExpr(Node);
1800   CXXConstructorDecl *Ctor = Node->getConstructor();
1801   dumpType(Ctor->getType());
1802   if (Node->isElidable())
1803     OS << " elidable";
1804   if (Node->requiresZeroInitialization())
1805     OS << " zeroing";
1806 }
1807
1808 void ASTDumper::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node) {
1809   VisitExpr(Node);
1810   OS << " ";
1811   dumpCXXTemporary(Node->getTemporary());
1812 }
1813
1814 void
1815 ASTDumper::VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node) {
1816   VisitExpr(Node);
1817   if (const ValueDecl *VD = Node->getExtendingDecl()) {
1818     OS << " extended by ";
1819     dumpBareDeclRef(VD);
1820   }
1821 }
1822
1823 void ASTDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
1824   VisitExpr(Node);
1825   for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
1826     dumpDeclRef(Node->getObject(i), "cleanup");
1827 }
1828
1829 void ASTDumper::dumpCXXTemporary(const CXXTemporary *Temporary) {
1830   OS << "(CXXTemporary";
1831   dumpPointer(Temporary);
1832   OS << ")";
1833 }
1834
1835 //===----------------------------------------------------------------------===//
1836 // Obj-C Expressions
1837 //===----------------------------------------------------------------------===//
1838
1839 void ASTDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
1840   VisitExpr(Node);
1841   OS << " selector=" << Node->getSelector().getAsString();
1842   switch (Node->getReceiverKind()) {
1843   case ObjCMessageExpr::Instance:
1844     break;
1845
1846   case ObjCMessageExpr::Class:
1847     OS << " class=";
1848     dumpBareType(Node->getClassReceiver());
1849     break;
1850
1851   case ObjCMessageExpr::SuperInstance:
1852     OS << " super (instance)";
1853     break;
1854
1855   case ObjCMessageExpr::SuperClass:
1856     OS << " super (class)";
1857     break;
1858   }
1859 }
1860
1861 void ASTDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
1862   VisitExpr(Node);
1863   OS << " selector=" << Node->getBoxingMethod()->getSelector().getAsString();
1864 }
1865
1866 void ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
1867   VisitStmt(Node);
1868   if (const VarDecl *CatchParam = Node->getCatchParamDecl())
1869     dumpDecl(CatchParam);
1870   else
1871     OS << " catch all";
1872 }
1873
1874 void ASTDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
1875   VisitExpr(Node);
1876   dumpType(Node->getEncodedType());
1877 }
1878
1879 void ASTDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
1880   VisitExpr(Node);
1881
1882   OS << " " << Node->getSelector().getAsString();
1883 }
1884
1885 void ASTDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
1886   VisitExpr(Node);
1887
1888   OS << ' ' << *Node->getProtocol();
1889 }
1890
1891 void ASTDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
1892   VisitExpr(Node);
1893   if (Node->isImplicitProperty()) {
1894     OS << " Kind=MethodRef Getter=\"";
1895     if (Node->getImplicitPropertyGetter())
1896       OS << Node->getImplicitPropertyGetter()->getSelector().getAsString();
1897     else
1898       OS << "(null)";
1899
1900     OS << "\" Setter=\"";
1901     if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
1902       OS << Setter->getSelector().getAsString();
1903     else
1904       OS << "(null)";
1905     OS << "\"";
1906   } else {
1907     OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty() <<'"';
1908   }
1909
1910   if (Node->isSuperReceiver())
1911     OS << " super";
1912
1913   OS << " Messaging=";
1914   if (Node->isMessagingGetter() && Node->isMessagingSetter())
1915     OS << "Getter&Setter";
1916   else if (Node->isMessagingGetter())
1917     OS << "Getter";
1918   else if (Node->isMessagingSetter())
1919     OS << "Setter";
1920 }
1921
1922 void ASTDumper::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node) {
1923   VisitExpr(Node);
1924   if (Node->isArraySubscriptRefExpr())
1925     OS << " Kind=ArraySubscript GetterForArray=\"";
1926   else
1927     OS << " Kind=DictionarySubscript GetterForDictionary=\"";
1928   if (Node->getAtIndexMethodDecl())
1929     OS << Node->getAtIndexMethodDecl()->getSelector().getAsString();
1930   else
1931     OS << "(null)";
1932
1933   if (Node->isArraySubscriptRefExpr())
1934     OS << "\" SetterForArray=\"";
1935   else
1936     OS << "\" SetterForDictionary=\"";
1937   if (Node->setAtIndexMethodDecl())
1938     OS << Node->setAtIndexMethodDecl()->getSelector().getAsString();
1939   else
1940     OS << "(null)";
1941 }
1942
1943 void ASTDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) {
1944   VisitExpr(Node);
1945   OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
1946 }
1947
1948 //===----------------------------------------------------------------------===//
1949 // Comments
1950 //===----------------------------------------------------------------------===//
1951
1952 const char *ASTDumper::getCommandName(unsigned CommandID) {
1953   if (Traits)
1954     return Traits->getCommandInfo(CommandID)->Name;
1955   const CommandInfo *Info = CommandTraits::getBuiltinCommandInfo(CommandID);
1956   if (Info)
1957     return Info->Name;
1958   return "<not a builtin command>";
1959 }
1960
1961 void ASTDumper::dumpFullComment(const FullComment *C) {
1962   if (!C)
1963     return;
1964
1965   FC = C;
1966   dumpComment(C);
1967   FC = 0;
1968 }
1969
1970 void ASTDumper::dumpComment(const Comment *C) {
1971   IndentScope Indent(*this);
1972
1973   if (!C) {
1974     ColorScope Color(*this, NullColor);
1975     OS << "<<<NULL>>>";
1976     return;
1977   }
1978
1979   {
1980     ColorScope Color(*this, CommentColor);
1981     OS << C->getCommentKindName();
1982   }
1983   dumpPointer(C);
1984   dumpSourceRange(C->getSourceRange());
1985   ConstCommentVisitor<ASTDumper>::visit(C);
1986   for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
1987        I != E; ++I) {
1988     if (I + 1 == E)
1989       lastChild();
1990     dumpComment(*I);
1991   }
1992 }
1993
1994 void ASTDumper::visitTextComment(const TextComment *C) {
1995   OS << " Text=\"" << C->getText() << "\"";
1996 }
1997
1998 void ASTDumper::visitInlineCommandComment(const InlineCommandComment *C) {
1999   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
2000   switch (C->getRenderKind()) {
2001   case InlineCommandComment::RenderNormal:
2002     OS << " RenderNormal";
2003     break;
2004   case InlineCommandComment::RenderBold:
2005     OS << " RenderBold";
2006     break;
2007   case InlineCommandComment::RenderMonospaced:
2008     OS << " RenderMonospaced";
2009     break;
2010   case InlineCommandComment::RenderEmphasized:
2011     OS << " RenderEmphasized";
2012     break;
2013   }
2014
2015   for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
2016     OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
2017 }
2018
2019 void ASTDumper::visitHTMLStartTagComment(const HTMLStartTagComment *C) {
2020   OS << " Name=\"" << C->getTagName() << "\"";
2021   if (C->getNumAttrs() != 0) {
2022     OS << " Attrs: ";
2023     for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
2024       const HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
2025       OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
2026     }
2027   }
2028   if (C->isSelfClosing())
2029     OS << " SelfClosing";
2030 }
2031
2032 void ASTDumper::visitHTMLEndTagComment(const HTMLEndTagComment *C) {
2033   OS << " Name=\"" << C->getTagName() << "\"";
2034 }
2035
2036 void ASTDumper::visitBlockCommandComment(const BlockCommandComment *C) {
2037   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
2038   for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
2039     OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
2040 }
2041
2042 void ASTDumper::visitParamCommandComment(const ParamCommandComment *C) {
2043   OS << " " << ParamCommandComment::getDirectionAsString(C->getDirection());
2044
2045   if (C->isDirectionExplicit())
2046     OS << " explicitly";
2047   else
2048     OS << " implicitly";
2049
2050   if (C->hasParamName()) {
2051     if (C->isParamIndexValid())
2052       OS << " Param=\"" << C->getParamName(FC) << "\"";
2053     else
2054       OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
2055   }
2056
2057   if (C->isParamIndexValid())
2058     OS << " ParamIndex=" << C->getParamIndex();
2059 }
2060
2061 void ASTDumper::visitTParamCommandComment(const TParamCommandComment *C) {
2062   if (C->hasParamName()) {
2063     if (C->isPositionValid())
2064       OS << " Param=\"" << C->getParamName(FC) << "\"";
2065     else
2066       OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
2067   }
2068
2069   if (C->isPositionValid()) {
2070     OS << " Position=<";
2071     for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
2072       OS << C->getIndex(i);
2073       if (i != e - 1)
2074         OS << ", ";
2075     }
2076     OS << ">";
2077   }
2078 }
2079
2080 void ASTDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) {
2081   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""
2082         " CloseName=\"" << C->getCloseName() << "\"";
2083 }
2084
2085 void ASTDumper::visitVerbatimBlockLineComment(
2086     const VerbatimBlockLineComment *C) {
2087   OS << " Text=\"" << C->getText() << "\"";
2088 }
2089
2090 void ASTDumper::visitVerbatimLineComment(const VerbatimLineComment *C) {
2091   OS << " Text=\"" << C->getText() << "\"";
2092 }
2093
2094 //===----------------------------------------------------------------------===//
2095 // Decl method implementations
2096 //===----------------------------------------------------------------------===//
2097
2098 void Decl::dump() const {
2099   dump(llvm::errs());
2100 }
2101
2102 void Decl::dump(raw_ostream &OS) const {
2103   ASTDumper P(OS, &getASTContext().getCommentCommandTraits(),
2104               &getASTContext().getSourceManager());
2105   P.dumpDecl(this);
2106 }
2107
2108 void Decl::dumpColor() const {
2109   ASTDumper P(llvm::errs(), &getASTContext().getCommentCommandTraits(),
2110               &getASTContext().getSourceManager(), /*ShowColors*/true);
2111   P.dumpDecl(this);
2112 }
2113
2114 void DeclContext::dumpLookups() const {
2115   dumpLookups(llvm::errs());
2116 }
2117
2118 void DeclContext::dumpLookups(raw_ostream &OS) const {
2119   const DeclContext *DC = this;
2120   while (!DC->isTranslationUnit())
2121     DC = DC->getParent();
2122   ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
2123   ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager());
2124   P.dumpLookups(this);
2125 }
2126
2127 //===----------------------------------------------------------------------===//
2128 // Stmt method implementations
2129 //===----------------------------------------------------------------------===//
2130
2131 void Stmt::dump(SourceManager &SM) const {
2132   dump(llvm::errs(), SM);
2133 }
2134
2135 void Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
2136   ASTDumper P(OS, 0, &SM);
2137   P.dumpStmt(this);
2138 }
2139
2140 void Stmt::dump() const {
2141   ASTDumper P(llvm::errs(), 0, 0);
2142   P.dumpStmt(this);
2143 }
2144
2145 void Stmt::dumpColor() const {
2146   ASTDumper P(llvm::errs(), 0, 0, /*ShowColors*/true);
2147   P.dumpStmt(this);
2148 }
2149
2150 //===----------------------------------------------------------------------===//
2151 // Comment method implementations
2152 //===----------------------------------------------------------------------===//
2153
2154 void Comment::dump() const {
2155   dump(llvm::errs(), 0, 0);
2156 }
2157
2158 void Comment::dump(const ASTContext &Context) const {
2159   dump(llvm::errs(), &Context.getCommentCommandTraits(),
2160        &Context.getSourceManager());
2161 }
2162
2163 void Comment::dump(raw_ostream &OS, const CommandTraits *Traits,
2164                    const SourceManager *SM) const {
2165   const FullComment *FC = dyn_cast<FullComment>(this);
2166   ASTDumper D(OS, Traits, SM);
2167   D.dumpFullComment(FC);
2168 }
2169
2170 void Comment::dumpColor() const {
2171   const FullComment *FC = dyn_cast<FullComment>(this);
2172   ASTDumper D(llvm::errs(), 0, 0, /*ShowColors*/true);
2173   D.dumpFullComment(FC);
2174 }