aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2010-06-02 15:44:35 +0000
committerAnders Carlsson <andersca@mac.com>2010-06-02 15:44:35 +0000
commitabd6b09e3daa4d82b7e8ee6966d7f745fd121835 (patch)
treecdae6e239604b93fabfd362936fd8275e46f8948
parentffaa0a94fd62419fd27f2ce120dec9ac74d97e81 (diff)
When building RTTI descriptors for pointer types, we need to get the unqualified array type and the qualifiers from it.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@105326 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CGRTTI.cpp20
-rw-r--r--test/CodeGenCXX/rtti-layout.cpp14
2 files changed, 28 insertions, 6 deletions
diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp
index aec1c4554a..4f058299b0 100644
--- a/lib/CodeGen/CGRTTI.cpp
+++ b/lib/CodeGen/CGRTTI.cpp
@@ -728,15 +728,19 @@ void RTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) {
void RTTIBuilder::BuildPointerTypeInfo(const PointerType *Ty) {
QualType PointeeTy = Ty->getPointeeType();
+ Qualifiers Quals;
+ QualType UnqualifiedPointeeTy =
+ CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals);
+
// Itanium C++ ABI 2.9.5p7:
// __flags is a flag word describing the cv-qualification and other
// attributes of the type pointed to
- unsigned Flags = ComputeQualifierFlags(PointeeTy.getQualifiers());
+ unsigned Flags = ComputeQualifierFlags(Quals);
// Itanium C++ ABI 2.9.5p7:
// When the abi::__pbase_type_info is for a direct or indirect pointer to an
// incomplete class type, the incomplete target type flag is set.
- if (ContainsIncompleteClassType(PointeeTy))
+ if (ContainsIncompleteClassType(UnqualifiedPointeeTy))
Flags |= PTI_Incomplete;
const llvm::Type *UnsignedIntLTy =
@@ -747,7 +751,7 @@ void RTTIBuilder::BuildPointerTypeInfo(const PointerType *Ty) {
// __pointee is a pointer to the std::type_info derivation for the
// unqualified type being pointed to.
llvm::Constant *PointeeTypeInfo =
- RTTIBuilder(CGM).BuildTypeInfo(PointeeTy.getUnqualifiedType());
+ RTTIBuilder(CGM).BuildTypeInfo(UnqualifiedPointeeTy);
Fields.push_back(PointeeTypeInfo);
}
@@ -756,17 +760,21 @@ void RTTIBuilder::BuildPointerTypeInfo(const PointerType *Ty) {
void RTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {
QualType PointeeTy = Ty->getPointeeType();
+ Qualifiers Quals;
+ QualType UnqualifiedPointeeTy =
+ CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals);
+
// Itanium C++ ABI 2.9.5p7:
// __flags is a flag word describing the cv-qualification and other
// attributes of the type pointed to.
- unsigned Flags = ComputeQualifierFlags(PointeeTy.getQualifiers());
+ unsigned Flags = ComputeQualifierFlags(Quals);
const RecordType *ClassType = cast<RecordType>(Ty->getClass());
// Itanium C++ ABI 2.9.5p7:
// When the abi::__pbase_type_info is for a direct or indirect pointer to an
// incomplete class type, the incomplete target type flag is set.
- if (ContainsIncompleteClassType(PointeeTy))
+ if (ContainsIncompleteClassType(UnqualifiedPointeeTy))
Flags |= PTI_Incomplete;
if (IsIncompleteClassType(ClassType))
@@ -780,7 +788,7 @@ void RTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {
// __pointee is a pointer to the std::type_info derivation for the
// unqualified type being pointed to.
llvm::Constant *PointeeTypeInfo =
- RTTIBuilder(CGM).BuildTypeInfo(PointeeTy.getUnqualifiedType());
+ RTTIBuilder(CGM).BuildTypeInfo(UnqualifiedPointeeTy);
Fields.push_back(PointeeTypeInfo);
// Itanium C++ ABI 2.9.5p9:
diff --git a/test/CodeGenCXX/rtti-layout.cpp b/test/CodeGenCXX/rtti-layout.cpp
index 1ad87fbc7e..7128c4e4d0 100644
--- a/test/CodeGenCXX/rtti-layout.cpp
+++ b/test/CodeGenCXX/rtti-layout.cpp
@@ -93,6 +93,14 @@ struct VMI7 : VMIBase1, VMI5, private VMI6 { };
#define CHECK_BASE_INFO_TYPE(type, index, base) CHECK(to<__vmi_class_type_info>(typeid(type)).__base_info[(index)].__base_type == &typeid(base))
#define CHECK_BASE_INFO_OFFSET_FLAGS(type, index, offset, flags) CHECK(to<__vmi_class_type_info>(typeid(type)).__base_info[(index)].__offset_flags == (((offset) << 8) | (flags)))
+struct B {
+ static int const volatile (*a)[10];
+ static int (*b)[10];
+
+ static int const volatile (B::*c)[10];
+ static int (B::*d)[10];
+};
+
// CHECK: define i32 @_Z1fv()
int f() {
// Vectors should be treated as fundamental types.
@@ -168,6 +176,12 @@ int f() {
CHECK(to<__pbase_type_info>(typeid(Incomplete Incomplete::*)).__flags == (__pbase_type_info::__incomplete_class_mask | __pbase_type_info::__incomplete_mask));
CHECK(to<__pbase_type_info>(typeid(Incomplete A::*)).__flags == (__pbase_type_info::__incomplete_mask));
+ // Check that when stripping qualifiers off the pointee type, we correctly handle arrays.
+ CHECK(to<__pbase_type_info>(typeid(B::a)).__flags == (__pbase_type_info::__const_mask | __pbase_type_info::__volatile_mask));
+ CHECK(to<__pbase_type_info>(typeid(B::a)).__pointee == to<__pbase_type_info>(typeid(B::b)).__pointee);
+ CHECK(to<__pbase_type_info>(typeid(B::c)).__flags == (__pbase_type_info::__const_mask | __pbase_type_info::__volatile_mask));
+ CHECK(to<__pbase_type_info>(typeid(B::c)).__pointee == to<__pbase_type_info>(typeid(B::d)).__pointee);
+
// Success!
// CHECK: ret i32 0
return 0;