[clang] [CIR] Handle an empty C++ class in x86_64 callconv lowering (PR #214742)
Adam Smith via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 7 07:58:52 PDT 2026
================
@@ -143,6 +143,10 @@ def CIR_RecordLayoutAttr : CIR_Attr<"RecordLayout", "record_layout", [
- `record_align_in_bytes`: from `ASTRecordLayout::getAlignment()`.
Needed because CIR's DataLayout cannot account for
`__attribute__((aligned(N)))`.
+ - `is_empty`: whether the record carries no data for argument passing
----------------
adams381 wrote:
It cannot be calculated from the CIR type as it stands. `struct { int : 3; }` and `struct { unsigned char c; }` lower to `!cir.struct<"UnnamedBits" {!u8i}>` and `!cir.struct<"OneByte" {!u8i}>`, identical apart from the name and neither marked `padded`, yet classic CodeGen drops the first from the signature and passes the second in a register. A structural test answers both the same way, and they need opposite answers. Both cases are in `record-type-metadata.cpp`.
I debated with myself on the shape of this PR as I was implementing it. "All fields are padding" was the first version of this patch, matching `padded` plus a single padding-byte member. It handles the common empty class and quietly mispasses the unnamed bit-field, which is what moved me to the AST.
CIR does not record a bit-field's storage unit, so that byte is indistinguishable from a byte of data. Recording it would make emptiness calculable, but it is a CIRGen change of a different size than this patch.
`is_empty` is implemented the same way as `arg_passing_kind`, `has_trivial_dtor` and `record_align` on `cir.record_layout`. They are all AST facts the type does not preserve.
https://github.com/llvm/llvm-project/pull/214742
More information about the cfe-commits
mailing list