[cfe-commits] r91804 - in /cfe/trunk: lib/CodeGen/CGRTTI.cpp test/CodeGenCXX/rtti-layout.cpp test/CodeGenCXX/rtti-linkage.cpp
Anders Carlsson
andersca at mac.com
Sun Dec 20 15:37:56 PST 2009
Author: andersca
Date: Sun Dec 20 17:37:55 2009
New Revision: 91804
URL: http://llvm.org/viewvc/llvm-project?rev=91804&view=rev
Log:
Correcly handle pointers to member pointer types where the class or the pointee is incomplete.
Modified:
cfe/trunk/lib/CodeGen/CGRTTI.cpp
cfe/trunk/test/CodeGenCXX/rtti-layout.cpp
cfe/trunk/test/CodeGenCXX/rtti-linkage.cpp
Modified: cfe/trunk/lib/CodeGen/CGRTTI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGRTTI.cpp?rev=91804&r1=91803&r2=91804&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGRTTI.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGRTTI.cpp Sun Dec 20 17:37:55 2009
@@ -508,16 +508,34 @@
return !RecordTy->getDecl()->isDefinition();
}
-/// IsPointerToIncompleteClassType - Returns whether the given pointer type
+/// ContainsIncompleteClassType - Returns whether the given type contains an
+/// incomplete class type. This is true if
+///
+/// * The given type is an incomplete class type.
+/// * The given type is a pointer type whose pointee type contains an
+/// incomplete class type.
+/// * The given type is a member pointer type whose class is an incomplete
+/// class type.
+/// * The given type is a member pointer type whoise pointee type contains an
+/// incomplete class type.
/// is an indirect or direct pointer to an incomplete class type.
-static bool IsPointerToIncompleteClassType(const PointerType *PointerTy) {
- QualType PointeeTy = PointerTy->getPointeeType();
- while ((PointerTy = dyn_cast<PointerType>(PointeeTy)))
- PointeeTy = PointerTy->getPointeeType();
-
- if (const RecordType *RecordTy = dyn_cast<RecordType>(PointeeTy)) {
- // Check if the record type is incomplete.
- return IsIncompleteClassType(RecordTy);
+static bool ContainsIncompleteClassType(QualType Ty) {
+ if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
+ if (IsIncompleteClassType(RecordTy))
+ return true;
+ }
+
+ if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty))
+ return ContainsIncompleteClassType(PointerTy->getPointeeType());
+
+ if (const MemberPointerType *MemberPointerTy =
+ dyn_cast<MemberPointerType>(Ty)) {
+ // Check if the class type is incomplete.
+ const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
+ if (IsIncompleteClassType(ClassType))
+ return true;
+
+ return ContainsIncompleteClassType(MemberPointerTy->getPointeeType());
}
return false;
@@ -526,34 +544,19 @@
/// getTypeInfoLinkage - Return the linkage that the type info and type info
/// name constants should have for the given type.
static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(QualType Ty) {
- if (const PointerType *PointerTy = dyn_cast<PointerType>(Ty)) {
- // Itanium C++ ABI 2.9.5p7:
- // In addition, it and all of the intermediate abi::__pointer_type_info
- // structs in the chain down to the abi::__class_type_info for the
- // incomplete class type must be prevented from resolving to the
- // corresponding type_info structs for the complete class type, possibly
- // by making them local static objects. Finally, a dummy class RTTI is
- // generated for the incomplete type that will not resolve to the final
- // complete class RTTI (because the latter need not exist), possibly by
- // making it a local static object.
- if (IsPointerToIncompleteClassType(PointerTy))
- return llvm::GlobalValue::InternalLinkage;
+ // Itanium C++ ABI 2.9.5p7:
+ // In addition, it and all of the intermediate abi::__pointer_type_info
+ // structs in the chain down to the abi::__class_type_info for the
+ // incomplete class type must be prevented from resolving to the
+ // corresponding type_info structs for the complete class type, possibly
+ // by making them local static objects. Finally, a dummy class RTTI is
+ // generated for the incomplete type that will not resolve to the final
+ // complete class RTTI (because the latter need not exist), possibly by
+ // making it a local static object.
+ if (ContainsIncompleteClassType(Ty))
+ return llvm::GlobalValue::InternalLinkage;
- // FIXME: Check linkage and anonymous namespace.
- return llvm::GlobalValue::WeakODRLinkage;
- } else if (const MemberPointerType *MemberPointerTy =
- dyn_cast<MemberPointerType>(Ty)) {
- // If the class type is incomplete, then the type info constants should
- // have internal linkage.
- const RecordType *ClassType = cast<RecordType>(MemberPointerTy->getClass());
- if (!ClassType->getDecl()->isDefinition())
- return llvm::GlobalValue::InternalLinkage;
-
- // FIXME: Check linkage and anonymous namespace.
- return llvm::GlobalValue::WeakODRLinkage;
- }
-
- assert(false && "FIXME!");
+ // FIXME: Check linkage and anonymous namespace.
return llvm::GlobalValue::WeakODRLinkage;
}
@@ -664,8 +667,7 @@
/// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct,
/// used for pointer types.
void RTTIBuilder::BuildPointerTypeInfo(const PointerType *Ty) {
- const PointerType *PointerTy = cast<PointerType>(Ty);
- QualType PointeeTy = PointerTy->getPointeeType();
+ QualType PointeeTy = Ty->getPointeeType();
// Itanium C++ ABI 2.9.5p7:
// __flags is a flag word describing the cv-qualification and other
@@ -675,7 +677,7 @@
// 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 (IsPointerToIncompleteClassType(PointerTy))
+ if (ContainsIncompleteClassType(PointeeTy))
Flags |= PTI_Incomplete;
const llvm::Type *UnsignedIntLTy =
@@ -699,12 +701,16 @@
unsigned Flags = DetermineQualifierFlags(PointeeTy.getQualifiers());
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))
+ Flags |= PTI_Incomplete;
+
if (IsIncompleteClassType(ClassType))
Flags |= PTI_ContainingClassIncomplete;
- // FIXME: Handle PTI_Incomplete.
-
const llvm::Type *UnsignedIntLTy =
CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
Info.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Flags));
Modified: cfe/trunk/test/CodeGenCXX/rtti-layout.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/rtti-layout.cpp?rev=91804&r1=91803&r2=91804&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/rtti-layout.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/rtti-layout.cpp Sun Dec 20 17:37:55 2009
@@ -20,17 +20,21 @@
}
struct Incomplete;
-#define CHECK(x) if ((x)) return __LINE__;
+struct A { };
+
+#define CHECK(x) if (!(x)) return __LINE__;
// CHECK: define i32 @_Z1fv()
int f() {
// Pointers to incomplete classes.
- CHECK(to<__pbase_type_info>(typeid(Incomplete *)).__flags != __pbase_type_info::__incomplete_mask);
- CHECK(to<__pbase_type_info>(typeid(Incomplete **)).__flags != __pbase_type_info::__incomplete_mask);
- CHECK(to<__pbase_type_info>(typeid(Incomplete ***)).__flags != __pbase_type_info::__incomplete_mask);
+ CHECK(to<__pbase_type_info>(typeid(Incomplete *)).__flags == __pbase_type_info::__incomplete_mask);
+ CHECK(to<__pbase_type_info>(typeid(Incomplete **)).__flags == __pbase_type_info::__incomplete_mask);
+ CHECK(to<__pbase_type_info>(typeid(Incomplete ***)).__flags == __pbase_type_info::__incomplete_mask);
// Member pointers.
- CHECK(to<__pbase_type_info>(typeid(int Incomplete::*)).__flags != __pbase_type_info::__incomplete_class_mask);
+ CHECK(to<__pbase_type_info>(typeid(int Incomplete::*)).__flags == __pbase_type_info::__incomplete_class_mask);
+ 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));
// Success!
// CHECK: ret i32 0
Modified: cfe/trunk/test/CodeGenCXX/rtti-linkage.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/rtti-linkage.cpp?rev=91804&r1=91803&r2=91804&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/rtti-linkage.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/rtti-linkage.cpp Sun Dec 20 17:37:55 2009
@@ -9,6 +9,19 @@
// CHECK: _ZTIP1C = internal constant
// CHECK: _ZTSPP1C = internal constant
// CHECK: _ZTIPP1C = internal constant
+// CHECK: _ZTSM1Ci = internal constant
+// CHECK: _ZTIM1Ci = internal constant
+// CHECK: _ZTSPM1Ci = internal constant
+// CHECK: _ZTIPM1Ci = internal constant
+// CHECK: _ZTSM1CS_ = internal constant
+// CHECK: _ZTIM1CS_ = internal constant
+// CHECK: _ZTSM1CPS_ = internal constant
+// CHECK: _ZTIM1CPS_ = internal constant
+// CHECK: _ZTSM1A1C = internal constant
+// CHECK: _ZTIM1A1C = internal constant
+// CHECK: _ZTSM1AP1C = internal constant
+// CHECK: _ZTIM1AP1C = internal constant
+
// A has no key function, so its RTTI data should be weak_odr.
struct A { };
@@ -26,6 +39,12 @@
void f() {
(void)typeid(C*);
(void)typeid(C**);
+ (void)typeid(int C::*);
+ (void)typeid(int C::**);
+ (void)typeid(C C::*);
+ (void)typeid(C *C::*);
+ (void)typeid(C A::*);
+ (void)typeid(C* A::*);
}
More information about the cfe-commits
mailing list