[-cxx-abi microsoft] Emit linkonce_odr definitions for declarations of static data members with inline initializers (PR17689)

This makes Clang emit a linkonce_odr definition for 'val' in the code below,
to be compatible with MSVC-compiled code:

  struct Foo {
    static const int val = 1;
  };

Differential Revision: http://llvm-reviews.chandlerc.com/D2233

llvm-svn: 195283
This commit is contained in:
Hans Wennborg
2013-11-21 00:15:56 +00:00
parent 9c9d7d14d1
commit feedf8515b
4 changed files with 56 additions and 0 deletions

View File

@@ -1607,6 +1607,13 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
CXXThreadLocals.push_back(std::make_pair(D, GV));
setTLSMode(GV, *D);
}
// If required by the ABI, treat declarations of static data members with
// inline initializers as definitions.
if (getCXXABI().isInlineInitializedStaticDataMemberLinkOnce() &&
D->isStaticDataMember() && D->hasInit() &&
!D->isThisDeclarationADefinition())
EmitGlobalVarDefinition(D);
}
if (AddrSpace != Ty->getAddressSpace())
@@ -1860,6 +1867,14 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
llvm::GlobalValue::LinkageTypes Linkage =
GetLLVMLinkageVarDefinition(D, GV->isConstant());
GV->setLinkage(Linkage);
// If required by the ABI, give definitions of static data members with inline
// initializers linkonce_odr linkage.
if (getCXXABI().isInlineInitializedStaticDataMemberLinkOnce() &&
D->isStaticDataMember() && InitExpr &&
!InitDecl->isThisDeclarationADefinition())
GV->setLinkage(llvm::GlobalVariable::LinkOnceODRLinkage);
if (Linkage == llvm::GlobalVariable::CommonLinkage)
// common vars aren't constant even if declared const.
GV->setConstant(false);