r312665 - [modules ts] Emit global variables in a module interface unit as part of that unit, not in importers.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 6 13:01:15 PDT 2017


Author: rsmith
Date: Wed Sep  6 13:01:14 2017
New Revision: 312665

URL: http://llvm.org/viewvc/llvm-project?rev=312665&view=rev
Log:
[modules ts] Emit global variables in a module interface unit as part of that unit, not in importers.

Modified:
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
    cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp
    cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=312665&r1=312664&r2=312665&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Wed Sep  6 13:01:14 2017
@@ -1133,7 +1133,7 @@ private:
   /// predefines buffer may contain additional definitions.
   std::string SuggestedPredefines;
 
-  llvm::DenseMap<const Decl *, bool> BodySource;
+  llvm::DenseMap<const Decl *, bool> DefinitionSource;
 
   /// \brief Reads a statement from the specified cursor.
   Stmt *ReadStmtFromStream(ModuleFile &F);

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=312665&r1=312664&r2=312665&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Sep  6 13:01:14 2017
@@ -8908,7 +8908,7 @@ static GVALinkage basicGVALinkageForFunc
 }
 
 static GVALinkage adjustGVALinkageForAttributes(const ASTContext &Context,
-                                                GVALinkage L, const Decl *D) {
+                                                const Decl *D, GVALinkage L) {
   // See http://msdn.microsoft.com/en-us/library/xa0d9ste.aspx
   // dllexport/dllimport on inline functions.
   if (D->hasAttr<DLLImportAttr>()) {
@@ -8927,25 +8927,37 @@ static GVALinkage adjustGVALinkageForAtt
   return L;
 }
 
-GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) const {
-  auto L = adjustGVALinkageForAttributes(
-      *this, basicGVALinkageForFunction(*this, FD), FD);
-  auto EK = ExternalASTSource::EK_ReplyHazy;
-  if (auto *Ext = getExternalSource())
-    EK = Ext->hasExternalDefinitions(FD);
-  switch (EK) {
+/// Adjust the GVALinkage for a declaration based on what an external AST source
+/// knows about whether there can be other definitions of this declaration.
+static GVALinkage
+adjustGVALinkageForExternalDefinitionKind(const ASTContext &Ctx, const Decl *D,
+                                          GVALinkage L) {
+  ExternalASTSource *Source = Ctx.getExternalSource();
+  if (!Source)
+    return L;
+
+  switch (Source->hasExternalDefinitions(D)) {
   case ExternalASTSource::EK_Never:
+    // Other translation units rely on us to provide the definition.
     if (L == GVA_DiscardableODR)
       return GVA_StrongODR;
     break;
+
   case ExternalASTSource::EK_Always:
     return GVA_AvailableExternally;
+
   case ExternalASTSource::EK_ReplyHazy:
     break;
   }
   return L;
 }
 
+GVALinkage ASTContext::GetGVALinkageForFunction(const FunctionDecl *FD) const {
+  return adjustGVALinkageForExternalDefinitionKind(*this, FD,
+           adjustGVALinkageForAttributes(*this, FD,
+             basicGVALinkageForFunction(*this, FD)));
+}
+
 static GVALinkage basicGVALinkageForVariable(const ASTContext &Context,
                                              const VarDecl *VD) {
   if (!VD->isExternallyVisible())
@@ -9024,8 +9036,9 @@ static GVALinkage basicGVALinkageForVari
 }
 
 GVALinkage ASTContext::GetGVALinkageForVariable(const VarDecl *VD) {
-  return adjustGVALinkageForAttributes(
-      *this, basicGVALinkageForVariable(*this, VD), VD);
+  return adjustGVALinkageForExternalDefinitionKind(*this, VD,
+           adjustGVALinkageForAttributes(*this, VD,
+             basicGVALinkageForVariable(*this, VD)));
 }
 
 bool ASTContext::DeclMustBeEmitted(const Decl *D) {
@@ -9108,9 +9121,14 @@ bool ASTContext::DeclMustBeEmitted(const
     return false;
 
   // Variables that can be needed in other TUs are required.
-  if (!isDiscardableGVALinkage(GetGVALinkageForVariable(VD)))
+  auto Linkage = GetGVALinkageForVariable(VD);
+  if (!isDiscardableGVALinkage(Linkage))
     return true;
 
+  // We never need to emit a variable that is available in another TU.
+  if (Linkage == GVA_AvailableExternally)
+    return false;
+
   // Variables that have destruction with side-effects are required.
   if (VD->getType().isDestructedType())
     return true;

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=312665&r1=312664&r2=312665&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Wed Sep  6 13:01:14 2017
@@ -8291,8 +8291,8 @@ ASTReader::getSourceDescriptor(unsigned
 }
 
 ExternalASTSource::ExtKind ASTReader::hasExternalDefinitions(const Decl *FD) {
-  auto I = BodySource.find(FD);
-  if (I == BodySource.end())
+  auto I = DefinitionSource.find(FD);
+  if (I == DefinitionSource.end())
     return EK_ReplyHazy;
   return I->second ? EK_Never : EK_Always;
 }

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=312665&r1=312664&r2=312665&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Wed Sep  6 13:01:14 2017
@@ -453,7 +453,7 @@ uint64_t ASTDeclReader::GetCurrentCursor
 
 void ASTDeclReader::ReadFunctionDefinition(FunctionDecl *FD) {
   if (Record.readInt())
-    Reader.BodySource[FD] = Loc.F->Kind == ModuleKind::MK_MainFile;
+    Reader.DefinitionSource[FD] = Loc.F->Kind == ModuleKind::MK_MainFile;
   if (auto *CD = dyn_cast<CXXConstructorDecl>(FD)) {
     CD->NumCtorInitializers = Record.readInt();
     if (CD->NumCtorInitializers)
@@ -1294,6 +1294,9 @@ ASTDeclReader::RedeclarableResult ASTDec
     }
   }
 
+  if (VD->getStorageDuration() == SD_Static && Record.readInt())
+    Reader.DefinitionSource[VD] = Loc.F->Kind == ModuleKind::MK_MainFile;
+
   enum VarKind {
     VarNotTemplate = 0, VarTemplate, StaticDataMemberSpecialization
   };
@@ -1589,9 +1592,9 @@ void ASTDeclReader::ReadCXXDefinitionDat
   Data.HasODRHash = true;
 
   if (Record.readInt()) {
-    Reader.BodySource[D] = Loc.F->Kind == ModuleKind::MK_MainFile
-                               ? ExternalASTSource::EK_Never
-                               : ExternalASTSource::EK_Always;
+    Reader.DefinitionSource[D] = Loc.F->Kind == ModuleKind::MK_MainFile
+                                     ? ExternalASTSource::EK_Never
+                                     : ExternalASTSource::EK_Always;
   }
 
   Data.NumBases = Record.readInt();

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=312665&r1=312664&r2=312665&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Wed Sep  6 13:01:14 2017
@@ -928,6 +928,24 @@ void ASTDeclWriter::VisitVarDecl(VarDecl
   } else {
     Record.push_back(0);
   }
+
+  if (D->getStorageDuration() == SD_Static) {
+    bool ModulesCodegen = false;
+    if (Writer.WritingModule &&
+        !D->getDescribedVarTemplate() && !D->getMemberSpecializationInfo() &&
+        !isa<VarTemplateSpecializationDecl>(D)) {
+      // When building a C++ Modules TS module interface unit, a strong
+      // definition in the module interface is provided by the compilation of
+      // that module interface unit, not by its users. (Inline variables are
+      // still emitted in module users.)
+      ModulesCodegen =
+          (Writer.WritingModule->Kind == Module::ModuleInterfaceUnit &&
+           Writer.Context->GetGVALinkageForVariable(D) == GVA_StrongExternal);
+    }
+    Record.push_back(ModulesCodegen);
+    if (ModulesCodegen)
+      Writer.ModularCodegenDecls.push_back(Writer.GetDeclRef(D));
+  }
   
   enum {
     VarNotTemplate = 0, VarTemplate, StaticDataMemberSpecialization
@@ -963,6 +981,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl
       !D->isConstexpr() &&
       !D->isInitCapture() &&
       !D->isPreviousDeclInSameBlockScope() &&
+      D->getStorageDuration() != SD_Static &&
       !D->getMemberSpecializationInfo())
     AbbrevToUse = Writer.getDeclVarAbbrev();
 

Modified: cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp?rev=312665&r1=312664&r2=312665&view=diff
==============================================================================
--- cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp (original)
+++ cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp Wed Sep  6 13:01:14 2017
@@ -2,17 +2,15 @@
 // RUN: %clang_cc1 -fmodules-ts %s -triple %itanium_abi_triple -fmodule-file=%t -emit-llvm -o - | FileCheck %s --implicit-check-not=unused --implicit-check-not=global_module
 
 // CHECK-DAG: @extern_var_exported = external global
-// FIXME: Should this be 'external global'?
 // CHECK-DAG: @inline_var_exported = linkonce_odr global
-// CHECK-DAG: @_ZW6ModuleE19static_var_exported = external global
-// CHECK-DAG: @const_var_exported = external constant
+// CHECK-DAG: @_ZW6ModuleE19static_var_exported = available_externally global i32 0,
+// CHECK-DAG: @const_var_exported = available_externally constant i32 3,
 //
 // FIXME: The module name should be mangled into all of these.
 // CHECK-DAG: @extern_var_module_linkage = external global
-// FIXME: Should this be 'external global'?
 // CHECK-DAG: @inline_var_module_linkage = linkonce_odr global
-// CHECK-DAG: @_ZW6ModuleE25static_var_module_linkage = external global
-// CHECK-DAG: @_ZW6ModuleE24const_var_module_linkage = external constant
+// CHECK-DAG: @_ZW6ModuleE25static_var_module_linkage = available_externally global i32 0,
+// CHECK-DAG: @_ZW6ModuleE24const_var_module_linkage = available_externally constant i32 3,
 
 module Module;
 

Modified: cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp?rev=312665&r1=312664&r2=312665&view=diff
==============================================================================
--- cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp (original)
+++ cfe/trunk/test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp Wed Sep  6 13:01:14 2017
@@ -2,11 +2,9 @@
 // RUN: %clang_cc1 -fmodules-ts %s -triple %itanium_abi_triple -fmodule-file=%t -emit-llvm -o - | FileCheck %s --implicit-check-not=unused --implicit-check-not=global_module
 
 // CHECK-DAG: @extern_var_exported = external global
-// FIXME: Should this be 'external global'?
 // CHECK-DAG: @inline_var_exported = linkonce_odr global
-// FIXME: These should be 'extern global' and 'extern constant'.
-// CHECK-DAG: @_ZW6ModuleE19static_var_exported = global
-// CHECK-DAG: @const_var_exported = constant
+// CHECK-DAG: @_ZW6ModuleE19static_var_exported = available_externally global i32 0
+// CHECK-DAG: @const_var_exported = available_externally constant i32 3
 
 import Module;
 




More information about the cfe-commits mailing list