forked from OSchip/llvm-project
[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:
parent
2c8e16d507
commit
6910347f62
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue