aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGRTTI.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-12-29 21:58:32 +0000
committerAnders Carlsson <andersca@mac.com>2009-12-29 21:58:32 +0000
commit978ef68bc4cde1448a1f6c8ab0e20543cec1a486 (patch)
tree1d32c5f47d503ac64139c87719ade97032326bee /lib/CodeGen/CGRTTI.cpp
parent09b6e6e8854cc4a824060101a9633082e55d7a33 (diff)
Test linkage of RTTI descriptors of array types.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92274 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGRTTI.cpp')
-rw-r--r--lib/CodeGen/CGRTTI.cpp90
1 files changed, 61 insertions, 29 deletions
diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp
index fc1098c985..8680f71cda 100644
--- a/lib/CodeGen/CGRTTI.cpp
+++ b/lib/CodeGen/CGRTTI.cpp
@@ -367,11 +367,11 @@ public:
case Type::MemberPointer:
case Type::FunctionProto:
case Type::FunctionNoProto:
- return BuildTypeInfo(Ty);
-
case Type::ConstantArray:
case Type::IncompleteArray:
case Type::VariableArray:
+ return BuildTypeInfo(Ty);
+
case Type::Vector:
case Type::ExtVector:
return BuildSimpleType(Ty, "_ZTVN10__cxxabiv117__array_type_infoE");
@@ -598,7 +598,15 @@ static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(QualType Ty) {
if (ContainsIncompleteClassType(Ty))
return llvm::GlobalValue::InternalLinkage;
- if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty)) {
+ 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()) ==
@@ -606,9 +614,11 @@ static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(QualType Ty) {
return llvm::GlobalVariable::InternalLinkage;
return llvm::GlobalVariable::WeakODRLinkage;
+ break;
}
-
- if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
+
+ 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.
@@ -630,31 +640,39 @@ static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(QualType Ty) {
return llvm::GlobalValue::ExternalLinkage;
}
- if (Ty->getTypeClass() == Type::Builtin) {
+ case Type::Builtin:
return llvm::GlobalValue::WeakODRLinkage;
- }
- if (const FunctionType *FT = dyn_cast<FunctionType>(Ty)) {
- if (getTypeInfoLinkage(FT->getResultType())
- == llvm::GlobalValue::InternalLinkage)
- return llvm::GlobalValue::InternalLinkage;
+ case Type::FunctionProto: {
+ const FunctionProtoType *FPT = cast<FunctionProtoType>(Ty);
- if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(Ty)) {
- for (unsigned i = 0; i < FPT->getNumArgs(); ++i)
- if (getTypeInfoLinkage(FPT->getArgType(i))
- == llvm::GlobalValue::InternalLinkage)
- return llvm::GlobalValue::InternalLinkage;
- for (unsigned i = 0; i < FPT->getNumExceptions(); ++i)
- if (getTypeInfoLinkage(FPT->getExceptionType(i))
- == llvm::GlobalValue::InternalLinkage)
- 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;
}
-
+
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;
+ }
+
+ }
- // FIXME: We need to add code to handle all types.
- assert(false && "Unhandled type!");
return llvm::GlobalValue::WeakODRLinkage;
}
@@ -663,7 +681,19 @@ void RTTIBuilder::BuildVtablePointer(const Type *Ty) {
switch (Ty->getTypeClass()) {
default: assert(0 && "Unhandled type!");
-
+
+ case Type::ConstantArray:
+ case Type::IncompleteArray:
+ // abi::__array_type_info
+ VtableName = "_ZTVN10__cxxabiv117__array_type_infoE";
+ break;
+
+ case Type::FunctionNoProto:
+ case Type::FunctionProto:
+ // abi::__function_type_info
+ VtableName = "_ZTVN10__cxxabiv120__function_type_infoE";
+ break;
+
case Type::Record: {
const CXXRecordDecl *RD =
cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
@@ -678,15 +708,11 @@ void RTTIBuilder::BuildVtablePointer(const Type *Ty) {
// abi::__pointer_type_info
VtableName = "_ZTVN10__cxxabiv119__pointer_type_infoE";
break;
+
case Type::MemberPointer:
// abi::__pointer_to_member_type_info
VtableName = "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
break;
-
- case Type::FunctionNoProto:
- case Type::FunctionProto:
- // abi::__function_type_info
- VtableName = "_ZTVN10__cxxabiv120__function_type_infoE";
}
llvm::Constant *Vtable =
@@ -734,6 +760,12 @@ llvm::Constant *RTTIBuilder::BuildTypeInfo(QualType Ty) {
assert(false && "Builtin type info must be in the standard library!");
break;
+ case Type::ConstantArray:
+ case Type::IncompleteArray:
+ // Itanium C++ ABI 2.9.5p4:
+ // abi::__array_type_info adds no data members to std::type_info;
+ break;
+
case Type::FunctionNoProto:
case Type::FunctionProto:
// Itanium C++ ABI 2.9.5p4: