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