Fix support for _Bool bitfields. The issue is that the bitfield width 
used for _Bool is not the same as the primitive width (which for _Bool 
is 1 bit).  The load and store changes add some casts to make the 
types consistent.  The EmitLValue changes make sure that the pointer is 
of an appropriate type for loading the bitfield.

This isn't perfect, but it's an improvement, and getting everything 
right depends on actually laying out structs in an ABI-compliant way.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@51224 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index d679107..840ed43 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -14,11 +14,13 @@
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
 #include "clang/AST/AST.h"
+#include "clang/Basic/TargetInfo.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Function.h"
 #include "llvm/GlobalVariable.h"
 #include "llvm/Support/MathExtras.h"
+#include "llvm/Target/TargetData.h"
 using namespace clang;
 using namespace CodeGen;
 
@@ -175,6 +177,11 @@
   V = LV.isBitfieldSigned() ?
     Builder.CreateAShr(V, ShAmt, "tmp") :
     Builder.CreateLShr(V, ShAmt, "tmp");
+
+  // The bitfield type and the normal type differ when the storage sizes
+  // differ (currently just _Bool).
+  V = Builder.CreateIntCast(V, ConvertType(ExprType), false, "tmp");
+
   return RValue::get(V);
 }
 
@@ -280,13 +287,18 @@
   unsigned short StartBit = Dst.getBitfieldStartBit();
   unsigned short BitfieldSize = Dst.getBitfieldSize();
   llvm::Value *Ptr = Dst.getBitfieldAddr();
-  const llvm::Type *EltTy =
-    cast<llvm::PointerType>(Ptr->getType())->getElementType();
-  unsigned EltTySize = EltTy->getPrimitiveSizeInBits();
 
   llvm::Value *NewVal = Src.getScalarVal();
   llvm::Value *OldVal = Builder.CreateLoad(Ptr, "tmp");
 
+  // The bitfield type and the normal type differ when the storage sizes
+  // differ (currently just _Bool).
+  const llvm::Type *EltTy = OldVal->getType();
+  unsigned EltTySize = CGM.getTargetData().getABITypeSizeInBits(EltTy);
+
+  NewVal = Builder.CreateIntCast(NewVal, EltTy, false, "tmp");
+
+  // Move the bits into the appropriate location
   llvm::Value *ShAmt = llvm::ConstantInt::get(EltTy, StartBit);
   NewVal = Builder.CreateShl(NewVal, ShAmt, "tmp");
 
@@ -531,7 +543,11 @@
   if (!Field->isBitField()) {
     V = Builder.CreateStructGEP(BaseValue, idx, "tmp");
   } else {
-    const llvm::Type *FieldTy = ConvertType(Field->getType());
+    // FIXME: CodeGenTypes should expose a method to get the appropriate
+    // type for FieldTy (the appropriate type is ABI-dependent).
+    unsigned EltTySize =
+      CGM.getTargetData().getABITypeSizeInBits(ConvertType(Field->getType()));
+    const llvm::Type *FieldTy = llvm::IntegerType::get(EltTySize);
     const llvm::PointerType *BaseTy =
       cast<llvm::PointerType>(BaseValue->getType());
     unsigned AS = BaseTy->getAddressSpace();