diff options
-rw-r--r-- | include/clang/Sema/Sema.h | 2 | ||||
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 9 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 60 |
3 files changed, 49 insertions, 22 deletions
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index ef35bc1610..4bdf3802aa 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -1387,7 +1387,7 @@ public: CXXMethodDecl *Method); ExprResult PerformContextuallyConvertToBool(Expr *From); - ExprResult PerformContextuallyConvertToObjCId(Expr *From); + ExprResult PerformContextuallyConvertToObjCPointer(Expr *From); ExprResult ConvertToIntegralOrEnumerationType(SourceLocation Loc, Expr *FromE, diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index f6ace99bf6..f7f00f3f91 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -1366,17 +1366,12 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, IsNull ? CK_NullToPointer : CK_IntegralToPointer).take(); } ReceiverType = Receiver->getType(); - } - else { + } else { ExprResult ReceiverRes; if (getLangOptions().CPlusPlus) - ReceiverRes = PerformContextuallyConvertToObjCId(Receiver); + ReceiverRes = PerformContextuallyConvertToObjCPointer(Receiver); if (ReceiverRes.isUsable()) { Receiver = ReceiverRes.take(); - if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Receiver)) { - Receiver = ICE->getSubExpr(); - ReceiverType = Receiver->getType(); - } return BuildInstanceMessage(Receiver, ReceiverType, SuperLoc, diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index c0b83d9b47..1c78b3d113 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -3868,25 +3868,57 @@ ExprResult Sema::PerformContextuallyConvertToBool(Expr *From) { return ExprError(); } -/// TryContextuallyConvertToObjCId - Attempt to contextually convert the -/// expression From to 'id'. +/// dropPointerConversions - If the given standard conversion sequence +/// involves any pointer conversions, remove them. This may change +/// the result type of the conversion sequence. +static void dropPointerConversion(StandardConversionSequence &SCS) { + if (SCS.Second == ICK_Pointer_Conversion) { + SCS.Second = ICK_Identity; + SCS.Third = ICK_Identity; + SCS.ToTypePtrs[2] = SCS.ToTypePtrs[1] = SCS.ToTypePtrs[0]; + } +} + +/// TryContextuallyConvertToObjCPointer - Attempt to contextually +/// convert the expression From to an Objective-C pointer type. static ImplicitConversionSequence -TryContextuallyConvertToObjCId(Sema &S, Expr *From) { +TryContextuallyConvertToObjCPointer(Sema &S, Expr *From) { + // Do an implicit conversion to 'id'. QualType Ty = S.Context.getObjCIdType(); - return TryImplicitConversion(S, From, Ty, - // FIXME: Are these flags correct? - /*SuppressUserConversions=*/false, - /*AllowExplicit=*/true, - /*InOverloadResolution=*/false, - /*CStyle=*/false, - /*AllowObjCWritebackConversion=*/false); + ImplicitConversionSequence ICS + = TryImplicitConversion(S, From, Ty, + // FIXME: Are these flags correct? + /*SuppressUserConversions=*/false, + /*AllowExplicit=*/true, + /*InOverloadResolution=*/false, + /*CStyle=*/false, + /*AllowObjCWritebackConversion=*/false); + + // Strip off any final conversions to 'id'. + switch (ICS.getKind()) { + case ImplicitConversionSequence::BadConversion: + case ImplicitConversionSequence::AmbiguousConversion: + case ImplicitConversionSequence::EllipsisConversion: + break; + + case ImplicitConversionSequence::UserDefinedConversion: + dropPointerConversion(ICS.UserDefined.After); + break; + + case ImplicitConversionSequence::StandardConversion: + dropPointerConversion(ICS.Standard); + break; + } + + return ICS; } -/// PerformContextuallyConvertToObjCId - Perform a contextual conversion -/// of the expression From to 'id'. -ExprResult Sema::PerformContextuallyConvertToObjCId(Expr *From) { +/// PerformContextuallyConvertToObjCPointer - Perform a contextual +/// conversion of the expression From to an Objective-C pointer type. +ExprResult Sema::PerformContextuallyConvertToObjCPointer(Expr *From) { QualType Ty = Context.getObjCIdType(); - ImplicitConversionSequence ICS = TryContextuallyConvertToObjCId(*this, From); + ImplicitConversionSequence ICS = + TryContextuallyConvertToObjCPointer(*this, From); if (!ICS.isBad()) return PerformImplicitConversion(From, Ty, ICS, AA_Converting); return ExprError(); |