[clang] [CIR] Add support for DumpRecordLayouts (PR #145058)

via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 20 08:50:32 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: None (Andres-Salamanca)

<details>
<summary>Changes</summary>

This PR adds support for the `-fdump-record-layouts` flag.

---
Full diff: https://github.com/llvm/llvm-project/pull/145058.diff


3 Files Affected:

- (modified) clang/lib/CIR/CodeGen/CIRGenRecordLayout.h (+2) 
- (modified) clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp (+43-1) 
- (added) clang/test/CIR/CodeGen/dumb-record.cpp (+41) 


``````````diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenRecordLayout.h b/clang/lib/CIR/CodeGen/CIRGenRecordLayout.h
index 3b51ab784d374..b28afe42c39a0 100644
--- a/clang/lib/CIR/CodeGen/CIRGenRecordLayout.h
+++ b/clang/lib/CIR/CodeGen/CIRGenRecordLayout.h
@@ -197,6 +197,8 @@ class CIRGenRecordLayout {
     assert(it != bitFields.end() && "Unable to find bitfield info");
     return it->second;
   }
+  void print(raw_ostream &os) const;
+  LLVM_DUMP_METHOD void dump() const;
 };
 
 } // namespace clang::CIRGen
diff --git a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
index 8dbf1b36a93b2..7f5fd36500d92 100644
--- a/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp
@@ -639,13 +639,55 @@ CIRGenTypes::computeRecordLayout(const RecordDecl *rd, cir::RecordType *ty) {
 
   // Dump the layout, if requested.
   if (getASTContext().getLangOpts().DumpRecordLayouts) {
-    cgm.errorNYI(rd->getSourceRange(), "computeRecordLayout: dump layout");
+    llvm::outs() << "\n*** Dumping CIRgen Record Layout\n";
+    llvm::outs() << "Record: ";
+    rd->dump(llvm::outs());
+    llvm::outs() << "\nLayout: ";
+    rl->print(llvm::outs());
   }
 
   // TODO: implement verification
   return rl;
 }
 
+void CIRGenRecordLayout::print(raw_ostream &os) const {
+  os << "<CIRecordLayout\n";
+  os << "   CIR Type:" << completeObjectType << "\n";
+  if (baseSubobjectType)
+    os << "   NonVirtualBaseCIRType:" << baseSubobjectType << "\n";
+  os << "   IsZeroInitializable:" << zeroInitializable << "\n";
+  os << "   BitFields:[\n";
+  std::vector<std::pair<unsigned, const CIRGenBitFieldInfo *>> bitInfo;
+  for (auto &[decl, info] : bitFields) {
+    const RecordDecl *rd = decl->getParent();
+    unsigned index = 0;
+    for (RecordDecl::field_iterator it = rd->field_begin(); *it != decl; ++it)
+      ++index;
+    bitInfo.push_back(std::make_pair(index, &info));
+  }
+  llvm::array_pod_sort(bitInfo.begin(), bitInfo.end());
+  for (std::pair<unsigned, const CIRGenBitFieldInfo *> &info : bitInfo) {
+    os.indent(4);
+    info.second->print(os);
+    os << "\n";
+  }
+  os << "   ]>\n";
+}
+
+void CIRGenBitFieldInfo::print(raw_ostream &os) const {
+  os << "<CIRBitFieldInfo" << " name:" << name << " offset:" << offset
+     << " size:" << size << " isSigned:" << isSigned
+     << " storageSize:" << storageSize
+     << " storageOffset:" << storageOffset.getQuantity()
+     << " volatileOffset:" << volatileOffset
+     << " volatileStorageSize:" << volatileStorageSize
+     << " volatileStorageOffset:" << volatileStorageOffset.getQuantity() << ">";
+}
+
+void CIRGenRecordLayout::dump() const { print(llvm::errs()); }
+
+void CIRGenBitFieldInfo::dump() const { print(llvm::errs()); }
+
 void CIRRecordLowering::lowerUnion() {
   CharUnits layoutSize = astRecordLayout.getSize();
   mlir::Type storageType = nullptr;
diff --git a/clang/test/CIR/CodeGen/dumb-record.cpp b/clang/test/CIR/CodeGen/dumb-record.cpp
new file mode 100644
index 0000000000000..5e8c584ddddd0
--- /dev/null
+++ b/clang/test/CIR/CodeGen/dumb-record.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir -fdump-record-layouts %s -o - | FileCheck %s
+
+struct SimpleStruct {
+  int a;
+  float b;
+} simple;
+// CHECK: Layout: <CIRecordLayout
+// CHECK: CIR Type:!cir.record<struct "SimpleStruct" {!cir.int<s, 32>, !cir.float}>
+// CHECK: NonVirtualBaseCIRType:!cir.record<struct "SimpleStruct" {!cir.int<s, 32>, !cir.float}>
+// CHECK: IsZeroInitializable:1
+// CHECK:   BitFields:[
+// CHECK: ]>
+
+struct Empty {
+} empty;
+
+// CHECK: Layout: <CIRecordLayout
+// CHECK:  CIR Type:!cir.record<struct "Empty" padded {!cir.int<u, 8>}>
+// CHECK:  NonVirtualBaseCIRType:!cir.record<struct "Empty" padded {!cir.int<u, 8>}>
+// CHECK:  IsZeroInitializable:1
+// CHECK:  BitFields:[
+// CHECK:  ]>
+
+struct BitfieldsInOrder {
+  char a;
+  unsigned bit: 8;
+  unsigned should : 20;
+  unsigned have: 3;
+  unsigned order: 1;
+} bitfield_order;
+
+// CHECK: Layout: <CIRecordLayout
+// CHECK:  CIR Type:!cir.record<struct "BitfieldsInOrder" {!cir.int<s, 8>, !cir.int<u, 8>, !cir.int<u, 32>}>
+// CHECK:  NonVirtualBaseCIRType:!cir.record<struct "BitfieldsInOrder" {!cir.int<s, 8>, !cir.int<u, 8>, !cir.int<u, 32>}>
+// CHECK:  IsZeroInitializable:1
+// CHECK:  BitFields:[
+// CHECK-NEXT:   <CIRBitFieldInfo name:bit offset:0 size:8 isSigned:0 storageSize:8 storageOffset:1 volatileOffset:0 volatileStorageSize:0 volatileStorageOffset:0>
+// CHECK-NEXT:   <CIRBitFieldInfo name:should offset:0 size:20 isSigned:0 storageSize:32 storageOffset:4 volatileOffset:0 volatileStorageSize:0 volatileStorageOffset:0>
+// CHECK-NEXT:   <CIRBitFieldInfo name:have offset:20 size:3 isSigned:0 storageSize:32 storageOffset:4 volatileOffset:0 volatileStorageSize:0 volatileStorageOffset:0>
+// CHECK-NEXT:   <CIRBitFieldInfo name:order offset:23 size:1 isSigned:0 storageSize:32 storageOffset:4 volatileOffset:0 volatileStorageSize:0 volatileStorageOffset:0>
+// CHECK:]>

``````````

</details>


https://github.com/llvm/llvm-project/pull/145058


More information about the cfe-commits mailing list