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