EricWF updated this revision to Diff 146065.
EricWF marked 3 inline comments as done.
EricWF added a comment.
Address @rjmccall's comments.
https://reviews.llvm.org/D46665
Files:
lib/CodeGen/ItaniumCXXABI.cpp
test/CodeGenCXX/rtti-linkage.cpp
Index: test/CodeGenCXX/rtti-linkage.cpp
===================================================================
--- test/CodeGenCXX/rtti-linkage.cpp
+++ test/CodeGenCXX/rtti-linkage.cpp
@@ -1,29 +1,31 @@
-// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-BOTH
-// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -fvisibility hidden -emit-llvm -o - | FileCheck -check-prefix=CHECK-WITH-HIDDEN -check-prefix=CHECK-BOTH %s
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -o - | \
+// RUN: FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-BOTH \
+// RUN: -DLINKONCE_VIS_CONSTANT='linkonce_odr constant'
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -fvisibility hidden -emit-llvm -o - | \
+// RUN: FileCheck %s -check-prefix=CHECK-WITH-HIDDEN -check-prefix=CHECK-BOTH \
+// RUN: -DLINKONCE_VIS_CONSTANT='linkonce_odr hidden constant'
#include <typeinfo>
-// CHECK-BOTH: _ZTSP1C = internal constant
-// CHECK-BOTH: _ZTS1C = internal constant
+// CHECK-BOTH: _ZTSP1C = [[LINKONCE_VIS_CONSTANT]]
+// CHECK-BOTH: _ZTS1C = [[LINKONCE_VIS_CONSTANT]]
// CHECK-BOTH: _ZTI1C = internal constant
// CHECK-BOTH: _ZTIP1C = internal constant
-// CHECK-BOTH: _ZTSPP1C = internal constant
+// CHECK-BOTH: _ZTSPP1C = [[LINKONCE_VIS_CONSTANT]]
// CHECK-BOTH: _ZTIPP1C = internal constant
-// CHECK-BOTH: _ZTSM1Ci = internal constant
+// CHECK-BOTH: _ZTSM1Ci = [[LINKONCE_VIS_CONSTANT]]
// CHECK-BOTH: _ZTIM1Ci = internal constant
-// CHECK-BOTH: _ZTSPM1Ci = internal constant
+// CHECK-BOTH: _ZTSPM1Ci = [[LINKONCE_VIS_CONSTANT]]
// CHECK-BOTH: _ZTIPM1Ci = internal constant
-// CHECK-BOTH: _ZTSM1CS_ = internal constant
+// CHECK-BOTH: _ZTSM1CS_ = [[LINKONCE_VIS_CONSTANT]]
// CHECK-BOTH: _ZTIM1CS_ = internal constant
-// CHECK-BOTH: _ZTSM1CPS_ = internal constant
+// CHECK-BOTH: _ZTSM1CPS_ = [[LINKONCE_VIS_CONSTANT]]
// CHECK-BOTH: _ZTIM1CPS_ = internal constant
-// CHECK-BOTH: _ZTSM1A1C = internal constant
-// CHECK: _ZTS1A = linkonce_odr constant
-// CHECK-WITH-HIDDEN: _ZTS1A = linkonce_odr hidden constant
-// CHECK: _ZTI1A = linkonce_odr constant
-// CHECK-WITH-HIDDEN: _ZTI1A = linkonce_odr hidden constant
+// CHECK-BOTH: _ZTSM1A1C = [[LINKONCE_VIS_CONSTANT]]
+// CHECK-BOTH: _ZTS1A = [[LINKONCE_VIS_CONSTANT]]
+// CHECK-BOTH: _ZTI1A = [[LINKONCE_VIS_CONSTANT]]
// CHECK-BOTH: _ZTIM1A1C = internal constant
-// CHECK-BOTH: _ZTSM1AP1C = internal constant
+// CHECK-BOTH: _ZTSM1AP1C = [[LINKONCE_VIS_CONSTANT]]
// CHECK-BOTH: _ZTIM1AP1C = internal constant
// CHECK-WITH-HIDDEN: _ZTSFN12_GLOBAL__N_11DEvE = internal constant
@@ -52,6 +54,12 @@
// CHECK: _ZTSFvvE = linkonce_odr constant
// CHECK: _ZTIFvvE = linkonce_odr constant
// CHECK: _ZTIPFvvE = linkonce_odr constant
+// CHECK: _ZTSPN12_GLOBAL__N_12DIE = internal constant
+// CHECK: _ZTSN12_GLOBAL__N_12DIE = internal constant
+// CHECK: _ZTIN12_GLOBAL__N_12DIE = internal constant
+// CHECK: _ZTIPN12_GLOBAL__N_12DIE = internal constant
+// CHECK: _ZTSMN12_GLOBAL__N_12DIEFvvE = internal constant
+// CHECK: _ZTIMN12_GLOBAL__N_12DIEFvvE = internal constant
// CHECK: _ZTSN12_GLOBAL__N_11EE = internal constant
// CHECK: _ZTIN12_GLOBAL__N_11EE = internal constant
// CHECK: _ZTSA10_i = linkonce_odr constant
@@ -99,9 +107,10 @@
}
namespace {
- // D is inside an anonymous namespace, so all type information related to D should have
- // internal linkage.
+// D and DI are inside an anonymous namespace, so all type information related
+// to both should have internal linkage.
struct D {};
+struct DI;
// E is also inside an anonymous namespace.
enum E {};
@@ -127,6 +136,9 @@
// internal linkage.
(void)typeid(void (*)() throw (D));
+ (void)typeid(DI *);
+ (void)typeid(void (DI::*)());
+
(void)typeid(E);
return typeid(getD());
Index: lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- lib/CodeGen/ItaniumCXXABI.cpp
+++ lib/CodeGen/ItaniumCXXABI.cpp
@@ -3008,20 +3008,10 @@
/// Return the linkage that the type info and type info name constants
/// should have for the given type.
-static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM,
- QualType Ty) {
- // Itanium C++ ABI 2.9.5p7:
- // In addition, it and all of the intermediate abi::__pointer_type_info
- // structs in the chain down to the abi::__class_type_info for the
- // incomplete class type must be prevented from resolving to the
- // corresponding type_info structs for the complete class type, possibly
- // by making them local static objects. Finally, a dummy class RTTI is
- // generated for the incomplete type that will not resolve to the final
- // complete class RTTI (because the latter need not exist), possibly by
- // making it a local static object.
- if (ContainsIncompleteClassType(Ty))
- return llvm::GlobalValue::InternalLinkage;
-
+static std::pair<llvm::GlobalVariable::LinkageTypes,
+ llvm::GlobalVariable::LinkageTypes>
+getTypeInfoLinkage(CodeGenModule &CGM, QualType Ty) {
+ llvm::GlobalValue::LinkageTypes TypeLinkage = [&]() {
switch (Ty->getLinkage()) {
case NoLinkage:
case InternalLinkage:
@@ -3046,7 +3036,7 @@
ShouldUseExternalRTTIDescriptor(CGM, Ty))
return llvm::GlobalValue::ExternalLinkage;
// MinGW always uses LinkOnceODRLinkage for type info.
- if (RD->isDynamicClass() &&
+ if (RD->isCompleteDefinition() && RD->isDynamicClass() &&
!CGM.getContext()
.getTargetInfo()
.getTriple()
@@ -3056,8 +3046,20 @@
return llvm::GlobalValue::LinkOnceODRLinkage;
}
-
llvm_unreachable("Invalid linkage!");
+ }();
+ // Itanium C++ ABI 2.9.5p7:
+ // In addition, it and all of the intermediate abi::__pointer_type_info
+ // structs in the chain down to the abi::__class_type_info for the
+ // incomplete class type must be prevented from resolving to the
+ // corresponding type_info structs for the complete class type, possibly
+ // by making them local static objects. Finally, a dummy class RTTI is
+ // generated for the incomplete type that will not resolve to the final
+ // complete class RTTI (because the latter need not exist), possibly by
+ // making it a local static object.
+ if (ContainsIncompleteClassType(Ty))
+ return {llvm::GlobalValue::InternalLinkage, TypeLinkage};
+ return {TypeLinkage, TypeLinkage};
}
llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force,
@@ -3084,23 +3086,25 @@
return GetAddrOfExternalRTTIDescriptor(Ty);
// Emit the standard library with external linkage.
- llvm::GlobalVariable::LinkageTypes Linkage;
+ llvm::GlobalVariable::LinkageTypes InfoLinkage, NameLinkage;
if (IsStdLib)
- Linkage = llvm::GlobalValue::ExternalLinkage;
- else
- Linkage = getTypeInfoLinkage(CGM, Ty);
-
+ InfoLinkage = NameLinkage = llvm::GlobalValue::ExternalLinkage;
+ else {
+ auto LinkagePair = getTypeInfoLinkage(CGM, Ty);
+ InfoLinkage = LinkagePair.first;
+ NameLinkage = LinkagePair.second;
+ }
// Add the vtable pointer.
BuildVTablePointer(cast<Type>(Ty));
// And the name.
- llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, Linkage);
+ llvm::GlobalVariable *TypeName = GetAddrOfTypeName(Ty, NameLinkage);
llvm::Constant *TypeNameField;
// If we're supposed to demote the visibility, be sure to set a flag
// to use a string comparison for type_info comparisons.
ItaniumCXXABI::RTTIUniquenessKind RTTIUniqueness =
- CXXABI.classifyRTTIUniqueness(Ty, Linkage);
+ CXXABI.classifyRTTIUniqueness(Ty, NameLinkage);
if (RTTIUniqueness != ItaniumCXXABI::RUK_Unique) {
// The flag is the sign bit, which on ARM64 is defined to be clear
// for global pointers. This is very ARM64-specific.
@@ -3206,7 +3210,7 @@
llvm::Module &M = CGM.getModule();
llvm::GlobalVariable *GV =
new llvm::GlobalVariable(M, Init->getType(),
- /*Constant=*/true, Linkage, Init, Name);
+ /*Constant=*/true, InfoLinkage, Init, Name);
// If there's already an old global variable, replace it with the new one.
if (OldGV) {
@@ -3237,19 +3241,20 @@
// Give the type_info object and name the formal visibility of the
// type itself.
- llvm::GlobalValue::VisibilityTypes llvmVisibility;
+ auto computeVisibility = [&](llvm::GlobalValue::LinkageTypes Linkage) {
if (llvm::GlobalValue::isLocalLinkage(Linkage))
// If the linkage is local, only default visibility makes sense.
- llvmVisibility = llvm::GlobalValue::DefaultVisibility;
+ return llvm::GlobalValue::DefaultVisibility;
else if (RTTIUniqueness == ItaniumCXXABI::RUK_NonUniqueHidden)
- llvmVisibility = llvm::GlobalValue::HiddenVisibility;
+ return llvm::GlobalValue::HiddenVisibility;
else
- llvmVisibility = CodeGenModule::GetLLVMVisibility(Ty->getVisibility());
+ return CodeGenModule::GetLLVMVisibility(Ty->getVisibility());
+ };
- TypeName->setVisibility(llvmVisibility);
+ TypeName->setVisibility(computeVisibility(NameLinkage));
CGM.setDSOLocal(TypeName);
- GV->setVisibility(llvmVisibility);
+ GV->setVisibility(computeVisibility(InfoLinkage));
CGM.setDSOLocal(GV);
if (CGM.getTriple().isWindowsItaniumEnvironment()) {
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits