aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGExpr.cpp')
-rw-r--r--lib/CodeGen/CGExpr.cpp224
1 files changed, 114 insertions, 110 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index bb487f6e3fdf..d9dd70ac9e49 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -84,10 +84,9 @@ RValue CodeGenFunction::EmitReferenceBindingToExpr(const Expr* E,
if (const CXXExprWithTemporaries *TE = dyn_cast<CXXExprWithTemporaries>(E)) {
ShouldDestroyTemporaries = TE->shouldDestroyTemporaries();
- if (ShouldDestroyTemporaries) {
- // Keep track of the current cleanup stack depth.
+ // Keep track of the current cleanup stack depth.
+ if (ShouldDestroyTemporaries)
OldNumLiveTemporaries = LiveTemporaries.size();
- }
E = TE->getSubExpr();
}
@@ -148,7 +147,6 @@ RValue CodeGenFunction::EmitReferenceBindingToExpr(const Expr* E,
// Check if need to perform the derived-to-base cast.
if (BaseClassDecl) {
llvm::Value *Derived = Val.getAggregateAddr();
-
llvm::Value *Base =
GetAddressCXXOfBaseClass(Derived, DerivedClassDecl, BaseClassDecl,
/*NullCheckValue=*/false);
@@ -189,18 +187,21 @@ unsigned CodeGenFunction::getAccessedFieldNo(unsigned Idx,
//===----------------------------------------------------------------------===//
RValue CodeGenFunction::GetUndefRValue(QualType Ty) {
- if (Ty->isVoidType()) {
+ if (Ty->isVoidType())
return RValue::get(0);
- } else if (const ComplexType *CTy = Ty->getAs<ComplexType>()) {
+
+ if (const ComplexType *CTy = Ty->getAs<ComplexType>()) {
const llvm::Type *EltTy = ConvertType(CTy->getElementType());
llvm::Value *U = llvm::UndefValue::get(EltTy);
return RValue::getComplex(std::make_pair(U, U));
- } else if (hasAggregateLLVMType(Ty)) {
+ }
+
+ if (hasAggregateLLVMType(Ty)) {
const llvm::Type *LTy = llvm::PointerType::getUnqual(ConvertType(Ty));
return RValue::getAggregate(llvm::UndefValue::get(LTy));
- } else {
- return RValue::get(llvm::UndefValue::get(ConvertType(Ty)));
}
+
+ return RValue::get(llvm::UndefValue::get(ConvertType(Ty)));
}
RValue CodeGenFunction::EmitUnsupportedRValue(const Expr *E,
@@ -245,7 +246,6 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
case Expr::VAArgExprClass:
return EmitVAArgExprLValue(cast<VAArgExpr>(E));
case Expr::DeclRefExprClass:
- case Expr::QualifiedDeclRefExprClass:
return EmitDeclRefLValue(cast<DeclRefExpr>(E));
case Expr::ParenExprClass:return EmitLValue(cast<ParenExpr>(E)->getSubExpr());
case Expr::PredefinedExprClass:
@@ -343,9 +343,8 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) {
if (LV.isObjCWeak()) {
// load of a __weak object.
llvm::Value *AddrWeakObj = LV.getAddress();
- llvm::Value *read_weak = CGM.getObjCRuntime().EmitObjCWeakRead(*this,
- AddrWeakObj);
- return RValue::get(read_weak);
+ return RValue::get(CGM.getObjCRuntime().EmitObjCWeakRead(*this,
+ AddrWeakObj));
}
if (LV.isSimple()) {
@@ -522,10 +521,8 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
if (Dst.isPropertyRef())
return EmitStoreThroughPropertyRefLValue(Src, Dst, Ty);
- if (Dst.isKVCRef())
- return EmitStoreThroughKVCRefLValue(Src, Dst, Ty);
-
- assert(0 && "Unknown LValue type");
+ assert(Dst.isKVCRef() && "Unknown LValue type");
+ return EmitStoreThroughKVCRefLValue(Src, Dst, Ty);
}
if (Dst.isObjCWeak() && !Dst.isNonGC()) {
@@ -551,8 +548,7 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
llvm::Value *BytesBetween = Builder.CreateSub(LHS, RHS, "ivar.offset");
CGM.getObjCRuntime().EmitObjCIvarAssign(*this, src, dst,
BytesBetween);
- }
- else if (Dst.isGlobalObjCRef())
+ } else if (Dst.isGlobalObjCRef())
CGM.getObjCRuntime().EmitObjCGlobalAssign(*this, src, LvalueDst);
else
CGM.getObjCRuntime().EmitObjCStrongCastAssign(*this, src, LvalueDst);
@@ -702,13 +698,12 @@ void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
// FIXME: since we're shuffling with undef, can we just use the indices
// into that? This could be simpler.
llvm::SmallVector<llvm::Constant*, 4> ExtMask;
+ const llvm::Type *Int32Ty = llvm::Type::getInt32Ty(VMContext);
unsigned i;
for (i = 0; i != NumSrcElts; ++i)
- ExtMask.push_back(llvm::ConstantInt::get(
- llvm::Type::getInt32Ty(VMContext), i));
+ ExtMask.push_back(llvm::ConstantInt::get(Int32Ty, i));
for (; i != NumDstElts; ++i)
- ExtMask.push_back(llvm::UndefValue::get(
- llvm::Type::getInt32Ty(VMContext)));
+ ExtMask.push_back(llvm::UndefValue::get(Int32Ty));
llvm::Value *ExtMaskV = llvm::ConstantVector::get(&ExtMask[0],
ExtMask.size());
llvm::Value *ExtSrcVal =
@@ -717,15 +712,13 @@ void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
ExtMaskV, "tmp");
// build identity
llvm::SmallVector<llvm::Constant*, 4> Mask;
- for (unsigned i = 0; i != NumDstElts; ++i) {
- Mask.push_back(llvm::ConstantInt::get(
- llvm::Type::getInt32Ty(VMContext), i));
- }
+ for (unsigned i = 0; i != NumDstElts; ++i)
+ Mask.push_back(llvm::ConstantInt::get(Int32Ty, i));
+
// modify when what gets shuffled in
for (unsigned i = 0; i != NumSrcElts; ++i) {
unsigned Idx = getAccessedFieldNo(i, Elts);
- Mask[Idx] = llvm::ConstantInt::get(
- llvm::Type::getInt32Ty(VMContext), i+NumDstElts);
+ Mask[Idx] = llvm::ConstantInt::get(Int32Ty, i+NumDstElts);
}
llvm::Value *MaskV = llvm::ConstantVector::get(&Mask[0], Mask.size());
Vec = Builder.CreateShuffleVector(Vec, ExtSrcVal, MaskV, "tmp");
@@ -736,8 +729,8 @@ void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
} else {
// If the Src is a scalar (not a vector) it must be updating one element.
unsigned InIdx = getAccessedFieldNo(0, Elts);
- llvm::Value *Elt = llvm::ConstantInt::get(
- llvm::Type::getInt32Ty(VMContext), InIdx);
+ const llvm::Type *Int32Ty = llvm::Type::getInt32Ty(VMContext);
+ llvm::Value *Elt = llvm::ConstantInt::get(Int32Ty, InIdx);
Vec = Builder.CreateInsertElement(Vec, SrcVal, Elt, "tmp");
}
@@ -747,8 +740,8 @@ void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
// setObjCGCLValueClass - sets class of he lvalue for the purpose of
// generating write-barries API. It is currently a global, ivar,
// or neither.
-static
-void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E, LValue &LV) {
+static void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E,
+ LValue &LV) {
if (Ctx.getLangOptions().getGCMode() == LangOptions::NonGC)
return;
@@ -759,6 +752,7 @@ void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E, LValue &LV) {
LV.SetObjCArray(LV, E->getType()->isArrayType());
return;
}
+
if (const DeclRefExpr *Exp = dyn_cast<DeclRefExpr>(E)) {
if (const VarDecl *VD = dyn_cast<VarDecl>(Exp->getDecl())) {
if ((VD->isBlockVarDecl() && !VD->hasLocalStorage()) ||
@@ -766,10 +760,15 @@ void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E, LValue &LV) {
LV.SetGlobalObjCRef(LV, true);
}
LV.SetObjCArray(LV, E->getType()->isArrayType());
+ return;
}
- else if (const UnaryOperator *Exp = dyn_cast<UnaryOperator>(E))
+
+ if (const UnaryOperator *Exp = dyn_cast<UnaryOperator>(E)) {
setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV);
- else if (const ParenExpr *Exp = dyn_cast<ParenExpr>(E)) {
+ return;
+ }
+
+ if (const ParenExpr *Exp = dyn_cast<ParenExpr>(E)) {
setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV);
if (LV.isObjCIvar()) {
// If cast is to a structure pointer, follow gcc's behavior and make it
@@ -779,13 +778,20 @@ void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E, LValue &LV) {
ExpTy = ExpTy->getAs<PointerType>()->getPointeeType();
if (ExpTy->isRecordType())
LV.SetObjCIvar(LV, false);
- }
+ }
+ return;
}
- else if (const ImplicitCastExpr *Exp = dyn_cast<ImplicitCastExpr>(E))
+ if (const ImplicitCastExpr *Exp = dyn_cast<ImplicitCastExpr>(E)) {
setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV);
- else if (const CStyleCastExpr *Exp = dyn_cast<CStyleCastExpr>(E))
+ return;
+ }
+
+ if (const CStyleCastExpr *Exp = dyn_cast<CStyleCastExpr>(E)) {
setObjCGCLValueClass(Ctx, Exp->getSubExpr(), LV);
- else if (const ArraySubscriptExpr *Exp = dyn_cast<ArraySubscriptExpr>(E)) {
+ return;
+ }
+
+ if (const ArraySubscriptExpr *Exp = dyn_cast<ArraySubscriptExpr>(E)) {
setObjCGCLValueClass(Ctx, Exp->getBase(), LV);
if (LV.isObjCIvar() && !LV.isObjCArray())
// Using array syntax to assigning to what an ivar points to is not
@@ -795,12 +801,15 @@ void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E, LValue &LV) {
// Using array syntax to assigning to what global points to is not
// same as assigning to the global itself. {id *G;} G[i] = 0;
LV.SetGlobalObjCRef(LV, false);
+ return;
}
- else if (const MemberExpr *Exp = dyn_cast<MemberExpr>(E)) {
+
+ if (const MemberExpr *Exp = dyn_cast<MemberExpr>(E)) {
setObjCGCLValueClass(Ctx, Exp->getBase(), LV);
// We don't know if member is an 'ivar', but this flag is looked at
// only in the context of LV.isObjCIvar().
LV.SetObjCArray(LV, E->getType()->isArrayType());
+ return;
}
}
@@ -839,14 +848,18 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
LValue::SetObjCNonGC(LV, NonGCable);
setObjCGCLValueClass(getContext(), E, LV);
return LV;
- } else if (VD && VD->isFileVarDecl()) {
+ }
+
+ if (VD && VD->isFileVarDecl()) {
llvm::Value *V = CGM.GetAddrOfGlobalVar(VD);
if (VD->getType()->isReferenceType())
V = Builder.CreateLoad(V, "tmp");
LValue LV = LValue::MakeAddr(V, MakeQualifiers(E->getType()));
setObjCGCLValueClass(getContext(), E, LV);
return LV;
- } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(E->getDecl())) {
+ }
+
+ if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(E->getDecl())) {
llvm::Value* V = CGM.GetAddrOfFunction(FD);
if (!FD->hasPrototype()) {
if (const FunctionProtoType *Proto =
@@ -861,15 +874,19 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
}
}
return LValue::MakeAddr(V, MakeQualifiers(E->getType()));
- } else if (const ImplicitParamDecl *IPD =
- dyn_cast<ImplicitParamDecl>(E->getDecl())) {
+ }
+
+ if (const ImplicitParamDecl *IPD = dyn_cast<ImplicitParamDecl>(E->getDecl())){
llvm::Value *V = LocalDeclMap[IPD];
assert(V && "BlockVarDecl not entered in LocalDeclMap?");
return LValue::MakeAddr(V, MakeQualifiers(E->getType()));
- } else if (const QualifiedDeclRefExpr *QDRExpr =
- dyn_cast<QualifiedDeclRefExpr>(E)) {
- return EmitPointerToDataMemberLValue(QDRExpr);
}
+
+ if (E->getQualifier()) {
+ // FIXME: the qualifier check does not seem sufficient here
+ return EmitPointerToDataMemberLValue(E);
+ }
+
assert(0 && "Unimp declref");
//an invalid LValue, but the assert will
//ensure that this point is never reached.
@@ -888,25 +905,24 @@ LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
QualType ExprTy = getContext().getCanonicalType(E->getSubExpr()->getType());
switch (E->getOpcode()) {
default: assert(0 && "Unknown unary operator lvalue!");
- case UnaryOperator::Deref:
- {
- QualType T = E->getSubExpr()->getType()->getPointeeType();
- assert(!T.isNull() && "CodeGenFunction::EmitUnaryOpLValue: Illegal type");
-
- Qualifiers Quals = MakeQualifiers(T);
- Quals.setAddressSpace(ExprTy.getAddressSpace());
-
- LValue LV = LValue::MakeAddr(EmitScalarExpr(E->getSubExpr()), Quals);
- // We should not generate __weak write barrier on indirect reference
- // of a pointer to object; as in void foo (__weak id *param); *param = 0;
- // But, we continue to generate __strong write barrier on indirect write
- // into a pointer to object.
- if (getContext().getLangOptions().ObjC1 &&
- getContext().getLangOptions().getGCMode() != LangOptions::NonGC &&
- LV.isObjCWeak())
- LValue::SetObjCNonGC(LV, !E->isOBJCGCCandidate(getContext()));
- return LV;
- }
+ case UnaryOperator::Deref: {
+ QualType T = E->getSubExpr()->getType()->getPointeeType();
+ assert(!T.isNull() && "CodeGenFunction::EmitUnaryOpLValue: Illegal type");
+
+ Qualifiers Quals = MakeQualifiers(T);
+ Quals.setAddressSpace(ExprTy.getAddressSpace());
+
+ LValue LV = LValue::MakeAddr(EmitScalarExpr(E->getSubExpr()), Quals);
+ // We should not generate __weak write barrier on indirect reference
+ // of a pointer to object; as in void foo (__weak id *param); *param = 0;
+ // But, we continue to generate __strong write barrier on indirect write
+ // into a pointer to object.
+ if (getContext().getLangOptions().ObjC1 &&
+ getContext().getLangOptions().getGCMode() != LangOptions::NonGC &&
+ LV.isObjCWeak())
+ LValue::SetObjCNonGC(LV, !E->isOBJCGCCandidate(getContext()));
+ return LV;
+ }
case UnaryOperator::Real:
case UnaryOperator::Imag:
LValue LV = EmitLValue(E->getSubExpr());
@@ -932,8 +948,7 @@ LValue CodeGenFunction::EmitPredefinedFunctionName(unsigned Type) {
std::string GlobalVarName;
switch (Type) {
- default:
- assert(0 && "Invalid type");
+ default: assert(0 && "Invalid type");
case PredefinedExpr::Func:
GlobalVarName = "__func__.";
break;
@@ -1089,12 +1104,12 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
llvm::Constant *BaseElts = Base.getExtVectorElts();
llvm::SmallVector<llvm::Constant *, 4> CElts;
+ const llvm::Type *Int32Ty = llvm::Type::getInt32Ty(VMContext);
for (unsigned i = 0, e = Indices.size(); i != e; ++i) {
if (isa<llvm::ConstantAggregateZero>(BaseElts))
- CElts.push_back(llvm::ConstantInt::get(
- llvm::Type::getInt32Ty(VMContext), 0));
+ CElts.push_back(llvm::ConstantInt::get(Int32Ty, 0));
else
- CElts.push_back(BaseElts->getOperand(Indices[i]));
+ CElts.push_back(cast<llvm::Constant>(BaseElts->getOperand(Indices[i])));
}
llvm::Constant *CV = llvm::ConstantVector::get(&CElts[0], CElts.size());
return LValue::MakeExtVectorElt(Base.getExtVectorAddr(), CV,
@@ -1211,13 +1226,12 @@ LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr* E){
const Expr* InitExpr = E->getInitializer();
LValue Result = LValue::MakeAddr(DeclPtr, MakeQualifiers(E->getType()));
- if (E->getType()->isComplexType()) {
+ if (E->getType()->isComplexType())
EmitComplexExprIntoAddr(InitExpr, DeclPtr, false);
- } else if (hasAggregateLLVMType(E->getType())) {
+ else if (hasAggregateLLVMType(E->getType()))
EmitAnyExpr(InitExpr, DeclPtr, false);
- } else {
+ else
EmitStoreThroughLValue(EmitAnyExpr(InitExpr), Result, E->getType());
- }
return Result;
}
@@ -1238,9 +1252,7 @@ CodeGenFunction::EmitConditionalOperatorLValue(const ConditionalOperator* E) {
if (!LHS.isSimple())
return EmitUnsupportedLValue(E, "conditional operator");
- llvm::Value *Temp = CreateTempAlloca(LHS.getAddress()->getType(),
- "condtmp");
-
+ llvm::Value *Temp = CreateTempAlloca(LHS.getAddress()->getType(),"condtmp");
Builder.CreateStore(LHS.getAddress(), Temp);
EmitBranch(ContBlock);
@@ -1379,7 +1391,8 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) {
return EmitLValue(E->getRHS());
}
- if (E->getOpcode() == BinaryOperator::PtrMemD)
+ if (E->getOpcode() == BinaryOperator::PtrMemD ||
+ E->getOpcode() == BinaryOperator::PtrMemI)
return EmitPointerToDataMemberBinaryExpr(E);
// Can only get l-value for binary operator expressions which are a
@@ -1406,15 +1419,14 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) {
LValue CodeGenFunction::EmitCallExprLValue(const CallExpr *E) {
RValue RV = EmitCallExpr(E);
- if (RV.isScalar()) {
- assert(E->getCallReturnType()->isReferenceType() &&
- "Can't have a scalar return unless the return type is a "
- "reference type!");
-
- return LValue::MakeAddr(RV.getScalarVal(), MakeQualifiers(E->getType()));
- }
+ if (!RV.isScalar())
+ return LValue::MakeAddr(RV.getAggregateAddr(),MakeQualifiers(E->getType()));
+
+ assert(E->getCallReturnType()->isReferenceType() &&
+ "Can't have a scalar return unless the return type is a "
+ "reference type!");
- return LValue::MakeAddr(RV.getAggregateAddr(), MakeQualifiers(E->getType()));
+ return LValue::MakeAddr(RV.getScalarVal(), MakeQualifiers(E->getType()));
}
LValue CodeGenFunction::EmitVAArgExprLValue(const VAArgExpr *E) {
@@ -1439,9 +1451,7 @@ LValue CodeGenFunction::EmitCXXConstructLValue(const CXXConstructExpr *E) {
LValue
CodeGenFunction::EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E) {
LValue LV = EmitLValue(E->getSubExpr());
-
PushCXXTemporary(E->getTemporary(), LV.getAddress());
-
return LV;
}
@@ -1497,21 +1507,18 @@ CodeGenFunction::EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E) {
return LValue::MakePropertyRef(E, E->getType().getCVRQualifiers());
}
-LValue
-CodeGenFunction::EmitObjCKVCRefLValue(
+LValue CodeGenFunction::EmitObjCKVCRefLValue(
const ObjCImplicitSetterGetterRefExpr *E) {
// This is a special l-value that just issues sends when we load or store
// through it.
return LValue::MakeKVCRef(E, E->getType().getCVRQualifiers());
}
-LValue
-CodeGenFunction::EmitObjCSuperExprLValue(const ObjCSuperExpr *E) {
+LValue CodeGenFunction::EmitObjCSuperExprLValue(const ObjCSuperExpr *E) {
return EmitUnsupportedLValue(E, "use of super");
}
LValue CodeGenFunction::EmitStmtExprLValue(const StmtExpr *E) {
-
// Can only get l-value for message expression returning aggregate type
RValue RV = EmitAnyExprToTemp(E);
// FIXME: can this be volatile?
@@ -1519,8 +1526,7 @@ LValue CodeGenFunction::EmitStmtExprLValue(const StmtExpr *E) {
}
-LValue CodeGenFunction::EmitPointerToDataMemberLValue(
- const QualifiedDeclRefExpr *E) {
+LValue CodeGenFunction::EmitPointerToDataMemberLValue(const DeclRefExpr *E) {
const FieldDecl *Field = cast<FieldDecl>(E->getDecl());
const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(Field->getDeclContext());
QualType NNSpecTy =
@@ -1530,12 +1536,9 @@ LValue CodeGenFunction::EmitPointerToDataMemberLValue(
llvm::Value *V = llvm::Constant::getNullValue(ConvertType(NNSpecTy));
LValue MemExpLV = EmitLValueForField(V, const_cast<FieldDecl*>(Field),
/*isUnion*/false, /*Qualifiers*/0);
- const llvm::Type* ResultType = ConvertType(
- getContext().getPointerDiffType());
- V = Builder.CreatePtrToInt(MemExpLV.getAddress(), ResultType,
- "datamember");
- LValue LV = LValue::MakeAddr(V, MakeQualifiers(E->getType()));
- return LV;
+ const llvm::Type *ResultType = ConvertType(getContext().getPointerDiffType());
+ V = Builder.CreatePtrToInt(MemExpLV.getAddress(), ResultType, "datamember");
+ return LValue::MakeAddr(V, MakeQualifiers(E->getType()));
}
RValue CodeGenFunction::EmitCall(llvm::Value *Callee, QualType CalleeType,
@@ -1566,9 +1569,11 @@ RValue CodeGenFunction::EmitCall(llvm::Value *Callee, QualType CalleeType,
Callee, Args, TargetDecl);
}
-LValue CodeGenFunction::EmitPointerToDataMemberBinaryExpr(
- const BinaryOperator *E) {
+LValue CodeGenFunction::
+EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E) {
llvm::Value *BaseV = EmitLValue(E->getLHS()).getAddress();
+ if (E->getOpcode() == BinaryOperator::PtrMemI)
+ BaseV = Builder.CreateLoad(BaseV, "indir.ptr");
const llvm::Type *i8Ty = llvm::Type::getInt8PtrTy(getLLVMContext());
BaseV = Builder.CreateBitCast(BaseV, i8Ty);
LValue RHSLV = EmitLValue(E->getRHS());
@@ -1577,13 +1582,12 @@ LValue CodeGenFunction::EmitPointerToDataMemberBinaryExpr(
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));
+ Ty = Ty->getAs<MemberPointerType>()->getPointeeType();
+
+ const llvm::Type *PType = ConvertType(getContext().getPointerType(Ty));
AddV = Builder.CreateBitCast(AddV, PType);
- LValue LV = LValue::MakeAddr(AddV, MakeQualifiers(Ty));
- return LV;
+ return LValue::MakeAddr(AddV, MakeQualifiers(Ty));
}