pub struct Object {
pub name: String,
pub ty: Ty,
pub storage: Storage,
pub is_const: bool,
pub is_register: bool,
pub vla_storage: bool,
pub align: Option<u64>,
pub flexible_len: Option<u64>,
pub asm_label: Option<String>,
pub section: Option<String>,
pub range: SourceRange,
}Expand description
A named object.
Fields§
§name: StringThe name as written in C.
ty: TyThe object’s type.
storage: StorageHow the object is stored.
is_const: boolWhether the object’s type is const-qualified.
is_register: boolWhether the declaration said register.
The specifier is a hint about speed that this crate has nothing to do
with — Rust decides where a local lives — but it has one rule with
teeth: C11 6.7.1p6 says the address of such an object “cannot be
computed, either explicitly (by use of the unary & operator as
discussed in 6.5.3.2) or implicitly (by converting an array name to a
pointer as discussed in 6.3.2.1)”, so sizeof is the only operator an
array declared register can be the operand of. WG14 DR116 is that
rule; drs/dr1xx.c is where it is checked.
vla_storage: boolSet when this is the hidden frame of a
variable length array: the mark of the function’s bump
arena taken just before the elements were allocated, in which case
Object::ty is the element type and the generated binding is the
arena’s frame guard (a slot of the function’s array of marks in
CFG mode).
It is not an object of the C program at all; it exists so that the arena moves back down to the mark when the block ends, which is the lifetime C gives the array.
align: Option<u64>The alignment _Alignas(N) or __attribute__((aligned(N))) asked for,
when it is stricter than the one the type already has.
Rust has no way to over-align a binding, so the object is generated
inside a one-field wrapper that carries the alignment —
#[repr(C, align(N))] struct __cinrs_align_N<T>(pub T); — and every
access to it goes through the field. The C object’s type is unchanged:
sizeof is the type’s size and the wrapper is invisible to everything
but the generated binding. See codegen.
None is the ordinary case, and also what a request no stricter than
the natural alignment leaves behind — there is nothing for a wrapper to
say.
flexible_len: Option<u64>How many elements the object’s storage gives the record’s flexible array member, when an initialiser filled it in.
GNU C lets an object with static storage duration initialise the
member (static struct W w = { 3, { 1, 2, 3 } };), which makes the
object larger than its own type — something Rust has no way to say
about a value of type W. The item is therefore given a companion
type with the same leading layout and a tail of this length,
__cinrs_W_3, and every use of the object is a place reached through
(*(&raw mut w).cast::<W>()). sizeof w is still sizeof(struct W),
which is what GCC says too. See codegen.
asm_label: Option<String>The symbol __asm__("name") renamed the object to.
section: Option<String>The section __attribute__((section("…"))) asked for.
range: SourceRangeWhere the declarator was written.