From: Anders Carlsson Date: Tue, 29 Dec 2009 22:13:01 +0000 (+0000) Subject: Handle enum types as well. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9c7b6bb952672b9d184a4426138579d55c370afc;p=clang Handle enum types as well. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92276 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp index 8680f71cda..0e3db3a095 100644 --- a/lib/CodeGen/CGRTTI.cpp +++ b/lib/CodeGen/CGRTTI.cpp @@ -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(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(cast(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(cast(Ty)->getDecl()); diff --git a/test/CodeGenCXX/rtti-linkage.cpp b/test/CodeGenCXX/rtti-linkage.cpp index b4caa86229..1050bae7cb 100644 --- a/test/CodeGenCXX/rtti-linkage.cpp +++ b/test/CodeGenCXX/rtti-linkage.cpp @@ -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()); }