r299987 - Modular Codegen: Support homing debug info for types in modular objects

David Blaikie via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 11 14:13:37 PDT 2017


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




More information about the cfe-commits mailing list