https://github.com/Andres-Salamanca created 
https://github.com/llvm/llvm-project/pull/145058

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

>From f3e99df1a2677112cf183c50921b745d887685b6 Mon Sep 17 00:00:00 2001
From: Andres Salamanca <andrealebarbari...@gmail.com>
Date: Fri, 20 Jun 2025 10:44:27 -0500
Subject: [PATCH] Add support for DumpRecordLayouts

---
 clang/lib/CIR/CodeGen/CIRGenRecordLayout.h    |  2 +
 .../CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp | 44 ++++++++++++++++++-
 clang/test/CIR/CodeGen/dumb-record.cpp        | 41 +++++++++++++++++
 3 files changed, 86 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/CIR/CodeGen/dumb-record.cpp

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:]>

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to