diff options
author | Steve Naroff <snaroff@apple.com> | 2009-07-10 23:34:53 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2009-07-10 23:34:53 +0000 |
commit | 14108da7f7fc059772711e4ffee1322a27b152a7 (patch) | |
tree | 5461a189505985c1c245c3f63a48030f0cd5e929 /lib/Sema/SemaOverload.cpp | |
parent | 7ecbfbcddd278eede10bd38fa03a95a2110b191a (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.cpp | 126 |
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; } |