]> granicus.if.org Git - clang/commitdiff
Test linkage of RTTI descriptors of array types.
authorAnders Carlsson <andersca@mac.com>
Tue, 29 Dec 2009 21:58:32 +0000 (21:58 +0000)
committerAnders Carlsson <andersca@mac.com>
Tue, 29 Dec 2009 21:58:32 +0000 (21:58 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92274 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGRTTI.cpp

index fc1098c98589ea3b79f4d9360c2b84aaf7e8d399..8680f71cda7ff8221502fa3348964183d4e302e1 100644 (file)
@@ -367,11 +367,11 @@ public:
     case Type::MemberPointer:
     case Type::FunctionProto:
     case Type::FunctionNoProto:
-      return BuildTypeInfo(Ty);
-
     case Type::ConstantArray:
     case Type::IncompleteArray:
     case Type::VariableArray:
+      return BuildTypeInfo(Ty);
+
     case Type::Vector:
     case Type::ExtVector:
       return BuildSimpleType(Ty, "_ZTVN10__cxxabiv117__array_type_infoE");
@@ -598,7 +598,15 @@ static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(QualType Ty) {
   if (ContainsIncompleteClassType(Ty))
     return llvm::GlobalValue::InternalLinkage;
   
-  if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty)) {
+  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()) == 
@@ -606,9 +614,11 @@ static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(QualType Ty) {
       return llvm::GlobalVariable::InternalLinkage;
     
     return llvm::GlobalVariable::WeakODRLinkage;
+    break;
   }
-    
-  if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
+
+  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.
@@ -630,31 +640,39 @@ static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(QualType Ty) {
     return llvm::GlobalValue::ExternalLinkage;
   }
 
-  if (Ty->getTypeClass() == Type::Builtin) {
+  case Type::Builtin:
     return llvm::GlobalValue::WeakODRLinkage;
-  }
 
-  if (const FunctionType *FT = dyn_cast<FunctionType>(Ty)) {
-    if (getTypeInfoLinkage(FT->getResultType())
-        == llvm::GlobalValue::InternalLinkage)
-      return llvm::GlobalValue::InternalLinkage;
+  case Type::FunctionProto: {
+    const FunctionProtoType *FPT = cast<FunctionProtoType>(Ty);
 
-    if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(Ty)) {
-      for (unsigned i = 0; i < FPT->getNumArgs(); ++i)
-        if (getTypeInfoLinkage(FPT->getArgType(i))
-            == llvm::GlobalValue::InternalLinkage)
-          return llvm::GlobalValue::InternalLinkage;
-      for (unsigned i = 0; i < FPT->getNumExceptions(); ++i)
-        if (getTypeInfoLinkage(FPT->getExceptionType(i))
-            == llvm::GlobalValue::InternalLinkage)
-          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;
     }
-
+    
     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;
+  }
+
+  }
 
-  // FIXME: We need to add code to handle all types.
-  assert(false && "Unhandled type!");
   return llvm::GlobalValue::WeakODRLinkage;
 }
 
@@ -663,7 +681,19 @@ void RTTIBuilder::BuildVtablePointer(const Type *Ty) {
 
   switch (Ty->getTypeClass()) {
   default: assert(0 && "Unhandled type!");
-  
+
+  case Type::ConstantArray:
+  case Type::IncompleteArray:
+    // abi::__array_type_info
+    VtableName = "_ZTVN10__cxxabiv117__array_type_infoE";
+    break;
+
+  case Type::FunctionNoProto:
+  case Type::FunctionProto:
+    // abi::__function_type_info
+    VtableName = "_ZTVN10__cxxabiv120__function_type_infoE";
+    break;
+
   case Type::Record: {
     const CXXRecordDecl *RD = 
       cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
@@ -678,15 +708,11 @@ void RTTIBuilder::BuildVtablePointer(const Type *Ty) {
     // abi::__pointer_type_info
     VtableName = "_ZTVN10__cxxabiv119__pointer_type_infoE";
     break;
+
   case Type::MemberPointer:
     // abi::__pointer_to_member_type_info
     VtableName = "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
     break;
-  
-  case Type::FunctionNoProto:
-  case Type::FunctionProto:
-    // abi::__function_type_info
-    VtableName = "_ZTVN10__cxxabiv120__function_type_infoE";
   }
 
   llvm::Constant *Vtable = 
@@ -734,6 +760,12 @@ llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty) {
     assert(false && "Builtin type info must be in the standard library!");
     break;
 
+  case Type::ConstantArray:
+  case Type::IncompleteArray:
+    // Itanium C++ ABI 2.9.5p4:
+    // abi::__array_type_info adds no data members to std::type_info;
+    break;
+
   case Type::FunctionNoProto:
   case Type::FunctionProto:
     // Itanium C++ ABI 2.9.5p4: