Hi all!
I am writing CGRecordLayoutBuilder for Microsoft ABI and I have a problem.
I have the following code for testing test code - Pastebin.com .
When generated layout for a class C, I have break assert in CGRecordLayoutBuilder.cpp line 968
assert(TypeSizeInBits == getTargetData().getTypeAllocSizeInBits(Ty) &&
"Type size mismatch!");.
During debugging, I discovered that TypeSizeInBits smaller getTargetData().getTypeAllocSizeInBits(Ty) 4 bytes.
After investigation, I discovered that the alignment is added in StructLayout constructor (TargetData.cpp line 73)
// Add padding to the end of the struct so that it could be put in an array
// and all array elements would be aligned correctly.
if ((StructSize & (StructAlignment-1)) != 0)
StructSize = TargetData::RoundUpAlignment(StructSize, StructAlignment);
But this alignment is not necessary for class C.
MSVC doesn't add to the end of the class alignment, if it has a virtual base classes.
I see two solutions to this problem:
1. Rewrite assert like this
(pseudocode)
if ABI == Microsoft && Class has virtual basses
assert(TypeSizeInBits == (getTargetData().getTypeAllocSizeInBits(Ty) - 32) &&
"Type size mismatch!");
else
old version;
2. Provide to StructLyout information about ABI.
I think the first way is more simple.
What is the best way to solve this problem?
Maybe you able to offer a better approach?
- Dmitry.