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
This commit is contained in:
John McCall 2011-09-09 06:11:02 +00:00
parent 5d5134014f
commit fec112d50e
3 changed files with 51 additions and 24 deletions

View File

@ -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,

View File

@ -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,

View File

@ -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();