EricWF updated this revision to Diff 146053.
EricWF marked an inline comment as done.
EricWF added a comment.

Address @rsmith's inline comments.

- Calculate the linkage for the type name using the linkage for the type.
- Promote the type name visibility for the incomplete class types as well as 
for pointer and member pointers.


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,8 +3008,8 @@
 
 /// \brief 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) {
+static llvm::GlobalVariable::LinkageTypes
+getTypeInfoLinkage(CodeGenModule &CGM, QualType Ty, bool ForName = false) {
   // 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
@@ -3019,9 +3019,15 @@
   //   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))
+  if (ContainsIncompleteClassType(Ty)) {
+    if (!ForName)
       return llvm::GlobalValue::InternalLinkage;
 
+    // Compute the linkage for the type info name for the type name of an
+    // incomplete type, pointer-to-incomplete type, or member-pointer for an
+    // incomplete class type.
+  }
+
   switch (Ty->getLinkage()) {
   case NoLinkage:
   case InternalLinkage:
@@ -3046,7 +3052,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()
@@ -3084,23 +3090,24 @@
     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 {
+    InfoLinkage = getTypeInfoLinkage(CGM, Ty);
+    NameLinkage = getTypeInfoLinkage(CGM, Ty, /*ForName*/ true);
+  }
   // 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, InfoLinkage);
   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 +3213,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 +3244,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
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to