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 | adcc1d18e28f54526c0cd9d904a6fff2db7febcc (patch) | |
| tree | e52a96ebbc9c3582e07c35515abf9ee613dc58e7 /clang/lib | |
| parent | 07943af506491ea77cd85a6983f3c8596d1756c2 (diff) | |
| download | bcm5719-llvm-adcc1d18e28f54526c0cd9d904a6fff2db7febcc.tar.gz bcm5719-llvm-adcc1d18e28f54526c0cd9d904a6fff2db7febcc.zip  | |
When given the magic class __cxxabiv1::__fundamental_type_info, produce
the typeinfo for the fundamental types.
Fixes PR6685.
llvm-svn: 99701
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/CodeGen/CGRTTI.cpp | 69 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 8 | 
3 files changed, 72 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/CGRTTI.cpp b/clang/lib/CodeGen/CGRTTI.cpp index 4aa46e53104..7d284c88523 100644 --- a/clang/lib/CodeGen/CGRTTI.cpp +++ b/clang/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/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 1606710bc5c..c44b3119722 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -79,6 +79,7 @@ void CodeGenModule::createObjCRuntime() {  }  void CodeGenModule::Release() { +  EmitFundamentalRTTIDescriptors();    EmitDeferred();    EmitCXXGlobalInitFunc();    EmitCXXGlobalDtorFunc(); diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 5946a6fd945..e4b0054650f 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/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);  | 

