aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
authorSteve Naroff <snaroff@apple.com>2009-07-10 23:34:53 +0000
committerSteve Naroff <snaroff@apple.com>2009-07-10 23:34:53 +0000
commit14108da7f7fc059772711e4ffee1322a27b152a7 (patch)
tree5461a189505985c1c245c3f63a48030f0cd5e929 /lib/Sema/SemaOverload.cpp
parent7ecbfbcddd278eede10bd38fa03a95a2110b191a (diff)
This patch includes a conceptually simple, but very intrusive/pervasive change.
The idea is to segregate Objective-C "object" pointers from general C pointers (utilizing the recently added ObjCObjectPointerType). The fun starts in Sema::GetTypeForDeclarator(), where "SomeInterface *" is now represented by a single AST node (rather than a PointerType whose Pointee is an ObjCInterfaceType). Since a significant amount of code assumed ObjC object pointers where based on C pointers/structs, this patch is very tedious. It should also explain why it is hard to accomplish this in smaller, self-contained patches. This patch does most of the "heavy lifting" related to moving from PointerType->ObjCObjectPointerType. It doesn't include all potential "cleanups". The good news is additional cleanups can be done later (some are noted in the code). This patch is so large that I didn't want to include any changes that are purely aesthetic. By making the ObjC types truly built-in, they are much easier to work with (and require fewer "hacks"). For example, there is no need for ASTContext::isObjCIdStructType() or ASTContext::isObjCClassStructType()! We believe this change (and the follow-up cleanups) will pay dividends over time. Given the amount of code change, I do expect some fallout from this change (though it does pass all of the clang tests). If you notice any problems, please let us know asap! Thanks. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@75314 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r--lib/Sema/SemaOverload.cpp126
1 files changed, 57 insertions, 69 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index d10d32c62a..4021e547e1 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -1005,77 +1005,64 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType,
if (!getLangOptions().ObjC1)
return false;
- // Conversions with Objective-C's id<...>.
- if ((FromType->isObjCQualifiedIdType() || ToType->isObjCQualifiedIdType()) &&
- ObjCQualifiedIdTypesAreCompatible(ToType, FromType, /*compare=*/false)) {
- ConvertedType = ToType;
- return true;
- }
+ // First, we handle all conversions on ObjC object pointer types.
+ const ObjCObjectPointerType* ToObjCPtr = ToType->getAsObjCObjectPointerType();
+ const ObjCObjectPointerType *FromObjCPtr =
+ FromType->getAsObjCObjectPointerType();
+
+ if (ToObjCPtr && FromObjCPtr) {
+ // Objective C++: We're able to convert between "id" and a pointer
+ // to any interface (in both directions).
+ if (ToObjCPtr->isObjCIdType() && FromObjCPtr->isObjCIdType()) {
+ ConvertedType = ToType;
+ return true;
+ }
+ // Objective C++: Allow conversions between the Objective-C "Class" and a
+ // pointer to any interface (in both directions).
+ if (ToObjCPtr->isObjCClassType() || FromObjCPtr->isObjCClassType()) {
+ ConvertedType = ToType;
+ return true;
+ }
+ // Conversions with Objective-C's id<...>.
+ if ((FromObjCPtr->isObjCQualifiedIdType() ||
+ ToObjCPtr->isObjCQualifiedIdType()) &&
+ ObjCQualifiedIdTypesAreCompatible(ToType, FromType, /*compare=*/false)) {
+ ConvertedType = ToType;
+ return true;
+ }
+ // Objective C++: We're able to convert from a pointer to an
+ // interface to a pointer to a different interface.
+ if (Context.canAssignObjCInterfaces(ToObjCPtr, FromObjCPtr)) {
+ ConvertedType = ToType;
+ return true;
+ }
- // Beyond this point, both types need to be pointers or block pointers.
+ if (Context.canAssignObjCInterfaces(FromObjCPtr, ToObjCPtr)) {
+ // Okay: this is some kind of implicit downcast of Objective-C
+ // interfaces, which is permitted. However, we're going to
+ // complain about it.
+ IncompatibleObjC = true;
+ ConvertedType = FromType;
+ return true;
+ }
+ }
+ // Beyond this point, both types need to be C pointers or block pointers.
QualType ToPointeeType;
- const PointerType* ToTypePtr = ToType->getAsPointerType();
- if (ToTypePtr)
- ToPointeeType = ToTypePtr->getPointeeType();
+ if (const PointerType *ToCPtr = ToType->getAsPointerType())
+ ToPointeeType = ToCPtr->getPointeeType();
else if (const BlockPointerType *ToBlockPtr = ToType->getAsBlockPointerType())
ToPointeeType = ToBlockPtr->getPointeeType();
else
return false;
QualType FromPointeeType;
- const PointerType *FromTypePtr = FromType->getAsPointerType();
- if (FromTypePtr)
- FromPointeeType = FromTypePtr->getPointeeType();
- else if (const BlockPointerType *FromBlockPtr
- = FromType->getAsBlockPointerType())
+ if (const PointerType *FromCPtr = FromType->getAsPointerType())
+ FromPointeeType = FromCPtr->getPointeeType();
+ else if (const BlockPointerType *FromBlockPtr = FromType->getAsBlockPointerType())
FromPointeeType = FromBlockPtr->getPointeeType();
else
return false;
- // Objective C++: We're able to convert from a pointer to an
- // interface to a pointer to a different interface.
- const ObjCInterfaceType* FromIface = FromPointeeType->getAsObjCInterfaceType();
- const ObjCInterfaceType* ToIface = ToPointeeType->getAsObjCInterfaceType();
- if (FromIface && ToIface &&
- Context.canAssignObjCInterfaces(ToIface, FromIface)) {
- ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
- ToPointeeType,
- ToType, Context);
- return true;
- }
-
- if (FromIface && ToIface &&
- Context.canAssignObjCInterfaces(FromIface, ToIface)) {
- // Okay: this is some kind of implicit downcast of Objective-C
- // interfaces, which is permitted. However, we're going to
- // complain about it.
- IncompatibleObjC = true;
- ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
- ToPointeeType,
- ToType, Context);
- return true;
- }
-
- // Objective C++: We're able to convert between "id" and a pointer
- // to any interface (in both directions).
- if ((FromIface && Context.isObjCIdStructType(ToPointeeType))
- || (ToIface && Context.isObjCIdStructType(FromPointeeType))) {
- ConvertedType = BuildSimilarlyQualifiedPointerType(FromTypePtr,
- ToPointeeType,
- ToType, Context);
- return true;
- }
-
- // Objective C++: Allow conversions between the Objective-C "id" and
- // "Class", in either direction.
- if ((Context.isObjCIdStructType(FromPointeeType) &&
- Context.isObjCClassStructType(ToPointeeType)) ||
- (Context.isObjCClassStructType(FromPointeeType) &&
- Context.isObjCIdStructType(ToPointeeType))) {
- ConvertedType = ToType;
- return true;
- }
-
// If we have pointers to pointers, recursively check whether this
// is an Objective-C conversion.
if (FromPointeeType->isPointerType() && ToPointeeType->isPointerType() &&
@@ -1086,7 +1073,6 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType,
ConvertedType = ToType;
return true;
}
-
// If we have pointers to functions or blocks, check whether the only
// differences in the argument and result types are in Objective-C
// pointer conversions. If so, we permit the conversion (but
@@ -1167,15 +1153,6 @@ bool Sema::CheckPointerConversion(Expr *From, QualType ToType) {
QualType FromPointeeType = FromPtrType->getPointeeType(),
ToPointeeType = ToPtrType->getPointeeType();
- // Objective-C++ conversions are always okay.
- // FIXME: We should have a different class of conversions for the
- // Objective-C++ implicit conversions.
- if (Context.isObjCIdStructType(FromPointeeType) ||
- Context.isObjCIdStructType(ToPointeeType) ||
- Context.isObjCClassStructType(FromPointeeType) ||
- Context.isObjCClassStructType(ToPointeeType))
- return false;
-
if (FromPointeeType->isRecordType() &&
ToPointeeType->isRecordType()) {
// We must have a derived-to-base conversion. Check an
@@ -1185,7 +1162,18 @@ bool Sema::CheckPointerConversion(Expr *From, QualType ToType) {
From->getSourceRange());
}
}
+ if (const ObjCObjectPointerType *FromPtrType =
+ FromType->getAsObjCObjectPointerType())
+ if (const ObjCObjectPointerType *ToPtrType =
+ ToType->getAsObjCObjectPointerType()) {
+ // Objective-C++ conversions are always okay.
+ // FIXME: We should have a different class of conversions for the
+ // Objective-C++ implicit conversions.
+ if (FromPtrType->isObjCIdType() || ToPtrType->isObjCIdType() ||
+ FromPtrType->isObjCClassType() || ToPtrType->isObjCClassType())
+ return false;
+ }
return false;
}