[MSVC] Fix for http://llvm.org/PR24132: __declspec(property): double invocations of foo() when compiling foo()->propertyName

Removes extra codegen for base expression of MS property call
Differential Revision: http://reviews.llvm.org/D13375

llvm-svn: 250265
This commit is contained in:
Alexey Bataev 2015-10-14 04:05:42 +00:00
parent 2c8e16d507
commit 6910347f62
2 changed files with 31 additions and 11 deletions

View File

@ -328,11 +328,12 @@ namespace {
class MSPropertyOpBuilder : public PseudoOpBuilder {
MSPropertyRefExpr *RefExpr;
OpaqueValueExpr *InstanceBase;
public:
MSPropertyOpBuilder(Sema &S, MSPropertyRefExpr *refExpr) :
PseudoOpBuilder(S, refExpr->getSourceRange().getBegin()),
RefExpr(refExpr) {}
RefExpr(refExpr), InstanceBase(nullptr) {}
Expr *rebuildAndCaptureObject(Expr *) override;
ExprResult buildGet() override;
@ -1400,10 +1401,10 @@ ExprResult ObjCSubscriptOpBuilder::buildSet(Expr *op, SourceLocation opcLoc,
//===----------------------------------------------------------------------===//
Expr *MSPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) {
Expr *NewBase = capture(RefExpr->getBaseExpr());
InstanceBase = capture(RefExpr->getBaseExpr());
syntacticBase =
MSPropertyRefRebuilder(S, NewBase).rebuild(syntacticBase);
MSPropertyRefRebuilder(S, InstanceBase).rebuild(syntacticBase);
return syntacticBase;
}
@ -1420,10 +1421,10 @@ ExprResult MSPropertyOpBuilder::buildGet() {
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, nullptr);
ExprResult GetterExpr =
S.ActOnMemberAccessExpr(S.getCurScope(), InstanceBase, SourceLocation(),
RefExpr->isArrow() ? tok::arrow : tok::period, SS,
SourceLocation(), GetterName, nullptr);
if (GetterExpr.isInvalid()) {
S.Diag(RefExpr->getMemberLoc(),
diag::error_cannot_find_suitable_accessor) << 0 /* getter */
@ -1450,10 +1451,10 @@ ExprResult MSPropertyOpBuilder::buildSet(Expr *op, SourceLocation sl,
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, nullptr);
ExprResult SetterExpr =
S.ActOnMemberAccessExpr(S.getCurScope(), InstanceBase, SourceLocation(),
RefExpr->isArrow() ? tok::arrow : tok::period, SS,
SourceLocation(), SetterName, nullptr);
if (SetterExpr.isInvalid()) {
S.Diag(RefExpr->getMemberLoc(),
diag::error_cannot_find_suitable_accessor) << 1 /* setter */

View File

@ -0,0 +1,19 @@
// RUN: %clang_cc1 -emit-llvm -triple=x86_64-pc-win32 -fms-compatibility %s -o - | FileCheck %s
class Test1 {
private:
int x_;
public:
Test1(int x) : x_(x) {}
__declspec(property(get = get_x)) int X;
int get_x() const { return x_; }
static Test1 *GetTest1() { return new Test1(10); }
};
// CHECK-LABEL: main
int main(int argc, char **argv) {
// CHECK: [[CALL:%.+]] = call %class.Test1* @"\01?GetTest1@Test1@@SAPEAV1@XZ"()
// CHECK-NEXT: call i32 @"\01?get_x@Test1@@QEBAHXZ"(%class.Test1* [[CALL]])
return Test1::GetTest1()->X;
}