aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExpr.cpp
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2008-05-17 20:03:47 +0000
committerEli Friedman <eli.friedman@gmail.com>2008-05-17 20:03:47 +0000
commit316bb1b9eb9dc3da60e930f50c9b7578411d4966 (patch)
tree42ea2358ffb8a4546b5e7aa0e9b08f02113099df /lib/CodeGen/CGExpr.cpp
parent489ecd59eff2602744cbd5089c48ad0d77963dfa (diff)
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
Diffstat (limited to 'lib/CodeGen/CGExpr.cpp')
-rw-r--r--lib/CodeGen/CGExpr.cpp24
1 files changed, 20 insertions, 4 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index d6791074c7..840ed4314f 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 @@ 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();