Fields.push_back(VTable);
}
+// maybeUpdateRTTILinkage - Will update the linkage of the RTTI data structures
+// from available_externally to the correct linkage if necessary. An example of
+// this is:
+//
+// struct A {
+// virtual void f();
+// };
+//
+// const std::type_info &g() {
+// return typeid(A);
+// }
+//
+// void A::f() { }
+//
+// When we're generating the typeid(A) expression, we do not yet know that
+// A's key function is defined in this translation unit, so we will give the
+// typeinfo and typename structures available_externally linkage. When A::f
+// forces the vtable to be generated, we need to change the linkage of the
+// typeinfo and typename structs, otherwise we'll end up with undefined
+// externals when linking.
+static void
+maybeUpdateRTTILinkage(CodeGenModule &CGM, llvm::GlobalVariable *GV,
+ QualType Ty) {
+ // We're only interested in globals with available_externally linkage.
+ if (!GV->hasAvailableExternallyLinkage())
+ return;
+
+ // Get the real linkage for the type.
+ llvm::GlobalVariable::LinkageTypes Linkage = getTypeInfoLinkage(CGM, Ty);
+
+ // If variable is supposed to have available_externally linkage, we don't
+ // need to do anything.
+ if (Linkage == llvm::GlobalVariable::AvailableExternallyLinkage)
+ return;
+
+ // Update the typeinfo linkage.
+ GV->setLinkage(Linkage);
+
+ // Get the typename global.
+ llvm::SmallString<256> OutName;
+ CGM.getCXXABI().getMangleContext().mangleCXXRTTIName(Ty, OutName);
+ llvm::StringRef Name = OutName.str();
+
+ llvm::GlobalVariable *TypeNameGV = CGM.getModule().getNamedGlobal(Name);
+
+ assert(TypeNameGV->hasAvailableExternallyLinkage() &&
+ "Type name has different linkage from type info!");
+
+ // And update its linkage.
+ TypeNameGV->setLinkage(Linkage);
+}
+
llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) {
// We want to operate on the canonical type.
Ty = CGM.getContext().getCanonicalType(Ty);
llvm::StringRef Name = OutName.str();
llvm::GlobalVariable *OldGV = CGM.getModule().getNamedGlobal(Name);
- if (OldGV && !OldGV->isDeclaration())
+ if (OldGV && !OldGV->isDeclaration()) {
+ maybeUpdateRTTILinkage(CGM, OldGV, Ty);
+
return llvm::ConstantExpr::getBitCast(OldGV, Int8PtrTy);
+ }
// Check if there is already an external RTTI descriptor for this type.
bool IsStdLib = IsStandardLibraryRTTIDescriptor(Ty);
switch (KeyFunction->getTemplateSpecializationKind()) {
case TSK_Undeclared:
case TSK_ExplicitSpecialization:
+ // When compiling with optimizations turned on, we emit all vtables,
+ // even if the key function is not defined in the current translation
+ // unit. If this is the case, use available_externally linkage.
+ if (!Def && CodeGenOpts.OptimizationLevel)
+ return llvm::GlobalVariable::AvailableExternallyLinkage;
+
if (KeyFunction->isInlined())
return llvm::GlobalVariable::LinkOnceODRLinkage;
switch (KeyFunction->getTemplateSpecializationKind()) {
case TSK_Undeclared:
case TSK_ExplicitSpecialization:
+ // The key function is in another translation unit. Mark all of the
+ // virtual members of this class as referenced so that we can build a
+ // vtable anyway (in order to do devirtualization when optimizations
+ // are turned on for example.
+ MarkVirtualMembersReferenced(Loc, Class);
+ continue;
+
case TSK_ExplicitInstantiationDeclaration:
// The key function is in another translation unit.
continue;
--- /dev/null
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -O3 -o %t
+// RUN: FileCheck --check-prefix=CHECK-TEST1 %s < %t
+// RUN: FileCheck --check-prefix=CHECK-TEST2 %s < %t
+
+#include <typeinfo>
+
+// Test1::A's key function (f) is not defined in this translation unit, but in
+// order to devirtualize calls, we emit the class related data with
+// available_externally linkage.
+
+// CHECK-TEST1: @_ZTVN5Test11AE = available_externally
+// CHECK-TEST1: @_ZTSN5Test11AE = available_externally
+// CHECK-TEST1: @_ZTIN5Test11AE = available_externally
+namespace Test1 {
+
+struct A {
+ A();
+ virtual void f();
+ virtual ~A() { }
+};
+
+A::A() { }
+
+void f(A* a) {
+ a->f();
+};
+
+// CHECK: define void @_ZN5Test11gEv
+// CHECK: call void @_ZN5Test11A1fEv
+void g() {
+ A a;
+ f(&a);
+}
+
+}
+
+// Test2::A's key function (f) is defined in this translation unit, but when
+// we're doing codegen for the typeid(A) call, we don't know that yet.
+// This tests mainly that the typeinfo and typename constants have their linkage
+// updated correctly.
+
+// CHECK-TEST2: @_ZTSN5Test21AE = constant
+// CHECK-TEST2: @_ZTIN5Test21AE = unnamed_addr constant
+// CHECK-TEST2: @_ZTVN5Test21AE = unnamed_addr constant
+namespace Test2 {
+ struct A {
+ virtual void f();
+ };
+
+ const std::type_info &g() {
+ return typeid(A);
+ };
+
+ void A::f() { }
+}