diff options
| author | Alexey Bataev <a.bataev@hotmail.com> | 2015-12-10 04:38:18 +0000 |
|---|---|---|
| committer | Alexey Bataev <a.bataev@hotmail.com> | 2015-12-10 04:38:18 +0000 |
| commit | 60520e22030df6dec13d6618c7be1701c3a3da14 (patch) | |
| tree | 378b9270f95f10b9d6f408992302e9d70598427d /clang/lib/Sema | |
| parent | c2d654322b073df27cb82f1e3e89edddce542197 (diff) | |
| download | bcm5719-llvm-60520e22030df6dec13d6618c7be1701c3a3da14.tar.gz bcm5719-llvm-60520e22030df6dec13d6618c7be1701c3a3da14.zip | |
[MSVC] Fix for http://llvm.org/PR25636: indexed accessor property not supported correctly.
All problems described in http://llvm.org/PR25636 are implemented except for return value of the 'put' property. This patch fixes this problem with the indexed properties
Differential Revision: http://reviews.llvm.org/D15174
llvm-svn: 255218
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/SemaPseudoObject.cpp | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaPseudoObject.cpp b/clang/lib/Sema/SemaPseudoObject.cpp index f94fb17c8b8..e5d51f173ca 100644 --- a/clang/lib/Sema/SemaPseudoObject.cpp +++ b/clang/lib/Sema/SemaPseudoObject.cpp @@ -229,7 +229,7 @@ namespace { } /// Return true if assignments have a non-void result. - bool CanCaptureValue(Expr *exp) { + static bool CanCaptureValue(Expr *exp) { if (exp->isGLValue()) return true; QualType ty = exp->getType(); @@ -245,6 +245,20 @@ namespace { virtual ExprResult buildGet() = 0; virtual ExprResult buildSet(Expr *, SourceLocation, bool captureSetValueAsResult) = 0; + /// \brief Should the result of an assignment be the formal result of the + /// setter call or the value that was passed to the setter? + /// + /// Different pseudo-object language features use different language rules + /// for this. + /// The default is to use the set value. Currently, this affects the + /// behavior of simple assignments, compound assignments, and prefix + /// increment and decrement. + /// Postfix increment and decrement always use the getter result as the + /// expression result. + /// + /// If this method returns true, and the set value isn't capturable for + /// some reason, the result of the expression will be void. + virtual bool captureSetValueAsResult() const { return true; } }; /// A PseudoOpBuilder for Objective-C \@properties. @@ -339,6 +353,7 @@ namespace { Expr *rebuildAndCaptureObject(Expr *) override; ExprResult buildGet() override; ExprResult buildSet(Expr *op, SourceLocation, bool) override; + bool captureSetValueAsResult() const override { return false; } }; } @@ -455,9 +470,12 @@ PseudoOpBuilder::buildAssignmentOperation(Scope *Sc, SourceLocation opcLoc, // The result of the assignment, if not void, is the value set into // the l-value. - result = buildSet(result.get(), opcLoc, /*captureSetValueAsResult*/ true); + result = buildSet(result.get(), opcLoc, captureSetValueAsResult()); if (result.isInvalid()) return ExprError(); addSemanticExpr(result.get()); + if (!captureSetValueAsResult() && !result.get()->getType()->isVoidType() && + (result.get()->isTypeDependent() || CanCaptureValue(result.get()))) + setResultToLastSemantic(); return complete(syntactic); } @@ -499,9 +517,14 @@ PseudoOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc, // Store that back into the result. The value stored is the result // of a prefix operation. - result = buildSet(result.get(), opcLoc, UnaryOperator::isPrefix(opcode)); + result = buildSet(result.get(), opcLoc, UnaryOperator::isPrefix(opcode) && + captureSetValueAsResult()); if (result.isInvalid()) return ExprError(); addSemanticExpr(result.get()); + if (UnaryOperator::isPrefix(opcode) && !captureSetValueAsResult() && + !result.get()->getType()->isVoidType() && + (result.get()->isTypeDependent() || CanCaptureValue(result.get()))) + setResultToLastSemantic(); UnaryOperator *syntactic = new (S.Context) UnaryOperator(syntacticOp, opcode, resultType, |

