summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaPseudoObject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaPseudoObject.cpp')
-rw-r--r--clang/lib/Sema/SemaPseudoObject.cpp67
1 files changed, 39 insertions, 28 deletions
diff --git a/clang/lib/Sema/SemaPseudoObject.cpp b/clang/lib/Sema/SemaPseudoObject.cpp
index 8a671b14872..a267670cc9b 100644
--- a/clang/lib/Sema/SemaPseudoObject.cpp
+++ b/clang/lib/Sema/SemaPseudoObject.cpp
@@ -190,11 +190,12 @@ namespace {
Sema &S;
unsigned ResultIndex;
SourceLocation GenericLoc;
+ bool IsUnique;
SmallVector<Expr *, 4> Semantics;
- PseudoOpBuilder(Sema &S, SourceLocation genericLoc)
+ PseudoOpBuilder(Sema &S, SourceLocation genericLoc, bool IsUnique)
: S(S), ResultIndex(PseudoObjectExpr::NoResult),
- GenericLoc(genericLoc) {}
+ GenericLoc(genericLoc), IsUnique(IsUnique) {}
virtual ~PseudoOpBuilder() {}
@@ -208,6 +209,9 @@ namespace {
assert(ResultIndex == PseudoObjectExpr::NoResult);
ResultIndex = Semantics.size();
Semantics.push_back(resultExpr);
+ // An OVE is not unique if it is used as the result expression.
+ if (auto *OVE = dyn_cast<OpaqueValueExpr>(Semantics.back()))
+ OVE->setIsUnique(false);
}
ExprResult buildRValueOperation(Expr *op);
@@ -227,6 +231,9 @@ namespace {
void setResultToLastSemantic() {
assert(ResultIndex == PseudoObjectExpr::NoResult);
ResultIndex = Semantics.size() - 1;
+ // An OVE is not unique if it is used as the result expression.
+ if (auto *OVE = dyn_cast<OpaqueValueExpr>(Semantics.back()))
+ OVE->setIsUnique(false);
}
/// Return true if assignments have a non-void result.
@@ -274,10 +281,10 @@ namespace {
Selector GetterSelector;
public:
- ObjCPropertyOpBuilder(Sema &S, ObjCPropertyRefExpr *refExpr) :
- PseudoOpBuilder(S, refExpr->getLocation()), RefExpr(refExpr),
- SyntacticRefExpr(nullptr), InstanceReceiver(nullptr), Getter(nullptr),
- Setter(nullptr) {
+ ObjCPropertyOpBuilder(Sema &S, ObjCPropertyRefExpr *refExpr, bool IsUnique)
+ : PseudoOpBuilder(S, refExpr->getLocation(), IsUnique),
+ RefExpr(refExpr), SyntacticRefExpr(nullptr),
+ InstanceReceiver(nullptr), Getter(nullptr), Setter(nullptr) {
}
ExprResult buildRValueOperation(Expr *op);
@@ -314,11 +321,10 @@ namespace {
Selector AtIndexSetterSelector;
public:
- ObjCSubscriptOpBuilder(Sema &S, ObjCSubscriptRefExpr *refExpr) :
- PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()),
- RefExpr(refExpr),
- InstanceBase(nullptr), InstanceKey(nullptr),
- AtIndexGetter(nullptr), AtIndexSetter(nullptr) {}
+ ObjCSubscriptOpBuilder(Sema &S, ObjCSubscriptRefExpr *refExpr, bool IsUnique)
+ : PseudoOpBuilder(S, refExpr->getSourceRange().getBegin(), IsUnique),
+ RefExpr(refExpr), InstanceBase(nullptr), InstanceKey(nullptr),
+ AtIndexGetter(nullptr), AtIndexSetter(nullptr) {}
ExprResult buildRValueOperation(Expr *op);
ExprResult buildAssignmentOperation(Scope *Sc,
@@ -342,11 +348,11 @@ namespace {
MSPropertyRefExpr *getBaseMSProperty(MSPropertySubscriptExpr *E);
public:
- MSPropertyOpBuilder(Sema &S, MSPropertyRefExpr *refExpr) :
- PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()),
- RefExpr(refExpr), InstanceBase(nullptr) {}
- MSPropertyOpBuilder(Sema &S, MSPropertySubscriptExpr *refExpr)
- : PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()),
+ MSPropertyOpBuilder(Sema &S, MSPropertyRefExpr *refExpr, bool IsUnique)
+ : PseudoOpBuilder(S, refExpr->getSourceRange().getBegin(), IsUnique),
+ RefExpr(refExpr), InstanceBase(nullptr) {}
+ MSPropertyOpBuilder(Sema &S, MSPropertySubscriptExpr *refExpr, bool IsUnique)
+ : PseudoOpBuilder(S, refExpr->getSourceRange().getBegin(), IsUnique),
InstanceBase(nullptr) {
RefExpr = getBaseMSProperty(refExpr);
}
@@ -365,7 +371,9 @@ OpaqueValueExpr *PseudoOpBuilder::capture(Expr *e) {
new (S.Context) OpaqueValueExpr(GenericLoc, e->getType(),
e->getValueKind(), e->getObjectKind(),
e);
-
+ if (IsUnique)
+ captured->setIsUnique(true);
+
// Make sure we bind that in the semantics.
addSemanticExpr(captured);
return captured;
@@ -397,6 +405,8 @@ OpaqueValueExpr *PseudoOpBuilder::captureValueAsResult(Expr *e) {
if (e == Semantics[index]) break;
}
ResultIndex = index;
+ // An OVE is not unique if it is used as the result expression.
+ cast<OpaqueValueExpr>(e)->setIsUnique(false);
return cast<OpaqueValueExpr>(e);
}
@@ -1528,20 +1538,20 @@ ExprResult Sema::checkPseudoObjectRValue(Expr *E) {
Expr *opaqueRef = E->IgnoreParens();
if (ObjCPropertyRefExpr *refExpr
= dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
- ObjCPropertyOpBuilder builder(*this, refExpr);
+ ObjCPropertyOpBuilder builder(*this, refExpr, true);
return builder.buildRValueOperation(E);
}
else if (ObjCSubscriptRefExpr *refExpr
= dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
- ObjCSubscriptOpBuilder builder(*this, refExpr);
+ ObjCSubscriptOpBuilder builder(*this, refExpr, true);
return builder.buildRValueOperation(E);
} else if (MSPropertyRefExpr *refExpr
= dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
- MSPropertyOpBuilder builder(*this, refExpr);
+ MSPropertyOpBuilder builder(*this, refExpr, true);
return builder.buildRValueOperation(E);
} else if (MSPropertySubscriptExpr *RefExpr =
dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
- MSPropertyOpBuilder Builder(*this, RefExpr);
+ MSPropertyOpBuilder Builder(*this, RefExpr, true);
return Builder.buildRValueOperation(E);
} else {
llvm_unreachable("unknown pseudo-object kind!");
@@ -1560,18 +1570,18 @@ ExprResult Sema::checkPseudoObjectIncDec(Scope *Sc, SourceLocation opcLoc,
Expr *opaqueRef = op->IgnoreParens();
if (ObjCPropertyRefExpr *refExpr
= dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
- ObjCPropertyOpBuilder builder(*this, refExpr);
+ ObjCPropertyOpBuilder builder(*this, refExpr, false);
return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
} else if (isa<ObjCSubscriptRefExpr>(opaqueRef)) {
Diag(opcLoc, diag::err_illegal_container_subscripting_op);
return ExprError();
} else if (MSPropertyRefExpr *refExpr
= dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
- MSPropertyOpBuilder builder(*this, refExpr);
+ MSPropertyOpBuilder builder(*this, refExpr, false);
return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
} else if (MSPropertySubscriptExpr *RefExpr
= dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
- MSPropertyOpBuilder Builder(*this, RefExpr);
+ MSPropertyOpBuilder Builder(*this, RefExpr, false);
return Builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
} else {
llvm_unreachable("unknown pseudo-object kind!");
@@ -1594,22 +1604,23 @@ ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc,
RHS = result.get();
}
+ bool IsSimpleAssign = opcode == BO_Assign;
Expr *opaqueRef = LHS->IgnoreParens();
if (ObjCPropertyRefExpr *refExpr
= dyn_cast<ObjCPropertyRefExpr>(opaqueRef)) {
- ObjCPropertyOpBuilder builder(*this, refExpr);
+ ObjCPropertyOpBuilder builder(*this, refExpr, IsSimpleAssign);
return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
} else if (ObjCSubscriptRefExpr *refExpr
= dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
- ObjCSubscriptOpBuilder builder(*this, refExpr);
+ ObjCSubscriptOpBuilder builder(*this, refExpr, IsSimpleAssign);
return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
} else if (MSPropertyRefExpr *refExpr
= dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
- MSPropertyOpBuilder builder(*this, refExpr);
+ MSPropertyOpBuilder builder(*this, refExpr, IsSimpleAssign);
return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
} else if (MSPropertySubscriptExpr *RefExpr
= dyn_cast<MSPropertySubscriptExpr>(opaqueRef)) {
- MSPropertyOpBuilder Builder(*this, RefExpr);
+ MSPropertyOpBuilder Builder(*this, RefExpr, IsSimpleAssign);
return Builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
} else {
llvm_unreachable("unknown pseudo-object kind!");
OpenPOWER on IntegriCloud