diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2010-06-19 06:24:06 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2010-06-19 06:24:06 +0000 |
commit | c96b2496fc6bc7efafd1fa1d441f26128e06926f (patch) | |
tree | df3a20ea8c86adf04a516c11203aafcf4a4bc22a /clang/lib/CodeGen/CodeGenModule.cpp | |
parent | 87233f785b253761dd94a6924d117ba7a6ba3690 (diff) | |
download | bcm5719-llvm-c96b2496fc6bc7efafd1fa1d441f26128e06926f.tar.gz bcm5719-llvm-c96b2496fc6bc7efafd1fa1d441f26128e06926f.zip |
Fix for PR7415: refactor CodeGenModule::MayDeferGeneration and make it less
conservative for static variables in templated classes.
llvm-svn: 106385
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 104 |
1 files changed, 45 insertions, 59 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index fbd80ed8d5b..28f73d688c2 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -590,6 +590,47 @@ llvm::Constant *CodeGenModule::EmitAnnotateAttr(llvm::GlobalValue *GV, return llvm::ConstantStruct::get(VMContext, Fields, 4, false); } +static CodeGenModule::GVALinkage +GetLinkageForVariable(ASTContext &Context, const VarDecl *VD) { + // If this is a static data member, compute the kind of template + // specialization. Otherwise, this variable is not part of a + // template. + TemplateSpecializationKind TSK = TSK_Undeclared; + if (VD->isStaticDataMember()) + TSK = VD->getTemplateSpecializationKind(); + + Linkage L = VD->getLinkage(); + if (L == ExternalLinkage && Context.getLangOptions().CPlusPlus && + VD->getType()->getLinkage() == UniqueExternalLinkage) + L = UniqueExternalLinkage; + + switch (L) { + case NoLinkage: + case InternalLinkage: + case UniqueExternalLinkage: + return CodeGenModule::GVA_Internal; + + case ExternalLinkage: + switch (TSK) { + case TSK_Undeclared: + case TSK_ExplicitSpecialization: + return CodeGenModule::GVA_StrongExternal; + + case TSK_ExplicitInstantiationDeclaration: + llvm_unreachable("Variable should not be instantiated"); + // Fall through to treat this like any other instantiation. + + case TSK_ExplicitInstantiationDefinition: + return CodeGenModule::GVA_ExplicitTemplateInstantiation; + + case TSK_ImplicitInstantiation: + return CodeGenModule::GVA_TemplateInstantiation; + } + } + + return CodeGenModule::GVA_StrongExternal; +} + bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) { // Never defer when EmitAllDecls is specified or the decl has // attribute used. @@ -638,24 +679,10 @@ bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) { } } - // Static data may be deferred, but out-of-line static data members - // cannot be. - Linkage L = VD->getLinkage(); - if (L == ExternalLinkage && getContext().getLangOptions().CPlusPlus && - VD->getType()->getLinkage() == UniqueExternalLinkage) - L = UniqueExternalLinkage; - - switch (L) { - case NoLinkage: - case InternalLinkage: - case UniqueExternalLinkage: - // Initializer has side effects? - if (VD->getInit() && VD->getInit()->HasSideEffects(Context)) - return false; - return !(VD->isStaticDataMember() && VD->isOutOfLine()); - - case ExternalLinkage: - break; + GVALinkage L = GetLinkageForVariable(getContext(), VD); + if (L == GVA_Internal || L == GVA_TemplateInstantiation) { + if (!(VD->getInit() && VD->getInit()->HasSideEffects(Context))) + return true; } return false; @@ -1053,47 +1080,6 @@ CodeGenModule::getVTableLinkage(const CXXRecordDecl *RD) { return llvm::GlobalVariable::WeakODRLinkage; } -static CodeGenModule::GVALinkage -GetLinkageForVariable(ASTContext &Context, const VarDecl *VD) { - // If this is a static data member, compute the kind of template - // specialization. Otherwise, this variable is not part of a - // template. - TemplateSpecializationKind TSK = TSK_Undeclared; - if (VD->isStaticDataMember()) - TSK = VD->getTemplateSpecializationKind(); - - Linkage L = VD->getLinkage(); - if (L == ExternalLinkage && Context.getLangOptions().CPlusPlus && - VD->getType()->getLinkage() == UniqueExternalLinkage) - L = UniqueExternalLinkage; - - switch (L) { - case NoLinkage: - case InternalLinkage: - case UniqueExternalLinkage: - return CodeGenModule::GVA_Internal; - - case ExternalLinkage: - switch (TSK) { - case TSK_Undeclared: - case TSK_ExplicitSpecialization: - return CodeGenModule::GVA_StrongExternal; - - case TSK_ExplicitInstantiationDeclaration: - llvm_unreachable("Variable should not be instantiated"); - // Fall through to treat this like any other instantiation. - - case TSK_ExplicitInstantiationDefinition: - return CodeGenModule::GVA_ExplicitTemplateInstantiation; - - case TSK_ImplicitInstantiation: - return CodeGenModule::GVA_TemplateInstantiation; - } - } - - return CodeGenModule::GVA_StrongExternal; -} - CharUnits CodeGenModule::GetTargetTypeStoreSize(const llvm::Type *Ty) const { return CharUnits::fromQuantity( TheTargetData.getTypeStoreSizeInBits(Ty) / Context.getCharWidth()); |