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