diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 40 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 11 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterDecl.cpp | 19 |
4 files changed, 57 insertions, 17 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 1fb146e839b..fbc8874e93e 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -8908,7 +8908,7 @@ static GVALinkage basicGVALinkageForFunction(const ASTContext &Context, } 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 adjustGVALinkageForAttributes(const ASTContext &Context, 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 basicGVALinkageForVariable(const ASTContext &Context, } 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 Decl *D) { 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; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 4ba54fb7127..3221d78d167 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -8291,8 +8291,8 @@ ASTReader::getSourceDescriptor(unsigned ID) { } 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; } diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 533a3f9bdca..6932261ad9b 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -453,7 +453,7 @@ uint64_t ASTDeclReader::GetCurrentCursorOffset() { 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 ASTDeclReader::VisitVarDeclImpl(VarDecl *VD) { } } + 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::ReadCXXDefinitionData( 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(); diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index 76021e270ba..bdf3fca49a7 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -928,6 +928,24 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { } 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) { !D->isConstexpr() && !D->isInitCapture() && !D->isPreviousDeclInSameBlockScope() && + D->getStorageDuration() != SD_Static && !D->getMemberSpecializationInfo()) AbbrevToUse = Writer.getDeclVarAbbrev(); |