diff options
Diffstat (limited to 'lib/AST/ASTDumper.cpp')
-rw-r--r-- | lib/AST/ASTDumper.cpp | 1721 |
1 files changed, 277 insertions, 1444 deletions
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index 8a653ecebae3f..b52ec21943e6d 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -13,7 +13,9 @@ //===----------------------------------------------------------------------===// #include "clang/AST/ASTContext.h" +#include "clang/AST/ASTDumperUtils.h" #include "clang/AST/Attr.h" +#include "clang/AST/AttrVisitor.h" #include "clang/AST/CommentVisitor.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclLookups.h" @@ -22,6 +24,8 @@ #include "clang/AST/DeclVisitor.h" #include "clang/AST/LocInfoType.h" #include "clang/AST/StmtVisitor.h" +#include "clang/AST/TemplateArgumentVisitor.h" +#include "clang/AST/TextNodeDumper.h" #include "clang/AST/TypeVisitor.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/Module.h" @@ -35,177 +39,35 @@ using namespace clang::comments; //===----------------------------------------------------------------------===// namespace { - // Colors used for various parts of the AST dump - // Do not use bold yellow for any text. It is hard to read on white screens. - struct TerminalColor { - raw_ostream::Colors Color; - bool Bold; - }; + class ASTDumper + : public ConstDeclVisitor<ASTDumper>, + public ConstStmtVisitor<ASTDumper>, + public ConstCommentVisitor<ASTDumper, void, const FullComment *>, + public TypeVisitor<ASTDumper>, + public ConstAttrVisitor<ASTDumper>, + public ConstTemplateArgumentVisitor<ASTDumper> { - // Red - CastColor - // Green - TypeColor - // Bold Green - DeclKindNameColor, UndeserializedColor - // Yellow - AddressColor, LocationColor - // Blue - CommentColor, NullColor, IndentColor - // Bold Blue - AttrColor - // Bold Magenta - StmtColor - // Cyan - ValueKindColor, ObjectKindColor - // Bold Cyan - ValueColor, DeclNameColor - - // Decl kind names (VarDecl, FunctionDecl, etc) - static const TerminalColor DeclKindNameColor = { raw_ostream::GREEN, true }; - // Attr names (CleanupAttr, GuardedByAttr, etc) - static const TerminalColor AttrColor = { raw_ostream::BLUE, true }; - // Statement names (DeclStmt, ImplicitCastExpr, etc) - static const TerminalColor StmtColor = { raw_ostream::MAGENTA, true }; - // Comment names (FullComment, ParagraphComment, TextComment, etc) - static const TerminalColor CommentColor = { raw_ostream::BLUE, false }; - - // Type names (int, float, etc, plus user defined types) - static const TerminalColor TypeColor = { raw_ostream::GREEN, false }; - - // Pointer address - static const TerminalColor AddressColor = { raw_ostream::YELLOW, false }; - // Source locations - static const TerminalColor LocationColor = { raw_ostream::YELLOW, false }; - - // lvalue/xvalue - static const TerminalColor ValueKindColor = { raw_ostream::CYAN, false }; - // bitfield/objcproperty/objcsubscript/vectorcomponent - static const TerminalColor ObjectKindColor = { raw_ostream::CYAN, false }; - - // Null statements - static const TerminalColor NullColor = { raw_ostream::BLUE, false }; - - // Undeserialized entities - static const TerminalColor UndeserializedColor = { raw_ostream::GREEN, true }; - - // CastKind from CastExpr's - static const TerminalColor CastColor = { raw_ostream::RED, false }; - - // Value of the statement - static const TerminalColor ValueColor = { raw_ostream::CYAN, true }; - // Decl names - static const TerminalColor DeclNameColor = { raw_ostream::CYAN, true }; - - // Indents ( `, -. | ) - static const TerminalColor IndentColor = { raw_ostream::BLUE, false }; + TextNodeDumper NodeDumper; - class ASTDumper - : public ConstDeclVisitor<ASTDumper>, public ConstStmtVisitor<ASTDumper>, - public ConstCommentVisitor<ASTDumper>, public TypeVisitor<ASTDumper> { raw_ostream &OS; - const CommandTraits *Traits; - const SourceManager *SM; /// The policy to use for printing; can be defaulted. PrintingPolicy PrintPolicy; - /// Pending[i] is an action to dump an entity at level i. - llvm::SmallVector<std::function<void(bool isLastChild)>, 32> Pending; - /// Indicates whether we should trigger deserialization of nodes that had /// not already been loaded. bool Deserialize = false; - /// Indicates whether we're at the top level. - bool TopLevel = true; - - /// Indicates if we're handling the first child after entering a new depth. - bool FirstChild = true; - - /// Prefix for currently-being-dumped entity. - std::string Prefix; - - /// Keep track of the last location we print out so that we can - /// print out deltas from then on out. - const char *LastLocFilename = ""; - unsigned LastLocLine = ~0U; - - /// The \c FullComment parent of the comment being dumped. - const FullComment *FC = nullptr; - - bool ShowColors; + const bool ShowColors; /// Dump a child of the current node. - template<typename Fn> void dumpChild(Fn doDumpChild) { - // If we're at the top level, there's nothing interesting to do; just - // run the dumper. - if (TopLevel) { - TopLevel = false; - doDumpChild(); - while (!Pending.empty()) { - Pending.back()(true); - Pending.pop_back(); - } - Prefix.clear(); - OS << "\n"; - TopLevel = true; - return; - } - - const FullComment *OrigFC = FC; - auto dumpWithIndent = [this, doDumpChild, OrigFC](bool isLastChild) { - // Print out the appropriate tree structure and work out the prefix for - // children of this node. For instance: - // - // A Prefix = "" - // |-B Prefix = "| " - // | `-C Prefix = "| " - // `-D Prefix = " " - // |-E Prefix = " | " - // `-F Prefix = " " - // G Prefix = "" - // - // Note that the first level gets no prefix. - { - OS << '\n'; - ColorScope Color(*this, IndentColor); - OS << Prefix << (isLastChild ? '`' : '|') << '-'; - this->Prefix.push_back(isLastChild ? ' ' : '|'); - this->Prefix.push_back(' '); - } - - FirstChild = true; - unsigned Depth = Pending.size(); - - FC = OrigFC; - doDumpChild(); - - // If any children are left, they're the last at their nesting level. - // Dump those ones out now. - while (Depth < Pending.size()) { - Pending.back()(true); - this->Pending.pop_back(); - } - - // Restore the old prefix. - this->Prefix.resize(Prefix.size() - 2); - }; - - if (FirstChild) { - Pending.push_back(std::move(dumpWithIndent)); - } else { - Pending.back()(false); - Pending.back() = std::move(dumpWithIndent); - } - FirstChild = false; + template<typename Fn> void dumpChild(Fn DoDumpChild) { + NodeDumper.AddChild(DoDumpChild); + } + template <typename Fn> void dumpChild(StringRef Label, Fn DoDumpChild) { + NodeDumper.AddChild(Label, DoDumpChild); } - - class ColorScope { - ASTDumper &Dumper; - public: - ColorScope(ASTDumper &Dumper, TerminalColor Color) - : Dumper(Dumper) { - if (Dumper.ShowColors) - Dumper.OS.changeColor(Color.Color, Color.Bold); - } - ~ColorScope() { - if (Dumper.ShowColors) - Dumper.OS.resetColor(); - } - }; public: ASTDumper(raw_ostream &OS, const CommandTraits *Traits, @@ -219,40 +81,39 @@ namespace { ASTDumper(raw_ostream &OS, const CommandTraits *Traits, const SourceManager *SM, bool ShowColors, const PrintingPolicy &PrintPolicy) - : OS(OS), Traits(Traits), SM(SM), PrintPolicy(PrintPolicy), - ShowColors(ShowColors) {} + : NodeDumper(OS, ShowColors, SM, PrintPolicy, Traits), OS(OS), + PrintPolicy(PrintPolicy), ShowColors(ShowColors) {} void setDeserialize(bool D) { Deserialize = D; } void dumpDecl(const Decl *D); - void dumpStmt(const Stmt *S); - void dumpFullComment(const FullComment *C); + void dumpStmt(const Stmt *S, StringRef Label = {}); // Utilities - void dumpPointer(const void *Ptr); - void dumpSourceRange(SourceRange R); - void dumpLocation(SourceLocation Loc); - void dumpBareType(QualType T, bool Desugar = true); - void dumpType(QualType T); void dumpTypeAsChild(QualType T); void dumpTypeAsChild(const Type *T); - void dumpBareDeclRef(const Decl *Node); - void dumpDeclRef(const Decl *Node, const char *Label = nullptr); - void dumpName(const NamedDecl *D); - bool hasNodes(const DeclContext *DC); void dumpDeclContext(const DeclContext *DC); void dumpLookups(const DeclContext *DC, bool DumpDecls); void dumpAttr(const Attr *A); // C++ Utilities - void dumpAccessSpecifier(AccessSpecifier AS); void dumpCXXCtorInitializer(const CXXCtorInitializer *Init); void dumpTemplateParameters(const TemplateParameterList *TPL); void dumpTemplateArgumentListInfo(const TemplateArgumentListInfo &TALI); - void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A); + void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A, + const Decl *From = nullptr, + const char *Label = nullptr); void dumpTemplateArgumentList(const TemplateArgumentList &TAL); void dumpTemplateArgument(const TemplateArgument &A, - SourceRange R = SourceRange()); + SourceRange R = SourceRange(), + const Decl *From = nullptr, + const char *Label = nullptr); + template <typename SpecializationDecl> + void dumpTemplateDeclSpecialization(const SpecializationDecl *D, + bool DumpExplicitInst, + bool DumpRefOnly); + template <typename TemplateDecl> + void dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst); // Objective-C utilities. void dumpObjCTypeParamList(const ObjCTypeParamList *typeParams); @@ -261,6 +122,9 @@ namespace { void VisitComplexType(const ComplexType *T) { dumpTypeAsChild(T->getElementType()); } + void VisitLocInfoType(const LocInfoType *T) { + dumpTypeAsChild(T->getTypeSourceInfo()->getType()); + } void VisitPointerType(const PointerType *T) { dumpTypeAsChild(T->getPointeeType()); } @@ -270,92 +134,39 @@ namespace { void VisitReferenceType(const ReferenceType *T) { dumpTypeAsChild(T->getPointeeType()); } - void VisitRValueReferenceType(const ReferenceType *T) { - if (T->isSpelledAsLValue()) - OS << " written as lvalue reference"; - VisitReferenceType(T); - } void VisitMemberPointerType(const MemberPointerType *T) { dumpTypeAsChild(T->getClass()); dumpTypeAsChild(T->getPointeeType()); } void VisitArrayType(const ArrayType *T) { - switch (T->getSizeModifier()) { - case ArrayType::Normal: break; - case ArrayType::Static: OS << " static"; break; - case ArrayType::Star: OS << " *"; break; - } - OS << " " << T->getIndexTypeQualifiers().getAsString(); dumpTypeAsChild(T->getElementType()); } - void VisitConstantArrayType(const ConstantArrayType *T) { - OS << " " << T->getSize(); - VisitArrayType(T); - } void VisitVariableArrayType(const VariableArrayType *T) { - OS << " "; - dumpSourceRange(T->getBracketsRange()); VisitArrayType(T); dumpStmt(T->getSizeExpr()); } void VisitDependentSizedArrayType(const DependentSizedArrayType *T) { - VisitArrayType(T); - OS << " "; - dumpSourceRange(T->getBracketsRange()); + dumpTypeAsChild(T->getElementType()); dumpStmt(T->getSizeExpr()); } void VisitDependentSizedExtVectorType( const DependentSizedExtVectorType *T) { - OS << " "; - dumpLocation(T->getAttributeLoc()); dumpTypeAsChild(T->getElementType()); dumpStmt(T->getSizeExpr()); } void VisitVectorType(const VectorType *T) { - switch (T->getVectorKind()) { - case VectorType::GenericVector: break; - case VectorType::AltiVecVector: OS << " altivec"; break; - case VectorType::AltiVecPixel: OS << " altivec pixel"; break; - case VectorType::AltiVecBool: OS << " altivec bool"; break; - case VectorType::NeonVector: OS << " neon"; break; - case VectorType::NeonPolyVector: OS << " neon poly"; break; - } - OS << " " << T->getNumElements(); dumpTypeAsChild(T->getElementType()); } void VisitFunctionType(const FunctionType *T) { - auto EI = T->getExtInfo(); - if (EI.getNoReturn()) OS << " noreturn"; - if (EI.getProducesResult()) OS << " produces_result"; - if (EI.getHasRegParm()) OS << " regparm " << EI.getRegParm(); - OS << " " << FunctionType::getNameForCallConv(EI.getCC()); dumpTypeAsChild(T->getReturnType()); } void VisitFunctionProtoType(const FunctionProtoType *T) { - auto EPI = T->getExtProtoInfo(); - if (EPI.HasTrailingReturn) OS << " trailing_return"; - if (T->isConst()) OS << " const"; - if (T->isVolatile()) OS << " volatile"; - if (T->isRestrict()) OS << " restrict"; - switch (EPI.RefQualifier) { - case RQ_None: break; - case RQ_LValue: OS << " &"; break; - case RQ_RValue: OS << " &&"; break; - } - // FIXME: Exception specification. - // FIXME: Consumed parameters. VisitFunctionType(T); for (QualType PT : T->getParamTypes()) dumpTypeAsChild(PT); - if (EPI.Variadic) + if (T->getExtProtoInfo().Variadic) dumpChild([=] { OS << "..."; }); } - void VisitUnresolvedUsingType(const UnresolvedUsingType *T) { - dumpDeclRef(T->getDecl()); - } - void VisitTypedefType(const TypedefType *T) { - dumpDeclRef(T->getDecl()); - } void VisitTypeOfExprType(const TypeOfExprType *T) { dumpStmt(T->getUnderlyingExpr()); } @@ -363,25 +174,12 @@ namespace { dumpStmt(T->getUnderlyingExpr()); } void VisitUnaryTransformType(const UnaryTransformType *T) { - switch (T->getUTTKind()) { - case UnaryTransformType::EnumUnderlyingType: - OS << " underlying_type"; - break; - } dumpTypeAsChild(T->getBaseType()); } - void VisitTagType(const TagType *T) { - dumpDeclRef(T->getDecl()); - } void VisitAttributedType(const AttributedType *T) { // FIXME: AttrKind dumpTypeAsChild(T->getModifiedType()); } - void VisitTemplateTypeParmType(const TemplateTypeParmType *T) { - OS << " depth " << T->getDepth() << " index " << T->getIndex(); - if (T->isParameterPack()) OS << " pack"; - dumpDeclRef(T->getDecl()); - } void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) { dumpTypeAsChild(T->getReplacedParameter()); } @@ -390,25 +188,12 @@ namespace { dumpTypeAsChild(T->getReplacedParameter()); dumpTemplateArgument(T->getArgumentPack()); } - void VisitAutoType(const AutoType *T) { - if (T->isDecltypeAuto()) OS << " decltype(auto)"; - if (!T->isDeduced()) - OS << " undeduced"; - } void VisitTemplateSpecializationType(const TemplateSpecializationType *T) { - if (T->isTypeAlias()) OS << " alias"; - OS << " "; T->getTemplateName().dump(OS); for (auto &Arg : *T) dumpTemplateArgument(Arg); if (T->isTypeAlias()) dumpTypeAsChild(T->getAliasedType()); } - void VisitInjectedClassNameType(const InjectedClassNameType *T) { - dumpDeclRef(T->getDecl()); - } - void VisitObjCInterfaceType(const ObjCInterfaceType *T) { - dumpDeclRef(T->getDecl()); - } void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) { dumpTypeAsChild(T->getPointeeType()); } @@ -422,7 +207,6 @@ namespace { dumpTypeAsChild(T->getOriginalType()); } void VisitPackExpansionType(const PackExpansionType *T) { - if (auto N = T->getNumExpansions()) OS << " expansions " << *N; if (!T->isSugared()) dumpTypeAsChild(T->getPattern()); } @@ -450,6 +234,7 @@ namespace { // OpenMP decls void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D); void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D); + void VisitOMPRequiresDecl(const OMPRequiresDecl *D); void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D); // C++ Decls @@ -460,12 +245,6 @@ namespace { void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D); void VisitCXXRecordDecl(const CXXRecordDecl *D); void VisitStaticAssertDecl(const StaticAssertDecl *D); - template<typename SpecializationDecl> - void VisitTemplateDeclSpecialization(const SpecializationDecl *D, - bool DumpExplicitInst, - bool DumpRefOnly); - template<typename TemplateDecl> - void VisitTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst); void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D); void VisitClassTemplateDecl(const ClassTemplateDecl *D); void VisitClassTemplateSpecializationDecl( @@ -504,96 +283,47 @@ namespace { void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D); void VisitObjCPropertyDecl(const ObjCPropertyDecl *D); void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D); + void Visit(const BlockDecl::Capture &C); void VisitBlockDecl(const BlockDecl *D); // Stmts. - void VisitStmt(const Stmt *Node); void VisitDeclStmt(const DeclStmt *Node); void VisitAttributedStmt(const AttributedStmt *Node); - void VisitLabelStmt(const LabelStmt *Node); - void VisitGotoStmt(const GotoStmt *Node); void VisitCXXCatchStmt(const CXXCatchStmt *Node); void VisitCapturedStmt(const CapturedStmt *Node); // OpenMP + void Visit(const OMPClause *C); void VisitOMPExecutableDirective(const OMPExecutableDirective *Node); // Exprs - void VisitExpr(const Expr *Node); - void VisitCastExpr(const CastExpr *Node); - void VisitImplicitCastExpr(const ImplicitCastExpr *Node); - void VisitDeclRefExpr(const DeclRefExpr *Node); - void VisitPredefinedExpr(const PredefinedExpr *Node); - void VisitCharacterLiteral(const CharacterLiteral *Node); - void VisitIntegerLiteral(const IntegerLiteral *Node); - void VisitFixedPointLiteral(const FixedPointLiteral *Node); - void VisitFloatingLiteral(const FloatingLiteral *Node); - void VisitStringLiteral(const StringLiteral *Str); void VisitInitListExpr(const InitListExpr *ILE); - void VisitArrayInitLoopExpr(const ArrayInitLoopExpr *ILE); - void VisitArrayInitIndexExpr(const ArrayInitIndexExpr *ILE); - void VisitUnaryOperator(const UnaryOperator *Node); - void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node); - void VisitMemberExpr(const MemberExpr *Node); - void VisitExtVectorElementExpr(const ExtVectorElementExpr *Node); - void VisitBinaryOperator(const BinaryOperator *Node); - void VisitCompoundAssignOperator(const CompoundAssignOperator *Node); - void VisitAddrLabelExpr(const AddrLabelExpr *Node); void VisitBlockExpr(const BlockExpr *Node); void VisitOpaqueValueExpr(const OpaqueValueExpr *Node); void VisitGenericSelectionExpr(const GenericSelectionExpr *E); // C++ - void VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node); - void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node); - void VisitCXXThisExpr(const CXXThisExpr *Node); - void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node); - void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *Node); - void VisitCXXConstructExpr(const CXXConstructExpr *Node); - void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node); - void VisitCXXNewExpr(const CXXNewExpr *Node); - void VisitCXXDeleteExpr(const CXXDeleteExpr *Node); - void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node); - void VisitExprWithCleanups(const ExprWithCleanups *Node); - void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node); - void dumpCXXTemporary(const CXXTemporary *Temporary); void VisitLambdaExpr(const LambdaExpr *Node) { - VisitExpr(Node); dumpDecl(Node->getLambdaClass()); } void VisitSizeOfPackExpr(const SizeOfPackExpr *Node); - void - VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *Node); // ObjC void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node); - void VisitObjCEncodeExpr(const ObjCEncodeExpr *Node); - void VisitObjCMessageExpr(const ObjCMessageExpr *Node); - void VisitObjCBoxedExpr(const ObjCBoxedExpr *Node); - void VisitObjCSelectorExpr(const ObjCSelectorExpr *Node); - void VisitObjCProtocolExpr(const ObjCProtocolExpr *Node); - void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node); - void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node); - void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node); - void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node); // Comments. - const char *getCommandName(unsigned CommandID); - void dumpComment(const Comment *C); - - // Inline comments. - void visitTextComment(const TextComment *C); - void visitInlineCommandComment(const InlineCommandComment *C); - void visitHTMLStartTagComment(const HTMLStartTagComment *C); - void visitHTMLEndTagComment(const HTMLEndTagComment *C); - - // Block comments. - void visitBlockCommandComment(const BlockCommandComment *C); - void visitParamCommandComment(const ParamCommandComment *C); - void visitTParamCommandComment(const TParamCommandComment *C); - void visitVerbatimBlockComment(const VerbatimBlockComment *C); - void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C); - void visitVerbatimLineComment(const VerbatimLineComment *C); + void dumpComment(const Comment *C, const FullComment *FC); + + void VisitExpressionTemplateArgument(const TemplateArgument &TA) { + dumpStmt(TA.getAsExpr()); + } + void VisitPackTemplateArgument(const TemplateArgument &TA) { + for (const auto &TArg : TA.pack_elements()) + dumpTemplateArgument(TArg); + } + +// Implements Visit methods for Attrs. +#include "clang/AST/AttrNodeTraverse.inc" }; } @@ -601,188 +331,31 @@ namespace { // Utilities //===----------------------------------------------------------------------===// -void ASTDumper::dumpPointer(const void *Ptr) { - ColorScope Color(*this, AddressColor); - OS << ' ' << Ptr; -} - -void ASTDumper::dumpLocation(SourceLocation Loc) { - if (!SM) - return; - - ColorScope Color(*this, LocationColor); - SourceLocation SpellingLoc = SM->getSpellingLoc(Loc); - - // The general format we print out is filename:line:col, but we drop pieces - // that haven't changed since the last loc printed. - PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc); - - if (PLoc.isInvalid()) { - OS << "<invalid sloc>"; - return; - } - - if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) { - OS << PLoc.getFilename() << ':' << PLoc.getLine() - << ':' << PLoc.getColumn(); - LastLocFilename = PLoc.getFilename(); - LastLocLine = PLoc.getLine(); - } else if (PLoc.getLine() != LastLocLine) { - OS << "line" << ':' << PLoc.getLine() - << ':' << PLoc.getColumn(); - LastLocLine = PLoc.getLine(); - } else { - OS << "col" << ':' << PLoc.getColumn(); - } -} - -void ASTDumper::dumpSourceRange(SourceRange R) { - // Can't translate locations if a SourceManager isn't available. - if (!SM) - return; - - OS << " <"; - dumpLocation(R.getBegin()); - if (R.getBegin() != R.getEnd()) { - OS << ", "; - dumpLocation(R.getEnd()); - } - OS << ">"; - - // <t2.c:123:421[blah], t2.c:412:321> - -} - -void ASTDumper::dumpBareType(QualType T, bool Desugar) { - ColorScope Color(*this, TypeColor); - - SplitQualType T_split = T.split(); - OS << "'" << QualType::getAsString(T_split, PrintPolicy) << "'"; - - if (Desugar && !T.isNull()) { - // If the type is sugared, also dump a (shallow) desugared type. - SplitQualType D_split = T.getSplitDesugaredType(); - if (T_split != D_split) - OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'"; - } -} - -void ASTDumper::dumpType(QualType T) { - OS << ' '; - dumpBareType(T); -} - void ASTDumper::dumpTypeAsChild(QualType T) { SplitQualType SQT = T.split(); if (!SQT.Quals.hasQualifiers()) return dumpTypeAsChild(SQT.Ty); dumpChild([=] { - OS << "QualType"; - dumpPointer(T.getAsOpaquePtr()); - OS << " "; - dumpBareType(T, false); - OS << " " << T.split().Quals.getAsString(); + NodeDumper.Visit(T); dumpTypeAsChild(T.split().Ty); }); } void ASTDumper::dumpTypeAsChild(const Type *T) { dumpChild([=] { - if (!T) { - ColorScope Color(*this, NullColor); - OS << "<<<NULL>>>"; - return; - } - if (const LocInfoType *LIT = llvm::dyn_cast<LocInfoType>(T)) { - { - ColorScope Color(*this, TypeColor); - OS << "LocInfo Type"; - } - dumpPointer(T); - dumpTypeAsChild(LIT->getTypeSourceInfo()->getType()); + NodeDumper.Visit(T); + if (!T) return; - } - - { - ColorScope Color(*this, TypeColor); - OS << T->getTypeClassName() << "Type"; - } - dumpPointer(T); - OS << " "; - dumpBareType(QualType(T, 0), false); + TypeVisitor<ASTDumper>::Visit(T); QualType SingleStepDesugar = T->getLocallyUnqualifiedSingleStepDesugaredType(); if (SingleStepDesugar != QualType(T, 0)) - OS << " sugar"; - if (T->isDependentType()) - OS << " dependent"; - else if (T->isInstantiationDependentType()) - OS << " instantiation_dependent"; - if (T->isVariablyModifiedType()) - OS << " variably_modified"; - if (T->containsUnexpandedParameterPack()) - OS << " contains_unexpanded_pack"; - if (T->isFromAST()) - OS << " imported"; - - TypeVisitor<ASTDumper>::Visit(T); - - if (SingleStepDesugar != QualType(T, 0)) dumpTypeAsChild(SingleStepDesugar); }); } -void ASTDumper::dumpBareDeclRef(const Decl *D) { - if (!D) { - ColorScope Color(*this, NullColor); - OS << "<<<NULL>>>"; - return; - } - - { - ColorScope Color(*this, DeclKindNameColor); - OS << D->getDeclKindName(); - } - dumpPointer(D); - - if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) { - ColorScope Color(*this, DeclNameColor); - OS << " '" << ND->getDeclName() << '\''; - } - - if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) - dumpType(VD->getType()); -} - -void ASTDumper::dumpDeclRef(const Decl *D, const char *Label) { - if (!D) - return; - - dumpChild([=]{ - if (Label) - OS << Label << ' '; - dumpBareDeclRef(D); - }); -} - -void ASTDumper::dumpName(const NamedDecl *ND) { - if (ND->getDeclName()) { - ColorScope Color(*this, DeclNameColor); - OS << ' ' << ND->getNameAsString(); - } -} - -bool ASTDumper::hasNodes(const DeclContext *DC) { - if (!DC) - return false; - - return DC->hasExternalLexicalStorage() || - (Deserialize ? DC->decls_begin() != DC->decls_end() - : DC->noload_decls_begin() != DC->noload_decls_end()); -} - void ASTDumper::dumpDeclContext(const DeclContext *DC) { if (!DC) return; @@ -791,8 +364,8 @@ void ASTDumper::dumpDeclContext(const DeclContext *DC) { dumpDecl(D); if (DC->hasExternalLexicalStorage()) { - dumpChild([=]{ - ColorScope Color(*this, UndeserializedColor); + dumpChild([=] { + ColorScope Color(OS, ShowColors, UndeserializedColor); OS << "<undeserialized declarations>"; }); } @@ -801,12 +374,12 @@ void ASTDumper::dumpDeclContext(const DeclContext *DC) { void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) { dumpChild([=] { OS << "StoredDeclsMap "; - dumpBareDeclRef(cast<Decl>(DC)); + NodeDumper.dumpBareDeclRef(cast<Decl>(DC)); const DeclContext *Primary = DC->getPrimaryContext(); if (Primary != DC) { OS << " primary"; - dumpPointer(cast<Decl>(Primary)); + NodeDumper.dumpPointer(cast<Decl>(Primary)); } bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage(); @@ -821,14 +394,14 @@ void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) { dumpChild([=] { OS << "DeclarationName "; { - ColorScope Color(*this, DeclNameColor); + ColorScope Color(OS, ShowColors, DeclNameColor); OS << '\'' << Name << '\''; } for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end(); RI != RE; ++RI) { dumpChild([=] { - dumpBareDeclRef(*RI); + NodeDumper.dumpBareDeclRef(*RI); if ((*RI)->isHidden()) OS << " hidden"; @@ -850,7 +423,7 @@ void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) { if (HasUndeserializedLookups) { dumpChild([=] { - ColorScope Color(*this, UndeserializedColor); + ColorScope Color(OS, ShowColors, UndeserializedColor); OS << "<undeserialized lookups>"; }); } @@ -859,87 +432,18 @@ void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) { void ASTDumper::dumpAttr(const Attr *A) { dumpChild([=] { - { - ColorScope Color(*this, AttrColor); - - switch (A->getKind()) { -#define ATTR(X) case attr::X: OS << #X; break; -#include "clang/Basic/AttrList.inc" - } - OS << "Attr"; - } - dumpPointer(A); - dumpSourceRange(A->getRange()); - if (A->isInherited()) - OS << " Inherited"; - if (A->isImplicit()) - OS << " Implicit"; -#include "clang/AST/AttrDump.inc" + NodeDumper.Visit(A); + ConstAttrVisitor<ASTDumper>::Visit(A); }); } -static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {} - -template<typename T> -static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) { - const T *First = D->getFirstDecl(); - if (First != D) - OS << " first " << First; -} - -template<typename T> -static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) { - const T *Prev = D->getPreviousDecl(); - if (Prev) - OS << " prev " << Prev; -} - -/// Dump the previous declaration in the redeclaration chain for a declaration, -/// if any. -static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) { - switch (D->getKind()) { -#define DECL(DERIVED, BASE) \ - case Decl::DERIVED: \ - return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D)); -#define ABSTRACT_DECL(DECL) -#include "clang/AST/DeclNodes.inc" - } - llvm_unreachable("Decl that isn't part of DeclNodes.inc!"); -} - //===----------------------------------------------------------------------===// // C++ Utilities //===----------------------------------------------------------------------===// -void ASTDumper::dumpAccessSpecifier(AccessSpecifier AS) { - switch (AS) { - case AS_none: - break; - case AS_public: - OS << "public"; - break; - case AS_protected: - OS << "protected"; - break; - case AS_private: - OS << "private"; - break; - } -} - void ASTDumper::dumpCXXCtorInitializer(const CXXCtorInitializer *Init) { dumpChild([=] { - OS << "CXXCtorInitializer"; - if (Init->isAnyMemberInitializer()) { - OS << ' '; - dumpBareDeclRef(Init->getAnyMember()); - } else if (Init->isBaseInitializer()) { - dumpType(QualType(Init->getBaseClass(), 0)); - } else if (Init->isDelegatingInitializer()) { - dumpType(Init->getTypeSourceInfo()->getType()); - } else { - llvm_unreachable("Unknown initializer type"); - } + NodeDumper.Visit(Init); dumpStmt(Init->getInit()); }); } @@ -959,8 +463,9 @@ void ASTDumper::dumpTemplateArgumentListInfo( dumpTemplateArgumentLoc(TALI[i]); } -void ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A) { - dumpTemplateArgument(A.getArgument(), A.getSourceRange()); +void ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A, + const Decl *From, const char *Label) { + dumpTemplateArgument(A.getArgument(), A.getSourceRange(), From, Label); } void ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) { @@ -968,49 +473,11 @@ void ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) { dumpTemplateArgument(TAL[i]); } -void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R) { +void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R, + const Decl *From, const char *Label) { dumpChild([=] { - OS << "TemplateArgument"; - if (R.isValid()) - dumpSourceRange(R); - - switch (A.getKind()) { - case TemplateArgument::Null: - OS << " null"; - break; - case TemplateArgument::Type: - OS << " type"; - dumpType(A.getAsType()); - break; - case TemplateArgument::Declaration: - OS << " decl"; - dumpDeclRef(A.getAsDecl()); - break; - case TemplateArgument::NullPtr: - OS << " nullptr"; - break; - case TemplateArgument::Integral: - OS << " integral " << A.getAsIntegral(); - break; - case TemplateArgument::Template: - OS << " template "; - A.getAsTemplate().dump(OS); - break; - case TemplateArgument::TemplateExpansion: - OS << " template expansion"; - A.getAsTemplateOrTemplatePattern().dump(OS); - break; - case TemplateArgument::Expression: - OS << " expr"; - dumpStmt(A.getAsExpr()); - break; - case TemplateArgument::Pack: - OS << " pack"; - for (TemplateArgument::pack_iterator I = A.pack_begin(), E = A.pack_end(); - I != E; ++I) - dumpTemplateArgument(*I); - break; - } + NodeDumper.Visit(A, R, From, Label); + ConstTemplateArgumentVisitor<ASTDumper>::Visit(A); }); } @@ -1032,46 +499,9 @@ void ASTDumper::dumpObjCTypeParamList(const ObjCTypeParamList *typeParams) { void ASTDumper::dumpDecl(const Decl *D) { dumpChild([=] { - if (!D) { - ColorScope Color(*this, NullColor); - OS << "<<<NULL>>>"; + NodeDumper.Visit(D); + if (!D) return; - } - - { - ColorScope Color(*this, DeclKindNameColor); - OS << D->getDeclKindName() << "Decl"; - } - dumpPointer(D); - if (D->getLexicalDeclContext() != D->getDeclContext()) - OS << " parent " << cast<Decl>(D->getDeclContext()); - dumpPreviousDecl(OS, D); - dumpSourceRange(D->getSourceRange()); - OS << ' '; - dumpLocation(D->getLocation()); - if (D->isFromASTFile()) - OS << " imported"; - if (Module *M = D->getOwningModule()) - OS << " in " << M->getFullModuleName(); - if (auto *ND = dyn_cast<NamedDecl>(D)) - for (Module *M : D->getASTContext().getModulesWithMergedDefinition( - const_cast<NamedDecl *>(ND))) - dumpChild([=] { OS << "also in " << M->getFullModuleName(); }); - if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) - if (ND->isHidden()) - OS << " hidden"; - if (D->isImplicit()) - OS << " implicit"; - if (D->isUsed()) - OS << " used"; - else if (D->isThisDeclarationReferenced()) - OS << " referenced"; - if (D->isInvalidDecl()) - OS << " invalid"; - if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) - if (FD->isConstexpr()) - OS << " constexpr"; - ConstDeclVisitor<ASTDumper>::Visit(D); @@ -1081,22 +511,25 @@ void ASTDumper::dumpDecl(const Decl *D) { if (const FullComment *Comment = D->getASTContext().getLocalCommentForDeclUncached(D)) - dumpFullComment(Comment); + dumpComment(Comment, Comment); // Decls within functions are visited by the body. - if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D) && - hasNodes(dyn_cast<DeclContext>(D))) - dumpDeclContext(cast<DeclContext>(D)); + if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D)) { + auto DC = dyn_cast<DeclContext>(D); + if (DC && + (DC->hasExternalLexicalStorage() || + (Deserialize ? DC->decls_begin() != DC->decls_end() + : DC->noload_decls_begin() != DC->noload_decls_end()))) + dumpDeclContext(DC); + } }); } -void ASTDumper::VisitLabelDecl(const LabelDecl *D) { - dumpName(D); -} +void ASTDumper::VisitLabelDecl(const LabelDecl *D) { NodeDumper.dumpName(D); } void ASTDumper::VisitTypedefDecl(const TypedefDecl *D) { - dumpName(D); - dumpType(D->getUnderlyingType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getUnderlyingType()); if (D->isModulePrivate()) OS << " __module_private__"; dumpTypeAsChild(D->getUnderlyingType()); @@ -1109,16 +542,16 @@ void ASTDumper::VisitEnumDecl(const EnumDecl *D) { else OS << " struct"; } - dumpName(D); + NodeDumper.dumpName(D); if (D->isModulePrivate()) OS << " __module_private__"; if (D->isFixed()) - dumpType(D->getIntegerType()); + NodeDumper.dumpType(D->getIntegerType()); } void ASTDumper::VisitRecordDecl(const RecordDecl *D) { OS << ' ' << D->getKindName(); - dumpName(D); + NodeDumper.dumpName(D); if (D->isModulePrivate()) OS << " __module_private__"; if (D->isCompleteDefinition()) @@ -1126,23 +559,23 @@ void ASTDumper::VisitRecordDecl(const RecordDecl *D) { } void ASTDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) { - dumpName(D); - dumpType(D->getType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getType()); if (const Expr *Init = D->getInitExpr()) dumpStmt(Init); } void ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) { - dumpName(D); - dumpType(D->getType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getType()); for (auto *Child : D->chain()) - dumpDeclRef(Child); + NodeDumper.dumpDeclRef(Child); } void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) { - dumpName(D); - dumpType(D->getType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getType()); StorageClass SC = D->getStorageClass(); if (SC != SC_None) @@ -1166,7 +599,7 @@ void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) { if (D->isTrivial()) OS << " trivial"; - if (const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>()) { + if (const auto *FPT = D->getType()->getAs<FunctionProtoType>()) { FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); switch (EPI.ExceptionSpec.Type) { default: break; @@ -1179,23 +612,7 @@ void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) { } } - if (const FunctionTemplateSpecializationInfo *FTSI = - D->getTemplateSpecializationInfo()) - dumpTemplateArgumentList(*FTSI->TemplateArguments); - - if (!D->param_begin() && D->getNumParams()) - dumpChild([=] { OS << "<<NULL params x " << D->getNumParams() << ">>"; }); - else - for (const ParmVarDecl *Parameter : D->parameters()) - dumpDecl(Parameter); - - if (const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(D)) - for (CXXConstructorDecl::init_const_iterator I = C->init_begin(), - E = C->init_end(); - I != E; ++I) - dumpCXXCtorInitializer(*I); - - if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { + if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) { if (MD->size_overridden_methods() != 0) { auto dumpOverride = [=](const CXXMethodDecl *D) { SplitQualType T_split = D->getType().split(); @@ -1218,13 +635,26 @@ void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) { } } + if (const auto *FTSI = D->getTemplateSpecializationInfo()) + dumpTemplateArgumentList(*FTSI->TemplateArguments); + + if (!D->param_begin() && D->getNumParams()) + dumpChild([=] { OS << "<<NULL params x " << D->getNumParams() << ">>"; }); + else + for (const ParmVarDecl *Parameter : D->parameters()) + dumpDecl(Parameter); + + if (const auto *C = dyn_cast<CXXConstructorDecl>(D)) + for (const auto *I : C->inits()) + dumpCXXCtorInitializer(I); + if (D->doesThisDeclarationHaveABody()) dumpStmt(D->getBody()); } void ASTDumper::VisitFieldDecl(const FieldDecl *D) { - dumpName(D); - dumpType(D->getType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getType()); if (D->isMutable()) OS << " mutable"; if (D->isModulePrivate()) @@ -1237,8 +667,8 @@ void ASTDumper::VisitFieldDecl(const FieldDecl *D) { } void ASTDumper::VisitVarDecl(const VarDecl *D) { - dumpName(D); - dumpType(D->getType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getType()); StorageClass SC = D->getStorageClass(); if (SC != SC_None) OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); @@ -1272,8 +702,8 @@ void ASTDumper::VisitDecompositionDecl(const DecompositionDecl *D) { } void ASTDumper::VisitBindingDecl(const BindingDecl *D) { - dumpName(D); - dumpType(D->getType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getType()); if (auto *E = D->getBinding()) dumpStmt(E); } @@ -1320,12 +750,13 @@ void ASTDumper::VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) { } void ASTDumper::VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) { - dumpName(D); - dumpType(D->getType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getType()); OS << " combiner"; - dumpStmt(D->getCombiner()); - if (auto *Initializer = D->getInitializer()) { + NodeDumper.dumpPointer(D->getCombiner()); + if (const auto *Initializer = D->getInitializer()) { OS << " initializer"; + NodeDumper.dumpPointer(Initializer); switch (D->getInitializerKind()) { case OMPDeclareReductionDecl::DirectInit: OS << " omp_priv = "; @@ -1336,13 +767,36 @@ void ASTDumper::VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) { case OMPDeclareReductionDecl::CallInit: break; } + } + + dumpStmt(D->getCombiner()); + if (const auto *Initializer = D->getInitializer()) dumpStmt(Initializer); +} + +void ASTDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) { + for (auto *C : D->clauselists()) { + dumpChild([=] { + if (!C) { + ColorScope Color(OS, ShowColors, NullColor); + OS << "<<<NULL>>> OMPClause"; + return; + } + { + ColorScope Color(OS, ShowColors, AttrColor); + StringRef ClauseName(getOpenMPClauseName(C->getClauseKind())); + OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper() + << ClauseName.drop_front() << "Clause"; + } + NodeDumper.dumpPointer(C); + NodeDumper.dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc())); + }); } } void ASTDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) { - dumpName(D); - dumpType(D->getType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getType()); dumpStmt(D->getInit()); } @@ -1351,31 +805,31 @@ void ASTDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) { //===----------------------------------------------------------------------===// void ASTDumper::VisitNamespaceDecl(const NamespaceDecl *D) { - dumpName(D); + NodeDumper.dumpName(D); if (D->isInline()) OS << " inline"; if (!D->isOriginalNamespace()) - dumpDeclRef(D->getOriginalNamespace(), "original"); + NodeDumper.dumpDeclRef(D->getOriginalNamespace(), "original"); } void ASTDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) { OS << ' '; - dumpBareDeclRef(D->getNominatedNamespace()); + NodeDumper.dumpBareDeclRef(D->getNominatedNamespace()); } void ASTDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) { - dumpName(D); - dumpDeclRef(D->getAliasedNamespace()); + NodeDumper.dumpName(D); + NodeDumper.dumpDeclRef(D->getAliasedNamespace()); } void ASTDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) { - dumpName(D); - dumpType(D->getUnderlyingType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getUnderlyingType()); dumpTypeAsChild(D->getUnderlyingType()); } void ASTDumper::VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) { - dumpName(D); + NodeDumper.dumpName(D); dumpTemplateParameters(D->getTemplateParameters()); dumpDecl(D->getTemplatedDecl()); } @@ -1387,7 +841,7 @@ void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { dumpChild([=] { { - ColorScope Color(*this, DeclKindNameColor); + ColorScope Color(OS, ShowColors, DeclKindNameColor); OS << "DefinitionData"; } #define FLAG(fn, name) if (D->fn()) OS << " " #name; @@ -1415,7 +869,7 @@ void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { dumpChild([=] { { - ColorScope Color(*this, DeclKindNameColor); + ColorScope Color(OS, ShowColors, DeclKindNameColor); OS << "DefaultConstructor"; } FLAG(hasDefaultConstructor, exists); @@ -1429,7 +883,7 @@ void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { dumpChild([=] { { - ColorScope Color(*this, DeclKindNameColor); + ColorScope Color(OS, ShowColors, DeclKindNameColor); OS << "CopyConstructor"; } FLAG(hasSimpleCopyConstructor, simple); @@ -1447,7 +901,7 @@ void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { dumpChild([=] { { - ColorScope Color(*this, DeclKindNameColor); + ColorScope Color(OS, ShowColors, DeclKindNameColor); OS << "MoveConstructor"; } FLAG(hasMoveConstructor, exists); @@ -1464,7 +918,7 @@ void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { dumpChild([=] { { - ColorScope Color(*this, DeclKindNameColor); + ColorScope Color(OS, ShowColors, DeclKindNameColor); OS << "CopyAssignment"; } FLAG(hasTrivialCopyAssignment, trivial); @@ -1478,7 +932,7 @@ void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { dumpChild([=] { { - ColorScope Color(*this, DeclKindNameColor); + ColorScope Color(OS, ShowColors, DeclKindNameColor); OS << "MoveAssignment"; } FLAG(hasMoveAssignment, exists); @@ -1492,7 +946,7 @@ void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { dumpChild([=] { { - ColorScope Color(*this, DeclKindNameColor); + ColorScope Color(OS, ShowColors, DeclKindNameColor); OS << "Destructor"; } FLAG(hasSimpleDestructor, simple); @@ -1511,8 +965,8 @@ void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { dumpChild([=] { if (I.isVirtual()) OS << "virtual "; - dumpAccessSpecifier(I.getAccessSpecifier()); - dumpType(I.getType()); + NodeDumper.dumpAccessSpecifier(I.getAccessSpecifier()); + NodeDumper.dumpType(I.getType()); if (I.isPackExpansion()) OS << "..."; }); @@ -1524,10 +978,10 @@ void ASTDumper::VisitStaticAssertDecl(const StaticAssertDecl *D) { dumpStmt(D->getMessage()); } -template<typename SpecializationDecl> -void ASTDumper::VisitTemplateDeclSpecialization(const SpecializationDecl *D, - bool DumpExplicitInst, - bool DumpRefOnly) { +template <typename SpecializationDecl> +void ASTDumper::dumpTemplateDeclSpecialization(const SpecializationDecl *D, + bool DumpExplicitInst, + bool DumpRefOnly) { bool DumpedAny = false; for (auto *RedeclWithBadType : D->redecls()) { // FIXME: The redecls() range sometimes has elements of a less-specific @@ -1551,7 +1005,7 @@ void ASTDumper::VisitTemplateDeclSpecialization(const SpecializationDecl *D, case TSK_Undeclared: case TSK_ImplicitInstantiation: if (DumpRefOnly) - dumpDeclRef(Redecl); + NodeDumper.dumpDeclRef(Redecl); else dumpDecl(Redecl); DumpedAny = true; @@ -1563,31 +1017,30 @@ void ASTDumper::VisitTemplateDeclSpecialization(const SpecializationDecl *D, // Ensure we dump at least one decl for each specialization. if (!DumpedAny) - dumpDeclRef(D); + NodeDumper.dumpDeclRef(D); } -template<typename TemplateDecl> -void ASTDumper::VisitTemplateDecl(const TemplateDecl *D, - bool DumpExplicitInst) { - dumpName(D); +template <typename TemplateDecl> +void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) { + NodeDumper.dumpName(D); dumpTemplateParameters(D->getTemplateParameters()); dumpDecl(D->getTemplatedDecl()); for (auto *Child : D->specializations()) - VisitTemplateDeclSpecialization(Child, DumpExplicitInst, - !D->isCanonicalDecl()); + dumpTemplateDeclSpecialization(Child, DumpExplicitInst, + !D->isCanonicalDecl()); } void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) { // FIXME: We don't add a declaration of a function template specialization // to its context when it's explicitly instantiated, so dump explicit // instantiations when we dump the template itself. - VisitTemplateDecl(D, true); + dumpTemplateDecl(D, true); } void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) { - VisitTemplateDecl(D, false); + dumpTemplateDecl(D, false); } void ASTDumper::VisitClassTemplateSpecializationDecl( @@ -1610,11 +1063,11 @@ void ASTDumper::VisitClassScopeFunctionSpecializationDecl( } void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) { - VisitTemplateDecl(D, false); + dumpTemplateDecl(D, false); } void ASTDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) { - dumpName(D); + NodeDumper.dumpName(D); dumpTemplateParameters(D->getTemplateParameters()); } @@ -1638,19 +1091,25 @@ void ASTDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { OS << " depth " << D->getDepth() << " index " << D->getIndex(); if (D->isParameterPack()) OS << " ..."; - dumpName(D); + NodeDumper.dumpName(D); if (D->hasDefaultArgument()) - dumpTemplateArgument(D->getDefaultArgument()); + dumpTemplateArgument(D->getDefaultArgument(), SourceRange(), + D->getDefaultArgStorage().getInheritedFrom(), + D->defaultArgumentWasInherited() ? "inherited from" + : "previous"); } void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) { - dumpType(D->getType()); + NodeDumper.dumpType(D->getType()); OS << " depth " << D->getDepth() << " index " << D->getIndex(); if (D->isParameterPack()) OS << " ..."; - dumpName(D); + NodeDumper.dumpName(D); if (D->hasDefaultArgument()) - dumpTemplateArgument(D->getDefaultArgument()); + dumpTemplateArgument(D->getDefaultArgument(), SourceRange(), + D->getDefaultArgStorage().getInheritedFrom(), + D->defaultArgumentWasInherited() ? "inherited from" + : "previous"); } void ASTDumper::VisitTemplateTemplateParmDecl( @@ -1658,10 +1117,12 @@ void ASTDumper::VisitTemplateTemplateParmDecl( OS << " depth " << D->getDepth() << " index " << D->getIndex(); if (D->isParameterPack()) OS << " ..."; - dumpName(D); + NodeDumper.dumpName(D); dumpTemplateParameters(D->getTemplateParameters()); if (D->hasDefaultArgument()) - dumpTemplateArgumentLoc(D->getDefaultArgument()); + dumpTemplateArgumentLoc( + D->getDefaultArgument(), D->getDefaultArgStorage().getInheritedFrom(), + D->defaultArgumentWasInherited() ? "inherited from" : "previous"); } void ASTDumper::VisitUsingDecl(const UsingDecl *D) { @@ -1684,12 +1145,12 @@ void ASTDumper::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) if (D->getQualifier()) D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); OS << D->getNameAsString(); - dumpType(D->getType()); + NodeDumper.dumpType(D->getType()); } void ASTDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) { OS << ' '; - dumpBareDeclRef(D->getTargetDecl()); + NodeDumper.dumpBareDeclRef(D->getTargetDecl()); if (auto *TD = dyn_cast<TypeDecl>(D->getUnderlyingDecl())) dumpTypeAsChild(TD->getTypeForDecl()); } @@ -1701,21 +1162,21 @@ void ASTDumper::VisitConstructorUsingShadowDecl( dumpChild([=] { OS << "target "; - dumpBareDeclRef(D->getTargetDecl()); + NodeDumper.dumpBareDeclRef(D->getTargetDecl()); }); dumpChild([=] { OS << "nominated "; - dumpBareDeclRef(D->getNominatedBaseClass()); + NodeDumper.dumpBareDeclRef(D->getNominatedBaseClass()); OS << ' '; - dumpBareDeclRef(D->getNominatedBaseClassShadowDecl()); + NodeDumper.dumpBareDeclRef(D->getNominatedBaseClassShadowDecl()); }); dumpChild([=] { OS << "constructed "; - dumpBareDeclRef(D->getConstructedBaseClass()); + NodeDumper.dumpBareDeclRef(D->getConstructedBaseClass()); OS << ' '; - dumpBareDeclRef(D->getConstructedBaseClassShadowDecl()); + NodeDumper.dumpBareDeclRef(D->getConstructedBaseClassShadowDecl()); }); } @@ -1728,12 +1189,12 @@ void ASTDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) { void ASTDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) { OS << ' '; - dumpAccessSpecifier(D->getAccess()); + NodeDumper.dumpAccessSpecifier(D->getAccess()); } void ASTDumper::VisitFriendDecl(const FriendDecl *D) { if (TypeSourceInfo *T = D->getFriendType()) - dumpType(T->getType()); + NodeDumper.dumpType(T->getType()); else dumpDecl(D->getFriendDecl()); } @@ -1743,8 +1204,8 @@ void ASTDumper::VisitFriendDecl(const FriendDecl *D) { //===----------------------------------------------------------------------===// void ASTDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) { - dumpName(D); - dumpType(D->getType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getType()); if (D->getSynthesize()) OS << " synthesize"; @@ -1772,8 +1233,8 @@ void ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) { OS << " -"; else OS << " +"; - dumpName(D); - dumpType(D->getReturnType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getReturnType()); if (D->isThisDeclarationADefinition()) { dumpDeclContext(D); @@ -1790,7 +1251,7 @@ void ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) { } void ASTDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) { - dumpName(D); + NodeDumper.dumpName(D); switch (D->getVariance()) { case ObjCTypeParamVariance::Invariant: break; @@ -1806,47 +1267,47 @@ void ASTDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) { if (D->hasExplicitBound()) OS << " bounded"; - dumpType(D->getUnderlyingType()); + NodeDumper.dumpType(D->getUnderlyingType()); } void ASTDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) { - dumpName(D); - dumpDeclRef(D->getClassInterface()); - dumpObjCTypeParamList(D->getTypeParamList()); - dumpDeclRef(D->getImplementation()); + NodeDumper.dumpName(D); + NodeDumper.dumpDeclRef(D->getClassInterface()); + NodeDumper.dumpDeclRef(D->getImplementation()); for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I) - dumpDeclRef(*I); + NodeDumper.dumpDeclRef(*I); + dumpObjCTypeParamList(D->getTypeParamList()); } void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) { - dumpName(D); - dumpDeclRef(D->getClassInterface()); - dumpDeclRef(D->getCategoryDecl()); + NodeDumper.dumpName(D); + NodeDumper.dumpDeclRef(D->getClassInterface()); + NodeDumper.dumpDeclRef(D->getCategoryDecl()); } void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) { - dumpName(D); + NodeDumper.dumpName(D); for (auto *Child : D->protocols()) - dumpDeclRef(Child); + NodeDumper.dumpDeclRef(Child); } void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) { - dumpName(D); - dumpObjCTypeParamList(D->getTypeParamListAsWritten()); - dumpDeclRef(D->getSuperClass(), "super"); + NodeDumper.dumpName(D); + NodeDumper.dumpDeclRef(D->getSuperClass(), "super"); - dumpDeclRef(D->getImplementation()); + NodeDumper.dumpDeclRef(D->getImplementation()); for (auto *Child : D->protocols()) - dumpDeclRef(Child); + NodeDumper.dumpDeclRef(Child); + dumpObjCTypeParamList(D->getTypeParamListAsWritten()); } void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) { - dumpName(D); - dumpDeclRef(D->getSuperClass(), "super"); - dumpDeclRef(D->getClassInterface()); + NodeDumper.dumpName(D); + NodeDumper.dumpDeclRef(D->getSuperClass(), "super"); + NodeDumper.dumpDeclRef(D->getClassInterface()); for (ObjCImplementationDecl::init_const_iterator I = D->init_begin(), E = D->init_end(); I != E; ++I) @@ -1854,13 +1315,13 @@ void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) { } void ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) { - dumpName(D); - dumpDeclRef(D->getClassInterface()); + NodeDumper.dumpName(D); + NodeDumper.dumpDeclRef(D->getClassInterface()); } void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) { - dumpName(D); - dumpType(D->getType()); + NodeDumper.dumpName(D); + NodeDumper.dumpType(D->getType()); if (D->getPropertyImplementation() == ObjCPropertyDecl::Required) OS << " required"; @@ -1892,20 +1353,28 @@ void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) { if (Attrs & ObjCPropertyDecl::OBJC_PR_class) OS << " class"; if (Attrs & ObjCPropertyDecl::OBJC_PR_getter) - dumpDeclRef(D->getGetterMethodDecl(), "getter"); + NodeDumper.dumpDeclRef(D->getGetterMethodDecl(), "getter"); if (Attrs & ObjCPropertyDecl::OBJC_PR_setter) - dumpDeclRef(D->getSetterMethodDecl(), "setter"); + NodeDumper.dumpDeclRef(D->getSetterMethodDecl(), "setter"); } } void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) { - dumpName(D->getPropertyDecl()); + NodeDumper.dumpName(D->getPropertyDecl()); if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) OS << " synthesize"; else OS << " dynamic"; - dumpDeclRef(D->getPropertyDecl()); - dumpDeclRef(D->getPropertyIvarDecl()); + NodeDumper.dumpDeclRef(D->getPropertyDecl()); + NodeDumper.dumpDeclRef(D->getPropertyIvarDecl()); +} + +void ASTDumper::Visit(const BlockDecl::Capture &C) { + dumpChild([=] { + NodeDumper.Visit(C); + if (C.hasCopyExpr()) + dumpStmt(C.getCopyExpr()); + }); } void ASTDumper::VisitBlockDecl(const BlockDecl *D) { @@ -1918,21 +1387,8 @@ void ASTDumper::VisitBlockDecl(const BlockDecl *D) { if (D->capturesCXXThis()) dumpChild([=]{ OS << "capture this"; }); - for (const auto &I : D->captures()) { - dumpChild([=] { - OS << "capture"; - if (I.isByRef()) - OS << " byref"; - if (I.isNested()) - OS << " nested"; - if (I.getVariable()) { - OS << ' '; - dumpBareDeclRef(I.getVariable()); - } - if (I.hasCopyExpr()) - dumpStmt(I.getCopyExpr()); - }); - } + for (const auto &I : D->captures()) + Visit(I); dumpStmt(D->getBody()); } @@ -1940,42 +1396,27 @@ void ASTDumper::VisitBlockDecl(const BlockDecl *D) { // Stmt dumping methods. //===----------------------------------------------------------------------===// -void ASTDumper::dumpStmt(const Stmt *S) { - dumpChild([=] { +void ASTDumper::dumpStmt(const Stmt *S, StringRef Label) { + dumpChild(Label, [=] { + NodeDumper.Visit(S); + if (!S) { - ColorScope Color(*this, NullColor); - OS << "<<<NULL>>>"; return; } + ConstStmtVisitor<ASTDumper>::Visit(S); + // Some statements have custom mechanisms for dumping their children. - if (const DeclStmt *DS = dyn_cast<DeclStmt>(S)) { - VisitDeclStmt(DS); - return; - } - if (const GenericSelectionExpr *GSE = dyn_cast<GenericSelectionExpr>(S)) { - VisitGenericSelectionExpr(GSE); + if (isa<DeclStmt>(S) || isa<GenericSelectionExpr>(S)) { return; } - ConstStmtVisitor<ASTDumper>::Visit(S); - for (const Stmt *SubStmt : S->children()) dumpStmt(SubStmt); }); } -void ASTDumper::VisitStmt(const Stmt *Node) { - { - ColorScope Color(*this, StmtColor); - OS << Node->getStmtClassName(); - } - dumpPointer(Node); - dumpSourceRange(Node->getSourceRange()); -} - void ASTDumper::VisitDeclStmt(const DeclStmt *Node) { - VisitStmt(Node); for (DeclStmt::const_decl_iterator I = Node->decl_begin(), E = Node->decl_end(); I != E; ++I) @@ -1983,31 +1424,17 @@ void ASTDumper::VisitDeclStmt(const DeclStmt *Node) { } void ASTDumper::VisitAttributedStmt(const AttributedStmt *Node) { - VisitStmt(Node); for (ArrayRef<const Attr *>::iterator I = Node->getAttrs().begin(), E = Node->getAttrs().end(); I != E; ++I) dumpAttr(*I); } -void ASTDumper::VisitLabelStmt(const LabelStmt *Node) { - VisitStmt(Node); - OS << " '" << Node->getName() << "'"; -} - -void ASTDumper::VisitGotoStmt(const GotoStmt *Node) { - VisitStmt(Node); - OS << " '" << Node->getLabel()->getName() << "'"; - dumpPointer(Node->getLabel()); -} - void ASTDumper::VisitCXXCatchStmt(const CXXCatchStmt *Node) { - VisitStmt(Node); dumpDecl(Node->getExceptionDecl()); } void ASTDumper::VisitCapturedStmt(const CapturedStmt *Node) { - VisitStmt(Node); dumpDecl(Node->getCapturedDecl()); } @@ -2015,287 +1442,41 @@ void ASTDumper::VisitCapturedStmt(const CapturedStmt *Node) { // OpenMP dumping methods. //===----------------------------------------------------------------------===// +void ASTDumper::Visit(const OMPClause *C) { + dumpChild([=] { + NodeDumper.Visit(C); + for (auto *S : C->children()) + dumpStmt(S); + }); +} + void ASTDumper::VisitOMPExecutableDirective( const OMPExecutableDirective *Node) { - VisitStmt(Node); - for (auto *C : Node->clauses()) { - dumpChild([=] { - if (!C) { - ColorScope Color(*this, NullColor); - OS << "<<<NULL>>> OMPClause"; - return; - } - { - ColorScope Color(*this, AttrColor); - StringRef ClauseName(getOpenMPClauseName(C->getClauseKind())); - OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper() - << ClauseName.drop_front() << "Clause"; - } - dumpPointer(C); - dumpSourceRange(SourceRange(C->getLocStart(), C->getLocEnd())); - if (C->isImplicit()) - OS << " <implicit>"; - for (auto *S : C->children()) - dumpStmt(S); - }); - } + for (const auto *C : Node->clauses()) + Visit(C); } //===----------------------------------------------------------------------===// // Expr dumping methods. //===----------------------------------------------------------------------===// -void ASTDumper::VisitExpr(const Expr *Node) { - VisitStmt(Node); - dumpType(Node->getType()); - - { - ColorScope Color(*this, ValueKindColor); - switch (Node->getValueKind()) { - case VK_RValue: - break; - case VK_LValue: - OS << " lvalue"; - break; - case VK_XValue: - OS << " xvalue"; - break; - } - } - - { - ColorScope Color(*this, ObjectKindColor); - switch (Node->getObjectKind()) { - case OK_Ordinary: - break; - case OK_BitField: - OS << " bitfield"; - break; - case OK_ObjCProperty: - OS << " objcproperty"; - break; - case OK_ObjCSubscript: - OS << " objcsubscript"; - break; - case OK_VectorComponent: - OS << " vectorcomponent"; - break; - } - } -} - -static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) { - if (Node->path_empty()) - return; - - OS << " ("; - bool First = true; - for (CastExpr::path_const_iterator I = Node->path_begin(), - E = Node->path_end(); - I != E; ++I) { - const CXXBaseSpecifier *Base = *I; - if (!First) - OS << " -> "; - - const CXXRecordDecl *RD = - cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); - - if (Base->isVirtual()) - OS << "virtual "; - OS << RD->getName(); - First = false; - } - - OS << ')'; -} - -void ASTDumper::VisitCastExpr(const CastExpr *Node) { - VisitExpr(Node); - OS << " <"; - { - ColorScope Color(*this, CastColor); - OS << Node->getCastKindName(); - } - dumpBasePath(OS, Node); - OS << ">"; -} - -void ASTDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) { - VisitCastExpr(Node); - if (Node->isPartOfExplicitCast()) - OS << " part_of_explicit_cast"; -} - -void ASTDumper::VisitDeclRefExpr(const DeclRefExpr *Node) { - VisitExpr(Node); - - OS << " "; - dumpBareDeclRef(Node->getDecl()); - if (Node->getDecl() != Node->getFoundDecl()) { - OS << " ("; - dumpBareDeclRef(Node->getFoundDecl()); - OS << ")"; - } -} - -void ASTDumper::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node) { - VisitExpr(Node); - OS << " ("; - if (!Node->requiresADL()) - OS << "no "; - OS << "ADL) = '" << Node->getName() << '\''; - - UnresolvedLookupExpr::decls_iterator - I = Node->decls_begin(), E = Node->decls_end(); - if (I == E) - OS << " empty"; - for (; I != E; ++I) - dumpPointer(*I); -} - -void ASTDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) { - VisitExpr(Node); - - { - ColorScope Color(*this, DeclKindNameColor); - OS << " " << Node->getDecl()->getDeclKindName() << "Decl"; - } - OS << "='" << *Node->getDecl() << "'"; - dumpPointer(Node->getDecl()); - if (Node->isFreeIvar()) - OS << " isFreeIvar"; -} - -void ASTDumper::VisitPredefinedExpr(const PredefinedExpr *Node) { - VisitExpr(Node); - OS << " " << PredefinedExpr::getIdentTypeName(Node->getIdentType()); -} - -void ASTDumper::VisitCharacterLiteral(const CharacterLiteral *Node) { - VisitExpr(Node); - ColorScope Color(*this, ValueColor); - OS << " " << Node->getValue(); -} - -void ASTDumper::VisitIntegerLiteral(const IntegerLiteral *Node) { - VisitExpr(Node); - - bool isSigned = Node->getType()->isSignedIntegerType(); - ColorScope Color(*this, ValueColor); - OS << " " << Node->getValue().toString(10, isSigned); -} - -void ASTDumper::VisitFixedPointLiteral(const FixedPointLiteral *Node) { - VisitExpr(Node); - - ColorScope Color(*this, ValueColor); - OS << " " << Node->getValueAsString(/*Radix=*/10); -} - -void ASTDumper::VisitFloatingLiteral(const FloatingLiteral *Node) { - VisitExpr(Node); - ColorScope Color(*this, ValueColor); - OS << " " << Node->getValueAsApproximateDouble(); -} - -void ASTDumper::VisitStringLiteral(const StringLiteral *Str) { - VisitExpr(Str); - ColorScope Color(*this, ValueColor); - OS << " "; - Str->outputString(OS); -} void ASTDumper::VisitInitListExpr(const InitListExpr *ILE) { - VisitExpr(ILE); if (auto *Filler = ILE->getArrayFiller()) { - dumpChild([=] { - OS << "array filler"; - dumpStmt(Filler); - }); - } - if (auto *Field = ILE->getInitializedFieldInUnion()) { - OS << " field "; - dumpBareDeclRef(Field); - } -} - -void ASTDumper::VisitArrayInitLoopExpr(const ArrayInitLoopExpr *E) { - VisitExpr(E); -} - -void ASTDumper::VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E) { - VisitExpr(E); -} - -void ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) { - VisitExpr(Node); - OS << " " << (Node->isPostfix() ? "postfix" : "prefix") - << " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; - if (!Node->canOverflow()) - OS << " cannot overflow"; -} - -void ASTDumper::VisitUnaryExprOrTypeTraitExpr( - const UnaryExprOrTypeTraitExpr *Node) { - VisitExpr(Node); - switch(Node->getKind()) { - case UETT_SizeOf: - OS << " sizeof"; - break; - case UETT_AlignOf: - OS << " alignof"; - break; - case UETT_VecStep: - OS << " vec_step"; - break; - case UETT_OpenMPRequiredSimdAlign: - OS << " __builtin_omp_required_simd_align"; - break; + dumpStmt(Filler, "array_filler"); } - if (Node->isArgumentType()) - dumpType(Node->getArgumentType()); -} - -void ASTDumper::VisitMemberExpr(const MemberExpr *Node) { - VisitExpr(Node); - OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl(); - dumpPointer(Node->getMemberDecl()); -} - -void ASTDumper::VisitExtVectorElementExpr(const ExtVectorElementExpr *Node) { - VisitExpr(Node); - OS << " " << Node->getAccessor().getNameStart(); -} - -void ASTDumper::VisitBinaryOperator(const BinaryOperator *Node) { - VisitExpr(Node); - OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; -} - -void ASTDumper::VisitCompoundAssignOperator( - const CompoundAssignOperator *Node) { - VisitExpr(Node); - OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) - << "' ComputeLHSTy="; - dumpBareType(Node->getComputationLHSType()); - OS << " ComputeResultTy="; - dumpBareType(Node->getComputationResultType()); } void ASTDumper::VisitBlockExpr(const BlockExpr *Node) { - VisitExpr(Node); dumpDecl(Node->getBlockDecl()); } void ASTDumper::VisitOpaqueValueExpr(const OpaqueValueExpr *Node) { - VisitExpr(Node); - if (Expr *Source = Node->getSourceExpr()) dumpStmt(Source); } void ASTDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) { - VisitExpr(E); if (E->isResultDependent()) OS << " result_dependent"; dumpStmt(E->getControllingExpr()); @@ -2305,7 +1486,7 @@ void ASTDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) { dumpChild([=] { if (const TypeSourceInfo *TSI = E->getAssocTypeSourceInfo(I)) { OS << "case "; - dumpType(TSI->getType()); + NodeDumper.dumpType(TSI->getType()); } else { OS << "default"; } @@ -2320,394 +1501,42 @@ void ASTDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) { } } -// GNU extensions. - -void ASTDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) { - VisitExpr(Node); - OS << " " << Node->getLabel()->getName(); - dumpPointer(Node->getLabel()); -} - //===----------------------------------------------------------------------===// // C++ Expressions //===----------------------------------------------------------------------===// -void ASTDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) { - VisitExpr(Node); - OS << " " << Node->getCastName() - << "<" << Node->getTypeAsWritten().getAsString() << ">" - << " <" << Node->getCastKindName(); - dumpBasePath(OS, Node); - OS << ">"; -} - -void ASTDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) { - VisitExpr(Node); - OS << " " << (Node->getValue() ? "true" : "false"); -} - -void ASTDumper::VisitCXXThisExpr(const CXXThisExpr *Node) { - VisitExpr(Node); - OS << " this"; -} - -void ASTDumper::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node) { - VisitExpr(Node); - OS << " functional cast to " << Node->getTypeAsWritten().getAsString() - << " <" << Node->getCastKindName() << ">"; -} - -void ASTDumper::VisitCXXUnresolvedConstructExpr( - const CXXUnresolvedConstructExpr *Node) { - VisitExpr(Node); - dumpType(Node->getTypeAsWritten()); - if (Node->isListInitialization()) - OS << " list"; -} - -void ASTDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) { - VisitExpr(Node); - CXXConstructorDecl *Ctor = Node->getConstructor(); - dumpType(Ctor->getType()); - if (Node->isElidable()) - OS << " elidable"; - if (Node->isListInitialization()) - OS << " list"; - if (Node->isStdInitListInitialization()) - OS << " std::initializer_list"; - if (Node->requiresZeroInitialization()) - OS << " zeroing"; -} - -void ASTDumper::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node) { - VisitExpr(Node); - OS << " "; - dumpCXXTemporary(Node->getTemporary()); -} - -void ASTDumper::VisitCXXNewExpr(const CXXNewExpr *Node) { - VisitExpr(Node); - if (Node->isGlobalNew()) - OS << " global"; - if (Node->isArray()) - OS << " array"; - if (Node->getOperatorNew()) { - OS << ' '; - dumpBareDeclRef(Node->getOperatorNew()); - } - // We could dump the deallocation function used in case of error, but it's - // usually not that interesting. -} - -void ASTDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *Node) { - VisitExpr(Node); - if (Node->isGlobalDelete()) - OS << " global"; - if (Node->isArrayForm()) - OS << " array"; - if (Node->getOperatorDelete()) { - OS << ' '; - dumpBareDeclRef(Node->getOperatorDelete()); - } -} - -void -ASTDumper::VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node) { - VisitExpr(Node); - if (const ValueDecl *VD = Node->getExtendingDecl()) { - OS << " extended by "; - dumpBareDeclRef(VD); - } -} - -void ASTDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) { - VisitExpr(Node); - for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i) - dumpDeclRef(Node->getObject(i), "cleanup"); -} - -void ASTDumper::dumpCXXTemporary(const CXXTemporary *Temporary) { - OS << "(CXXTemporary"; - dumpPointer(Temporary); - OS << ")"; -} - void ASTDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) { - VisitExpr(Node); - dumpPointer(Node->getPack()); - dumpName(Node->getPack()); if (Node->isPartiallySubstituted()) for (const auto &A : Node->getPartialArguments()) dumpTemplateArgument(A); } -void ASTDumper::VisitCXXDependentScopeMemberExpr( - const CXXDependentScopeMemberExpr *Node) { - VisitExpr(Node); - OS << " " << (Node->isArrow() ? "->" : ".") << Node->getMember(); -} - //===----------------------------------------------------------------------===// // Obj-C Expressions //===----------------------------------------------------------------------===// -void ASTDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) { - VisitExpr(Node); - OS << " selector="; - Node->getSelector().print(OS); - switch (Node->getReceiverKind()) { - case ObjCMessageExpr::Instance: - break; - - case ObjCMessageExpr::Class: - OS << " class="; - dumpBareType(Node->getClassReceiver()); - break; - - case ObjCMessageExpr::SuperInstance: - OS << " super (instance)"; - break; - - case ObjCMessageExpr::SuperClass: - OS << " super (class)"; - break; - } -} - -void ASTDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) { - VisitExpr(Node); - if (auto *BoxingMethod = Node->getBoxingMethod()) { - OS << " selector="; - BoxingMethod->getSelector().print(OS); - } -} - void ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) { - VisitStmt(Node); if (const VarDecl *CatchParam = Node->getCatchParamDecl()) dumpDecl(CatchParam); - else - OS << " catch all"; -} - -void ASTDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) { - VisitExpr(Node); - dumpType(Node->getEncodedType()); -} - -void ASTDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) { - VisitExpr(Node); - - OS << " "; - Node->getSelector().print(OS); -} - -void ASTDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) { - VisitExpr(Node); - - OS << ' ' << *Node->getProtocol(); -} - -void ASTDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) { - VisitExpr(Node); - if (Node->isImplicitProperty()) { - OS << " Kind=MethodRef Getter=\""; - if (Node->getImplicitPropertyGetter()) - Node->getImplicitPropertyGetter()->getSelector().print(OS); - else - OS << "(null)"; - - OS << "\" Setter=\""; - if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter()) - Setter->getSelector().print(OS); - else - OS << "(null)"; - OS << "\""; - } else { - OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty() <<'"'; - } - - if (Node->isSuperReceiver()) - OS << " super"; - - OS << " Messaging="; - if (Node->isMessagingGetter() && Node->isMessagingSetter()) - OS << "Getter&Setter"; - else if (Node->isMessagingGetter()) - OS << "Getter"; - else if (Node->isMessagingSetter()) - OS << "Setter"; -} - -void ASTDumper::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node) { - VisitExpr(Node); - if (Node->isArraySubscriptRefExpr()) - OS << " Kind=ArraySubscript GetterForArray=\""; - else - OS << " Kind=DictionarySubscript GetterForDictionary=\""; - if (Node->getAtIndexMethodDecl()) - Node->getAtIndexMethodDecl()->getSelector().print(OS); - else - OS << "(null)"; - - if (Node->isArraySubscriptRefExpr()) - OS << "\" SetterForArray=\""; - else - OS << "\" SetterForDictionary=\""; - if (Node->setAtIndexMethodDecl()) - Node->setAtIndexMethodDecl()->getSelector().print(OS); - else - OS << "(null)"; -} - -void ASTDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) { - VisitExpr(Node); - OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no"); } //===----------------------------------------------------------------------===// // Comments //===----------------------------------------------------------------------===// -const char *ASTDumper::getCommandName(unsigned CommandID) { - if (Traits) - return Traits->getCommandInfo(CommandID)->Name; - const CommandInfo *Info = CommandTraits::getBuiltinCommandInfo(CommandID); - if (Info) - return Info->Name; - return "<not a builtin command>"; -} - -void ASTDumper::dumpFullComment(const FullComment *C) { - if (!C) - return; - - FC = C; - dumpComment(C); - FC = nullptr; -} - -void ASTDumper::dumpComment(const Comment *C) { +void ASTDumper::dumpComment(const Comment *C, const FullComment *FC) { dumpChild([=] { + NodeDumper.Visit(C, FC); if (!C) { - ColorScope Color(*this, NullColor); - OS << "<<<NULL>>>"; return; } - - { - ColorScope Color(*this, CommentColor); - OS << C->getCommentKindName(); - } - dumpPointer(C); - dumpSourceRange(C->getSourceRange()); - ConstCommentVisitor<ASTDumper>::visit(C); + ConstCommentVisitor<ASTDumper, void, const FullComment *>::visit(C, FC); for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); I != E; ++I) - dumpComment(*I); + dumpComment(*I, FC); }); } -void ASTDumper::visitTextComment(const TextComment *C) { - OS << " Text=\"" << C->getText() << "\""; -} - -void ASTDumper::visitInlineCommandComment(const InlineCommandComment *C) { - OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; - switch (C->getRenderKind()) { - case InlineCommandComment::RenderNormal: - OS << " RenderNormal"; - break; - case InlineCommandComment::RenderBold: - OS << " RenderBold"; - break; - case InlineCommandComment::RenderMonospaced: - OS << " RenderMonospaced"; - break; - case InlineCommandComment::RenderEmphasized: - OS << " RenderEmphasized"; - break; - } - - for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) - OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; -} - -void ASTDumper::visitHTMLStartTagComment(const HTMLStartTagComment *C) { - OS << " Name=\"" << C->getTagName() << "\""; - if (C->getNumAttrs() != 0) { - OS << " Attrs: "; - for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) { - const HTMLStartTagComment::Attribute &Attr = C->getAttr(i); - OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\""; - } - } - if (C->isSelfClosing()) - OS << " SelfClosing"; -} - -void ASTDumper::visitHTMLEndTagComment(const HTMLEndTagComment *C) { - OS << " Name=\"" << C->getTagName() << "\""; -} - -void ASTDumper::visitBlockCommandComment(const BlockCommandComment *C) { - OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; - for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) - OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; -} - -void ASTDumper::visitParamCommandComment(const ParamCommandComment *C) { - OS << " " << ParamCommandComment::getDirectionAsString(C->getDirection()); - - if (C->isDirectionExplicit()) - OS << " explicitly"; - else - OS << " implicitly"; - - if (C->hasParamName()) { - if (C->isParamIndexValid()) - OS << " Param=\"" << C->getParamName(FC) << "\""; - else - OS << " Param=\"" << C->getParamNameAsWritten() << "\""; - } - - if (C->isParamIndexValid() && !C->isVarArgParam()) - OS << " ParamIndex=" << C->getParamIndex(); -} - -void ASTDumper::visitTParamCommandComment(const TParamCommandComment *C) { - if (C->hasParamName()) { - if (C->isPositionValid()) - OS << " Param=\"" << C->getParamName(FC) << "\""; - else - OS << " Param=\"" << C->getParamNameAsWritten() << "\""; - } - - if (C->isPositionValid()) { - OS << " Position=<"; - for (unsigned i = 0, e = C->getDepth(); i != e; ++i) { - OS << C->getIndex(i); - if (i != e - 1) - OS << ", "; - } - OS << ">"; - } -} - -void ASTDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) { - OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"" - " CloseName=\"" << C->getCloseName() << "\""; -} - -void ASTDumper::visitVerbatimBlockLineComment( - const VerbatimBlockLineComment *C) { - OS << " Text=\"" << C->getText() << "\""; -} - -void ASTDumper::visitVerbatimLineComment(const VerbatimLineComment *C) { - OS << " Text=\"" << C->getText() << "\""; -} - //===----------------------------------------------------------------------===// // Type method implementations //===----------------------------------------------------------------------===// @@ -2816,12 +1645,16 @@ LLVM_DUMP_METHOD void Comment::dump(const ASTContext &Context) const { void Comment::dump(raw_ostream &OS, const CommandTraits *Traits, const SourceManager *SM) const { const FullComment *FC = dyn_cast<FullComment>(this); + if (!FC) + return; ASTDumper D(OS, Traits, SM); - D.dumpFullComment(FC); + D.dumpComment(FC, FC); } LLVM_DUMP_METHOD void Comment::dumpColor() const { const FullComment *FC = dyn_cast<FullComment>(this); + if (!FC) + return; ASTDumper D(llvm::errs(), nullptr, nullptr, /*ShowColors*/true); - D.dumpFullComment(FC); + D.dumpComment(FC, FC); } |