machdocs
Home GitHub

Decorators

A decorator is a codegen directive attached to a declaration. It controls how the compiler emits a symbol - its linker name, alignment, section placement, inlining, or PE import routing - and nothing else.

Note

Decorators are codegen-only. Visibility (pub / ext) is a separate concern and is never controlled by a decorator.

Surface

A decorator is written as an attribute clause. A bare flag takes no arguments; a directive takes comptime-expression arguments.

#[name]            # bare flag (e.g. inline)
#[name(args)]      # directive with comptime-expr arguments
Restriction

A line comment that begins #[ with no space opens an attribute. Write such a comment with a separating space: # [...].

Placement

Decorators appear before the declaration they target, one per line or space-separated on the same line. They attach to the immediately following declaration only and do not bleed across declarations.

#[inline]
#[symbol("big")]
fun big(a: i64, b: i64) i64 { ... }

#[align(64)] #[symbol("g_lit64")]
pub var g_lit64: u8 = 7;

Directives

The directive set is closed; new directives require a compiler change.

symbol(str) - linker name

Overrides the emitted or imported symbol name. Applies to functions and globals. Without it, the compiler mangles the mach name; symbol gives the linker the exact name.

#[symbol("main")]
fun entry(argc: i64, argv: **u8) i64 { ... }

#[symbol("write")]
ext fun libc_write(fd: i64, buf: *u8, n: i64) i64;

library(str) - PE import routing

Pins an ext import to a specific DLL in the link's dependency set. Applies to ext functions only, and composes with symbol - the import is emitted under the renamed symbol within the named DLL.

#[library("ws2_32.dll")] #[symbol("WSAStartup")]
ext fun wsa_startup(ver: u16, data: *u8) i32;

inline - force inlining

Marks a function for inlining at every call site, overriding the compiler's size- and use-count heuristics. Applies to functions only and takes no arguments.

#[inline]
fun fast_path(x: i64) i64 { ret x * 2; }

align(expr) - alignment override

Sets the alignment of a global variable or a record/union type. expr must be a comptime integer - a literal, or a comptime expression such as $size_of(T) or $align_of(T).

#[align(64)]
pub var cache_line: u8 = 0;

#[align($size_of(Pair))]
pub var g_cmp: u8 = 0;

#[align(32)]
rec Over { a: u8; }

section(str) - object section placement

Places a function or global variable in a named section instead of the default .text / .data. The section is created if absent; cross-section calls and accesses use ordinary relocations.

#[section(".hottext")] #[symbol("f_hot")]
fun f_hot(x: i64) i64 { ret x + 1; }

#[section(".machsec")] #[symbol("g_sec")]
pub var g_sec: u64 = 100;

Applicability

Each directive targets a fixed set of declaration kinds. The full matrix:

Directivefunext funval / varrec / uni
symbolyesyesyesno
librarynoyesnono
inlineyesnonono
alignnonoyesyes
sectionyesyesyesno

See also

  • Visibility - pub / ext, the separate concern decorators never touch
  • Intrinsics - $size_of and $align_of as align arguments
  • Manifest - the [os.*].libs set a library pin resolves against