This is an attempt for adding bitfield support to __builtin_dump_struct.
Details
Diff Detail
- Repository
- rC Clang
Event Timeline
This version is working for non packed structures. For packed structures, it might sometimes work, sometimes not.
The resulting assembly code seems to be the right one.
If someone went through bitfields manipulation, please do not hesitate to comment !
Requesting for help :)
lib/CodeGen/CGBuiltin.cpp | ||
---|---|---|
1250 | What happens if this overflows due to being < 0? |
I will for sure add tests @lebedev.ri . Fact is that, for the moment, this is not working as expected.
This is why I am asking for a bit of help about this bitfield handling :)
lib/CodeGen/CGBuiltin.cpp | ||
---|---|---|
1250 | How could this be < 0 ? |
Adding a few more reviewers to see if they have ideas on the bitfield handling. Can you describe a bit more about what's incorrect with it when the structures are packed? Code examples might help.
lib/CodeGen/CGBuiltin.cpp | ||
---|---|---|
1250 | I don't think it should happen in the normal course of things. I'd probably just put in an assert to ensure that the high bit is never set in HighBits unless it's also set in StorageSize. |
Yeah, I know nothing about this dump feature or what's being fixed here - test cases would be great to help motivate/explain.
First thanks all for reviewing !
Basically, what's happening is that it works good with non-packed structures.
Here is an example for packed structure (with unsigned signed short):
struct lol { unsigned short a:3; unsigned short b:2; unsigned short c:6; unsigned short d:2; unsigned short e:6; } __attribute__((packed)); int main(void) { struct lol lolo = { .a = 2, .b = 1, .c = 13, .d = 2, .e = 9 }; __builtin_dump_struct(&lolo, &printf); return 0; }
Here is the output I get :
unsigned short a : 2 unsigned short b : 1 unsigned short c : 13 unsigned short d : 2 unsigned short e : 1
The last unsigned short is incorrect.
If I switch this to signed integers, I get :
unsigned short a : 0 unsigned short b : 0 unsigned short c : 0 unsigned short d : 0 unsigned short e : 0
All the fields are zeroed. I absolutely do not understand what is happening...
Thanks for trying to help guys !
This doesn't seem to build for me - so hard to debug/probe it:
llvm/src/tools/clang/lib/CodeGen/CGBuiltin.cpp:1264:65: error: no viable conversion from 'clang::QualType' to 'llvm::Type *'
CGF.CGM.getDataLayout().getTypeSizeInBits(CanonicalType), ^~~~~~~~~~~~~
llvm/src/include/llvm/IR/DataLayout.h:560:53: note: passing argument to parameter 'Ty' here
inline uint64_t DataLayout::getTypeSizeInBits(Type *Ty) const {
^
1 error generated.
Yeah, doesn't look like this code handles a value crossing the boundary of
the size of the bitfield type (it's reading only the low bit).
I suspect looking at the code that generates bitfield accesses would be
useful - and/or maybe actually calling into that very code, rather than
reimplementing it here? CodeGenFunction::EmitLoadOfBitfieldLValue seems to
be the place to go (I found this by writing a short example that loads one
of these strided bitfield values & then breaking in
llvm::BinaryOperator::BinaryOperator until I found the 'and' operation,
since that seemed like the more interesting one).
What happens if this overflows due to being < 0?