Search code examples
c++macosclangllvm

Dumping memory layout of C++ object does not work in clang


I have read an article about dumping a C++ object's memory layout with Clang and now I am trying to play with this feature. I have create two classes:

// simple.cpp
struct Base
{
    int value;
};

struct Derived : Base
{
    int count;
};

int main(int argc, char* argv[])
{
    return 0;
}

and run the following command:

$ clang -cc1 -fdump-record-layouts-simple simple.cpp

and get nothing. clang version is:

$ clang++ -dumpversion
4.2.1

If I run the following command:

$ clang -cc1 --help

and among a lot information I can find this one:

...
  -fdump-record-layouts-simple
                          Dump record layout information in a simple form used for testing
  -fdump-record-layouts   Dump record layout information
  -fdump-vtable-layouts   Dump the layouts of all vtables that will be emitted in a translation unit
...

What I do wrong?


Solution

  • You need to make two changes:

    1. Add the -emit-llvm compiler switch. Without this, LLVM output is not required, so record layouts are never computed and so not dumped.
    2. Use the classes in your code. If the classes are never used, no code generation is done for them, and their layouts are not dumped.

    With these changes made, output like this is printed on stdout:

    *** Dumping AST Record Layout
    Type: struct Base
    
    Layout: <ASTRecordLayout
      Size:32
      DataSize:32
      Alignment:32
      FieldOffsets: [0]>
    
    *** Dumping AST Record Layout
    Type: struct Derived
    
    Layout: <ASTRecordLayout
      Size:64
      DataSize:64
      Alignment:32
      FieldOffsets: [32]>
    

    ...

    Layout: <CGRecordLayout
      LLVMType:%struct.Base = type { i32 }
      NonVirtualBaseLLVMType:%struct.Base = type { i32 }
      IsZeroInitializable:1
      BitFields:[
    ]>
    
    Layout: <CGRecordLayout
      LLVMType:%struct.Derived = type { %struct.Base, i32 }
      NonVirtualBaseLLVMType:%struct.Derived = type { %struct.Base, i32 }
      IsZeroInitializable:1
      BitFields:[
    ]>