Index: cfe/trunk/lib/Sema/SemaPseudoObject.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaPseudoObject.cpp +++ cfe/trunk/lib/Sema/SemaPseudoObject.cpp @@ -328,11 +328,12 @@ 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 @@ //===----------------------------------------------------------------------===// 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 @@ 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 @@ 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 */ Index: cfe/trunk/test/CodeGenCXX/ms-property.cpp =================================================================== --- cfe/trunk/test/CodeGenCXX/ms-property.cpp +++ cfe/trunk/test/CodeGenCXX/ms-property.cpp @@ -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; +}