diff --git a/clang/lib/CIR/CodeGen/CIRGenRecordLayout.h b/clang/lib/CIR/CodeGen/CIRGenRecordLayout.h index f10322136d49..0ef57279c6ab 100644 --- a/clang/lib/CIR/CodeGen/CIRGenRecordLayout.h +++ b/clang/lib/CIR/CodeGen/CIRGenRecordLayout.h @@ -107,7 +107,7 @@ struct CIRGenBitFieldInfo { StorageSize(StorageSize), StorageOffset(StorageOffset) {} void print(llvm::raw_ostream &OS) const; - void dump() const; + LLVM_DUMP_METHOD void dump() const; /// Given a bit-field decl, build an appropriate helper object for /// accessing that field (which is expected to have the given offset and @@ -201,6 +201,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/CIRRecordLayoutBuilder.cpp b/clang/lib/CIR/CodeGen/CIRRecordLayoutBuilder.cpp index ec13f93a9bf1..15e313569077 100644 --- a/clang/lib/CIR/CodeGen/CIRRecordLayoutBuilder.cpp +++ b/clang/lib/CIR/CodeGen/CIRRecordLayoutBuilder.cpp @@ -760,13 +760,55 @@ CIRGenTypes::computeRecordLayout(const RecordDecl *D, cir::RecordType *Ty) { // Dump the layout, if requested. if (getContext().getLangOpts().DumpRecordLayouts) { - llvm_unreachable("NYI"); + llvm::outs() << "\n*** Dumping CIRgen Record Layout\n"; + llvm::outs() << "Record: "; + D->dump(llvm::outs()); + llvm::outs() << "\nLayout: "; + RL->print(llvm::outs()); } // TODO: implement verification return RL; } +void CIRGenRecordLayout::print(raw_ostream &os) const { + os << "> 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 (auto &info : bitInfo) { + os.indent(4); + info.second->print(os); + os << "\n"; + } + os << " ]>\n"; +} + +void CIRGenRecordLayout::dump() const { print(llvm::errs()); } + +void CIRGenBitFieldInfo::print(raw_ostream &os) const { + os << ""; +} + +void CIRGenBitFieldInfo::dump() const { print(llvm::errs()); } + CIRGenBitFieldInfo CIRGenBitFieldInfo::MakeInfo(CIRGenTypes &Types, const FieldDecl *FD, uint64_t Offset, uint64_t Size, diff --git a/clang/test/CIR/CodeGen/dumb-record.cpp b/clang/test/CIR/CodeGen/dumb-record.cpp new file mode 100644 index 000000000000..7c3a18141e5e --- /dev/null +++ b/clang/test/CIR/CodeGen/dumb-record.cpp @@ -0,0 +1,64 @@ +// 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: , !cir.float} #cir.record.decl.ast> +// CHECK: NonVirtualBaseCIRType:!cir.record, !cir.float} #cir.record.decl.ast> +// CHECK: IsZeroInitializable:1 +// CHECK: BitFields:[ +// CHECK: ]> + +struct Empty { +} empty; + +// CHECK: Layout: } #cir.record.decl.ast> +// CHECK: NonVirtualBaseCIRType:!cir.record} #cir.record.decl.ast> +// 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: , !cir.int, !cir.array x 2>, !cir.array x 3>, !cir.int} #cir.record.decl.ast> +// CHECK: NonVirtualBaseCIRType:!cir.record, !cir.int, !cir.array x 2>, !cir.array x 3>, !cir.int} #cir.record.decl.ast> +// CHECK: IsZeroInitializable:1 +// CHECK: BitFields:[ +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK-NEXT: +// CHECK:]> + +struct Inner { + int x; +} in; + +//CHECK: Layout: } #cir.record.decl.ast> +//CHECK: NonVirtualBaseCIRType:!cir.record} #cir.record.decl.ast> +//CHECK: IsZeroInitializable:1 +//CHECK: BitFields:[ +//CHECK: ]> + +struct Outer { + Inner i; + int y = 6; +} ou; + +//CHECK: Layout: } #cir.record.decl.ast>, !cir.int} #cir.record.decl.ast> +//CHECK: NonVirtualBaseCIRType:!cir.record} #cir.record.decl.ast>, !cir.int} #cir.record.decl.ast> +//CHECK: IsZeroInitializable:1 +//CHECK: BitFields:[ +//CHECK: ]>