aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExpr.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2011-02-20 13:06:31 +0000
committerDimitry Andric <dim@FreeBSD.org>2011-02-20 13:06:31 +0000
commitbca07a4524feb4edec581062d631a13116320a24 (patch)
treea9243275843fbeaa590afc07ee888e006b8d54ea /lib/CodeGen/CGExpr.cpp
parent998bc5802ecdd65ce3b270f6c69a8ae8557f0a10 (diff)
downloadsrc-bca07a4524feb4edec581062d631a13116320a24.tar.gz
src-bca07a4524feb4edec581062d631a13116320a24.zip
Vendor import of clang trunk r126079:vendor/clang/clang-r126079
Notes
Notes: svn path=/vendor/clang/dist/; revision=218887 svn path=/vendor/clang/clang-r126079/; revision=218888; tag=vendor/clang/clang-r126079
Diffstat (limited to 'lib/CodeGen/CGExpr.cpp')
-rw-r--r--lib/CodeGen/CGExpr.cpp662
1 files changed, 329 insertions, 333 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 3750ab80c3fc..1b7e7a007ed2 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -29,6 +29,18 @@ using namespace CodeGen;
// Miscellaneous Helper Methods
//===--------------------------------------------------------------------===//
+llvm::Value *CodeGenFunction::EmitCastToVoidPtr(llvm::Value *value) {
+ unsigned addressSpace =
+ cast<llvm::PointerType>(value->getType())->getAddressSpace();
+
+ const llvm::PointerType *destType = Int8PtrTy;
+ if (addressSpace)
+ destType = llvm::Type::getInt8PtrTy(getLLVMContext(), addressSpace);
+
+ if (value->getType() == destType) return value;
+ return Builder.CreateBitCast(value, destType);
+}
+
/// CreateTempAlloca - This creates a alloca and inserts it into the entry
/// block.
llvm::AllocaInst *CodeGenFunction::CreateTempAlloca(const llvm::Type *Ty,
@@ -68,7 +80,7 @@ llvm::AllocaInst *CodeGenFunction::CreateMemTemp(QualType Ty,
llvm::Value *CodeGenFunction::EvaluateExprAsBool(const Expr *E) {
if (const MemberPointerType *MPT = E->getType()->getAs<MemberPointerType>()) {
llvm::Value *MemPtr = EmitScalarExpr(E);
- return CGM.getCXXABI().EmitMemberPointerIsNotNull(CGF, MemPtr, MPT);
+ return CGM.getCXXABI().EmitMemberPointerIsNotNull(*this, MemPtr, MPT);
}
QualType BoolTy = getContext().BoolTy;
@@ -78,35 +90,40 @@ llvm::Value *CodeGenFunction::EvaluateExprAsBool(const Expr *E) {
return EmitComplexToScalarConversion(EmitComplexExpr(E), E->getType(),BoolTy);
}
-/// EmitAnyExpr - Emit code to compute the specified expression which can have
-/// any type. The result is returned as an RValue struct. If this is an
-/// aggregate expression, the aggloc/agglocvolatile arguments indicate where the
+/// EmitIgnoredExpr - Emit code to compute the specified expression,
+/// ignoring the result.
+void CodeGenFunction::EmitIgnoredExpr(const Expr *E) {
+ if (E->isRValue())
+ return (void) EmitAnyExpr(E, AggValueSlot::ignored(), true);
+
+ // Just emit it as an l-value and drop the result.
+ EmitLValue(E);
+}
+
+/// EmitAnyExpr - Emit code to compute the specified expression which
+/// can have any type. The result is returned as an RValue struct.
+/// If this is an aggregate expression, AggSlot indicates where the
/// result should be returned.
-RValue CodeGenFunction::EmitAnyExpr(const Expr *E, llvm::Value *AggLoc,
- bool IsAggLocVolatile, bool IgnoreResult,
- bool IsInitializer) {
+RValue CodeGenFunction::EmitAnyExpr(const Expr *E, AggValueSlot AggSlot,
+ bool IgnoreResult) {
if (!hasAggregateLLVMType(E->getType()))
return RValue::get(EmitScalarExpr(E, IgnoreResult));
else if (E->getType()->isAnyComplexType())
- return RValue::getComplex(EmitComplexExpr(E, false, false,
- IgnoreResult, IgnoreResult));
+ return RValue::getComplex(EmitComplexExpr(E, IgnoreResult, IgnoreResult));
- EmitAggExpr(E, AggLoc, IsAggLocVolatile, IgnoreResult, IsInitializer);
- return RValue::getAggregate(AggLoc, IsAggLocVolatile);
+ EmitAggExpr(E, AggSlot, IgnoreResult);
+ return AggSlot.asRValue();
}
/// EmitAnyExprToTemp - Similary to EmitAnyExpr(), however, the result will
/// always be accessible even if no aggregate location is provided.
-RValue CodeGenFunction::EmitAnyExprToTemp(const Expr *E,
- bool IsAggLocVolatile,
- bool IsInitializer) {
- llvm::Value *AggLoc = 0;
+RValue CodeGenFunction::EmitAnyExprToTemp(const Expr *E) {
+ AggValueSlot AggSlot = AggValueSlot::ignored();
if (hasAggregateLLVMType(E->getType()) &&
!E->getType()->isAnyComplexType())
- AggLoc = CreateMemTemp(E->getType(), "agg.tmp");
- return EmitAnyExpr(E, AggLoc, IsAggLocVolatile, /*IgnoreResult=*/false,
- IsInitializer);
+ AggSlot = CreateAggTemp(E->getType(), "agg.tmp");
+ return EmitAnyExpr(E, AggSlot);
}
/// EmitAnyExprToMem - Evaluate an expression into a given memory
@@ -118,7 +135,7 @@ void CodeGenFunction::EmitAnyExprToMem(const Expr *E,
if (E->getType()->isComplexType())
EmitComplexExprIntoAddr(E, Location, IsLocationVolatile);
else if (hasAggregateLLVMType(E->getType()))
- EmitAggExpr(E, Location, IsLocationVolatile, /*Ignore*/ false, IsInit);
+ EmitAggExpr(E, AggValueSlot::forAddr(Location, IsLocationVolatile, IsInit));
else {
RValue RV = RValue::get(EmitScalarExpr(E, /*Ignore*/ false));
LValue LV = MakeAddrLValue(Location, E->getType());
@@ -126,34 +143,34 @@ void CodeGenFunction::EmitAnyExprToMem(const Expr *E,
}
}
+namespace {
/// \brief An adjustment to be made to the temporary created when emitting a
/// reference binding, which accesses a particular subobject of that temporary.
-struct SubobjectAdjustment {
- enum { DerivedToBaseAdjustment, FieldAdjustment } Kind;
-
- union {
- struct {
- const CastExpr *BasePath;
- const CXXRecordDecl *DerivedClass;
- } DerivedToBase;
-
- FieldDecl *Field;
+ struct SubobjectAdjustment {
+ enum { DerivedToBaseAdjustment, FieldAdjustment } Kind;
+
+ union {
+ struct {
+ const CastExpr *BasePath;
+ const CXXRecordDecl *DerivedClass;
+ } DerivedToBase;
+
+ FieldDecl *Field;
+ };
+
+ SubobjectAdjustment(const CastExpr *BasePath,
+ const CXXRecordDecl *DerivedClass)
+ : Kind(DerivedToBaseAdjustment) {
+ DerivedToBase.BasePath = BasePath;
+ DerivedToBase.DerivedClass = DerivedClass;
+ }
+
+ SubobjectAdjustment(FieldDecl *Field)
+ : Kind(FieldAdjustment) {
+ this->Field = Field;
+ }
};
-
- SubobjectAdjustment(const CastExpr *BasePath,
- const CXXRecordDecl *DerivedClass)
- : Kind(DerivedToBaseAdjustment)
- {
- DerivedToBase.BasePath = BasePath;
- DerivedToBase.DerivedClass = DerivedClass;
- }
-
- SubobjectAdjustment(FieldDecl *Field)
- : Kind(FieldAdjustment)
- {
- this->Field = Field;
- }
-};
+}
static llvm::Value *
CreateReferenceTemporary(CodeGenFunction& CGF, QualType Type,
@@ -161,8 +178,10 @@ CreateReferenceTemporary(CodeGenFunction& CGF, QualType Type,
if (const VarDecl *VD = dyn_cast_or_null<VarDecl>(InitializedDecl)) {
if (VD->hasGlobalStorage()) {
llvm::SmallString<256> Name;
- CGF.CGM.getCXXABI().getMangleContext().mangleReferenceTemporary(VD, Name);
-
+ llvm::raw_svector_ostream Out(Name);
+ CGF.CGM.getCXXABI().getMangleContext().mangleReferenceTemporary(VD, Out);
+ Out.flush();
+
const llvm::Type *RefTempTy = CGF.ConvertTypeForMem(Type);
// Create the reference temporary.
@@ -180,14 +199,14 @@ CreateReferenceTemporary(CodeGenFunction& CGF, QualType Type,
}
static llvm::Value *
-EmitExprForReferenceBinding(CodeGenFunction& CGF, const Expr* E,
+EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
llvm::Value *&ReferenceTemporary,
const CXXDestructorDecl *&ReferenceTemporaryDtor,
const NamedDecl *InitializedDecl) {
if (const CXXDefaultArgExpr *DAE = dyn_cast<CXXDefaultArgExpr>(E))
E = DAE->getExpr();
- if (const CXXExprWithTemporaries *TE = dyn_cast<CXXExprWithTemporaries>(E)) {
+ if (const ExprWithCleanups *TE = dyn_cast<ExprWithCleanups>(E)) {
CodeGenFunction::RunCleanupsScope Scope(CGF);
return EmitExprForReferenceBinding(CGF, TE->getSubExpr(),
@@ -197,10 +216,9 @@ EmitExprForReferenceBinding(CodeGenFunction& CGF, const Expr* E,
}
RValue RV;
- if (E->isLvalue(CGF.getContext()) == Expr::LV_Valid) {
+ if (E->isGLValue()) {
// Emit the expression as an lvalue.
LValue LV = CGF.EmitLValue(E);
-
if (LV.isSimple())
return LV.getAddress();
@@ -232,8 +250,8 @@ EmitExprForReferenceBinding(CodeGenFunction& CGF, const Expr* E,
continue;
}
} else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
- if (ME->getBase()->isLvalue(CGF.getContext()) != Expr::LV_Valid &&
- ME->getBase()->getType()->isRecordType()) {
+ if (!ME->isArrow() && ME->getBase()->isRValue()) {
+ assert(ME->getBase()->getType()->isRecordType());
if (FieldDecl *Field = dyn_cast<FieldDecl>(ME->getMemberDecl())) {
E = ME->getBase();
Adjustments.push_back(SubobjectAdjustment(Field));
@@ -247,13 +265,16 @@ EmitExprForReferenceBinding(CodeGenFunction& CGF, const Expr* E,
}
// Create a reference temporary if necessary.
+ AggValueSlot AggSlot = AggValueSlot::ignored();
if (CGF.hasAggregateLLVMType(E->getType()) &&
- !E->getType()->isAnyComplexType())
+ !E->getType()->isAnyComplexType()) {
ReferenceTemporary = CreateReferenceTemporary(CGF, E->getType(),
InitializedDecl);
+ AggSlot = AggValueSlot::forAddr(ReferenceTemporary, false,
+ InitializedDecl != 0);
+ }
- RV = CGF.EmitAnyExpr(E, ReferenceTemporary, /*IsAggLocVolatile=*/false,
- /*IgnoreResult=*/false, InitializedDecl);
+ RV = CGF.EmitAnyExpr(E, AggSlot);
if (InitializedDecl) {
// Get the destructor for the reference temporary.
@@ -328,7 +349,7 @@ EmitExprForReferenceBinding(CodeGenFunction& CGF, const Expr* E,
}
RValue
-CodeGenFunction::EmitReferenceBindingToExpr(const Expr* E,
+CodeGenFunction::EmitReferenceBindingToExpr(const Expr *E,
const NamedDecl *InitializedDecl) {
llvm::Value *ReferenceTemporary = 0;
const CXXDestructorDecl *ReferenceTemporaryDtor = 0;
@@ -343,8 +364,8 @@ CodeGenFunction::EmitReferenceBindingToExpr(const Expr* E,
if (VD->hasGlobalStorage()) {
llvm::Constant *DtorFn =
CGM.GetAddrOfCXXDestructor(ReferenceTemporaryDtor, Dtor_Complete);
- CGF.EmitCXXGlobalDtorRegistration(DtorFn,
- cast<llvm::Constant>(ReferenceTemporary));
+ EmitCXXGlobalDtorRegistration(DtorFn,
+ cast<llvm::Constant>(ReferenceTemporary));
return RValue::get(Value);
}
@@ -370,14 +391,14 @@ void CodeGenFunction::EmitCheck(llvm::Value *Address, unsigned Size) {
if (!CatchUndefined)
return;
- Address = Builder.CreateBitCast(Address, PtrToInt8Ty);
+ // This needs to be to the standard address space.
+ Address = Builder.CreateBitCast(Address, Int8PtrTy);
const llvm::Type *IntPtrT = IntPtrTy;
llvm::Value *F = CGM.getIntrinsic(llvm::Intrinsic::objectsize, &IntPtrT, 1);
- const llvm::IntegerType *Int1Ty = llvm::Type::getInt1Ty(VMContext);
// In time, people may want to control this and use a 1 here.
- llvm::Value *Arg = llvm::ConstantInt::get(Int1Ty, 0);
+ llvm::Value *Arg = Builder.getFalse();
llvm::Value *C = Builder.CreateCall2(F, Address, Arg);
llvm::BasicBlock *Cont = createBasicBlock();
llvm::BasicBlock *Check = createBasicBlock();
@@ -468,7 +489,8 @@ LValue CodeGenFunction::EmitUnsupportedLValue(const Expr *E,
LValue CodeGenFunction::EmitCheckedLValue(const Expr *E) {
LValue LV = EmitLValue(E);
if (!isa<DeclRefExpr>(E) && !LV.isBitField() && LV.isSimple())
- EmitCheck(LV.getAddress(), getContext().getTypeSize(E->getType()) / 8);
+ EmitCheck(LV.getAddress(),
+ getContext().getTypeSizeInChars(E->getType()).getQuantity());
return LV;
}
@@ -498,7 +520,9 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
case Expr::BinaryOperatorClass:
return EmitBinaryOperatorLValue(cast<BinaryOperator>(E));
case Expr::CompoundAssignOperatorClass:
- return EmitCompoundAssignOperatorLValue(cast<CompoundAssignOperator>(E));
+ if (!E->getType()->isAnyComplexType())
+ return EmitCompoundAssignmentLValue(cast<CompoundAssignOperator>(E));
+ return EmitComplexCompoundAssignmentLValue(cast<CompoundAssignOperator>(E));
case Expr::CallExprClass:
case Expr::CXXMemberCallExprClass:
case Expr::CXXOperatorCallExprClass:
@@ -523,8 +547,8 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
return EmitCXXConstructLValue(cast<CXXConstructExpr>(E));
case Expr::CXXBindTemporaryExprClass:
return EmitCXXBindTemporaryLValue(cast<CXXBindTemporaryExpr>(E));
- case Expr::CXXExprWithTemporariesClass:
- return EmitCXXExprWithTemporariesLValue(cast<CXXExprWithTemporaries>(E));
+ case Expr::ExprWithCleanupsClass:
+ return EmitExprWithCleanupsLValue(cast<ExprWithCleanups>(E));
case Expr::CXXScalarValueInitExprClass:
return EmitNullInitializationLValue(cast<CXXScalarValueInitExpr>(E));
case Expr::CXXDefaultArgExprClass:
@@ -538,11 +562,6 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
return EmitObjCIvarRefLValue(cast<ObjCIvarRefExpr>(E));
case Expr::ObjCPropertyRefExprClass:
return EmitObjCPropertyRefLValue(cast<ObjCPropertyRefExpr>(E));
- case Expr::ObjCImplicitSetterGetterRefExprClass:
- return EmitObjCKVCRefLValue(cast<ObjCImplicitSetterGetterRefExpr>(E));
- case Expr::ObjCSuperExprClass:
- return EmitObjCSuperExprLValue(cast<ObjCSuperExpr>(E));
-
case Expr::StmtExprClass:
return EmitStmtExprLValue(cast<StmtExpr>(E));
case Expr::UnaryOperatorClass:
@@ -557,8 +576,12 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
return EmitCompoundLiteralLValue(cast<CompoundLiteralExpr>(E));
case Expr::ConditionalOperatorClass:
return EmitConditionalOperatorLValue(cast<ConditionalOperator>(E));
+ case Expr::BinaryConditionalOperatorClass:
+ return EmitConditionalOperatorLValue(cast<BinaryConditionalOperator>(E));
case Expr::ChooseExprClass:
return EmitLValue(cast<ChooseExpr>(E)->getChosenSubExpr(getContext()));
+ case Expr::OpaqueValueExprClass:
+ return EmitOpaqueValueLValue(cast<OpaqueValueExpr>(E));
case Expr::ImplicitCastExprClass:
case Expr::CStyleCastExprClass:
case Expr::CXXFunctionalCastExprClass:
@@ -571,35 +594,58 @@ LValue CodeGenFunction::EmitLValue(const Expr *E) {
}
llvm::Value *CodeGenFunction::EmitLoadOfScalar(llvm::Value *Addr, bool Volatile,
- unsigned Alignment, QualType Ty) {
+ unsigned Alignment, QualType Ty,
+ llvm::MDNode *TBAAInfo) {
llvm::LoadInst *Load = Builder.CreateLoad(Addr, "tmp");
if (Volatile)
Load->setVolatile(true);
if (Alignment)
Load->setAlignment(Alignment);
+ if (TBAAInfo)
+ CGM.DecorateInstruction(Load, TBAAInfo);
- // Bool can have different representation in memory than in registers.
- llvm::Value *V = Load;
- if (Ty->isBooleanType())
- if (V->getType() != llvm::Type::getInt1Ty(VMContext))
- V = Builder.CreateTrunc(V, llvm::Type::getInt1Ty(VMContext), "tobool");
+ return EmitFromMemory(Load, Ty);
+}
- return V;
+static bool isBooleanUnderlyingType(QualType Ty) {
+ if (const EnumType *ET = dyn_cast<EnumType>(Ty))
+ return ET->getDecl()->getIntegerType()->isBooleanType();
+ return false;
}
-void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr,
- bool Volatile, unsigned Alignment,
- QualType Ty) {
+llvm::Value *CodeGenFunction::EmitToMemory(llvm::Value *Value, QualType Ty) {
+ // Bool has a different representation in memory than in registers.
+ if (Ty->isBooleanType() || isBooleanUnderlyingType(Ty)) {
+ // This should really always be an i1, but sometimes it's already
+ // an i8, and it's awkward to track those cases down.
+ if (Value->getType()->isIntegerTy(1))
+ return Builder.CreateZExt(Value, Builder.getInt8Ty(), "frombool");
+ assert(Value->getType()->isIntegerTy(8) && "value rep of bool not i1/i8");
+ }
- if (Ty->isBooleanType()) {
- // Bool can have different representation in memory than in registers.
- const llvm::PointerType *DstPtr = cast<llvm::PointerType>(Addr->getType());
- Value = Builder.CreateIntCast(Value, DstPtr->getElementType(), false);
+ return Value;
+}
+
+llvm::Value *CodeGenFunction::EmitFromMemory(llvm::Value *Value, QualType Ty) {
+ // Bool has a different representation in memory than in registers.
+ if (Ty->isBooleanType() || isBooleanUnderlyingType(Ty)) {
+ assert(Value->getType()->isIntegerTy(8) && "memory rep of bool not i8");
+ return Builder.CreateTrunc(Value, Builder.getInt1Ty(), "tobool");
}
+ return Value;
+}
+
+void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr,
+ bool Volatile, unsigned Alignment,
+ QualType Ty,
+ llvm::MDNode *TBAAInfo) {
+ Value = EmitToMemory(Value, Ty);
llvm::StoreInst *Store = Builder.CreateStore(Value, Addr, Volatile);
if (Alignment)
Store->setAlignment(Alignment);
+ if (TBAAInfo)
+ CGM.DecorateInstruction(Store, TBAAInfo);
}
/// EmitLoadOfLValue - Given an expression that represents a value lvalue, this
@@ -622,7 +668,8 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) {
// Everything needs a load.
return RValue::get(EmitLoadOfScalar(Ptr, LV.isVolatileQualified(),
- LV.getAlignment(), ExprType));
+ LV.getAlignment(), ExprType,
+ LV.getTBAAInfo()));
}
@@ -641,11 +688,8 @@ RValue CodeGenFunction::EmitLoadOfLValue(LValue LV, QualType ExprType) {
if (LV.isBitField())
return EmitLoadOfBitfieldLValue(LV, ExprType);
- if (LV.isPropertyRef())
- return EmitLoadOfPropertyRefLValue(LV, ExprType);
-
- assert(LV.isKVCRef() && "Unknown LValue type!");
- return EmitLoadOfKVCRefLValue(LV, ExprType);
+ assert(LV.isPropertyRef() && "Unknown LValue type!");
+ return EmitLoadOfPropertyRefLValue(LV);
}
RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV,
@@ -671,13 +715,13 @@ RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV,
// Offset by the byte offset, if used.
if (AI.FieldByteOffset) {
- const llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(VMContext);
- Ptr = Builder.CreateBitCast(Ptr, i8PTy);
+ Ptr = EmitCastToVoidPtr(Ptr);
Ptr = Builder.CreateConstGEP1_32(Ptr, AI.FieldByteOffset,"bf.field.offs");
}
// Cast to the access type.
- const llvm::Type *PTy = llvm::Type::getIntNPtrTy(VMContext, AI.AccessWidth,
+ const llvm::Type *PTy = llvm::Type::getIntNPtrTy(getLLVMContext(),
+ AI.AccessWidth,
ExprType.getAddressSpace());
Ptr = Builder.CreateBitCast(Ptr, PTy);
@@ -720,16 +764,6 @@ RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV,
return RValue::get(Res);
}
-RValue CodeGenFunction::EmitLoadOfPropertyRefLValue(LValue LV,
- QualType ExprType) {
- return EmitObjCPropertyGet(LV.getPropertyRefExpr());
-}
-
-RValue CodeGenFunction::EmitLoadOfKVCRefLValue(LValue LV,
- QualType ExprType) {
- return EmitObjCPropertyGet(LV.getKVCRefExpr());
-}
-
// If this is a reference to a subset of the elements of a vector, create an
// appropriate shufflevector.
RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV,
@@ -757,9 +791,8 @@ RValue CodeGenFunction::EmitLoadOfExtVectorElementLValue(LValue LV,
Mask.push_back(llvm::ConstantInt::get(Int32Ty, InIdx));
}
- llvm::Value *MaskV = llvm::ConstantVector::get(&Mask[0], Mask.size());
- Vec = Builder.CreateShuffleVector(Vec,
- llvm::UndefValue::get(Vec->getType()),
+ llvm::Value *MaskV = llvm::ConstantVector::get(Mask);
+ Vec = Builder.CreateShuffleVector(Vec, llvm::UndefValue::get(Vec->getType()),
MaskV, "tmp");
return RValue::get(Vec);
}
@@ -790,11 +823,8 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
if (Dst.isBitField())
return EmitStoreThroughBitfieldLValue(Src, Dst, Ty);
- if (Dst.isPropertyRef())
- return EmitStoreThroughPropertyRefLValue(Src, Dst, Ty);
-
- assert(Dst.isKVCRef() && "Unknown LValue type");
- return EmitStoreThroughKVCRefLValue(Src, Dst, Ty);
+ assert(Dst.isPropertyRef() && "Unknown LValue type");
+ return EmitStoreThroughPropertyRefLValue(Src, Dst);
}
if (Dst.isObjCWeak() && !Dst.isNonGC()) {
@@ -831,7 +861,8 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst,
assert(Src.isScalar() && "Can't emit an agg store with this method");
EmitStoreOfScalar(Src.getScalarVal(), Dst.getAddress(),
- Dst.isVolatileQualified(), Dst.getAlignment(), Ty);
+ Dst.isVolatileQualified(), Dst.getAlignment(), Ty,
+ Dst.getTBAAInfo());
}
void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
@@ -877,6 +908,8 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
// Get the field pointer.
llvm::Value *Ptr = Dst.getBitFieldBaseAddr();
+ unsigned addressSpace =
+ cast<llvm::PointerType>(Ptr->getType())->getAddressSpace();
// Only offset by the field index if used, so that incoming values are not
// required to be structures.
@@ -885,14 +918,15 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
// Offset by the byte offset, if used.
if (AI.FieldByteOffset) {
- const llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(VMContext);
- Ptr = Builder.CreateBitCast(Ptr, i8PTy);
+ Ptr = EmitCastToVoidPtr(Ptr);
Ptr = Builder.CreateConstGEP1_32(Ptr, AI.FieldByteOffset,"bf.field.offs");
}
// Cast to the access type.
- const llvm::Type *PTy = llvm::Type::getIntNPtrTy(VMContext, AI.AccessWidth,
- Ty.getAddressSpace());
+ const llvm::Type *AccessLTy =
+ llvm::Type::getIntNTy(getLLVMContext(), AI.AccessWidth);
+
+ const llvm::Type *PTy = AccessLTy->getPointerTo(addressSpace);
Ptr = Builder.CreateBitCast(Ptr, PTy);
// Extract the piece of the bit-field value to write in this access, limited
@@ -904,8 +938,6 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
AI.TargetBitWidth));
// Extend or truncate to the access size.
- const llvm::Type *AccessLTy =
- llvm::Type::getIntNTy(VMContext, AI.AccessWidth);
if (ResSizeInBits < AI.AccessWidth)
Val = Builder.CreateZExt(Val, AccessLTy);
else if (ResSizeInBits > AI.AccessWidth)
@@ -938,18 +970,6 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,
}
}
-void CodeGenFunction::EmitStoreThroughPropertyRefLValue(RValue Src,
- LValue Dst,
- QualType Ty) {
- EmitObjCPropertySet(Dst.getPropertyRefExpr(), Src);
-}
-
-void CodeGenFunction::EmitStoreThroughKVCRefLValue(RValue Src,
- LValue Dst,
- QualType Ty) {
- EmitObjCPropertySet(Dst.getKVCRefExpr(), Src);
-}
-
void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
LValue Dst,
QualType Ty) {
@@ -975,7 +995,7 @@ void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
Mask[InIdx] = llvm::ConstantInt::get(Int32Ty, i);
}
- llvm::Value *MaskV = llvm::ConstantVector::get(&Mask[0], Mask.size());
+ llvm::Value *MaskV = llvm::ConstantVector::get(Mask);
Vec = Builder.CreateShuffleVector(SrcVal,
llvm::UndefValue::get(Vec->getType()),
MaskV, "tmp");
@@ -990,8 +1010,7 @@ void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
ExtMask.push_back(llvm::ConstantInt::get(Int32Ty, i));
for (; i != NumDstElts; ++i)
ExtMask.push_back(llvm::UndefValue::get(Int32Ty));
- llvm::Value *ExtMaskV = llvm::ConstantVector::get(&ExtMask[0],
- ExtMask.size());
+ llvm::Value *ExtMaskV = llvm::ConstantVector::get(ExtMask);
llvm::Value *ExtSrcVal =
Builder.CreateShuffleVector(SrcVal,
llvm::UndefValue::get(SrcVal->getType()),
@@ -1006,7 +1025,7 @@ void CodeGenFunction::EmitStoreThroughExtVectorComponentLValue(RValue Src,
unsigned Idx = getAccessedFieldNo(i, Elts);
Mask[Idx] = llvm::ConstantInt::get(Int32Ty, i+NumDstElts);
}
- llvm::Value *MaskV = llvm::ConstantVector::get(&Mask[0], Mask.size());
+ llvm::Value *MaskV = llvm::ConstantVector::get(Mask);
Vec = Builder.CreateShuffleVector(Vec, ExtSrcVal, MaskV, "tmp");
} else {
// We should never shorten the vector
@@ -1040,8 +1059,7 @@ static void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E,
if (const DeclRefExpr *Exp = dyn_cast<DeclRefExpr>(E)) {
if (const VarDecl *VD = dyn_cast<VarDecl>(Exp->getDecl())) {
- if ((VD->isBlockVarDecl() && !VD->hasLocalStorage()) ||
- VD->isFileVarDecl()) {
+ if (VD->hasGlobalStorage()) {
LV.setGlobalObjCRef(true);
LV.setThreadLocalRef(VD->isThreadSpecified());
}
@@ -1116,7 +1134,7 @@ static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF,
static LValue EmitFunctionDeclLValue(CodeGenFunction &CGF,
const Expr *E, const FunctionDecl *FD) {
- llvm::Value* V = CGF.CGM.GetAddrOfFunction(FD);
+ llvm::Value *V = CGF.CGM.GetAddrOfFunction(FD);
if (!FD->hasPrototype()) {
if (const FunctionProtoType *Proto =
FD->getType()->getAs<FunctionProtoType>()) {
@@ -1135,10 +1153,10 @@ static LValue EmitFunctionDeclLValue(CodeGenFunction &CGF,
LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
const NamedDecl *ND = E->getDecl();
- unsigned Alignment = CGF.getContext().getDeclAlign(ND).getQuantity();
+ unsigned Alignment = getContext().getDeclAlign(ND).getQuantity();
if (ND->hasAttr<WeakRefAttr>()) {
- const ValueDecl* VD = cast<ValueDecl>(ND);
+ const ValueDecl *VD = cast<ValueDecl>(ND);
llvm::Constant *Aliasee = CGM.GetWeakRefReference(VD);
return MakeAddrLValue(Aliasee, E->getType(), Alignment);
}
@@ -1149,20 +1167,18 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
if (VD->hasExternalStorage() || VD->isFileVarDecl())
return EmitGlobalVarDeclLValue(*this, E, VD);
- bool NonGCable = VD->hasLocalStorage() && !VD->hasAttr<BlocksAttr>();
+ bool NonGCable = VD->hasLocalStorage() &&
+ !VD->getType()->isReferenceType() &&
+ !VD->hasAttr<BlocksAttr>();
llvm::Value *V = LocalDeclMap[VD];
- if (!V && getContext().getLangOptions().CPlusPlus &&
- VD->isStaticLocal())
+ if (!V && VD->isStaticLocal())
V = CGM.getStaticLocalDeclAddress(VD);
assert(V && "DeclRefExpr not entered in LocalDeclMap?");
- if (VD->hasAttr<BlocksAttr>()) {
- V = Builder.CreateStructGEP(V, 1, "forwarding");
- V = Builder.CreateLoad(V);
- V = Builder.CreateStructGEP(V, getByRefValueLLVMField(VD),
- VD->getNameAsString());
- }
+ if (VD->hasAttr<BlocksAttr>())
+ V = BuildBlockByrefAddress(V, VD);
+
if (VD->getType()->isReferenceType())
V = Builder.CreateLoad(V, "tmp");
@@ -1174,24 +1190,10 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
setObjCGCLValueClass(getContext(), E, LV);
return LV;
}
-
- // If we're emitting an instance method as an independent lvalue,
- // we're actually emitting a member pointer.
- if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(ND))
- if (MD->isInstance()) {
- llvm::Value *V = CGM.getCXXABI().EmitMemberPointer(MD);
- return MakeAddrLValue(V, MD->getType(), Alignment);
- }
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
- return EmitFunctionDeclLValue(*this, E, FD);
-
- // If we're emitting a field as an independent lvalue, we're
- // actually emitting a member pointer.
- if (const FieldDecl *FD = dyn_cast<FieldDecl>(ND)) {
- llvm::Value *V = CGM.getCXXABI().EmitMemberPointer(FD);
- return MakeAddrLValue(V, FD->getType(), Alignment);
- }
-
+
+ if (const FunctionDecl *fn = dyn_cast<FunctionDecl>(ND))
+ return EmitFunctionDeclLValue(*this, E, fn);
+
assert(false && "Unhandled DeclRefExpr");
// an invalid LValue, but the assert will
@@ -1201,7 +1203,7 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) {
LValue CodeGenFunction::EmitBlockDeclRefLValue(const BlockDeclRefExpr *E) {
unsigned Alignment =
- CGF.getContext().getDeclAlign(E->getDecl()).getQuantity();
+ getContext().getDeclAlign(E->getDecl()).getQuantity();
return MakeAddrLValue(GetAddrOfBlockDecl(E), E->getType(), Alignment);
}
@@ -1233,9 +1235,22 @@ LValue CodeGenFunction::EmitUnaryOpLValue(const UnaryOperator *E) {
case UO_Real:
case UO_Imag: {
LValue LV = EmitLValue(E->getSubExpr());
+ assert(LV.isSimple() && "real/imag on non-ordinary l-value");
+ llvm::Value *Addr = LV.getAddress();
+
+ // real and imag are valid on scalars. This is a faster way of
+ // testing that.
+ if (!cast<llvm::PointerType>(Addr->getType())
+ ->getElementType()->isStructTy()) {
+ assert(E->getSubExpr()->getType()->isArithmeticType());
+ return LV;
+ }
+
+ assert(E->getSubExpr()->getType()->isAnyComplexType());
+
unsigned Idx = E->getOpcode() == UO_Imag;
return MakeAddrLValue(Builder.CreateStructGEP(LV.getAddress(),
- Idx, "idx"),
+ Idx, "idx"),
ExprTy);
}
case UO_PreInc:
@@ -1297,7 +1312,9 @@ LValue CodeGenFunction::EmitPredefinedLValue(const PredefinedExpr *E) {
CurDecl = getContext().getTranslationUnitDecl();
std::string FunctionName =
- PredefinedExpr::ComputeName((PredefinedExpr::IdentType)Type, CurDecl);
+ (isa<BlockDecl>(CurDecl)
+ ? FnName.str()
+ : PredefinedExpr::ComputeName((PredefinedExpr::IdentType)Type, CurDecl));
llvm::Constant *C =
CGM.GetAddrOfConstantCString(FunctionName, GlobalVarName.c_str());
@@ -1363,15 +1380,14 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {
// Emit the vector as an lvalue to get its address.
LValue LHS = EmitLValue(E->getBase());
assert(LHS.isSimple() && "Can only subscript lvalue vectors here!");
- Idx = Builder.CreateIntCast(Idx, CGF.Int32Ty, IdxSigned, "vidx");
+ Idx = Builder.CreateIntCast(Idx, Int32Ty, IdxSigned, "vidx");
return LValue::MakeVectorElt(LHS.getAddress(), Idx,
E->getBase()->getType().getCVRQualifiers());
}
// Extend or truncate the index type to 32 or 64-bits.
- if (!Idx->getType()->isIntegerTy(LLVMPointerWidth))
- Idx = Builder.CreateIntCast(Idx, IntPtrTy,
- IdxSigned, "idxprom");
+ if (Idx->getType() != IntPtrTy)
+ Idx = Builder.CreateIntCast(Idx, IntPtrTy, IdxSigned, "idxprom");
// FIXME: As llvm implements the object size checking, this can come out.
if (CatchUndefined) {
@@ -1401,17 +1417,12 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {
Idx = Builder.CreateMul(Idx, VLASize);
- QualType BaseType = getContext().getBaseElementType(VAT);
-
- CharUnits BaseTypeSize = getContext().getTypeSizeInChars(BaseType);
- Idx = Builder.CreateUDiv(Idx,
- llvm::ConstantInt::get(Idx->getType(),
- BaseTypeSize.getQuantity()));
-
// The base must be a pointer, which is not an aggregate. Emit it.
llvm::Value *Base = EmitScalarExpr(E->getBase());
-
- Address = Builder.CreateInBoundsGEP(Base, Idx, "arrayidx");
+
+ Address = EmitCastToVoidPtr(Base);
+ Address = Builder.CreateInBoundsGEP(Address, Idx, "arrayidx");
+ Address = Builder.CreateBitCast(Address, Base->getType());
} else if (const ObjCObjectType *OIT = E->getType()->getAs<ObjCObjectType>()){
// Indexing over an interface, as in "NSString *P; P[4];"
llvm::Value *InterfaceSize =
@@ -1420,12 +1431,10 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E) {
Idx = Builder.CreateMul(Idx, InterfaceSize);
- const llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(VMContext);
-
// The base must be a pointer, which is not an aggregate. Emit it.
llvm::Value *Base = EmitScalarExpr(E->getBase());
- Address = Builder.CreateGEP(Builder.CreateBitCast(Base, i8PTy),
- Idx, "arrayidx");
+ Address = EmitCastToVoidPtr(Base);
+ Address = Builder.CreateGEP(Address, Idx, "arrayidx");
Address = Builder.CreateBitCast(Address, Base->getType());
} else if (const Expr *Array = isSimpleArrayDecayOperand(E->getBase())) {
// If this is A[i] where A is an array, the frontend will have decayed the
@@ -1469,7 +1478,7 @@ llvm::Constant *GenerateConstantVector(llvm::LLVMContext &VMContext,
for (unsigned i = 0, e = Elts.size(); i != e; ++i)
CElts.push_back(llvm::ConstantInt::get(Int32Ty, Elts[i]));
- return llvm::ConstantVector::get(&CElts[0], CElts.size());
+ return llvm::ConstantVector::get(CElts);
}
LValue CodeGenFunction::
@@ -1485,7 +1494,7 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
const PointerType *PT = E->getBase()->getType()->getAs<PointerType>();
Base = MakeAddrLValue(Ptr, PT->getPointeeType());
Base.getQuals().removeObjCGCAttr();
- } else if (E->getBase()->isLvalue(getContext()) == Expr::LV_Valid) {
+ } else if (E->getBase()->isGLValue()) {
// Otherwise, if the base is an lvalue ( as in the case of foo.x.x),
// emit the base as an lvalue.
assert(E->getBase()->getType()->isVectorType());
@@ -1507,7 +1516,7 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
E->getEncodedElementAccess(Indices);
if (Base.isSimple()) {
- llvm::Constant *CV = GenerateConstantVector(VMContext, Indices);
+ llvm::Constant *CV = GenerateConstantVector(getLLVMContext(), Indices);
return LValue::MakeExtVectorElt(Base.getAddress(), CV,
Base.getVRQualifiers());
}
@@ -1522,7 +1531,7 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
else
CElts.push_back(cast<llvm::Constant>(BaseElts->getOperand(Indices[i])));
}
- llvm::Constant *CV = llvm::ConstantVector::get(&CElts[0], CElts.size());
+ llvm::Constant *CV = llvm::ConstantVector::get(CElts);
return LValue::MakeExtVectorElt(Base.getExtVectorAddr(), CV,
Base.getVRQualifiers());
}
@@ -1539,12 +1548,6 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
const PointerType *PTy =
BaseExpr->getType()->getAs<PointerType>();
BaseQuals = PTy->getPointeeType().getQualifiers();
- } else if (isa<ObjCPropertyRefExpr>(BaseExpr->IgnoreParens()) ||
- isa<ObjCImplicitSetterGetterRefExpr>(
- BaseExpr->IgnoreParens())) {
- RValue RV = EmitObjCPropertyGet(BaseExpr);
- BaseValue = RV.getAggregateAddr();
- BaseQuals = BaseExpr->getType().getQualifiers();
} else {
LValue BaseLV = EmitLValue(BaseExpr);
if (BaseLV.isNonGC())
@@ -1574,8 +1577,8 @@ LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
return LValue();
}
-LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value* BaseValue,
- const FieldDecl* Field,
+LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value *BaseValue,
+ const FieldDecl *Field,
unsigned CVRQualifiers) {
const CGRecordLayout &RL =
CGM.getTypes().getCGRecordLayout(Field->getParent());
@@ -1589,23 +1592,13 @@ LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value* BaseValue,
/// that the base value is a pointer to the enclosing record, derive
/// an lvalue for the ultimate field.
LValue CodeGenFunction::EmitLValueForAnonRecordField(llvm::Value *BaseValue,
- const FieldDecl *Field,
+ const IndirectFieldDecl *Field,
unsigned CVRQualifiers) {
- llvm::SmallVector<const FieldDecl *, 8> Path;
- Path.push_back(Field);
-
- while (Field->getParent()->isAnonymousStructOrUnion()) {
- const ValueDecl *VD = Field->getParent()->getAnonymousStructOrUnionObject();
- if (!isa<FieldDecl>(VD)) break;
- Field = cast<FieldDecl>(VD);
- Path.push_back(Field);
- }
-
- llvm::SmallVectorImpl<const FieldDecl*>::reverse_iterator
- I = Path.rbegin(), E = Path.rend();
+ IndirectFieldDecl::chain_iterator I = Field->chain_begin(),
+ IEnd = Field->chain_end();
while (true) {
- LValue LV = EmitLValueForField(BaseValue, *I, CVRQualifiers);
- if (++I == E) return LV;
+ LValue LV = EmitLValueForField(BaseValue, cast<FieldDecl>(*I), CVRQualifiers);
+ if (++I == IEnd) return LV;
assert(LV.isSimple());
BaseValue = LV.getAddress();
@@ -1613,8 +1606,8 @@ LValue CodeGenFunction::EmitLValueForAnonRecordField(llvm::Value *BaseValue,
}
}
-LValue CodeGenFunction::EmitLValueForField(llvm::Value* BaseValue,
- const FieldDecl* Field,
+LValue CodeGenFunction::EmitLValueForField(llvm::Value *BaseValue,
+ const FieldDecl *Field,
unsigned CVRQualifiers) {
if (Field->isBitField())
return EmitLValueForBitfield(BaseValue, Field, CVRQualifiers);
@@ -1628,7 +1621,7 @@ LValue CodeGenFunction::EmitLValueForField(llvm::Value* BaseValue,
if (Field->getParent()->isUnion()) {
const llvm::Type *FieldTy =
CGM.getTypes().ConvertTypeForMem(Field->getType());
- const llvm::PointerType * BaseTy =
+ const llvm::PointerType *BaseTy =
cast<llvm::PointerType>(BaseValue->getType());
unsigned AS = BaseTy->getAddressSpace();
V = Builder.CreateBitCast(V,
@@ -1650,8 +1643,8 @@ LValue CodeGenFunction::EmitLValueForField(llvm::Value* BaseValue,
}
LValue
-CodeGenFunction::EmitLValueForFieldInitialization(llvm::Value* BaseValue,
- const FieldDecl* Field,
+CodeGenFunction::EmitLValueForFieldInitialization(llvm::Value *BaseValue,
+ const FieldDecl *Field,
unsigned CVRQualifiers) {
QualType FieldType = Field->getType();
@@ -1669,71 +1662,74 @@ CodeGenFunction::EmitLValueForFieldInitialization(llvm::Value* BaseValue,
return MakeAddrLValue(V, FieldType, Alignment);
}
-LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr* E){
+LValue CodeGenFunction::EmitCompoundLiteralLValue(const CompoundLiteralExpr *E){
llvm::Value *DeclPtr = CreateMemTemp(E->getType(), ".compoundliteral");
- const Expr* InitExpr = E->getInitializer();
+ const Expr *InitExpr = E->getInitializer();
LValue Result = MakeAddrLValue(DeclPtr, E->getType());
- EmitAnyExprToMem(InitExpr, DeclPtr, /*Volatile*/ false);
+ EmitAnyExprToMem(InitExpr, DeclPtr, /*Volatile*/ false, /*Init*/ true);
return Result;
}
-LValue
-CodeGenFunction::EmitConditionalOperatorLValue(const ConditionalOperator* E) {
- if (E->isLvalue(getContext()) == Expr::LV_Valid) {
- if (int Cond = ConstantFoldsToSimpleInteger(E->getCond())) {
- Expr *Live = Cond == 1 ? E->getLHS() : E->getRHS();
- if (Live)
- return EmitLValue(Live);
- }
+LValue CodeGenFunction::
+EmitConditionalOperatorLValue(const AbstractConditionalOperator *expr) {
+ if (!expr->isGLValue()) {
+ // ?: here should be an aggregate.
+ assert((hasAggregateLLVMType(expr->getType()) &&
+ !expr->getType()->isAnyComplexType()) &&
+ "Unexpected conditional operator!");
+ return EmitAggExprToLValue(expr);
+ }
- if (!E->getLHS())
- return EmitUnsupportedLValue(E, "conditional operator with missing LHS");
+ const Expr *condExpr = expr->getCond();
- llvm::BasicBlock *LHSBlock = createBasicBlock("cond.true");
- llvm::BasicBlock *RHSBlock = createBasicBlock("cond.false");
- llvm::BasicBlock *ContBlock = createBasicBlock("cond.end");
-
- EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock);
+ if (int condValue = ConstantFoldsToSimpleInteger(condExpr)) {
+ const Expr *live = expr->getTrueExpr(), *dead = expr->getFalseExpr();
+ if (condValue == -1) std::swap(live, dead);
+
+ if (!ContainsLabel(dead))
+ return EmitLValue(live);
+ }
+
+ OpaqueValueMapping binding(*this, expr);
+
+ llvm::BasicBlock *lhsBlock = createBasicBlock("cond.true");
+ llvm::BasicBlock *rhsBlock = createBasicBlock("cond.false");
+ llvm::BasicBlock *contBlock = createBasicBlock("cond.end");
+
+ ConditionalEvaluation eval(*this);
+ EmitBranchOnBoolExpr(condExpr, lhsBlock, rhsBlock);
- // Any temporaries created here are conditional.
- BeginConditionalBranch();
- EmitBlock(LHSBlock);
- LValue LHS = EmitLValue(E->getLHS());
- EndConditionalBranch();
+ // Any temporaries created here are conditional.
+ EmitBlock(lhsBlock);
+ eval.begin(*this);
+ LValue lhs = EmitLValue(expr->getTrueExpr());
+ eval.end(*this);
- if (!LHS.isSimple())
- return EmitUnsupportedLValue(E, "conditional operator");
+ if (!lhs.isSimple())
+ return EmitUnsupportedLValue(expr, "conditional operator");
- // FIXME: We shouldn't need an alloca for this.
- llvm::Value *Temp = CreateTempAlloca(LHS.getAddress()->getType(),"condtmp");
- Builder.CreateStore(LHS.getAddress(), Temp);
- EmitBranch(ContBlock);
-
- // Any temporaries created here are conditional.
- BeginConditionalBranch();
- EmitBlock(RHSBlock);
- LValue RHS = EmitLValue(E->getRHS());
- EndConditionalBranch();
- if (!RHS.isSimple())
- return EmitUnsupportedLValue(E, "conditional operator");
-
- Builder.CreateStore(RHS.getAddress(), Temp);
- EmitBranch(ContBlock);
-
- EmitBlock(ContBlock);
+ lhsBlock = Builder.GetInsertBlock();
+ Builder.CreateBr(contBlock);
- Temp = Builder.CreateLoad(Temp, "lv");
- return MakeAddrLValue(Temp, E->getType());
- }
-
- // ?: here should be an aggregate.
- assert((hasAggregateLLVMType(E->getType()) &&
- !E->getType()->isAnyComplexType()) &&
- "Unexpected conditional operator!");
+ // Any temporaries created here are conditional.
+ EmitBlock(rhsBlock);
+ eval.begin(*this);
+ LValue rhs = EmitLValue(expr->getFalseExpr());
+ eval.end(*this);
+ if (!rhs.isSimple())
+ return EmitUnsupportedLValue(expr, "conditional operator");
+ rhsBlock = Builder.GetInsertBlock();
- return EmitAggExprToLValue(E);
+ EmitBlock(contBlock);
+
+ llvm::PHINode *phi = Builder.CreatePHI(lhs.getAddress()->getType(),
+ "cond-lvalue");
+ phi->reserveOperandSpace(2);
+ phi->addIncoming(lhs.getAddress(), lhsBlock);
+ phi->addIncoming(rhs.getAddress(), rhsBlock);
+ return MakeAddrLValue(phi, expr->getType());
}
/// EmitCastLValue - Casts are never lvalues unless that cast is a dynamic_cast.
@@ -1747,36 +1743,57 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
switch (E->getCastKind()) {
case CK_ToVoid:
return EmitUnsupportedLValue(E, "unexpected cast lvalue");
-
- case CK_NoOp:
- if (E->getSubExpr()->Classify(getContext()).getKind()
- != Expr::Classification::CL_PRValue) {
- LValue LV = EmitLValue(E->getSubExpr());
- if (LV.isPropertyRef() || LV.isKVCRef()) {
- QualType QT = E->getSubExpr()->getType();
- RValue RV =
- LV.isPropertyRef() ? EmitLoadOfPropertyRefLValue(LV, QT)
- : EmitLoadOfKVCRefLValue(LV, QT);
- assert(!RV.isScalar() && "EmitCastLValue-scalar cast of property ref");
- llvm::Value *V = RV.getAggregateAddr();
- return MakeAddrLValue(V, QT);
- }
- return LV;
+
+ case CK_Dependent:
+ llvm_unreachable("dependent cast kind in IR gen!");
+
+ case CK_GetObjCProperty: {
+ LValue LV = EmitLValue(E->getSubExpr());
+ assert(LV.isPropertyRef());
+ RValue RV = EmitLoadOfPropertyRefLValue(LV);
+
+ // Property is an aggregate r-value.
+ if (RV.isAggregate()) {
+ return MakeAddrLValue(RV.getAggregateAddr(), E->getType());
}
+
+ // Implicit property returns an l-value.
+ assert(RV.isScalar());
+ return MakeAddrLValue(RV.getScalarVal(), E->getSubExpr()->getType());
+ }
+
+ case CK_NoOp:
+ case CK_LValueToRValue:
+ if (!E->getSubExpr()->Classify(getContext()).isPRValue()
+ || E->getType()->isRecordType())
+ return EmitLValue(E->getSubExpr());
// Fall through to synthesize a temporary.
-
- case CK_Unknown:
+
case CK_BitCast:
case CK_ArrayToPointerDecay:
case CK_FunctionToPointerDecay:
case CK_NullToMemberPointer:
+ case CK_NullToPointer:
case CK_IntegralToPointer:
case CK_PointerToIntegral:
+ case CK_PointerToBoolean:
case CK_VectorSplat:
case CK_IntegralCast:
+ case CK_IntegralToBoolean:
case CK_IntegralToFloating:
case CK_FloatingToIntegral:
+ case CK_FloatingToBoolean:
case CK_FloatingCast:
+ case CK_FloatingRealToComplex:
+ case CK_FloatingComplexToReal:
+ case CK_FloatingComplexToBoolean:
+ case CK_FloatingComplexCast:
+ case CK_FloatingComplexToIntegralComplex:
+ case CK_IntegralRealToComplex:
+ case CK_IntegralComplexToReal:
+ case CK_IntegralComplexToBoolean:
+ case CK_IntegralComplexCast:
+ case CK_IntegralComplexToFloatingComplex:
case CK_DerivedToBaseMemberPointer:
case CK_BaseToDerivedMemberPointer:
case CK_MemberPointerToBoolean:
@@ -1810,17 +1827,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
cast<CXXRecordDecl>(DerivedClassTy->getDecl());
LValue LV = EmitLValue(E->getSubExpr());
- llvm::Value *This;
- if (LV.isPropertyRef() || LV.isKVCRef()) {
- QualType QT = E->getSubExpr()->getType();
- RValue RV =
- LV.isPropertyRef() ? EmitLoadOfPropertyRefLValue(LV, QT)
- : EmitLoadOfKVCRefLValue(LV, QT);
- assert (!RV.isScalar() && "EmitCastLValue");
- This = RV.getAggregateAddr();
- }
- else
- This = LV.getAddress();
+ llvm::Value *This = LV.getAddress();
// Perform the derived-to-base conversion
llvm::Value *Base =
@@ -1876,6 +1883,11 @@ LValue CodeGenFunction::EmitNullInitializationLValue(
return LV;
}
+LValue CodeGenFunction::EmitOpaqueValueLValue(const OpaqueValueExpr *e) {
+ assert(e->isGLValue() || e->getType()->isRecordType());
+ return getOpaqueLValueMapping(e);
+}
+
//===--------------------------------------------------------------------===//
// Expression Emission
//===--------------------------------------------------------------------===//
@@ -1922,7 +1934,7 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E,
LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) {
// Comma expressions just emit their LHS then their RHS as an l-value.
if (E->getOpcode() == BO_Comma) {
- EmitAnyExpr(E->getLHS());
+ EmitIgnoredExpr(E->getLHS());
EnsureInsertPoint();
return EmitLValue(E->getRHS());
}
@@ -1930,20 +1942,20 @@ LValue CodeGenFunction::EmitBinaryOperatorLValue(const BinaryOperator *E) {
if (E->getOpcode() == BO_PtrMemD ||
E->getOpcode() == BO_PtrMemI)
return EmitPointerToDataMemberBinaryExpr(E);
-
- // Can only get l-value for binary operator expressions which are a
- // simple assignment of aggregate type.
- if (E->getOpcode() != BO_Assign)
- return EmitUnsupportedLValue(E, "binary l-value expression");
+ assert(E->getOpcode() == BO_Assign && "unexpected binary l-value");
+
if (!hasAggregateLLVMType(E->getType())) {
- // Emit the LHS as an l-value.
+ // __block variables need the RHS evaluated first.
+ RValue RV = EmitAnyExpr(E->getRHS());
LValue LV = EmitLValue(E->getLHS());
- // Store the value through the l-value.
- EmitStoreThroughLValue(EmitAnyExpr(E->getRHS()), LV, E->getType());
+ EmitStoreThroughLValue(RV, LV, E->getType());
return LV;
}
-
+
+ if (E->getType()->isAnyComplexType())
+ return EmitComplexAssignmentLValue(E);
+
return EmitAggExprToLValue(E);
}
@@ -1966,9 +1978,11 @@ LValue CodeGenFunction::EmitVAArgExprLValue(const VAArgExpr *E) {
}
LValue CodeGenFunction::EmitCXXConstructLValue(const CXXConstructExpr *E) {
- llvm::Value *Temp = CreateMemTemp(E->getType(), "tmp");
- EmitCXXConstructExpr(Temp, E);
- return MakeAddrLValue(Temp, E->getType());
+ assert(E->getType()->getAsCXXRecordDecl()->hasTrivialDestructor()
+ && "binding l-value to type which needs a temporary");
+ AggValueSlot Slot = CreateAggTemp(E->getType(), "tmp");
+ EmitCXXConstructExpr(E, Slot);
+ return MakeAddrLValue(Slot.getAddr(), E->getType());
}
LValue
@@ -1978,9 +1992,11 @@ CodeGenFunction::EmitCXXTypeidLValue(const CXXTypeidExpr *E) {
LValue
CodeGenFunction::EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E) {
- LValue LV = EmitLValue(E->getSubExpr());
- EmitCXXTemporary(E->getTemporary(), LV.getAddress());
- return LV;
+ AggValueSlot Slot = CreateAggTemp(E->getType(), "temp.lvalue");
+ Slot.setLifetimeExternallyManaged();
+ EmitAggExpr(E->getSubExpr(), Slot);
+ EmitCXXTemporary(E->getTemporary(), Slot.getAddr());
+ return MakeAddrLValue(Slot.getAddr(), E->getType());
}
LValue CodeGenFunction::EmitObjCMessageExprLValue(const ObjCMessageExpr *E) {
@@ -2040,24 +2056,6 @@ LValue CodeGenFunction::EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E) {
return LV;
}
-LValue
-CodeGenFunction::EmitObjCPropertyRefLValue(const ObjCPropertyRefExpr *E) {
- // This is a special l-value that just issues sends when we load or store
- // through it.
- return LValue::MakePropertyRef(E, E->getType().getCVRQualifiers());
-}
-
-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) {
- 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);
@@ -2078,7 +2076,6 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, llvm::Value *Callee,
const FunctionType *FnType
= cast<FunctionType>(cast<PointerType>(CalleeType)->getPointeeType());
- QualType ResultType = FnType->getResultType();
CallArgList Args;
EmitCallArgs(Args, dyn_cast<FunctionProtoType>(FnType), ArgBeg, ArgEnd);
@@ -2105,4 +2102,3 @@ EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E) {
return MakeAddrLValue(AddV, MPT->getPointeeType());
}
-