[cfe-dev] Implementation of the CGRecordLayoutBuilder for Microsoft ABI.

r4start r4start at gmail.com
Fri Sep 23 05:30:53 PDT 2011


Hi all!

I am writing CGRecordLayoutBuilder for Microsoft ABI and I have a problem.
I have the following code for testing http://pastebin.com/27U2hcDC .

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.



More information about the cfe-dev mailing list