ASTDumper.cpp revision 296417
138032Speter//===--- ASTDumper.cpp - Dumping implementation for ASTs ------------------===//
238032Speter//
338032Speter//                     The LLVM Compiler Infrastructure
438032Speter//
538032Speter// This file is distributed under the University of Illinois Open Source
638032Speter// License. See LICENSE.TXT for details.
738032Speter//
838032Speter//===----------------------------------------------------------------------===//
938032Speter//
1038032Speter// This file implements the AST dump methods, which dump out the
1138032Speter// AST in a form that exposes type details and other fields.
1238032Speter//
1338032Speter//===----------------------------------------------------------------------===//
1438032Speter
1538032Speter#include "clang/AST/ASTContext.h"
1638032Speter#include "clang/AST/Attr.h"
1738032Speter#include "clang/AST/CommentVisitor.h"
1838032Speter#include "clang/AST/DeclCXX.h"
1938032Speter#include "clang/AST/DeclLookups.h"
2038032Speter#include "clang/AST/DeclObjC.h"
2138032Speter#include "clang/AST/DeclVisitor.h"
2238032Speter#include "clang/AST/StmtVisitor.h"
2338032Speter#include "clang/AST/TypeVisitor.h"
2438032Speter#include "clang/Basic/Builtins.h"
2538032Speter#include "clang/Basic/Module.h"
2638032Speter#include "clang/Basic/SourceManager.h"
2738032Speter#include "clang/Sema/LocInfoType.h"
2838032Speter#include "llvm/Support/raw_ostream.h"
2938032Speterusing namespace clang;
3038032Speterusing namespace clang::comments;
3138032Speter
3238032Speter//===----------------------------------------------------------------------===//
3338032Speter// ASTDumper Visitor
3438032Speter//===----------------------------------------------------------------------===//
3538032Speter
3638032Speternamespace  {
3738032Speter  // Colors used for various parts of the AST dump
3838032Speter  // Do not use bold yellow for any text.  It is hard to read on white screens.
3938032Speter
4038032Speter  struct TerminalColor {
4138032Speter    raw_ostream::Colors Color;
4238032Speter    bool Bold;
4338032Speter  };
4438032Speter
4538032Speter  // Red           - CastColor
4638032Speter  // Green         - TypeColor
4738032Speter  // Bold Green    - DeclKindNameColor, UndeserializedColor
4838032Speter  // Yellow        - AddressColor, LocationColor
4938032Speter  // Blue          - CommentColor, NullColor, IndentColor
5038032Speter  // Bold Blue     - AttrColor
5138032Speter  // Bold Magenta  - StmtColor
5238032Speter  // Cyan          - ValueKindColor, ObjectKindColor
5338032Speter  // Bold Cyan     - ValueColor, DeclNameColor
5438032Speter
5538032Speter  // Decl kind names (VarDecl, FunctionDecl, etc)
5638032Speter  static const TerminalColor DeclKindNameColor = { raw_ostream::GREEN, true };
5738032Speter  // Attr names (CleanupAttr, GuardedByAttr, etc)
5838032Speter  static const TerminalColor AttrColor = { raw_ostream::BLUE, true };
5938032Speter  // Statement names (DeclStmt, ImplicitCastExpr, etc)
6038032Speter  static const TerminalColor StmtColor = { raw_ostream::MAGENTA, true };
6138032Speter  // Comment names (FullComment, ParagraphComment, TextComment, etc)
6238032Speter  static const TerminalColor CommentColor = { raw_ostream::BLUE, false };
6338032Speter
6438032Speter  // Type names (int, float, etc, plus user defined types)
6538032Speter  static const TerminalColor TypeColor = { raw_ostream::GREEN, false };
6638032Speter
6738032Speter  // Pointer address
6838032Speter  static const TerminalColor AddressColor = { raw_ostream::YELLOW, false };
6938032Speter  // Source locations
7038032Speter  static const TerminalColor LocationColor = { raw_ostream::YELLOW, false };
7138032Speter
7238032Speter  // lvalue/xvalue
7338032Speter  static const TerminalColor ValueKindColor = { raw_ostream::CYAN, false };
7438032Speter  // bitfield/objcproperty/objcsubscript/vectorcomponent
7538032Speter  static const TerminalColor ObjectKindColor = { raw_ostream::CYAN, false };
7638032Speter
7738032Speter  // Null statements
7838032Speter  static const TerminalColor NullColor = { raw_ostream::BLUE, false };
7938032Speter
8038032Speter  // Undeserialized entities
8138032Speter  static const TerminalColor UndeserializedColor = { raw_ostream::GREEN, true };
8238032Speter
8338032Speter  // CastKind from CastExpr's
8438032Speter  static const TerminalColor CastColor = { raw_ostream::RED, false };
8538032Speter
8638032Speter  // Value of the statement
8738032Speter  static const TerminalColor ValueColor = { raw_ostream::CYAN, true };
8838032Speter  // Decl names
8938032Speter  static const TerminalColor DeclNameColor = { raw_ostream::CYAN, true };
9038032Speter
9138032Speter  // Indents ( `, -. | )
9238032Speter  static const TerminalColor IndentColor = { raw_ostream::BLUE, false };
9338032Speter
9438032Speter  class ASTDumper
9538032Speter      : public ConstDeclVisitor<ASTDumper>, public ConstStmtVisitor<ASTDumper>,
9638032Speter        public ConstCommentVisitor<ASTDumper>, public TypeVisitor<ASTDumper> {
9738032Speter    raw_ostream &OS;
9838032Speter    const CommandTraits *Traits;
9938032Speter    const SourceManager *SM;
10038032Speter
10138032Speter    /// Pending[i] is an action to dump an entity at level i.
10238032Speter    llvm::SmallVector<std::function<void(bool isLastChild)>, 32> Pending;
10338032Speter
10438032Speter    /// Indicates whether we're at the top level.
10538032Speter    bool TopLevel;
10638032Speter
10738032Speter    /// Indicates if we're handling the first child after entering a new depth.
10838032Speter    bool FirstChild;
10938032Speter
11038032Speter    /// Prefix for currently-being-dumped entity.
11138032Speter    std::string Prefix;
11238032Speter
11338032Speter    /// Keep track of the last location we print out so that we can
11438032Speter    /// print out deltas from then on out.
11538032Speter    const char *LastLocFilename;
11638032Speter    unsigned LastLocLine;
11738032Speter
11838032Speter    /// The \c FullComment parent of the comment being dumped.
11938032Speter    const FullComment *FC;
12038032Speter
12138032Speter    bool ShowColors;
12238032Speter
12338032Speter    /// Dump a child of the current node.
12438032Speter    template<typename Fn> void dumpChild(Fn doDumpChild) {
12538032Speter      // If we're at the top level, there's nothing interesting to do; just
12638032Speter      // run the dumper.
12738032Speter      if (TopLevel) {
12838032Speter        TopLevel = false;
12938032Speter        doDumpChild();
13038032Speter        while (!Pending.empty()) {
13138032Speter          Pending.back()(true);
13238032Speter          Pending.pop_back();
13338032Speter        }
13438032Speter        Prefix.clear();
13538032Speter        OS << "\n";
13638032Speter        TopLevel = true;
13738032Speter        return;
13838032Speter      }
13938032Speter
14038032Speter      const FullComment *OrigFC = FC;
14138032Speter      auto dumpWithIndent = [this, doDumpChild, OrigFC](bool isLastChild) {
14238032Speter        // Print out the appropriate tree structure and work out the prefix for
14338032Speter        // children of this node. For instance:
14438032Speter        //
14538032Speter        //   A        Prefix = ""
14638032Speter        //   |-B      Prefix = "| "
14738032Speter        //   | `-C    Prefix = "|   "
14838032Speter        //   `-D      Prefix = "  "
14938032Speter        //     |-E    Prefix = "  | "
15038032Speter        //     `-F    Prefix = "    "
15138032Speter        //   G        Prefix = ""
15238032Speter        //
15338032Speter        // Note that the first level gets no prefix.
15438032Speter        {
15538032Speter          OS << '\n';
15638032Speter          ColorScope Color(*this, IndentColor);
15738032Speter          OS << Prefix << (isLastChild ? '`' : '|') << '-';
15838032Speter          this->Prefix.push_back(isLastChild ? ' ' : '|');
15938032Speter          this->Prefix.push_back(' ');
16038032Speter        }
16138032Speter
16238032Speter        FirstChild = true;
16338032Speter        unsigned Depth = Pending.size();
16438032Speter
16538032Speter        FC = OrigFC;
16638032Speter        doDumpChild();
16738032Speter
16838032Speter        // If any children are left, they're the last at their nesting level.
16938032Speter        // Dump those ones out now.
17038032Speter        while (Depth < Pending.size()) {
17138032Speter          Pending.back()(true);
17238032Speter          this->Pending.pop_back();
17338032Speter        }
17438032Speter
17538032Speter        // Restore the old prefix.
17638032Speter        this->Prefix.resize(Prefix.size() - 2);
17738032Speter      };
17838032Speter
17938032Speter      if (FirstChild) {
18038032Speter        Pending.push_back(std::move(dumpWithIndent));
18138032Speter      } else {
18238032Speter        Pending.back()(false);
18338032Speter        Pending.back() = std::move(dumpWithIndent);
18438032Speter      }
18538032Speter      FirstChild = false;
18638032Speter    }
18738032Speter
18838032Speter    class ColorScope {
18938032Speter      ASTDumper &Dumper;
19038032Speter    public:
19138032Speter      ColorScope(ASTDumper &Dumper, TerminalColor Color)
19238032Speter        : Dumper(Dumper) {
19338032Speter        if (Dumper.ShowColors)
19438032Speter          Dumper.OS.changeColor(Color.Color, Color.Bold);
19538032Speter      }
19638032Speter      ~ColorScope() {
19738032Speter        if (Dumper.ShowColors)
19838032Speter          Dumper.OS.resetColor();
19938032Speter      }
20038032Speter    };
20138032Speter
20238032Speter  public:
20338032Speter    ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
20438032Speter              const SourceManager *SM)
20538032Speter      : OS(OS), Traits(Traits), SM(SM), TopLevel(true), FirstChild(true),
20638032Speter        LastLocFilename(""), LastLocLine(~0U), FC(nullptr),
20738032Speter        ShowColors(SM && SM->getDiagnostics().getShowColors()) { }
20838032Speter
20938032Speter    ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
21038032Speter              const SourceManager *SM, bool ShowColors)
21138032Speter      : OS(OS), Traits(Traits), SM(SM), TopLevel(true), FirstChild(true),
21238032Speter        LastLocFilename(""), LastLocLine(~0U),
21338032Speter        ShowColors(ShowColors) { }
21438032Speter
21538032Speter    void dumpDecl(const Decl *D);
21638032Speter    void dumpStmt(const Stmt *S);
21738032Speter    void dumpFullComment(const FullComment *C);
21838032Speter
21938032Speter    // Utilities
22038032Speter    void dumpPointer(const void *Ptr);
22138032Speter    void dumpSourceRange(SourceRange R);
22238032Speter    void dumpLocation(SourceLocation Loc);
22338032Speter    void dumpBareType(QualType T, bool Desugar = true);
22438032Speter    void dumpType(QualType T);
22538032Speter    void dumpTypeAsChild(QualType T);
22638032Speter    void dumpTypeAsChild(const Type *T);
22738032Speter    void dumpBareDeclRef(const Decl *Node);
22838032Speter    void dumpDeclRef(const Decl *Node, const char *Label = nullptr);
22938032Speter    void dumpName(const NamedDecl *D);
23038032Speter    bool hasNodes(const DeclContext *DC);
23138032Speter    void dumpDeclContext(const DeclContext *DC);
23238032Speter    void dumpLookups(const DeclContext *DC, bool DumpDecls);
23338032Speter    void dumpAttr(const Attr *A);
23438032Speter
23538032Speter    // C++ Utilities
23638032Speter    void dumpAccessSpecifier(AccessSpecifier AS);
23738032Speter    void dumpCXXCtorInitializer(const CXXCtorInitializer *Init);
23838032Speter    void dumpTemplateParameters(const TemplateParameterList *TPL);
23938032Speter    void dumpTemplateArgumentListInfo(const TemplateArgumentListInfo &TALI);
24038032Speter    void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A);
24138032Speter    void dumpTemplateArgumentList(const TemplateArgumentList &TAL);
24238032Speter    void dumpTemplateArgument(const TemplateArgument &A,
24338032Speter                              SourceRange R = SourceRange());
24438032Speter
24538032Speter    // Objective-C utilities.
24638032Speter    void dumpObjCTypeParamList(const ObjCTypeParamList *typeParams);
24738032Speter
24838032Speter    // Types
24938032Speter    void VisitComplexType(const ComplexType *T) {
25038032Speter      dumpTypeAsChild(T->getElementType());
25138032Speter    }
25238032Speter    void VisitPointerType(const PointerType *T) {
25338032Speter      dumpTypeAsChild(T->getPointeeType());
25438032Speter    }
25538032Speter    void VisitBlockPointerType(const BlockPointerType *T) {
25638032Speter      dumpTypeAsChild(T->getPointeeType());
25738032Speter    }
25838032Speter    void VisitReferenceType(const ReferenceType *T) {
25938032Speter      dumpTypeAsChild(T->getPointeeType());
26038032Speter    }
26138032Speter    void VisitRValueReferenceType(const ReferenceType *T) {
26238032Speter      if (T->isSpelledAsLValue())
26338032Speter        OS << " written as lvalue reference";
26438032Speter      VisitReferenceType(T);
26538032Speter    }
26638032Speter    void VisitMemberPointerType(const MemberPointerType *T) {
26738032Speter      dumpTypeAsChild(T->getClass());
26838032Speter      dumpTypeAsChild(T->getPointeeType());
26938032Speter    }
27038032Speter    void VisitArrayType(const ArrayType *T) {
27138032Speter      switch (T->getSizeModifier()) {
27238032Speter        case ArrayType::Normal: break;
27338032Speter        case ArrayType::Static: OS << " static"; break;
27438032Speter        case ArrayType::Star: OS << " *"; break;
27538032Speter      }
27638032Speter      OS << " " << T->getIndexTypeQualifiers().getAsString();
27738032Speter      dumpTypeAsChild(T->getElementType());
27838032Speter    }
27938032Speter    void VisitConstantArrayType(const ConstantArrayType *T) {
28038032Speter      OS << " " << T->getSize();
28138032Speter      VisitArrayType(T);
28238032Speter    }
28338032Speter    void VisitVariableArrayType(const VariableArrayType *T) {
28438032Speter      OS << " ";
28538032Speter      dumpSourceRange(T->getBracketsRange());
28638032Speter      VisitArrayType(T);
28738032Speter      dumpStmt(T->getSizeExpr());
28838032Speter    }
28938032Speter    void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
29038032Speter      VisitArrayType(T);
29138032Speter      OS << " ";
29238032Speter      dumpSourceRange(T->getBracketsRange());
29338032Speter      dumpStmt(T->getSizeExpr());
29438032Speter    }
29538032Speter    void VisitDependentSizedExtVectorType(
29638032Speter        const DependentSizedExtVectorType *T) {
29738032Speter      OS << " ";
29838032Speter      dumpLocation(T->getAttributeLoc());
29938032Speter      dumpTypeAsChild(T->getElementType());
30038032Speter      dumpStmt(T->getSizeExpr());
30138032Speter    }
30238032Speter    void VisitVectorType(const VectorType *T) {
30338032Speter      switch (T->getVectorKind()) {
30438032Speter        case VectorType::GenericVector: break;
30538032Speter        case VectorType::AltiVecVector: OS << " altivec"; break;
30638032Speter        case VectorType::AltiVecPixel: OS << " altivec pixel"; break;
30738032Speter        case VectorType::AltiVecBool: OS << " altivec bool"; break;
30838032Speter        case VectorType::NeonVector: OS << " neon"; break;
30938032Speter        case VectorType::NeonPolyVector: OS << " neon poly"; break;
31038032Speter      }
31138032Speter      OS << " " << T->getNumElements();
31238032Speter      dumpTypeAsChild(T->getElementType());
31338032Speter    }
31438032Speter    void VisitFunctionType(const FunctionType *T) {
31538032Speter      auto EI = T->getExtInfo();
31638032Speter      if (EI.getNoReturn()) OS << " noreturn";
31738032Speter      if (EI.getProducesResult()) OS << " produces_result";
31838032Speter      if (EI.getHasRegParm()) OS << " regparm " << EI.getRegParm();
31938032Speter      OS << " " << FunctionType::getNameForCallConv(EI.getCC());
32038032Speter      dumpTypeAsChild(T->getReturnType());
32138032Speter    }
32238032Speter    void VisitFunctionProtoType(const FunctionProtoType *T) {
32338032Speter      auto EPI = T->getExtProtoInfo();
32438032Speter      if (EPI.HasTrailingReturn) OS << " trailing_return";
32538032Speter      if (T->isConst()) OS << " const";
32638032Speter      if (T->isVolatile()) OS << " volatile";
32738032Speter      if (T->isRestrict()) OS << " restrict";
32838032Speter      switch (EPI.RefQualifier) {
32938032Speter        case RQ_None: break;
33038032Speter        case RQ_LValue: OS << " &"; break;
33138032Speter        case RQ_RValue: OS << " &&"; break;
33238032Speter      }
33338032Speter      // FIXME: Exception specification.
33438032Speter      // FIXME: Consumed parameters.
33538032Speter      VisitFunctionType(T);
33638032Speter      for (QualType PT : T->getParamTypes())
33738032Speter        dumpTypeAsChild(PT);
33838032Speter      if (EPI.Variadic)
33938032Speter        dumpChild([=] { OS << "..."; });
34038032Speter    }
34138032Speter    void VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
34238032Speter      dumpDeclRef(T->getDecl());
34338032Speter    }
34438032Speter    void VisitTypedefType(const TypedefType *T) {
34538032Speter      dumpDeclRef(T->getDecl());
34638032Speter    }
34738032Speter    void VisitTypeOfExprType(const TypeOfExprType *T) {
34838032Speter      dumpStmt(T->getUnderlyingExpr());
34938032Speter    }
35038032Speter    void VisitDecltypeType(const DecltypeType *T) {
35138032Speter      dumpStmt(T->getUnderlyingExpr());
35238032Speter    }
35338032Speter    void VisitUnaryTransformType(const UnaryTransformType *T) {
35438032Speter      switch (T->getUTTKind()) {
35538032Speter      case UnaryTransformType::EnumUnderlyingType:
35638032Speter        OS << " underlying_type";
35738032Speter        break;
35838032Speter      }
35938032Speter      dumpTypeAsChild(T->getBaseType());
36038032Speter    }
36138032Speter    void VisitTagType(const TagType *T) {
36238032Speter      dumpDeclRef(T->getDecl());
36338032Speter    }
36438032Speter    void VisitAttributedType(const AttributedType *T) {
36538032Speter      // FIXME: AttrKind
36638032Speter      dumpTypeAsChild(T->getModifiedType());
36738032Speter    }
36838032Speter    void VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
36938032Speter      OS << " depth " << T->getDepth() << " index " << T->getIndex();
37038032Speter      if (T->isParameterPack()) OS << " pack";
37138032Speter      dumpDeclRef(T->getDecl());
37238032Speter    }
37338032Speter    void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
37438032Speter      dumpTypeAsChild(T->getReplacedParameter());
37538032Speter    }
37638032Speter    void VisitSubstTemplateTypeParmPackType(
37738032Speter        const SubstTemplateTypeParmPackType *T) {
37838032Speter      dumpTypeAsChild(T->getReplacedParameter());
37938032Speter      dumpTemplateArgument(T->getArgumentPack());
38038032Speter    }
38138032Speter    void VisitAutoType(const AutoType *T) {
38238032Speter      if (T->isDecltypeAuto()) OS << " decltype(auto)";
38338032Speter      if (!T->isDeduced())
38438032Speter        OS << " undeduced";
38538032Speter    }
38638032Speter    void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
38738032Speter      if (T->isTypeAlias()) OS << " alias";
38838032Speter      OS << " "; T->getTemplateName().dump(OS);
38938032Speter      for (auto &Arg : *T)
39038032Speter        dumpTemplateArgument(Arg);
39138032Speter      if (T->isTypeAlias())
39238032Speter        dumpTypeAsChild(T->getAliasedType());
39338032Speter    }
39438032Speter    void VisitInjectedClassNameType(const InjectedClassNameType *T) {
39538032Speter      dumpDeclRef(T->getDecl());
39638032Speter    }
39738032Speter    void VisitObjCInterfaceType(const ObjCInterfaceType *T) {
39838032Speter      dumpDeclRef(T->getDecl());
39938032Speter    }
40038032Speter    void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
40138032Speter      dumpTypeAsChild(T->getPointeeType());
40238032Speter    }
40338032Speter    void VisitAtomicType(const AtomicType *T) {
40438032Speter      dumpTypeAsChild(T->getValueType());
40538032Speter    }
40638032Speter    void VisitAdjustedType(const AdjustedType *T) {
40738032Speter      dumpTypeAsChild(T->getOriginalType());
40838032Speter    }
40938032Speter    void VisitPackExpansionType(const PackExpansionType *T) {
41038032Speter      if (auto N = T->getNumExpansions()) OS << " expansions " << *N;
41138032Speter      if (!T->isSugared())
41238032Speter        dumpTypeAsChild(T->getPattern());
41338032Speter    }
41438032Speter    // FIXME: ElaboratedType, DependentNameType,
41538032Speter    // DependentTemplateSpecializationType, ObjCObjectType
41638032Speter
41738032Speter    // Decls
41838032Speter    void VisitLabelDecl(const LabelDecl *D);
41938032Speter    void VisitTypedefDecl(const TypedefDecl *D);
42038032Speter    void VisitEnumDecl(const EnumDecl *D);
42138032Speter    void VisitRecordDecl(const RecordDecl *D);
42238032Speter    void VisitEnumConstantDecl(const EnumConstantDecl *D);
42338032Speter    void VisitIndirectFieldDecl(const IndirectFieldDecl *D);
42438032Speter    void VisitFunctionDecl(const FunctionDecl *D);
42538032Speter    void VisitFieldDecl(const FieldDecl *D);
42638032Speter    void VisitVarDecl(const VarDecl *D);
42738032Speter    void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D);
42838032Speter    void VisitImportDecl(const ImportDecl *D);
42938032Speter
43038032Speter    // C++ Decls
43138032Speter    void VisitNamespaceDecl(const NamespaceDecl *D);
43238032Speter    void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D);
43338032Speter    void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D);
43438032Speter    void VisitTypeAliasDecl(const TypeAliasDecl *D);
43538032Speter    void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D);
43638032Speter    void VisitCXXRecordDecl(const CXXRecordDecl *D);
43738032Speter    void VisitStaticAssertDecl(const StaticAssertDecl *D);
43838032Speter    template<typename SpecializationDecl>
43938032Speter    void VisitTemplateDeclSpecialization(const SpecializationDecl *D,
44038032Speter                                         bool DumpExplicitInst,
44138032Speter                                         bool DumpRefOnly);
44238032Speter    template<typename TemplateDecl>
44338032Speter    void VisitTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst);
44438032Speter    void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
44538032Speter    void VisitClassTemplateDecl(const ClassTemplateDecl *D);
44638032Speter    void VisitClassTemplateSpecializationDecl(
44738032Speter        const ClassTemplateSpecializationDecl *D);
44838032Speter    void VisitClassTemplatePartialSpecializationDecl(
44938032Speter        const ClassTemplatePartialSpecializationDecl *D);
45038032Speter    void VisitClassScopeFunctionSpecializationDecl(
45138032Speter        const ClassScopeFunctionSpecializationDecl *D);
45238032Speter    void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D);
45338032Speter    void VisitVarTemplateDecl(const VarTemplateDecl *D);
45438032Speter    void VisitVarTemplateSpecializationDecl(
45538032Speter        const VarTemplateSpecializationDecl *D);
45638032Speter    void VisitVarTemplatePartialSpecializationDecl(
45738032Speter        const VarTemplatePartialSpecializationDecl *D);
45838032Speter    void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
45938032Speter    void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
46038032Speter    void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
46138032Speter    void VisitUsingDecl(const UsingDecl *D);
46238032Speter    void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D);
46338032Speter    void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D);
46438032Speter    void VisitUsingShadowDecl(const UsingShadowDecl *D);
46538032Speter    void VisitLinkageSpecDecl(const LinkageSpecDecl *D);
46638032Speter    void VisitAccessSpecDecl(const AccessSpecDecl *D);
46738032Speter    void VisitFriendDecl(const FriendDecl *D);
46838032Speter
46938032Speter    // ObjC Decls
47038032Speter    void VisitObjCIvarDecl(const ObjCIvarDecl *D);
47138032Speter    void VisitObjCMethodDecl(const ObjCMethodDecl *D);
47238032Speter    void VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D);
47338032Speter    void VisitObjCCategoryDecl(const ObjCCategoryDecl *D);
47438032Speter    void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D);
47538032Speter    void VisitObjCProtocolDecl(const ObjCProtocolDecl *D);
47638032Speter    void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D);
47738032Speter    void VisitObjCImplementationDecl(const ObjCImplementationDecl *D);
47838032Speter    void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D);
47938032Speter    void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
48038032Speter    void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
48138032Speter    void VisitBlockDecl(const BlockDecl *D);
48238032Speter
48338032Speter    // Stmts.
48438032Speter    void VisitStmt(const Stmt *Node);
48538032Speter    void VisitDeclStmt(const DeclStmt *Node);
48638032Speter    void VisitAttributedStmt(const AttributedStmt *Node);
48738032Speter    void VisitLabelStmt(const LabelStmt *Node);
48838032Speter    void VisitGotoStmt(const GotoStmt *Node);
48938032Speter    void VisitCXXCatchStmt(const CXXCatchStmt *Node);
49038032Speter
49138032Speter    // Exprs
49238032Speter    void VisitExpr(const Expr *Node);
49338032Speter    void VisitCastExpr(const CastExpr *Node);
49438032Speter    void VisitDeclRefExpr(const DeclRefExpr *Node);
49538032Speter    void VisitPredefinedExpr(const PredefinedExpr *Node);
49638032Speter    void VisitCharacterLiteral(const CharacterLiteral *Node);
49738032Speter    void VisitIntegerLiteral(const IntegerLiteral *Node);
49838032Speter    void VisitFloatingLiteral(const FloatingLiteral *Node);
49938032Speter    void VisitStringLiteral(const StringLiteral *Str);
50038032Speter    void VisitInitListExpr(const InitListExpr *ILE);
50138032Speter    void VisitUnaryOperator(const UnaryOperator *Node);
50238032Speter    void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node);
50338032Speter    void VisitMemberExpr(const MemberExpr *Node);
50438032Speter    void VisitExtVectorElementExpr(const ExtVectorElementExpr *Node);
50538032Speter    void VisitBinaryOperator(const BinaryOperator *Node);
50638032Speter    void VisitCompoundAssignOperator(const CompoundAssignOperator *Node);
50738032Speter    void VisitAddrLabelExpr(const AddrLabelExpr *Node);
50838032Speter    void VisitBlockExpr(const BlockExpr *Node);
50938032Speter    void VisitOpaqueValueExpr(const OpaqueValueExpr *Node);
51038032Speter
51138032Speter    // C++
51238032Speter    void VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node);
51338032Speter    void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node);
51438032Speter    void VisitCXXThisExpr(const CXXThisExpr *Node);
51538032Speter    void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node);
51638032Speter    void VisitCXXConstructExpr(const CXXConstructExpr *Node);
51738032Speter    void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node);
51838032Speter    void VisitCXXNewExpr(const CXXNewExpr *Node);
51938032Speter    void VisitCXXDeleteExpr(const CXXDeleteExpr *Node);
52038032Speter    void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node);
52138032Speter    void VisitExprWithCleanups(const ExprWithCleanups *Node);
52238032Speter    void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node);
52338032Speter    void dumpCXXTemporary(const CXXTemporary *Temporary);
52438032Speter    void VisitLambdaExpr(const LambdaExpr *Node) {
52538032Speter      VisitExpr(Node);
52638032Speter      dumpDecl(Node->getLambdaClass());
52738032Speter    }
52838032Speter    void VisitSizeOfPackExpr(const SizeOfPackExpr *Node);
52938032Speter
53038032Speter    // ObjC
53138032Speter    void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node);
53238032Speter    void VisitObjCEncodeExpr(const ObjCEncodeExpr *Node);
53338032Speter    void VisitObjCMessageExpr(const ObjCMessageExpr *Node);
53438032Speter    void VisitObjCBoxedExpr(const ObjCBoxedExpr *Node);
53538032Speter    void VisitObjCSelectorExpr(const ObjCSelectorExpr *Node);
53638032Speter    void VisitObjCProtocolExpr(const ObjCProtocolExpr *Node);
53738032Speter    void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node);
53838032Speter    void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node);
53938032Speter    void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node);
54038032Speter    void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node);
54138032Speter
54238032Speter    // Comments.
54338032Speter    const char *getCommandName(unsigned CommandID);
54438032Speter    void dumpComment(const Comment *C);
54538032Speter
54638032Speter    // Inline comments.
54738032Speter    void visitTextComment(const TextComment *C);
54838032Speter    void visitInlineCommandComment(const InlineCommandComment *C);
54938032Speter    void visitHTMLStartTagComment(const HTMLStartTagComment *C);
55038032Speter    void visitHTMLEndTagComment(const HTMLEndTagComment *C);
55138032Speter
55238032Speter    // Block comments.
55338032Speter    void visitBlockCommandComment(const BlockCommandComment *C);
55438032Speter    void visitParamCommandComment(const ParamCommandComment *C);
55538032Speter    void visitTParamCommandComment(const TParamCommandComment *C);
55638032Speter    void visitVerbatimBlockComment(const VerbatimBlockComment *C);
55738032Speter    void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
55838032Speter    void visitVerbatimLineComment(const VerbatimLineComment *C);
55938032Speter  };
56038032Speter}
56138032Speter
56238032Speter//===----------------------------------------------------------------------===//
56338032Speter//  Utilities
56438032Speter//===----------------------------------------------------------------------===//
56538032Speter
56638032Spetervoid ASTDumper::dumpPointer(const void *Ptr) {
56738032Speter  ColorScope Color(*this, AddressColor);
56838032Speter  OS << ' ' << Ptr;
56938032Speter}
57038032Speter
57138032Spetervoid ASTDumper::dumpLocation(SourceLocation Loc) {
57238032Speter  if (!SM)
57338032Speter    return;
57438032Speter
57538032Speter  ColorScope Color(*this, LocationColor);
57638032Speter  SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
57738032Speter
57838032Speter  // The general format we print out is filename:line:col, but we drop pieces
57938032Speter  // that haven't changed since the last loc printed.
58038032Speter  PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
58138032Speter
58238032Speter  if (PLoc.isInvalid()) {
58338032Speter    OS << "<invalid sloc>";
58438032Speter    return;
58538032Speter  }
58638032Speter
58738032Speter  if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
58838032Speter    OS << PLoc.getFilename() << ':' << PLoc.getLine()
58938032Speter       << ':' << PLoc.getColumn();
59038032Speter    LastLocFilename = PLoc.getFilename();
59138032Speter    LastLocLine = PLoc.getLine();
59238032Speter  } else if (PLoc.getLine() != LastLocLine) {
59338032Speter    OS << "line" << ':' << PLoc.getLine()
59438032Speter       << ':' << PLoc.getColumn();
59538032Speter    LastLocLine = PLoc.getLine();
59638032Speter  } else {
59738032Speter    OS << "col" << ':' << PLoc.getColumn();
59838032Speter  }
59938032Speter}
60038032Speter
60138032Spetervoid ASTDumper::dumpSourceRange(SourceRange R) {
60238032Speter  // Can't translate locations if a SourceManager isn't available.
60338032Speter  if (!SM)
60438032Speter    return;
60538032Speter
60638032Speter  OS << " <";
60738032Speter  dumpLocation(R.getBegin());
60838032Speter  if (R.getBegin() != R.getEnd()) {
60938032Speter    OS << ", ";
61038032Speter    dumpLocation(R.getEnd());
61138032Speter  }
61238032Speter  OS << ">";
61338032Speter
61438032Speter  // <t2.c:123:421[blah], t2.c:412:321>
61538032Speter
61638032Speter}
61738032Speter
61838032Spetervoid ASTDumper::dumpBareType(QualType T, bool Desugar) {
61938032Speter  ColorScope Color(*this, TypeColor);
62038032Speter
62138032Speter  SplitQualType T_split = T.split();
62238032Speter  OS << "'" << QualType::getAsString(T_split) << "'";
62338032Speter
62438032Speter  if (Desugar && !T.isNull()) {
62538032Speter    // If the type is sugared, also dump a (shallow) desugared type.
62638032Speter    SplitQualType D_split = T.getSplitDesugaredType();
62738032Speter    if (T_split != D_split)
62838032Speter      OS << ":'" << QualType::getAsString(D_split) << "'";
62938032Speter  }
63038032Speter}
63138032Speter
63238032Spetervoid ASTDumper::dumpType(QualType T) {
63338032Speter  OS << ' ';
63438032Speter  dumpBareType(T);
63538032Speter}
63638032Speter
63738032Spetervoid ASTDumper::dumpTypeAsChild(QualType T) {
63838032Speter  SplitQualType SQT = T.split();
63938032Speter  if (!SQT.Quals.hasQualifiers())
64038032Speter    return dumpTypeAsChild(SQT.Ty);
64138032Speter
64238032Speter  dumpChild([=] {
64338032Speter    OS << "QualType";
64438032Speter    dumpPointer(T.getAsOpaquePtr());
64538032Speter    OS << " ";
64638032Speter    dumpBareType(T, false);
64738032Speter    OS << " " << T.split().Quals.getAsString();
64838032Speter    dumpTypeAsChild(T.split().Ty);
64938032Speter  });
65038032Speter}
65138032Speter
65238032Spetervoid ASTDumper::dumpTypeAsChild(const Type *T) {
65338032Speter  dumpChild([=] {
65438032Speter    if (!T) {
65538032Speter      ColorScope Color(*this, NullColor);
65638032Speter      OS << "<<<NULL>>>";
65738032Speter      return;
65838032Speter    }
65938032Speter    if (const LocInfoType *LIT = llvm::dyn_cast<LocInfoType>(T)) {
66038032Speter      {
66138032Speter        ColorScope Color(*this, TypeColor);
66238032Speter        OS << "LocInfo Type";
66338032Speter      }
66438032Speter      dumpPointer(T);
66538032Speter      dumpTypeAsChild(LIT->getTypeSourceInfo()->getType());
66638032Speter      return;
66738032Speter    }
66838032Speter
66938032Speter    {
67038032Speter      ColorScope Color(*this, TypeColor);
67138032Speter      OS << T->getTypeClassName() << "Type";
67238032Speter    }
67338032Speter    dumpPointer(T);
67438032Speter    OS << " ";
67538032Speter    dumpBareType(QualType(T, 0), false);
67638032Speter
67738032Speter    QualType SingleStepDesugar =
67838032Speter        T->getLocallyUnqualifiedSingleStepDesugaredType();
67938032Speter    if (SingleStepDesugar != QualType(T, 0))
68038032Speter      OS << " sugar";
68138032Speter    if (T->isDependentType())
68238032Speter      OS << " dependent";
68338032Speter    else if (T->isInstantiationDependentType())
68438032Speter      OS << " instantiation_dependent";
68538032Speter    if (T->isVariablyModifiedType())
68638032Speter      OS << " variably_modified";
68738032Speter    if (T->containsUnexpandedParameterPack())
68838032Speter      OS << " contains_unexpanded_pack";
68938032Speter    if (T->isFromAST())
69038032Speter      OS << " imported";
69138032Speter
69238032Speter    TypeVisitor<ASTDumper>::Visit(T);
69338032Speter
69438032Speter    if (SingleStepDesugar != QualType(T, 0))
69538032Speter      dumpTypeAsChild(SingleStepDesugar);
69638032Speter  });
69738032Speter}
69838032Speter
69938032Spetervoid ASTDumper::dumpBareDeclRef(const Decl *D) {
70038032Speter  {
70138032Speter    ColorScope Color(*this, DeclKindNameColor);
70238032Speter    OS << D->getDeclKindName();
70338032Speter  }
70438032Speter  dumpPointer(D);
70538032Speter
70638032Speter  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
70738032Speter    ColorScope Color(*this, DeclNameColor);
70838032Speter    OS << " '" << ND->getDeclName() << '\'';
70938032Speter  }
71038032Speter
71138032Speter  if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
71238032Speter    dumpType(VD->getType());
71338032Speter}
71438032Speter
71538032Spetervoid ASTDumper::dumpDeclRef(const Decl *D, const char *Label) {
71638032Speter  if (!D)
71738032Speter    return;
71838032Speter
71938032Speter  dumpChild([=]{
72038032Speter    if (Label)
72138032Speter      OS << Label << ' ';
72238032Speter    dumpBareDeclRef(D);
72338032Speter  });
72438032Speter}
72538032Speter
72638032Spetervoid ASTDumper::dumpName(const NamedDecl *ND) {
72738032Speter  if (ND->getDeclName()) {
72838032Speter    ColorScope Color(*this, DeclNameColor);
72938032Speter    OS << ' ' << ND->getNameAsString();
73038032Speter  }
73138032Speter}
73238032Speter
73338032Speterbool ASTDumper::hasNodes(const DeclContext *DC) {
73438032Speter  if (!DC)
73538032Speter    return false;
73638032Speter
73738032Speter  return DC->hasExternalLexicalStorage() ||
73838032Speter         DC->noload_decls_begin() != DC->noload_decls_end();
73938032Speter}
74038032Speter
74138032Spetervoid ASTDumper::dumpDeclContext(const DeclContext *DC) {
74238032Speter  if (!DC)
74338032Speter    return;
74438032Speter
74538032Speter  for (auto *D : DC->noload_decls())
74638032Speter    dumpDecl(D);
74738032Speter
74838032Speter  if (DC->hasExternalLexicalStorage()) {
74938032Speter    dumpChild([=]{
75038032Speter      ColorScope Color(*this, UndeserializedColor);
75138032Speter      OS << "<undeserialized declarations>";
75238032Speter    });
75338032Speter  }
75438032Speter}
75538032Speter
75638032Spetervoid ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
75738032Speter  dumpChild([=] {
75838032Speter    OS << "StoredDeclsMap ";
75938032Speter    dumpBareDeclRef(cast<Decl>(DC));
76038032Speter
76138032Speter    const DeclContext *Primary = DC->getPrimaryContext();
76238032Speter    if (Primary != DC) {
76338032Speter      OS << " primary";
76438032Speter      dumpPointer(cast<Decl>(Primary));
76538032Speter    }
76638032Speter
76738032Speter    bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage();
76838032Speter
76938032Speter    DeclContext::all_lookups_iterator I = Primary->noload_lookups_begin(),
77038032Speter                                      E = Primary->noload_lookups_end();
77138032Speter    while (I != E) {
77238032Speter      DeclarationName Name = I.getLookupName();
77338032Speter      DeclContextLookupResult R = *I++;
77438032Speter
77538032Speter      dumpChild([=] {
77638032Speter        OS << "DeclarationName ";
77738032Speter        {
77838032Speter          ColorScope Color(*this, DeclNameColor);
77938032Speter          OS << '\'' << Name << '\'';
78038032Speter        }
78138032Speter
78238032Speter        for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end();
78338032Speter             RI != RE; ++RI) {
78438032Speter          dumpChild([=] {
78538032Speter            dumpBareDeclRef(*RI);
78638032Speter
78738032Speter            if ((*RI)->isHidden())
78838032Speter              OS << " hidden";
78938032Speter
79038032Speter            // If requested, dump the redecl chain for this lookup.
79138032Speter            if (DumpDecls) {
79238032Speter              // Dump earliest decl first.
79338032Speter              std::function<void(Decl *)> DumpWithPrev = [&](Decl *D) {
79438032Speter                if (Decl *Prev = D->getPreviousDecl())
79538032Speter                  DumpWithPrev(Prev);
79638032Speter                dumpDecl(D);
79738032Speter              };
79838032Speter              DumpWithPrev(*RI);
79938032Speter            }
80038032Speter          });
80138032Speter        }
80238032Speter      });
80338032Speter    }
80438032Speter
80538032Speter    if (HasUndeserializedLookups) {
80638032Speter      dumpChild([=] {
80738032Speter        ColorScope Color(*this, UndeserializedColor);
80838032Speter        OS << "<undeserialized lookups>";
80938032Speter      });
81038032Speter    }
81138032Speter  });
81238032Speter}
81338032Speter
81438032Spetervoid ASTDumper::dumpAttr(const Attr *A) {
81538032Speter  dumpChild([=] {
81638032Speter    {
81738032Speter      ColorScope Color(*this, AttrColor);
81838032Speter
81938032Speter      switch (A->getKind()) {
82038032Speter#define ATTR(X) case attr::X: OS << #X; break;
82138032Speter#include "clang/Basic/AttrList.inc"
82238032Speter      default:
82338032Speter        llvm_unreachable("unexpected attribute kind");
82438032Speter      }
82538032Speter      OS << "Attr";
82638032Speter    }
82738032Speter    dumpPointer(A);
82838032Speter    dumpSourceRange(A->getRange());
82938032Speter    if (A->isInherited())
83038032Speter      OS << " Inherited";
83138032Speter    if (A->isImplicit())
83238032Speter      OS << " Implicit";
83338032Speter#include "clang/AST/AttrDump.inc"
83438032Speter  });
83538032Speter}
83638032Speter
83738032Speterstatic void dumpPreviousDeclImpl(raw_ostream &OS, ...) {}
83838032Speter
83938032Spetertemplate<typename T>
84038032Speterstatic void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) {
84138032Speter  const T *First = D->getFirstDecl();
84238032Speter  if (First != D)
84338032Speter    OS << " first " << First;
84438032Speter}
84538032Speter
84638032Spetertemplate<typename T>
84738032Speterstatic void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
84838032Speter  const T *Prev = D->getPreviousDecl();
84938032Speter  if (Prev)
85038032Speter    OS << " prev " << Prev;
85138032Speter}
85238032Speter
85338032Speter/// Dump the previous declaration in the redeclaration chain for a declaration,
85438032Speter/// if any.
85538032Speterstatic void dumpPreviousDecl(raw_ostream &OS, const Decl *D) {
85638032Speter  switch (D->getKind()) {
85738032Speter#define DECL(DERIVED, BASE) \
85838032Speter  case Decl::DERIVED: \
85938032Speter    return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D));
86038032Speter#define ABSTRACT_DECL(DECL)
86138032Speter#include "clang/AST/DeclNodes.inc"
86238032Speter  }
86338032Speter  llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
86438032Speter}
86538032Speter
86638032Speter//===----------------------------------------------------------------------===//
86738032Speter//  C++ Utilities
86838032Speter//===----------------------------------------------------------------------===//
86938032Speter
87038032Spetervoid ASTDumper::dumpAccessSpecifier(AccessSpecifier AS) {
87138032Speter  switch (AS) {
87238032Speter  case AS_none:
87338032Speter    break;
87438032Speter  case AS_public:
87538032Speter    OS << "public";
87638032Speter    break;
87738032Speter  case AS_protected:
87838032Speter    OS << "protected";
87938032Speter    break;
88038032Speter  case AS_private:
88138032Speter    OS << "private";
88238032Speter    break;
88338032Speter  }
88438032Speter}
88538032Speter
88638032Spetervoid ASTDumper::dumpCXXCtorInitializer(const CXXCtorInitializer *Init) {
88738032Speter  dumpChild([=] {
88838032Speter    OS << "CXXCtorInitializer";
88938032Speter    if (Init->isAnyMemberInitializer()) {
89038032Speter      OS << ' ';
89138032Speter      dumpBareDeclRef(Init->getAnyMember());
89238032Speter    } else if (Init->isBaseInitializer()) {
89338032Speter      dumpType(QualType(Init->getBaseClass(), 0));
89438032Speter    } else if (Init->isDelegatingInitializer()) {
89538032Speter      dumpType(Init->getTypeSourceInfo()->getType());
89638032Speter    } else {
89738032Speter      llvm_unreachable("Unknown initializer type");
89838032Speter    }
89938032Speter    dumpStmt(Init->getInit());
90038032Speter  });
90138032Speter}
90238032Speter
90338032Spetervoid ASTDumper::dumpTemplateParameters(const TemplateParameterList *TPL) {
90438032Speter  if (!TPL)
90538032Speter    return;
90638032Speter
90738032Speter  for (TemplateParameterList::const_iterator I = TPL->begin(), E = TPL->end();
90838032Speter       I != E; ++I)
90938032Speter    dumpDecl(*I);
91038032Speter}
91138032Speter
91238032Spetervoid ASTDumper::dumpTemplateArgumentListInfo(
91338032Speter    const TemplateArgumentListInfo &TALI) {
91438032Speter  for (unsigned i = 0, e = TALI.size(); i < e; ++i)
91538032Speter    dumpTemplateArgumentLoc(TALI[i]);
91638032Speter}
91738032Speter
91838032Spetervoid ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A) {
91938032Speter  dumpTemplateArgument(A.getArgument(), A.getSourceRange());
92038032Speter}
92138032Speter
92238032Spetervoid ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) {
92338032Speter  for (unsigned i = 0, e = TAL.size(); i < e; ++i)
92438032Speter    dumpTemplateArgument(TAL[i]);
92538032Speter}
92638032Speter
92738032Spetervoid ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R) {
92838032Speter  dumpChild([=] {
92938032Speter    OS << "TemplateArgument";
93038032Speter    if (R.isValid())
93138032Speter      dumpSourceRange(R);
93238032Speter
93338032Speter    switch (A.getKind()) {
93438032Speter    case TemplateArgument::Null:
93538032Speter      OS << " null";
93638032Speter      break;
93738032Speter    case TemplateArgument::Type:
93838032Speter      OS << " type";
93938032Speter      dumpType(A.getAsType());
94038032Speter      break;
94138032Speter    case TemplateArgument::Declaration:
94238032Speter      OS << " decl";
94338032Speter      dumpDeclRef(A.getAsDecl());
94438032Speter      break;
94538032Speter    case TemplateArgument::NullPtr:
94638032Speter      OS << " nullptr";
94738032Speter      break;
94838032Speter    case TemplateArgument::Integral:
94938032Speter      OS << " integral " << A.getAsIntegral();
95038032Speter      break;
95138032Speter    case TemplateArgument::Template:
95238032Speter      OS << " template ";
95338032Speter      A.getAsTemplate().dump(OS);
95438032Speter      break;
95538032Speter    case TemplateArgument::TemplateExpansion:
95638032Speter      OS << " template expansion";
95738032Speter      A.getAsTemplateOrTemplatePattern().dump(OS);
95838032Speter      break;
95938032Speter    case TemplateArgument::Expression:
96038032Speter      OS << " expr";
96138032Speter      dumpStmt(A.getAsExpr());
96238032Speter      break;
96338032Speter    case TemplateArgument::Pack:
96438032Speter      OS << " pack";
96538032Speter      for (TemplateArgument::pack_iterator I = A.pack_begin(), E = A.pack_end();
96638032Speter           I != E; ++I)
96738032Speter        dumpTemplateArgument(*I);
96838032Speter      break;
96938032Speter    }
97038032Speter  });
97138032Speter}
97238032Speter
97338032Speter//===----------------------------------------------------------------------===//
97438032Speter//  Objective-C Utilities
97538032Speter//===----------------------------------------------------------------------===//
97638032Spetervoid ASTDumper::dumpObjCTypeParamList(const ObjCTypeParamList *typeParams) {
97738032Speter  if (!typeParams)
97838032Speter    return;
97938032Speter
98038032Speter  for (auto typeParam : *typeParams) {
98138032Speter    dumpDecl(typeParam);
98238032Speter  }
98338032Speter}
98438032Speter
98538032Speter//===----------------------------------------------------------------------===//
98638032Speter//  Decl dumping methods.
98738032Speter//===----------------------------------------------------------------------===//
98838032Speter
98938032Spetervoid ASTDumper::dumpDecl(const Decl *D) {
99038032Speter  dumpChild([=] {
99138032Speter    if (!D) {
99238032Speter      ColorScope Color(*this, NullColor);
99338032Speter      OS << "<<<NULL>>>";
99438032Speter      return;
99538032Speter    }
99638032Speter
99738032Speter    {
99838032Speter      ColorScope Color(*this, DeclKindNameColor);
99938032Speter      OS << D->getDeclKindName() << "Decl";
100038032Speter    }
100138032Speter    dumpPointer(D);
100238032Speter    if (D->getLexicalDeclContext() != D->getDeclContext())
100338032Speter      OS << " parent " << cast<Decl>(D->getDeclContext());
100438032Speter    dumpPreviousDecl(OS, D);
100538032Speter    dumpSourceRange(D->getSourceRange());
100638032Speter    OS << ' ';
100738032Speter    dumpLocation(D->getLocation());
100838032Speter    if (Module *M = D->getImportedOwningModule())
100938032Speter      OS << " in " << M->getFullModuleName();
101038032Speter    else if (Module *M = D->getLocalOwningModule())
101138032Speter      OS << " in (local) " << M->getFullModuleName();
101238032Speter    if (auto *ND = dyn_cast<NamedDecl>(D))
101338032Speter      for (Module *M : D->getASTContext().getModulesWithMergedDefinition(
101438032Speter               const_cast<NamedDecl *>(ND)))
101538032Speter        dumpChild([=] { OS << "also in " << M->getFullModuleName(); });
101638032Speter    if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
101738032Speter      if (ND->isHidden())
101838032Speter        OS << " hidden";
101938032Speter    if (D->isImplicit())
102038032Speter      OS << " implicit";
102138032Speter    if (D->isUsed())
102238032Speter      OS << " used";
102338032Speter    else if (D->isThisDeclarationReferenced())
102438032Speter      OS << " referenced";
102538032Speter    if (D->isInvalidDecl())
102638032Speter      OS << " invalid";
102738032Speter    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
102838032Speter      if (FD->isConstexpr())
102938032Speter        OS << " constexpr";
103038032Speter
103138032Speter
103238032Speter    ConstDeclVisitor<ASTDumper>::Visit(D);
103338032Speter
103438032Speter    for (Decl::attr_iterator I = D->attr_begin(), E = D->attr_end(); I != E;
103538032Speter         ++I)
103638032Speter      dumpAttr(*I);
103738032Speter
103838032Speter    if (const FullComment *Comment =
103938032Speter            D->getASTContext().getLocalCommentForDeclUncached(D))
104038032Speter      dumpFullComment(Comment);
104138032Speter
104238032Speter    // Decls within functions are visited by the body.
104338032Speter    if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D) &&
104438032Speter        hasNodes(dyn_cast<DeclContext>(D)))
104538032Speter      dumpDeclContext(cast<DeclContext>(D));
104638032Speter  });
104738032Speter}
104838032Speter
104938032Spetervoid ASTDumper::VisitLabelDecl(const LabelDecl *D) {
105038032Speter  dumpName(D);
105138032Speter}
105238032Speter
105338032Spetervoid ASTDumper::VisitTypedefDecl(const TypedefDecl *D) {
105438032Speter  dumpName(D);
105538032Speter  dumpType(D->getUnderlyingType());
105638032Speter  if (D->isModulePrivate())
105738032Speter    OS << " __module_private__";
105838032Speter  dumpTypeAsChild(D->getUnderlyingType());
105938032Speter}
106038032Speter
106138032Spetervoid ASTDumper::VisitEnumDecl(const EnumDecl *D) {
106238032Speter  if (D->isScoped()) {
106338032Speter    if (D->isScopedUsingClassTag())
106438032Speter      OS << " class";
106538032Speter    else
106638032Speter      OS << " struct";
106738032Speter  }
106838032Speter  dumpName(D);
106938032Speter  if (D->isModulePrivate())
107038032Speter    OS << " __module_private__";
107138032Speter  if (D->isFixed())
107238032Speter    dumpType(D->getIntegerType());
107338032Speter}
107438032Speter
107538032Spetervoid ASTDumper::VisitRecordDecl(const RecordDecl *D) {
107638032Speter  OS << ' ' << D->getKindName();
107738032Speter  dumpName(D);
107838032Speter  if (D->isModulePrivate())
107938032Speter    OS << " __module_private__";
108038032Speter  if (D->isCompleteDefinition())
108138032Speter    OS << " definition";
108238032Speter}
108338032Speter
108438032Spetervoid ASTDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
108538032Speter  dumpName(D);
108638032Speter  dumpType(D->getType());
108738032Speter  if (const Expr *Init = D->getInitExpr())
108838032Speter    dumpStmt(Init);
108938032Speter}
109038032Speter
109138032Spetervoid ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
109238032Speter  dumpName(D);
109338032Speter  dumpType(D->getType());
109438032Speter
109538032Speter  for (auto *Child : D->chain())
109638032Speter    dumpDeclRef(Child);
109738032Speter}
109838032Speter
109938032Spetervoid ASTDumper::VisitFunctionDecl(const FunctionDecl *D) {
110038032Speter  dumpName(D);
110138032Speter  dumpType(D->getType());
110238032Speter
110338032Speter  StorageClass SC = D->getStorageClass();
110438032Speter  if (SC != SC_None)
110538032Speter    OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
110638032Speter  if (D->isInlineSpecified())
110738032Speter    OS << " inline";
110838032Speter  if (D->isVirtualAsWritten())
110938032Speter    OS << " virtual";
111038032Speter  if (D->isModulePrivate())
111138032Speter    OS << " __module_private__";
111238032Speter
111338032Speter  if (D->isPure())
111438032Speter    OS << " pure";
111538032Speter  else if (D->isDeletedAsWritten())
111638032Speter    OS << " delete";
111738032Speter
111838032Speter  if (const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>()) {
111938032Speter    FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
112038032Speter    switch (EPI.ExceptionSpec.Type) {
112138032Speter    default: break;
112238032Speter    case EST_Unevaluated:
112338032Speter      OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl;
112438032Speter      break;
112538032Speter    case EST_Uninstantiated:
112638032Speter      OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate;
112738032Speter      break;
112838032Speter    }
112938032Speter  }
113038032Speter
113138032Speter  if (const FunctionTemplateSpecializationInfo *FTSI =
113238032Speter          D->getTemplateSpecializationInfo())
113338032Speter    dumpTemplateArgumentList(*FTSI->TemplateArguments);
113438032Speter
113538032Speter  for (ArrayRef<NamedDecl *>::iterator
113638032Speter       I = D->getDeclsInPrototypeScope().begin(),
113738032Speter       E = D->getDeclsInPrototypeScope().end(); I != E; ++I)
113838032Speter    dumpDecl(*I);
113938032Speter
114038032Speter  if (!D->param_begin() && D->getNumParams())
114138032Speter    dumpChild([=] { OS << "<<NULL params x " << D->getNumParams() << ">>"; });
114238032Speter  else
114338032Speter    for (FunctionDecl::param_const_iterator I = D->param_begin(),
114438032Speter                                            E = D->param_end();
114538032Speter         I != E; ++I)
114638032Speter      dumpDecl(*I);
114738032Speter
114838032Speter  if (const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(D))
114938032Speter    for (CXXConstructorDecl::init_const_iterator I = C->init_begin(),
115038032Speter                                                 E = C->init_end();
115138032Speter         I != E; ++I)
115238032Speter      dumpCXXCtorInitializer(*I);
115338032Speter
115438032Speter  if (D->doesThisDeclarationHaveABody())
115538032Speter    dumpStmt(D->getBody());
115638032Speter}
115738032Speter
115838032Spetervoid ASTDumper::VisitFieldDecl(const FieldDecl *D) {
115938032Speter  dumpName(D);
116038032Speter  dumpType(D->getType());
116138032Speter  if (D->isMutable())
116238032Speter    OS << " mutable";
116338032Speter  if (D->isModulePrivate())
116438032Speter    OS << " __module_private__";
116538032Speter
116638032Speter  if (D->isBitField())
116738032Speter    dumpStmt(D->getBitWidth());
116838032Speter  if (Expr *Init = D->getInClassInitializer())
116938032Speter    dumpStmt(Init);
117038032Speter}
117138032Speter
117238032Spetervoid ASTDumper::VisitVarDecl(const VarDecl *D) {
117338032Speter  dumpName(D);
117438032Speter  dumpType(D->getType());
117538032Speter  StorageClass SC = D->getStorageClass();
117638032Speter  if (SC != SC_None)
117738032Speter    OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
117838032Speter  switch (D->getTLSKind()) {
117938032Speter  case VarDecl::TLS_None: break;
118038032Speter  case VarDecl::TLS_Static: OS << " tls"; break;
118138032Speter  case VarDecl::TLS_Dynamic: OS << " tls_dynamic"; break;
118238032Speter  }
118338032Speter  if (D->isModulePrivate())
118438032Speter    OS << " __module_private__";
118538032Speter  if (D->isNRVOVariable())
118638032Speter    OS << " nrvo";
118738032Speter  if (D->hasInit()) {
118838032Speter    switch (D->getInitStyle()) {
118938032Speter    case VarDecl::CInit: OS << " cinit"; break;
119038032Speter    case VarDecl::CallInit: OS << " callinit"; break;
119138032Speter    case VarDecl::ListInit: OS << " listinit"; break;
119238032Speter    }
119338032Speter    dumpStmt(D->getInit());
119438032Speter  }
119538032Speter}
119638032Speter
119738032Spetervoid ASTDumper::VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) {
119838032Speter  dumpStmt(D->getAsmString());
119938032Speter}
120038032Speter
120138032Spetervoid ASTDumper::VisitImportDecl(const ImportDecl *D) {
120238032Speter  OS << ' ' << D->getImportedModule()->getFullModuleName();
120338032Speter}
120438032Speter
120538032Speter//===----------------------------------------------------------------------===//
120638032Speter// C++ Declarations
120738032Speter//===----------------------------------------------------------------------===//
120838032Speter
120938032Spetervoid ASTDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
121038032Speter  dumpName(D);
121138032Speter  if (D->isInline())
121238032Speter    OS << " inline";
121338032Speter  if (!D->isOriginalNamespace())
121438032Speter    dumpDeclRef(D->getOriginalNamespace(), "original");
121538032Speter}
121638032Speter
121738032Spetervoid ASTDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
121838032Speter  OS << ' ';
121938032Speter  dumpBareDeclRef(D->getNominatedNamespace());
122038032Speter}
122138032Speter
122238032Spetervoid ASTDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
122338032Speter  dumpName(D);
122438032Speter  dumpDeclRef(D->getAliasedNamespace());
122538032Speter}
122638032Speter
122738032Spetervoid ASTDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
122838032Speter  dumpName(D);
122938032Speter  dumpType(D->getUnderlyingType());
123038032Speter  dumpTypeAsChild(D->getUnderlyingType());
123138032Speter}
123238032Speter
123338032Spetervoid ASTDumper::VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {
123438032Speter  dumpName(D);
123538032Speter  dumpTemplateParameters(D->getTemplateParameters());
123638032Speter  dumpDecl(D->getTemplatedDecl());
123738032Speter}
123838032Speter
123938032Spetervoid ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
124038032Speter  VisitRecordDecl(D);
124138032Speter  if (!D->isCompleteDefinition())
124238032Speter    return;
124338032Speter
124438032Speter  for (const auto &I : D->bases()) {
124538032Speter    dumpChild([=] {
124638032Speter      if (I.isVirtual())
124738032Speter        OS << "virtual ";
124838032Speter      dumpAccessSpecifier(I.getAccessSpecifier());
124938032Speter      dumpType(I.getType());
125038032Speter      if (I.isPackExpansion())
125138032Speter        OS << "...";
125238032Speter    });
125338032Speter  }
125438032Speter}
125538032Speter
125638032Spetervoid ASTDumper::VisitStaticAssertDecl(const StaticAssertDecl *D) {
125738032Speter  dumpStmt(D->getAssertExpr());
125838032Speter  dumpStmt(D->getMessage());
125938032Speter}
126038032Speter
126138032Spetertemplate<typename SpecializationDecl>
126238032Spetervoid ASTDumper::VisitTemplateDeclSpecialization(const SpecializationDecl *D,
126338032Speter                                                bool DumpExplicitInst,
126438032Speter                                                bool DumpRefOnly) {
126538032Speter  bool DumpedAny = false;
126638032Speter  for (auto *RedeclWithBadType : D->redecls()) {
126738032Speter    // FIXME: The redecls() range sometimes has elements of a less-specific
126838032Speter    // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
126938032Speter    // us TagDecls, and should give CXXRecordDecls).
127038032Speter    auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
127138032Speter    if (!Redecl) {
127238032Speter      // Found the injected-class-name for a class template. This will be dumped
127338032Speter      // as part of its surrounding class so we don't need to dump it here.
127438032Speter      assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
127538032Speter             "expected an injected-class-name");
127638032Speter      continue;
127738032Speter    }
127838032Speter
127938032Speter    switch (Redecl->getTemplateSpecializationKind()) {
128038032Speter    case TSK_ExplicitInstantiationDeclaration:
128138032Speter    case TSK_ExplicitInstantiationDefinition:
128238032Speter      if (!DumpExplicitInst)
128338032Speter        break;
128438032Speter      // Fall through.
128538032Speter    case TSK_Undeclared:
128638032Speter    case TSK_ImplicitInstantiation:
128738032Speter      if (DumpRefOnly)
128838032Speter        dumpDeclRef(Redecl);
128938032Speter      else
129038032Speter        dumpDecl(Redecl);
129138032Speter      DumpedAny = true;
129238032Speter      break;
129338032Speter    case TSK_ExplicitSpecialization:
129438032Speter      break;
129538032Speter    }
129638032Speter  }
129738032Speter
129838032Speter  // Ensure we dump at least one decl for each specialization.
129938032Speter  if (!DumpedAny)
130038032Speter    dumpDeclRef(D);
130138032Speter}
130238032Speter
130338032Spetertemplate<typename TemplateDecl>
130438032Spetervoid ASTDumper::VisitTemplateDecl(const TemplateDecl *D,
130538032Speter                                  bool DumpExplicitInst) {
130638032Speter  dumpName(D);
130738032Speter  dumpTemplateParameters(D->getTemplateParameters());
130838032Speter
130938032Speter  dumpDecl(D->getTemplatedDecl());
131038032Speter
131138032Speter  for (auto *Child : D->specializations())
131238032Speter    VisitTemplateDeclSpecialization(Child, DumpExplicitInst,
131338032Speter                                    !D->isCanonicalDecl());
131438032Speter}
131538032Speter
131638032Spetervoid ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
131738032Speter  // FIXME: We don't add a declaration of a function template specialization
131838032Speter  // to its context when it's explicitly instantiated, so dump explicit
131938032Speter  // instantiations when we dump the template itself.
132038032Speter  VisitTemplateDecl(D, true);
132138032Speter}
132238032Speter
132338032Spetervoid ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
132438032Speter  VisitTemplateDecl(D, false);
132538032Speter}
132638032Speter
132738032Spetervoid ASTDumper::VisitClassTemplateSpecializationDecl(
132838032Speter    const ClassTemplateSpecializationDecl *D) {
132938032Speter  VisitCXXRecordDecl(D);
133038032Speter  dumpTemplateArgumentList(D->getTemplateArgs());
133138032Speter}
133238032Speter
133338032Spetervoid ASTDumper::VisitClassTemplatePartialSpecializationDecl(
133438032Speter    const ClassTemplatePartialSpecializationDecl *D) {
133538032Speter  VisitClassTemplateSpecializationDecl(D);
133638032Speter  dumpTemplateParameters(D->getTemplateParameters());
133738032Speter}
133838032Speter
133938032Spetervoid ASTDumper::VisitClassScopeFunctionSpecializationDecl(
134038032Speter    const ClassScopeFunctionSpecializationDecl *D) {
134138032Speter  dumpDeclRef(D->getSpecialization());
134238032Speter  if (D->hasExplicitTemplateArgs())
134338032Speter    dumpTemplateArgumentListInfo(D->templateArgs());
134438032Speter}
134538032Speter
134638032Spetervoid ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
134738032Speter  VisitTemplateDecl(D, false);
134838032Speter}
134938032Speter
135038032Spetervoid ASTDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
135138032Speter  dumpName(D);
135238032Speter  dumpTemplateParameters(D->getTemplateParameters());
135338032Speter}
135438032Speter
135538032Spetervoid ASTDumper::VisitVarTemplateSpecializationDecl(
135638032Speter    const VarTemplateSpecializationDecl *D) {
135738032Speter  dumpTemplateArgumentList(D->getTemplateArgs());
135838032Speter  VisitVarDecl(D);
135938032Speter}
136038032Speter
136138032Spetervoid ASTDumper::VisitVarTemplatePartialSpecializationDecl(
136238032Speter    const VarTemplatePartialSpecializationDecl *D) {
136338032Speter  dumpTemplateParameters(D->getTemplateParameters());
136438032Speter  VisitVarTemplateSpecializationDecl(D);
136538032Speter}
136638032Speter
136738032Spetervoid ASTDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
136838032Speter  if (D->wasDeclaredWithTypename())
136938032Speter    OS << " typename";
137038032Speter  else
137138032Speter    OS << " class";
137238032Speter  if (D->isParameterPack())
137338032Speter    OS << " ...";
137438032Speter  dumpName(D);
137538032Speter  if (D->hasDefaultArgument())
137638032Speter    dumpTemplateArgument(D->getDefaultArgument());
137738032Speter}
137838032Speter
137938032Spetervoid ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
138038032Speter  dumpType(D->getType());
138138032Speter  if (D->isParameterPack())
138238032Speter    OS << " ...";
138338032Speter  dumpName(D);
138438032Speter  if (D->hasDefaultArgument())
138538032Speter    dumpTemplateArgument(D->getDefaultArgument());
138638032Speter}
138738032Speter
138838032Spetervoid ASTDumper::VisitTemplateTemplateParmDecl(
138938032Speter    const TemplateTemplateParmDecl *D) {
139038032Speter  if (D->isParameterPack())
139138032Speter    OS << " ...";
139238032Speter  dumpName(D);
139338032Speter  dumpTemplateParameters(D->getTemplateParameters());
139438032Speter  if (D->hasDefaultArgument())
139538032Speter    dumpTemplateArgumentLoc(D->getDefaultArgument());
139638032Speter}
139738032Speter
139838032Spetervoid ASTDumper::VisitUsingDecl(const UsingDecl *D) {
139938032Speter  OS << ' ';
140038032Speter  if (D->getQualifier())
140138032Speter    D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
140238032Speter  OS << D->getNameAsString();
140338032Speter}
140438032Speter
140538032Spetervoid ASTDumper::VisitUnresolvedUsingTypenameDecl(
140638032Speter    const UnresolvedUsingTypenameDecl *D) {
140738032Speter  OS << ' ';
140838032Speter  if (D->getQualifier())
140938032Speter    D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
141038032Speter  OS << D->getNameAsString();
141138032Speter}
141238032Speter
141338032Spetervoid ASTDumper::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
141438032Speter  OS << ' ';
141538032Speter  if (D->getQualifier())
141638032Speter    D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
141738032Speter  OS << D->getNameAsString();
141838032Speter  dumpType(D->getType());
141938032Speter}
142038032Speter
142138032Spetervoid ASTDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
142238032Speter  OS << ' ';
142338032Speter  dumpBareDeclRef(D->getTargetDecl());
142438032Speter  if (auto *TD = dyn_cast<TypeDecl>(D->getUnderlyingDecl()))
142538032Speter    dumpTypeAsChild(TD->getTypeForDecl());
142638032Speter}
142738032Speter
142838032Spetervoid ASTDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
142938032Speter  switch (D->getLanguage()) {
143038032Speter  case LinkageSpecDecl::lang_c: OS << " C"; break;
143138032Speter  case LinkageSpecDecl::lang_cxx: OS << " C++"; break;
143238032Speter  }
143338032Speter}
143438032Speter
143538032Spetervoid ASTDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
143638032Speter  OS << ' ';
143738032Speter  dumpAccessSpecifier(D->getAccess());
143838032Speter}
143938032Speter
144038032Spetervoid ASTDumper::VisitFriendDecl(const FriendDecl *D) {
144138032Speter  if (TypeSourceInfo *T = D->getFriendType())
144238032Speter    dumpType(T->getType());
144338032Speter  else
144438032Speter    dumpDecl(D->getFriendDecl());
144538032Speter}
144638032Speter
144738032Speter//===----------------------------------------------------------------------===//
144838032Speter// Obj-C Declarations
144938032Speter//===----------------------------------------------------------------------===//
145038032Speter
145138032Spetervoid ASTDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
145238032Speter  dumpName(D);
145338032Speter  dumpType(D->getType());
145438032Speter  if (D->getSynthesize())
145538032Speter    OS << " synthesize";
145638032Speter
145738032Speter  switch (D->getAccessControl()) {
145838032Speter  case ObjCIvarDecl::None:
145938032Speter    OS << " none";
146038032Speter    break;
146138032Speter  case ObjCIvarDecl::Private:
146238032Speter    OS << " private";
146338032Speter    break;
146438032Speter  case ObjCIvarDecl::Protected:
146538032Speter    OS << " protected";
146638032Speter    break;
146738032Speter  case ObjCIvarDecl::Public:
146838032Speter    OS << " public";
146938032Speter    break;
147038032Speter  case ObjCIvarDecl::Package:
147138032Speter    OS << " package";
147238032Speter    break;
147338032Speter  }
147438032Speter}
147538032Speter
147638032Spetervoid ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
147738032Speter  if (D->isInstanceMethod())
147838032Speter    OS << " -";
147938032Speter  else
148038032Speter    OS << " +";
148138032Speter  dumpName(D);
148238032Speter  dumpType(D->getReturnType());
148338032Speter
148438032Speter  if (D->isThisDeclarationADefinition()) {
148538032Speter    dumpDeclContext(D);
148638032Speter  } else {
148738032Speter    for (ObjCMethodDecl::param_const_iterator I = D->param_begin(),
148838032Speter                                              E = D->param_end();
148938032Speter         I != E; ++I)
149038032Speter      dumpDecl(*I);
149138032Speter  }
149238032Speter
149338032Speter  if (D->isVariadic())
149438032Speter    dumpChild([=] { OS << "..."; });
149538032Speter
149638032Speter  if (D->hasBody())
149738032Speter    dumpStmt(D->getBody());
149838032Speter}
149938032Speter
150038032Spetervoid ASTDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) {
1501  dumpName(D);
1502  switch (D->getVariance()) {
1503  case ObjCTypeParamVariance::Invariant:
1504    break;
1505
1506  case ObjCTypeParamVariance::Covariant:
1507    OS << " covariant";
1508    break;
1509
1510  case ObjCTypeParamVariance::Contravariant:
1511    OS << " contravariant";
1512    break;
1513  }
1514
1515  if (D->hasExplicitBound())
1516    OS << " bounded";
1517  dumpType(D->getUnderlyingType());
1518}
1519
1520void ASTDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
1521  dumpName(D);
1522  dumpDeclRef(D->getClassInterface());
1523  dumpObjCTypeParamList(D->getTypeParamList());
1524  dumpDeclRef(D->getImplementation());
1525  for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(),
1526                                           E = D->protocol_end();
1527       I != E; ++I)
1528    dumpDeclRef(*I);
1529}
1530
1531void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
1532  dumpName(D);
1533  dumpDeclRef(D->getClassInterface());
1534  dumpDeclRef(D->getCategoryDecl());
1535}
1536
1537void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
1538  dumpName(D);
1539
1540  for (auto *Child : D->protocols())
1541    dumpDeclRef(Child);
1542}
1543
1544void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
1545  dumpName(D);
1546  dumpObjCTypeParamList(D->getTypeParamListAsWritten());
1547  dumpDeclRef(D->getSuperClass(), "super");
1548
1549  dumpDeclRef(D->getImplementation());
1550  for (auto *Child : D->protocols())
1551    dumpDeclRef(Child);
1552}
1553
1554void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
1555  dumpName(D);
1556  dumpDeclRef(D->getSuperClass(), "super");
1557  dumpDeclRef(D->getClassInterface());
1558  for (ObjCImplementationDecl::init_const_iterator I = D->init_begin(),
1559                                                   E = D->init_end();
1560       I != E; ++I)
1561    dumpCXXCtorInitializer(*I);
1562}
1563
1564void ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) {
1565  dumpName(D);
1566  dumpDeclRef(D->getClassInterface());
1567}
1568
1569void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
1570  dumpName(D);
1571  dumpType(D->getType());
1572
1573  if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
1574    OS << " required";
1575  else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
1576    OS << " optional";
1577
1578  ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes();
1579  if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) {
1580    if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly)
1581      OS << " readonly";
1582    if (Attrs & ObjCPropertyDecl::OBJC_PR_assign)
1583      OS << " assign";
1584    if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite)
1585      OS << " readwrite";
1586    if (Attrs & ObjCPropertyDecl::OBJC_PR_retain)
1587      OS << " retain";
1588    if (Attrs & ObjCPropertyDecl::OBJC_PR_copy)
1589      OS << " copy";
1590    if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic)
1591      OS << " nonatomic";
1592    if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic)
1593      OS << " atomic";
1594    if (Attrs & ObjCPropertyDecl::OBJC_PR_weak)
1595      OS << " weak";
1596    if (Attrs & ObjCPropertyDecl::OBJC_PR_strong)
1597      OS << " strong";
1598    if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained)
1599      OS << " unsafe_unretained";
1600    if (Attrs & ObjCPropertyDecl::OBJC_PR_getter)
1601      dumpDeclRef(D->getGetterMethodDecl(), "getter");
1602    if (Attrs & ObjCPropertyDecl::OBJC_PR_setter)
1603      dumpDeclRef(D->getSetterMethodDecl(), "setter");
1604  }
1605}
1606
1607void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
1608  dumpName(D->getPropertyDecl());
1609  if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
1610    OS << " synthesize";
1611  else
1612    OS << " dynamic";
1613  dumpDeclRef(D->getPropertyDecl());
1614  dumpDeclRef(D->getPropertyIvarDecl());
1615}
1616
1617void ASTDumper::VisitBlockDecl(const BlockDecl *D) {
1618  for (auto I : D->params())
1619    dumpDecl(I);
1620
1621  if (D->isVariadic())
1622    dumpChild([=]{ OS << "..."; });
1623
1624  if (D->capturesCXXThis())
1625    dumpChild([=]{ OS << "capture this"; });
1626
1627  for (const auto &I : D->captures()) {
1628    dumpChild([=] {
1629      OS << "capture";
1630      if (I.isByRef())
1631        OS << " byref";
1632      if (I.isNested())
1633        OS << " nested";
1634      if (I.getVariable()) {
1635        OS << ' ';
1636        dumpBareDeclRef(I.getVariable());
1637      }
1638      if (I.hasCopyExpr())
1639        dumpStmt(I.getCopyExpr());
1640    });
1641  }
1642  dumpStmt(D->getBody());
1643}
1644
1645//===----------------------------------------------------------------------===//
1646//  Stmt dumping methods.
1647//===----------------------------------------------------------------------===//
1648
1649void ASTDumper::dumpStmt(const Stmt *S) {
1650  dumpChild([=] {
1651    if (!S) {
1652      ColorScope Color(*this, NullColor);
1653      OS << "<<<NULL>>>";
1654      return;
1655    }
1656
1657    if (const DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
1658      VisitDeclStmt(DS);
1659      return;
1660    }
1661
1662    ConstStmtVisitor<ASTDumper>::Visit(S);
1663
1664    for (const Stmt *SubStmt : S->children())
1665      dumpStmt(SubStmt);
1666  });
1667}
1668
1669void ASTDumper::VisitStmt(const Stmt *Node) {
1670  {
1671    ColorScope Color(*this, StmtColor);
1672    OS << Node->getStmtClassName();
1673  }
1674  dumpPointer(Node);
1675  dumpSourceRange(Node->getSourceRange());
1676}
1677
1678void ASTDumper::VisitDeclStmt(const DeclStmt *Node) {
1679  VisitStmt(Node);
1680  for (DeclStmt::const_decl_iterator I = Node->decl_begin(),
1681                                     E = Node->decl_end();
1682       I != E; ++I)
1683    dumpDecl(*I);
1684}
1685
1686void ASTDumper::VisitAttributedStmt(const AttributedStmt *Node) {
1687  VisitStmt(Node);
1688  for (ArrayRef<const Attr *>::iterator I = Node->getAttrs().begin(),
1689                                        E = Node->getAttrs().end();
1690       I != E; ++I)
1691    dumpAttr(*I);
1692}
1693
1694void ASTDumper::VisitLabelStmt(const LabelStmt *Node) {
1695  VisitStmt(Node);
1696  OS << " '" << Node->getName() << "'";
1697}
1698
1699void ASTDumper::VisitGotoStmt(const GotoStmt *Node) {
1700  VisitStmt(Node);
1701  OS << " '" << Node->getLabel()->getName() << "'";
1702  dumpPointer(Node->getLabel());
1703}
1704
1705void ASTDumper::VisitCXXCatchStmt(const CXXCatchStmt *Node) {
1706  VisitStmt(Node);
1707  dumpDecl(Node->getExceptionDecl());
1708}
1709
1710//===----------------------------------------------------------------------===//
1711//  Expr dumping methods.
1712//===----------------------------------------------------------------------===//
1713
1714void ASTDumper::VisitExpr(const Expr *Node) {
1715  VisitStmt(Node);
1716  dumpType(Node->getType());
1717
1718  {
1719    ColorScope Color(*this, ValueKindColor);
1720    switch (Node->getValueKind()) {
1721    case VK_RValue:
1722      break;
1723    case VK_LValue:
1724      OS << " lvalue";
1725      break;
1726    case VK_XValue:
1727      OS << " xvalue";
1728      break;
1729    }
1730  }
1731
1732  {
1733    ColorScope Color(*this, ObjectKindColor);
1734    switch (Node->getObjectKind()) {
1735    case OK_Ordinary:
1736      break;
1737    case OK_BitField:
1738      OS << " bitfield";
1739      break;
1740    case OK_ObjCProperty:
1741      OS << " objcproperty";
1742      break;
1743    case OK_ObjCSubscript:
1744      OS << " objcsubscript";
1745      break;
1746    case OK_VectorComponent:
1747      OS << " vectorcomponent";
1748      break;
1749    }
1750  }
1751}
1752
1753static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
1754  if (Node->path_empty())
1755    return;
1756
1757  OS << " (";
1758  bool First = true;
1759  for (CastExpr::path_const_iterator I = Node->path_begin(),
1760                                     E = Node->path_end();
1761       I != E; ++I) {
1762    const CXXBaseSpecifier *Base = *I;
1763    if (!First)
1764      OS << " -> ";
1765
1766    const CXXRecordDecl *RD =
1767    cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
1768
1769    if (Base->isVirtual())
1770      OS << "virtual ";
1771    OS << RD->getName();
1772    First = false;
1773  }
1774
1775  OS << ')';
1776}
1777
1778void ASTDumper::VisitCastExpr(const CastExpr *Node) {
1779  VisitExpr(Node);
1780  OS << " <";
1781  {
1782    ColorScope Color(*this, CastColor);
1783    OS << Node->getCastKindName();
1784  }
1785  dumpBasePath(OS, Node);
1786  OS << ">";
1787}
1788
1789void ASTDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
1790  VisitExpr(Node);
1791
1792  OS << " ";
1793  dumpBareDeclRef(Node->getDecl());
1794  if (Node->getDecl() != Node->getFoundDecl()) {
1795    OS << " (";
1796    dumpBareDeclRef(Node->getFoundDecl());
1797    OS << ")";
1798  }
1799}
1800
1801void ASTDumper::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node) {
1802  VisitExpr(Node);
1803  OS << " (";
1804  if (!Node->requiresADL())
1805    OS << "no ";
1806  OS << "ADL) = '" << Node->getName() << '\'';
1807
1808  UnresolvedLookupExpr::decls_iterator
1809    I = Node->decls_begin(), E = Node->decls_end();
1810  if (I == E)
1811    OS << " empty";
1812  for (; I != E; ++I)
1813    dumpPointer(*I);
1814}
1815
1816void ASTDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) {
1817  VisitExpr(Node);
1818
1819  {
1820    ColorScope Color(*this, DeclKindNameColor);
1821    OS << " " << Node->getDecl()->getDeclKindName() << "Decl";
1822  }
1823  OS << "='" << *Node->getDecl() << "'";
1824  dumpPointer(Node->getDecl());
1825  if (Node->isFreeIvar())
1826    OS << " isFreeIvar";
1827}
1828
1829void ASTDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
1830  VisitExpr(Node);
1831  OS << " " << PredefinedExpr::getIdentTypeName(Node->getIdentType());
1832}
1833
1834void ASTDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
1835  VisitExpr(Node);
1836  ColorScope Color(*this, ValueColor);
1837  OS << " " << Node->getValue();
1838}
1839
1840void ASTDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
1841  VisitExpr(Node);
1842
1843  bool isSigned = Node->getType()->isSignedIntegerType();
1844  ColorScope Color(*this, ValueColor);
1845  OS << " " << Node->getValue().toString(10, isSigned);
1846}
1847
1848void ASTDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
1849  VisitExpr(Node);
1850  ColorScope Color(*this, ValueColor);
1851  OS << " " << Node->getValueAsApproximateDouble();
1852}
1853
1854void ASTDumper::VisitStringLiteral(const StringLiteral *Str) {
1855  VisitExpr(Str);
1856  ColorScope Color(*this, ValueColor);
1857  OS << " ";
1858  Str->outputString(OS);
1859}
1860
1861void ASTDumper::VisitInitListExpr(const InitListExpr *ILE) {
1862  VisitExpr(ILE);
1863  if (auto *Filler = ILE->getArrayFiller()) {
1864    dumpChild([=] {
1865      OS << "array filler";
1866      dumpStmt(Filler);
1867    });
1868  }
1869  if (auto *Field = ILE->getInitializedFieldInUnion()) {
1870    OS << " field ";
1871    dumpBareDeclRef(Field);
1872  }
1873}
1874
1875void ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) {
1876  VisitExpr(Node);
1877  OS << " " << (Node->isPostfix() ? "postfix" : "prefix")
1878     << " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1879}
1880
1881void ASTDumper::VisitUnaryExprOrTypeTraitExpr(
1882    const UnaryExprOrTypeTraitExpr *Node) {
1883  VisitExpr(Node);
1884  switch(Node->getKind()) {
1885  case UETT_SizeOf:
1886    OS << " sizeof";
1887    break;
1888  case UETT_AlignOf:
1889    OS << " alignof";
1890    break;
1891  case UETT_VecStep:
1892    OS << " vec_step";
1893    break;
1894  case UETT_OpenMPRequiredSimdAlign:
1895    OS << " __builtin_omp_required_simd_align";
1896    break;
1897  }
1898  if (Node->isArgumentType())
1899    dumpType(Node->getArgumentType());
1900}
1901
1902void ASTDumper::VisitMemberExpr(const MemberExpr *Node) {
1903  VisitExpr(Node);
1904  OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
1905  dumpPointer(Node->getMemberDecl());
1906}
1907
1908void ASTDumper::VisitExtVectorElementExpr(const ExtVectorElementExpr *Node) {
1909  VisitExpr(Node);
1910  OS << " " << Node->getAccessor().getNameStart();
1911}
1912
1913void ASTDumper::VisitBinaryOperator(const BinaryOperator *Node) {
1914  VisitExpr(Node);
1915  OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
1916}
1917
1918void ASTDumper::VisitCompoundAssignOperator(
1919    const CompoundAssignOperator *Node) {
1920  VisitExpr(Node);
1921  OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
1922     << "' ComputeLHSTy=";
1923  dumpBareType(Node->getComputationLHSType());
1924  OS << " ComputeResultTy=";
1925  dumpBareType(Node->getComputationResultType());
1926}
1927
1928void ASTDumper::VisitBlockExpr(const BlockExpr *Node) {
1929  VisitExpr(Node);
1930  dumpDecl(Node->getBlockDecl());
1931}
1932
1933void ASTDumper::VisitOpaqueValueExpr(const OpaqueValueExpr *Node) {
1934  VisitExpr(Node);
1935
1936  if (Expr *Source = Node->getSourceExpr())
1937    dumpStmt(Source);
1938}
1939
1940// GNU extensions.
1941
1942void ASTDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
1943  VisitExpr(Node);
1944  OS << " " << Node->getLabel()->getName();
1945  dumpPointer(Node->getLabel());
1946}
1947
1948//===----------------------------------------------------------------------===//
1949// C++ Expressions
1950//===----------------------------------------------------------------------===//
1951
1952void ASTDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) {
1953  VisitExpr(Node);
1954  OS << " " << Node->getCastName()
1955     << "<" << Node->getTypeAsWritten().getAsString() << ">"
1956     << " <" << Node->getCastKindName();
1957  dumpBasePath(OS, Node);
1958  OS << ">";
1959}
1960
1961void ASTDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
1962  VisitExpr(Node);
1963  OS << " " << (Node->getValue() ? "true" : "false");
1964}
1965
1966void ASTDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
1967  VisitExpr(Node);
1968  OS << " this";
1969}
1970
1971void ASTDumper::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node) {
1972  VisitExpr(Node);
1973  OS << " functional cast to " << Node->getTypeAsWritten().getAsString()
1974     << " <" << Node->getCastKindName() << ">";
1975}
1976
1977void ASTDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
1978  VisitExpr(Node);
1979  CXXConstructorDecl *Ctor = Node->getConstructor();
1980  dumpType(Ctor->getType());
1981  if (Node->isElidable())
1982    OS << " elidable";
1983  if (Node->requiresZeroInitialization())
1984    OS << " zeroing";
1985}
1986
1987void ASTDumper::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node) {
1988  VisitExpr(Node);
1989  OS << " ";
1990  dumpCXXTemporary(Node->getTemporary());
1991}
1992
1993void ASTDumper::VisitCXXNewExpr(const CXXNewExpr *Node) {
1994  VisitExpr(Node);
1995  if (Node->isGlobalNew())
1996    OS << " global";
1997  if (Node->isArray())
1998    OS << " array";
1999  if (Node->getOperatorNew()) {
2000    OS << ' ';
2001    dumpBareDeclRef(Node->getOperatorNew());
2002  }
2003  // We could dump the deallocation function used in case of error, but it's
2004  // usually not that interesting.
2005}
2006
2007void ASTDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *Node) {
2008  VisitExpr(Node);
2009  if (Node->isGlobalDelete())
2010    OS << " global";
2011  if (Node->isArrayForm())
2012    OS << " array";
2013  if (Node->getOperatorDelete()) {
2014    OS << ' ';
2015    dumpBareDeclRef(Node->getOperatorDelete());
2016  }
2017}
2018
2019void
2020ASTDumper::VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node) {
2021  VisitExpr(Node);
2022  if (const ValueDecl *VD = Node->getExtendingDecl()) {
2023    OS << " extended by ";
2024    dumpBareDeclRef(VD);
2025  }
2026}
2027
2028void ASTDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
2029  VisitExpr(Node);
2030  for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
2031    dumpDeclRef(Node->getObject(i), "cleanup");
2032}
2033
2034void ASTDumper::dumpCXXTemporary(const CXXTemporary *Temporary) {
2035  OS << "(CXXTemporary";
2036  dumpPointer(Temporary);
2037  OS << ")";
2038}
2039
2040void ASTDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
2041  VisitExpr(Node);
2042  dumpPointer(Node->getPack());
2043  dumpName(Node->getPack());
2044  if (Node->isPartiallySubstituted())
2045    for (const auto &A : Node->getPartialArguments())
2046      dumpTemplateArgument(A);
2047}
2048
2049
2050//===----------------------------------------------------------------------===//
2051// Obj-C Expressions
2052//===----------------------------------------------------------------------===//
2053
2054void ASTDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
2055  VisitExpr(Node);
2056  OS << " selector=";
2057  Node->getSelector().print(OS);
2058  switch (Node->getReceiverKind()) {
2059  case ObjCMessageExpr::Instance:
2060    break;
2061
2062  case ObjCMessageExpr::Class:
2063    OS << " class=";
2064    dumpBareType(Node->getClassReceiver());
2065    break;
2066
2067  case ObjCMessageExpr::SuperInstance:
2068    OS << " super (instance)";
2069    break;
2070
2071  case ObjCMessageExpr::SuperClass:
2072    OS << " super (class)";
2073    break;
2074  }
2075}
2076
2077void ASTDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
2078  VisitExpr(Node);
2079  OS << " selector=";
2080  Node->getBoxingMethod()->getSelector().print(OS);
2081}
2082
2083void ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
2084  VisitStmt(Node);
2085  if (const VarDecl *CatchParam = Node->getCatchParamDecl())
2086    dumpDecl(CatchParam);
2087  else
2088    OS << " catch all";
2089}
2090
2091void ASTDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
2092  VisitExpr(Node);
2093  dumpType(Node->getEncodedType());
2094}
2095
2096void ASTDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
2097  VisitExpr(Node);
2098
2099  OS << " ";
2100  Node->getSelector().print(OS);
2101}
2102
2103void ASTDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
2104  VisitExpr(Node);
2105
2106  OS << ' ' << *Node->getProtocol();
2107}
2108
2109void ASTDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
2110  VisitExpr(Node);
2111  if (Node->isImplicitProperty()) {
2112    OS << " Kind=MethodRef Getter=\"";
2113    if (Node->getImplicitPropertyGetter())
2114      Node->getImplicitPropertyGetter()->getSelector().print(OS);
2115    else
2116      OS << "(null)";
2117
2118    OS << "\" Setter=\"";
2119    if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
2120      Setter->getSelector().print(OS);
2121    else
2122      OS << "(null)";
2123    OS << "\"";
2124  } else {
2125    OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty() <<'"';
2126  }
2127
2128  if (Node->isSuperReceiver())
2129    OS << " super";
2130
2131  OS << " Messaging=";
2132  if (Node->isMessagingGetter() && Node->isMessagingSetter())
2133    OS << "Getter&Setter";
2134  else if (Node->isMessagingGetter())
2135    OS << "Getter";
2136  else if (Node->isMessagingSetter())
2137    OS << "Setter";
2138}
2139
2140void ASTDumper::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node) {
2141  VisitExpr(Node);
2142  if (Node->isArraySubscriptRefExpr())
2143    OS << " Kind=ArraySubscript GetterForArray=\"";
2144  else
2145    OS << " Kind=DictionarySubscript GetterForDictionary=\"";
2146  if (Node->getAtIndexMethodDecl())
2147    Node->getAtIndexMethodDecl()->getSelector().print(OS);
2148  else
2149    OS << "(null)";
2150
2151  if (Node->isArraySubscriptRefExpr())
2152    OS << "\" SetterForArray=\"";
2153  else
2154    OS << "\" SetterForDictionary=\"";
2155  if (Node->setAtIndexMethodDecl())
2156    Node->setAtIndexMethodDecl()->getSelector().print(OS);
2157  else
2158    OS << "(null)";
2159}
2160
2161void ASTDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) {
2162  VisitExpr(Node);
2163  OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
2164}
2165
2166//===----------------------------------------------------------------------===//
2167// Comments
2168//===----------------------------------------------------------------------===//
2169
2170const char *ASTDumper::getCommandName(unsigned CommandID) {
2171  if (Traits)
2172    return Traits->getCommandInfo(CommandID)->Name;
2173  const CommandInfo *Info = CommandTraits::getBuiltinCommandInfo(CommandID);
2174  if (Info)
2175    return Info->Name;
2176  return "<not a builtin command>";
2177}
2178
2179void ASTDumper::dumpFullComment(const FullComment *C) {
2180  if (!C)
2181    return;
2182
2183  FC = C;
2184  dumpComment(C);
2185  FC = nullptr;
2186}
2187
2188void ASTDumper::dumpComment(const Comment *C) {
2189  dumpChild([=] {
2190    if (!C) {
2191      ColorScope Color(*this, NullColor);
2192      OS << "<<<NULL>>>";
2193      return;
2194    }
2195
2196    {
2197      ColorScope Color(*this, CommentColor);
2198      OS << C->getCommentKindName();
2199    }
2200    dumpPointer(C);
2201    dumpSourceRange(C->getSourceRange());
2202    ConstCommentVisitor<ASTDumper>::visit(C);
2203    for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
2204         I != E; ++I)
2205      dumpComment(*I);
2206  });
2207}
2208
2209void ASTDumper::visitTextComment(const TextComment *C) {
2210  OS << " Text=\"" << C->getText() << "\"";
2211}
2212
2213void ASTDumper::visitInlineCommandComment(const InlineCommandComment *C) {
2214  OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
2215  switch (C->getRenderKind()) {
2216  case InlineCommandComment::RenderNormal:
2217    OS << " RenderNormal";
2218    break;
2219  case InlineCommandComment::RenderBold:
2220    OS << " RenderBold";
2221    break;
2222  case InlineCommandComment::RenderMonospaced:
2223    OS << " RenderMonospaced";
2224    break;
2225  case InlineCommandComment::RenderEmphasized:
2226    OS << " RenderEmphasized";
2227    break;
2228  }
2229
2230  for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
2231    OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
2232}
2233
2234void ASTDumper::visitHTMLStartTagComment(const HTMLStartTagComment *C) {
2235  OS << " Name=\"" << C->getTagName() << "\"";
2236  if (C->getNumAttrs() != 0) {
2237    OS << " Attrs: ";
2238    for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
2239      const HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
2240      OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
2241    }
2242  }
2243  if (C->isSelfClosing())
2244    OS << " SelfClosing";
2245}
2246
2247void ASTDumper::visitHTMLEndTagComment(const HTMLEndTagComment *C) {
2248  OS << " Name=\"" << C->getTagName() << "\"";
2249}
2250
2251void ASTDumper::visitBlockCommandComment(const BlockCommandComment *C) {
2252  OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
2253  for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
2254    OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
2255}
2256
2257void ASTDumper::visitParamCommandComment(const ParamCommandComment *C) {
2258  OS << " " << ParamCommandComment::getDirectionAsString(C->getDirection());
2259
2260  if (C->isDirectionExplicit())
2261    OS << " explicitly";
2262  else
2263    OS << " implicitly";
2264
2265  if (C->hasParamName()) {
2266    if (C->isParamIndexValid())
2267      OS << " Param=\"" << C->getParamName(FC) << "\"";
2268    else
2269      OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
2270  }
2271
2272  if (C->isParamIndexValid() && !C->isVarArgParam())
2273    OS << " ParamIndex=" << C->getParamIndex();
2274}
2275
2276void ASTDumper::visitTParamCommandComment(const TParamCommandComment *C) {
2277  if (C->hasParamName()) {
2278    if (C->isPositionValid())
2279      OS << " Param=\"" << C->getParamName(FC) << "\"";
2280    else
2281      OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
2282  }
2283
2284  if (C->isPositionValid()) {
2285    OS << " Position=<";
2286    for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
2287      OS << C->getIndex(i);
2288      if (i != e - 1)
2289        OS << ", ";
2290    }
2291    OS << ">";
2292  }
2293}
2294
2295void ASTDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) {
2296  OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""
2297        " CloseName=\"" << C->getCloseName() << "\"";
2298}
2299
2300void ASTDumper::visitVerbatimBlockLineComment(
2301    const VerbatimBlockLineComment *C) {
2302  OS << " Text=\"" << C->getText() << "\"";
2303}
2304
2305void ASTDumper::visitVerbatimLineComment(const VerbatimLineComment *C) {
2306  OS << " Text=\"" << C->getText() << "\"";
2307}
2308
2309//===----------------------------------------------------------------------===//
2310// Type method implementations
2311//===----------------------------------------------------------------------===//
2312
2313void QualType::dump(const char *msg) const {
2314  if (msg)
2315    llvm::errs() << msg << ": ";
2316  dump();
2317}
2318
2319LLVM_DUMP_METHOD void QualType::dump() const {
2320  ASTDumper Dumper(llvm::errs(), nullptr, nullptr);
2321  Dumper.dumpTypeAsChild(*this);
2322}
2323
2324LLVM_DUMP_METHOD void Type::dump() const { QualType(this, 0).dump(); }
2325
2326//===----------------------------------------------------------------------===//
2327// Decl method implementations
2328//===----------------------------------------------------------------------===//
2329
2330LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); }
2331
2332LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS) const {
2333  ASTDumper P(OS, &getASTContext().getCommentCommandTraits(),
2334              &getASTContext().getSourceManager());
2335  P.dumpDecl(this);
2336}
2337
2338LLVM_DUMP_METHOD void Decl::dumpColor() const {
2339  ASTDumper P(llvm::errs(), &getASTContext().getCommentCommandTraits(),
2340              &getASTContext().getSourceManager(), /*ShowColors*/true);
2341  P.dumpDecl(this);
2342}
2343
2344LLVM_DUMP_METHOD void DeclContext::dumpLookups() const {
2345  dumpLookups(llvm::errs());
2346}
2347
2348LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS,
2349                                               bool DumpDecls) const {
2350  const DeclContext *DC = this;
2351  while (!DC->isTranslationUnit())
2352    DC = DC->getParent();
2353  ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
2354  ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager());
2355  P.dumpLookups(this, DumpDecls);
2356}
2357
2358//===----------------------------------------------------------------------===//
2359// Stmt method implementations
2360//===----------------------------------------------------------------------===//
2361
2362LLVM_DUMP_METHOD void Stmt::dump(SourceManager &SM) const {
2363  dump(llvm::errs(), SM);
2364}
2365
2366LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
2367  ASTDumper P(OS, nullptr, &SM);
2368  P.dumpStmt(this);
2369}
2370
2371LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS) const {
2372  ASTDumper P(OS, nullptr, nullptr);
2373  P.dumpStmt(this);
2374}
2375
2376LLVM_DUMP_METHOD void Stmt::dump() const {
2377  ASTDumper P(llvm::errs(), nullptr, nullptr);
2378  P.dumpStmt(this);
2379}
2380
2381LLVM_DUMP_METHOD void Stmt::dumpColor() const {
2382  ASTDumper P(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
2383  P.dumpStmt(this);
2384}
2385
2386//===----------------------------------------------------------------------===//
2387// Comment method implementations
2388//===----------------------------------------------------------------------===//
2389
2390LLVM_DUMP_METHOD void Comment::dump() const {
2391  dump(llvm::errs(), nullptr, nullptr);
2392}
2393
2394LLVM_DUMP_METHOD void Comment::dump(const ASTContext &Context) const {
2395  dump(llvm::errs(), &Context.getCommentCommandTraits(),
2396       &Context.getSourceManager());
2397}
2398
2399void Comment::dump(raw_ostream &OS, const CommandTraits *Traits,
2400                   const SourceManager *SM) const {
2401  const FullComment *FC = dyn_cast<FullComment>(this);
2402  ASTDumper D(OS, Traits, SM);
2403  D.dumpFullComment(FC);
2404}
2405
2406LLVM_DUMP_METHOD void Comment::dumpColor() const {
2407  const FullComment *FC = dyn_cast<FullComment>(this);
2408  ASTDumper D(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
2409  D.dumpFullComment(FC);
2410}
2411