aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExprScalar.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-10-21 23:45:42 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-10-21 23:45:42 +0000
commitf51dc64f90851f636302dbaaf3f52c0524cdac36 (patch)
treebf49ae765a53425b6c8c6c5b584d4a3c3b2391e9 /lib/CodeGen/CGExprScalar.cpp
parent573d9c325279b6e156c7fde163ffe3629c62d596 (diff)
Code gen for '.*' binary expressions - WIP.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84800 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprScalar.cpp')
-rw-r--r--lib/CodeGen/CGExprScalar.cpp27
1 files changed, 27 insertions, 0 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<BinaryOperator>(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<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++) {