#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;
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);
}
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");
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();
--- /dev/null
+// RUN: clang -emit-llvm %s
+
+// From GCC PR19331
+struct SysParams
+{
+ unsigned short tag;
+ unsigned short version;
+ unsigned int seqnum;
+ int contrast;
+ int igain_1, igain_2;
+ int oattn_1, oattn_2;
+ int max_out_vltg_1, max_out_vltg_2;
+ int max_mains_current;
+ int meters_mode;
+ int input_select;
+ _Bool input_parallelch2:1;
+ _Bool cliplmt_ch1:1;
+ _Bool cliplmt_ch2:1;
+ _Bool gate_ch1:1;
+ _Bool gate_ch2:1;
+ _Bool mute_ch1:1;
+ _Bool mute_ch2:1;
+ _Bool brownout:1;
+ _Bool power_on:1;
+ _Bool pwrup_mute:1;
+ _Bool keylock:1;
+ _Bool dsp_ch1:1;
+ _Bool dsp_ch2:1;
+ int dsp_preset;
+ long unlock_code;
+};
+extern struct SysParams params;
+
+void foo(void *);
+void kcmd_setParams(void)
+{
+ struct {
+ unsigned char igain_1;
+ unsigned char igain_2;
+ unsigned char max_out_vltg_1;
+ unsigned char max_out_vltg_2;
+ unsigned char max_imains;
+ unsigned char cliplmt_ch1:1;
+ unsigned char cliplmt_ch2:1;
+ unsigned char gate_ch1:1;
+ unsigned char gate_ch2:1;
+ } msg;
+ foo(&msg);
+ params.cliplmt_ch1 = msg.cliplmt_ch1;
+ params.cliplmt_ch2 = msg.cliplmt_ch2;
+ params.gate_ch1 = msg.gate_ch1;
+ params.gate_ch2 = msg.gate_ch2;
+}
+