[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 09:13:28 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:
On your padding question, one marker covers both. Neither kind of padding contributes an eightbyte, and nothing in classification branches on which it is, so I don't think user padding needs an attribute of its own.
The shape of the storage is no help either. An unnamed bit-field takes whatever fits: `{!u8i}` at 3 bits, `{!u32i}` at 32, `{!cir.array<!u8i x 5>}` at 40. So `struct { unsigned : 32; }` and a record holding one `unsigned` are both `{!u32i}`.
The "AST facts" phrasing was loose and your reading is right. `has_trivial_dtor` is a semantic property, which a layout genuinely cannot carry. Emptiness is a layout property, and layout is the type's job. I guess I was arguing the type is under-describing the record.
On further reflection, marking which members are padding is the way to go, which I take to be the "field" property you had in mind. This is going to be needed for the packed and over-aligned records work that I have pending anyway, so we may as well update the type now. That is the version that makes emptiness a genuine calculation, since `padded` today is a single bool for the whole record. This would need to go up as a separate PR before I can update this one to use it.
https://github.com/llvm/llvm-project/pull/214742
More information about the cfe-commits
mailing list