]> granicus.if.org Git - clang/commitdiff
Handle enum types as well.
authorAnders Carlsson <andersca@mac.com>
Tue, 29 Dec 2009 22:13:01 +0000 (22:13 +0000)
committerAnders Carlsson <andersca@mac.com>
Tue, 29 Dec 2009 22:13:01 +0000 (22:13 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92276 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 8680f71cda7ff8221502fa3348964183d4e302e1..0e3db3a09553dd8ddaedfc3be8e91f64935b5731 100644 (file)
@@ -370,13 +370,12 @@ public:
     case Type::ConstantArray:
     case Type::IncompleteArray:
     case Type::VariableArray:
+    case Type::Enum:
       return BuildTypeInfo(Ty);
 
     case Type::Vector:
     case Type::ExtVector:
       return BuildSimpleType(Ty, "_ZTVN10__cxxabiv117__array_type_infoE");
-    case Type::Enum:
-      return BuildSimpleType(Ty, "_ZTVN10__cxxabiv116__enum_type_infoE");
     }
   }
   
@@ -614,7 +613,17 @@ static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(QualType Ty) {
       return llvm::GlobalVariable::InternalLinkage;
     
     return llvm::GlobalVariable::WeakODRLinkage;
-    break;
+  }
+
+  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: {
@@ -694,6 +703,11 @@ void RTTIBuilder::BuildVtablePointer(const Type *Ty) {
     VtableName = "_ZTVN10__cxxabiv120__function_type_infoE";
     break;
 
+  case Type::Enum:
+    // abi::__enum_type_info
+    VtableName = "_ZTVN10__cxxabiv116__enum_type_infoE";
+    break;
+      
   case Type::Record: {
     const CXXRecordDecl *RD = 
       cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
@@ -772,6 +786,11 @@ llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty) {
     // abi::__function_type_info adds no data members to std::type_info;
     break;
 
+  case Type::Enum:
+    // Itanium C++ ABI 2.9.5p4:
+    // abi::__enum_type_info adds no data members to std::type_info;
+    break;
+
   case Type::Record: {
     const CXXRecordDecl *RD = 
       cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
index b4caa8622907815da1a3c82a865554c57a75756a..1050bae7cbb8fff88129f72c74f57949d2de4736 100644 (file)
@@ -38,6 +38,9 @@
 // CHECK: _ZTIFvvE = weak_odr
 // CHECK: _ZTIPFvvE = weak_odr constant
 
+// CHECK: _ZTSN12_GLOBAL__N_11EE = internal constant
+// CHECK: _ZTIN12_GLOBAL__N_11EE = internal constant
+
 // A has no key function, so its RTTI data should be weak_odr.
 struct A { };
 
@@ -67,6 +70,10 @@ namespace {
   // D is inside an anonymous namespace, so all type information related to D should have
   // internal linkage.
   struct D { };
+  
+  // E is also inside an anonymous namespace.
+  enum E { };
+  
 };
 
 const D getD();
@@ -80,6 +87,8 @@ const std::type_info &t2() {
   // internal linkage.
   (void)typeid(void (*)() throw (D));
   
+  (void)typeid(E);
+  
   // CHECK: _ZTIN12_GLOBAL__N_11DE to
   return typeid(getD());  
 }