summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CGRTTI.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGRTTI.cpp')
-rw-r--r--lib/CodeGen/CGRTTI.cpp101
1 files changed, 39 insertions, 62 deletions
diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp
index 1caec97..aec1c45 100644
--- a/lib/CodeGen/CGRTTI.cpp
+++ b/lib/CodeGen/CGRTTI.cpp
@@ -31,8 +31,8 @@ class RTTIBuilder {
/// descriptor of the given type.
llvm::Constant *GetAddrOfExternalRTTIDescriptor(QualType Ty);
- /// BuildVtablePointer - Build the vtable pointer for the given type.
- void BuildVtablePointer(const Type *Ty);
+ /// BuildVTablePointer - Build the vtable pointer for the given type.
+ void BuildVTablePointer(const Type *Ty);
/// BuildSIClassTypeInfo - Build an abi::__si_class_type_info, used for single
/// inheritance, according to the Itanium C++ ABI, 2.9.5p6b.
@@ -148,6 +148,9 @@ public:
};
/// BuildTypeInfo - Build the RTTI type info struct for the given type.
+ ///
+ /// \param Force - true to force the creation of this RTTI value
+ /// \param ForEH - true if this is for exception handling
llvm::Constant *BuildTypeInfo(QualType Ty, bool Force = false);
};
}
@@ -242,9 +245,10 @@ static bool TypeInfoIsInStandardLibrary(const PointerType *PointerTy) {
}
/// ShouldUseExternalRTTIDescriptor - Returns whether the type information for
-/// the given type exists somewhere else, and that we should not emit the typ
+/// the given type exists somewhere else, and that we should not emit the type
/// information in this translation unit.
-bool ShouldUseExternalRTTIDescriptor(QualType Ty) {
+static bool ShouldUseExternalRTTIDescriptor(ASTContext &Context,
+ QualType Ty) {
// Type info for builtin types is defined in the standard library.
if (const BuiltinType *BuiltinTy = dyn_cast<BuiltinType>(Ty))
return TypeInfoIsInStandardLibrary(BuiltinTy);
@@ -254,6 +258,9 @@ bool ShouldUseExternalRTTIDescriptor(QualType Ty) {
if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
return TypeInfoIsInStandardLibrary(PointerTy);
+ // If RTTI is disabled, don't consider key functions.
+ if (!Context.getLangOptions().RTTI) return false;
+
if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
if (!RD->hasDefinition())
@@ -337,7 +344,7 @@ static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(QualType Ty) {
if (const RecordType *Record = dyn_cast<RecordType>(Ty)) {
const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
if (RD->isDynamicClass())
- return CodeGenModule::getVtableLinkage(RD);
+ return CodeGenModule::getVTableLinkage(RD);
}
return llvm::GlobalValue::WeakODRLinkage;
@@ -375,8 +382,8 @@ static bool CanUseSingleInheritance(const CXXRecordDecl *RD) {
return true;
}
-void RTTIBuilder::BuildVtablePointer(const Type *Ty) {
- const char *VtableName;
+void RTTIBuilder::BuildVTablePointer(const Type *Ty) {
+ const char *VTableName;
switch (Ty->getTypeClass()) {
default: assert(0 && "Unhandled type!");
@@ -386,24 +393,24 @@ void RTTIBuilder::BuildVtablePointer(const Type *Ty) {
case Type::Vector:
case Type::ExtVector:
// abi::__fundamental_type_info.
- VtableName = "_ZTVN10__cxxabiv123__fundamental_type_infoE";
+ VTableName = "_ZTVN10__cxxabiv123__fundamental_type_infoE";
break;
case Type::ConstantArray:
case Type::IncompleteArray:
// abi::__array_type_info.
- VtableName = "_ZTVN10__cxxabiv117__array_type_infoE";
+ VTableName = "_ZTVN10__cxxabiv117__array_type_infoE";
break;
case Type::FunctionNoProto:
case Type::FunctionProto:
// abi::__function_type_info.
- VtableName = "_ZTVN10__cxxabiv120__function_type_infoE";
+ VTableName = "_ZTVN10__cxxabiv120__function_type_infoE";
break;
case Type::Enum:
// abi::__enum_type_info.
- VtableName = "_ZTVN10__cxxabiv116__enum_type_infoE";
+ VTableName = "_ZTVN10__cxxabiv116__enum_type_infoE";
break;
case Type::Record: {
@@ -412,13 +419,13 @@ void RTTIBuilder::BuildVtablePointer(const Type *Ty) {
if (!RD->hasDefinition() || !RD->getNumBases()) {
// abi::__class_type_info.
- VtableName = "_ZTVN10__cxxabiv117__class_type_infoE";
+ VTableName = "_ZTVN10__cxxabiv117__class_type_infoE";
} else if (CanUseSingleInheritance(RD)) {
// abi::__si_class_type_info.
- VtableName = "_ZTVN10__cxxabiv120__si_class_type_infoE";
+ VTableName = "_ZTVN10__cxxabiv120__si_class_type_infoE";
} else {
// abi::__vmi_class_type_info.
- VtableName = "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
+ VTableName = "_ZTVN10__cxxabiv121__vmi_class_type_infoE";
}
break;
@@ -426,30 +433,31 @@ void RTTIBuilder::BuildVtablePointer(const Type *Ty) {
case Type::Pointer:
// abi::__pointer_type_info.
- VtableName = "_ZTVN10__cxxabiv119__pointer_type_infoE";
+ VTableName = "_ZTVN10__cxxabiv119__pointer_type_infoE";
break;
case Type::MemberPointer:
// abi::__pointer_to_member_type_info.
- VtableName = "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
+ VTableName = "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
break;
}
- llvm::Constant *Vtable =
- CGM.getModule().getOrInsertGlobal(VtableName, Int8PtrTy);
+ llvm::Constant *VTable =
+ CGM.getModule().getOrInsertGlobal(VTableName, Int8PtrTy);
const llvm::Type *PtrDiffTy =
CGM.getTypes().ConvertType(CGM.getContext().getPointerDiffType());
// The vtable address point is 2.
llvm::Constant *Two = llvm::ConstantInt::get(PtrDiffTy, 2);
- Vtable = llvm::ConstantExpr::getInBoundsGetElementPtr(Vtable, &Two, 1);
- Vtable = llvm::ConstantExpr::getBitCast(Vtable, Int8PtrTy);
+ VTable = llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, &Two, 1);
+ VTable = llvm::ConstantExpr::getBitCast(VTable, Int8PtrTy);
- Fields.push_back(Vtable);
+ Fields.push_back(VTable);
}
-llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) {
+llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty,
+ bool Force) {
// We want to operate on the canonical type.
Ty = CGM.getContext().getCanonicalType(Ty);
@@ -463,13 +471,13 @@ llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty, bool Force) {
return llvm::ConstantExpr::getBitCast(OldGV, Int8PtrTy);
// Check if there is already an external RTTI descriptor for this type.
- if (!Force && ShouldUseExternalRTTIDescriptor(Ty))
+ if (!Force && ShouldUseExternalRTTIDescriptor(CGM.getContext(), Ty))
return GetAddrOfExternalRTTIDescriptor(Ty);
llvm::GlobalVariable::LinkageTypes Linkage = getTypeInfoLinkage(Ty);
// Add the vtable pointer.
- BuildVtablePointer(cast<Type>(Ty));
+ BuildVTablePointer(cast<Type>(Ty));
// And the name.
Fields.push_back(BuildName(Ty, DecideHidden(Ty), Linkage));
@@ -782,42 +790,17 @@ void RTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {
Fields.push_back(RTTIBuilder(CGM).BuildTypeInfo(QualType(ClassType, 0)));
}
-llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty) {
- if (!getContext().getLangOptions().RTTI) {
+llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty,
+ bool ForEH) {
+ // Return a bogus pointer if RTTI is disabled, unless it's for EH.
+ // FIXME: should we even be calling this method if RTTI is disabled
+ // and it's not for EH?
+ if (!ForEH && !getContext().getLangOptions().RTTI) {
const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
return llvm::Constant::getNullValue(Int8PtrTy);
}
-
- 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;
+ return RTTIBuilder(*this).BuildTypeInfo(Ty);
}
void CodeGenModule::EmitFundamentalRTTIDescriptor(QualType Type) {
@@ -829,12 +812,6 @@ void CodeGenModule::EmitFundamentalRTTIDescriptor(QualType Type) {
}
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,
OpenPOWER on IntegriCloud