From: Anders Carlsson Date: Wed, 2 Jun 2010 15:44:35 +0000 (+0000) Subject: When building RTTI descriptors for pointer types, we need to get the unqualified... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=abd6b09e3daa4d82b7e8ee6966d7f745fd121835;p=clang 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 --- 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(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;