aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-07-03 05:51:27 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-07-03 05:51:27 +0000
commit93de4b1608f196e641c44dea839b428cf0fb8cf7 (patch)
treee93ce240cbed24fe060f563d5e2e2f1d16a3d403
parent78b84f5454a044e8d8d6c9d7b028cf98ba608c97 (diff)
downloadllvm-93de4b1608f196e641c44dea839b428cf0fb8cf7.zip
llvm-93de4b1608f196e641c44dea839b428cf0fb8cf7.tar.gz
llvm-93de4b1608f196e641c44dea839b428cf0fb8cf7.tar.bz2
MS ABI: Get linkage of RTTI data correct
The Itanium rules are not appropriate for the MS ABI. RTTI data is _never_ imported and thus is never available_externally. It is either internal (if the type's linkage is internal) or linkonce_odr. This also means that classes which inherit from dllimport'd bases force their translation unit to duplicate the entirety of the RTTI data of that base. Interestingly, the complete object locator can never be referenced by translation units which import the class. This fixes PR20106. llvm-svn: 212256
-rw-r--r--clang/lib/CodeGen/MicrosoftRTTI.cpp19
-rw-r--r--clang/test/CodeGenCXX/dllimport-rtti.cpp13
2 files changed, 30 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/MicrosoftRTTI.cpp b/clang/lib/CodeGen/MicrosoftRTTI.cpp
index 776a161..f539bfb 100644
--- a/clang/lib/CodeGen/MicrosoftRTTI.cpp
+++ b/clang/lib/CodeGen/MicrosoftRTTI.cpp
@@ -230,6 +230,20 @@ uint32_t MSRTTIClass::initialize(const MSRTTIClass *Parent,
return NumBases;
}
+static llvm::GlobalValue::LinkageTypes getLinkageForRTTI(QualType Ty) {
+ switch (Ty->getLinkage()) {
+ case NoLinkage:
+ case InternalLinkage:
+ case UniqueExternalLinkage:
+ return llvm::GlobalValue::InternalLinkage;
+
+ case VisibleNoLinkage:
+ case ExternalLinkage:
+ return llvm::GlobalValue::LinkOnceODRLinkage;
+ }
+ llvm_unreachable("Invalid linkage!");
+}
+
/// \brief An ephemeral helper class for building MS RTTI types. It caches some
/// calls to the module and information about the most derived class in a
/// hierarchy.
@@ -242,7 +256,8 @@ struct MSRTTIBuilder {
MSRTTIBuilder(CodeGenModule &CGM, const CXXRecordDecl *RD)
: CGM(CGM), Context(CGM.getContext()), VMContext(CGM.getLLVMContext()),
- Module(CGM.getModule()), RD(RD), Linkage(CGM.getVTableLinkage(RD)),
+ Module(CGM.getModule()), RD(RD),
+ Linkage(getLinkageForRTTI(CGM.getContext().getTagDeclType(RD))),
Mangler(
cast<MicrosoftMangleContext>(CGM.getCXXABI().getMangleContext())) {}
@@ -499,7 +514,7 @@ llvm::Constant *CodeGenModule::getMSTypeDescriptor(QualType Type) {
return llvm::ConstantExpr::getBitCast(
new llvm::GlobalVariable(
getModule(), TypeDescriptorType, /*Constant=*/false,
- getTypeInfoLinkage(Type),
+ getLinkageForRTTI(Type),
llvm::ConstantStruct::get(TypeDescriptorType, Fields),
MangledName.c_str()),
Int8PtrTy);
diff --git a/clang/test/CodeGenCXX/dllimport-rtti.cpp b/clang/test/CodeGenCXX/dllimport-rtti.cpp
new file mode 100644
index 0000000..7ed7dad
--- /dev/null
+++ b/clang/test/CodeGenCXX/dllimport-rtti.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++1y -O1 -disable-llvm-optzns -o - %s | FileCheck %s
+
+struct __declspec(dllimport) S {
+ virtual void f();
+} s;
+// CHECK-DAG: @"\01??_7S@@6B@" = available_externally dllimport
+// CHECK-DAG: @"\01??_R0?AUS@@@8" = linkonce_odr
+// CHECK-DAG: @"\01??_R1A@?0A@EA@S@@8" = linkonce_odr
+// CHECK-DAG: @"\01??_R2S@@8" = linkonce_odr
+// CHECK-DAG: @"\01??_R3S@@8" = linkonce_odr
+
+struct U : S {
+} u;