summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaPseudoObject.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaPseudoObject.cpp')
-rw-r--r--lib/Sema/SemaPseudoObject.cpp131
1 files changed, 123 insertions, 8 deletions
diff --git a/lib/Sema/SemaPseudoObject.cpp b/lib/Sema/SemaPseudoObject.cpp
index b135507..054d557 100644
--- a/lib/Sema/SemaPseudoObject.cpp
+++ b/lib/Sema/SemaPseudoObject.cpp
@@ -153,6 +153,23 @@ namespace {
refExpr->getRBracket());
}
};
+
+ struct MSPropertyRefRebuilder : Rebuilder<MSPropertyRefRebuilder> {
+ Expr *NewBase;
+ MSPropertyRefRebuilder(Sema &S, Expr *newBase)
+ : Rebuilder<MSPropertyRefRebuilder>(S), NewBase(newBase) {}
+
+ typedef MSPropertyRefExpr specific_type;
+ Expr *rebuildSpecific(MSPropertyRefExpr *refExpr) {
+ assert(refExpr->getBaseExpr());
+
+ return new (S.Context)
+ MSPropertyRefExpr(NewBase, refExpr->getPropertyDecl(),
+ refExpr->isArrow(), refExpr->getType(),
+ refExpr->getValueKind(), refExpr->getQualifierLoc(),
+ refExpr->getMemberLoc());
+ }
+ };
class PseudoOpBuilder {
public:
@@ -284,6 +301,18 @@ namespace {
ExprResult buildSet(Expr *op, SourceLocation, bool);
};
+ class MSPropertyOpBuilder : public PseudoOpBuilder {
+ MSPropertyRefExpr *RefExpr;
+
+ public:
+ MSPropertyOpBuilder(Sema &S, MSPropertyRefExpr *refExpr) :
+ PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()),
+ RefExpr(refExpr) {}
+
+ Expr *rebuildAndCaptureObject(Expr *);
+ ExprResult buildGet();
+ ExprResult buildSet(Expr *op, SourceLocation, bool);
+ };
}
/// Capture the given expression in an OpaqueValueExpr.
@@ -412,7 +441,8 @@ PseudoOpBuilder::buildIncDecOperation(Scope *Sc, SourceLocation opcLoc,
QualType resultType = result.get()->getType();
// That's the postfix result.
- if (UnaryOperator::isPostfix(opcode) && CanCaptureValueOfType(resultType)) {
+ if (UnaryOperator::isPostfix(opcode) &&
+ (result.get()->isTypeDependent() || CanCaptureValueOfType(resultType))) {
result = capture(result.take());
setResultToLastSemantic();
}
@@ -633,12 +663,11 @@ ExprResult ObjCPropertyOpBuilder::buildGet() {
assert(InstanceReceiver || RefExpr->isSuperReceiver());
msg = S.BuildInstanceMessageImplicit(InstanceReceiver, receiverType,
GenericLoc, Getter->getSelector(),
- Getter, MultiExprArg());
+ Getter, None);
} else {
msg = S.BuildClassMessageImplicit(receiverType, RefExpr->isSuperReceiver(),
- GenericLoc,
- Getter->getSelector(), Getter,
- MultiExprArg());
+ GenericLoc, Getter->getSelector(),
+ Getter, None);
}
return msg;
}
@@ -1088,8 +1117,7 @@ bool ObjCSubscriptOpBuilder::findAtIndexGetter() {
/*TInfo=*/0,
SC_None,
0);
- AtIndexGetter->setMethodParams(S.Context, Argument,
- ArrayRef<SourceLocation>());
+ AtIndexGetter->setMethodParams(S.Context, Argument, None);
}
if (!AtIndexGetter) {
@@ -1213,7 +1241,7 @@ bool ObjCSubscriptOpBuilder::findAtIndexSetter() {
SC_None,
0);
Params.push_back(key);
- AtIndexSetter->setMethodParams(S.Context, Params, ArrayRef<SourceLocation>());
+ AtIndexSetter->setMethodParams(S.Context, Params, None);
}
if (!AtIndexSetter) {
@@ -1324,6 +1352,77 @@ ExprResult ObjCSubscriptOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
}
//===----------------------------------------------------------------------===//
+// MSVC __declspec(property) references
+//===----------------------------------------------------------------------===//
+
+Expr *MSPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
+ Expr *NewBase = capture(RefExpr->getBaseExpr());
+
+ syntacticBase =
+ MSPropertyRefRebuilder(S, NewBase).rebuild(syntacticBase);
+
+ return syntacticBase;
+}
+
+ExprResult MSPropertyOpBuilder::buildGet() {
+ if (!RefExpr->getPropertyDecl()->hasGetter()) {
+ S.Diag(RefExpr->getMemberLoc(), diag::err_no_getter_for_property)
+ << RefExpr->getPropertyDecl()->getName();
+ return ExprError();
+ }
+
+ UnqualifiedId GetterName;
+ IdentifierInfo *II = RefExpr->getPropertyDecl()->getGetterId();
+ GetterName.setIdentifier(II, RefExpr->getMemberLoc());
+ CXXScopeSpec SS;
+ SS.Adopt(RefExpr->getQualifierLoc());
+ ExprResult GetterExpr = S.ActOnMemberAccessExpr(
+ S.getCurScope(), RefExpr->getBaseExpr(), SourceLocation(),
+ RefExpr->isArrow() ? tok::arrow : tok::period, SS, SourceLocation(),
+ GetterName, 0, true);
+ if (GetterExpr.isInvalid()) {
+ S.Diag(RefExpr->getMemberLoc(), diag::error_cannot_find_suitable_getter)
+ << RefExpr->getPropertyDecl()->getName();
+ return ExprError();
+ }
+
+ MultiExprArg ArgExprs;
+ return S.ActOnCallExpr(S.getCurScope(), GetterExpr.take(),
+ RefExpr->getSourceRange().getBegin(), ArgExprs,
+ RefExpr->getSourceRange().getEnd());
+}
+
+ExprResult MSPropertyOpBuilder::buildSet(Expr *op, SourceLocation sl,
+ bool captureSetValueAsResult) {
+ if (!RefExpr->getPropertyDecl()->hasSetter()) {
+ S.Diag(RefExpr->getMemberLoc(), diag::err_no_setter_for_property)
+ << RefExpr->getPropertyDecl()->getName();
+ return ExprError();
+ }
+
+ UnqualifiedId SetterName;
+ IdentifierInfo *II = RefExpr->getPropertyDecl()->getSetterId();
+ SetterName.setIdentifier(II, RefExpr->getMemberLoc());
+ CXXScopeSpec SS;
+ SS.Adopt(RefExpr->getQualifierLoc());
+ ExprResult SetterExpr = S.ActOnMemberAccessExpr(
+ S.getCurScope(), RefExpr->getBaseExpr(), SourceLocation(),
+ RefExpr->isArrow() ? tok::arrow : tok::period, SS, SourceLocation(),
+ SetterName, 0, true);
+ if (SetterExpr.isInvalid()) {
+ S.Diag(RefExpr->getMemberLoc(), diag::error_cannot_find_suitable_setter)
+ << RefExpr->getPropertyDecl()->getName();
+ return ExprError();
+ }
+
+ SmallVector<Expr*, 1> ArgExprs;
+ ArgExprs.push_back(op);
+ return S.ActOnCallExpr(S.getCurScope(), SetterExpr.take(),
+ RefExpr->getSourceRange().getBegin(), ArgExprs,
+ op->getSourceRange().getEnd());
+}
+
+//===----------------------------------------------------------------------===//
// General Sema routines.
//===----------------------------------------------------------------------===//
@@ -1338,6 +1437,10 @@ ExprResult Sema::checkPseudoObjectRValue(Expr *E) {
= dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
ObjCSubscriptOpBuilder builder(*this, refExpr);
return builder.buildRValueOperation(E);
+ } else if (MSPropertyRefExpr *refExpr
+ = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
+ MSPropertyOpBuilder builder(*this, refExpr);
+ return builder.buildRValueOperation(E);
} else {
llvm_unreachable("unknown pseudo-object kind!");
}
@@ -1360,6 +1463,10 @@ ExprResult Sema::checkPseudoObjectIncDec(Scope *Sc, SourceLocation opcLoc,
} 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);
+ return builder.buildIncDecOperation(Sc, opcLoc, opcode, op);
} else {
llvm_unreachable("unknown pseudo-object kind!");
}
@@ -1389,6 +1496,10 @@ ExprResult Sema::checkPseudoObjectAssignment(Scope *S, SourceLocation opcLoc,
= dyn_cast<ObjCSubscriptRefExpr>(opaqueRef)) {
ObjCSubscriptOpBuilder builder(*this, refExpr);
return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
+ } else if (MSPropertyRefExpr *refExpr
+ = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
+ MSPropertyOpBuilder builder(*this, refExpr);
+ return builder.buildAssignmentOperation(S, opcLoc, opcode, LHS, RHS);
} else {
llvm_unreachable("unknown pseudo-object kind!");
}
@@ -1414,6 +1525,10 @@ static Expr *stripOpaqueValuesFromPseudoObjectRef(Sema &S, Expr *E) {
OpaqueValueExpr *keyOVE = cast<OpaqueValueExpr>(refExpr->getKeyExpr());
return ObjCSubscriptRefRebuilder(S, baseOVE->getSourceExpr(),
keyOVE->getSourceExpr()).rebuild(E);
+ } else if (MSPropertyRefExpr *refExpr
+ = dyn_cast<MSPropertyRefExpr>(opaqueRef)) {
+ OpaqueValueExpr *baseOVE = cast<OpaqueValueExpr>(refExpr->getBaseExpr());
+ return MSPropertyRefRebuilder(S, baseOVE->getSourceExpr()).rebuild(E);
} else {
llvm_unreachable("unknown pseudo-object kind!");
}
OpenPOWER on IntegriCloud