diff options
Diffstat (limited to 'lib/Sema/SemaPseudoObject.cpp')
-rw-r--r-- | lib/Sema/SemaPseudoObject.cpp | 131 |
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!"); } |