From fec112d50e801ea624900de5efd4bfd210ce53a4 Mon Sep 17 00:00:00 2001 From: John McCall Date: Fri, 9 Sep 2011 06:11:02 +0000 Subject: [PATCH] Contextually converting to 'id' is not a useful operation. Contextually converting to an arbitrary Objective-C pointer type is. Without significantly re-implementing anything, change the API to reflect this, and as a minor optimization, strip the pointer conversion off before potentially building it. Mostly, this removes a really bizarre-looking bit of code from BuildInstanceMessage. llvm-svn: 139354 --- clang/include/clang/Sema/Sema.h | 2 +- clang/lib/Sema/SemaExprObjC.cpp | 9 ++--- clang/lib/Sema/SemaOverload.cpp | 64 ++++++++++++++++++++++++--------- 3 files changed, 51 insertions(+), 24 deletions(-) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index ef35bc161066..4bdf3802aabd 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/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/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index f6ace99bf6c0..f7f00f3f91b3 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/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(Receiver)) { - Receiver = ICE->getSubExpr(); - ReceiverType = Receiver->getType(); - } return BuildInstanceMessage(Receiver, ReceiverType, SuperLoc, diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index c0b83d9b47ae..1c78b3d11381 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/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'. -static ImplicitConversionSequence -TryContextuallyConvertToObjCId(Sema &S, Expr *From) { - 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); +/// 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]; + } } -/// PerformContextuallyConvertToObjCId - Perform a contextual conversion -/// of the expression From to 'id'. -ExprResult Sema::PerformContextuallyConvertToObjCId(Expr *From) { +/// TryContextuallyConvertToObjCPointer - Attempt to contextually +/// convert the expression From to an Objective-C pointer type. +static ImplicitConversionSequence +TryContextuallyConvertToObjCPointer(Sema &S, Expr *From) { + // Do an implicit conversion to 'id'. + QualType Ty = S.Context.getObjCIdType(); + 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; +} + +/// 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();