From: Douglas Gregor Date: Thu, 27 Nov 2008 01:19:21 +0000 (+0000) Subject: Add implicit conversions for Objective-C qualified ids, e.g., X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7ca09760ee77ad03eac8212e580338bacd46f4d4;p=clang Add implicit conversions for Objective-C qualified ids, e.g., id The intended overloading behavior of these entities isn't entirely clear, and GCC seems to have some strange limitations (e.g., the inability to overload on id vs. id). We'll want to revisit these semantics and determine just how Objective-C++ overloading should really work. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60142 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 43b5e77e87..80bb9eda88 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -744,7 +744,13 @@ BuildSimilarlyQualifiedPointerType(const PointerType *FromPtr, /// might differ from ToType in its cv-qualifiers at some level) into /// ConvertedType. /// -/// This routine also supports conversions to and from block pointers. +/// This routine also supports conversions to and from block pointers +/// and conversions with Objective-C's 'id', 'id', and +/// pointers to interfaces. FIXME: Once we've determined the +/// appropriate overloading rules for Objective-C, we may want to +/// split the Objective-C checks into a different routine; however, +/// GCC seems to consider all of these conversions to be pointer +/// conversions, so for now they live here. bool Sema::IsPointerConversion(Expr *From, QualType FromType, QualType ToType, QualType& ConvertedType) { @@ -761,6 +767,13 @@ bool Sema::IsPointerConversion(Expr *From, QualType FromType, QualType ToType, return true; } + // Conversions with Objective-C's id<...>. + if ((FromType->isObjCQualifiedIdType() || ToType->isObjCQualifiedIdType()) && + ObjCQualifiedIdTypesAreCompatible(ToType, FromType, /*compare=*/false)) { + ConvertedType = ToType; + return true; + } + const PointerType* ToTypePtr = ToType->getAsPointerType(); if (!ToTypePtr) return false; @@ -1332,7 +1345,10 @@ Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1, // Compare based on pointer conversions. if (SCS1.Second == ICK_Pointer_Conversion && - SCS2.Second == ICK_Pointer_Conversion) { + SCS2.Second == ICK_Pointer_Conversion && + /*FIXME: Remove if Objective-C id conversions get their own rank*/ + FromType1->isPointerType() && FromType2->isPointerType() && + ToType1->isPointerType() && ToType2->isPointerType()) { QualType FromPointee1 = FromType1->getAsPointerType()->getPointeeType().getUnqualifiedType(); QualType ToPointee1 diff --git a/test/SemaObjCXX/overload.mm b/test/SemaObjCXX/overload.mm index f4477d36fc..8a42746424 100644 --- a/test/SemaObjCXX/overload.mm +++ b/test/SemaObjCXX/overload.mm @@ -1,10 +1,19 @@ // RUN clang -fsyntax-only -verify %s -@interface A +@protocol P0 +@end + +@protocol P1 +@end + +@interface A @end @interface B : A @end +@interface C +@end + int& f(A*); float& f(B*); void g(A*); @@ -37,3 +46,13 @@ void cv_test(A* a, B* b, const A* ac, const B* bc) { int& i3 = cv2(a); float& f3 = cv2(ac); } + + +int& qualid(id); +float& qualid(id); // FIXME: GCC complains that this isn't an overload. Is it? + +void qualid_test(A *a, B *b, C *c) { + int& i1 = qualid(a); + int& i2 = qualid(b); + float& f1 = qualid(c); +}