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; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits