]> granicus.if.org Git - clang/commitdiff
Complete code gen for '.*' binary expression for
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 22 Oct 2009 22:57:31 +0000 (22:57 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 22 Oct 2009 22:57:31 +0000 (22:57 +0000)
both scalar and aggregates.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84910 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExpr.cpp
lib/CodeGen/CGExprAgg.cpp
lib/CodeGen/CGExprScalar.cpp
lib/CodeGen/CodeGenFunction.h
test/CodeGenCXX/ptr-to-datamember.cpp

index 0b56fa94b795075d842d0870cb452c170713550a..bfbd6f70bc98a8abc969e6c3c345150deae3270f 100644 (file)
@@ -1379,6 +1379,9 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) {
     return EmitLValue(E->getRHS());
   }
 
+  if (E->getOpcode() == BinaryOperator::PtrMemD)
+    return EmitPointerToDataMemberBinaryExpr(E);
+  
   // Can only get l-value for binary operator expressions which are a
   // simple assignment of aggregate type.
   if (E->getOpcode() != BinaryOperator::Assign)
@@ -1560,3 +1563,25 @@ RValue CodeGenFunction::EmitCall(llvm::Value *Callee, QualType CalleeType,
                                                  CallingConvention),
                   Callee, Args, TargetDecl);
 }
+
+LValue CodeGenFunction::EmitPointerToDataMemberBinaryExpr(
+                                                    const BinaryOperator *E) {
+  llvm::Value *BaseV = EmitLValue(E->getLHS()).getAddress();
+  const llvm::Type *i8Ty = llvm::Type::getInt8PtrTy(getLLVMContext());
+  BaseV = Builder.CreateBitCast(BaseV, i8Ty);
+  LValue RHSLV = EmitLValue(E->getRHS());
+  llvm::Value *OffsetV = 
+    EmitLoadOfLValue(RHSLV, E->getRHS()->getType()).getScalarVal();
+  const llvm::Type* ResultType = ConvertType(getContext().getPointerDiffType());
+  OffsetV = Builder.CreateBitCast(OffsetV, ResultType);
+  llvm::Value *AddV = Builder.CreateInBoundsGEP(BaseV, OffsetV, "add.ptr");
+  QualType Ty = E->getRHS()->getType();
+  const MemberPointerType *MemPtrType = Ty->getAs<MemberPointerType>();
+  Ty = MemPtrType->getPointeeType();
+  const llvm::Type* PType = 
+  ConvertType(getContext().getPointerType(Ty));
+  AddV = Builder.CreateBitCast(AddV, PType);
+  LValue LV = LValue::MakeAddr(AddV, MakeQualifiers(Ty));
+  return LV;
+}
+
index 066029f9a5308e3ebee30c27ca438697b5e73dd7..f47b6ab3c8cc3e270ab47dd5d73876545e6505e7 100644 (file)
@@ -92,6 +92,7 @@ public:
   void VisitCallExpr(const CallExpr *E);
   void VisitStmtExpr(const StmtExpr *E);
   void VisitBinaryOperator(const BinaryOperator *BO);
+  void VisitPointerToDataMemberBinaryOperator(const BinaryOperator *BO);
   void VisitBinAssign(const BinaryOperator *E);
   void VisitBinComma(const BinaryOperator *E);
   void VisitUnaryAddrOf(const UnaryOperator *E);
@@ -328,7 +329,16 @@ void AggExprEmitter::VisitStmtExpr(const StmtExpr *E) {
 }
 
 void AggExprEmitter::VisitBinaryOperator(const BinaryOperator *E) {
-  CGF.ErrorUnsupported(E, "aggregate binary expression");
+  if (E->getOpcode() == BinaryOperator::PtrMemD)
+    VisitPointerToDataMemberBinaryOperator(E);
+  else
+    CGF.ErrorUnsupported(E, "aggregate binary expression");
+}
+
+void AggExprEmitter::VisitPointerToDataMemberBinaryOperator(
+                                                    const BinaryOperator *E) {
+  LValue LV = CGF.EmitPointerToDataMemberBinaryExpr(E);
+  EmitFinalDestCopy(E, LV);
 }
 
 void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
index 831b48033a7fceff6b220f91bab4dc11c1b7d45a..69604f9aaaee351f3fe6239e9129d778d24da1a7 100644 (file)
@@ -106,7 +106,6 @@ public:
     return 0;
   }
   Value *VisitExpr(Expr *S);
-  Value *VisitPointerToDataMemberBinaryExpr(const BinaryOperator *BExpr);
   
   Value *VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr()); }
 
@@ -539,8 +538,11 @@ EmitComplexToScalarConversion(CodeGenFunction::ComplexPairTy Src,
 
 Value *ScalarExprEmitter::VisitExpr(Expr *E) {
   if (const BinaryOperator *BExpr = dyn_cast<BinaryOperator>(E))
-    if (BExpr->getOpcode() == BinaryOperator::PtrMemD)
-      return VisitPointerToDataMemberBinaryExpr(BExpr);
+    if (BExpr->getOpcode() == BinaryOperator::PtrMemD) {
+      LValue LV = CGF.EmitPointerToDataMemberBinaryExpr(BExpr);
+      Value *InVal = CGF.EmitLoadOfLValue(LV, E->getType()).getScalarVal();
+      return InVal;
+    }
   
   CGF.ErrorUnsupported(E, "scalar expression");
   if (E->getType()->isVoidType())
@@ -548,27 +550,6 @@ Value *ScalarExprEmitter::VisitExpr(Expr *E) {
   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<MemberPointerType>();
-  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<llvm::Constant*, 32> indices;
   for (unsigned i = 2; i < E->getNumSubExprs(); i++) {
index 3e65e47024bd29304c80b21bdc5b74172c7cbc4c..639e683f0369a0d1391141396f138a861ae91867 100644 (file)
@@ -845,7 +845,8 @@ public:
   LValue EmitObjCKVCRefLValue(const ObjCImplicitSetterGetterRefExpr *E);
   LValue EmitObjCSuperExprLValue(const ObjCSuperExpr *E);
   LValue EmitStmtExprLValue(const StmtExpr *E);
-
+  LValue EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E);
+  
   //===--------------------------------------------------------------------===//
   //                         Scalar Expression Emission
   //===--------------------------------------------------------------------===//
index b0d7ddc7796fc9e2bb2490caa76d543af6b7c495..eee03c060f91c9d249838cec0025e3271f75d020 100644 (file)
@@ -2,6 +2,12 @@
 
 extern "C" int printf(...);
 
+struct F {
+  F() : iF(1), fF(2.0) {}
+  int iF;
+  float fF;
+};
+
 struct V {
   double d;
   int iV;
@@ -23,8 +29,28 @@ public:
   float f;
   double d;
   int Ai;
+  F Af;
 }; 
 
+void pr(const F& b) {
+  printf(" %d %f\n", b.iF, b.fF);
+}
+
+void test_aggr_pdata(A& a1) {
+  F A::* af = &A::Af;
+  pr(a1.*af);
+
+  (a1.*af).iF = 100;
+  (a1.*af).fF = 200.00;
+  printf(" %d %f\n", (a1.*af).iF, (a1.*af).fF);
+  pr(a1.*af);
+
+  (a1.*af).iF++;
+  (a1.*af).fF--;
+  --(a1.*af).fF;
+  pr(a1.*af);
+}
+
 int main() 
 {
   A a1;
@@ -40,4 +66,5 @@ int main()
   printf("%d\n", &A::B::V::iV);
   printf("%d\n", &A::B1::V::iV);
   printf("%d, %f, %f  \n", a1.*pa, a1.*pf, a1.*pd);
+  test_aggr_pdata(a1);
 }