diff options
| author | Eli Friedman <eli.friedman@gmail.com> | 2008-05-17 20:03:47 +0000 | 
|---|---|---|
| committer | Eli Friedman <eli.friedman@gmail.com> | 2008-05-17 20:03:47 +0000 | 
| commit | f2442dcc8d653d3dcb37104df35357d2ed31a31a (patch) | |
| tree | a6d786f30735ee3799676e63881ef908dbd649f4 /clang/lib/CodeGen | |
| parent | eb185ca5e95aad1e3f61971bf1e39b1035b409d1 (diff) | |
| download | bcm5719-llvm-f2442dcc8d653d3dcb37104df35357d2ed31a31a.tar.gz bcm5719-llvm-f2442dcc8d653d3dcb37104df35357d2ed31a31a.zip | |
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.
llvm-svn: 51224
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 24 | 
1 files changed, 20 insertions, 4 deletions
| diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index d6791074c7d..840ed4314f6 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/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 @@ RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV,    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 @@ void CodeGenFunction::EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst,    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 @@ LValue CodeGenFunction::EmitLValueForField(llvm::Value* BaseValue,    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(); | 

