Hi rnk,

This makes us 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;
  };

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

Files:
  lib/CodeGen/CodeGenModule.cpp
  test/CodeGenCXX/ms-integer-static-data-members.cpp

Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -1607,6 +1607,12 @@
         CXXThreadLocals.push_back(std::make_pair(D, GV));
       setTLSMode(GV, *D);
     }
+
+    // In the MS ABI, treat declarations of static data members with inline
+    // initializers as definitions.
+    if (getTarget().getCXXABI().isMicrosoft() && D->isStaticDataMember() &&
+        D->hasInit() && !D->isThisDeclarationADefinition())
+      EmitGlobalVarDefinition(D); 
   }
 
   if (AddrSpace != Ty->getAddressSpace())
@@ -1860,6 +1866,13 @@
   llvm::GlobalValue::LinkageTypes Linkage = 
     GetLLVMLinkageVarDefinition(D, GV->isConstant());
   GV->setLinkage(Linkage);
+
+  // In the MS ABI, give definitions of static data members with inline
+  // initializers linkonce_odr linkage.
+  if (getTarget().getCXXABI().isMicrosoft() && 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);
Index: test/CodeGenCXX/ms-integer-static-data-members.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/ms-integer-static-data-members.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -emit-llvm -cxx-abi microsoft -triple=i386-pc-win32 %s -o - 
| FileCheck %s
+// RUN: %clang_cc1 -DREAL_DEFINITION -emit-llvm -cxx-abi microsoft 
-triple=i386-pc-win32 %s -o - | FileCheck %s
+
+struct S {
+  // For MS ABI, we emit a linkonce_odr definition here, even though it's 
really just a declaration.
+  static const int x = 5;
+};
+
+const int *f() {
+  return &S::x;
+};
+
+#ifdef REAL_DEFINITION
+const int S::x;
+#endif
+
+// CHECK: @"\01?x@S@@2HB" = linkonce_odr constant i32 5, align 4
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -1607,6 +1607,12 @@
         CXXThreadLocals.push_back(std::make_pair(D, GV));
       setTLSMode(GV, *D);
     }
+
+    // In the MS ABI, treat declarations of static data members with inline
+    // initializers as definitions.
+    if (getTarget().getCXXABI().isMicrosoft() && D->isStaticDataMember() &&
+        D->hasInit() && !D->isThisDeclarationADefinition())
+      EmitGlobalVarDefinition(D); 
   }
 
   if (AddrSpace != Ty->getAddressSpace())
@@ -1860,6 +1866,13 @@
   llvm::GlobalValue::LinkageTypes Linkage = 
     GetLLVMLinkageVarDefinition(D, GV->isConstant());
   GV->setLinkage(Linkage);
+
+  // In the MS ABI, give definitions of static data members with inline
+  // initializers linkonce_odr linkage.
+  if (getTarget().getCXXABI().isMicrosoft() && 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);
Index: test/CodeGenCXX/ms-integer-static-data-members.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCXX/ms-integer-static-data-members.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -emit-llvm -cxx-abi microsoft -triple=i386-pc-win32 %s -o - | FileCheck %s
+// RUN: %clang_cc1 -DREAL_DEFINITION -emit-llvm -cxx-abi microsoft -triple=i386-pc-win32 %s -o - | FileCheck %s
+
+struct S {
+  // For MS ABI, we emit a linkonce_odr definition here, even though it's really just a declaration.
+  static const int x = 5;
+};
+
+const int *f() {
+  return &S::x;
+};
+
+#ifdef REAL_DEFINITION
+const int S::x;
+#endif
+
+// CHECK: @"\01?x@S@@2HB" = linkonce_odr constant i32 5, align 4 
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to