[clang] [CIR] Add support for DumpRecordLayouts (PR #145058)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 20 08:50:03 PDT 2025
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 <andrealebarbaritos at 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:]>
More information about the cfe-commits
mailing list