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.cpp31
1 files changed, 18 insertions, 13 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index c7a104ea45..b9746330bf 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -247,6 +247,7 @@ EmitExprForReferenceBinding(CodeGenFunction &CGF, const Expr *E,
RV = CGF.EmitLoadOfPropertyRefLValue(LV);
return RV.getScalarVal();
}
+
if (LV.isSimple())
return LV.getAddress();
@@ -460,9 +461,7 @@ CodeGenFunction::EmitReferenceBindingToExpr(const Expr *E,
else {
switch (ObjCARCReferenceLifetimeType.getObjCLifetime()) {
case Qualifiers::OCL_None:
- llvm_unreachable("Not a reference temporary that needs to be deallocated");
- break;
-
+ assert(0 && "Not a reference temporary that needs to be deallocated");
case Qualifiers::OCL_ExplicitNone:
case Qualifiers::OCL_Autoreleasing:
// Nothing to do.
@@ -769,6 +768,7 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr,
llvm::MDNode *TBAAInfo) {
Value = EmitToMemory(Value, Ty);
+ // If this is a pointer r-value, make sure that it has the right scalar type.
if (isa<llvm::PointerType>(Value->getType())) {
llvm::Type *EltTy =
cast<llvm::PointerType>(Addr->getType())->getElementType();
@@ -1295,13 +1295,14 @@ static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF,
if (VD->getType()->isReferenceType())
V = CGF.Builder.CreateLoad(V, "tmp");
unsigned Alignment = CGF.getContext().getDeclAlign(VD).getQuantity();
+
LValue LV = CGF.MakeAddrLValue(V, E->getType(), Alignment);
setObjCGCLValueClass(CGF.getContext(), E, LV);
return LV;
}
static LValue EmitFunctionDeclLValue(CodeGenFunction &CGF,
- const Expr *E, const FunctionDecl *FD) {
+ const Expr *E, const FunctionDecl *FD) {
llvm::Value *V = CGF.CGM.GetAddrOfFunction(FD);
if (!FD->hasPrototype()) {
if (const FunctionProtoType *Proto =
@@ -1813,20 +1814,14 @@ LValue CodeGenFunction::EmitLValueForField(llvm::Value *baseAddr,
bool mayAlias = rec->hasAttr<MayAliasAttr>();
- llvm::Value *addr;
+ llvm::Value *addr = baseAddr;
if (rec->isUnion()) {
- // For unions, we just cast to the appropriate type.
+ // For unions, there is no pointer adjustment.
assert(!type->isReferenceType() && "union has reference member");
-
- const llvm::Type *llvmType = CGM.getTypes().ConvertTypeForMem(type);
- unsigned AS =
- cast<llvm::PointerType>(baseAddr->getType())->getAddressSpace();
- addr = Builder.CreateBitCast(baseAddr, llvmType->getPointerTo(AS),
- field->getName());
} else {
// For structs, we GEP to the field that the record layout suggests.
unsigned idx = CGM.getTypes().getCGRecordLayout(rec).getLLVMFieldNo(field);
- addr = Builder.CreateStructGEP(baseAddr, idx, field->getName());
+ addr = Builder.CreateStructGEP(addr, idx, field->getName());
// If this is a reference field, load the reference right now.
if (const ReferenceType *refType = type->getAs<ReferenceType>()) {
@@ -1848,6 +1843,16 @@ LValue CodeGenFunction::EmitLValueForField(llvm::Value *baseAddr,
cvr = 0; // qualifiers don't recursively apply to referencee
}
}
+
+ // Make sure that the address is pointing to the right type. This is critical
+ // for both unions and structs. A union needs a bitcast, a struct element
+ // will need a bitcast if the LLVM type laid out doesn't match the desired
+ // type.
+ const llvm::Type *llvmType = CGM.getTypes().ConvertTypeForMem(type);
+ unsigned AS = cast<llvm::PointerType>(baseAddr->getType())->getAddressSpace();
+ addr = Builder.CreateBitCast(addr, llvmType->getPointerTo(AS),
+ field->getName());
+
unsigned alignment = getContext().getDeclAlign(field).getQuantity();
LValue LV = MakeAddrLValue(addr, type, alignment);