Skip to content

Commit 6621441

Browse files
[CIR] Add support for DumpRecordLayouts (#145058)
This PR adds support for the `-fdump-record-layouts` flag.
1 parent 5f74d9b commit 6621441

File tree

3 files changed

+86
-1
lines changed

3 files changed

+86
-1
lines changed

clang/lib/CIR/CodeGen/CIRGenRecordLayout.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,8 @@ class CIRGenRecordLayout {
197197
assert(it != bitFields.end() && "Unable to find bitfield info");
198198
return it->second;
199199
}
200+
void print(raw_ostream &os) const;
201+
LLVM_DUMP_METHOD void dump() const;
200202
};
201203

202204
} // namespace clang::CIRGen

clang/lib/CIR/CodeGen/CIRGenRecordLayoutBuilder.cpp

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,13 +640,55 @@ CIRGenTypes::computeRecordLayout(const RecordDecl *rd, cir::RecordType *ty) {
640640

641641
// Dump the layout, if requested.
642642
if (getASTContext().getLangOpts().DumpRecordLayouts) {
643-
cgm.errorNYI(rd->getSourceRange(), "computeRecordLayout: dump layout");
643+
llvm::outs() << "\n*** Dumping CIRgen Record Layout\n";
644+
llvm::outs() << "Record: ";
645+
rd->dump(llvm::outs());
646+
llvm::outs() << "\nLayout: ";
647+
rl->print(llvm::outs());
644648
}
645649

646650
// TODO: implement verification
647651
return rl;
648652
}
649653

654+
void CIRGenRecordLayout::print(raw_ostream &os) const {
655+
os << "<CIRecordLayout\n";
656+
os << " CIR Type:" << completeObjectType << "\n";
657+
if (baseSubobjectType)
658+
os << " NonVirtualBaseCIRType:" << baseSubobjectType << "\n";
659+
os << " IsZeroInitializable:" << zeroInitializable << "\n";
660+
os << " BitFields:[\n";
661+
std::vector<std::pair<unsigned, const CIRGenBitFieldInfo *>> bitInfo;
662+
for (auto &[decl, info] : bitFields) {
663+
const RecordDecl *rd = decl->getParent();
664+
unsigned index = 0;
665+
for (RecordDecl::field_iterator it = rd->field_begin(); *it != decl; ++it)
666+
++index;
667+
bitInfo.push_back(std::make_pair(index, &info));
668+
}
669+
llvm::array_pod_sort(bitInfo.begin(), bitInfo.end());
670+
for (std::pair<unsigned, const CIRGenBitFieldInfo *> &info : bitInfo) {
671+
os.indent(4);
672+
info.second->print(os);
673+
os << "\n";
674+
}
675+
os << " ]>\n";
676+
}
677+
678+
void CIRGenBitFieldInfo::print(raw_ostream &os) const {
679+
os << "<CIRBitFieldInfo" << " name:" << name << " offset:" << offset
680+
<< " size:" << size << " isSigned:" << isSigned
681+
<< " storageSize:" << storageSize
682+
<< " storageOffset:" << storageOffset.getQuantity()
683+
<< " volatileOffset:" << volatileOffset
684+
<< " volatileStorageSize:" << volatileStorageSize
685+
<< " volatileStorageOffset:" << volatileStorageOffset.getQuantity() << ">";
686+
}
687+
688+
void CIRGenRecordLayout::dump() const { print(llvm::errs()); }
689+
690+
void CIRGenBitFieldInfo::dump() const { print(llvm::errs()); }
691+
650692
void CIRRecordLowering::lowerUnion() {
651693
CharUnits layoutSize = astRecordLayout.getSize();
652694
mlir::Type storageType = nullptr;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir -fdump-record-layouts %s -o - | FileCheck %s
2+
3+
struct SimpleStruct {
4+
int a;
5+
float b;
6+
} simple;
7+
// CHECK: Layout: <CIRecordLayout
8+
// CHECK: CIR Type:!cir.record<struct "SimpleStruct" {!cir.int<s, 32>, !cir.float}>
9+
// CHECK: NonVirtualBaseCIRType:!cir.record<struct "SimpleStruct" {!cir.int<s, 32>, !cir.float}>
10+
// CHECK: IsZeroInitializable:1
11+
// CHECK: BitFields:[
12+
// CHECK: ]>
13+
14+
struct Empty {
15+
} empty;
16+
17+
// CHECK: Layout: <CIRecordLayout
18+
// CHECK: CIR Type:!cir.record<struct "Empty" padded {!cir.int<u, 8>}>
19+
// CHECK: NonVirtualBaseCIRType:!cir.record<struct "Empty" padded {!cir.int<u, 8>}>
20+
// CHECK: IsZeroInitializable:1
21+
// CHECK: BitFields:[
22+
// CHECK: ]>
23+
24+
struct BitfieldsInOrder {
25+
char a;
26+
unsigned bit: 8;
27+
unsigned should : 20;
28+
unsigned have: 3;
29+
unsigned order: 1;
30+
} bitfield_order;
31+
32+
// CHECK: Layout: <CIRecordLayout
33+
// CHECK: CIR Type:!cir.record<struct "BitfieldsInOrder" {!cir.int<s, 8>, !cir.int<u, 8>, !cir.int<u, 32>}>
34+
// CHECK: NonVirtualBaseCIRType:!cir.record<struct "BitfieldsInOrder" {!cir.int<s, 8>, !cir.int<u, 8>, !cir.int<u, 32>}>
35+
// CHECK: IsZeroInitializable:1
36+
// CHECK: BitFields:[
37+
// CHECK-NEXT: <CIRBitFieldInfo name:bit offset:0 size:8 isSigned:0 storageSize:8 storageOffset:1 volatileOffset:0 volatileStorageSize:0 volatileStorageOffset:0>
38+
// CHECK-NEXT: <CIRBitFieldInfo name:should offset:0 size:20 isSigned:0 storageSize:32 storageOffset:4 volatileOffset:0 volatileStorageSize:0 volatileStorageOffset:0>
39+
// CHECK-NEXT: <CIRBitFieldInfo name:have offset:20 size:3 isSigned:0 storageSize:32 storageOffset:4 volatileOffset:0 volatileStorageSize:0 volatileStorageOffset:0>
40+
// CHECK-NEXT: <CIRBitFieldInfo name:order offset:23 size:1 isSigned:0 storageSize:32 storageOffset:4 volatileOffset:0 volatileStorageSize:0 volatileStorageOffset:0>
41+
// CHECK:]>

0 commit comments

Comments
 (0)