clang API Documentation

ASTDumper.cpp
Go to the documentation of this file.
00001 //===--- ASTDumper.cpp - Dumping implementation for ASTs ------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements the AST dump methods, which dump out the
00011 // AST in a form that exposes type details and other fields.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "clang/AST/ASTContext.h"
00016 #include "clang/AST/Attr.h"
00017 #include "clang/AST/CommentVisitor.h"
00018 #include "clang/AST/DeclCXX.h"
00019 #include "clang/AST/DeclLookups.h"
00020 #include "clang/AST/DeclObjC.h"
00021 #include "clang/AST/DeclVisitor.h"
00022 #include "clang/AST/StmtVisitor.h"
00023 #include "clang/AST/TypeVisitor.h"
00024 #include "clang/Basic/Module.h"
00025 #include "clang/Basic/SourceManager.h"
00026 #include "llvm/Support/raw_ostream.h"
00027 using namespace clang;
00028 using namespace clang::comments;
00029 
00030 //===----------------------------------------------------------------------===//
00031 // ASTDumper Visitor
00032 //===----------------------------------------------------------------------===//
00033 
00034 namespace  {
00035   // Colors used for various parts of the AST dump
00036   // Do not use bold yellow for any text.  It is hard to read on white screens.
00037 
00038   struct TerminalColor {
00039     raw_ostream::Colors Color;
00040     bool Bold;
00041   };
00042 
00043   // Red           - CastColor
00044   // Green         - TypeColor
00045   // Bold Green    - DeclKindNameColor, UndeserializedColor
00046   // Yellow        - AddressColor, LocationColor
00047   // Blue          - CommentColor, NullColor, IndentColor
00048   // Bold Blue     - AttrColor
00049   // Bold Magenta  - StmtColor
00050   // Cyan          - ValueKindColor, ObjectKindColor
00051   // Bold Cyan     - ValueColor, DeclNameColor
00052 
00053   // Decl kind names (VarDecl, FunctionDecl, etc)
00054   static const TerminalColor DeclKindNameColor = { raw_ostream::GREEN, true };
00055   // Attr names (CleanupAttr, GuardedByAttr, etc)
00056   static const TerminalColor AttrColor = { raw_ostream::BLUE, true };
00057   // Statement names (DeclStmt, ImplicitCastExpr, etc)
00058   static const TerminalColor StmtColor = { raw_ostream::MAGENTA, true };
00059   // Comment names (FullComment, ParagraphComment, TextComment, etc)
00060   static const TerminalColor CommentColor = { raw_ostream::BLUE, false };
00061 
00062   // Type names (int, float, etc, plus user defined types)
00063   static const TerminalColor TypeColor = { raw_ostream::GREEN, false };
00064 
00065   // Pointer address
00066   static const TerminalColor AddressColor = { raw_ostream::YELLOW, false };
00067   // Source locations
00068   static const TerminalColor LocationColor = { raw_ostream::YELLOW, false };
00069 
00070   // lvalue/xvalue
00071   static const TerminalColor ValueKindColor = { raw_ostream::CYAN, false };
00072   // bitfield/objcproperty/objcsubscript/vectorcomponent
00073   static const TerminalColor ObjectKindColor = { raw_ostream::CYAN, false };
00074 
00075   // Null statements
00076   static const TerminalColor NullColor = { raw_ostream::BLUE, false };
00077 
00078   // Undeserialized entities
00079   static const TerminalColor UndeserializedColor = { raw_ostream::GREEN, true };
00080 
00081   // CastKind from CastExpr's
00082   static const TerminalColor CastColor = { raw_ostream::RED, false };
00083 
00084   // Value of the statement
00085   static const TerminalColor ValueColor = { raw_ostream::CYAN, true };
00086   // Decl names
00087   static const TerminalColor DeclNameColor = { raw_ostream::CYAN, true };
00088 
00089   // Indents ( `, -. | )
00090   static const TerminalColor IndentColor = { raw_ostream::BLUE, false };
00091 
00092   class ASTDumper
00093       : public ConstDeclVisitor<ASTDumper>, public ConstStmtVisitor<ASTDumper>,
00094         public ConstCommentVisitor<ASTDumper>, public TypeVisitor<ASTDumper> {
00095     raw_ostream &OS;
00096     const CommandTraits *Traits;
00097     const SourceManager *SM;
00098 
00099     /// Pending[i] is an action to dump an entity at level i.
00100     llvm::SmallVector<std::function<void(bool isLastChild)>, 32> Pending;
00101 
00102     /// Indicates whether we're at the top level.
00103     bool TopLevel;
00104 
00105     /// Indicates if we're handling the first child after entering a new depth.
00106     bool FirstChild;
00107 
00108     /// Prefix for currently-being-dumped entity.
00109     std::string Prefix;
00110 
00111     /// Keep track of the last location we print out so that we can
00112     /// print out deltas from then on out.
00113     const char *LastLocFilename;
00114     unsigned LastLocLine;
00115 
00116     /// The \c FullComment parent of the comment being dumped.
00117     const FullComment *FC;
00118 
00119     bool ShowColors;
00120 
00121     /// Dump a child of the current node.
00122     template<typename Fn> void dumpChild(Fn doDumpChild) {
00123       // If we're at the top level, there's nothing interesting to do; just
00124       // run the dumper.
00125       if (TopLevel) {
00126         TopLevel = false;
00127         doDumpChild();
00128         while (!Pending.empty()) {
00129           Pending.back()(true);
00130           Pending.pop_back();
00131         }
00132         Prefix.clear();
00133         OS << "\n";
00134         TopLevel = true;
00135         return;
00136       }
00137 
00138       const FullComment *OrigFC = FC;
00139       auto dumpWithIndent = [this, doDumpChild, OrigFC](bool isLastChild) {
00140         // Print out the appropriate tree structure and work out the prefix for
00141         // children of this node. For instance:
00142         //
00143         //   A        Prefix = ""
00144         //   |-B      Prefix = "| "
00145         //   | `-C    Prefix = "|   "
00146         //   `-D      Prefix = "  "
00147         //     |-E    Prefix = "  | "
00148         //     `-F    Prefix = "    "
00149         //   G        Prefix = ""
00150         //
00151         // Note that the first level gets no prefix.
00152         {
00153           OS << '\n';
00154           ColorScope Color(*this, IndentColor);
00155           OS << Prefix << (isLastChild ? '`' : '|') << '-';
00156           this->Prefix.push_back(isLastChild ? ' ' : '|');
00157           this->Prefix.push_back(' ');
00158         }
00159 
00160         FirstChild = true;
00161         unsigned Depth = Pending.size();
00162 
00163         FC = OrigFC;
00164         doDumpChild();
00165 
00166         // If any children are left, they're the last at their nesting level.
00167         // Dump those ones out now.
00168         while (Depth < Pending.size()) {
00169           Pending.back()(true);
00170           this->Pending.pop_back();
00171         }
00172 
00173         // Restore the old prefix.
00174         this->Prefix.resize(Prefix.size() - 2);
00175       };
00176 
00177       if (FirstChild) {
00178         Pending.push_back(std::move(dumpWithIndent));
00179       } else {
00180         Pending.back()(false);
00181         Pending.back() = std::move(dumpWithIndent);
00182       }
00183       FirstChild = false;
00184     }
00185 
00186     class ColorScope {
00187       ASTDumper &Dumper;
00188     public:
00189       ColorScope(ASTDumper &Dumper, TerminalColor Color)
00190         : Dumper(Dumper) {
00191         if (Dumper.ShowColors)
00192           Dumper.OS.changeColor(Color.Color, Color.Bold);
00193       }
00194       ~ColorScope() {
00195         if (Dumper.ShowColors)
00196           Dumper.OS.resetColor();
00197       }
00198     };
00199 
00200   public:
00201     ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
00202               const SourceManager *SM)
00203       : OS(OS), Traits(Traits), SM(SM), TopLevel(true), FirstChild(true),
00204         LastLocFilename(""), LastLocLine(~0U), FC(nullptr),
00205         ShowColors(SM && SM->getDiagnostics().getShowColors()) { }
00206 
00207     ASTDumper(raw_ostream &OS, const CommandTraits *Traits,
00208               const SourceManager *SM, bool ShowColors)
00209       : OS(OS), Traits(Traits), SM(SM), TopLevel(true), FirstChild(true),
00210         LastLocFilename(""), LastLocLine(~0U),
00211         ShowColors(ShowColors) { }
00212 
00213     void dumpDecl(const Decl *D);
00214     void dumpStmt(const Stmt *S);
00215     void dumpFullComment(const FullComment *C);
00216 
00217     // Utilities
00218     void dumpPointer(const void *Ptr);
00219     void dumpSourceRange(SourceRange R);
00220     void dumpLocation(SourceLocation Loc);
00221     void dumpBareType(QualType T, bool Desugar = true);
00222     void dumpType(QualType T);
00223     void dumpTypeAsChild(QualType T);
00224     void dumpTypeAsChild(const Type *T);
00225     void dumpBareDeclRef(const Decl *Node);
00226     void dumpDeclRef(const Decl *Node, const char *Label = nullptr);
00227     void dumpName(const NamedDecl *D);
00228     bool hasNodes(const DeclContext *DC);
00229     void dumpDeclContext(const DeclContext *DC);
00230     void dumpLookups(const DeclContext *DC, bool DumpDecls);
00231     void dumpAttr(const Attr *A);
00232 
00233     // C++ Utilities
00234     void dumpAccessSpecifier(AccessSpecifier AS);
00235     void dumpCXXCtorInitializer(const CXXCtorInitializer *Init);
00236     void dumpTemplateParameters(const TemplateParameterList *TPL);
00237     void dumpTemplateArgumentListInfo(const TemplateArgumentListInfo &TALI);
00238     void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A);
00239     void dumpTemplateArgumentList(const TemplateArgumentList &TAL);
00240     void dumpTemplateArgument(const TemplateArgument &A,
00241                               SourceRange R = SourceRange());
00242 
00243     // Types
00244     void VisitComplexType(const ComplexType *T) {
00245       dumpTypeAsChild(T->getElementType());
00246     }
00247     void VisitPointerType(const PointerType *T) {
00248       dumpTypeAsChild(T->getPointeeType());
00249     }
00250     void VisitBlockPointerType(const BlockPointerType *T) {
00251       dumpTypeAsChild(T->getPointeeType());
00252     }
00253     void VisitReferenceType(const ReferenceType *T) {
00254       dumpTypeAsChild(T->getPointeeType());
00255     }
00256     void VisitRValueReferenceType(const ReferenceType *T) {
00257       if (T->isSpelledAsLValue())
00258         OS << " written as lvalue reference";
00259       VisitReferenceType(T);
00260     }
00261     void VisitMemberPointerType(const MemberPointerType *T) {
00262       dumpTypeAsChild(T->getClass());
00263       dumpTypeAsChild(T->getPointeeType());
00264     }
00265     void VisitArrayType(const ArrayType *T) {
00266       switch (T->getSizeModifier()) {
00267         case ArrayType::Normal: break;
00268         case ArrayType::Static: OS << " static"; break;
00269         case ArrayType::Star: OS << " *"; break;
00270       }
00271       OS << " " << T->getIndexTypeQualifiers().getAsString();
00272       dumpTypeAsChild(T->getElementType());
00273     }
00274     void VisitConstantArrayType(const ConstantArrayType *T) {
00275       OS << " " << T->getSize();
00276       VisitArrayType(T);
00277     }
00278     void VisitVariableArrayType(const VariableArrayType *T) {
00279       OS << " ";
00280       dumpSourceRange(T->getBracketsRange());
00281       VisitArrayType(T);
00282       dumpStmt(T->getSizeExpr());
00283     }
00284     void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
00285       VisitArrayType(T);
00286       OS << " ";
00287       dumpSourceRange(T->getBracketsRange());
00288       dumpStmt(T->getSizeExpr());
00289     }
00290     void VisitDependentSizedExtVectorType(
00291         const DependentSizedExtVectorType *T) {
00292       OS << " ";
00293       dumpLocation(T->getAttributeLoc());
00294       dumpTypeAsChild(T->getElementType());
00295       dumpStmt(T->getSizeExpr());
00296     }
00297     void VisitVectorType(const VectorType *T) {
00298       switch (T->getVectorKind()) {
00299         case VectorType::GenericVector: break;
00300         case VectorType::AltiVecVector: OS << " altivec"; break;
00301         case VectorType::AltiVecPixel: OS << " altivec pixel"; break;
00302         case VectorType::AltiVecBool: OS << " altivec bool"; break;
00303         case VectorType::NeonVector: OS << " neon"; break;
00304         case VectorType::NeonPolyVector: OS << " neon poly"; break;
00305       }
00306       OS << " " << T->getNumElements();
00307       dumpTypeAsChild(T->getElementType());
00308     }
00309     void VisitFunctionType(const FunctionType *T) {
00310       auto EI = T->getExtInfo();
00311       if (EI.getNoReturn()) OS << " noreturn";
00312       if (EI.getProducesResult()) OS << " produces_result";
00313       if (EI.getHasRegParm()) OS << " regparm " << EI.getRegParm();
00314       OS << " " << FunctionType::getNameForCallConv(EI.getCC());
00315       dumpTypeAsChild(T->getReturnType());
00316     }
00317     void VisitFunctionProtoType(const FunctionProtoType *T) {
00318       auto EPI = T->getExtProtoInfo();
00319       if (EPI.HasTrailingReturn) OS << " trailing_return";
00320       if (T->isConst()) OS << " const";
00321       if (T->isVolatile()) OS << " volatile";
00322       if (T->isRestrict()) OS << " restrict";
00323       switch (EPI.RefQualifier) {
00324         case RQ_None: break;
00325         case RQ_LValue: OS << " &"; break;
00326         case RQ_RValue: OS << " &&"; break;
00327       }
00328       // FIXME: Exception specification.
00329       // FIXME: Consumed parameters.
00330       VisitFunctionType(T);
00331       for (QualType PT : T->getParamTypes())
00332         dumpTypeAsChild(PT);
00333       if (EPI.Variadic)
00334         dumpChild([=] { OS << "..."; });
00335     }
00336     void VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
00337       dumpDeclRef(T->getDecl());
00338     }
00339     void VisitTypedefType(const TypedefType *T) {
00340       dumpDeclRef(T->getDecl());
00341     }
00342     void VisitTypeOfExprType(const TypeOfExprType *T) {
00343       dumpStmt(T->getUnderlyingExpr());
00344     }
00345     void VisitDecltypeType(const DecltypeType *T) {
00346       dumpStmt(T->getUnderlyingExpr());
00347     }
00348     void VisitUnaryTransformType(const UnaryTransformType *T) {
00349       switch (T->getUTTKind()) {
00350       case UnaryTransformType::EnumUnderlyingType:
00351         OS << " underlying_type";
00352         break;
00353       }
00354       dumpTypeAsChild(T->getBaseType());
00355     }
00356     void VisitTagType(const TagType *T) {
00357       dumpDeclRef(T->getDecl());
00358     }
00359     void VisitAttributedType(const AttributedType *T) {
00360       // FIXME: AttrKind
00361       dumpTypeAsChild(T->getModifiedType());
00362     }
00363     void VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
00364       OS << " depth " << T->getDepth() << " index " << T->getIndex();
00365       if (T->isParameterPack()) OS << " pack";
00366       dumpDeclRef(T->getDecl());
00367     }
00368     void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
00369       dumpTypeAsChild(T->getReplacedParameter());
00370     }
00371     void VisitSubstTemplateTypeParmPackType(
00372         const SubstTemplateTypeParmPackType *T) {
00373       dumpTypeAsChild(T->getReplacedParameter());
00374       dumpTemplateArgument(T->getArgumentPack());
00375     }
00376     void VisitAutoType(const AutoType *T) {
00377       if (T->isDecltypeAuto()) OS << " decltype(auto)";
00378       if (!T->isDeduced())
00379         OS << " undeduced";
00380     }
00381     void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
00382       if (T->isTypeAlias()) OS << " alias";
00383       OS << " "; T->getTemplateName().dump(OS);
00384       for (auto &Arg : *T)
00385         dumpTemplateArgument(Arg);
00386       if (T->isTypeAlias())
00387         dumpTypeAsChild(T->getAliasedType());
00388     }
00389     void VisitInjectedClassNameType(const InjectedClassNameType *T) {
00390       dumpDeclRef(T->getDecl());
00391     }
00392     void VisitObjCInterfaceType(const ObjCInterfaceType *T) {
00393       dumpDeclRef(T->getDecl());
00394     }
00395     void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
00396       dumpTypeAsChild(T->getPointeeType());
00397     }
00398     void VisitAtomicType(const AtomicType *T) {
00399       dumpTypeAsChild(T->getValueType());
00400     }
00401     void VisitAdjustedType(const AdjustedType *T) {
00402       dumpTypeAsChild(T->getOriginalType());
00403     }
00404     void VisitPackExpansionType(const PackExpansionType *T) {
00405       if (auto N = T->getNumExpansions()) OS << " expansions " << *N;
00406       if (!T->isSugared())
00407         dumpTypeAsChild(T->getPattern());
00408     }
00409     // FIXME: ElaboratedType, DependentNameType,
00410     // DependentTemplateSpecializationType, ObjCObjectType
00411 
00412     // Decls
00413     void VisitLabelDecl(const LabelDecl *D);
00414     void VisitTypedefDecl(const TypedefDecl *D);
00415     void VisitEnumDecl(const EnumDecl *D);
00416     void VisitRecordDecl(const RecordDecl *D);
00417     void VisitEnumConstantDecl(const EnumConstantDecl *D);
00418     void VisitIndirectFieldDecl(const IndirectFieldDecl *D);
00419     void VisitFunctionDecl(const FunctionDecl *D);
00420     void VisitFieldDecl(const FieldDecl *D);
00421     void VisitVarDecl(const VarDecl *D);
00422     void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D);
00423     void VisitImportDecl(const ImportDecl *D);
00424 
00425     // C++ Decls
00426     void VisitNamespaceDecl(const NamespaceDecl *D);
00427     void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D);
00428     void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D);
00429     void VisitTypeAliasDecl(const TypeAliasDecl *D);
00430     void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D);
00431     void VisitCXXRecordDecl(const CXXRecordDecl *D);
00432     void VisitStaticAssertDecl(const StaticAssertDecl *D);
00433     template<typename SpecializationDecl>
00434     void VisitTemplateDeclSpecialization(const SpecializationDecl *D,
00435                                          bool DumpExplicitInst,
00436                                          bool DumpRefOnly);
00437     template<typename TemplateDecl>
00438     void VisitTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst);
00439     void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
00440     void VisitClassTemplateDecl(const ClassTemplateDecl *D);
00441     void VisitClassTemplateSpecializationDecl(
00442         const ClassTemplateSpecializationDecl *D);
00443     void VisitClassTemplatePartialSpecializationDecl(
00444         const ClassTemplatePartialSpecializationDecl *D);
00445     void VisitClassScopeFunctionSpecializationDecl(
00446         const ClassScopeFunctionSpecializationDecl *D);
00447     void VisitVarTemplateDecl(const VarTemplateDecl *D);
00448     void VisitVarTemplateSpecializationDecl(
00449         const VarTemplateSpecializationDecl *D);
00450     void VisitVarTemplatePartialSpecializationDecl(
00451         const VarTemplatePartialSpecializationDecl *D);
00452     void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
00453     void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
00454     void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
00455     void VisitUsingDecl(const UsingDecl *D);
00456     void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D);
00457     void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D);
00458     void VisitUsingShadowDecl(const UsingShadowDecl *D);
00459     void VisitLinkageSpecDecl(const LinkageSpecDecl *D);
00460     void VisitAccessSpecDecl(const AccessSpecDecl *D);
00461     void VisitFriendDecl(const FriendDecl *D);
00462 
00463     // ObjC Decls
00464     void VisitObjCIvarDecl(const ObjCIvarDecl *D);
00465     void VisitObjCMethodDecl(const ObjCMethodDecl *D);
00466     void VisitObjCCategoryDecl(const ObjCCategoryDecl *D);
00467     void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D);
00468     void VisitObjCProtocolDecl(const ObjCProtocolDecl *D);
00469     void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D);
00470     void VisitObjCImplementationDecl(const ObjCImplementationDecl *D);
00471     void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D);
00472     void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
00473     void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
00474     void VisitBlockDecl(const BlockDecl *D);
00475 
00476     // Stmts.
00477     void VisitStmt(const Stmt *Node);
00478     void VisitDeclStmt(const DeclStmt *Node);
00479     void VisitAttributedStmt(const AttributedStmt *Node);
00480     void VisitLabelStmt(const LabelStmt *Node);
00481     void VisitGotoStmt(const GotoStmt *Node);
00482     void VisitCXXCatchStmt(const CXXCatchStmt *Node);
00483 
00484     // Exprs
00485     void VisitExpr(const Expr *Node);
00486     void VisitCastExpr(const CastExpr *Node);
00487     void VisitDeclRefExpr(const DeclRefExpr *Node);
00488     void VisitPredefinedExpr(const PredefinedExpr *Node);
00489     void VisitCharacterLiteral(const CharacterLiteral *Node);
00490     void VisitIntegerLiteral(const IntegerLiteral *Node);
00491     void VisitFloatingLiteral(const FloatingLiteral *Node);
00492     void VisitStringLiteral(const StringLiteral *Str);
00493     void VisitInitListExpr(const InitListExpr *ILE);
00494     void VisitUnaryOperator(const UnaryOperator *Node);
00495     void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node);
00496     void VisitMemberExpr(const MemberExpr *Node);
00497     void VisitExtVectorElementExpr(const ExtVectorElementExpr *Node);
00498     void VisitBinaryOperator(const BinaryOperator *Node);
00499     void VisitCompoundAssignOperator(const CompoundAssignOperator *Node);
00500     void VisitAddrLabelExpr(const AddrLabelExpr *Node);
00501     void VisitBlockExpr(const BlockExpr *Node);
00502     void VisitOpaqueValueExpr(const OpaqueValueExpr *Node);
00503 
00504     // C++
00505     void VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node);
00506     void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node);
00507     void VisitCXXThisExpr(const CXXThisExpr *Node);
00508     void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node);
00509     void VisitCXXConstructExpr(const CXXConstructExpr *Node);
00510     void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node);
00511     void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node);
00512     void VisitExprWithCleanups(const ExprWithCleanups *Node);
00513     void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node);
00514     void dumpCXXTemporary(const CXXTemporary *Temporary);
00515     void VisitLambdaExpr(const LambdaExpr *Node) {
00516       VisitExpr(Node);
00517       dumpDecl(Node->getLambdaClass());
00518     }
00519 
00520     // ObjC
00521     void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node);
00522     void VisitObjCEncodeExpr(const ObjCEncodeExpr *Node);
00523     void VisitObjCMessageExpr(const ObjCMessageExpr *Node);
00524     void VisitObjCBoxedExpr(const ObjCBoxedExpr *Node);
00525     void VisitObjCSelectorExpr(const ObjCSelectorExpr *Node);
00526     void VisitObjCProtocolExpr(const ObjCProtocolExpr *Node);
00527     void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node);
00528     void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node);
00529     void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node);
00530     void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node);
00531 
00532     // Comments.
00533     const char *getCommandName(unsigned CommandID);
00534     void dumpComment(const Comment *C);
00535 
00536     // Inline comments.
00537     void visitTextComment(const TextComment *C);
00538     void visitInlineCommandComment(const InlineCommandComment *C);
00539     void visitHTMLStartTagComment(const HTMLStartTagComment *C);
00540     void visitHTMLEndTagComment(const HTMLEndTagComment *C);
00541 
00542     // Block comments.
00543     void visitBlockCommandComment(const BlockCommandComment *C);
00544     void visitParamCommandComment(const ParamCommandComment *C);
00545     void visitTParamCommandComment(const TParamCommandComment *C);
00546     void visitVerbatimBlockComment(const VerbatimBlockComment *C);
00547     void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
00548     void visitVerbatimLineComment(const VerbatimLineComment *C);
00549   };
00550 }
00551 
00552 //===----------------------------------------------------------------------===//
00553 //  Utilities
00554 //===----------------------------------------------------------------------===//
00555 
00556 void ASTDumper::dumpPointer(const void *Ptr) {
00557   ColorScope Color(*this, AddressColor);
00558   OS << ' ' << Ptr;
00559 }
00560 
00561 void ASTDumper::dumpLocation(SourceLocation Loc) {
00562   if (!SM)
00563     return;
00564 
00565   ColorScope Color(*this, LocationColor);
00566   SourceLocation SpellingLoc = SM->getSpellingLoc(Loc);
00567 
00568   // The general format we print out is filename:line:col, but we drop pieces
00569   // that haven't changed since the last loc printed.
00570   PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc);
00571 
00572   if (PLoc.isInvalid()) {
00573     OS << "<invalid sloc>";
00574     return;
00575   }
00576 
00577   if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) {
00578     OS << PLoc.getFilename() << ':' << PLoc.getLine()
00579        << ':' << PLoc.getColumn();
00580     LastLocFilename = PLoc.getFilename();
00581     LastLocLine = PLoc.getLine();
00582   } else if (PLoc.getLine() != LastLocLine) {
00583     OS << "line" << ':' << PLoc.getLine()
00584        << ':' << PLoc.getColumn();
00585     LastLocLine = PLoc.getLine();
00586   } else {
00587     OS << "col" << ':' << PLoc.getColumn();
00588   }
00589 }
00590 
00591 void ASTDumper::dumpSourceRange(SourceRange R) {
00592   // Can't translate locations if a SourceManager isn't available.
00593   if (!SM)
00594     return;
00595 
00596   OS << " <";
00597   dumpLocation(R.getBegin());
00598   if (R.getBegin() != R.getEnd()) {
00599     OS << ", ";
00600     dumpLocation(R.getEnd());
00601   }
00602   OS << ">";
00603 
00604   // <t2.c:123:421[blah], t2.c:412:321>
00605 
00606 }
00607 
00608 void ASTDumper::dumpBareType(QualType T, bool Desugar) {
00609   ColorScope Color(*this, TypeColor);
00610 
00611   SplitQualType T_split = T.split();
00612   OS << "'" << QualType::getAsString(T_split) << "'";
00613 
00614   if (Desugar && !T.isNull()) {
00615     // If the type is sugared, also dump a (shallow) desugared type.
00616     SplitQualType D_split = T.getSplitDesugaredType();
00617     if (T_split != D_split)
00618       OS << ":'" << QualType::getAsString(D_split) << "'";
00619   }
00620 }
00621 
00622 void ASTDumper::dumpType(QualType T) {
00623   OS << ' ';
00624   dumpBareType(T);
00625 }
00626 
00627 void ASTDumper::dumpTypeAsChild(QualType T) {
00628   SplitQualType SQT = T.split();
00629   if (!SQT.Quals.hasQualifiers())
00630     return dumpTypeAsChild(SQT.Ty);
00631 
00632   dumpChild([=] {
00633     OS << "QualType";
00634     dumpPointer(T.getAsOpaquePtr());
00635     OS << " ";
00636     dumpBareType(T, false);
00637     OS << " " << T.split().Quals.getAsString();
00638     dumpTypeAsChild(T.split().Ty);
00639   });
00640 }
00641 
00642 void ASTDumper::dumpTypeAsChild(const Type *T) {
00643   dumpChild([=] {
00644     if (!T) {
00645       ColorScope Color(*this, NullColor);
00646       OS << "<<<NULL>>>";
00647       return;
00648     }
00649 
00650     {
00651       ColorScope Color(*this, TypeColor);
00652       OS << T->getTypeClassName() << "Type";
00653     }
00654     dumpPointer(T);
00655     OS << " ";
00656     dumpBareType(QualType(T, 0), false);
00657 
00658     QualType SingleStepDesugar =
00659         T->getLocallyUnqualifiedSingleStepDesugaredType();
00660     if (SingleStepDesugar != QualType(T, 0))
00661       OS << " sugar";
00662     if (T->isDependentType())
00663       OS << " dependent";
00664     else if (T->isInstantiationDependentType())
00665       OS << " instantiation_dependent";
00666     if (T->isVariablyModifiedType())
00667       OS << " variably_modified";
00668     if (T->containsUnexpandedParameterPack())
00669       OS << " contains_unexpanded_pack";
00670     if (T->isFromAST())
00671       OS << " imported";
00672 
00673     TypeVisitor<ASTDumper>::Visit(T);
00674 
00675     if (SingleStepDesugar != QualType(T, 0))
00676       dumpTypeAsChild(SingleStepDesugar);
00677   });
00678 }
00679 
00680 void ASTDumper::dumpBareDeclRef(const Decl *D) {
00681   {
00682     ColorScope Color(*this, DeclKindNameColor);
00683     OS << D->getDeclKindName();
00684   }
00685   dumpPointer(D);
00686 
00687   if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
00688     ColorScope Color(*this, DeclNameColor);
00689     OS << " '" << ND->getDeclName() << '\'';
00690   }
00691 
00692   if (const ValueDecl *VD = dyn_cast<ValueDecl>(D))
00693     dumpType(VD->getType());
00694 }
00695 
00696 void ASTDumper::dumpDeclRef(const Decl *D, const char *Label) {
00697   if (!D)
00698     return;
00699 
00700   dumpChild([=]{
00701     if (Label)
00702       OS << Label << ' ';
00703     dumpBareDeclRef(D);
00704   });
00705 }
00706 
00707 void ASTDumper::dumpName(const NamedDecl *ND) {
00708   if (ND->getDeclName()) {
00709     ColorScope Color(*this, DeclNameColor);
00710     OS << ' ' << ND->getNameAsString();
00711   }
00712 }
00713 
00714 bool ASTDumper::hasNodes(const DeclContext *DC) {
00715   if (!DC)
00716     return false;
00717 
00718   return DC->hasExternalLexicalStorage() ||
00719          DC->noload_decls_begin() != DC->noload_decls_end();
00720 }
00721 
00722 void ASTDumper::dumpDeclContext(const DeclContext *DC) {
00723   if (!DC)
00724     return;
00725 
00726   for (auto *D : DC->noload_decls())
00727     dumpDecl(D);
00728 
00729   if (DC->hasExternalLexicalStorage()) {
00730     dumpChild([=]{
00731       ColorScope Color(*this, UndeserializedColor);
00732       OS << "<undeserialized declarations>";
00733     });
00734   }
00735 }
00736 
00737 void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
00738   dumpChild([=] {
00739     OS << "StoredDeclsMap ";
00740     dumpBareDeclRef(cast<Decl>(DC));
00741 
00742     const DeclContext *Primary = DC->getPrimaryContext();
00743     if (Primary != DC) {
00744       OS << " primary";
00745       dumpPointer(cast<Decl>(Primary));
00746     }
00747 
00748     bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage();
00749 
00750     DeclContext::all_lookups_iterator I = Primary->noload_lookups_begin(),
00751                                       E = Primary->noload_lookups_end();
00752     while (I != E) {
00753       DeclarationName Name = I.getLookupName();
00754       DeclContextLookupResult R = *I++;
00755 
00756       dumpChild([=] {
00757         OS << "DeclarationName ";
00758         {
00759           ColorScope Color(*this, DeclNameColor);
00760           OS << '\'' << Name << '\'';
00761         }
00762 
00763         for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end();
00764              RI != RE; ++RI) {
00765           dumpChild([=] {
00766             dumpBareDeclRef(*RI);
00767 
00768             if ((*RI)->isHidden())
00769               OS << " hidden";
00770 
00771             // If requested, dump the redecl chain for this lookup.
00772             if (DumpDecls) {
00773               // Dump earliest decl first.
00774               std::function<void(Decl *)> DumpWithPrev = [&](Decl *D) {
00775                 if (Decl *Prev = D->getPreviousDecl())
00776                   DumpWithPrev(Prev);
00777                 dumpDecl(D);
00778               };
00779               DumpWithPrev(*RI);
00780             }
00781           });
00782         }
00783       });
00784     }
00785 
00786     if (HasUndeserializedLookups) {
00787       dumpChild([=] {
00788         ColorScope Color(*this, UndeserializedColor);
00789         OS << "<undeserialized lookups>";
00790       });
00791     }
00792   });
00793 }
00794 
00795 void ASTDumper::dumpAttr(const Attr *A) {
00796   dumpChild([=] {
00797     {
00798       ColorScope Color(*this, AttrColor);
00799 
00800       switch (A->getKind()) {
00801 #define ATTR(X) case attr::X: OS << #X; break;
00802 #include "clang/Basic/AttrList.inc"
00803       default:
00804         llvm_unreachable("unexpected attribute kind");
00805       }
00806       OS << "Attr";
00807     }
00808     dumpPointer(A);
00809     dumpSourceRange(A->getRange());
00810     if (A->isInherited())
00811       OS << " Inherited";
00812     if (A->isImplicit())
00813       OS << " Implicit";
00814 #include "clang/AST/AttrDump.inc"
00815   });
00816 }
00817 
00818 static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {}
00819 
00820 template<typename T>
00821 static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) {
00822   const T *First = D->getFirstDecl();
00823   if (First != D)
00824     OS << " first " << First;
00825 }
00826 
00827 template<typename T>
00828 static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) {
00829   const T *Prev = D->getPreviousDecl();
00830   if (Prev)
00831     OS << " prev " << Prev;
00832 }
00833 
00834 /// Dump the previous declaration in the redeclaration chain for a declaration,
00835 /// if any.
00836 static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) {
00837   switch (D->getKind()) {
00838 #define DECL(DERIVED, BASE) \
00839   case Decl::DERIVED: \
00840     return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D));
00841 #define ABSTRACT_DECL(DECL)
00842 #include "clang/AST/DeclNodes.inc"
00843   }
00844   llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
00845 }
00846 
00847 //===----------------------------------------------------------------------===//
00848 //  C++ Utilities
00849 //===----------------------------------------------------------------------===//
00850 
00851 void ASTDumper::dumpAccessSpecifier(AccessSpecifier AS) {
00852   switch (AS) {
00853   case AS_none:
00854     break;
00855   case AS_public:
00856     OS << "public";
00857     break;
00858   case AS_protected:
00859     OS << "protected";
00860     break;
00861   case AS_private:
00862     OS << "private";
00863     break;
00864   }
00865 }
00866 
00867 void ASTDumper::dumpCXXCtorInitializer(const CXXCtorInitializer *Init) {
00868   dumpChild([=] {
00869     OS << "CXXCtorInitializer";
00870     if (Init->isAnyMemberInitializer()) {
00871       OS << ' ';
00872       dumpBareDeclRef(Init->getAnyMember());
00873     } else if (Init->isBaseInitializer()) {
00874       dumpType(QualType(Init->getBaseClass(), 0));
00875     } else if (Init->isDelegatingInitializer()) {
00876       dumpType(Init->getTypeSourceInfo()->getType());
00877     } else {
00878       llvm_unreachable("Unknown initializer type");
00879     }
00880     dumpStmt(Init->getInit());
00881   });
00882 }
00883 
00884 void ASTDumper::dumpTemplateParameters(const TemplateParameterList *TPL) {
00885   if (!TPL)
00886     return;
00887 
00888   for (TemplateParameterList::const_iterator I = TPL->begin(), E = TPL->end();
00889        I != E; ++I)
00890     dumpDecl(*I);
00891 }
00892 
00893 void ASTDumper::dumpTemplateArgumentListInfo(
00894     const TemplateArgumentListInfo &TALI) {
00895   for (unsigned i = 0, e = TALI.size(); i < e; ++i)
00896     dumpTemplateArgumentLoc(TALI[i]);
00897 }
00898 
00899 void ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A) {
00900   dumpTemplateArgument(A.getArgument(), A.getSourceRange());
00901 }
00902 
00903 void ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) {
00904   for (unsigned i = 0, e = TAL.size(); i < e; ++i)
00905     dumpTemplateArgument(TAL[i]);
00906 }
00907 
00908 void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R) {
00909   dumpChild([=] {
00910     OS << "TemplateArgument";
00911     if (R.isValid())
00912       dumpSourceRange(R);
00913 
00914     switch (A.getKind()) {
00915     case TemplateArgument::Null:
00916       OS << " null";
00917       break;
00918     case TemplateArgument::Type:
00919       OS << " type";
00920       dumpType(A.getAsType());
00921       break;
00922     case TemplateArgument::Declaration:
00923       OS << " decl";
00924       dumpDeclRef(A.getAsDecl());
00925       break;
00926     case TemplateArgument::NullPtr:
00927       OS << " nullptr";
00928       break;
00929     case TemplateArgument::Integral:
00930       OS << " integral " << A.getAsIntegral();
00931       break;
00932     case TemplateArgument::Template:
00933       OS << " template ";
00934       A.getAsTemplate().dump(OS);
00935       break;
00936     case TemplateArgument::TemplateExpansion:
00937       OS << " template expansion";
00938       A.getAsTemplateOrTemplatePattern().dump(OS);
00939       break;
00940     case TemplateArgument::Expression:
00941       OS << " expr";
00942       dumpStmt(A.getAsExpr());
00943       break;
00944     case TemplateArgument::Pack:
00945       OS << " pack";
00946       for (TemplateArgument::pack_iterator I = A.pack_begin(), E = A.pack_end();
00947            I != E; ++I)
00948         dumpTemplateArgument(*I);
00949       break;
00950     }
00951   });
00952 }
00953 
00954 //===----------------------------------------------------------------------===//
00955 //  Decl dumping methods.
00956 //===----------------------------------------------------------------------===//
00957 
00958 void ASTDumper::dumpDecl(const Decl *D) {
00959   dumpChild([=] {
00960     if (!D) {
00961       ColorScope Color(*this, NullColor);
00962       OS << "<<<NULL>>>";
00963       return;
00964     }
00965 
00966     {
00967       ColorScope Color(*this, DeclKindNameColor);
00968       OS << D->getDeclKindName() << "Decl";
00969     }
00970     dumpPointer(D);
00971     if (D->getLexicalDeclContext() != D->getDeclContext())
00972       OS << " parent " << cast<Decl>(D->getDeclContext());
00973     dumpPreviousDecl(OS, D);
00974     dumpSourceRange(D->getSourceRange());
00975     OS << ' ';
00976     dumpLocation(D->getLocation());
00977     if (Module *M = D->getOwningModule())
00978       OS << " in " << M->getFullModuleName();
00979     if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
00980       if (ND->isHidden())
00981         OS << " hidden";
00982     if (D->isImplicit())
00983       OS << " implicit";
00984     if (D->isUsed())
00985       OS << " used";
00986     else if (D->isThisDeclarationReferenced())
00987       OS << " referenced";
00988     if (D->isInvalidDecl())
00989       OS << " invalid";
00990 
00991     ConstDeclVisitor<ASTDumper>::Visit(D);
00992 
00993     for (Decl::attr_iterator I = D->attr_begin(), E = D->attr_end(); I != E;
00994          ++I)
00995       dumpAttr(*I);
00996 
00997     if (const FullComment *Comment =
00998             D->getASTContext().getLocalCommentForDeclUncached(D))
00999       dumpFullComment(Comment);
01000 
01001     // Decls within functions are visited by the body.
01002     if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D) &&
01003         hasNodes(dyn_cast<DeclContext>(D)))
01004       dumpDeclContext(cast<DeclContext>(D));
01005   });
01006 }
01007 
01008 void ASTDumper::VisitLabelDecl(const LabelDecl *D) {
01009   dumpName(D);
01010 }
01011 
01012 void ASTDumper::VisitTypedefDecl(const TypedefDecl *D) {
01013   dumpName(D);
01014   dumpType(D->getUnderlyingType());
01015   if (D->isModulePrivate())
01016     OS << " __module_private__";
01017 }
01018 
01019 void ASTDumper::VisitEnumDecl(const EnumDecl *D) {
01020   if (D->isScoped()) {
01021     if (D->isScopedUsingClassTag())
01022       OS << " class";
01023     else
01024       OS << " struct";
01025   }
01026   dumpName(D);
01027   if (D->isModulePrivate())
01028     OS << " __module_private__";
01029   if (D->isFixed())
01030     dumpType(D->getIntegerType());
01031 }
01032 
01033 void ASTDumper::VisitRecordDecl(const RecordDecl *D) {
01034   OS << ' ' << D->getKindName();
01035   dumpName(D);
01036   if (D->isModulePrivate())
01037     OS << " __module_private__";
01038   if (D->isCompleteDefinition())
01039     OS << " definition";
01040 }
01041 
01042 void ASTDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) {
01043   dumpName(D);
01044   dumpType(D->getType());
01045   if (const Expr *Init = D->getInitExpr())
01046     dumpStmt(Init);
01047 }
01048 
01049 void ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) {
01050   dumpName(D);
01051   dumpType(D->getType());
01052 
01053   for (auto *Child : D->chain())
01054     dumpDeclRef(Child);
01055 }
01056 
01057 void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) {
01058   dumpName(D);
01059   dumpType(D->getType());
01060 
01061   StorageClass SC = D->getStorageClass();
01062   if (SC != SC_None)
01063     OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
01064   if (D->isInlineSpecified())
01065     OS << " inline";
01066   if (D->isVirtualAsWritten())
01067     OS << " virtual";
01068   if (D->isModulePrivate())
01069     OS << " __module_private__";
01070 
01071   if (D->isPure())
01072     OS << " pure";
01073   else if (D->isDeletedAsWritten())
01074     OS << " delete";
01075 
01076   if (const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>()) {
01077     FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
01078     switch (EPI.ExceptionSpec.Type) {
01079     default: break;
01080     case EST_Unevaluated:
01081       OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl;
01082       break;
01083     case EST_Uninstantiated:
01084       OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate;
01085       break;
01086     }
01087   }
01088 
01089   if (const FunctionTemplateSpecializationInfo *FTSI =
01090           D->getTemplateSpecializationInfo())
01091     dumpTemplateArgumentList(*FTSI->TemplateArguments);
01092 
01093   for (ArrayRef<NamedDecl *>::iterator
01094        I = D->getDeclsInPrototypeScope().begin(),
01095        E = D->getDeclsInPrototypeScope().end(); I != E; ++I)
01096     dumpDecl(*I);
01097 
01098   for (FunctionDecl::param_const_iterator I = D->param_begin(),
01099                                           E = D->param_end();
01100        I != E; ++I)
01101     dumpDecl(*I);
01102 
01103   if (const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(D))
01104     for (CXXConstructorDecl::init_const_iterator I = C->init_begin(),
01105                                                  E = C->init_end();
01106          I != E; ++I)
01107       dumpCXXCtorInitializer(*I);
01108 
01109   if (D->doesThisDeclarationHaveABody())
01110     dumpStmt(D->getBody());
01111 }
01112 
01113 void ASTDumper::VisitFieldDecl(const FieldDecl *D) {
01114   dumpName(D);
01115   dumpType(D->getType());
01116   if (D->isMutable())
01117     OS << " mutable";
01118   if (D->isModulePrivate())
01119     OS << " __module_private__";
01120 
01121   if (D->isBitField())
01122     dumpStmt(D->getBitWidth());
01123   if (Expr *Init = D->getInClassInitializer())
01124     dumpStmt(Init);
01125 }
01126 
01127 void ASTDumper::VisitVarDecl(const VarDecl *D) {
01128   dumpName(D);
01129   dumpType(D->getType());
01130   StorageClass SC = D->getStorageClass();
01131   if (SC != SC_None)
01132     OS << ' ' << VarDecl::getStorageClassSpecifierString(SC);
01133   switch (D->getTLSKind()) {
01134   case VarDecl::TLS_None: break;
01135   case VarDecl::TLS_Static: OS << " tls"; break;
01136   case VarDecl::TLS_Dynamic: OS << " tls_dynamic"; break;
01137   }
01138   if (D->isModulePrivate())
01139     OS << " __module_private__";
01140   if (D->isNRVOVariable())
01141     OS << " nrvo";
01142   if (D->hasInit()) {
01143     switch (D->getInitStyle()) {
01144     case VarDecl::CInit: OS << " cinit"; break;
01145     case VarDecl::CallInit: OS << " callinit"; break;
01146     case VarDecl::ListInit: OS << " listinit"; break;
01147     }
01148     dumpStmt(D->getInit());
01149   }
01150 }
01151 
01152 void ASTDumper::VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) {
01153   dumpStmt(D->getAsmString());
01154 }
01155 
01156 void ASTDumper::VisitImportDecl(const ImportDecl *D) {
01157   OS << ' ' << D->getImportedModule()->getFullModuleName();
01158 }
01159 
01160 //===----------------------------------------------------------------------===//
01161 // C++ Declarations
01162 //===----------------------------------------------------------------------===//
01163 
01164 void ASTDumper::VisitNamespaceDecl(const NamespaceDecl *D) {
01165   dumpName(D);
01166   if (D->isInline())
01167     OS << " inline";
01168   if (!D->isOriginalNamespace())
01169     dumpDeclRef(D->getOriginalNamespace(), "original");
01170 }
01171 
01172 void ASTDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
01173   OS << ' ';
01174   dumpBareDeclRef(D->getNominatedNamespace());
01175 }
01176 
01177 void ASTDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
01178   dumpName(D);
01179   dumpDeclRef(D->getAliasedNamespace());
01180 }
01181 
01182 void ASTDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) {
01183   dumpName(D);
01184   dumpType(D->getUnderlyingType());
01185 }
01186 
01187 void ASTDumper::VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {
01188   dumpName(D);
01189   dumpTemplateParameters(D->getTemplateParameters());
01190   dumpDecl(D->getTemplatedDecl());
01191 }
01192 
01193 void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
01194   VisitRecordDecl(D);
01195   if (!D->isCompleteDefinition())
01196     return;
01197 
01198   for (const auto &I : D->bases()) {
01199     dumpChild([=] {
01200       if (I.isVirtual())
01201         OS << "virtual ";
01202       dumpAccessSpecifier(I.getAccessSpecifier());
01203       dumpType(I.getType());
01204       if (I.isPackExpansion())
01205         OS << "...";
01206     });
01207   }
01208 }
01209 
01210 void ASTDumper::VisitStaticAssertDecl(const StaticAssertDecl *D) {
01211   dumpStmt(D->getAssertExpr());
01212   dumpStmt(D->getMessage());
01213 }
01214 
01215 template<typename SpecializationDecl>
01216 void ASTDumper::VisitTemplateDeclSpecialization(const SpecializationDecl *D,
01217                                                 bool DumpExplicitInst,
01218                                                 bool DumpRefOnly) {
01219   bool DumpedAny = false;
01220   for (auto *RedeclWithBadType : D->redecls()) {
01221     // FIXME: The redecls() range sometimes has elements of a less-specific
01222     // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
01223     // us TagDecls, and should give CXXRecordDecls).
01224     auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
01225     if (!Redecl) {
01226       // Found the injected-class-name for a class template. This will be dumped
01227       // as part of its surrounding class so we don't need to dump it here.
01228       assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
01229              "expected an injected-class-name");
01230       continue;
01231     }
01232 
01233     switch (Redecl->getTemplateSpecializationKind()) {
01234     case TSK_ExplicitInstantiationDeclaration:
01235     case TSK_ExplicitInstantiationDefinition:
01236       if (!DumpExplicitInst)
01237         break;
01238       // Fall through.
01239     case TSK_Undeclared:
01240     case TSK_ImplicitInstantiation:
01241       if (DumpRefOnly)
01242         dumpDeclRef(Redecl);
01243       else
01244         dumpDecl(Redecl);
01245       DumpedAny = true;
01246       break;
01247     case TSK_ExplicitSpecialization:
01248       break;
01249     }
01250   }
01251 
01252   // Ensure we dump at least one decl for each specialization.
01253   if (!DumpedAny)
01254     dumpDeclRef(D);
01255 }
01256 
01257 template<typename TemplateDecl>
01258 void ASTDumper::VisitTemplateDecl(const TemplateDecl *D,
01259                                   bool DumpExplicitInst) {
01260   dumpName(D);
01261   dumpTemplateParameters(D->getTemplateParameters());
01262 
01263   dumpDecl(D->getTemplatedDecl());
01264 
01265   for (auto *Child : D->specializations())
01266     VisitTemplateDeclSpecialization(Child, DumpExplicitInst,
01267                                     !D->isCanonicalDecl());
01268 }
01269 
01270 void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
01271   // FIXME: We don't add a declaration of a function template specialization
01272   // to its context when it's explicitly instantiated, so dump explicit
01273   // instantiations when we dump the template itself.
01274   VisitTemplateDecl(D, true);
01275 }
01276 
01277 void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
01278   VisitTemplateDecl(D, false);
01279 }
01280 
01281 void ASTDumper::VisitClassTemplateSpecializationDecl(
01282     const ClassTemplateSpecializationDecl *D) {
01283   VisitCXXRecordDecl(D);
01284   dumpTemplateArgumentList(D->getTemplateArgs());
01285 }
01286 
01287 void ASTDumper::VisitClassTemplatePartialSpecializationDecl(
01288     const ClassTemplatePartialSpecializationDecl *D) {
01289   VisitClassTemplateSpecializationDecl(D);
01290   dumpTemplateParameters(D->getTemplateParameters());
01291 }
01292 
01293 void ASTDumper::VisitClassScopeFunctionSpecializationDecl(
01294     const ClassScopeFunctionSpecializationDecl *D) {
01295   dumpDeclRef(D->getSpecialization());
01296   if (D->hasExplicitTemplateArgs())
01297     dumpTemplateArgumentListInfo(D->templateArgs());
01298 }
01299 
01300 void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
01301   VisitTemplateDecl(D, false);
01302 }
01303 
01304 void ASTDumper::VisitVarTemplateSpecializationDecl(
01305     const VarTemplateSpecializationDecl *D) {
01306   dumpTemplateArgumentList(D->getTemplateArgs());
01307   VisitVarDecl(D);
01308 }
01309 
01310 void ASTDumper::VisitVarTemplatePartialSpecializationDecl(
01311     const VarTemplatePartialSpecializationDecl *D) {
01312   dumpTemplateParameters(D->getTemplateParameters());
01313   VisitVarTemplateSpecializationDecl(D);
01314 }
01315 
01316 void ASTDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
01317   if (D->wasDeclaredWithTypename())
01318     OS << " typename";
01319   else
01320     OS << " class";
01321   if (D->isParameterPack())
01322     OS << " ...";
01323   dumpName(D);
01324   if (D->hasDefaultArgument())
01325     dumpTemplateArgument(D->getDefaultArgument());
01326 }
01327 
01328 void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
01329   dumpType(D->getType());
01330   if (D->isParameterPack())
01331     OS << " ...";
01332   dumpName(D);
01333   if (D->hasDefaultArgument())
01334     dumpTemplateArgument(D->getDefaultArgument());
01335 }
01336 
01337 void ASTDumper::VisitTemplateTemplateParmDecl(
01338     const TemplateTemplateParmDecl *D) {
01339   if (D->isParameterPack())
01340     OS << " ...";
01341   dumpName(D);
01342   dumpTemplateParameters(D->getTemplateParameters());
01343   if (D->hasDefaultArgument())
01344     dumpTemplateArgumentLoc(D->getDefaultArgument());
01345 }
01346 
01347 void ASTDumper::VisitUsingDecl(const UsingDecl *D) {
01348   OS << ' ';
01349   D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
01350   OS << D->getNameAsString();
01351 }
01352 
01353 void ASTDumper::VisitUnresolvedUsingTypenameDecl(
01354     const UnresolvedUsingTypenameDecl *D) {
01355   OS << ' ';
01356   D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
01357   OS << D->getNameAsString();
01358 }
01359 
01360 void ASTDumper::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
01361   OS << ' ';
01362   D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
01363   OS << D->getNameAsString();
01364   dumpType(D->getType());
01365 }
01366 
01367 void ASTDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) {
01368   OS << ' ';
01369   dumpBareDeclRef(D->getTargetDecl());
01370 }
01371 
01372 void ASTDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
01373   switch (D->getLanguage()) {
01374   case LinkageSpecDecl::lang_c: OS << " C"; break;
01375   case LinkageSpecDecl::lang_cxx: OS << " C++"; break;
01376   }
01377 }
01378 
01379 void ASTDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
01380   OS << ' ';
01381   dumpAccessSpecifier(D->getAccess());
01382 }
01383 
01384 void ASTDumper::VisitFriendDecl(const FriendDecl *D) {
01385   if (TypeSourceInfo *T = D->getFriendType())
01386     dumpType(T->getType());
01387   else
01388     dumpDecl(D->getFriendDecl());
01389 }
01390 
01391 //===----------------------------------------------------------------------===//
01392 // Obj-C Declarations
01393 //===----------------------------------------------------------------------===//
01394 
01395 void ASTDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) {
01396   dumpName(D);
01397   dumpType(D->getType());
01398   if (D->getSynthesize())
01399     OS << " synthesize";
01400 
01401   switch (D->getAccessControl()) {
01402   case ObjCIvarDecl::None:
01403     OS << " none";
01404     break;
01405   case ObjCIvarDecl::Private:
01406     OS << " private";
01407     break;
01408   case ObjCIvarDecl::Protected:
01409     OS << " protected";
01410     break;
01411   case ObjCIvarDecl::Public:
01412     OS << " public";
01413     break;
01414   case ObjCIvarDecl::Package:
01415     OS << " package";
01416     break;
01417   }
01418 }
01419 
01420 void ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
01421   if (D->isInstanceMethod())
01422     OS << " -";
01423   else
01424     OS << " +";
01425   dumpName(D);
01426   dumpType(D->getReturnType());
01427 
01428   if (D->isThisDeclarationADefinition()) {
01429     dumpDeclContext(D);
01430   } else {
01431     for (ObjCMethodDecl::param_const_iterator I = D->param_begin(),
01432                                               E = D->param_end();
01433          I != E; ++I)
01434       dumpDecl(*I);
01435   }
01436 
01437   if (D->isVariadic())
01438     dumpChild([=] { OS << "..."; });
01439 
01440   if (D->hasBody())
01441     dumpStmt(D->getBody());
01442 }
01443 
01444 void ASTDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
01445   dumpName(D);
01446   dumpDeclRef(D->getClassInterface());
01447   dumpDeclRef(D->getImplementation());
01448   for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(),
01449                                            E = D->protocol_end();
01450        I != E; ++I)
01451     dumpDeclRef(*I);
01452 }
01453 
01454 void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) {
01455   dumpName(D);
01456   dumpDeclRef(D->getClassInterface());
01457   dumpDeclRef(D->getCategoryDecl());
01458 }
01459 
01460 void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
01461   dumpName(D);
01462 
01463   for (auto *Child : D->protocols())
01464     dumpDeclRef(Child);
01465 }
01466 
01467 void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
01468   dumpName(D);
01469   dumpDeclRef(D->getSuperClass(), "super");
01470 
01471   dumpDeclRef(D->getImplementation());
01472   for (auto *Child : D->protocols())
01473     dumpDeclRef(Child);
01474 }
01475 
01476 void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
01477   dumpName(D);
01478   dumpDeclRef(D->getSuperClass(), "super");
01479   dumpDeclRef(D->getClassInterface());
01480   for (ObjCImplementationDecl::init_const_iterator I = D->init_begin(),
01481                                                    E = D->init_end();
01482        I != E; ++I)
01483     dumpCXXCtorInitializer(*I);
01484 }
01485 
01486 void ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) {
01487   dumpName(D);
01488   dumpDeclRef(D->getClassInterface());
01489 }
01490 
01491 void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
01492   dumpName(D);
01493   dumpType(D->getType());
01494 
01495   if (D->getPropertyImplementation() == ObjCPropertyDecl::Required)
01496     OS << " required";
01497   else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional)
01498     OS << " optional";
01499 
01500   ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes();
01501   if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) {
01502     if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly)
01503       OS << " readonly";
01504     if (Attrs & ObjCPropertyDecl::OBJC_PR_assign)
01505       OS << " assign";
01506     if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite)
01507       OS << " readwrite";
01508     if (Attrs & ObjCPropertyDecl::OBJC_PR_retain)
01509       OS << " retain";
01510     if (Attrs & ObjCPropertyDecl::OBJC_PR_copy)
01511       OS << " copy";
01512     if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic)
01513       OS << " nonatomic";
01514     if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic)
01515       OS << " atomic";
01516     if (Attrs & ObjCPropertyDecl::OBJC_PR_weak)
01517       OS << " weak";
01518     if (Attrs & ObjCPropertyDecl::OBJC_PR_strong)
01519       OS << " strong";
01520     if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained)
01521       OS << " unsafe_unretained";
01522     if (Attrs & ObjCPropertyDecl::OBJC_PR_getter)
01523       dumpDeclRef(D->getGetterMethodDecl(), "getter");
01524     if (Attrs & ObjCPropertyDecl::OBJC_PR_setter)
01525       dumpDeclRef(D->getSetterMethodDecl(), "setter");
01526   }
01527 }
01528 
01529 void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
01530   dumpName(D->getPropertyDecl());
01531   if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
01532     OS << " synthesize";
01533   else
01534     OS << " dynamic";
01535   dumpDeclRef(D->getPropertyDecl());
01536   dumpDeclRef(D->getPropertyIvarDecl());
01537 }
01538 
01539 void ASTDumper::VisitBlockDecl(const BlockDecl *D) {
01540   for (auto I : D->params())
01541     dumpDecl(I);
01542 
01543   if (D->isVariadic())
01544     dumpChild([=]{ OS << "..."; });
01545 
01546   if (D->capturesCXXThis())
01547     dumpChild([=]{ OS << "capture this"; });
01548 
01549   for (const auto &I : D->captures()) {
01550     dumpChild([=] {
01551       OS << "capture";
01552       if (I.isByRef())
01553         OS << " byref";
01554       if (I.isNested())
01555         OS << " nested";
01556       if (I.getVariable()) {
01557         OS << ' ';
01558         dumpBareDeclRef(I.getVariable());
01559       }
01560       if (I.hasCopyExpr())
01561         dumpStmt(I.getCopyExpr());
01562     });
01563   }
01564   dumpStmt(D->getBody());
01565 }
01566 
01567 //===----------------------------------------------------------------------===//
01568 //  Stmt dumping methods.
01569 //===----------------------------------------------------------------------===//
01570 
01571 void ASTDumper::dumpStmt(const Stmt *S) {
01572   dumpChild([=] {
01573     if (!S) {
01574       ColorScope Color(*this, NullColor);
01575       OS << "<<<NULL>>>";
01576       return;
01577     }
01578 
01579     if (const DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
01580       VisitDeclStmt(DS);
01581       return;
01582     }
01583 
01584     ConstStmtVisitor<ASTDumper>::Visit(S);
01585 
01586     for (Stmt::const_child_range CI = S->children(); CI; ++CI)
01587       dumpStmt(*CI);
01588   });
01589 }
01590 
01591 void ASTDumper::VisitStmt(const Stmt *Node) {
01592   {   
01593     ColorScope Color(*this, StmtColor);
01594     OS << Node->getStmtClassName();
01595   }
01596   dumpPointer(Node);
01597   dumpSourceRange(Node->getSourceRange());
01598 }
01599 
01600 void ASTDumper::VisitDeclStmt(const DeclStmt *Node) {
01601   VisitStmt(Node);
01602   for (DeclStmt::const_decl_iterator I = Node->decl_begin(),
01603                                      E = Node->decl_end();
01604        I != E; ++I)
01605     dumpDecl(*I);
01606 }
01607 
01608 void ASTDumper::VisitAttributedStmt(const AttributedStmt *Node) {
01609   VisitStmt(Node);
01610   for (ArrayRef<const Attr *>::iterator I = Node->getAttrs().begin(),
01611                                         E = Node->getAttrs().end();
01612        I != E; ++I)
01613     dumpAttr(*I);
01614 }
01615 
01616 void ASTDumper::VisitLabelStmt(const LabelStmt *Node) {
01617   VisitStmt(Node);
01618   OS << " '" << Node->getName() << "'";
01619 }
01620 
01621 void ASTDumper::VisitGotoStmt(const GotoStmt *Node) {
01622   VisitStmt(Node);
01623   OS << " '" << Node->getLabel()->getName() << "'";
01624   dumpPointer(Node->getLabel());
01625 }
01626 
01627 void ASTDumper::VisitCXXCatchStmt(const CXXCatchStmt *Node) {
01628   VisitStmt(Node);
01629   dumpDecl(Node->getExceptionDecl());
01630 }
01631 
01632 //===----------------------------------------------------------------------===//
01633 //  Expr dumping methods.
01634 //===----------------------------------------------------------------------===//
01635 
01636 void ASTDumper::VisitExpr(const Expr *Node) {
01637   VisitStmt(Node);
01638   dumpType(Node->getType());
01639 
01640   {
01641     ColorScope Color(*this, ValueKindColor);
01642     switch (Node->getValueKind()) {
01643     case VK_RValue:
01644       break;
01645     case VK_LValue:
01646       OS << " lvalue";
01647       break;
01648     case VK_XValue:
01649       OS << " xvalue";
01650       break;
01651     }
01652   }
01653 
01654   {
01655     ColorScope Color(*this, ObjectKindColor);
01656     switch (Node->getObjectKind()) {
01657     case OK_Ordinary:
01658       break;
01659     case OK_BitField:
01660       OS << " bitfield";
01661       break;
01662     case OK_ObjCProperty:
01663       OS << " objcproperty";
01664       break;
01665     case OK_ObjCSubscript:
01666       OS << " objcsubscript";
01667       break;
01668     case OK_VectorComponent:
01669       OS << " vectorcomponent";
01670       break;
01671     }
01672   }
01673 }
01674 
01675 static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
01676   if (Node->path_empty())
01677     return;
01678 
01679   OS << " (";
01680   bool First = true;
01681   for (CastExpr::path_const_iterator I = Node->path_begin(),
01682                                      E = Node->path_end();
01683        I != E; ++I) {
01684     const CXXBaseSpecifier *Base = *I;
01685     if (!First)
01686       OS << " -> ";
01687 
01688     const CXXRecordDecl *RD =
01689     cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
01690 
01691     if (Base->isVirtual())
01692       OS << "virtual ";
01693     OS << RD->getName();
01694     First = false;
01695   }
01696 
01697   OS << ')';
01698 }
01699 
01700 void ASTDumper::VisitCastExpr(const CastExpr *Node) {
01701   VisitExpr(Node);
01702   OS << " <";
01703   {
01704     ColorScope Color(*this, CastColor);
01705     OS << Node->getCastKindName();
01706   }
01707   dumpBasePath(OS, Node);
01708   OS << ">";
01709 }
01710 
01711 void ASTDumper::VisitDeclRefExpr(const DeclRefExpr *Node) {
01712   VisitExpr(Node);
01713 
01714   OS << " ";
01715   dumpBareDeclRef(Node->getDecl());
01716   if (Node->getDecl() != Node->getFoundDecl()) {
01717     OS << " (";
01718     dumpBareDeclRef(Node->getFoundDecl());
01719     OS << ")";
01720   }
01721 }
01722 
01723 void ASTDumper::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node) {
01724   VisitExpr(Node);
01725   OS << " (";
01726   if (!Node->requiresADL())
01727     OS << "no ";
01728   OS << "ADL) = '" << Node->getName() << '\'';
01729 
01730   UnresolvedLookupExpr::decls_iterator
01731     I = Node->decls_begin(), E = Node->decls_end();
01732   if (I == E)
01733     OS << " empty";
01734   for (; I != E; ++I)
01735     dumpPointer(*I);
01736 }
01737 
01738 void ASTDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) {
01739   VisitExpr(Node);
01740 
01741   {
01742     ColorScope Color(*this, DeclKindNameColor);
01743     OS << " " << Node->getDecl()->getDeclKindName() << "Decl";
01744   }
01745   OS << "='" << *Node->getDecl() << "'";
01746   dumpPointer(Node->getDecl());
01747   if (Node->isFreeIvar())
01748     OS << " isFreeIvar";
01749 }
01750 
01751 void ASTDumper::VisitPredefinedExpr(const PredefinedExpr *Node) {
01752   VisitExpr(Node);
01753   OS << " " << PredefinedExpr::getIdentTypeName(Node->getIdentType());
01754 }
01755 
01756 void ASTDumper::VisitCharacterLiteral(const CharacterLiteral *Node) {
01757   VisitExpr(Node);
01758   ColorScope Color(*this, ValueColor);
01759   OS << " " << Node->getValue();
01760 }
01761 
01762 void ASTDumper::VisitIntegerLiteral(const IntegerLiteral *Node) {
01763   VisitExpr(Node);
01764 
01765   bool isSigned = Node->getType()->isSignedIntegerType();
01766   ColorScope Color(*this, ValueColor);
01767   OS << " " << Node->getValue().toString(10, isSigned);
01768 }
01769 
01770 void ASTDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
01771   VisitExpr(Node);
01772   ColorScope Color(*this, ValueColor);
01773   OS << " " << Node->getValueAsApproximateDouble();
01774 }
01775 
01776 void ASTDumper::VisitStringLiteral(const StringLiteral *Str) {
01777   VisitExpr(Str);
01778   ColorScope Color(*this, ValueColor);
01779   OS << " ";
01780   Str->outputString(OS);
01781 }
01782 
01783 void ASTDumper::VisitInitListExpr(const InitListExpr *ILE) {
01784   VisitExpr(ILE);
01785   if (auto *Filler = ILE->getArrayFiller()) {
01786     dumpChild([=] {
01787       OS << "array filler";
01788       dumpStmt(Filler);
01789     });
01790   }
01791   if (auto *Field = ILE->getInitializedFieldInUnion()) {
01792     OS << " field ";
01793     dumpBareDeclRef(Field);
01794   }
01795 }
01796 
01797 void ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) {
01798   VisitExpr(Node);
01799   OS << " " << (Node->isPostfix() ? "postfix" : "prefix")
01800      << " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
01801 }
01802 
01803 void ASTDumper::VisitUnaryExprOrTypeTraitExpr(
01804     const UnaryExprOrTypeTraitExpr *Node) {
01805   VisitExpr(Node);
01806   switch(Node->getKind()) {
01807   case UETT_SizeOf:
01808     OS << " sizeof";
01809     break;
01810   case UETT_AlignOf:
01811     OS << " alignof";
01812     break;
01813   case UETT_VecStep:
01814     OS << " vec_step";
01815     break;
01816   }
01817   if (Node->isArgumentType())
01818     dumpType(Node->getArgumentType());
01819 }
01820 
01821 void ASTDumper::VisitMemberExpr(const MemberExpr *Node) {
01822   VisitExpr(Node);
01823   OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl();
01824   dumpPointer(Node->getMemberDecl());
01825 }
01826 
01827 void ASTDumper::VisitExtVectorElementExpr(const ExtVectorElementExpr *Node) {
01828   VisitExpr(Node);
01829   OS << " " << Node->getAccessor().getNameStart();
01830 }
01831 
01832 void ASTDumper::VisitBinaryOperator(const BinaryOperator *Node) {
01833   VisitExpr(Node);
01834   OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'";
01835 }
01836 
01837 void ASTDumper::VisitCompoundAssignOperator(
01838     const CompoundAssignOperator *Node) {
01839   VisitExpr(Node);
01840   OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode())
01841      << "' ComputeLHSTy=";
01842   dumpBareType(Node->getComputationLHSType());
01843   OS << " ComputeResultTy=";
01844   dumpBareType(Node->getComputationResultType());
01845 }
01846 
01847 void ASTDumper::VisitBlockExpr(const BlockExpr *Node) {
01848   VisitExpr(Node);
01849   dumpDecl(Node->getBlockDecl());
01850 }
01851 
01852 void ASTDumper::VisitOpaqueValueExpr(const OpaqueValueExpr *Node) {
01853   VisitExpr(Node);
01854 
01855   if (Expr *Source = Node->getSourceExpr())
01856     dumpStmt(Source);
01857 }
01858 
01859 // GNU extensions.
01860 
01861 void ASTDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) {
01862   VisitExpr(Node);
01863   OS << " " << Node->getLabel()->getName();
01864   dumpPointer(Node->getLabel());
01865 }
01866 
01867 //===----------------------------------------------------------------------===//
01868 // C++ Expressions
01869 //===----------------------------------------------------------------------===//
01870 
01871 void ASTDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) {
01872   VisitExpr(Node);
01873   OS << " " << Node->getCastName()
01874      << "<" << Node->getTypeAsWritten().getAsString() << ">"
01875      << " <" << Node->getCastKindName();
01876   dumpBasePath(OS, Node);
01877   OS << ">";
01878 }
01879 
01880 void ASTDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) {
01881   VisitExpr(Node);
01882   OS << " " << (Node->getValue() ? "true" : "false");
01883 }
01884 
01885 void ASTDumper::VisitCXXThisExpr(const CXXThisExpr *Node) {
01886   VisitExpr(Node);
01887   OS << " this";
01888 }
01889 
01890 void ASTDumper::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node) {
01891   VisitExpr(Node);
01892   OS << " functional cast to " << Node->getTypeAsWritten().getAsString()
01893      << " <" << Node->getCastKindName() << ">";
01894 }
01895 
01896 void ASTDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) {
01897   VisitExpr(Node);
01898   CXXConstructorDecl *Ctor = Node->getConstructor();
01899   dumpType(Ctor->getType());
01900   if (Node->isElidable())
01901     OS << " elidable";
01902   if (Node->requiresZeroInitialization())
01903     OS << " zeroing";
01904 }
01905 
01906 void ASTDumper::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node) {
01907   VisitExpr(Node);
01908   OS << " ";
01909   dumpCXXTemporary(Node->getTemporary());
01910 }
01911 
01912 void
01913 ASTDumper::VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node) {
01914   VisitExpr(Node);
01915   if (const ValueDecl *VD = Node->getExtendingDecl()) {
01916     OS << " extended by ";
01917     dumpBareDeclRef(VD);
01918   }
01919 }
01920 
01921 void ASTDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) {
01922   VisitExpr(Node);
01923   for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i)
01924     dumpDeclRef(Node->getObject(i), "cleanup");
01925 }
01926 
01927 void ASTDumper::dumpCXXTemporary(const CXXTemporary *Temporary) {
01928   OS << "(CXXTemporary";
01929   dumpPointer(Temporary);
01930   OS << ")";
01931 }
01932 
01933 //===----------------------------------------------------------------------===//
01934 // Obj-C Expressions
01935 //===----------------------------------------------------------------------===//
01936 
01937 void ASTDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) {
01938   VisitExpr(Node);
01939   OS << " selector=";
01940   Node->getSelector().print(OS);
01941   switch (Node->getReceiverKind()) {
01942   case ObjCMessageExpr::Instance:
01943     break;
01944 
01945   case ObjCMessageExpr::Class:
01946     OS << " class=";
01947     dumpBareType(Node->getClassReceiver());
01948     break;
01949 
01950   case ObjCMessageExpr::SuperInstance:
01951     OS << " super (instance)";
01952     break;
01953 
01954   case ObjCMessageExpr::SuperClass:
01955     OS << " super (class)";
01956     break;
01957   }
01958 }
01959 
01960 void ASTDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) {
01961   VisitExpr(Node);
01962   OS << " selector=";
01963   Node->getBoxingMethod()->getSelector().print(OS);
01964 }
01965 
01966 void ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
01967   VisitStmt(Node);
01968   if (const VarDecl *CatchParam = Node->getCatchParamDecl())
01969     dumpDecl(CatchParam);
01970   else
01971     OS << " catch all";
01972 }
01973 
01974 void ASTDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) {
01975   VisitExpr(Node);
01976   dumpType(Node->getEncodedType());
01977 }
01978 
01979 void ASTDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) {
01980   VisitExpr(Node);
01981 
01982   OS << " ";
01983   Node->getSelector().print(OS);
01984 }
01985 
01986 void ASTDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) {
01987   VisitExpr(Node);
01988 
01989   OS << ' ' << *Node->getProtocol();
01990 }
01991 
01992 void ASTDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) {
01993   VisitExpr(Node);
01994   if (Node->isImplicitProperty()) {
01995     OS << " Kind=MethodRef Getter=\"";
01996     if (Node->getImplicitPropertyGetter())
01997       Node->getImplicitPropertyGetter()->getSelector().print(OS);
01998     else
01999       OS << "(null)";
02000 
02001     OS << "\" Setter=\"";
02002     if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter())
02003       Setter->getSelector().print(OS);
02004     else
02005       OS << "(null)";
02006     OS << "\"";
02007   } else {
02008     OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty() <<'"';
02009   }
02010 
02011   if (Node->isSuperReceiver())
02012     OS << " super";
02013 
02014   OS << " Messaging=";
02015   if (Node->isMessagingGetter() && Node->isMessagingSetter())
02016     OS << "Getter&Setter";
02017   else if (Node->isMessagingGetter())
02018     OS << "Getter";
02019   else if (Node->isMessagingSetter())
02020     OS << "Setter";
02021 }
02022 
02023 void ASTDumper::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node) {
02024   VisitExpr(Node);
02025   if (Node->isArraySubscriptRefExpr())
02026     OS << " Kind=ArraySubscript GetterForArray=\"";
02027   else
02028     OS << " Kind=DictionarySubscript GetterForDictionary=\"";
02029   if (Node->getAtIndexMethodDecl())
02030     Node->getAtIndexMethodDecl()->getSelector().print(OS);
02031   else
02032     OS << "(null)";
02033 
02034   if (Node->isArraySubscriptRefExpr())
02035     OS << "\" SetterForArray=\"";
02036   else
02037     OS << "\" SetterForDictionary=\"";
02038   if (Node->setAtIndexMethodDecl())
02039     Node->setAtIndexMethodDecl()->getSelector().print(OS);
02040   else
02041     OS << "(null)";
02042 }
02043 
02044 void ASTDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) {
02045   VisitExpr(Node);
02046   OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no");
02047 }
02048 
02049 //===----------------------------------------------------------------------===//
02050 // Comments
02051 //===----------------------------------------------------------------------===//
02052 
02053 const char *ASTDumper::getCommandName(unsigned CommandID) {
02054   if (Traits)
02055     return Traits->getCommandInfo(CommandID)->Name;
02056   const CommandInfo *Info = CommandTraits::getBuiltinCommandInfo(CommandID);
02057   if (Info)
02058     return Info->Name;
02059   return "<not a builtin command>";
02060 }
02061 
02062 void ASTDumper::dumpFullComment(const FullComment *C) {
02063   if (!C)
02064     return;
02065 
02066   FC = C;
02067   dumpComment(C);
02068   FC = nullptr;
02069 }
02070 
02071 void ASTDumper::dumpComment(const Comment *C) {
02072   dumpChild([=] {
02073     if (!C) {
02074       ColorScope Color(*this, NullColor);
02075       OS << "<<<NULL>>>";
02076       return;
02077     }
02078 
02079     {
02080       ColorScope Color(*this, CommentColor);
02081       OS << C->getCommentKindName();
02082     }
02083     dumpPointer(C);
02084     dumpSourceRange(C->getSourceRange());
02085     ConstCommentVisitor<ASTDumper>::visit(C);
02086     for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
02087          I != E; ++I)
02088       dumpComment(*I);
02089   });
02090 }
02091 
02092 void ASTDumper::visitTextComment(const TextComment *C) {
02093   OS << " Text=\"" << C->getText() << "\"";
02094 }
02095 
02096 void ASTDumper::visitInlineCommandComment(const InlineCommandComment *C) {
02097   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
02098   switch (C->getRenderKind()) {
02099   case InlineCommandComment::RenderNormal:
02100     OS << " RenderNormal";
02101     break;
02102   case InlineCommandComment::RenderBold:
02103     OS << " RenderBold";
02104     break;
02105   case InlineCommandComment::RenderMonospaced:
02106     OS << " RenderMonospaced";
02107     break;
02108   case InlineCommandComment::RenderEmphasized:
02109     OS << " RenderEmphasized";
02110     break;
02111   }
02112 
02113   for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
02114     OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
02115 }
02116 
02117 void ASTDumper::visitHTMLStartTagComment(const HTMLStartTagComment *C) {
02118   OS << " Name=\"" << C->getTagName() << "\"";
02119   if (C->getNumAttrs() != 0) {
02120     OS << " Attrs: ";
02121     for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) {
02122       const HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
02123       OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\"";
02124     }
02125   }
02126   if (C->isSelfClosing())
02127     OS << " SelfClosing";
02128 }
02129 
02130 void ASTDumper::visitHTMLEndTagComment(const HTMLEndTagComment *C) {
02131   OS << " Name=\"" << C->getTagName() << "\"";
02132 }
02133 
02134 void ASTDumper::visitBlockCommandComment(const BlockCommandComment *C) {
02135   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"";
02136   for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i)
02137     OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\"";
02138 }
02139 
02140 void ASTDumper::visitParamCommandComment(const ParamCommandComment *C) {
02141   OS << " " << ParamCommandComment::getDirectionAsString(C->getDirection());
02142 
02143   if (C->isDirectionExplicit())
02144     OS << " explicitly";
02145   else
02146     OS << " implicitly";
02147 
02148   if (C->hasParamName()) {
02149     if (C->isParamIndexValid())
02150       OS << " Param=\"" << C->getParamName(FC) << "\"";
02151     else
02152       OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
02153   }
02154 
02155   if (C->isParamIndexValid() && !C->isVarArgParam())
02156     OS << " ParamIndex=" << C->getParamIndex();
02157 }
02158 
02159 void ASTDumper::visitTParamCommandComment(const TParamCommandComment *C) {
02160   if (C->hasParamName()) {
02161     if (C->isPositionValid())
02162       OS << " Param=\"" << C->getParamName(FC) << "\"";
02163     else
02164       OS << " Param=\"" << C->getParamNameAsWritten() << "\"";
02165   }
02166 
02167   if (C->isPositionValid()) {
02168     OS << " Position=<";
02169     for (unsigned i = 0, e = C->getDepth(); i != e; ++i) {
02170       OS << C->getIndex(i);
02171       if (i != e - 1)
02172         OS << ", ";
02173     }
02174     OS << ">";
02175   }
02176 }
02177 
02178 void ASTDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) {
02179   OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""
02180         " CloseName=\"" << C->getCloseName() << "\"";
02181 }
02182 
02183 void ASTDumper::visitVerbatimBlockLineComment(
02184     const VerbatimBlockLineComment *C) {
02185   OS << " Text=\"" << C->getText() << "\"";
02186 }
02187 
02188 void ASTDumper::visitVerbatimLineComment(const VerbatimLineComment *C) {
02189   OS << " Text=\"" << C->getText() << "\"";
02190 }
02191 
02192 //===----------------------------------------------------------------------===//
02193 // Type method implementations
02194 //===----------------------------------------------------------------------===//
02195 
02196 void QualType::dump(const char *msg) const {
02197   if (msg)
02198     llvm::errs() << msg << ": ";
02199   dump();
02200 }
02201 
02202 LLVM_DUMP_METHOD void QualType::dump() const {
02203   ASTDumper Dumper(llvm::errs(), nullptr, nullptr);
02204   Dumper.dumpTypeAsChild(*this);
02205 }
02206 
02207 LLVM_DUMP_METHOD void Type::dump() const { QualType(this, 0).dump(); }
02208 
02209 //===----------------------------------------------------------------------===//
02210 // Decl method implementations
02211 //===----------------------------------------------------------------------===//
02212 
02213 LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); }
02214 
02215 LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS) const {
02216   ASTDumper P(OS, &getASTContext().getCommentCommandTraits(),
02217               &getASTContext().getSourceManager());
02218   P.dumpDecl(this);
02219 }
02220 
02221 LLVM_DUMP_METHOD void Decl::dumpColor() const {
02222   ASTDumper P(llvm::errs(), &getASTContext().getCommentCommandTraits(),
02223               &getASTContext().getSourceManager(), /*ShowColors*/true);
02224   P.dumpDecl(this);
02225 }
02226 
02227 LLVM_DUMP_METHOD void DeclContext::dumpLookups() const {
02228   dumpLookups(llvm::errs());
02229 }
02230 
02231 LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS,
02232                                                bool DumpDecls) const {
02233   const DeclContext *DC = this;
02234   while (!DC->isTranslationUnit())
02235     DC = DC->getParent();
02236   ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
02237   ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager());
02238   P.dumpLookups(this, DumpDecls);
02239 }
02240 
02241 //===----------------------------------------------------------------------===//
02242 // Stmt method implementations
02243 //===----------------------------------------------------------------------===//
02244 
02245 LLVM_DUMP_METHOD void Stmt::dump(SourceManager &SM) const {
02246   dump(llvm::errs(), SM);
02247 }
02248 
02249 LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
02250   ASTDumper P(OS, nullptr, &SM);
02251   P.dumpStmt(this);
02252 }
02253 
02254 LLVM_DUMP_METHOD void Stmt::dump() const {
02255   ASTDumper P(llvm::errs(), nullptr, nullptr);
02256   P.dumpStmt(this);
02257 }
02258 
02259 LLVM_DUMP_METHOD void Stmt::dumpColor() const {
02260   ASTDumper P(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
02261   P.dumpStmt(this);
02262 }
02263 
02264 //===----------------------------------------------------------------------===//
02265 // Comment method implementations
02266 //===----------------------------------------------------------------------===//
02267 
02268 LLVM_DUMP_METHOD void Comment::dump() const {
02269   dump(llvm::errs(), nullptr, nullptr);
02270 }
02271 
02272 LLVM_DUMP_METHOD void Comment::dump(const ASTContext &Context) const {
02273   dump(llvm::errs(), &Context.getCommentCommandTraits(),
02274        &Context.getSourceManager());
02275 }
02276 
02277 void Comment::dump(raw_ostream &OS, const CommandTraits *Traits,
02278                    const SourceManager *SM) const {
02279   const FullComment *FC = dyn_cast<FullComment>(this);
02280   ASTDumper D(OS, Traits, SM);
02281   D.dumpFullComment(FC);
02282 }
02283 
02284 LLVM_DUMP_METHOD void Comment::dumpColor() const {
02285   const FullComment *FC = dyn_cast<FullComment>(this);
02286   ASTDumper D(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
02287   D.dumpFullComment(FC);
02288 }