diff options
Diffstat (limited to 'lib/AST/ASTDumper.cpp')
-rw-r--r-- | lib/AST/ASTDumper.cpp | 898 |
1 files changed, 761 insertions, 137 deletions
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index 51d0f26c56..31331f1f9d 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -12,11 +12,12 @@ // //===----------------------------------------------------------------------===// -#include "clang/AST/PrettyPrinter.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclVisitor.h" #include "clang/AST/StmtVisitor.h" +#include "clang/Basic/Module.h" #include "clang/Basic/SourceManager.h" #include "llvm/Support/raw_ostream.h" using namespace clang; @@ -26,7 +27,8 @@ using namespace clang; //===----------------------------------------------------------------------===// namespace { - class ASTDumper : public StmtVisitor<ASTDumper> { + class ASTDumper + : public DeclVisitor<ASTDumper>, public StmtVisitor<ASTDumper> { SourceManager *SM; raw_ostream &OS; unsigned IndentLevel; @@ -63,10 +65,78 @@ namespace { // Utilities void indent(); void unindent(); - void dumpSourceRange(const Stmt *Node); + void dumpPointer(const void *Ptr); + void dumpSourceRange(SourceRange R); void dumpLocation(SourceLocation Loc); + void dumpBareType(QualType T); void dumpType(QualType T); - void dumpDeclRef(Decl *node); + void dumpBareDeclRef(Decl *node); + void dumpDeclRef(Decl *node, const char *Label = NULL); + void dumpName(NamedDecl *D); + void dumpDeclContext(DeclContext *DC); + + // C++ Utilities + void dumpAccessSpecifier(AccessSpecifier AS); + void dumpCXXCtorInitializer(CXXCtorInitializer *Init); + void dumpTemplateParameters(TemplateParameterList *TPL); + void dumpTemplateArgumentListInfo(const TemplateArgumentListInfo &TALI); + void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A); + void dumpTemplateArgumentList(const TemplateArgumentList &TAL); + void dumpTemplateArgument(const TemplateArgument &A, + SourceRange R = SourceRange()); + + // Decls + void VisitLabelDecl(LabelDecl *D); + void VisitTypedefDecl(TypedefDecl *D); + void VisitEnumDecl(EnumDecl *D); + void VisitRecordDecl(RecordDecl *D); + void VisitEnumConstantDecl(EnumConstantDecl *D); + void VisitIndirectFieldDecl(IndirectFieldDecl *D); + void VisitFunctionDecl(FunctionDecl *D); + void VisitFieldDecl(FieldDecl *D); + void VisitVarDecl(VarDecl *D); + void VisitFileScopeAsmDecl(FileScopeAsmDecl *D); + void VisitImportDecl(ImportDecl *D); + + // C++ Decls + void VisitNamespaceDecl(NamespaceDecl *D); + void VisitUsingDirectiveDecl(UsingDirectiveDecl *D); + void VisitNamespaceAliasDecl(NamespaceAliasDecl *D); + void VisitTypeAliasDecl(TypeAliasDecl *D); + void VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D); + void VisitCXXRecordDecl(CXXRecordDecl *D); + void VisitStaticAssertDecl(StaticAssertDecl *D); + void VisitFunctionTemplateDecl(FunctionTemplateDecl *D); + void VisitClassTemplateDecl(ClassTemplateDecl *D); + void VisitClassTemplateSpecializationDecl( + ClassTemplateSpecializationDecl *D); + void VisitClassTemplatePartialSpecializationDecl( + ClassTemplatePartialSpecializationDecl *D); + void VisitClassScopeFunctionSpecializationDecl( + ClassScopeFunctionSpecializationDecl *D); + void VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D); + void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D); + void VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D); + void VisitUsingDecl(UsingDecl *D); + void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); + void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); + void VisitUsingShadowDecl(UsingShadowDecl *D); + void VisitLinkageSpecDecl(LinkageSpecDecl *D); + void VisitAccessSpecDecl(AccessSpecDecl *D); + void VisitFriendDecl(FriendDecl *D); + + // ObjC Decls + void VisitObjCIvarDecl(ObjCIvarDecl *D); + void VisitObjCMethodDecl(ObjCMethodDecl *D); + void VisitObjCCategoryDecl(ObjCCategoryDecl *D); + void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D); + void VisitObjCProtocolDecl(ObjCProtocolDecl *D); + void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); + void VisitObjCImplementationDecl(ObjCImplementationDecl *D); + void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D); + void VisitObjCPropertyDecl(ObjCPropertyDecl *D); + void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D); + void VisitBlockDecl(BlockDecl *D); // Stmts. void VisitStmt(Stmt *Node); @@ -137,6 +207,10 @@ void ASTDumper::unindent() { IndentLevel--; } +void ASTDumper::dumpPointer(const void *Ptr) { + OS << ' ' << Ptr; +} + void ASTDumper::dumpLocation(SourceLocation Loc) { SourceLocation SpellingLoc = SM->getSpellingLoc(Loc); @@ -163,15 +237,11 @@ void ASTDumper::dumpLocation(SourceLocation Loc) { } } -void ASTDumper::dumpSourceRange(const Stmt *Node) { +void ASTDumper::dumpSourceRange(SourceRange R) { // Can't translate locations if a SourceManager isn't available. if (!SM) return; - // TODO: If the parent expression is available, we can print a delta vs its - // location. - SourceRange R = Node->getSourceRange(); - OS << " <"; dumpLocation(R.getBegin()); if (R.getBegin() != R.getEnd()) { @@ -184,7 +254,7 @@ void ASTDumper::dumpSourceRange(const Stmt *Node) { } -void ASTDumper::dumpType(QualType T) { +void ASTDumper::dumpBareType(QualType T) { SplitQualType T_split = T.split(); OS << "'" << QualType::getAsString(T_split) << "'"; @@ -196,8 +266,14 @@ void ASTDumper::dumpType(QualType T) { } } -void ASTDumper::dumpDeclRef(Decl *D) { - OS << D->getDeclKindName() << ' ' << (void*) D; +void ASTDumper::dumpType(QualType T) { + OS << ' '; + dumpBareType(T); +} + +void ASTDumper::dumpBareDeclRef(Decl *D) { + OS << D->getDeclKindName(); + dumpPointer(D); if (NamedDecl *ND = dyn_cast<NamedDecl>(D)) { OS << " '"; @@ -205,9 +281,132 @@ void ASTDumper::dumpDeclRef(Decl *D) { OS << "'"; } - if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) { - OS << ' '; + if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) dumpType(VD->getType()); +} + +void ASTDumper::dumpDeclRef(Decl *D, const char *Label) { + if (!D) + return; + + IndentScope Indent(*this); + if (Label) + OS << Label << ' '; + dumpBareDeclRef(D); +} + +void ASTDumper::dumpName(NamedDecl *ND) { + if (ND->getDeclName()) + OS << ' ' << ND->getNameAsString(); +} + +void ASTDumper::dumpDeclContext(DeclContext *DC) { + if (!DC) + return; + for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end(); + I != E; ++I) + dumpDecl(*I); +} + +//===----------------------------------------------------------------------===// +// 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(CXXCtorInitializer *Init) { + IndentScope Indent(*this); + OS << "CXXCtorInitializer"; + if (Init->isAnyMemberInitializer()) { + OS << ' '; + dumpBareDeclRef(Init->getAnyMember()); + } else { + dumpType(QualType(Init->getBaseClass(), 0)); + } + dumpStmt(Init->getInit()); +} + +void ASTDumper::dumpTemplateParameters(TemplateParameterList *TPL) { + if (!TPL) + return; + + for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); + I != E; ++I) + dumpDecl(*I); +} + +void ASTDumper::dumpTemplateArgumentListInfo( + const TemplateArgumentListInfo &TALI) { + for (unsigned i = 0, e = TALI.size(); i < e; ++i) + dumpTemplateArgumentLoc(TALI[i]); +} + +void ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A) { + dumpTemplateArgument(A.getArgument(), A.getSourceRange()); +} + +void ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) { + for (unsigned i = 0, e = TAL.size(); i < e; ++i) + dumpTemplateArgument(TAL[i]); +} + +void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R) { + IndentScope Indent(*this); + OS << "TemplateArgument"; + if (R.isValid()) + dumpSourceRange(R); + + switch (A.getKind()) { + case TemplateArgument::Null: + OS << " null"; + break; + case TemplateArgument::Type: + OS << " type"; + dumpType(A.getAsType()); + break; + case TemplateArgument::Declaration: + OS << " decl"; + dumpDeclRef(A.getAsDecl()); + break; + case TemplateArgument::NullPtr: + OS << " nullptr"; + break; + case TemplateArgument::Integral: + OS << " integral"; + OS << ' ' << 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; } } @@ -216,71 +415,514 @@ void ASTDumper::dumpDeclRef(Decl *D) { //===----------------------------------------------------------------------===// void ASTDumper::dumpDecl(Decl *D) { - // FIXME: Need to complete/beautify this... this code simply shows the - // nodes are where they need to be. - if (TypedefDecl *localType = dyn_cast<TypedefDecl>(D)) { - OS << "\"typedef " << localType->getUnderlyingType().getAsString() - << ' ' << *localType << '"'; - } else if (TypeAliasDecl *localType = dyn_cast<TypeAliasDecl>(D)) { - OS << "\"using " << *localType << " = " - << localType->getUnderlyingType().getAsString() << '"'; - } else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) { - OS << "\""; - // Emit storage class for vardecls. - if (VarDecl *V = dyn_cast<VarDecl>(VD)) { - if (V->getStorageClass() != SC_None) - OS << VarDecl::getStorageClassSpecifierString(V->getStorageClass()) - << " "; + IndentScope Indent(*this); + + if (!D) { + OS << "<<<NULL>>>"; + return; + } + + OS << D->getDeclKindName() << "Decl"; + dumpPointer(D); + dumpSourceRange(D->getSourceRange()); + DeclVisitor<ASTDumper>::Visit(D); + // Decls within functions are visited by the body + if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D)) + dumpDeclContext(dyn_cast<DeclContext>(D)); +} + +void ASTDumper::VisitLabelDecl(LabelDecl *D) { + dumpName(D); +} + +void ASTDumper::VisitTypedefDecl(TypedefDecl *D) { + dumpName(D); + dumpType(D->getUnderlyingType()); + if (D->isModulePrivate()) + OS << " __module_private__"; +} + +void ASTDumper::VisitEnumDecl(EnumDecl *D) { + if (D->isScoped()) { + if (D->isScopedUsingClassTag()) + OS << " class"; + else + OS << " struct"; + } + dumpName(D); + if (D->isModulePrivate()) + OS << " __module_private__"; + if (D->isFixed()) + dumpType(D->getIntegerType()); +} + +void ASTDumper::VisitRecordDecl(RecordDecl *D) { + OS << ' ' << D->getKindName(); + dumpName(D); + if (D->isModulePrivate()) + OS << " __module_private__"; +} + +void ASTDumper::VisitEnumConstantDecl(EnumConstantDecl *D) { + dumpName(D); + dumpType(D->getType()); + if (Expr *Init = D->getInitExpr()) + dumpStmt(Init); +} + +void ASTDumper::VisitIndirectFieldDecl(IndirectFieldDecl *D) { + dumpName(D); + dumpType(D->getType()); + for (IndirectFieldDecl::chain_iterator I = D->chain_begin(), + E = D->chain_end(); I != E; ++I) + dumpDeclRef(*I); +} + +void ASTDumper::VisitFunctionDecl(FunctionDecl *D) { + dumpName(D); + dumpType(D->getType()); + + StorageClass SC = D->getStorageClassAsWritten(); + if (SC != SC_None) + OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); + if (D->isInlineSpecified()) + OS << " inline"; + if (D->isVirtualAsWritten()) + OS << " virtual"; + if (D->isModulePrivate()) + OS << " __module_private__"; + + if (D->isPure()) + OS << " pure"; + else if (D->isDeletedAsWritten()) + OS << " delete"; + + if (const FunctionTemplateSpecializationInfo *FTSI = + D->getTemplateSpecializationInfo()) + dumpTemplateArgumentList(*FTSI->TemplateArguments); + + for (llvm::ArrayRef<NamedDecl*>::iterator + I = D->getDeclsInPrototypeScope().begin(), + E = D->getDeclsInPrototypeScope().end(); I != E; ++I) + dumpDecl(*I); + + for (FunctionDecl::param_iterator I = D->param_begin(), E = D->param_end(); + I != E; ++I) + dumpDecl(*I); + + if (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 (D->doesThisDeclarationHaveABody()) + dumpStmt(D->getBody()); +} + +void ASTDumper::VisitFieldDecl(FieldDecl *D) { + dumpName(D); + dumpType(D->getType()); + if (D->isMutable()) + OS << " mutable"; + if (D->isModulePrivate()) + OS << " __module_private__"; + if (D->isBitField()) + dumpStmt(D->getBitWidth()); + if (Expr *Init = D->getInClassInitializer()) + dumpStmt(Init); +} + +void ASTDumper::VisitVarDecl(VarDecl *D) { + dumpName(D); + dumpType(D->getType()); + StorageClass SC = D->getStorageClassAsWritten(); + if (SC != SC_None) + OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); + if (D->isThreadSpecified()) + OS << " __thread"; + if (D->isModulePrivate()) + OS << " __module_private__"; + if (D->isNRVOVariable()) + OS << " nrvo"; + if (D->hasInit()) + dumpStmt(D->getInit()); +} + +void ASTDumper::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) { + dumpStmt(D->getAsmString()); +} + +void ASTDumper::VisitImportDecl(ImportDecl *D) { + OS << ' ' << D->getImportedModule()->getFullModuleName(); +} + +//===----------------------------------------------------------------------===// +// C++ Declarations +//===----------------------------------------------------------------------===// + +void ASTDumper::VisitNamespaceDecl(NamespaceDecl *D) { + dumpName(D); + if (D->isInline()) + OS << " inline"; + if (!D->isOriginalNamespace()) + dumpDeclRef(D->getOriginalNamespace(), "original"); +} + +void ASTDumper::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { + OS << ' '; + dumpBareDeclRef(D->getNominatedNamespace()); +} + +void ASTDumper::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { + dumpName(D); + dumpDeclRef(D->getAliasedNamespace()); +} + +void ASTDumper::VisitTypeAliasDecl(TypeAliasDecl *D) { + dumpName(D); + dumpType(D->getUnderlyingType()); +} + +void ASTDumper::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) { + dumpName(D); + dumpTemplateParameters(D->getTemplateParameters()); + dumpDecl(D->getTemplatedDecl()); +} + +void ASTDumper::VisitCXXRecordDecl(CXXRecordDecl *D) { + VisitRecordDecl(D); + if (!D->isCompleteDefinition()) + return; + + for (CXXRecordDecl::base_class_iterator I = D->bases_begin(), + E = D->bases_end(); I != E; ++I) { + IndentScope Indent(*this); + if (I->isVirtual()) + OS << "virtual "; + dumpAccessSpecifier(I->getAccessSpecifier()); + dumpType(I->getType()); + if (I->isPackExpansion()) + OS << "..."; + } +} + +void ASTDumper::VisitStaticAssertDecl(StaticAssertDecl *D) { + dumpStmt(D->getAssertExpr()); + dumpStmt(D->getMessage()); +} + +void ASTDumper::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { + dumpName(D); + dumpTemplateParameters(D->getTemplateParameters()); + dumpDecl(D->getTemplatedDecl()); + for (FunctionTemplateDecl::spec_iterator I = D->spec_begin(), + E = D->spec_end(); I != E; ++I) { + switch (I->getTemplateSpecializationKind()) { + case TSK_Undeclared: + case TSK_ImplicitInstantiation: + case TSK_ExplicitInstantiationDeclaration: + case TSK_ExplicitInstantiationDefinition: + dumpDecl(*I); + break; + case TSK_ExplicitSpecialization: + dumpDeclRef(*I); + break; + } + } +} + +void ASTDumper::VisitClassTemplateDecl(ClassTemplateDecl *D) { + dumpName(D); + dumpTemplateParameters(D->getTemplateParameters()); + dumpDecl(D->getTemplatedDecl()); + for (ClassTemplateDecl::spec_iterator I = D->spec_begin(), E = D->spec_end(); + I != E; ++I) { + switch (I->getTemplateSpecializationKind()) { + case TSK_Undeclared: + case TSK_ImplicitInstantiation: + dumpDecl(*I); + break; + case TSK_ExplicitSpecialization: + case TSK_ExplicitInstantiationDeclaration: + case TSK_ExplicitInstantiationDefinition: + dumpDeclRef(*I); + break; } + } +} - std::string Name = VD->getNameAsString(); - VD->getType().getAsStringInternal(Name, - PrintingPolicy(VD->getASTContext().getLangOpts())); - OS << Name; +void ASTDumper::VisitClassTemplateSpecializationDecl( + ClassTemplateSpecializationDecl *D) { + VisitCXXRecordDecl(D); + dumpTemplateArgumentList(D->getTemplateArgs()); +} - // If this is a vardecl with an initializer, emit it. - if (VarDecl *V = dyn_cast<VarDecl>(VD)) { - if (V->getInit()) { - OS << " ="; - dumpStmt(V->getInit()); - } +void ASTDumper::VisitClassTemplatePartialSpecializationDecl( + ClassTemplatePartialSpecializationDecl *D) { + VisitClassTemplateSpecializationDecl(D); + dumpTemplateParameters(D->getTemplateParameters()); +} + +void ASTDumper::VisitClassScopeFunctionSpecializationDecl( + ClassScopeFunctionSpecializationDecl *D) { + dumpDeclRef(D->getSpecialization()); + if (D->hasExplicitTemplateArgs()) + dumpTemplateArgumentListInfo(D->templateArgs()); +} + +void ASTDumper::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) { + if (D->wasDeclaredWithTypename()) + OS << " typename"; + else + OS << " class"; + if (D->isParameterPack()) + OS << " ..."; + dumpName(D); + if (D->hasDefaultArgument()) + dumpType(D->getDefaultArgument()); +} + +void ASTDumper::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) { + dumpType(D->getType()); + if (D->isParameterPack()) + OS << " ..."; + dumpName(D); + if (D->hasDefaultArgument()) + dumpStmt(D->getDefaultArgument()); +} + +void ASTDumper::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) { + if (D->isParameterPack()) + OS << " ..."; + dumpName(D); + dumpTemplateParameters(D->getTemplateParameters()); + if (D->hasDefaultArgument()) + dumpTemplateArgumentLoc(D->getDefaultArgument()); +} + +void ASTDumper::VisitUsingDecl(UsingDecl *D) { + OS << ' '; + D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); + OS << D->getNameAsString(); +} + +void +ASTDumper::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) { + OS << ' '; + D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); + OS << D->getNameAsString(); +} + +void ASTDumper::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { + OS << ' '; + D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); + OS << D->getNameAsString(); + dumpType(D->getType()); +} + +void ASTDumper::VisitUsingShadowDecl(UsingShadowDecl *D) { + OS << ' '; + dumpBareDeclRef(D->getTargetDecl()); +} + +void ASTDumper::VisitLinkageSpecDecl(LinkageSpecDecl *D) { + switch (D->getLanguage()) { + case LinkageSpecDecl::lang_c: OS << " C"; break; + case LinkageSpecDecl::lang_cxx: OS << " C++"; break; + } +} + +void ASTDumper::VisitAccessSpecDecl(AccessSpecDecl *D) { + OS << ' '; + dumpAccessSpecifier(D->getAccess()); +} + +void ASTDumper::VisitFriendDecl(FriendDecl *D) { + if (TypeSourceInfo *T = D->getFriendType()) + dumpType(T->getType()); + else + dumpDecl(D->getFriendDecl()); +} + +//===----------------------------------------------------------------------===// +// Obj-C Declarations +//===----------------------------------------------------------------------===// + +void ASTDumper::VisitObjCIvarDecl(ObjCIvarDecl *D) { + dumpName(D); + dumpType(D->getType()); + if (D->getSynthesize()) + OS << " synthesize"; + + switch (D->getAccessControl()) { + case ObjCIvarDecl::None: + OS << " none"; + break; + case ObjCIvarDecl::Private: + OS << " private"; + break; + case ObjCIvarDecl::Protected: + OS << " protected"; + break; + case ObjCIvarDecl::Public: + OS << " public"; + break; + case ObjCIvarDecl::Package: + OS << " package"; + break; + } +} + +void ASTDumper::VisitObjCMethodDecl(ObjCMethodDecl *D) { + if (D->isInstanceMethod()) + OS << " -"; + else + OS << " +"; + dumpName(D); + dumpType(D->getResultType()); + + if (D->isThisDeclarationADefinition()) + dumpDeclContext(D); + else { + for (ObjCMethodDecl::param_iterator I = D->param_begin(), + E = D->param_end(); I != E; ++I) { + dumpDecl(*I); } - OS << '"'; - } else if (TagDecl *TD = dyn_cast<TagDecl>(D)) { - // print a free standing tag decl (e.g. "struct x;"). - const char *tagname; - if (const IdentifierInfo *II = TD->getIdentifier()) - tagname = II->getNameStart(); - else - tagname = "<anonymous>"; - OS << '"' << TD->getKindName() << ' ' << tagname << ";\""; - // FIXME: print tag bodies. - } else if (UsingDirectiveDecl *UD = dyn_cast<UsingDirectiveDecl>(D)) { - // print using-directive decl (e.g. "using namespace x;") - const char *ns; - if (const IdentifierInfo *II = UD->getNominatedNamespace()->getIdentifier()) - ns = II->getNameStart(); - else - ns = "<anonymous>"; - OS << '"' << UD->getDeclKindName() << ns << ";\""; - } else if (UsingDecl *UD = dyn_cast<UsingDecl>(D)) { - // print using decl (e.g. "using std::string;") - const char *tn = UD->isTypeName() ? "typename " : ""; - OS << '"' << UD->getDeclKindName() << tn; - UD->getQualifier()->print(OS, - PrintingPolicy(UD->getASTContext().getLangOpts())); - OS << ";\""; - } else if (LabelDecl *LD = dyn_cast<LabelDecl>(D)) { - OS << "label " << *LD; - } else if (StaticAssertDecl *SAD = dyn_cast<StaticAssertDecl>(D)) { - OS << "\"static_assert("; - dumpStmt(SAD->getAssertExpr()); - OS << ","; - dumpStmt(SAD->getMessage()); - OS << ");\""; - } else { - llvm_unreachable("Unexpected decl"); } + + if (D->isVariadic()) { + IndentScope Indent(*this); + OS << "..."; + } + + if (D->hasBody()) + dumpStmt(D->getBody()); +} + +void ASTDumper::VisitObjCCategoryDecl(ObjCCategoryDecl *D) { + dumpName(D); + dumpDeclRef(D->getClassInterface()); + dumpDeclRef(D->getImplementation()); + for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(), + E = D->protocol_end(); I != E; ++I) + dumpDeclRef(*I); +} + +void ASTDumper::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { + dumpName(D); + dumpDeclRef(D->getClassInterface()); + dumpDeclRef(D->getCategoryDecl()); +} + +void ASTDumper::VisitObjCProtocolDecl(ObjCProtocolDecl *D) { + dumpName(D); + for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(), + E = D->protocol_end(); I != E; ++I) + dumpDeclRef(*I); +} + +void ASTDumper::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { + dumpName(D); + dumpDeclRef(D->getSuperClass(), "super"); + dumpDeclRef(D->getImplementation()); + for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(), + E = D->protocol_end(); I != E; ++I) + dumpDeclRef(*I); +} + +void ASTDumper::VisitObjCImplementationDecl(ObjCImplementationDecl *D) { + dumpName(D); + dumpDeclRef(D->getSuperClass(), "super"); + dumpDeclRef(D->getClassInterface()); + for (ObjCImplementationDecl::init_iterator I = D->init_begin(), + E = D->init_end(); I != E; ++I) + dumpCXXCtorInitializer(*I); +} + +void ASTDumper::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D) { + dumpName(D); + dumpDeclRef(D->getClassInterface()); +} + +void ASTDumper::VisitObjCPropertyDecl(ObjCPropertyDecl *D) { + dumpName(D); + dumpType(D->getType()); + + if (D->getPropertyImplementation() == ObjCPropertyDecl::Required) + OS << " required"; + else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional) + OS << " optional"; + + ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes(); + if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) { + if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly) + OS << " readonly"; + if (Attrs & ObjCPropertyDecl::OBJC_PR_assign) + OS << " assign"; + if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite) + OS << " readwrite"; + if (Attrs & ObjCPropertyDecl::OBJC_PR_retain) + OS << " retain"; + if (Attrs & ObjCPropertyDecl::OBJC_PR_copy) + OS << " copy"; + if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic) + OS << " nonatomic"; + if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic) + OS << " atomic"; + if (Attrs & ObjCPropertyDecl::OBJC_PR_weak) + OS << " weak"; + if (Attrs & ObjCPropertyDecl::OBJC_PR_strong) + OS << " strong"; + if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained) + OS << " unsafe_unretained"; + if (Attrs & ObjCPropertyDecl::OBJC_PR_getter) + dumpDeclRef(D->getGetterMethodDecl(), "getter"); + if (Attrs & ObjCPropertyDecl::OBJC_PR_setter) + dumpDeclRef(D->getSetterMethodDecl(), "setter"); + } +} + +void ASTDumper::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) { + dumpName(D->getPropertyDecl()); + if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) + OS << " synthesize"; + else + OS << " dynamic"; + dumpDeclRef(D->getPropertyDecl()); + dumpDeclRef(D->getPropertyIvarDecl()); +} + +void ASTDumper::VisitBlockDecl(BlockDecl *D) { + for (BlockDecl::param_iterator I = D->param_begin(), E = D->param_end(); + I != E; ++I) + dumpDecl(*I); + + if (D->isVariadic()) { + IndentScope Indent(*this); + OS << "..."; + } + + if (D->capturesCXXThis()) { + IndentScope Indent(*this); + OS << "capture this"; + } + for (BlockDecl::capture_iterator I = D->capture_begin(), + E = D->capture_end(); I != E; ++I) { + IndentScope Indent(*this); + OS << "capture"; + if (I->isByRef()) + OS << " byref"; + if (I->isNested()) + OS << " nested"; + if (I->getVariable()) { + OS << ' '; + dumpBareDeclRef(I->getVariable()); + } + if (I->hasCopyExpr()) + dumpStmt(I->getCopyExpr()); + } + + dumpStmt(D->getBody()); } //===----------------------------------------------------------------------===// @@ -300,25 +942,22 @@ void ASTDumper::dumpStmt(Stmt *S) { return; } - Visit(S); + StmtVisitor<ASTDumper>::Visit(S); for (Stmt::child_range CI = S->children(); CI; ++CI) dumpStmt(*CI); } void ASTDumper::VisitStmt(Stmt *Node) { - OS << Node->getStmtClassName() << " " << (const void *)Node; - dumpSourceRange(Node); + OS << Node->getStmtClassName(); + dumpPointer(Node); + dumpSourceRange(Node->getSourceRange()); } void ASTDumper::VisitDeclStmt(DeclStmt *Node) { VisitStmt(Node); - for (DeclStmt::decl_iterator DI = Node->decl_begin(), DE = Node->decl_end(); - DI != DE; ++DI) { - IndentScope Indent(*this); - Decl *D = *DI; - OS << (void*) D << " "; - dumpDecl(D); - } + for (DeclStmt::decl_iterator I = Node->decl_begin(), E = Node->decl_end(); + I != E; ++I) + dumpDecl(*I); } void ASTDumper::VisitLabelStmt(LabelStmt *Node) { @@ -328,8 +967,8 @@ void ASTDumper::VisitLabelStmt(LabelStmt *Node) { void ASTDumper::VisitGotoStmt(GotoStmt *Node) { VisitStmt(Node); - OS << " '" << Node->getLabel()->getName() - << "':" << (void*)Node->getLabel(); + OS << " '" << Node->getLabel()->getName() << "'"; + dumpPointer(Node->getLabel()); } //===----------------------------------------------------------------------===// @@ -338,7 +977,6 @@ void ASTDumper::VisitGotoStmt(GotoStmt *Node) { void ASTDumper::VisitExpr(Expr *Node) { VisitStmt(Node); - OS << ' '; dumpType(Node->getType()); switch (Node->getValueKind()) { @@ -405,10 +1043,10 @@ void ASTDumper::VisitDeclRefExpr(DeclRefExpr *Node) { VisitExpr(Node); OS << " "; - dumpDeclRef(Node->getDecl()); + dumpBareDeclRef(Node->getDecl()); if (Node->getDecl() != Node->getFoundDecl()) { OS << " ("; - dumpDeclRef(Node->getFoundDecl()); + dumpBareDeclRef(Node->getFoundDecl()); OS << ")"; } } @@ -425,15 +1063,15 @@ void ASTDumper::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) { if (I == E) OS << " empty"; for (; I != E; ++I) - OS << " " << (void*) *I; + dumpPointer(*I); } void ASTDumper::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { VisitExpr(Node); OS << " " << Node->getDecl()->getDeclKindName() - << "Decl='" << *Node->getDecl() - << "' " << (void*)Node->getDecl(); + << "Decl='" << *Node->getDecl() << "'"; + dumpPointer(Node->getDecl()); if (Node->isFreeIvar()) OS << " isFreeIvar"; } @@ -482,13 +1120,13 @@ void ASTDumper::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) { VisitExpr(Node); switch(Node->getKind()) { case UETT_SizeOf: - OS << " sizeof "; + OS << " sizeof"; break; case UETT_AlignOf: - OS << " alignof "; + OS << " alignof"; break; case UETT_VecStep: - OS << " vec_step "; + OS << " vec_step"; break; } if (Node->isArgumentType()) @@ -497,9 +1135,8 @@ void ASTDumper::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) { void ASTDumper::VisitMemberExpr(MemberExpr *Node) { VisitExpr(Node); - OS << " " << (Node->isArrow() ? "->" : ".") - << *Node->getMemberDecl() << ' ' - << (void*)Node->getMemberDecl(); + OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl(); + dumpPointer(Node->getMemberDecl()); } void ASTDumper::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) { @@ -516,36 +1153,14 @@ void ASTDumper::VisitCompoundAssignOperator(CompoundAssignOperator *Node) { VisitExpr(Node); OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "' ComputeLHSTy="; - dumpType(Node->getComputationLHSType()); + dumpBareType(Node->getComputationLHSType()); OS << " ComputeResultTy="; - dumpType(Node->getComputationResultType()); + dumpBareType(Node->getComputationResultType()); } void ASTDumper::VisitBlockExpr(BlockExpr *Node) { VisitExpr(Node); - - BlockDecl *block = Node->getBlockDecl(); - OS << " decl=" << block; - - if (block->capturesCXXThis()) { - IndentScope Indent(*this); - OS << "capture this"; - } - for (BlockDecl::capture_iterator - i = block->capture_begin(), e = block->capture_end(); i != e; ++i) { - IndentScope Indent(*this); - OS << "capture "; - if (i->isByRef()) - OS << "byref "; - if (i->isNested()) - OS << "nested "; - if (i->getVariable()) - dumpDeclRef(i->getVariable()); - if (i->hasCopyExpr()) - dumpStmt(i->getCopyExpr()); - } - - dumpStmt(block->getBody()); + dumpDecl(Node->getBlockDecl()); } void ASTDumper::VisitOpaqueValueExpr(OpaqueValueExpr *Node) { @@ -559,8 +1174,8 @@ void ASTDumper::VisitOpaqueValueExpr(OpaqueValueExpr *Node) { void ASTDumper::VisitAddrLabelExpr(AddrLabelExpr *Node) { VisitExpr(Node); - OS << " " << Node->getLabel()->getName() - << " " << (void*)Node->getLabel(); + OS << " " << Node->getLabel()->getName(); + dumpPointer(Node->getLabel()); } //===----------------------------------------------------------------------===// @@ -610,15 +1225,14 @@ void ASTDumper::VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *Node) { void ASTDumper::VisitExprWithCleanups(ExprWithCleanups *Node) { VisitExpr(Node); - for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i) { - IndentScope Indent(*this); - OS << "cleanup "; - dumpDeclRef(Node->getObject(i)); - } + for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i) + dumpDeclRef(Node->getObject(i), "cleanup"); } void ASTDumper::dumpCXXTemporary(CXXTemporary *Temporary) { - OS << "(CXXTemporary " << (void *)Temporary << ")"; + OS << "(CXXTemporary"; + dumpPointer(Temporary); + OS << ")"; } //===----------------------------------------------------------------------===// @@ -634,7 +1248,7 @@ void ASTDumper::VisitObjCMessageExpr(ObjCMessageExpr *Node) { case ObjCMessageExpr::Class: OS << " class="; - dumpType(Node->getClassReceiver()); + dumpBareType(Node->getClassReceiver()); break; case ObjCMessageExpr::SuperInstance: @@ -654,17 +1268,14 @@ void ASTDumper::VisitObjCBoxedExpr(ObjCBoxedExpr *Node) { void ASTDumper::VisitObjCAtCatchStmt(ObjCAtCatchStmt *Node) { VisitStmt(Node); - if (VarDecl *CatchParam = Node->getCatchParamDecl()) { - OS << " catch parm = "; + if (VarDecl *CatchParam = Node->getCatchParamDecl()) dumpDecl(CatchParam); - } else { + else OS << " catch all"; - } } void ASTDumper::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) { VisitExpr(Node); - OS << " "; dumpType(Node->getEncodedType()); } @@ -738,6 +1349,19 @@ void ASTDumper::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) { } //===----------------------------------------------------------------------===// |