Author: dblaikie Date: Tue Apr 11 16:13:37 2017 New Revision: 299987 URL: http://llvm.org/viewvc/llvm-project?rev=299987&view=rev Log: Modular Codegen: Support homing debug info for types in modular objects
Matching the function-homing support for modular codegen. Any type implicitly (implicit template specializations) or explicitly defined in a module is attached to that module's object file and omitted elsewhere (only a declaration used if necessary for references). Modified: cfe/trunk/include/clang/AST/ExternalASTSource.h cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h cfe/trunk/include/clang/Serialization/ASTReader.h cfe/trunk/lib/AST/ExternalASTSource.cpp cfe/trunk/lib/CodeGen/CGDebugInfo.cpp cfe/trunk/lib/CodeGen/CGDebugInfo.h cfe/trunk/lib/CodeGen/CodeGenModule.cpp cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp cfe/trunk/lib/Serialization/ASTReader.cpp cfe/trunk/lib/Serialization/ASTReaderDecl.cpp cfe/trunk/lib/Serialization/ASTWriter.cpp cfe/trunk/test/Modules/Inputs/codegen-nodep/foo.h cfe/trunk/test/Modules/codegen-nodep.test cfe/trunk/test/Modules/codegen.test Modified: cfe/trunk/include/clang/AST/ExternalASTSource.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExternalASTSource.h?rev=299987&r1=299986&r2=299987&view=diff ============================================================================== --- cfe/trunk/include/clang/AST/ExternalASTSource.h (original) +++ cfe/trunk/include/clang/AST/ExternalASTSource.h Tue Apr 11 16:13:37 2017 @@ -172,7 +172,7 @@ public: enum ExtKind { EK_Always, EK_Never, EK_ReplyHazy }; - virtual ExtKind hasExternalDefinitions(const FunctionDecl *FD); + virtual ExtKind hasExternalDefinitions(const Decl *D); /// \brief Finds all declarations lexically contained within the given /// DeclContext, after applying an optional filter predicate. Modified: cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h?rev=299987&r1=299986&r2=299987&view=diff ============================================================================== --- cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h (original) +++ cfe/trunk/include/clang/Sema/MultiplexExternalSemaSource.h Tue Apr 11 16:13:37 2017 @@ -90,7 +90,7 @@ public: /// initializers themselves. CXXCtorInitializer **GetExternalCXXCtorInitializers(uint64_t Offset) override; - ExtKind hasExternalDefinitions(const FunctionDecl *FD) override; + ExtKind hasExternalDefinitions(const Decl *D) override; /// \brief Find all declarations with the given name in the /// given context. Modified: cfe/trunk/include/clang/Serialization/ASTReader.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=299987&r1=299986&r2=299987&view=diff ============================================================================== --- cfe/trunk/include/clang/Serialization/ASTReader.h (original) +++ cfe/trunk/include/clang/Serialization/ASTReader.h Tue Apr 11 16:13:37 2017 @@ -1115,7 +1115,7 @@ private: /// predefines buffer may contain additional definitions. std::string SuggestedPredefines; - llvm::DenseMap<const FunctionDecl *, bool> BodySource; + llvm::DenseMap<const Decl *, bool> BodySource; /// \brief Reads a statement from the specified cursor. Stmt *ReadStmtFromStream(ModuleFile &F); @@ -1999,7 +1999,7 @@ public: /// \brief Return a descriptor for the corresponding module. llvm::Optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID) override; - ExtKind hasExternalDefinitions(const FunctionDecl *FD) override; + ExtKind hasExternalDefinitions(const Decl *D) override; /// \brief Retrieve a selector from the given module with its local ID /// number. Modified: cfe/trunk/lib/AST/ExternalASTSource.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExternalASTSource.cpp?rev=299987&r1=299986&r2=299987&view=diff ============================================================================== --- cfe/trunk/lib/AST/ExternalASTSource.cpp (original) +++ cfe/trunk/lib/AST/ExternalASTSource.cpp Tue Apr 11 16:13:37 2017 @@ -29,7 +29,7 @@ ExternalASTSource::getSourceDescriptor(u } ExternalASTSource::ExtKind -ExternalASTSource::hasExternalDefinitions(const FunctionDecl *FD) { +ExternalASTSource::hasExternalDefinitions(const Decl *D) { return EK_ReplyHazy; } Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=299987&r1=299986&r2=299987&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original) +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Tue Apr 11 16:13:37 2017 @@ -1820,6 +1820,10 @@ static bool shouldOmitDefinition(codegen if (DebugTypeExtRefs && isDefinedInClangModule(RD->getDefinition())) return true; + if (auto *ES = RD->getASTContext().getExternalSource()) + if (ES->hasExternalDefinitions(RD) == ExternalASTSource::EK_Always) + return true; + if (DebugKind > codegenoptions::LimitedDebugInfo) return false; @@ -2552,11 +2556,17 @@ void CGDebugInfo::completeTemplateDefini const ClassTemplateSpecializationDecl &SD) { if (DebugKind <= codegenoptions::DebugLineTablesOnly) return; + completeUnusedClass(SD); +} + +void CGDebugInfo::completeUnusedClass(const CXXRecordDecl &D) { + if (DebugKind <= codegenoptions::DebugLineTablesOnly) + return; - completeClassData(&SD); + completeClassData(&D); // In case this type has no member function definitions being emitted, ensure // it is retained - RetainedTypes.push_back(CGM.getContext().getRecordType(&SD).getAsOpaquePtr()); + RetainedTypes.push_back(CGM.getContext().getRecordType(&D).getAsOpaquePtr()); } llvm::DIType *CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile *Unit) { Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?rev=299987&r1=299986&r2=299987&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGDebugInfo.h (original) +++ cfe/trunk/lib/CodeGen/CGDebugInfo.h Tue Apr 11 16:13:37 2017 @@ -438,6 +438,7 @@ public: void completeClass(const RecordDecl *RD); void completeTemplateDefinition(const ClassTemplateSpecializationDecl &SD); + void completeUnusedClass(const CXXRecordDecl &D); /// Create debug info for a macro defined by a #define directive or a macro /// undefined by a #undef directive. Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=299987&r1=299986&r2=299987&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original) +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Tue Apr 11 16:13:37 2017 @@ -3820,6 +3820,11 @@ void CodeGenModule::EmitTopLevelDecl(Dec EmitDeclContext(cast<NamespaceDecl>(D)); break; case Decl::CXXRecord: + if (DebugInfo) { + if (auto *ES = D->getASTContext().getExternalSource()) + if (ES->hasExternalDefinitions(D) == ExternalASTSource::EK_Never) + DebugInfo->completeUnusedClass(cast<CXXRecordDecl>(*D)); + } // Emit any static data members, they may be definitions. for (auto *I : cast<CXXRecordDecl>(D)->decls()) if (isa<VarDecl>(I) || isa<CXXRecordDecl>(I)) Modified: cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp?rev=299987&r1=299986&r2=299987&view=diff ============================================================================== --- cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp (original) +++ cfe/trunk/lib/Sema/MultiplexExternalSemaSource.cpp Tue Apr 11 16:13:37 2017 @@ -95,9 +95,9 @@ MultiplexExternalSemaSource::GetExternal } ExternalASTSource::ExtKind -MultiplexExternalSemaSource::hasExternalDefinitions(const FunctionDecl *FD) { +MultiplexExternalSemaSource::hasExternalDefinitions(const Decl *D) { for (const auto &S : Sources) - if (auto EK = S->hasExternalDefinitions(FD)) + if (auto EK = S->hasExternalDefinitions(D)) if (EK != EK_ReplyHazy) return EK; return EK_ReplyHazy; Modified: cfe/trunk/lib/Serialization/ASTReader.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=299987&r1=299986&r2=299987&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReader.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReader.cpp Tue Apr 11 16:13:37 2017 @@ -8147,8 +8147,7 @@ ASTReader::getSourceDescriptor(unsigned return None; } -ExternalASTSource::ExtKind -ASTReader::hasExternalDefinitions(const FunctionDecl *FD) { +ExternalASTSource::ExtKind ASTReader::hasExternalDefinitions(const Decl *FD) { auto I = BodySource.find(FD); if (I == BodySource.end()) return EK_ReplyHazy; Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=299987&r1=299986&r2=299987&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Tue Apr 11 16:13:37 2017 @@ -119,7 +119,8 @@ namespace clang { } void ReadCXXRecordDefinition(CXXRecordDecl *D, bool Update); - void ReadCXXDefinitionData(struct CXXRecordDecl::DefinitionData &Data); + void ReadCXXDefinitionData(struct CXXRecordDecl::DefinitionData &Data, + const CXXRecordDecl *D); void MergeDefinitionData(CXXRecordDecl *D, struct CXXRecordDecl::DefinitionData &&NewDD); void ReadObjCDefinitionData(struct ObjCInterfaceDecl::DefinitionData &Data); @@ -1490,7 +1491,7 @@ void ASTDeclReader::VisitUnresolvedUsing } void ASTDeclReader::ReadCXXDefinitionData( - struct CXXRecordDecl::DefinitionData &Data) { + struct CXXRecordDecl::DefinitionData &Data, const CXXRecordDecl *D) { // Note: the caller has deserialized the IsLambda bit already. Data.UserDeclaredConstructor = Record.readInt(); Data.UserDeclaredSpecialMembers = Record.readInt(); @@ -1536,6 +1537,12 @@ void ASTDeclReader::ReadCXXDefinitionDat Data.HasDeclaredCopyAssignmentWithConstParam = Record.readInt(); Data.ODRHash = Record.readInt(); + if (Record.readInt()) { + Reader.BodySource[D] = Loc.F->Kind == ModuleKind::MK_MainFile + ? ExternalASTSource::EK_Never + : ExternalASTSource::EK_Always; + } + Data.NumBases = Record.readInt(); if (Data.NumBases) Data.Bases = ReadGlobalOffset(); @@ -1707,7 +1714,7 @@ void ASTDeclReader::ReadCXXRecordDefinit else DD = new (C) struct CXXRecordDecl::DefinitionData(D); - ReadCXXDefinitionData(*DD); + ReadCXXDefinitionData(*DD, D); // We might already have a definition for this record. This can happen either // because we're reading an update record, or because we've already done some @@ -2553,7 +2560,11 @@ static bool isConsumerInterestedIn(ASTCo Var->isThisDeclarationADefinition() == VarDecl::Definition; if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D)) return Func->doesThisDeclarationHaveABody() || HasBody; - + + if (auto *ES = D->getASTContext().getExternalSource()) + if (ES->hasExternalDefinitions(D) == ExternalASTSource::EK_Never) + return true; + return false; } Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=299987&r1=299986&r2=299987&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original) +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Tue Apr 11 16:13:37 2017 @@ -5770,6 +5770,12 @@ void ASTRecordWriter::AddCXXDefinitionDa Record->push_back(Data.HasDeclaredCopyConstructorWithConstParam); Record->push_back(Data.HasDeclaredCopyAssignmentWithConstParam); Record->push_back(Data.ODRHash); + bool ModularCodegen = Writer->Context->getLangOpts().ModularCodegen && + Writer->WritingModule && !D->isDependentType(); + Record->push_back(ModularCodegen); + if (ModularCodegen) + Writer->ModularCodegenDecls.push_back(Writer->GetDeclRef(D)); + // IsLambda bit is already saved. Record->push_back(Data.NumBases); Modified: cfe/trunk/test/Modules/Inputs/codegen-nodep/foo.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/codegen-nodep/foo.h?rev=299987&r1=299986&r2=299987&view=diff ============================================================================== --- cfe/trunk/test/Modules/Inputs/codegen-nodep/foo.h (original) +++ cfe/trunk/test/Modules/Inputs/codegen-nodep/foo.h Tue Apr 11 16:13:37 2017 @@ -1,5 +1,11 @@ template <typename T> -void ftempl() { +void foot() { } -inline void f() { +inline void foo() { } + +template <typename T> +struct bart { +}; +struct bar { +}; Modified: cfe/trunk/test/Modules/codegen-nodep.test URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/codegen-nodep.test?rev=299987&r1=299986&r2=299987&view=diff ============================================================================== --- cfe/trunk/test/Modules/codegen-nodep.test (original) +++ cfe/trunk/test/Modules/codegen-nodep.test Tue Apr 11 16:13:37 2017 @@ -7,7 +7,7 @@ RUN: %S/Inputs/codegen-nodep/ RUN: | llvm-bcanalyzer - -dump \ RUN: | FileCheck %s -Ensure there's only one modular codegen decl - the sentinel plain inline -function, not any for the function template. +Ensure there are only two modular codegen decls (one for the class, one for the +function - none for the class and function templates). -CHECK: <MODULAR_CODEGEN_DECLS op0={{[0-9]+}}/> +CHECK: <MODULAR_CODEGEN_DECLS op0={{[0-9]+}} op1={{[0-9]+}}/> Modified: cfe/trunk/test/Modules/codegen.test URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/codegen.test?rev=299987&r1=299986&r2=299987&view=diff ============================================================================== --- cfe/trunk/test/Modules/codegen.test (original) +++ cfe/trunk/test/Modules/codegen.test Tue Apr 11 16:13:37 2017 @@ -3,8 +3,8 @@ REQUIRES: x86-registered-target RUN: %clang_cc1 -triple=x86_64-linux-gnu -fmodules-codegen -x c++ -fmodules -emit-module -fmodule-name=foo %S/Inputs/codegen/foo.modulemap -o %t/foo.pcm -RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %t/foo.pcm | FileCheck --check-prefix=FOO --check-prefix=BOTH %s -RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - -fmodules -fmodule-file=%t/foo.pcm %S/Inputs/codegen/use.cpp | FileCheck --check-prefix=BOTH --check-prefix=USE %s +RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - %t/foo.pcm | FileCheck --check-prefix=FOO --check-prefix=BOTH %s +RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - -fmodules -fmodule-file=%t/foo.pcm %S/Inputs/codegen/use.cpp | FileCheck --check-prefix=BOTH --check-prefix=USE %s FOO: $_Z2f1PKcz = comdat any FOO: $_ZN13implicit_dtorD1Ev = comdat any @@ -25,3 +25,11 @@ FOO: define weak_odr void @_ZN13implicit USE: define linkonce_odr void @_ZN20uninst_implicit_dtorD1Ev USE: define linkonce_odr void @_Z4instIiEvv USE: define linkonce_odr void @_ZN20uninst_implicit_dtorD2Ev + +Modular debug info puts the definition of a class defined in a module in that +module's object. Users of the module only get a declaration. + +'distinct' is used for definition records (the flags field is empty/unspecified) +FOO: = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "implicit_dtor" +Declarations are non-distinct and include the 'DIFlagFwdDecl' flag. +USE: = !DICompositeType(tag: DW_TAG_structure_type, name: "implicit_dtor", {{.*}}, flags: DIFlagFwdDecl _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits