diff options
author | John McCall <rjmccall@apple.com> | 2011-10-25 07:27:56 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-10-25 07:27:56 +0000 |
commit | a1b852f8e1bee5ed3604ee483803cef39ce57a20 (patch) | |
tree | a660a7efb932f3eab03275702a554a2adcca90ec /lib/Sema/SemaOverload.cpp | |
parent | e88c4513157cc551ed8080b1e3b3b875a9a570e1 (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.cpp | 56 |
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(); |