]> granicus.if.org Git - clang/commitdiff
change EmitLValueForField to cast the returned lvalue to the right
authorChris Lattner <sabre@nondot.org>
Sun, 10 Jul 2011 05:34:54 +0000 (05:34 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 10 Jul 2011 05:34:54 +0000 (05:34 +0000)
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

lib/CodeGen/CGExpr.cpp

index c7a104ea45134d764df72f8ad518e6acadb4e214..b9746330bf10455e02c51ea4d4ce5cf50755ee97 100644 (file)
@@ -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);