aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExpr.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2011-07-10 05:34:54 +0000
committerChris Lattner <sabre@nondot.org>2011-07-10 05:34:54 +0000
commit74339dfbfe3fa9c1839ce02e3427e4dc5478a3ae (patch)
tree3a5b5d0322337d0683bcb25817fde5426b7285f4 /lib/CodeGen/CGExpr.cpp
parentf0a8679b6e6635117533b89894646f1450cea25b (diff)
change EmitLValueForField to cast the returned lvalue to the right
type, even when in the struct case. This was one root issue that was causing type mismatches throughout the compiler. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134862 91177308-0d34-0410-b5e6-96231b3b80d8
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);