]> granicus.if.org Git - clang/commitdiff
Drastically simplify the computation of linkage for typeinfo by using
authorDouglas Gregor <dgregor@apple.com>
Wed, 31 Mar 2010 00:15:35 +0000 (00:15 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 31 Mar 2010 00:15:35 +0000 (00:15 +0000)
the existing (and already well-tested) linkage computation for types,
with minor tweaks for dynamic classes and (pointers to) incomplete
types. Fixes PR6597.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99968 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGRTTI.cpp
test/CodeGenCXX/rtti-linkage.cpp

index 7d284c885236cae0e15fa33f0ced7ffdfaa375fe..1caec97fc367b760999f4133eb0fdc8350a5658d 100644 (file)
@@ -327,83 +327,20 @@ static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(QualType Ty) {
   if (ContainsIncompleteClassType(Ty))
     return llvm::GlobalValue::InternalLinkage;
   
-  switch (Ty->getTypeClass()) {
-  default:   
-    // FIXME: We need to add code to handle all types.
-    assert(false && "Unhandled type!");
-    break;
-
-  case Type::Pointer: {
-    const PointerType *PointerTy = cast<PointerType>(Ty);
-    // If the pointee type has internal linkage, then the pointer type needs to
-    // have it as well.
-    if (getTypeInfoLinkage(PointerTy->getPointeeType()) == 
-        llvm::GlobalVariable::InternalLinkage)
-      return llvm::GlobalVariable::InternalLinkage;
-    
-    return llvm::GlobalVariable::WeakODRLinkage;
-  }
-
-  case Type::Enum: {
-    const EnumType *EnumTy = cast<EnumType>(Ty);
-    const EnumDecl *ED = EnumTy->getDecl();
-    
-    // If we're in an anonymous namespace, then we always want internal linkage.
-    if (ED->isInAnonymousNamespace() || !ED->hasLinkage())
-      return llvm::GlobalVariable::InternalLinkage;
-    
-    return llvm::GlobalValue::WeakODRLinkage;
-  }
-
-  case Type::Record: {
-    const RecordType *RecordTy = cast<RecordType>(Ty);
-    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
-
-    // If we're in an anonymous namespace, then we always want internal linkage.
-    if (RD->isInAnonymousNamespace() || !RD->hasLinkage())
-      return llvm::GlobalVariable::InternalLinkage;
-
-    // If this class does not have a vtable, we want weak linkage.
-    if (!RD->isDynamicClass())
-      return llvm::GlobalValue::WeakODRLinkage;
-    
-    return CodeGenModule::getVtableLinkage(RD);
-  }
-
-  case Type::Vector:
-  case Type::ExtVector:
-  case Type::Builtin:
-    return llvm::GlobalValue::WeakODRLinkage;
-
-  case Type::FunctionProto: {
-    const FunctionProtoType *FPT = cast<FunctionProtoType>(Ty);
+  switch (Ty->getLinkage()) {
+  case NoLinkage:
+  case InternalLinkage:
+  case UniqueExternalLinkage:
+    return llvm::GlobalValue::InternalLinkage;
 
-    // Check the return type.
-    if (getTypeInfoLinkage(FPT->getResultType()) == 
-        llvm::GlobalValue::InternalLinkage)
-      return llvm::GlobalValue::InternalLinkage;
-    
-    // Check the parameter types.
-    for (unsigned i = 0; i != FPT->getNumArgs(); ++i) {
-      if (getTypeInfoLinkage(FPT->getArgType(i)) == 
-          llvm::GlobalValue::InternalLinkage)
-        return llvm::GlobalValue::InternalLinkage;
+  case ExternalLinkage:
+    if (const RecordType *Record = dyn_cast<RecordType>(Ty)) {
+      const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
+      if (RD->isDynamicClass())
+        return CodeGenModule::getVtableLinkage(RD);
     }
-    
-    return llvm::GlobalValue::WeakODRLinkage;
-  }
-  
-  case Type::ConstantArray: 
-  case Type::IncompleteArray: {
-    const ArrayType *AT = cast<ArrayType>(Ty);
-
-    // Check the element type.
-    if (getTypeInfoLinkage(AT->getElementType()) ==
-        llvm::GlobalValue::InternalLinkage)
-      return llvm::GlobalValue::InternalLinkage;
-  }
 
+    return llvm::GlobalValue::WeakODRLinkage;
   }
 
   return llvm::GlobalValue::WeakODRLinkage;
@@ -444,8 +381,8 @@ void RTTIBuilder::BuildVtablePointer(const Type *Ty) {
   switch (Ty->getTypeClass()) {
   default: assert(0 && "Unhandled type!");
 
-  // GCC treats vector types as fundamental types.
   case Type::Builtin:
+  // GCC treats vector types as fundamental types.
   case Type::Vector:
   case Type::ExtVector:
     // abi::__fundamental_type_info.
index 799c1d41c72616c17bbb2af4bd835ea92d6456db..b9eb5b4ad411313fd24094528512c62756a1c1db 100644 (file)
@@ -92,6 +92,7 @@ const std::type_info &t2() {
   (void)typeid(D *);
   (void)typeid(D (*)());
   (void)typeid(void (*)(D));
+  (void)typeid(void (*)(D&));
   // The exception specification is not part of the RTTI descriptor, so it should not have
   // internal linkage.
   (void)typeid(void (*)() throw (D));