diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h index 10354034a5e97d5963a9f02960cf97f7352641d3..e3c09e7b418f3930b3dc47e92fe5d3bf527209fb 100644 --- a/include/clang/AST/PrettyPrinter.h +++ b/include/clang/AST/PrettyPrinter.h @@ -40,8 +40,7 @@ struct PrintingPolicy { SuppressUnwrittenScope(false), SuppressInitializers(false), ConstantArraySizeAsWritten(false), AnonymousTagLocations(true), SuppressStrongLifetime(false), Bool(LO.Bool), - TerseOutput(false), PolishForDeclaration(false), - DumpSourceManager(0) { } + TerseOutput(false), PolishForDeclaration(false) { } /// \brief What language we're printing. LangOptions LangOpts; @@ -147,12 +146,6 @@ struct PrintingPolicy { /// declaration tag; such as, do not print attributes attached to the declaration. /// unsigned PolishForDeclaration : 1; - - /// \brief If we are "dumping" rather than "pretty-printing", this points to - /// a SourceManager which will be used to dump SourceLocations. Dumping - /// involves printing the internal details of the AST and pretty-printing - /// involves printing something similar to source code. - SourceManager *DumpSourceManager; }; } // end namespace clang diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h index 28aee84c2eb3aaa9d20239d1756cee0a19113457..174b451b2b4440dfbc749a20e052c971c8f22707 100644 --- a/include/clang/AST/TemplateName.h +++ b/include/clang/AST/TemplateName.h @@ -308,6 +308,9 @@ public: void print(raw_ostream &OS, const PrintingPolicy &Policy, bool SuppressNNS = false) const; + /// \brief Debugging aid that dumps the template name. + void dump(raw_ostream &OS) const; + /// \brief Debugging aid that dumps the template name to standard /// error. void dump() const; diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index 51d0f26c56e49b74f47b293ce0cca12fb1028803..31331f1f9d308e0ccbd6036a1803b9308725122a 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()); } @@ -737,6 +1348,19 @@ void ASTDumper::VisitObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Node) { OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no"); } +//===----------------------------------------------------------------------===// +// Decl method implementations +//===----------------------------------------------------------------------===// + +void Decl::dump() const { + dump(llvm::errs()); +} + +void Decl::dump(raw_ostream &OS) const { + ASTDumper P(&getASTContext().getSourceManager(), OS); + P.dumpDecl(const_cast<Decl*>(this)); +} + //===----------------------------------------------------------------------===// // Stmt method implementations //===----------------------------------------------------------------------===// diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp index 572e3d0bc7eae2d958bac603fbbc402587258834..4a7344c98288cb855a9f358ed78fd00a55756b34 100644 --- a/lib/AST/DeclPrinter.cpp +++ b/lib/AST/DeclPrinter.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This file implements the Decl::dump method, which pretty print the +// This file implements the Decl::print method, which pretty prints the // AST back out to C/Objective-C/C++/Objective-C++ code. // //===----------------------------------------------------------------------===// @@ -176,16 +176,6 @@ void DeclContext::dumpDeclContext() const { Printer.VisitDeclContext(const_cast<DeclContext *>(this), /*Indent=*/false); } -void Decl::dump() const { - dump(llvm::errs()); -} - -void Decl::dump(raw_ostream &Out) const { - PrintingPolicy Policy = getASTContext().getPrintingPolicy(); - Policy.DumpSourceManager = &getASTContext().getSourceManager(); - print(Out, Policy, /*Indentation*/ 0, /*PrintInstantiation*/ true); -} - raw_ostream& DeclPrinter::Indent(unsigned Indentation) { for (unsigned i = 0; i != Indentation; ++i) Out << " "; @@ -242,18 +232,18 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) { if (isa<ObjCIvarDecl>(*D)) continue; - if (!Policy.DumpSourceManager) { - // Skip over implicit declarations in pretty-printing mode. - if (D->isImplicit()) continue; - // FIXME: Ugly hack so we don't pretty-print the builtin declaration - // of __builtin_va_list or __[u]int128_t. There should be some other way - // to check that. - if (NamedDecl *ND = dyn_cast<NamedDecl>(*D)) { - if (IdentifierInfo *II = ND->getIdentifier()) { - if (II->isStr("__builtin_va_list") || - II->isStr("__int128_t") || II->isStr("__uint128_t")) - continue; - } + // Skip over implicit declarations in pretty-printing mode. + if (D->isImplicit()) + continue; + + // FIXME: Ugly hack so we don't pretty-print the builtin declaration + // of __builtin_va_list or __[u]int128_t. There should be some other way + // to check that. + if (NamedDecl *ND = dyn_cast<NamedDecl>(*D)) { + if (IdentifierInfo *II = ND->getIdentifier()) { + if (II->isStr("__builtin_va_list") || + II->isStr("__int128_t") || II->isStr("__uint128_t")) + continue; } } diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index 0c741495b9ec1debd6a5376d09c85baf1d8fd9e6..f021c71dcafe62900f788bdc5adb2dea903dc7ce 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -1875,11 +1875,6 @@ void Stmt::printPretty(raw_ostream &OS, return; } - if (Policy.DumpSourceManager) { - dump(OS, *Policy.DumpSourceManager); - return; - } - StmtPrinter P(OS, Helper, Policy, Indentation); P.Visit(const_cast<Stmt*>(this)); } diff --git a/lib/AST/TemplateName.cpp b/lib/AST/TemplateName.cpp index c86fe8c270844e5db560045dadc81ace49241bf3..f68dbda7c7e2ef701a093b74a0049c98cbe4a95d 100644 --- a/lib/AST/TemplateName.cpp +++ b/lib/AST/TemplateName.cpp @@ -168,9 +168,13 @@ const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB, return DB << NameStr; } -void TemplateName::dump() const { +void TemplateName::dump(raw_ostream &OS) const { LangOptions LO; // FIXME! LO.CPlusPlus = true; LO.Bool = true; - print(llvm::errs(), PrintingPolicy(LO)); + print(OS, PrintingPolicy(LO)); +} + +void TemplateName::dump() const { + dump(llvm::errs()); } diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp index 08d963951c1d77a32666fa0291023bf35924d2e9..be1113d47e3a65bef29a7897793b775ee9d543ff 100644 --- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp +++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp @@ -3,10 +3,10 @@ // CHECK: example0 void example0() { double d = 2.0; - // CHECK: double &rd = + // CHECK: VarDecl{{.*}}rd 'double &' // CHECK-NEXT: DeclRefExpr double &rd = d; - // CHECK: const double &rcd = + // CHECK: VarDecl{{.*}}rcd 'const double &' // CHECK-NEXT: ImplicitCastExpr{{.*}}'const double' lvalue <NoOp> const double &rcd = d; } @@ -16,10 +16,10 @@ struct B : A { } b; // CHECK: example1 void example1() { - // CHECK: A &ra = + // CHECK: VarDecl{{.*}}ra 'struct A &' // CHECK: ImplicitCastExpr{{.*}}'struct A' lvalue <DerivedToBase (A)> A &ra = b; - // CHECK: const A &rca = + // CHECK: VarDecl{{.*}}rca 'const struct A &' // CHECK: ImplicitCastExpr{{.*}}'const struct A' lvalue <NoOp> // CHECK: ImplicitCastExpr{{.*}}'struct A' lvalue <DerivedToBase (A)> const A& rca = b; @@ -33,12 +33,12 @@ struct X { // CHECK: example2 void example2() { - // CHECK: const A &rca = + // CHECK: VarDecl{{.*}}rca 'const struct A &' // CHECK: ImplicitCastExpr{{.*}}'const struct A' <NoOp> // CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase (A)> // CHECK: CallExpr{{.*}}B const A &rca = f(); - // CHECK: const A &r = + // CHECK: VarDecl{{.*}}r 'const struct A &' // CHECK: ImplicitCastExpr{{.*}}'const struct A' <NoOp> // CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase (A)> // CHECK: CXXMemberCallExpr{{.*}}'struct B' @@ -47,7 +47,7 @@ void example2() { // CHECK: example3 void example3() { - // CHECK: const double &rcd2 = + // CHECK: VarDecl{{.*}}rcd2 'const double &' // CHECK: ImplicitCastExpr{{.*}} <IntegralToFloating> const double& rcd2 = 2; } diff --git a/test/CodeGen/bitfield-2.c b/test/CodeGen/bitfield-2.c index fc85a8080a907614cdbf3608d32b770cf174c8a3..867ed8c2cec1f94e5e55794d0b55f7090006d8bf 100644 --- a/test/CodeGen/bitfield-2.c +++ b/test/CodeGen/bitfield-2.c @@ -9,7 +9,7 @@ // PR6176 // CHECK-RECORD: *** Dumping IRgen Record Layout -// CHECK-RECORD: Record: struct s0 +// CHECK-RECORD: Record: (RecordDecl{{.*}}s0 // CHECK-RECORD: Layout: <CGRecordLayout // CHECK-RECORD: LLVMType:%struct.s0 = type <{ [3 x i8] }> // CHECK-RECORD: IsZeroInitializable:1 @@ -49,7 +49,7 @@ unsigned long long test_0() { // PR5591 // CHECK-RECORD: *** Dumping IRgen Record Layout -// CHECK-RECORD: Record: struct s1 +// CHECK-RECORD: Record: (RecordDecl{{.*}}s1 // CHECK-RECORD: Layout: <CGRecordLayout // CHECK-RECORD: LLVMType:%struct.s1 = type <{ [3 x i8] }> // CHECK-RECORD: IsZeroInitializable:1 @@ -97,7 +97,7 @@ unsigned long long test_1() { // PR5567 // CHECK-RECORD: *** Dumping IRgen Record Layout -// CHECK-RECORD: Record: union u2 +// CHECK-RECORD: Record: (RecordDecl{{.*}}u2 // CHECK-RECORD: Layout: <CGRecordLayout // CHECK-RECORD: LLVMType:%union.u2 = type <{ i8 }> // CHECK-RECORD: IsZeroInitializable:1 @@ -269,7 +269,7 @@ _Bool test_6() { // Check that we compute the best alignment possible for each access. // // CHECK-RECORD: *** Dumping IRgen Record Layout -// CHECK-RECORD: Record: struct s7 +// CHECK-RECORD: Record: (RecordDecl{{.*}}s7 // CHECK-RECORD: Layout: <CGRecordLayout // CHECK-RECORD: LLVMType:%struct.s7 = type { i32, i32, i32, i8, [3 x i8], [4 x i8], [12 x i8] } // CHECK-RECORD: IsZeroInitializable:1 diff --git a/test/Misc/ast-dump-decl.c b/test/Misc/ast-dump-decl.c new file mode 100644 index 0000000000000000000000000000000000000000..4bfd1889549907f807ebd01551edf35254f23495 --- /dev/null +++ b/test/Misc/ast-dump-decl.c @@ -0,0 +1,152 @@ +// RUN: %clang_cc1 -ast-dump -ast-dump-filter Test %s | FileCheck -check-prefix CHECK -strict-whitespace %s +// RUN: %clang_cc1 -ast-dump %s | FileCheck -check-prefix CHECK-TU -strict-whitespace %s + +int TestLocation; +// CHECK: VarDecl 0x{{[^ ]*}} <{{.*}}:4:1, col:5> TestLocation + +struct TestIndent { + int x; +}; +// CHECK: {{^\(RecordDecl.*TestIndent[^()]*$}} +// CHECK-NEXT: {{^ \(FieldDecl.*x[^()]*\)\)$}} + +struct TestChildren { + int x; + struct y { + int z; + }; +}; +// CHECK: RecordDecl{{.*}}TestChildren +// CHECK-NEXT: FieldDecl{{.*}}x +// CHECK-NEXT: RecordDecl{{.*}}y +// CHECK-NEXT: FieldDecl{{.*}}z + +// CHECK-TU: TranslationUnitDecl + +void testLabelDecl() { + __label__ TestLabelDecl; + TestLabelDecl: goto TestLabelDecl; +} +// CHECK: LabelDecl{{.*}} TestLabelDecl + +typedef int TestTypedefDecl; +// CHECK: TypedefDecl{{.*}} TestTypedefDecl 'int' + +__module_private__ typedef int TestTypedefDeclPrivate; +// CHECK: TypedefDecl{{.*}} TestTypedefDeclPrivate 'int' __module_private__ + +enum TestEnumDecl { + testEnumDecl +}; +// CHECK: EnumDecl{{.*}} TestEnumDecl +// CHECK-NEXT: EnumConstantDecl{{.*}} testEnumDecl + +struct TestEnumDeclAnon { + enum { + testEnumDeclAnon + } e; +}; +// CHECK: RecordDecl{{.*}} TestEnumDeclAnon +// CHECK-NEXT: EnumDecl{{.*>$}} + +enum TestEnumDeclForward; +// CHECK: EnumDecl{{.*}} TestEnumDeclForward + +__module_private__ enum TestEnumDeclPrivate; +// CHECK: EnumDecl{{.*}} TestEnumDeclPrivate __module_private__ + +struct TestRecordDecl { + int i; +}; +// CHECK: RecordDecl{{.*}} struct TestRecordDecl +// CHECK-NEXT: FieldDecl + +struct TestRecordDeclEmpty { +}; +// CHECK: RecordDecl{{.*}} struct TestRecordDeclEmpty + +struct TestRecordDeclAnon1 { + struct { + } testRecordDeclAnon1; +}; +// CHECK: RecordDecl{{.*}} struct TestRecordDeclAnon1 +// CHECK-NEXT: RecordDecl{{.*}} struct + +struct TestRecordDeclAnon2 { + struct { + }; +}; +// CHECK: RecordDecl{{.*}} struct TestRecordDeclAnon2 +// CHECK-NEXT: RecordDecl{{.*}} struct + +struct TestRecordDeclForward; +// CHECK: RecordDecl{{.*}} struct TestRecordDeclForward + +__module_private__ struct TestRecordDeclPrivate; +// CHECK: RecordDecl{{.*}} struct TestRecordDeclPrivate __module_private__ + +enum testEnumConstantDecl { + TestEnumConstantDecl, + TestEnumConstantDeclInit = 1 +}; +// CHECK: EnumConstantDecl{{.*}} TestEnumConstantDecl 'int' +// CHECK: EnumConstantDecl{{.*}} TestEnumConstantDeclInit 'int' +// CHECK-NEXT: IntegerLiteral + +struct testIndirectFieldDecl { + struct { + int TestIndirectFieldDecl; + }; +}; +// CHECK: IndirectFieldDecl{{.*}} TestIndirectFieldDecl 'int' +// CHECK-NEXT: Field{{.*}} '' +// CHECK-NEXT: Field{{.*}} 'TestIndirectFieldDecl' + +int TestFunctionDecl(int x, enum { e } y) { + return x; +} +// CHECK: FunctionDecl{{.*}} TestFunctionDecl 'int (int, enum {{.*}})' +// CHECK-NEXT: EnumDecl +// CHECK-NEXT: EnumConstantDecl{{.*}} e +// CHECK-NEXT: ParmVarDecl{{.*}} x +// CHECK-NEXT: ParmVarDecl{{.*}} y +// CHECK-NEXT: CompoundStmt + +int TestFunctionDeclProto(int x); +// CHECK: FunctionDecl{{.*}} TestFunctionDeclProto 'int (int)' +// CHECK-NEXT: ParmVarDecl{{.*}} x + +extern int TestFunctionDeclSC(); +// CHECK: FunctionDecl{{.*}} TestFunctionDeclSC 'int ()' extern + +inline int TestFunctionDeclInline(); +// CHECK: FunctionDecl{{.*}} TestFunctionDeclInline 'int ()' inline + +struct testFieldDecl { + int TestFieldDecl; + int TestFieldDeclWidth : 1; + __module_private__ int TestFieldDeclPrivate; +}; +// CHECK: FieldDecl{{.*}} TestFieldDecl 'int' +// CHECK: FieldDecl{{.*}} TestFieldDeclWidth 'int' +// CHECK-NEXT: IntegerLiteral +// CHECK: FieldDecl{{.*}} TestFieldDeclPrivate 'int' __module_private__ + +int TestVarDecl; +// CHECK: VarDecl{{.*}} TestVarDecl 'int' + +extern int TestVarDeclSC; +// CHECK: VarDecl{{.*}} TestVarDeclSC 'int' extern + +__thread int TestVarDeclThread; +// CHECK: VarDecl{{.*}} TestVarDeclThread 'int' __thread + +__module_private__ int TestVarDeclPrivate; +// CHECK: VarDecl{{.*}} TestVarDeclPrivate 'int' __module_private__ + +int TestVarDeclInit = 0; +// CHECK: VarDecl{{.*}} TestVarDeclInit 'int' +// CHECK-NEXT: IntegerLiteral + +void testParmVarDecl(int TestParmVarDecl); +// CHECK: ParmVarDecl{{.*}} TestParmVarDecl 'int' diff --git a/test/Misc/ast-dump-decl.cpp b/test/Misc/ast-dump-decl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ab847cac6f341d093d8d012b610c57f8811f82c2 --- /dev/null +++ b/test/Misc/ast-dump-decl.cpp @@ -0,0 +1,405 @@ +// RUN: %clang_cc1 -std=c++11 -fms-extensions -ast-dump -ast-dump-filter Test %s | FileCheck -check-prefix CHECK -strict-whitespace %s + +class testEnumDecl { + enum class TestEnumDeclScoped; + enum TestEnumDeclFixed : int; +}; +// CHECK: EnumDecl{{.*}} class TestEnumDeclScoped 'int' +// CHECK: EnumDecl{{.*}} TestEnumDeclFixed 'int' + +class testFieldDecl { + int TestFieldDeclInit = 0; +}; +// CHECK: FieldDecl{{.*}} TestFieldDeclInit 'int' +// CHECK-NEXT: IntegerLiteral + +namespace testVarDeclNRVO { + class A { }; + A foo() { + A TestVarDeclNRVO; + return TestVarDeclNRVO; + } +} +// CHECK: VarDecl{{.*}} TestVarDeclNRVO 'class testVarDeclNRVO::A' nrvo + +void testParmVarDeclInit(int TestParmVarDeclInit = 0); +// CHECK: ParmVarDecl{{.*}} TestParmVarDeclInit 'int' +// CHECK-NEXT: IntegerLiteral{{.*}} + +namespace TestNamespaceDecl { + int i; +} +// CHECK: NamespaceDecl{{.*}} TestNamespaceDecl +// CHECK-NEXT: VarDecl + +namespace TestNamespaceDecl { + int j; +} +// CHECK: NamespaceDecl{{.*}} TestNamespaceDecl +// CHECK-NEXT: original Namespace +// CHECK-NEXT: VarDecl + +inline namespace TestNamespaceDeclInline { +} +// CHECK: NamespaceDecl{{.*}} TestNamespaceDeclInline inline + +namespace testUsingDirectiveDecl { + namespace A { + } +} +namespace TestUsingDirectiveDecl { + using namespace testUsingDirectiveDecl::A; +} +// CHECK: NamespaceDecl{{.*}} TestUsingDirectiveDecl +// CHECK-NEXT: UsingDirectiveDecl{{.*}} Namespace{{.*}} 'A' + +namespace testNamespaceAlias { + namespace A { + } +} +namespace TestNamespaceAlias = testNamespaceAlias::A; +// CHECK: NamespaceAliasDecl{{.*}} TestNamespaceAlias +// CHECK-NEXT: Namespace{{.*}} 'A' + +using TestTypeAliasDecl = int; +// CHECK: TypeAliasDecl{{.*}} TestTypeAliasDecl 'int' + +namespace testTypeAliasTemplateDecl { + template<typename T> class A; + template<typename T> using TestTypeAliasTemplateDecl = A<T>; +} +// CHECK: TypeAliasTemplateDecl{{.*}} TestTypeAliasTemplateDecl +// CHECK-NEXT: TemplateTypeParmDecl +// CHECK-NEXT: TypeAliasDecl{{.*}} TestTypeAliasTemplateDecl 'A<T>' + +namespace testCXXRecordDecl { + class A { }; + class B { }; + class TestCXXRecordDecl : virtual A, public B { + int i; + }; +} +// CHECK: CXXRecordDecl{{.*}} class TestCXXRecordDecl +// CHECK-NEXT: virtual private 'class testCXXRecordDecl::A' +// CHECK-NEXT: public 'class testCXXRecordDecl::B' +// CHECK-NEXT: CXXRecordDecl{{.*}} class TestCXXRecordDecl +// CHECK-NEXT: FieldDecl + +template<class...T> +class TestCXXRecordDeclPack : public T... { +}; +// CHECK: CXXRecordDecl{{.*}} class TestCXXRecordDeclPack +// CHECK-NEXT: public 'T'... +// CHECK-NEXT: CXXRecordDecl{{.*}} class TestCXXRecordDeclPack + +__module_private__ class TestCXXRecordDeclPrivate; +// CHECK: CXXRecordDecl{{.*}} class TestCXXRecordDeclPrivate __module_private__ + +class testCXXMethodDecl { + __module_private__ void TestCXXMethodDeclPrivate(); + virtual void TestCXXMethodDeclPure() = 0; + void TestCXXMethodDeclDelete() = delete; + void TestCXXMethodDeclThrow() throw(); + void TestCXXMethodDeclThrowType() throw(int); +}; +// CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclPrivate 'void (void)' __module_private__ +// CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclPure 'void (void)' virtual pure +// CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclDelete 'void (void)' delete +// CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclThrow 'void (void) throw()' +// CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclThrowType 'void (void) throw(int)' + +namespace testCXXConstructorDecl { + class A { }; + class TestCXXConstructorDecl : public A { + int I; + TestCXXConstructorDecl(A &a, int i) : A(a), I(i) { } + }; +} +// CHECK: CXXConstructorDecl{{.*}} TestCXXConstructorDecl 'void {{.*}}' +// CHECK-NEXT: ParmVarDecl{{.*}} a +// CHECK-NEXT: ParmVarDecl{{.*}} i +// CHECK-NEXT: CXXCtorInitializer{{.*}}A +// CHECK-NEXT: Expr +// CHECK: CXXCtorInitializer{{.*}}I +// CHECK-NEXT: Expr +// CHECK: CompoundStmt + +class TestCXXDestructorDecl { + ~TestCXXDestructorDecl() { } +}; +// CHECK: CXXDestructorDecl{{.*}} ~TestCXXDestructorDecl 'void (void) noexcept' +// CHECK-NEXT: CompoundStmt + +class TestCXXConversionDecl { + operator int() { return 0; } +}; +// CHECK: CXXConversionDecl{{.*}} operator int 'int (void)' +// CHECK-NEXT: CompoundStmt + +namespace TestStaticAssertDecl { + static_assert(true, "msg"); +} +// CHECK: NamespaceDecl{{.*}} TestStaticAssertDecl +// CHECK-NEXT: StaticAssertDecl{{.*>$}} +// CHECK-NEXT: CXXBoolLiteralExpr +// CHECK-NEXT: StringLiteral + +namespace testFunctionTemplateDecl { + class A { }; + class B { }; + class C { }; + class D { }; + template<typename T> void TestFunctionTemplate(T) { } + + // implicit instantiation + void bar(A a) { TestFunctionTemplate(a); } + + // explicit specialization + template<> void TestFunctionTemplate(B); + + // explicit instantiation declaration + extern template void TestFunctionTemplate(C); + + // explicit instantiation definition + template void TestFunctionTemplate(D); +} +// CHECK: FunctionTemplateDecl{{.*}} TestFunctionTemplate +// CHECK-NEXT: TemplateTypeParmDecl +// CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate 'void (T)' +// CHECK-NEXT: ParmVarDecl{{.*}} 'T' +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}A +// CHECK-NEXT: TemplateArgument +// CHECK-NEXT: ParmVarDecl +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: Function{{.*}} 'TestFunctionTemplate' {{.*}}B +// CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}C +// CHECK-NEXT: TemplateArgument +// CHECK-NEXT: ParmVarDecl +// CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}D +// CHECK-NEXT: TemplateArgument +// CHECK-NEXT: ParmVarDecl +// CHECK-NEXT: CompoundStmt +// CHECK: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}B +// CHECK-NEXT: TemplateArgument +// CHECK-NEXT: ParmVarDecl + +namespace testClassTemplateDecl { + class A { }; + class B { }; + class C { }; + class D { }; + + template<typename T> class TestClassTemplate { + int i; + }; + + // implicit instantiation + TestClassTemplate<A> a; + + // explicit specialization + template<> class TestClassTemplate<B> { + int j; + }; + + // explicit instantiation declaration + extern template class TestClassTemplate<C>; + + // explicit instantiation definition + template class TestClassTemplate<D>; + + // partial explicit specialization + template<typename T1, typename T2> class TestClassTemplatePartial { + int i; + }; + template<typename T1> class TestClassTemplatePartial<T1, A> { + int j; + }; +} +// CHECK: ClassTemplateDecl{{.*}} TestClassTemplate +// CHECK-NEXT: TemplateTypeParmDecl +// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate +// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate +// CHECK-NEXT: FieldDecl{{.*}} i +// CHECK-NEXT: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate +// CHECK-NEXT: TemplateArgument{{.*}}A +// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate +// CHECK-NEXT: FieldDecl{{.*}} i +// CHECK: ClassTemplateSpecialization{{.*}} 'TestClassTemplate' +// CHECK-NEXT: ClassTemplateSpecialization{{.*}} 'TestClassTemplate' +// CHECK-NEXT: ClassTemplateSpecialization{{.*}} 'TestClassTemplate' + +// CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate +// CHECK-NEXT: TemplateArgument{{.*}}B +// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate +// CHECK-NEXT: FieldDecl{{.*}} j + +// CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate +// CHECK-NEXT: TemplateArgument{{.*}}C +// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate +// CHECK-NEXT: FieldDecl{{.*}} i + +// CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate +// CHECK-NEXT: TemplateArgument{{.*}}D +// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate +// CHECK-NEXT: FieldDecl{{.*}} i + +// CHECK: ClassTemplatePartialSpecializationDecl{{.*}} class TestClassTemplatePartial +// CHECK-NEXT: TemplateArgument +// CHECK-NEXT: TemplateArgument{{.*}}A +// CHECK-NEXT: TemplateTypeParmDecl +// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplatePartial +// CHECK-NEXT: FieldDecl{{.*}} j + +template <class T> +class TestClassScopeFunctionSpecialization { + template<class U> void foo(U a) { } + template<> void foo<int>(int a) { } +}; +// CHECK: ClassScopeFunctionSpecializationDecl +// CHECK-NEXT: CXXMethod{{.*}} 'foo' 'void (int)' +// CHECK-NEXT: TemplateArgument{{.*}} 'int' + +namespace TestTemplateTypeParmDecl { + template<typename ... T, class U = int> void foo(); +} +// CHECK: NamespaceDecl{{.*}} TestTemplateTypeParmDecl +// CHECK-NEXT: FunctionTemplateDecl +// CHECK-NEXT: TemplateTypeParmDecl{{.*}} typename ... T +// CHECK-NEXT: TemplateTypeParmDecl{{.*}} class U 'int' + +namespace TestNonTypeTemplateParmDecl { + template<int I = 1, int ... J> void foo(); +} +// CHECK: NamespaceDecl{{.*}} TestNonTypeTemplateParmDecl +// CHECK-NEXT: FunctionTemplateDecl +// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int' I +// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 1 +// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int' ... J + +namespace TestTemplateTemplateParmDecl { + template<typename T> class A; + template <template <typename> class T = A, template <typename> class ... U> void foo(); +} +// CHECK: NamespaceDecl{{.*}} TestTemplateTemplateParmDecl +// CHECK: FunctionTemplateDecl +// CHECK-NEXT: TemplateTemplateParmDecl{{.*}} T +// CHECK-NEXT: TemplateTypeParmDecl{{.*}} typename +// CHECK-NEXT: TemplateArgument{{.*}} template A +// CHECK-NEXT: TemplateTemplateParmDecl{{.*}} ... U +// CHECK-NEXT: TemplateTypeParmDecl{{.*}} typename + +namespace TestTemplateArgument { + template<typename> class A { }; + template<template<typename> class ...> class B { }; + int foo(); + + template<typename> class testType { }; + template class testType<int>; + // CHECK: ClassTemplateSpecializationDecl{{.*}} class testType + // CHECK-NEXT: TemplateArgument{{.*}} type 'int' + + template<int fp(void)> class testDecl { }; + template class testDecl<foo>; + // CHECK: ClassTemplateSpecializationDecl{{.*}} class testDecl + // CHECK-NEXT: TemplateArgument{{.*}} decl + // CHECK-NEXT: Function{{.*}}foo + + template class testDecl<nullptr>; + // CHECK: ClassTemplateSpecializationDecl{{.*}} class testDecl + // CHECK-NEXT: TemplateArgument{{.*}} nullptr + + template<int> class testIntegral { }; + template class testIntegral<1>; + // CHECK: ClassTemplateSpecializationDecl{{.*}} class testIntegral + // CHECK-NEXT: TemplateArgument{{.*}} integral 1 + + template<template<typename> class> class testTemplate { }; + template class testTemplate<A>; + // CHECK: ClassTemplateSpecializationDecl{{.*}} class testTemplate + // CHECK-NEXT: TemplateArgument{{.*}} A + + template<template<typename> class ...T> class C { + B<T...> testTemplateExpansion; + }; + // FIXME: Need TemplateSpecializationType dumping to test TemplateExpansion. + + template<int, int = 0> class testExpr; + template<int I> class testExpr<I> { }; + // CHECK: ClassTemplatePartialSpecializationDecl{{.*}} class testExpr + // CHECK-NEXT: TemplateArgument{{.*}} expr + // CHECK-NEXT: DeclRefExpr{{.*}}I + + template<int, int ...> class testPack { }; + template class testPack<0, 1, 2>; + // CHECK: ClassTemplateSpecializationDecl{{.*}} class testPack + // CHECK-NEXT: TemplateArgument{{.*}} integral 0 + // CHECK-NEXT: TemplateArgument{{.*}} pack + // CHECK-NEXT: TemplateArgument{{.*}} integral 1 + // CHECK-NEXT: TemplateArgument{{.*}} integral 2 +} + +namespace testUsingDecl { + int i; +} +namespace TestUsingDecl { + using testUsingDecl::i; +} +// CHECK: NamespaceDecl{{.*}} TestUsingDecl +// CHECK-NEXT: UsingDecl{{.*}} testUsingDecl::i +// CHECK-NEXT: UsingShadowDecl{{.*}} Var{{.*}} 'i' 'int' + +namespace testUnresolvedUsing { + class A { }; + template<class T> class B { + public: + A a; + }; + template<class T> class TestUnresolvedUsing : public B<T> { + using typename B<T>::a; + using B<T>::a; + }; +} +// CHECK: CXXRecordDecl{{.*}} TestUnresolvedUsing +// CHECK: UnresolvedUsingTypenameDecl{{.*}} B<T>::a +// CHECK: UnresolvedUsingValueDecl{{.*}} B<T>::a + +namespace TestLinkageSpecDecl { + extern "C" void test1(); + extern "C++" void test2(); +} +// CHECK: NamespaceDecl{{.*}} TestLinkageSpecDecl +// CHECK-NEXT: LinkageSpecDecl{{.*}} C +// CHECK-NEXT: FunctionDecl +// CHECK-NEXT: LinkageSpecDecl{{.*}} C++ +// CHECK-NEXT: FunctionDecl + +class TestAccessSpecDecl { +public: +private: +protected: +}; +// CHECK: CXXRecordDecl{{.*}} class TestAccessSpecDecl +// CHECK-NEXT: CXXRecordDecl{{.*}} class TestAccessSpecDecl +// CHECK-NEXT: AccessSpecDecl{{.*}} public +// CHECK-NEXT: AccessSpecDecl{{.*}} private +// CHECK-NEXT: AccessSpecDecl{{.*}} protected + +template<typename T> class TestFriendDecl { + friend int foo(); + friend class A; + friend T; +}; +// CHECK: CXXRecord{{.*}} TestFriendDecl +// CHECK-NEXT: CXXRecord{{.*}} TestFriendDecl +// CHECK-NEXT: FriendDecl +// CHECK-NEXT: FunctionDecl{{.*}} foo +// CHECK-NEXT: FriendDecl{{.*}} 'class A':'class A' +// CHECK-NEXT: FriendDecl{{.*}} 'T' + +namespace TestFileScopeAsmDecl { + asm("ret"); +} +// CHECK: NamespaceDecl{{.*}} TestFileScopeAsmDecl{{$}} +// CHECK: FileScopeAsmDecl{{.*>$}} +// CHECK-NEXT: StringLiteral diff --git a/test/Misc/ast-dump-decl.m b/test/Misc/ast-dump-decl.m new file mode 100644 index 0000000000000000000000000000000000000000..f8a5e5a263d6a446738505b68adf8e741e01624c --- /dev/null +++ b/test/Misc/ast-dump-decl.m @@ -0,0 +1,136 @@ +// RUN: %clang_cc1 -Wno-unused -fblocks -ast-dump -ast-dump-filter Test %s | FileCheck -strict-whitespace %s + +@protocol P +@end + +@interface A +@end + +@interface TestObjCIvarDecl : A +@end + +@implementation TestObjCIvarDecl { + int varDefault; + @private int varPrivate; + @protected int varProtected; + @public int varPublic; + @package int varPackage; +} +@end +// CHECK: ObjCImplementationDecl{{.*}} TestObjCIvarDecl +// CHECK-NEXT: ObjCInterface{{.*}} 'TestObjCIvarDecl' +// CHECK-NEXT: ObjCIvarDecl{{.*}} varDefault 'int' private +// CHECK-NEXT: ObjCIvarDecl{{.*}} varPrivate 'int' private +// CHECK-NEXT: ObjCIvarDecl{{.*}} varProtected 'int' protected +// CHECK-NEXT: ObjCIvarDecl{{.*}} varPublic 'int' public +// CHECK-NEXT: ObjCIvarDecl{{.*}} varPackage 'int' package + +@interface testObjCMethodDecl : A { +} +- (int) TestObjCMethodDecl: (int)i, ...; +// CHECK: ObjCMethodDecl{{.*}} - TestObjCMethodDecl: 'int' +// CHECK-NEXT: ParmVarDecl{{.*}} i 'int' +// CHECK-NEXT: ... +@end + +@implementation testObjCMethodDecl +- (int) TestObjCMethodDecl: (int)i, ... { + return 0; +} +// CHECK: ObjCMethodDecl{{.*}} - TestObjCMethodDecl: 'int' +// CHECK-NEXT: ImplicitParamDecl{{.*}} self +// CHECK-NEXT: ImplicitParamDecl{{.*}} _cmd +// CHECK-NEXT: ParmVarDecl{{.*}} i 'int' +// CHECK-NEXT: ... +// CHECK-NEXT: CompoundStmt +@end + +@protocol TestObjCProtocolDecl +- (void) foo; +@end +// CHECK: ObjCProtocolDecl{{.*}} TestObjCProtocolDecl +// CHECK-NEXT: ObjCMethodDecl{{.*}} foo + +@interface TestObjCClass : A <P> +- (void) foo; +@end +// CHECK: ObjCInterfaceDecl{{.*}} TestObjCClass +// CHECK-NEXT: super ObjCInterface{{.*}} 'A' +// CHECK-NEXT: ObjCImplementation{{.*}} 'TestObjCClass' +// CHECK-NEXT: ObjCProtocol{{.*}} 'P' +// CHECK-NEXT: ObjCMethodDecl{{.*}} foo + +@implementation TestObjCClass : A { + int i; +} +- (void) foo { +} +@end +// CHECK: ObjCImplementationDecl{{.*}} TestObjCClass +// CHECK-NEXT: super ObjCInterface{{.*}} 'A' +// CHECK-NEXT: ObjCInterface{{.*}} 'TestObjCClass' +// CHECK-NEXT: ObjCIvarDecl{{.*}} i +// CHECK-NEXT: ObjCMethodDecl{{.*}} foo + +@interface TestObjCClass (TestObjCCategoryDecl) <P> +- (void) bar; +@end +// CHECK: ObjCCategoryDecl{{.*}} TestObjCCategoryDecl +// CHECK-NEXT: ObjCInterface{{.*}} 'TestObjCClass' +// CHECK-NEXT: ObjCCategoryImpl{{.*}} 'TestObjCClass' +// CHECK-NEXT: ObjCProtocol{{.*}} 'P' +// CHECK-NEXT: ObjCMethodDecl{{.*}} bar + +@implementation TestObjCClass (TestObjCCategoryDecl) +- (void) bar { +} +@end +// CHECK: ObjCCategoryImplDecl{{.*}} TestObjCClass +// CHECK-NEXT: ObjCInterface{{.*}} 'TestObjCClass' +// CHECK-NEXT: ObjCCategory{{.*}} 'TestObjCCategoryDecl' +// CHECK-NEXT: ObjCMethodDecl{{.*}} bar + +@compatibility_alias TestObjCCompatibleAliasDecl A; +// CHECK: ObjCCompatibleAliasDecl{{.*}} TestObjCCompatibleAliasDecl +// CHECK-NEXT: ObjCInterface{{.*}} 'A' + +@interface TestObjCProperty: A +@property(getter=getterFoo, setter=setterFoo:) int foo; +@property int bar; +@end +// CHECK: ObjCInterfaceDecl{{.*}} TestObjCProperty +// CHECK: ObjCPropertyDecl{{.*}} foo 'int' assign readwrite atomic unsafe_unretained +// CHECK-NEXT: getter ObjCMethod{{.*}} 'getterFoo' +// CHECK-NEXT: setter ObjCMethod{{.*}} 'setterFoo:' +// CHECK-NEXT: ObjCPropertyDecl{{.*}} bar 'int' assign readwrite atomic unsafe_unretained +// CHECK-NEXT: ObjCMethodDecl{{.*}} getterFoo +// CHECK-NEXT: ObjCMethodDecl{{.*}} setterFoo: +// CHECK-NEXT: ParmVarDecl{{.*}} foo +// CHECK-NEXT: ObjCMethodDecl{{.*}} bar +// CHECK-NEXT: ObjCMethodDecl{{.*}} setBar: +// CHECK-NEXT: ParmVarDecl{{.*}} bar + +@implementation TestObjCProperty { + int i; +} +@synthesize foo=i; +@synthesize bar; +@end +// CHECK: ObjCImplementationDecl{{.*}} TestObjCProperty +// CHECK: ObjCPropertyImplDecl{{.*}} foo synthesize +// CHECK-NEXT: ObjCProperty{{.*}} 'foo' +// CHECK-NEXT: ObjCIvar{{.*}} 'i' 'int' +// CHECK-NEXT: ObjCIvarDecl{{.*}} bar 'int' synthesize private +// CHECK-NEXT: ObjCPropertyImplDecl{{.*}} bar synthesize +// CHECK-NEXT: ObjCProperty{{.*}} 'bar' +// CHECK-NEXT: ObjCIvar{{.*}} 'bar' 'int' + +void TestBlockDecl(int x) { + ^(int y, ...){ x; }; +} +// CHECK: FunctionDecl{{.*}}TestBlockDecl +// CHECK: BlockDecl +// CHECK-NEXT: ParmVarDecl{{.*}} y 'int' +// CHECK-NEXT: ... +// CHECK-NEXT: capture ParmVar{{.*}} 'x' 'int' +// CHECK-NEXT: CompoundStmt diff --git a/test/Misc/ast-dump-decl.mm b/test/Misc/ast-dump-decl.mm new file mode 100644 index 0000000000000000000000000000000000000000..06ab5155110c4be9027745eb27a97d777abfa9af --- /dev/null +++ b/test/Misc/ast-dump-decl.mm @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -Wno-unused -fblocks -ast-dump -ast-dump-filter Test %s | FileCheck -strict-whitespace %s + +@interface A +@end + +@interface TestObjCImplementation : A +@end + +@implementation TestObjCImplementation : A { + struct X { + int i; + } X; +} +- (void) foo { +} +@end +// CHECK: ObjCImplementationDecl{{.*}} TestObjCImplementation +// CHECK-NEXT: super ObjCInterface{{.*}} 'A' +// CHECK-NEXT: ObjCInterface{{.*}} 'TestObjCImplementation' +// CHECK-NEXT: CXXCtorInitializer{{.*}} 'X' +// CHECK-NEXT: CXXConstructExpr +// CHECK-NEXT: ObjCIvarDecl{{.*}} X +// CHECK-NEXT: ObjCMethodDecl{{.*}} foo diff --git a/test/Misc/ast-dump-stmt.c b/test/Misc/ast-dump-stmt.c index d7fdce8d593c0baeb8a98f3ac678949ac3fac036..0df236edfc957e1a54078460e0fab442e1e093e0 100644 --- a/test/Misc/ast-dump-stmt.c +++ b/test/Misc/ast-dump-stmt.c @@ -1,31 +1,31 @@ // RUN: %clang_cc1 -ast-dump -ast-dump-filter Test %s | FileCheck -strict-whitespace %s int TestLocation = 0; -// CHECK: Dumping TestLocation -// CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <{{.*}}:3:20> 'int' 0 +// CHECK: VarDecl{{.*}}TestLocation +// CHECK-NEXT: IntegerLiteral 0x{{[^ ]*}} <col:20> 'int' 0 int TestIndent = 1 + (1); -// CHECK: Dumping TestIndent -// CHECK-NEXT: {{\(BinaryOperator[^()]*$}} -// CHECK-NEXT: {{^ \(IntegerLiteral.*0[^()]*\)$}} -// CHECK-NEXT: {{^ \(ParenExpr.*0[^()]*$}} -// CHECK-NEXT: {{^ \(IntegerLiteral.*0[^()]*\)\)\)$}} +// CHECK: VarDecl{{.*}}TestIndent +// CHECK-NEXT: {{^ \(BinaryOperator[^()]*$}} +// CHECK-NEXT: {{^ \(IntegerLiteral.*0[^()]*\)$}} +// CHECK-NEXT: {{^ \(ParenExpr.*0[^()]*$}} +// CHECK-NEXT: {{^ \(IntegerLiteral.*0[^()]*\)\)\)\)$}} void TestDeclStmt() { int x = 0; int y, z; } -// CHECK: Dumping TestDeclStmt +// CHECK: FunctionDecl{{.*}}TestDeclStmt // CHECK-NEXT: CompoundStmt // CHECK-NEXT: DeclStmt -// CHECK-NEXT: int x = +// CHECK-NEXT: VarDecl{{.*}}x // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: DeclStmt -// CHECK-NEXT: int y -// CHECK-NEXT: int z +// CHECK-NEXT: VarDecl{{.*}}y +// CHECK-NEXT: VarDecl{{.*}}z int TestOpaqueValueExpr = 0 ?: 1; -// CHECK: Dumping TestOpaqueValueExpr +// CHECK: VarDecl{{.*}}TestOpaqueValueExpr // CHECK-NEXT: BinaryConditionalOperator // CHECK-NEXT: IntegerLiteral // CHECK-NEXT: OpaqueValueExpr diff --git a/test/Misc/ast-dump-stmt.m b/test/Misc/ast-dump-stmt.m index 8dfee74ab544f0c380ed4d72dada6bb97a4caa2f..8c0ca897e51149e9b7c7a5eb72b8bb36d1e2a9a8 100644 --- a/test/Misc/ast-dump-stmt.m +++ b/test/Misc/ast-dump-stmt.m @@ -3,15 +3,14 @@ void TestBlockExpr(int x) { ^{ x; }; } -// CHECK: Dumping TestBlockExpr -// CHECK: BlockExpr{{.*}} decl= -// CHECK-NEXT: capture ParmVar -// CHECK-NEXT: CompoundStmt +// CHECK: FunctionDecl{{.*}}TestBlockExpr +// CHECK: BlockExpr{{.*}} 'void (^)(void)' +// CHECK-NEXT: BlockDecl void TestExprWithCleanup(int x) { ^{ x; }; } -// CHECK: Dumping TestExprWithCleanup +// CHECK: FunctionDecl{{.*}}TestExprWithCleanup // CHECK: ExprWithCleanups // CHECK-NEXT: cleanup Block // CHECK-NEXT: BlockExpr @@ -26,10 +25,11 @@ void TestObjCAtCatchStmt() { } @finally { } } -// CHECK: Dumping TestObjCAtCatchStmt +// CHECK: FunctionDecl{{.*}}TestObjCAtCatchStmt // CHECK: ObjCAtTryStmt // CHECK-NEXT: CompoundStmt -// CHECK-NEXT: ObjCAtCatchStmt{{.*}} catch parm = "A *a" +// CHECK-NEXT: ObjCAtCatchStmt{{.*}} +// CHECK-NEXT: VarDecl{{.*}}a // CHECK-NEXT: CompoundStmt // CHECK-NEXT: ObjCAtCatchStmt{{.*}} catch all // CHECK-NEXT: CompoundStmt diff --git a/test/Misc/ast-dump-templates.cpp b/test/Misc/ast-dump-templates.cpp index 7d56e7b04eb2d195825590ad36f5fda996e9fc39..7e28da95a1f2e6a8d95c5792bb347dc1ffc73b9f 100644 --- a/test/Misc/ast-dump-templates.cpp +++ b/test/Misc/ast-dump-templates.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -ast-dump %s > %t +// RUN: %clang_cc1 -ast-print %s > %t // RUN: FileCheck < %t %s -check-prefix=CHECK1 // RUN: FileCheck < %t %s -check-prefix=CHECK2 @@ -27,8 +27,8 @@ void baz() { // CHECK2: template <int X = 2, typename Y = double, int Z = 3> struct foo { // Template definition - foo -// CHECK1: template <int X, typename Y, int Z = (IntegerLiteral {{.*}} 'int' 5) -// CHECK2: template <int X, typename Y, int Z = (IntegerLiteral {{.*}} 'int' 5) +// CHECK1: template <int X, typename Y, int Z = 5> struct foo { +// CHECK2: template <int X, typename Y, int Z = 5> struct foo { // Template instantiation - bar // CHECK1: template <int A = 5, typename B = int> int bar() diff --git a/test/Misc/ast-dump-wchar.cpp b/test/Misc/ast-dump-wchar.cpp index 87d962fec87030c64e1f2cd81bfcf6ea3464e572..1dca83c47b937927e6a9a2880c08d5ea88526fad 100644 --- a/test/Misc/ast-dump-wchar.cpp +++ b/test/Misc/ast-dump-wchar.cpp @@ -1,13 +1,13 @@ // RUN: %clang_cc1 -std=c++11 -ast-dump %s -triple x86_64-linux-gnu | FileCheck %s char c8[] = u8"test\0\\\"\t\a\b\234"; -// CHECK: char c8[12] = (StringLiteral {{.*}} lvalue u8"test\000\\\"\t\a\b\234") +// CHECK: (StringLiteral {{.*}} lvalue u8"test\000\\\"\t\a\b\234") char16_t c16[] = u"test\0\\\"\t\a\b\234\u1234"; -// CHECK: char16_t c16[13] = (StringLiteral {{.*}} lvalue u"test\000\\\"\t\a\b\234\u1234") +// CHECK: (StringLiteral {{.*}} lvalue u"test\000\\\"\t\a\b\234\u1234") char32_t c32[] = U"test\0\\\"\t\a\b\234\u1234\U0010ffff"; // \ -// CHECK: char32_t c32[14] = (StringLiteral {{.*}} lvalue U"test\000\\\"\t\a\b\234\u1234\U0010FFFF") +// CHECK: (StringLiteral {{.*}} lvalue U"test\000\\\"\t\a\b\234\u1234\U0010FFFF") wchar_t wc[] = L"test\0\\\"\t\a\b\234\u1234\xffffffff"; // \ -// CHECK: wchar_t wc[14] = (StringLiteral {{.*}} lvalue L"test\000\\\"\t\a\b\234\x1234\xFFFFFFFF") +// CHECK: (StringLiteral {{.*}} lvalue L"test\000\\\"\t\a\b\234\x1234\xFFFFFFFF") diff --git a/test/PCH/objc_stmts.m b/test/PCH/objc_stmts.m index b9b10c53480a5bc7541793574604d5570cf0d7f6..8deb14a8154511263823616f2842650dd4495342 100644 --- a/test/PCH/objc_stmts.m +++ b/test/PCH/objc_stmts.m @@ -1,12 +1,12 @@ // Test this without pch. // RUN: %clang_cc1 -include %S/objc_stmts.h -emit-llvm -fobjc-exceptions -o - %s -// RUN: %clang_cc1 -include %S/objc_stmts.h -ast-dump -fobjc-exceptions -o - %s | FileCheck %s +// RUN: %clang_cc1 -include %S/objc_stmts.h -ast-print -fobjc-exceptions -o - %s | FileCheck %s // Test with pch. // RUN: %clang_cc1 -x objective-c -emit-pch -fobjc-exceptions -o %t %S/objc_stmts.h // RUN: %clang_cc1 -include-pch %t -emit-llvm -fobjc-exceptions -o - %s -// RUN: %clang_cc1 -include-pch %t -ast-dump -fobjc-exceptions -o - %s | FileCheck %s +// RUN: %clang_cc1 -include-pch %t -ast-print -fobjc-exceptions -o - %s | FileCheck %s -// CHECK: catch parm = "A *a" -// CHECK: catch parm = "B *b" -// CHECK: catch all +// CHECK: @catch(A *a) +// CHECK: @catch(B *b) +// CHECK: @catch() diff --git a/test/SemaTemplate/default-expr-arguments-2.cpp b/test/SemaTemplate/default-expr-arguments-2.cpp index 378999d0d3c47d3481afd75db4711446113bed87..037949455f53676b78a9bd9867fb01014ef5ff92 100644 --- a/test/SemaTemplate/default-expr-arguments-2.cpp +++ b/test/SemaTemplate/default-expr-arguments-2.cpp @@ -10,9 +10,9 @@ namespace PR6733 { bar(int x = kSomeConst) {} }; - // CHECK: void f() + // CHECK: FunctionDecl{{.*}}f 'void (void)' void f() { - // CHECK: bar<int> tmp = + // CHECK: VarDecl{{.*}}tmp 'bar<int>' // CHECK: CXXDefaultArgExpr{{.*}}'int' bar<int> tmp; } diff --git a/test/Tooling/clang-check-ast-dump.cpp b/test/Tooling/clang-check-ast-dump.cpp index 6e03f82d0fe945125910f99c549c048ff443b5b0..90827e10b776cde783e9f94bc4055002b9d567be 100644 --- a/test/Tooling/clang-check-ast-dump.cpp +++ b/test/Tooling/clang-check-ast-dump.cpp @@ -1,15 +1,19 @@ // RUN: clang-check -ast-dump "%s" -- 2>&1 | FileCheck %s -// CHECK: namespace test_namespace -// CHECK-NEXT: class TheClass -// CHECK: int theMethod(int x) (CompoundStmt +// CHECK: (NamespaceDecl{{.*}}test_namespace +// CHECK-NEXT: (CXXRecordDecl{{.*}}TheClass +// CHECK: (CXXMethodDecl{{.*}}theMethod +// CHECK-NEXT: (ParmVarDecl{{.*}}x +// CHECK-NEXT: (CompoundStmt // CHECK-NEXT: (ReturnStmt // CHECK-NEXT: (BinaryOperator // // RUN: clang-check -ast-dump -ast-dump-filter test_namespace::TheClass::theMethod "%s" -- 2>&1 | FileCheck -check-prefix CHECK-FILTER %s -// CHECK-FILTER-NOT: namespace test_namespace -// CHECK-FILTER-NOT: class TheClass +// CHECK-FILTER-NOT: NamespaceDecl +// CHECK-FILTER-NOT: CXXRecordDecl // CHECK-FILTER: {{^}}Dumping test_namespace::TheClass::theMethod -// CHECK-FILTER-NEXT: {{^}}int theMethod(int x) (CompoundStmt +// CHECK-FILTER-NEXT: {{^}}(CXXMethodDecl{{.*}}theMethod +// CHECK-FILTER-NEXT: (ParmVarDecl{{.*}}x +// CHECK-FILTER-NEXT: (CompoundStmt // CHECK-FILTER-NEXT: (ReturnStmt // CHECK-FILTER-NEXT: (BinaryOperator // @@ -26,7 +30,8 @@ // // RUN: clang-check -ast-dump -ast-dump-filter test_namespace::TheClass::n "%s" -- 2>&1 | FileCheck -check-prefix CHECK-ATTR %s // CHECK-ATTR: test_namespace -// CHECK-ATTR-NEXT: int n __attribute__((aligned((BinaryOperator +// CHECK-ATTR-NEXT: (FieldDecl{{.*}}n +// FIXME: attribute dumping not implemented yet // // RUN: clang-check -ast-dump -ast-dump-filter test_namespace::AfterNullNode "%s" -- 2>&1 | FileCheck -check-prefix CHECK-AFTER-NULL %s // CHECK-AFTER-NULL: class AfterNullNode