r195283 - [-cxx-abi microsoft] Emit linkonce_odr definitions for declarations of static data members with inline initializers (PR17689)
Hans Wennborg
hans at hanshq.net
Wed Nov 20 16:15:56 PST 2013
Author: hans
Date: Wed Nov 20 18:15:56 2013
New Revision: 195283
URL: http://llvm.org/viewvc/llvm-project?rev=195283&view=rev
Log:
[-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
Added:
cfe/trunk/test/CodeGenCXX/ms-integer-static-data-members.cpp
Modified:
cfe/trunk/lib/CodeGen/CGCXXABI.h
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
Modified: cfe/trunk/lib/CodeGen/CGCXXABI.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXXABI.h?rev=195283&r1=195282&r2=195283&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXXABI.h (original)
+++ cfe/trunk/lib/CodeGen/CGCXXABI.h Wed Nov 20 18:15:56 2013
@@ -373,6 +373,10 @@ public:
/// Gets the deleted virtual member call name.
virtual StringRef GetDeletedVirtualCallName() = 0;
+ /// \brief Returns true iff static data members that are initialized in the
+ /// class definition should have linkonce linkage.
+ virtual bool isInlineInitializedStaticDataMemberLinkOnce() { return false; }
+
/**************************** Array cookies ******************************/
/// Returns the extra size required in order to store the array
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=195283&r1=195282&r2=195283&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Wed Nov 20 18:15:56 2013
@@ -1607,6 +1607,13 @@ CodeGenModule::GetOrCreateLLVMGlobal(Str
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::EmitGlobalVarDefinit
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);
Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=195283&r1=195282&r2=195283&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Wed Nov 20 18:15:56 2013
@@ -50,6 +50,8 @@ public:
// arbitrary.
StringRef GetDeletedVirtualCallName() { return "_purecall"; }
+ bool isInlineInitializedStaticDataMemberLinkOnce() { return true; }
+
llvm::Value *adjustToCompleteObject(CodeGenFunction &CGF,
llvm::Value *ptr,
QualType type);
Added: cfe/trunk/test/CodeGenCXX/ms-integer-static-data-members.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/ms-integer-static-data-members.cpp?rev=195283&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/ms-integer-static-data-members.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/ms-integer-static-data-members.cpp Wed Nov 20 18:15:56 2013
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -emit-llvm -cxx-abi microsoft -triple=i386-pc-win32 %s -o - | FileCheck %s
+// RUN: %clang_cc1 -DINLINE_INIT -emit-llvm -cxx-abi microsoft -triple=i386-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK-INLINE
+// RUN: %clang_cc1 -DREAL_DEFINITION -emit-llvm -cxx-abi microsoft -triple=i386-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK-OUTOFLINE
+// RUN: %clang_cc1 -DINLINE_INIT -DREAL_DEFINITION -emit-llvm -cxx-abi microsoft -triple=i386-pc-win32 %s -o - | FileCheck %s --check-prefix=CHECK-INLINE
+
+struct S {
+ // For MS ABI, we emit a linkonce_odr definition here, even though it's really just a declaration.
+#ifdef INLINE_INIT
+ static const int x = 5;
+#else
+ static const int x;
+#endif
+};
+
+const int *f() {
+ return &S::x;
+};
+
+#ifdef REAL_DEFINITION
+#ifdef INLINE_INIT
+const int S::x;
+#else
+const int S::x = 5;
+#endif
+#endif
+
+
+// Inline initialization.
+// CHECK-INLINE: @"\01?x at S@@2HB" = linkonce_odr constant i32 5, align 4
+
+// Out-of-line initialization.
+// CHECK-OUTOFLINE: @"\01?x at S@@2HB" = constant i32 5, align 4
+
+// No initialization.
+// CHECK: @"\01?x at S@@2HB" = external constant i32
More information about the cfe-commits
mailing list