From f51dc64f90851f636302dbaaf3f52c0524cdac36 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Wed, 21 Oct 2009 23:45:42 +0000 Subject: [PATCH] Code gen for '.*' binary expressions - WIP. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84800 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGExprScalar.cpp | 27 +++++++++++++++++++++++++++ test/CodeGenCXX/ptr-to-datamember.cpp | 4 ++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index c3598edd8b..0042754f98 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -106,6 +106,8 @@ public: return 0; } Value *VisitExpr(Expr *S); + Value *VisitPointerToDataMemberBinaryExpr(const BinaryOperator *BExpr); + Value *VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr()); } // Leaves. @@ -536,12 +538,37 @@ EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src, //===----------------------------------------------------------------------===// Value *ScalarExprEmitter::VisitExpr(Expr *E) { + if (const BinaryOperator *BExpr = dyn_cast(E)) + if (BExpr->getOpcode() == BinaryOperator::PtrMemD) + return VisitPointerToDataMemberBinaryExpr(BExpr); + CGF.ErrorUnsupported(E, "scalar expression"); if (E->getType()->isVoidType()) return 0; return llvm::UndefValue::get(CGF.ConvertType(E->getType())); } +Value *ScalarExprEmitter::VisitPointerToDataMemberBinaryExpr( + const BinaryOperator *E) { + Value *BaseV = EmitLValue(E->getLHS()).getAddress(); + const llvm::Type *i8Ty = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); + BaseV = Builder.CreateBitCast(BaseV, i8Ty); + Value *OffsetV = EmitLoadOfLValue(E->getRHS()); + const llvm::Type* ResultType = ConvertType( + CGF.getContext().getPointerDiffType()); + OffsetV = Builder.CreateBitCast(OffsetV, ResultType); + Value *AddV = Builder.CreateInBoundsGEP(BaseV, OffsetV, "add.ptr"); + QualType Ty = E->getRHS()->getType(); + const MemberPointerType *MemPtrType = Ty->getAs(); + Ty = MemPtrType->getPointeeType(); + const llvm::Type* PType = + ConvertType(CGF.getContext().getPointerType(Ty)); + AddV = Builder.CreateBitCast(AddV, PType); + LValue LV = LValue::MakeAddr(AddV, CGF.MakeQualifiers(Ty)); + Value *InVal = CGF.EmitLoadOfLValue(LV, Ty).getScalarVal(); + return InVal; +} + Value *ScalarExprEmitter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) { llvm::SmallVector indices; for (unsigned i = 2; i < E->getNumSubExprs(); i++) { diff --git a/test/CodeGenCXX/ptr-to-datamember.cpp b/test/CodeGenCXX/ptr-to-datamember.cpp index 7e945a20dc..b0d7ddc779 100644 --- a/test/CodeGenCXX/ptr-to-datamember.cpp +++ b/test/CodeGenCXX/ptr-to-datamember.cpp @@ -19,6 +19,7 @@ struct B1 : virtual V{ class A : public B, public B1 { public: + A() : f(1.0), d(2.0), Ai(3) {} float f; double d; int Ai; @@ -38,6 +39,5 @@ int main() printf("%d\n", &A::B1::iV); printf("%d\n", &A::B::V::iV); printf("%d\n", &A::B1::V::iV); - // FIXME. NYI - // printf(" %d, %f, %f \n", a1.*pa, a1.f, a1.d); + printf("%d, %f, %f \n", a1.*pa, a1.*pf, a1.*pd); } -- 2.40.0