Move the LLVM field number for bit fields into the BitFieldInfo structure, since it's meaning is completely different than for non-bit fields.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76882 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index de44e69..9b5b68d 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -1026,7 +1026,8 @@
LValue CodeGenFunction::EmitLValueForBitfield(llvm::Value* BaseValue,
FieldDecl* Field,
unsigned CVRQualifiers) {
- unsigned idx = CGM.getTypes().getLLVMFieldNo(Field);
+ CodeGenTypes::BitFieldInfo Info = CGM.getTypes().getBitFieldInfo(Field);
+
// FIXME: CodeGenTypes should expose a method to get the appropriate type for
// FieldTy (the appropriate type is ABI-dependent).
const llvm::Type *FieldTy =
@@ -1037,13 +1038,12 @@
BaseValue = Builder.CreateBitCast(BaseValue,
VMContext.getPointerType(FieldTy, AS),
"tmp");
- llvm::Value *V = Builder.CreateGEP(BaseValue,
- VMContext.getConstantInt(llvm::Type::Int32Ty, idx),
- "tmp");
- CodeGenTypes::BitFieldInfo bitFieldInfo =
- CGM.getTypes().getBitFieldInfo(Field);
- return LValue::MakeBitfield(V, bitFieldInfo.Begin, bitFieldInfo.Size,
+ llvm::Value *Idx =
+ VMContext.getConstantInt(llvm::Type::Int32Ty, Info.FieldNo);
+ llvm::Value *V = Builder.CreateGEP(BaseValue, Idx, "tmp");
+
+ return LValue::MakeBitfield(V, Info.Start, Info.Size,
Field->getType()->isSignedIntegerType(),
Field->getType().getCVRQualifiers()|CVRQualifiers);
}
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp
index 43284b5..61b217b 100644
--- a/lib/CodeGen/CGExprConstant.cpp
+++ b/lib/CodeGen/CGExprConstant.cpp
@@ -139,16 +139,16 @@
const llvm::Type* Ty = CI->getType();
const llvm::TargetData &TD = CGM.getTypes().getTargetData();
unsigned size = TD.getTypeAllocSizeInBits(Ty);
- unsigned fieldOffset = CGM.getTypes().getLLVMFieldNo(Field) * size;
- CodeGenTypes::BitFieldInfo bitFieldInfo =
- CGM.getTypes().getBitFieldInfo(Field);
- fieldOffset += bitFieldInfo.Begin;
+ CodeGenTypes::BitFieldInfo Info = CGM.getTypes().getBitFieldInfo(Field);
+ unsigned FieldOffset = Info.FieldNo * size;
+
+ FieldOffset += Info.Start;
// Find where to start the insertion
// FIXME: This is O(n^2) in the number of bit-fields!
// FIXME: This won't work if the struct isn't completely packed!
unsigned offset = 0, i = 0;
- while (offset < (fieldOffset & -8))
+ while (offset < (FieldOffset & -8))
offset += TD.getTypeAllocSizeInBits(Elts[i++]->getType());
// Advance over 0 sized elements (must terminate in bounds since
@@ -160,15 +160,15 @@
// FIXME: This should never occur, but currently it can because initializer
// constants are cast to bool, and because clang is not enforcing bitfield
// width limits.
- if (bitFieldInfo.Size > V.getBitWidth())
- V.zext(bitFieldInfo.Size);
+ if (Info.Size > V.getBitWidth())
+ V.zext(Info.Size);
// Insert the bits into the struct
// FIXME: This algorthm is only correct on X86!
// FIXME: THis algorthm assumes bit-fields only have byte-size elements!
- unsigned bitsToInsert = bitFieldInfo.Size;
- unsigned curBits = std::min(8 - (fieldOffset & 7), bitsToInsert);
- unsigned byte = V.getLoBits(curBits).getZExtValue() << (fieldOffset & 7);
+ unsigned bitsToInsert = Info.Size;
+ unsigned curBits = std::min(8 - (FieldOffset & 7), bitsToInsert);
+ unsigned byte = V.getLoBits(curBits).getZExtValue() << (FieldOffset & 7);
do {
llvm::Constant* byteC =
VMContext.getConstantInt(llvm::Type::Int8Ty, byte);
diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp
index fa096bd..5f6946d 100644
--- a/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -85,8 +85,8 @@
const llvm::Type *Ty = Types.ConvertTypeForMemRecursive(D->getType());
uint64_t TypeSizeInBits = getTypeSizeInBytes(Ty) * 8;
- LLVMFields.push_back(LLVMFieldInfo(D, FieldOffset / TypeSizeInBits));
- LLVMBitFields.push_back(LLVMBitFieldInfo(D, FieldOffset % TypeSizeInBits,
+ LLVMBitFields.push_back(LLVMBitFieldInfo(D, FieldOffset / TypeSizeInBits,
+ FieldOffset % TypeSizeInBits,
FieldSize));
AppendBytes(NumBytesToAppend);
@@ -190,13 +190,13 @@
// Now add our field.
if (FD) {
AppendField(0, Size, Ty);
- Types.addFieldInfo(FD, 0);
if (FD->isBitField()) {
uint64_t FieldSize =
FD->getBitWidth()->EvaluateAsInt(Types.getContext()).getZExtValue();
- Types.addBitFieldInfo(FD, 0, FieldSize);
- }
+ Types.addBitFieldInfo(FD, 0, 0, FieldSize);
+ } else
+ Types.addFieldInfo(FD, 0);
}
// Append tail padding.
@@ -324,7 +324,7 @@
for (unsigned i = 0, e = Builder.LLVMBitFields.size(); i != e; ++i) {
const LLVMBitFieldInfo &Info = Builder.LLVMBitFields[i];
- Types.addBitFieldInfo(Info.FD, Info.Start, Info.Size);
+ Types.addBitFieldInfo(Info.FD, Info.FieldNo, Info.Start, Info.Size);
}
return new CGRecordLayout(Ty, llvm::SmallSet<unsigned, 8>());
diff --git a/lib/CodeGen/CGRecordLayoutBuilder.h b/lib/CodeGen/CGRecordLayoutBuilder.h
index c1ba605..2f212f8 100644
--- a/lib/CodeGen/CGRecordLayoutBuilder.h
+++ b/lib/CodeGen/CGRecordLayoutBuilder.h
@@ -66,11 +66,13 @@
/// LLVMBitFieldInfo - Holds location and size information about a bit field.
struct LLVMBitFieldInfo {
- LLVMBitFieldInfo(const FieldDecl *FD, unsigned Start, unsigned Size)
- : FD(FD), Start(Start), Size(Size) { }
+ LLVMBitFieldInfo(const FieldDecl *FD, unsigned FieldNo, unsigned Start,
+ unsigned Size)
+ : FD(FD), FieldNo(FieldNo), Start(Start), Size(Size) { }
const FieldDecl *FD;
+ unsigned FieldNo;
unsigned Start;
unsigned Size;
};
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index 59463fa..0869b2d 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -494,6 +494,8 @@
/// getLLVMFieldNo - Return llvm::StructType element number
/// that corresponds to the field FD.
unsigned CodeGenTypes::getLLVMFieldNo(const FieldDecl *FD) {
+ assert(!FD->isBitField() && "Don't use getLLVMFieldNo on bit fields!");
+
llvm::DenseMap<const FieldDecl*, unsigned>::iterator I = FieldInfo.find(FD);
assert (I != FieldInfo.end() && "Unable to find field info");
return I->second;
@@ -513,9 +515,9 @@
}
/// addBitFieldInfo - Assign a start bit and a size to field FD.
-void CodeGenTypes::addBitFieldInfo(const FieldDecl *FD, unsigned Begin,
- unsigned Size) {
- BitFields.insert(std::make_pair(FD, BitFieldInfo(Begin, Size)));
+void CodeGenTypes::addBitFieldInfo(const FieldDecl *FD, unsigned FieldNo,
+ unsigned Start, unsigned Size) {
+ BitFields.insert(std::make_pair(FD, BitFieldInfo(FieldNo, Start, Size)));
}
/// getCGRecordLayout - Return record layout info for the given llvm::Type.
@@ -559,8 +561,7 @@
// Bitfield field info is different from other field info;
// it actually ignores the underlying LLVM struct because
// there isn't any convenient mapping.
- CGT.addFieldInfo(*Field, offset / size);
- CGT.addBitFieldInfo(*Field, offset % size, BitFieldSize);
+ CGT.addBitFieldInfo(*Field, offset / size, offset % size, BitFieldSize);
} else {
// Put the element into the struct. This would be simpler
// if we didn't bother, but it seems a bit too strange to
@@ -603,8 +604,7 @@
uint64_t BitFieldSize =
BitWidth->EvaluateAsInt(CGT.getContext()).getZExtValue();
- CGT.addFieldInfo(*Field, 0);
- CGT.addBitFieldInfo(*Field, offset, BitFieldSize);
+ CGT.addBitFieldInfo(*Field, 0, offset, BitFieldSize);
} else {
CGT.addFieldInfo(*Field, 0);
}
diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h
index 925b933..0f6e51d 100644
--- a/lib/CodeGen/CodeGenTypes.h
+++ b/lib/CodeGen/CodeGenTypes.h
@@ -113,13 +113,15 @@
llvm::FoldingSet<CGFunctionInfo> FunctionInfos;
public:
- class BitFieldInfo {
- public:
- explicit BitFieldInfo(unsigned short B, unsigned short S)
- : Begin(B), Size(S) {}
+ struct BitFieldInfo {
+ BitFieldInfo(unsigned FieldNo,
+ unsigned Start,
+ unsigned Size)
+ : FieldNo(FieldNo), Start(Start), Size(Size) {}
- unsigned short Begin;
- unsigned short Size;
+ unsigned FieldNo;
+ unsigned Start;
+ unsigned Size;
};
private:
@@ -188,10 +190,11 @@
public: // These are internal details of CGT that shouldn't be used externally.
/// addFieldInfo - Assign field number to field FD.
- void addFieldInfo(const FieldDecl *FD, unsigned No);
+ void addFieldInfo(const FieldDecl *FD, unsigned FieldNo);
/// addBitFieldInfo - Assign a start bit and a size to field FD.
- void addBitFieldInfo(const FieldDecl *FD, unsigned Begin, unsigned Size);
+ void addBitFieldInfo(const FieldDecl *FD, unsigned FieldNo,
+ unsigned Start, unsigned Size);
/// getBitFieldInfo - Return the BitFieldInfo that corresponds to the field
/// FD.