aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Sema/Sema.h2
-rw-r--r--lib/Sema/SemaExprObjC.cpp9
-rw-r--r--lib/Sema/SemaOverload.cpp60
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();