aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-10-25 07:27:56 +0000
committerJohn McCall <rjmccall@apple.com>2011-10-25 07:27:56 +0000
commita1b852f8e1bee5ed3604ee483803cef39ce57a20 (patch)
treea660a7efb932f3eab03275702a554a2adcca90ec /lib/Sema/SemaOverload.cpp
parente88c4513157cc551ed8080b1e3b3b875a9a570e1 (diff)
Introduce a placeholder type for "pseudo object"
expressions: expressions which refer to a logical rather than a physical l-value, where the logical object is actually accessed via custom getter/setter code. A subsequent patch will generalize the AST for these so that arbitrary "implementing" sub-expressions can be provided. Right now the only client is ObjC properties, but this should be generalizable to similar language features, e.g. Managed C++'s __property methods. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142914 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r--lib/Sema/SemaOverload.cpp56
1 files changed, 12 insertions, 44 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 44395c59df..f5494dee17 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -575,17 +575,6 @@ namespace {
/// Return true on unrecoverable error.
static bool checkPlaceholderForOverload(Sema &S, Expr *&E,
UnbridgedCastsSet *unbridgedCasts = 0) {
- // ObjCProperty l-values are placeholder-like.
- if (E->getObjectKind() == OK_ObjCProperty) {
- ExprResult result = S.ConvertPropertyForRValue(E);
- if (result.isInvalid())
- return true;
-
- E = result.take();
- return false;
- }
-
- // Handle true placeholders.
if (const BuiltinType *placeholder = E->getType()->getAsPlaceholderType()) {
// We can't handle overloaded expressions here because overload
// resolution might reasonably tweak them.
@@ -1003,6 +992,9 @@ ExprResult
Sema::PerformImplicitConversion(Expr *From, QualType ToType,
AssignmentAction Action, bool AllowExplicit,
ImplicitConversionSequence& ICS) {
+ if (checkPlaceholderForOverload(*this, From))
+ return ExprError();
+
// Objective-C ARC: Determine whether we will allow the writeback conversion.
bool AllowObjCWritebackConversion
= getLangOptions().ObjCAutoRefCount &&
@@ -4086,6 +4078,9 @@ TryContextuallyConvertToBool(Sema &S, Expr *From) {
/// PerformContextuallyConvertToBool - Perform a contextual conversion
/// of the expression From to bool (C++0x [conv]p3).
ExprResult Sema::PerformContextuallyConvertToBool(Expr *From) {
+ if (checkPlaceholderForOverload(*this, From))
+ return ExprError();
+
ImplicitConversionSequence ICS = TryContextuallyConvertToBool(*this, From);
if (!ICS.isBad())
return PerformImplicitConversion(From, Context.BoolTy, ICS, AA_Converting);
@@ -4145,6 +4140,9 @@ TryContextuallyConvertToObjCPointer(Sema &S, Expr *From) {
/// PerformContextuallyConvertToObjCPointer - Perform a contextual
/// conversion of the expression From to an Objective-C pointer type.
ExprResult Sema::PerformContextuallyConvertToObjCPointer(Expr *From) {
+ if (checkPlaceholderForOverload(*this, From))
+ return ExprError();
+
QualType Ty = Context.getObjCIdType();
ImplicitConversionSequence ICS =
TryContextuallyConvertToObjCPointer(*this, From);
@@ -9009,39 +9007,9 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
if (checkPlaceholderForOverload(*this, Args[1]))
return ExprError();
- // The LHS is more complicated.
- if (Args[0]->getObjectKind() == OK_ObjCProperty) {
-
- // There's a tension for assignment operators between primitive
- // property assignment and the overloaded operators.
- if (BinaryOperator::isAssignmentOp(Opc)) {
- const ObjCPropertyRefExpr *PRE = LHS->getObjCProperty();
-
- // Is the property "logically" settable?
- bool Settable = (PRE->isExplicitProperty() ||
- PRE->getImplicitPropertySetter());
-
- // To avoid gratuitously inventing semantics, use the primitive
- // unless it isn't. Thoughts in case we ever really care:
- // - If the property isn't logically settable, we have to
- // load and hope.
- // - If the property is settable and this is simple assignment,
- // we really should use the primitive.
- // - If the property is settable, then we could try overloading
- // on a generic lvalue of the appropriate type; if it works
- // out to a builtin candidate, we would do that same operation
- // on the property, and otherwise just error.
- if (Settable)
- return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
- }
-
- ExprResult Result = ConvertPropertyForRValue(Args[0]);
- if (Result.isInvalid())
- return ExprError();
- Args[0] = Result.take();
- }
-
- // Handle all the other placeholders.
+ // Do placeholder-like conversion on the LHS; note that we should
+ // not get here with a PseudoObject LHS.
+ assert(Args[0]->getObjectKind() != OK_ObjCProperty);
if (checkPlaceholderForOverload(*this, Args[0]))
return ExprError();