summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2015-12-10 04:38:18 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2015-12-10 04:38:18 +0000
commit60520e22030df6dec13d6618c7be1701c3a3da14 (patch)
tree378b9270f95f10b9d6f408992302e9d70598427d /clang/lib/Sema
parentc2d654322b073df27cb82f1e3e89edddce542197 (diff)
downloadbcm5719-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.cpp29
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,
OpenPOWER on IntegriCloud