diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2010-03-27 02:52:14 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2010-03-27 02:52:14 +0000 |
commit | d1a5c31b78997befe75d10a4731cee4ab211cc31 (patch) | |
tree | 4234bbacc649cd967c56fbeb655acf6aebb60f12 | |
parent | b6e0edc4d0b1cf6315df288ccab6c51c47113398 (diff) |
When given the magic class __cxxabiv1::__fundamental_type_info, produce
the typeinfo for the fundamental types.
Fixes PR6685.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99701 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGRTTI.cpp | 69 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 1 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 8 |
3 files changed, 72 insertions, 6 deletions
diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp index 4aa46e5310..7d284c8852 100644 --- a/lib/CodeGen/CGRTTI.cpp +++ b/lib/CodeGen/CGRTTI.cpp @@ -148,7 +148,7 @@ public: }; /// BuildTypeInfo - Build the RTTI type info struct for the given type. - llvm::Constant *BuildTypeInfo(QualType Ty); + llvm::Constant *BuildTypeInfo(QualType Ty, bool Force = false); }; } @@ -445,6 +445,7 @@ void RTTIBuilder::BuildVtablePointer(const Type *Ty) { default: assert(0 && "Unhandled type!"); // GCC treats vector types as fundamental types. + case Type::Builtin: case Type::Vector: case Type::ExtVector: // abi::__fundamental_type_info. @@ -511,7 +512,7 @@ void RTTIBuilder::BuildVtablePointer(const Type *Ty) { Fields.push_back(Vtable); } -llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty) { +llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) { // We want to operate on the canonical type. Ty = CGM.getContext().getCanonicalType(Ty); @@ -525,7 +526,7 @@ llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty) { return llvm::ConstantExpr::getBitCast(OldGV, Int8PtrTy); // Check if there is already an external RTTI descriptor for this type. - if (ShouldUseExternalRTTIDescriptor(Ty)) + if (!Force && ShouldUseExternalRTTIDescriptor(Ty)) return GetAddrOfExternalRTTIDescriptor(Ty); llvm::GlobalVariable::LinkageTypes Linkage = getTypeInfoLinkage(Ty); @@ -538,11 +539,9 @@ llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty) { switch (Ty->getTypeClass()) { default: assert(false && "Unhandled type class!"); - case Type::Builtin: - assert(false && "Builtin type info must be in the standard library!"); - break; // GCC treats vector types as fundamental types. + case Type::Builtin: case Type::Vector: case Type::ExtVector: // Itanium C++ ABI 2.9.5p4: @@ -854,3 +853,61 @@ llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty) { return RTTIBuilder(*this).BuildTypeInfo(Ty); } + +// Try to find the magic class __cxxabiv1::__fundamental_type_info. If +// exists and has a destructor, we will emit the typeinfo for the fundamental +// types. This is the same behaviour as GCC. +static CXXRecordDecl *FindMagicClass(ASTContext &AC) { + const IdentifierInfo &NamespaceII = AC.Idents.get("__cxxabiv1"); + DeclarationName NamespaceDN = AC.DeclarationNames.getIdentifier(&NamespaceII); + TranslationUnitDecl *TUD = AC.getTranslationUnitDecl(); + DeclContext::lookup_result NamespaceLookup = TUD->lookup(NamespaceDN); + if (NamespaceLookup.first == NamespaceLookup.second) + return NULL; + const NamespaceDecl *Namespace = + dyn_cast<NamespaceDecl>(*NamespaceLookup.first); + if (!Namespace) + return NULL; + + const IdentifierInfo &ClassII = AC.Idents.get("__fundamental_type_info"); + DeclarationName ClassDN = AC.DeclarationNames.getIdentifier(&ClassII); + DeclContext::lookup_const_result ClassLookup = Namespace->lookup(ClassDN); + if (ClassLookup.first == ClassLookup.second) + return NULL; + CXXRecordDecl *Class = dyn_cast<CXXRecordDecl>(*ClassLookup.first); + + if (Class->hasDefinition() && Class->isDynamicClass() && + Class->getDestructor(AC)) + return Class; + + return NULL; +} + +void CodeGenModule::EmitFundamentalRTTIDescriptor(QualType Type) { + QualType PointerType = Context.getPointerType(Type); + QualType PointerTypeConst = Context.getPointerType(Type.withConst()); + RTTIBuilder(*this).BuildTypeInfo(Type, true); + RTTIBuilder(*this).BuildTypeInfo(PointerType, true); + RTTIBuilder(*this).BuildTypeInfo(PointerTypeConst, true); +} + +void CodeGenModule::EmitFundamentalRTTIDescriptors() { + CXXRecordDecl *RD = FindMagicClass(getContext()); + if (!RD) + return; + + getVTables().GenerateClassData(getVtableLinkage(RD), RD); + + QualType FundamentalTypes[] = { Context.VoidTy, Context.Char32Ty, + Context.Char16Ty, Context.UnsignedLongLongTy, + Context.LongLongTy, Context.WCharTy, + Context.UnsignedShortTy, Context.ShortTy, + Context.UnsignedLongTy, Context.LongTy, + Context.UnsignedIntTy, Context.IntTy, + Context.UnsignedCharTy, Context.FloatTy, + Context.LongDoubleTy, Context.DoubleTy, + Context.CharTy, Context.BoolTy, + Context.SignedCharTy }; + for (unsigned i = 0; i < sizeof(FundamentalTypes)/sizeof(QualType); ++i) + EmitFundamentalRTTIDescriptor(FundamentalTypes[i]); +} diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 1606710bc5..c44b311972 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -79,6 +79,7 @@ void CodeGenModule::createObjCRuntime() { } void CodeGenModule::Release() { + EmitFundamentalRTTIDescriptors(); EmitDeferred(); EmitCXXGlobalInitFunc(); EmitCXXGlobalDtorFunc(); diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 5946a6fd94..e4b0054650 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -515,6 +515,14 @@ private: void EmitAnnotations(void); + /// EmitFundamentalRTTIDescriptor - Emit the RTTI descriptors for the + /// given type. + void EmitFundamentalRTTIDescriptor(QualType Type); + + /// EmitFundamentalRTTIDescriptors - Emit the RTTI descriptors for the + /// builtin types. + void EmitFundamentalRTTIDescriptors(); + /// EmitDeferred - Emit any needed decls for which code generation /// was deferred. void EmitDeferred(void); |