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