mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-24 18:20:38 +00:00
Fix for PR7415: refactor CodeGenModule::MayDeferGeneration and make it less
conservative for static variables in templated classes. llvm-svn: 106385
This commit is contained in:
parent
87233f785b
commit
c96b2496fc
@ -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());
|
||||
|
12
clang/test/CodeGenCXX/template-static-var-defer.cpp
Normal file
12
clang/test/CodeGenCXX/template-static-var-defer.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | not grep define
|
||||
// PR7415
|
||||
class X {
|
||||
template <class Dummy> struct COMTypeInfo {
|
||||
static const int kIID;
|
||||
};
|
||||
static const int& GetIID() {return COMTypeInfo<int>::kIID;}
|
||||
};
|
||||
template <class Dummy> const int X::COMTypeInfo<Dummy>::kIID = 10;
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user