//===--- ASTDumper.cpp - Dumping implementation for ASTs ------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the AST dump methods, which dump out the
// AST in a form that exposes type details and other fields.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
#include "clang/AST/CommentVisitor.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclLookups.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
using namespace clang::comments;

//===----------------------------------------------------------------------===//
// ASTDumper Visitor
//===----------------------------------------------------------------------===//

namespace  {
  // Colors used for various parts of the AST dump

  struct TerminalColor {
    raw_ostream::Colors Color;
    bool Bold;
  };

  // Decl kind names (VarDecl, FunctionDecl, etc)
  static const TerminalColor DeclKindNameColor = { raw_ostream::GREEN, true };
  // Attr names (CleanupAttr, GuardedByAttr, etc)
  static const TerminalColor AttrColor = { raw_ostream::BLUE, true };
  // Statement names (DeclStmt, ImplicitCastExpr, etc)
  static const TerminalColor StmtColor = { raw_ostream::MAGENTA, true };
  // Comment names (FullComment, ParagraphComment, TextComment, etc)
  static const TerminalColor CommentColor = { raw_ostream::YELLOW, true };

  // Type names (int, float, etc, plus user defined types)
  static const TerminalColor TypeColor = { raw_ostream::GREEN, false };

  // Pointer address
  static const TerminalColor AddressColor = { raw_ostream::YELLOW, false };
  // Source locations
  static const TerminalColor LocationColor = { raw_ostream::YELLOW, false };

  // lvalue/xvalue
  static const TerminalColor ValueKindColor = { raw_ostream::CYAN, false };
  // bitfield/objcproperty/objcsubscript/vectorcomponent
  static const TerminalColor ObjectKindColor = { raw_ostream::CYAN, false };

  // Null statements
  static const TerminalColor NullColor = { raw_ostream::BLUE, false };

  // Undeserialized entities
  static const TerminalColor UndeserializedColor = { raw_ostream::GREEN, true };

  // CastKind from CastExpr's
  static const TerminalColor CastColor = { raw_ostream::RED, false };

  // Value of the statement
  static const TerminalColor ValueColor = { raw_ostream::CYAN, true };
  // Decl names
  static const TerminalColor DeclNameColor = { raw_ostream::CYAN, true };

  // Indents ( `, -. | )
  static const TerminalColor IndentColor = { raw_ostream::BLUE, false };

  class ASTDumper
      : public ConstDeclVisitor<ASTDumper>, public ConstStmtVisitor<ASTDumper>,
        public ConstCommentVisitor<ASTDumper> {
    raw_ostream &OS;
    const CommandTraits *Traits;
    const SourceManager *SM;
    bool IsFirstLine;

    // Indicates whether more child are expected at the current tree depth
    enum IndentType { IT_Child, IT_LastChild };

    /// Indents[i] indicates if another child exists at level i.
    /// Used by Indent() to print the tree structure. 
    llvm::SmallVector<IndentType, 32> Indents;

    /// Indicates that more children will be needed at this indent level.
    /// If true, prevents lastChild() from marking the node as the last child.
    /// This is used when there are multiple collections of children to be
    /// dumped as well as during conditional node dumping.
    bool MoreChildren;

    /// Keep track of the last location we print out so that we can
    /// print out deltas from then on out.
    const char *LastLocFilename;
    unsigned LastLocLine;

    /// The \c FullComment parent of the comment being dumped.
    const FullComment *FC;

    bool ShowColors;

    class IndentScope {
      ASTDumper &Dumper;
      // Preserve the Dumper's MoreChildren value from the previous IndentScope
      bool MoreChildren;
    public:
      IndentScope(ASTDumper &Dumper) : Dumper(Dumper) {
        MoreChildren = Dumper.hasMoreChildren();
        Dumper.setMoreChildren(false);
        Dumper.indent();
      }
      ~IndentScope() {
        Dumper.setMoreChildren(MoreChildren);
        Dumper.unindent();
      }
    };

    class ColorScope {
      ASTDumper &Dumper;
    public:
      ColorScope(ASTDumper &Dumper, TerminalColor Color)
        : Dumper(Dumper) {
        if (Dumper.ShowColors)
          Dumper.OS.changeColor(Color.Color, Color.Bold);
      }
      ~ColorScope() {
        if (Dumper.ShowColors)
          Dumper.OS.resetColor();
      }
    };

  public:
    ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
              const SourceManager *SM)
      : OS(OS), Traits(Traits), SM(SM), IsFirstLine(true), MoreChildren(false),
        LastLocFilename(""), LastLocLine(~0U), FC(0),
        ShowColors(SM && SM->getDiagnostics().getShowColors()) { }

    ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
              const SourceManager *SM, bool ShowColors)
      : OS(OS), Traits(Traits), SM(SM), IsFirstLine(true), MoreChildren(false),
        LastLocFilename(""), LastLocLine(~0U),
        ShowColors(ShowColors) { }

    ~ASTDumper() {
      OS << "\n";
    }

    void dumpDecl(const Decl *D);
    void dumpStmt(const Stmt *S);
    void dumpFullComment(const FullComment *C);

    // Formatting
    void indent();
    void unindent();
    void lastChild();
    bool hasMoreChildren();
    void setMoreChildren(bool Value);

    // Utilities
    void dumpPointer(const void *Ptr);
    void dumpSourceRange(SourceRange R);
    void dumpLocation(SourceLocation Loc);
    void dumpBareType(QualType T);
    void dumpType(QualType T);
    void dumpBareDeclRef(const Decl *Node);
    void dumpDeclRef(const Decl *Node, const char *Label = 0);
    void dumpName(const NamedDecl *D);
    bool hasNodes(const DeclContext *DC);
    void dumpDeclContext(const DeclContext *DC);
    void dumpLookups(const DeclContext *DC);
    void dumpAttr(const Attr *A);

    // C++ Utilities
    void dumpAccessSpecifier(AccessSpecifier AS);
    void dumpCXXCtorInitializer(const CXXCtorInitializer *Init);
    void dumpTemplateParameters(const TemplateParameterList *TPL);
    void dumpTemplateArgumentListInfo(const TemplateArgumentListInfo &TALI);
    void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A);
    void dumpTemplateArgumentList(const TemplateArgumentList &TAL);
    void dumpTemplateArgument(const TemplateArgument &A,
                              SourceRange R = SourceRange());

    // Decls
    void VisitLabelDecl(const LabelDecl *D);
    void VisitTypedefDecl(const TypedefDecl *D);
    void VisitEnumDecl(const EnumDecl *D);
    void VisitRecordDecl(const RecordDecl *D);
    void VisitEnumConstantDecl(const EnumConstantDecl *D);
    void VisitIndirectFieldDecl(const IndirectFieldDecl *D);
    void VisitFunctionDecl(const FunctionDecl *D);
    void VisitFieldDecl(const FieldDecl *D);
    void VisitVarDecl(const VarDecl *D);
    void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D);
    void VisitImportDecl(const ImportDecl *D);

    // C++ Decls
    void VisitNamespaceDecl(const NamespaceDecl *D);
    void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D);
    void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D);
    void VisitTypeAliasDecl(const TypeAliasDecl *D);
    void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D);
    void VisitCXXRecordDecl(const CXXRecordDecl *D);
    void VisitStaticAssertDecl(const StaticAssertDecl *D);
    void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
    void VisitClassTemplateDecl(const ClassTemplateDecl *D);
    void VisitClassTemplateSpecializationDecl(
        const ClassTemplateSpecializationDecl *D);
    void VisitClassTemplatePartialSpecializationDecl(
        const ClassTemplatePartialSpecializationDecl *D);
    void VisitClassScopeFunctionSpecializationDecl(
        const ClassScopeFunctionSpecializationDecl *D);
    void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
    void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
    void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
    void VisitUsingDecl(const UsingDecl *D);
    void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D);
    void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D);
    void VisitUsingShadowDecl(const UsingShadowDecl *D);
    void VisitLinkageSpecDecl(const LinkageSpecDecl *D);
    void VisitAccessSpecDecl(const AccessSpecDecl *D);
    void VisitFriendDecl(const FriendDecl *D);

    // ObjC Decls
    void VisitObjCIvarDecl(const ObjCIvarDecl *D);
    void VisitObjCMethodDecl(const ObjCMethodDecl *D);
    void VisitObjCCategoryDecl(const ObjCCategoryDecl *D);
    void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D);
    void VisitObjCProtocolDecl(const ObjCProtocolDecl *D);
    void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D);
    void VisitObjCImplementationDecl(const ObjCImplementationDecl *D);
    void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D);
    void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
    void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
    void VisitBlockDecl(const BlockDecl *D);

    // Stmts.
    void VisitStmt(const Stmt *Node);
    void VisitDeclStmt(const DeclStmt *Node);
    void VisitAttributedStmt(const AttributedStmt *Node);
    void VisitLabelStmt(const LabelStmt *Node);
    void VisitGotoStmt(const GotoStmt *Node);

    // Exprs
    void VisitExpr(const Expr *Node);
    void VisitCastExpr(const CastExpr *Node);
    void VisitDeclRefExpr(const DeclRefExpr *Node);
    void VisitPredefinedExpr(const PredefinedExpr *Node);
    void VisitCharacterLiteral(const CharacterLiteral *Node);
    void VisitIntegerLiteral(const IntegerLiteral *Node);
    void VisitFloatingLiteral(const FloatingLiteral *Node);
    void VisitStringLiteral(const StringLiteral *Str);
    void VisitUnaryOperator(const UnaryOperator *Node);
    void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node);
    void VisitMemberExpr(const MemberExpr *Node);
    void VisitExtVectorElementExpr(const ExtVectorElementExpr *Node);
    void VisitBinaryOperator(const BinaryOperator *Node);
    void VisitCompoundAssignOperator(const CompoundAssignOperator *Node);
    void VisitAddrLabelExpr(const AddrLabelExpr *Node);
    void VisitBlockExpr(const BlockExpr *Node);
    void VisitOpaqueValueExpr(const OpaqueValueExpr *Node);

    // C++
    void VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node);
    void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node);
    void VisitCXXThisExpr(const CXXThisExpr *Node);
    void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node);
    void VisitCXXConstructExpr(const CXXConstructExpr *Node);
    void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node);
    void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node);
    void VisitExprWithCleanups(const ExprWithCleanups *Node);
    void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node);
    void dumpCXXTemporary(const CXXTemporary *Temporary);

    // ObjC
    void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node);
    void VisitObjCEncodeExpr(const ObjCEncodeExpr *Node);
    void VisitObjCMessageExpr(const ObjCMessageExpr *Node);
    void VisitObjCBoxedExpr(const ObjCBoxedExpr *Node);
    void VisitObjCSelectorExpr(const ObjCSelectorExpr *Node);
    void VisitObjCProtocolExpr(const ObjCProtocolExpr *Node);
    void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node);
    void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node);
    void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node);
    void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node);

    // Comments.
    const char *getCommandName(unsigned CommandID);
    void dumpComment(const Comment *C);

    // Inline comments.
    void visitTextComment(const TextComment *C);
    void visitInlineCommandComment(const InlineCommandComment *C);
    void visitHTMLStartTagComment(const HTMLStartTagComment *C);
    void visitHTMLEndTagComment(const HTMLEndTagComment *C);

    // Block comments.
    void visitBlockCommandComment(const BlockCommandComment *C);
    void visitParamCommandComment(const ParamCommandComment *C);
    void visitTParamCommandComment(const TParamCommandComment *C);
    void visitVerbatimBlockComment(const VerbatimBlockComment *C);
    void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
    void visitVerbatimLineComment(const VerbatimLineComment *C);
  };
}

//===----------------------------------------------------------------------===//
//  Utilities
//===----------------------------------------------------------------------===//

// Print out the appropriate tree structure using the Indents vector.
// Example of tree and the Indents vector at each level.
// A        { }
// |-B      { IT_Child }
// | `-C    { IT_Child,     IT_LastChild }
// `-D      { IT_LastChild }
//   |-E    { IT_LastChild, IT_Child }
//   `-F    { IT_LastChild, IT_LastChild }
// Type            non-last element, last element
// IT_Child        "| "              "|-"
// IT_LastChild    "  "              "`-"
void ASTDumper::indent() {
  if (IsFirstLine)
    IsFirstLine = false;
  else
    OS << "\n";

  ColorScope Color(*this, IndentColor);
  for (SmallVectorImpl<IndentType>::const_iterator I = Indents.begin(),
                                                   E = Indents.end();
       I != E; ++I) {
    switch (*I) {
    case IT_Child:
      if (I == E - 1)
        OS << "|-";
      else
        OS << "| ";
      continue;
    case IT_LastChild:
      if (I == E - 1)
        OS << "`-";
      else
        OS << "  ";
      continue;
    }
    llvm_unreachable("Invalid IndentType");
  }
  Indents.push_back(IT_Child);
}

void ASTDumper::unindent() {
  Indents.pop_back();
}

// Call before each potential last child node is to be dumped.  If MoreChildren
// is false, then this is the last child, otherwise treat as a regular node.
void ASTDumper::lastChild() {
  if (!hasMoreChildren())
    Indents.back() = IT_LastChild;
}

// MoreChildren should be set before calling another function that may print
// additional nodes to prevent conflicting final child nodes.
bool ASTDumper::hasMoreChildren() {
  return MoreChildren;
}

void ASTDumper::setMoreChildren(bool Value) {
  MoreChildren = Value;
}

void ASTDumper::dumpPointer(const void *Ptr) {
  ColorScope Color(*this, AddressColor);
  OS << ' ' << Ptr;
}

void ASTDumper::dumpLocation(SourceLocation Loc) {
  ColorScope Color(*this, LocationColor);
  SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);

  // The general format we print out is filename:line:col, but we drop pieces
  // that haven't changed since the last loc printed.
  PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);

  if (PLoc.isInvalid()) {
    OS << "<invalid sloc>";
    return;
  }

  if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
    OS << PLoc.getFilename() << ':' << PLoc.getLine()
       << ':' << PLoc.getColumn();
    LastLocFilename = PLoc.getFilename();
    LastLocLine = PLoc.getLine();
  } else if (PLoc.getLine() != LastLocLine) {
    OS << "line" << ':' << PLoc.getLine()
       << ':' << PLoc.getColumn();
    LastLocLine = PLoc.getLine();
  } else {
    OS << "col" << ':' << PLoc.getColumn();
  }
}

void ASTDumper::dumpSourceRange(SourceRange R) {
  // Can't translate locations if a SourceManager isn't available.
  if (!SM)
    return;

  OS << " <";
  dumpLocation(R.getBegin());
  if (R.getBegin() != R.getEnd()) {
    OS << ", ";
    dumpLocation(R.getEnd());
  }
  OS << ">";

  // <t2.c:123:421[blah], t2.c:412:321>

}

void ASTDumper::dumpBareType(QualType T) {
  ColorScope Color(*this, TypeColor);
  
  SplitQualType T_split = T.split();
  OS << "'" << QualType::getAsString(T_split) << "'";

  if (!T.isNull()) {
    // If the type is sugared, also dump a (shallow) desugared type.
    SplitQualType D_split = T.getSplitDesugaredType();
    if (T_split != D_split)
      OS << ":'" << QualType::getAsString(D_split) << "'";
  }
}

void ASTDumper::dumpType(QualType T) {
  OS << ' ';
  dumpBareType(T);
}

void ASTDumper::dumpBareDeclRef(const Decl *D) {
  {
    ColorScope Color(*this, DeclKindNameColor);
    OS << D->getDeclKindName();
  }
  dumpPointer(D);

  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
    ColorScope Color(*this, DeclNameColor);
    OS << " '" << ND->getDeclName() << '\'';
  }

  if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
    dumpType(VD->getType());
}

void ASTDumper::dumpDeclRef(const Decl *D, const char *Label) {
  if (!D)
    return;

  IndentScope Indent(*this);
  if (Label)
    OS << Label << ' ';
  dumpBareDeclRef(D);
}

void ASTDumper::dumpName(const NamedDecl *ND) {
  if (ND->getDeclName()) {
    ColorScope Color(*this, DeclNameColor);
    OS << ' ' << ND->getNameAsString();
  }
}

bool ASTDumper::hasNodes(const DeclContext *DC) {
  if (!DC)
    return false;

  return DC->hasExternalLexicalStorage() ||
         DC->noload_decls_begin() != DC->noload_decls_end();
}

void ASTDumper::dumpDeclContext(const DeclContext *DC) {
  if (!DC)
    return;
  bool HasUndeserializedDecls = DC->hasExternalLexicalStorage();
  for (DeclContext::decl_iterator I = DC->noload_decls_begin(), E = DC->noload_decls_end();
       I != E; ++I) {
    DeclContext::decl_iterator Next = I;
    ++Next;
    if (Next == E && !HasUndeserializedDecls)
      lastChild();
    dumpDecl(*I);
  }
  if (HasUndeserializedDecls) {
    lastChild();
    IndentScope Indent(*this);
    ColorScope Color(*this, UndeserializedColor);
    OS << "<undeserialized declarations>";
  }
}

void ASTDumper::dumpLookups(const DeclContext *DC) {
  IndentScope Indent(*this);

  OS << "StoredDeclsMap ";
  dumpBareDeclRef(cast<Decl>(DC));

  const DeclContext *Primary = DC->getPrimaryContext();
  if (Primary != DC) {
    OS << " primary";
    dumpPointer(cast<Decl>(Primary));
  }

  bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage();

  DeclContext::all_lookups_iterator I = Primary->noload_lookups_begin(),
                                    E = Primary->noload_lookups_end();
  while (I != E) {
    DeclarationName Name = I.getLookupName();
    DeclContextLookupResult R = *I++;
    if (I == E && !HasUndeserializedLookups)
      lastChild();

    IndentScope Indent(*this);
    OS << "DeclarationName ";
    {
      ColorScope Color(*this, DeclNameColor);
      OS << '\'' << Name << '\'';
    }

    for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end();
         RI != RE; ++RI) {
      if (RI + 1 == RE)
        lastChild();
      dumpDeclRef(*RI);
    }
  }

  if (HasUndeserializedLookups) {
    lastChild();
    IndentScope Indent(*this);
    ColorScope Color(*this, UndeserializedColor);
    OS << "<undeserialized lookups>";
  }
}

void ASTDumper::dumpAttr(const Attr *A) {
  IndentScope Indent(*this);
  {
    ColorScope Color(*this, AttrColor);
    switch (A->getKind()) {
#define ATTR(X) case attr::X: OS << #X; break;
#include "clang/Basic/AttrList.inc"
    default: llvm_unreachable("unexpected attribute kind");
    }
    OS << "Attr";
  }
  dumpPointer(A);
  dumpSourceRange(A->getRange());
#include "clang/AST/AttrDump.inc"
}

static Decl *getPreviousDeclImpl(...) {
  return 0;
}

template<typename T>
static const Decl *getPreviousDeclImpl(const Redeclarable<T> *D) {
  return D->getPreviousDecl();
}

/// Get the previous declaration in the redeclaration chain for a declaration.
static const Decl *getPreviousDecl(const Decl *D) {
  switch (D->getKind()) {
#define DECL(DERIVED, BASE) \
  case Decl::DERIVED: \
    return getPreviousDeclImpl(cast<DERIVED##Decl>(D));
#define ABSTRACT_DECL(DECL)
#include "clang/AST/DeclNodes.inc"
  }
  llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
}

//===----------------------------------------------------------------------===//
//  C++ Utilities
//===----------------------------------------------------------------------===//

void ASTDumper::dumpAccessSpecifier(AccessSpecifier AS) {
  switch (AS) {
  case AS_none:
    break;
  case AS_public:
    OS << "public";
    break;
  case AS_protected:
    OS << "protected";
    break;
  case AS_private:
    OS << "private";
    break;
  }
}

void ASTDumper::dumpCXXCtorInitializer(const CXXCtorInitializer *Init) {
  IndentScope Indent(*this);
  OS << "CXXCtorInitializer";
  if (Init->isAnyMemberInitializer()) {
    OS << ' ';
    dumpBareDeclRef(Init->getAnyMember());
  } else {
    dumpType(QualType(Init->getBaseClass(), 0));
  }
  dumpStmt(Init->getInit());
}

void ASTDumper::dumpTemplateParameters(const TemplateParameterList *TPL) {
  if (!TPL)
    return;

  for (TemplateParameterList::const_iterator I = TPL->begin(), E = TPL->end();
       I != E; ++I)
    dumpDecl(*I);
}

void ASTDumper::dumpTemplateArgumentListInfo(
    const TemplateArgumentListInfo &TALI) {
  for (unsigned i = 0, e = TALI.size(); i < e; ++i) {
    if (i + 1 == e)
      lastChild();
    dumpTemplateArgumentLoc(TALI[i]);
  }
}

void ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A) {
  dumpTemplateArgument(A.getArgument(), A.getSourceRange());
}

void ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) {
  for (unsigned i = 0, e = TAL.size(); i < e; ++i)
    dumpTemplateArgument(TAL[i]);
}

void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R) {
  IndentScope Indent(*this);
  OS << "TemplateArgument";
  if (R.isValid())
    dumpSourceRange(R);

  switch (A.getKind()) {
  case TemplateArgument::Null:
    OS << " null";
    break;
  case TemplateArgument::Type:
    OS << " type";
    lastChild();
    dumpType(A.getAsType());
    break;
  case TemplateArgument::Declaration:
    OS << " decl";
    lastChild();
    dumpDeclRef(A.getAsDecl());
    break;
  case TemplateArgument::NullPtr:
    OS << " nullptr";
    break;
  case TemplateArgument::Integral:
    OS << " integral " << A.getAsIntegral();
    break;
  case TemplateArgument::Template:
    OS << " template ";
    A.getAsTemplate().dump(OS);
    break;
  case TemplateArgument::TemplateExpansion:
    OS << " template expansion";
    A.getAsTemplateOrTemplatePattern().dump(OS);
    break;
  case TemplateArgument::Expression:
    OS << " expr";
    lastChild();
    dumpStmt(A.getAsExpr());
    break;
  case TemplateArgument::Pack:
    OS << " pack";
    for (TemplateArgument::pack_iterator I = A.pack_begin(), E = A.pack_end();
         I != E; ++I) {
      if (I + 1 == E)
        lastChild();
      dumpTemplateArgument(*I);
    }
    break;
  }
}

//===----------------------------------------------------------------------===//
//  Decl dumping methods.
//===----------------------------------------------------------------------===//

void ASTDumper::dumpDecl(const Decl *D) {
  IndentScope Indent(*this);

  if (!D) {
    ColorScope Color(*this, NullColor);
    OS << "<<<NULL>>>";
    return;
  }

  {
    ColorScope Color(*this, DeclKindNameColor);
    OS << D->getDeclKindName() << "Decl";
  }
  dumpPointer(D);
  if (D->getLexicalDeclContext() != D->getDeclContext())
    OS << " parent " << cast<Decl>(D->getDeclContext());
  if (const Decl *Prev = getPreviousDecl(D))
    OS << " prev " << Prev;
  dumpSourceRange(D->getSourceRange());

  bool HasAttrs = D->attr_begin() != D->attr_end();
  const FullComment *Comment =
      D->getASTContext().getLocalCommentForDeclUncached(D);
  // Decls within functions are visited by the body
  bool HasDeclContext = !isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D) &&
                         hasNodes(dyn_cast<DeclContext>(D));

  setMoreChildren(HasAttrs || Comment || HasDeclContext);
  ConstDeclVisitor<ASTDumper>::Visit(D);

  setMoreChildren(Comment || HasDeclContext);
  for (Decl::attr_iterator I = D->attr_begin(), E = D->attr_end();
       I != E; ++I) {
    if (I + 1 == E)
      lastChild();
    dumpAttr(*I);
  }

  setMoreChildren(HasDeclContext);
  lastChild();
  dumpFullComment(Comment);

  if (D->isInvalidDecl())
    OS << " invalid";

  setMoreChildren(false);
  if (HasDeclContext)
    dumpDeclContext(cast<DeclContext>(D));
}

void ASTDumper::VisitLabelDecl(const LabelDecl *D) {
  dumpName(D);
}

void ASTDumper::VisitTypedefDecl(const TypedefDecl *D) {
  dumpName(D);
  dumpType(D->getUnderlyingType());
  if (D->isModulePrivate())
    OS << " __module_private__";
}

void ASTDumper::VisitEnumDecl(const EnumDecl *D) {
  if (D->isScoped()) {
    if (D->isScopedUsingClassTag())
      OS << " class";
    else
      OS << " struct";
  }
  dumpName(D);
  if (D->isModulePrivate())
    OS << " __module_private__";
  if (D->isFixed())
    dumpType(D->getIntegerType());
}

void ASTDumper::VisitRecordDecl(const RecordDecl *D) {
  OS << ' ' << D->getKindName();
  dumpName(D);
  if (D->isModulePrivate())
    OS << " __module_private__";
}

void ASTDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
  dumpName(D);
  dumpType(D->getType());
  if (const Expr *Init = D->getInitExpr()) {
    lastChild();
    dumpStmt(Init);
  }
}

void ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
  dumpName(D);
  dumpType(D->getType());
  for (IndirectFieldDecl::chain_iterator I = D->chain_begin(),
                                         E = D->chain_end();
       I != E; ++I) {
    if (I + 1 == E)
      lastChild();
    dumpDeclRef(*I);
  }
}

void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) {
  dumpName(D);
  dumpType(D->getType());

  StorageClass SC = D->getStorageClass();
  if (SC != SC_None)
    OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
  if (D->isInlineSpecified())
    OS << " inline";
  if (D->isVirtualAsWritten())
    OS << " virtual";
  if (D->isModulePrivate())
    OS << " __module_private__";

  if (D->isPure())
    OS << " pure";
  else if (D->isDeletedAsWritten())
    OS << " delete";

  if (const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>()) {
    FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
    switch (EPI.ExceptionSpecType) {
    default: break;
    case EST_Unevaluated:
      OS << " noexcept-unevaluated " << EPI.ExceptionSpecDecl;
      break;
    case EST_Uninstantiated:
      OS << " noexcept-uninstantiated " << EPI.ExceptionSpecTemplate;
      break;
    }
  }

  bool OldMoreChildren = hasMoreChildren();
  const FunctionTemplateSpecializationInfo *FTSI =
      D->getTemplateSpecializationInfo();
  bool HasTemplateSpecialization = FTSI;

  bool HasNamedDecls = D->getDeclsInPrototypeScope().begin() !=
                       D->getDeclsInPrototypeScope().end();

  bool HasFunctionDecls = D->param_begin() != D->param_end();

  const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(D);
  bool HasCtorInitializers = C && C->init_begin() != C->init_end();

  bool HasDeclarationBody = D->doesThisDeclarationHaveABody();

  setMoreChildren(OldMoreChildren || HasNamedDecls || HasFunctionDecls ||
                  HasCtorInitializers || HasDeclarationBody);
  if (HasTemplateSpecialization) {
    lastChild();
    dumpTemplateArgumentList(*FTSI->TemplateArguments);
  }

  setMoreChildren(OldMoreChildren || HasFunctionDecls ||
                  HasCtorInitializers || HasDeclarationBody);
  for (ArrayRef<NamedDecl *>::iterator
       I = D->getDeclsInPrototypeScope().begin(),
       E = D->getDeclsInPrototypeScope().end(); I != E; ++I) {
    if (I + 1 == E)
      lastChild();
    dumpDecl(*I);
  }

  setMoreChildren(OldMoreChildren || HasCtorInitializers || HasDeclarationBody);
  for (FunctionDecl::param_const_iterator I = D->param_begin(),
                                          E = D->param_end();
       I != E; ++I) {
    if (I + 1 == E)
      lastChild();
    dumpDecl(*I);
  }
 
  setMoreChildren(OldMoreChildren || HasDeclarationBody);
  if (HasCtorInitializers)
    for (CXXConstructorDecl::init_const_iterator I = C->init_begin(),
                                                 E = C->init_end();
         I != E; ++I) {
      if (I + 1 == E)
        lastChild();
      dumpCXXCtorInitializer(*I);
  }

  setMoreChildren(OldMoreChildren);
  if (HasDeclarationBody) {
    lastChild();
    dumpStmt(D->getBody());
  }
}

void ASTDumper::VisitFieldDecl(const FieldDecl *D) {
  dumpName(D);
  dumpType(D->getType());
  if (D->isMutable())
    OS << " mutable";
  if (D->isModulePrivate())
    OS << " __module_private__";

  bool OldMoreChildren = hasMoreChildren();
  bool IsBitField = D->isBitField();
  Expr *Init = D->getInClassInitializer();
  bool HasInit = Init;

  setMoreChildren(OldMoreChildren || HasInit);
  if (IsBitField) {
    lastChild();
    dumpStmt(D->getBitWidth());
  }
  setMoreChildren(OldMoreChildren);
  if (HasInit) {
    lastChild();
    dumpStmt(Init);
  }
}

void ASTDumper::VisitVarDecl(const VarDecl *D) {
  dumpName(D);
  dumpType(D->getType());
  StorageClass SC = D->getStorageClass();
  if (SC != SC_None)
    OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
  switch (D->getTLSKind()) {
  case VarDecl::TLS_None: break;
  case VarDecl::TLS_Static: OS << " tls"; break;
  case VarDecl::TLS_Dynamic: OS << " tls_dynamic"; break;
  }
  if (D->isModulePrivate())
    OS << " __module_private__";
  if (D->isNRVOVariable())
    OS << " nrvo";
  if (D->hasInit()) {
    lastChild();
    dumpStmt(D->getInit());
  }
}

void ASTDumper::VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) {
  lastChild();
  dumpStmt(D->getAsmString());
}

void ASTDumper::VisitImportDecl(const ImportDecl *D) {
  OS << ' ' << D->getImportedModule()->getFullModuleName();
}

//===----------------------------------------------------------------------===//
// C++ Declarations
//===----------------------------------------------------------------------===//

void ASTDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
  dumpName(D);
  if (D->isInline())
    OS << " inline";
  if (!D->isOriginalNamespace())
    dumpDeclRef(D->getOriginalNamespace(), "original");
}

void ASTDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
  OS << ' ';
  dumpBareDeclRef(D->getNominatedNamespace());
}

void ASTDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
  dumpName(D);
  dumpDeclRef(D->getAliasedNamespace());
}

void ASTDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
  dumpName(D);
  dumpType(D->getUnderlyingType());
}

void ASTDumper::VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {
  dumpName(D);
  dumpTemplateParameters(D->getTemplateParameters());
  dumpDecl(D->getTemplatedDecl());
}

void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
  VisitRecordDecl(D);
  if (!D->isCompleteDefinition())
    return;

  for (CXXRecordDecl::base_class_const_iterator I = D->bases_begin(),
                                                E = D->bases_end();
       I != E; ++I) {
    IndentScope Indent(*this);
    if (I->isVirtual())
      OS << "virtual ";
    dumpAccessSpecifier(I->getAccessSpecifier());
    dumpType(I->getType());
    if (I->isPackExpansion())
      OS << "...";
  }
}

void ASTDumper::VisitStaticAssertDecl(const StaticAssertDecl *D) {
  dumpStmt(D->getAssertExpr());
  lastChild();
  dumpStmt(D->getMessage());
}

void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
  dumpName(D);
  dumpTemplateParameters(D->getTemplateParameters());
  dumpDecl(D->getTemplatedDecl());
  for (FunctionTemplateDecl::spec_iterator I = D->spec_begin(),
                                           E = D->spec_end();
       I != E; ++I) {
    FunctionTemplateDecl::spec_iterator Next = I;
    ++Next;
    if (Next == E)
      lastChild();
    switch (I->getTemplateSpecializationKind()) {
    case TSK_Undeclared:
    case TSK_ImplicitInstantiation:
    case TSK_ExplicitInstantiationDeclaration:
    case TSK_ExplicitInstantiationDefinition:
      if (D == D->getCanonicalDecl())
        dumpDecl(*I);
      else
        dumpDeclRef(*I);
      break;
    case TSK_ExplicitSpecialization:
      dumpDeclRef(*I);
      break;
    }
  }
}

void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
  dumpName(D);
  dumpTemplateParameters(D->getTemplateParameters());

  ClassTemplateDecl::spec_iterator I = D->spec_begin();
  ClassTemplateDecl::spec_iterator E = D->spec_end();
  if (I == E)
    lastChild();
  dumpDecl(D->getTemplatedDecl());
  for (; I != E; ++I) {
    ClassTemplateDecl::spec_iterator Next = I;
    ++Next;
    if (Next == E)
      lastChild();
    switch (I->getTemplateSpecializationKind()) {
    case TSK_Undeclared:
    case TSK_ImplicitInstantiation:
      if (D == D->getCanonicalDecl())
        dumpDecl(*I);
      else
        dumpDeclRef(*I);
      break;
    case TSK_ExplicitSpecialization:
    case TSK_ExplicitInstantiationDeclaration:
    case TSK_ExplicitInstantiationDefinition:
      dumpDeclRef(*I);
      break;
    }
  }
}

void ASTDumper::VisitClassTemplateSpecializationDecl(
    const ClassTemplateSpecializationDecl *D) {
  VisitCXXRecordDecl(D);
  dumpTemplateArgumentList(D->getTemplateArgs());
}

void ASTDumper::VisitClassTemplatePartialSpecializationDecl(
    const ClassTemplatePartialSpecializationDecl *D) {
  VisitClassTemplateSpecializationDecl(D);
  dumpTemplateParameters(D->getTemplateParameters());
}

void ASTDumper::VisitClassScopeFunctionSpecializationDecl(
    const ClassScopeFunctionSpecializationDecl *D) {
  dumpDeclRef(D->getSpecialization());
  if (D->hasExplicitTemplateArgs())
    dumpTemplateArgumentListInfo(D->templateArgs());
}

void ASTDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
  if (D->wasDeclaredWithTypename())
    OS << " typename";
  else
    OS << " class";
  if (D->isParameterPack())
    OS << " ...";
  dumpName(D);
  if (D->hasDefaultArgument())
    dumpType(D->getDefaultArgument());
}

void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
  dumpType(D->getType());
  if (D->isParameterPack())
    OS << " ...";
  dumpName(D);
  if (D->hasDefaultArgument())
    dumpStmt(D->getDefaultArgument());
}

void ASTDumper::VisitTemplateTemplateParmDecl(
    const TemplateTemplateParmDecl *D) {
  if (D->isParameterPack())
    OS << " ...";
  dumpName(D);
  dumpTemplateParameters(D->getTemplateParameters());
  if (D->hasDefaultArgument())
    dumpTemplateArgumentLoc(D->getDefaultArgument());
}

void ASTDumper::VisitUsingDecl(const UsingDecl *D) {
  OS << ' ';
  D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
  OS << D->getNameAsString();
}

void ASTDumper::VisitUnresolvedUsingTypenameDecl(
    const UnresolvedUsingTypenameDecl *D) {
  OS << ' ';
  D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
  OS << D->getNameAsString();
}

void ASTDumper::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
  OS << ' ';
  D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
  OS << D->getNameAsString();
  dumpType(D->getType());
}

void ASTDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
  OS << ' ';
  dumpBareDeclRef(D->getTargetDecl());
}

void ASTDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
  switch (D->getLanguage()) {
  case LinkageSpecDecl::lang_c: OS << " C"; break;
  case LinkageSpecDecl::lang_cxx: OS << " C++"; break;
  }
}

void ASTDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
  OS << ' ';
  dumpAccessSpecifier(D->getAccess());
}

void ASTDumper::VisitFriendDecl(const FriendDecl *D) {
  lastChild();
  if (TypeSourceInfo *T = D->getFriendType())
    dumpType(T->getType());
  else
    dumpDecl(D->getFriendDecl());
}

//===----------------------------------------------------------------------===//
// Obj-C Declarations
//===----------------------------------------------------------------------===//

void ASTDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
  dumpName(D);
  dumpType(D->getType());
  if (D->getSynthesize())
    OS << " synthesize";

  switch (D->getAccessControl()) {
  case ObjCIvarDecl::None:
    OS << " none";
    break;
  case ObjCIvarDecl::Private:
    OS << " private";
    break;
  case ObjCIvarDecl::Protected:
    OS << " protected";
    break;
  case ObjCIvarDecl::Public:
    OS << " public";
    break;
  case ObjCIvarDecl::Package:
    OS << " package";
    break;
  }
}

void ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
  if (D->isInstanceMethod())
    OS << " -";
  else
    OS << " +";
  dumpName(D);
  dumpType(D->getResultType());

  bool OldMoreChildren = hasMoreChildren();
  bool IsVariadic = D->isVariadic();
  bool HasBody = D->hasBody();

  setMoreChildren(OldMoreChildren || IsVariadic || HasBody);
  if (D->isThisDeclarationADefinition()) {
    lastChild();
    dumpDeclContext(D);
  } else {
    for (ObjCMethodDecl::param_const_iterator I = D->param_begin(),
                                              E = D->param_end();
         I != E; ++I) {
      if (I + 1 == E)
        lastChild();
      dumpDecl(*I);
    }
  }

  setMoreChildren(OldMoreChildren || HasBody);
  if (IsVariadic) {
    lastChild();
    IndentScope Indent(*this);
    OS << "...";
  }

  setMoreChildren(OldMoreChildren);
  if (HasBody) {
    lastChild();
    dumpStmt(D->getBody());
  }
}

void ASTDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
  dumpName(D);
  dumpDeclRef(D->getClassInterface());
  if (D->protocol_begin() == D->protocol_end())
    lastChild();
  dumpDeclRef(D->getImplementation());
  for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(),
                                           E = D->protocol_end();
       I != E; ++I) {
    if (I + 1 == E)
      lastChild();
    dumpDeclRef(*I);
  }
}

void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
  dumpName(D);
  dumpDeclRef(D->getClassInterface());
  lastChild();
  dumpDeclRef(D->getCategoryDecl());
}

void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
  dumpName(D);
  for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(),
                                           E = D->protocol_end();
       I != E; ++I) {
    if (I + 1 == E)
      lastChild();
    dumpDeclRef(*I);
  }
}

void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
  dumpName(D);
  dumpDeclRef(D->getSuperClass(), "super");
  if (D->protocol_begin() == D->protocol_end())
    lastChild();
  dumpDeclRef(D->getImplementation());
  for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
                                            E = D->protocol_end();
       I != E; ++I) {
    if (I + 1 == E)
      lastChild();
    dumpDeclRef(*I);
  }
}

void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
  dumpName(D);
  dumpDeclRef(D->getSuperClass(), "super");
  if (D->init_begin() == D->init_end())
    lastChild();
  dumpDeclRef(D->getClassInterface());
  for (ObjCImplementationDecl::init_const_iterator I = D->init_begin(),
                                                   E = D->init_end();
       I != E; ++I) {
    if (I + 1 == E)
      lastChild();
    dumpCXXCtorInitializer(*I);
  }
}

void ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) {
  dumpName(D);
  lastChild();
  dumpDeclRef(D->getClassInterface());
}

void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
  dumpName(D);
  dumpType(D->getType());

  if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
    OS << " required";
  else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
    OS << " optional";

  ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes();
  if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) {
    if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly)
      OS << " readonly";
    if (Attrs & ObjCPropertyDecl::OBJC_PR_assign)
      OS << " assign";
    if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite)
      OS << " readwrite";
    if (Attrs & ObjCPropertyDecl::OBJC_PR_retain)
      OS << " retain";
    if (Attrs & ObjCPropertyDecl::OBJC_PR_copy)
      OS << " copy";
    if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic)
      OS << " nonatomic";
    if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic)
      OS << " atomic";
    if (Attrs & ObjCPropertyDecl::OBJC_PR_weak)
      OS << " weak";
    if (Attrs & ObjCPropertyDecl::OBJC_PR_strong)
      OS << " strong";
    if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained)
      OS << " unsafe_unretained";
    if (Attrs & ObjCPropertyDecl::OBJC_PR_getter) {
      if (!(Attrs & ObjCPropertyDecl::OBJC_PR_setter))
        lastChild();
      dumpDeclRef(D->getGetterMethodDecl(), "getter");
    }
    if (Attrs & ObjCPropertyDecl::OBJC_PR_setter) {
      lastChild();
      dumpDeclRef(D->getSetterMethodDecl(), "setter");
    }
  }
}

void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
  dumpName(D->getPropertyDecl());
  if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
    OS << " synthesize";
  else
    OS << " dynamic";
  dumpDeclRef(D->getPropertyDecl());
  lastChild();
  dumpDeclRef(D->getPropertyIvarDecl());
}

void ASTDumper::VisitBlockDecl(const BlockDecl *D) {
  for (BlockDecl::param_const_iterator I = D->param_begin(), E = D->param_end();
       I != E; ++I)
    dumpDecl(*I);

  if (D->isVariadic()) {
    IndentScope Indent(*this);
    OS << "...";
  }

  if (D->capturesCXXThis()) {
    IndentScope Indent(*this);
    OS << "capture this";
  }
  for (BlockDecl::capture_iterator I = D->capture_begin(), E = D->capture_end();
       I != E; ++I) {
    IndentScope Indent(*this);
    OS << "capture";
    if (I->isByRef())
      OS << " byref";
    if (I->isNested())
      OS << " nested";
    if (I->getVariable()) {
      OS << ' ';
      dumpBareDeclRef(I->getVariable());
    }
    if (I->hasCopyExpr())
      dumpStmt(I->getCopyExpr());
  }
  lastChild();
  dumpStmt(D->getBody());
}

//===----------------------------------------------------------------------===//
//  Stmt dumping methods.
//===----------------------------------------------------------------------===//

void ASTDumper::dumpStmt(const Stmt *S) {
  IndentScope Indent(*this);

  if (!S) {
    ColorScope Color(*this, NullColor);
    OS << "<<<NULL>>>";
    return;
  }

  if (const DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
    VisitDeclStmt(DS);
    return;
  }

  setMoreChildren(!S->children().empty());
  ConstStmtVisitor<ASTDumper>::Visit(S);
  setMoreChildren(false);
  for (Stmt::const_child_range CI = S->children(); CI; ++CI) {
    Stmt::const_child_range Next = CI;
    ++Next;
    if (!Next)
      lastChild();
    dumpStmt(*CI);
  }
}

void ASTDumper::VisitStmt(const Stmt *Node) {
  {   
    ColorScope Color(*this, StmtColor);
    OS << Node->getStmtClassName();
  }
  dumpPointer(Node);
  dumpSourceRange(Node->getSourceRange());
}

void ASTDumper::VisitDeclStmt(const DeclStmt *Node) {
  VisitStmt(Node);
  for (DeclStmt::const_decl_iterator I = Node->decl_begin(),
                                     E = Node->decl_end();
       I != E; ++I) {
    if (I + 1 == E)
      lastChild();
    dumpDecl(*I);
  }
}

void ASTDumper::VisitAttributedStmt(const AttributedStmt *Node) {
  VisitStmt(Node);
  for (ArrayRef<const Attr *>::iterator I = Node->getAttrs().begin(),
                                        E = Node->getAttrs().end();
       I != E; ++I) {
    if (I + 1 == E)
      lastChild();
    dumpAttr(*I);
  }
}

void ASTDumper::VisitLabelStmt(const LabelStmt *Node) {
  VisitStmt(Node);
  OS << " '" << Node->getName() << "'";
}

void ASTDumper::VisitGotoStmt(const GotoStmt *Node) {
  VisitStmt(Node);
  OS << " '" << Node->getLabel()->getName() << "'";
  dumpPointer(Node->getLabel());
}

//===----------------------------------------------------------------------===//
//  Expr dumping methods.
//===----------------------------------------------------------------------===//

void ASTDumper::VisitExpr(const Expr *Node) {
  VisitStmt(Node);
  dumpType(Node->getType());

  {
    ColorScope Color(*this, ValueKindColor);
    switch (Node->getValueKind()) {
    case VK_RValue:
      break;
    case VK_LValue:
      OS << " lvalue";
      break;
    case VK_XValue:
      OS << " xvalue";
      break;
    }
  }

  {
    ColorScope Color(*this, ObjectKindColor);
    switch (Node->getObjectKind()) {
    case OK_Ordinary:
      break;
    case OK_BitField:
      OS << " bitfield";
      break;
    case OK_ObjCProperty:
      OS << " objcproperty";
      break;
    case OK_ObjCSubscript:
      OS << " objcsubscript";
      break;
    case OK_VectorComponent:
      OS << " vectorcomponent";
      break;
    }
  }
}

static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
  if (Node->path_empty())
    return;

  OS << " (";
  bool First = true;
  for (CastExpr::path_const_iterator I = Node->path_begin(),
                                     E = Node->path_end();
       I != E; ++I) {
    const CXXBaseSpecifier *Base = *I;
    if (!First)
      OS << " -> ";

    const CXXRecordDecl *RD =
    cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());

    if (Base->isVirtual())
      OS << "virtual ";
    OS << RD->getName();
    First = false;
  }

  OS << ')';
}

void ASTDumper::VisitCastExpr(const CastExpr *Node) {
  VisitExpr(Node);
  OS << " <";
  {
    ColorScope Color(*this, CastColor);
    OS << Node->getCastKindName();
  }
  dumpBasePath(OS, Node);
  OS << ">";
}

void ASTDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
  VisitExpr(Node);

  OS << " ";
  dumpBareDeclRef(Node->getDecl());
  if (Node->getDecl() != Node->getFoundDecl()) {
    OS << " (";
    dumpBareDeclRef(Node->getFoundDecl());
    OS << ")";
  }
}

void ASTDumper::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node) {
  VisitExpr(Node);
  OS << " (";
  if (!Node->requiresADL())
    OS << "no ";
  OS << "ADL) = '" << Node->getName() << '\'';

  UnresolvedLookupExpr::decls_iterator
    I = Node->decls_begin(), E = Node->decls_end();
  if (I == E)
    OS << " empty";
  for (; I != E; ++I)
    dumpPointer(*I);
}

void ASTDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) {
  VisitExpr(Node);

  {
    ColorScope Color(*this, DeclKindNameColor);
    OS << " " << Node->getDecl()->getDeclKindName() << "Decl";
  }
  OS << "='" << *Node->getDecl() << "'";
  dumpPointer(Node->getDecl());
  if (Node->isFreeIvar())
    OS << " isFreeIvar";
}

void ASTDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
  VisitExpr(Node);
  switch (Node->getIdentType()) {
  default: llvm_unreachable("unknown case");
  case PredefinedExpr::Func:           OS <<  " __func__"; break;
  case PredefinedExpr::Function:       OS <<  " __FUNCTION__"; break;
  case PredefinedExpr::LFunction:      OS <<  " L__FUNCTION__"; break;
  case PredefinedExpr::PrettyFunction: OS <<  " __PRETTY_FUNCTION__";break;
  }
}

void ASTDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
  VisitExpr(Node);
  ColorScope Color(*this, ValueColor);
  OS << " " << Node->getValue();
}

void ASTDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
  VisitExpr(Node);

  bool isSigned = Node->getType()->isSignedIntegerType();
  ColorScope Color(*this, ValueColor);
  OS << " " << Node->getValue().toString(10, isSigned);
}

void ASTDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
  VisitExpr(Node);
  ColorScope Color(*this, ValueColor);
  OS << " " << Node->getValueAsApproximateDouble();
}

void ASTDumper::VisitStringLiteral(const StringLiteral *Str) {
  VisitExpr(Str);
  ColorScope Color(*this, ValueColor);
  OS << " ";
  Str->outputString(OS);
}

void ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) {
  VisitExpr(Node);
  OS << " " << (Node->isPostfix() ? "postfix" : "prefix")
     << " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
}

void ASTDumper::VisitUnaryExprOrTypeTraitExpr(
    const UnaryExprOrTypeTraitExpr *Node) {
  VisitExpr(Node);
  switch(Node->getKind()) {
  case UETT_SizeOf:
    OS << " sizeof";
    break;
  case UETT_AlignOf:
    OS << " alignof";
    break;
  case UETT_VecStep:
    OS << " vec_step";
    break;
  }
  if (Node->isArgumentType())
    dumpType(Node->getArgumentType());
}

void ASTDumper::VisitMemberExpr(const MemberExpr *Node) {
  VisitExpr(Node);
  OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
  dumpPointer(Node->getMemberDecl());
}

void ASTDumper::VisitExtVectorElementExpr(const ExtVectorElementExpr *Node) {
  VisitExpr(Node);
  OS << " " << Node->getAccessor().getNameStart();
}

void ASTDumper::VisitBinaryOperator(const BinaryOperator *Node) {
  VisitExpr(Node);
  OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
}

void ASTDumper::VisitCompoundAssignOperator(
    const CompoundAssignOperator *Node) {
  VisitExpr(Node);
  OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
     << "' ComputeLHSTy=";
  dumpBareType(Node->getComputationLHSType());
  OS << " ComputeResultTy=";
  dumpBareType(Node->getComputationResultType());
}

void ASTDumper::VisitBlockExpr(const BlockExpr *Node) {
  VisitExpr(Node);
  dumpDecl(Node->getBlockDecl());
}

void ASTDumper::VisitOpaqueValueExpr(const OpaqueValueExpr *Node) {
  VisitExpr(Node);

  if (Expr *Source = Node->getSourceExpr()) {
    lastChild();
    dumpStmt(Source);
  }
}

// GNU extensions.

void ASTDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
  VisitExpr(Node);
  OS << " " << Node->getLabel()->getName();
  dumpPointer(Node->getLabel());
}

//===----------------------------------------------------------------------===//
// C++ Expressions
//===----------------------------------------------------------------------===//

void ASTDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) {
  VisitExpr(Node);
  OS << " " << Node->getCastName()
     << "<" << Node->getTypeAsWritten().getAsString() << ">"
     << " <" << Node->getCastKindName();
  dumpBasePath(OS, Node);
  OS << ">";
}

void ASTDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
  VisitExpr(Node);
  OS << " " << (Node->getValue() ? "true" : "false");
}

void ASTDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
  VisitExpr(Node);
  OS << " this";
}

void ASTDumper::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node) {
  VisitExpr(Node);
  OS << " functional cast to " << Node->getTypeAsWritten().getAsString()
     << " <" << Node->getCastKindName() << ">";
}

void ASTDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
  VisitExpr(Node);
  CXXConstructorDecl *Ctor = Node->getConstructor();
  dumpType(Ctor->getType());
  if (Node->isElidable())
    OS << " elidable";
  if (Node->requiresZeroInitialization())
    OS << " zeroing";
}

void ASTDumper::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node) {
  VisitExpr(Node);
  OS << " ";
  dumpCXXTemporary(Node->getTemporary());
}

void
ASTDumper::VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node) {
  VisitExpr(Node);
  if (const ValueDecl *VD = Node->getExtendingDecl()) {
    OS << " extended by ";
    dumpBareDeclRef(VD);
  }
}

void ASTDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
  VisitExpr(Node);
  for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
    dumpDeclRef(Node->getObject(i), "cleanup");
}

void ASTDumper::dumpCXXTemporary(const CXXTemporary *Temporary) {
  OS << "(CXXTemporary";
  dumpPointer(Temporary);
  OS << ")";
}

//===----------------------------------------------------------------------===//
// Obj-C Expressions
//===----------------------------------------------------------------------===//

void ASTDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
  VisitExpr(Node);
  OS << " selector=" << Node->getSelector().getAsString();
  switch (Node->getReceiverKind()) {
  case ObjCMessageExpr::Instance:
    break;

  case ObjCMessageExpr::Class:
    OS << " class=";
    dumpBareType(Node->getClassReceiver());
    break;

  case ObjCMessageExpr::SuperInstance:
    OS << " super (instance)";
    break;

  case ObjCMessageExpr::SuperClass:
    OS << " super (class)";
    break;
  }
}

void ASTDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
  VisitExpr(Node);
  OS << " selector=" << Node->getBoxingMethod()->getSelector().getAsString();
}

void ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
  VisitStmt(Node);
  if (const VarDecl *CatchParam = Node->getCatchParamDecl())
    dumpDecl(CatchParam);
  else
    OS << " catch all";
}

void ASTDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
  VisitExpr(Node);
  dumpType(Node->getEncodedType());
}

void ASTDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
  VisitExpr(Node);

  OS << " " << Node->getSelector().getAsString();
}

void ASTDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
  VisitExpr(Node);

  OS << ' ' << *Node->getProtocol();
}

void ASTDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
  VisitExpr(Node);
  if (Node->isImplicitProperty()) {
    OS << " Kind=MethodRef Getter=\"";
    if (Node->getImplicitPropertyGetter())
      OS << Node->getImplicitPropertyGetter()->getSelector().getAsString();
    else
      OS << "(null)";

    OS << "\" Setter=\"";
    if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
      OS << Setter->getSelector().getAsString();
    else
      OS << "(null)";
    OS << "\"";
  } else {
    OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty() <<'"';
  }

  if (Node->isSuperReceiver())
    OS << " super";

  OS << " Messaging=";
  if (Node->isMessagingGetter() && Node->isMessagingSetter())
    OS << "Getter&Setter";
  else if (Node->isMessagingGetter())
    OS << "Getter";
  else if (Node->isMessagingSetter())
    OS << "Setter";
}

void ASTDumper::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node) {
  VisitExpr(Node);
  if (Node->isArraySubscriptRefExpr())
    OS << " Kind=ArraySubscript GetterForArray=\"";
  else
    OS << " Kind=DictionarySubscript GetterForDictionary=\"";
  if (Node->getAtIndexMethodDecl())
    OS << Node->getAtIndexMethodDecl()->getSelector().getAsString();
  else
    OS << "(null)";

  if (Node->isArraySubscriptRefExpr())
    OS << "\" SetterForArray=\"";
  else
    OS << "\" SetterForDictionary=\"";
  if (Node->setAtIndexMethodDecl())
    OS << Node->setAtIndexMethodDecl()->getSelector().getAsString();
  else
    OS << "(null)";
}

void ASTDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) {
  VisitExpr(Node);
  OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
}

//===----------------------------------------------------------------------===//
// Comments
//===----------------------------------------------------------------------===//

const char *ASTDumper::getCommandName(unsigned CommandID) {
  if (Traits)
    return Traits->getCommandInfo(CommandID)->Name;
  const CommandInfo *Info = CommandTraits::getBuiltinCommandInfo(CommandID);
  if (Info)
    return Info->Name;
  return "<not a builtin command>";
}

void ASTDumper::dumpFullComment(const FullComment *C) {
  if (!C)
    return;

  FC = C;
  dumpComment(C);
  FC = 0;
}

void ASTDumper::dumpComment(const Comment *C) {
  IndentScope Indent(*this);

  if (!C) {
    ColorScope Color(*this, NullColor);
    OS << "<<<NULL>>>";
    return;
  }

  {
    ColorScope Color(*this, CommentColor);
    OS << C->getCommentKindName();
  }
  dumpPointer(C);
  dumpSourceRange(C->getSourceRange());
  ConstCommentVisitor<ASTDumper>::visit(C);
  for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
       I != E; ++I) {
    if (I + 1 == E)
      lastChild();
    dumpComment(*I);
  }
}

void ASTDumper::visitTextComment(const TextComment *C) {
  OS << " Text=\"" << C->getText() << "\"";
}

void ASTDumper::visitInlineCommandComment(const InlineCommandComment *C) {
  OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
  switch (C->getRenderKind()) {
  case InlineCommandComment::RenderNormal:
    OS << " RenderNormal";
    break;
  case InlineCommandComment::RenderBold:
    OS << " RenderBold";
    break;
  case InlineCommandComment::RenderMonospaced:
    OS << " RenderMonospaced";
    break;
  case InlineCommandComment::RenderEmphasized:
    OS << " RenderEmphasized";
    break;
  }

  for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
    OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
}

void ASTDumper::visitHTMLStartTagComment(const HTMLStartTagComment *C) {
  OS << " Name=\"" << C->getTagName() << "\"";
  if (C->getNumAttrs() != 0) {
    OS << " Attrs: ";
    for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
      const HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
      OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
    }
  }
  if (C->isSelfClosing())
    OS << " SelfClosing";
}

void ASTDumper::visitHTMLEndTagComment(const HTMLEndTagComment *C) {
  OS << " Name=\"" << C->getTagName() << "\"";
}

void ASTDumper::visitBlockCommandComment(const BlockCommandComment *C) {
  OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
  for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
    OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
}

void ASTDumper::visitParamCommandComment(const ParamCommandComment *C) {
  OS << " " << ParamCommandComment::getDirectionAsString(C->getDirection());

  if (C->isDirectionExplicit())
    OS << " explicitly";
  else
    OS << " implicitly";

  if (C->hasParamName()) {
    if (C->isParamIndexValid())
      OS << " Param=\"" << C->getParamName(FC) << "\"";
    else
      OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
  }

  if (C->isParamIndexValid())
    OS << " ParamIndex=" << C->getParamIndex();
}

void ASTDumper::visitTParamCommandComment(const TParamCommandComment *C) {
  if (C->hasParamName()) {
    if (C->isPositionValid())
      OS << " Param=\"" << C->getParamName(FC) << "\"";
    else
      OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
  }

  if (C->isPositionValid()) {
    OS << " Position=<";
    for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
      OS << C->getIndex(i);
      if (i != e - 1)
        OS << ", ";
    }
    OS << ">";
  }
}

void ASTDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) {
  OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""
        " CloseName=\"" << C->getCloseName() << "\"";
}

void ASTDumper::visitVerbatimBlockLineComment(
    const VerbatimBlockLineComment *C) {
  OS << " Text=\"" << C->getText() << "\"";
}

void ASTDumper::visitVerbatimLineComment(const VerbatimLineComment *C) {
  OS << " Text=\"" << C->getText() << "\"";
}

//===----------------------------------------------------------------------===//
// Decl method implementations
//===----------------------------------------------------------------------===//

void Decl::dump() const {
  dump(llvm::errs());
}

void Decl::dump(raw_ostream &OS) const {
  ASTDumper P(OS, &getASTContext().getCommentCommandTraits(),
              &getASTContext().getSourceManager());
  P.dumpDecl(this);
}

void Decl::dumpColor() const {
  ASTDumper P(llvm::errs(), &getASTContext().getCommentCommandTraits(),
              &getASTContext().getSourceManager(), /*ShowColors*/true);
  P.dumpDecl(this);
}

void DeclContext::dumpLookups() const {
  dumpLookups(llvm::errs());
}

void DeclContext::dumpLookups(raw_ostream &OS) const {
  const DeclContext *DC = this;
  while (!DC->isTranslationUnit())
    DC = DC->getParent();
  ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
  ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager());
  P.dumpLookups(this);
}

//===----------------------------------------------------------------------===//
// Stmt method implementations
//===----------------------------------------------------------------------===//

void Stmt::dump(SourceManager &SM) const {
  dump(llvm::errs(), SM);
}

void Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
  ASTDumper P(OS, 0, &SM);
  P.dumpStmt(this);
}

void Stmt::dump() const {
  ASTDumper P(llvm::errs(), 0, 0);
  P.dumpStmt(this);
}

void Stmt::dumpColor() const {
  ASTDumper P(llvm::errs(), 0, 0, /*ShowColors*/true);
  P.dumpStmt(this);
}

//===----------------------------------------------------------------------===//
// Comment method implementations
//===----------------------------------------------------------------------===//

void Comment::dump() const {
  dump(llvm::errs(), 0, 0);
}

void Comment::dump(const ASTContext &Context) const {
  dump(llvm::errs(), &Context.getCommentCommandTraits(),
       &Context.getSourceManager());
}

void Comment::dump(raw_ostream &OS, const CommandTraits *Traits,
                   const SourceManager *SM) const {
  const FullComment *FC = dyn_cast<FullComment>(this);
  ASTDumper D(OS, Traits, SM);
  D.dumpFullComment(FC);
}

void Comment::dumpColor() const {
  const FullComment *FC = dyn_cast<FullComment>(this);
  ASTDumper D(llvm::errs(), 0, 0, /*ShowColors*/true);
  D.dumpFullComment(FC);
}
