diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-04-02 08:55:10 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-04-02 08:55:10 +0000 |
commit | 07b2cfcdb817cc0790420f159a313d61e7241cb9 (patch) | |
tree | d374cdca417e76f1bf101f139dba2db1d10ee8f7 /lib/CodeGen/CGRTTI.cpp | |
parent | 1e255aab650a7fa2047fd953cae65b12215280af (diff) | |
download | FreeBSD-src-07b2cfcdb817cc0790420f159a313d61e7241cb9.zip FreeBSD-src-07b2cfcdb817cc0790420f159a313d61e7241cb9.tar.gz |
Update clang to r100181.
Diffstat (limited to 'lib/CodeGen/CGRTTI.cpp')
-rw-r--r-- | lib/CodeGen/CGRTTI.cpp | 156 |
1 files changed, 75 insertions, 81 deletions
diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp index 4907223..1caec97 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); }; } @@ -327,83 +327,20 @@ static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(QualType Ty) { if (ContainsIncompleteClassType(Ty)) return llvm::GlobalValue::InternalLinkage; - 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()) == - llvm::GlobalVariable::InternalLinkage) - return llvm::GlobalVariable::InternalLinkage; - - return llvm::GlobalVariable::WeakODRLinkage; - } - - 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: { - 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. - if (RD->isInAnonymousNamespace() || !RD->hasLinkage()) - return llvm::GlobalVariable::InternalLinkage; - - // If this class does not have a vtable, we want weak linkage. - if (!RD->isDynamicClass()) - return llvm::GlobalValue::WeakODRLinkage; - - return CodeGenModule::getVtableLinkage(RD); - } - - case Type::Vector: - case Type::ExtVector: - case Type::Builtin: - return llvm::GlobalValue::WeakODRLinkage; - - case Type::FunctionProto: { - const FunctionProtoType *FPT = cast<FunctionProtoType>(Ty); + switch (Ty->getLinkage()) { + case NoLinkage: + case InternalLinkage: + case UniqueExternalLinkage: + 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; + case ExternalLinkage: + if (const RecordType *Record = dyn_cast<RecordType>(Ty)) { + const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl()); + if (RD->isDynamicClass()) + return CodeGenModule::getVtableLinkage(RD); } - - 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; - } + return llvm::GlobalValue::WeakODRLinkage; } return llvm::GlobalValue::WeakODRLinkage; @@ -444,6 +381,7 @@ void RTTIBuilder::BuildVtablePointer(const Type *Ty) { switch (Ty->getTypeClass()) { default: assert(0 && "Unhandled type!"); + case Type::Builtin: // GCC treats vector types as fundamental types. case Type::Vector: case Type::ExtVector: @@ -511,7 +449,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 +463,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 +476,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: @@ -760,7 +696,7 @@ void RTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) { // subobject. For a virtual base, this is the offset in the virtual table of // the virtual base offset for the virtual base referenced (negative). if (Base->isVirtual()) - OffsetFlags = CGM.getVtableInfo().getVirtualBaseOffsetOffset(RD, BaseDecl); + OffsetFlags = CGM.getVTables().getVirtualBaseOffsetOffset(RD, BaseDecl); else { const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD); OffsetFlags = Layout.getBaseClassOffset(BaseDecl) / 8; @@ -854,3 +790,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]); +} |