Skip to main content

rucc_lower/
unit.rs

1//! The module level of the walk: what a translation unit's declarations become.
2//!
3//! Design: `spec/08-ir.md` section 8.9.
4//!
5//! One typed tree becomes one [`Module`]. A file-scope object becomes a global with an image
6//! built from its initializer, a function becomes a [`Func`] whose body is built by
7//! [`body`](mod@crate::body), and a string literal becomes an unnamed constant global that
8//! whatever mentioned it points at.
9//!
10//! # What an image is
11//!
12//! An initializer arrives here already flattened: one entry per scalar that is stored, each
13//! with the byte offset it goes at, with every designator and every nested brace already
14//! resolved. So building the image is a walk over the entries in offset order, filling the gaps
15//! between them with zeros, and the only thing that has to be worked out per entry is whether
16//! the value is a number, a run of bytes from a string literal, or the address of something the
17//! linker has to place.
18//!
19//! # Names
20//!
21//! An object with linkage is known by the name it was written with, and there is nothing to
22//! invent. A `static` inside a function has no linkage and still needs a name in the object
23//! file, so it gets `name.N`, which is what gcc does and is why two functions may each have a
24//! `static int count;` without colliding. A string literal has no name at all and gets
25//! `.Lstr.N`, whose leading dot keeps it out of the symbol table on every target that has the
26//! convention.
27
28use std::cmp::Ordering;
29use std::collections::{BTreeMap, HashMap, HashSet};
30use std::fmt;
31
32use rucc_base::{Interner, Symbol};
33use rucc_diag::{Diagnostic, Span};
34use rucc_ir::{
35    Alias, AliasKind, AttrSet, Builder, DataList, Datum, Extra, FpContract, Func, Global, Imm,
36    InstData, Linkage as IrLinkage, Meta, Module, Opcode, Reloc, Signature, SymbolRef, TlsModel,
37    Type, Visibility as IrVisibility,
38};
39use rucc_sema::{
40    Address, Base, Const, Conversion, DeclFlags, DeclId, DeclKind, Definition, Effects, Emission,
41    Eval, ExprId, ExprKind, InitEntry, InitList, LabelId, Linkage, Priority, StorageDuration,
42    StrId, Tast, Visibility,
43};
44use rucc_target::{ObjectFormat, TargetInfo};
45use rucc_types::{TypeId, TypeKind, Types, compatible, is_complex, is_scalar};
46
47use crate::abi::{self, Plan};
48use crate::aliasing;
49use crate::body;
50use crate::directives;
51use crate::reach;
52use crate::repr;
53
54/// Which functions get a stack protector, which is what the `-fstack-protector` family decides.
55///
56/// The question is about the locals a function has, so it is answered here and not in the back
57/// end: by the time a frame is laid out the types are gone and every local is a size and an
58/// alignment. What the back end then does about the answer is its own business, and it is carried
59/// to it as [`rucc_ir::AttrSet::STACK_PROTECT`] on the function.
60///
61/// The names are gcc's, and so are the rules. A build that has been compiled with one of these for
62/// twenty years is entitled to the same set of protected functions from a compiler claiming to be
63/// compatible, because the ones left out are the ones an exploit goes looking for.
64#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
65pub enum Protector {
66    /// None of them, which is `-fno-stack-protector` and what a command line that says nothing
67    /// gets.
68    #[default]
69    None,
70    /// A function with a local array of at least eight bytes, or one whose stack grows while it
71    /// runs. `-fstack-protector`, which is the original and the narrowest.
72    Buffers,
73    /// Any of those, and any function with a local array at all, a local holding one, or a local
74    /// whose address is taken. `-fstack-protector-strong`, which is what every distribution builds
75    /// its packages with and therefore the one a real build line carries.
76    Strong,
77    /// Every function that has a frame at all. `-fstack-protector-all`.
78    All,
79}
80
81/// What overflows rather than being undefined, which is `-fwrapv` and its relatives.
82///
83/// Every licence the walk grants the optimizer about overflow is one flag on one instruction, and
84/// withdrawing a licence is not setting it. So this is read where the flags are chosen and nowhere
85/// else, and a unit built with either of these is a unit whose IR carries less rather than a unit
86/// the passes are told something extra about. That is also what makes it correct across link time
87/// optimization: a body from a unit that wraps and a body from one that does not keep their own
88/// answers when they end up in the same module.
89///
90/// `-ftrapv` is the exception and is the reason this is not simply two flags. It is the other
91/// answer to the question `-fwrapv` answers, and it is the only one of the three that asks for
92/// something to be generated rather than for something to be left out.
93#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
94pub struct Wrapping {
95    /// Whether signed arithmetic wraps, from `-fwrapv`. Set, and an add, a subtract, a multiply, a
96    /// shift and a negation in a signed type stop saying they do not wrap.
97    pub signed: bool,
98    /// Whether pointer arithmetic wraps, from `-fwrapv-pointer`. Set, and the multiply that turns
99    /// an index into a number of bytes stops saying so.
100    ///
101    /// That multiply is the whole of it here, because the addition itself never claimed anything: a
102    /// `ptradd` carries no flags in this IR and no pass reads one off it.
103    pub pointer: bool,
104    /// Whether a signed overflow stops the program, from `-ftrapv`. Set, and an add, a subtract, a
105    /// multiply and a negation in a signed type become calls to the routine in the runtime that
106    /// does the arithmetic and checks it.
107    ///
108    /// Never set at the same time as [`Wrapping::signed`], because a program cannot both wrap and
109    /// stop. The driver is what keeps that true.
110    pub trap: bool,
111}
112
113/// Everything the walk reads, which is a checked translation unit and the target it is for.
114///
115/// The interner is mutable because the walk invents names the program never wrote: the label a
116/// string literal is emitted under, and the mangled name of a function-scope `static`.
117pub struct Context<'a> {
118    /// The typed tree.
119    pub tast: &'a Tast,
120    /// The types it points into.
121    pub types: &'a Types,
122    /// What is being compiled for, which is where every width and every alignment comes from.
123    pub target: &'a TargetInfo,
124    /// The name table.
125    pub names: &'a mut Interner,
126    /// What a name that no declaration of it said anything about gets, which is `-fvisibility=`.
127    ///
128    /// A fact about the compilation rather than about any declaration, which is why it arrives
129    /// here rather than on the tree: the checker knows what was written and this knows what the
130    /// command line asked for, and the answer is the first of those where there is one.
131    pub visibility: IrVisibility,
132    /// Which functions get a stack protector, which is `-fstack-protector` and its relatives.
133    pub protector: Protector,
134    /// What overflows rather than being undefined, which is `-fwrapv` and its relatives.
135    ///
136    /// A fact about the compilation for the same reason the two above it are: what was written is
137    /// on the tree and what was asked for is on the command line.
138    pub wrapping: Wrapping,
139    /// Whether an access carries the node for the type it goes through, which is
140    /// `-fstrict-aliasing` and is on unless `-fno-strict-aliasing` cleared it.
141    ///
142    /// Clearing it here rather than in the optimizer is what makes the flag one condition in one
143    /// place: an access with no node conflicts with every other access, so a unit built with the
144    /// flag off is a unit whose IR says less rather than a unit the passes are told something
145    /// extra about. That is also what keeps it right across link time optimization, the way
146    /// [`Context::wrapping`] is: a body from a unit that named its types and a body from one that
147    /// did not keep their own answers when they end up in the same module.
148    pub aliasing: bool,
149    /// Whether an access says how far the padding after it reaches, which is
150    /// `-fsafety-init=nopadding` and is what a build with no safety tier gets too, since nothing
151    /// reads the number then.
152    ///
153    /// Here rather than in the safety pass for the reason [`Context::aliasing`] is here: what the
154    /// number is takes a record's layout, and the layout is a thing the walk has in hand and the
155    /// pass over the IR does not. The pass reads it and does not decide anything, which keeps the
156    /// flag one condition in one place and keeps it right across link time optimization.
157    pub padding: bool,
158    /// How far a multiply and an addition may be fused into one rounding, which is
159    /// `-ffp-contract=`.
160    ///
161    /// A fact about the compilation like the ones above it, and the one of them that is written
162    /// down rather than acted on: it goes onto every function with a body as
163    /// [`rucc_ir::Attrs::fp_contract`], because the place that would fuse anything is the code
164    /// generator and by the time it runs the command line is gone and the two operations it might
165    /// fuse may have come from different statements.
166    pub contract: FpContract,
167    /// What every function in the unit is aligned to unless it asked for more itself, which is
168    /// `-falign-functions` and is `None` for the alignment the target gives anyway.
169    ///
170    /// A fact about the compilation like the ones above it, and it meets a fact about a
171    /// declaration here rather than further down: `__attribute__((aligned(N)))` is a statement
172    /// about one function and this is a preference about all of them, so the function takes the
173    /// larger of the two and everything below reads one number.
174    pub align: Option<u32>,
175    /// Whether every function calls the two profiling hooks on the way in and on the way out,
176    /// which is `-finstrument-functions`.
177    ///
178    /// Done here rather than in a pass because gcc does it before it inlines anything, so a body
179    /// that is inlined takes its two calls with it and they still name the function they were
180    /// written for. A pass over the IR would see the body only after that had happened to it.
181    pub instrument: bool,
182    /// Whether an exception may unwind through what the walk builds, which is `-fexceptions`.
183    ///
184    /// What it asks of C is that a `cleanup` handler run when an unwind passes through its scope,
185    /// and that takes a landing pad and a table the personality routine reads, neither of which is
186    /// built yet. So what it does here is turn down the one shape the missing pad would change the
187    /// meaning of, a call made while a handler is owed, rather than build it without the pad.
188    pub exceptions: bool,
189    /// How a file named by a `.incbin` in an `asm` at file scope is read, given the name as the
190    /// template wrote it and handing back either the bytes or what went wrong.
191    ///
192    /// Passed in rather than reached for, because the walk has no business opening files and
193    /// because a caller that put its sources somewhere other than a disk has put this file there
194    /// too. The name is resolved the way an assembler resolves it, which is against the directory
195    /// the compiler was run in and not against the directory the source was found in.
196    pub read: &'a mut dyn FnMut(&str) -> Result<Vec<u8>, String>,
197}
198
199// Written out rather than derived because a closure has no `Debug`, and printing one would say
200// nothing anyway. What is worth reading here is the settings, so those are what this prints.
201impl fmt::Debug for Context<'_> {
202    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
203        f.debug_struct("Context")
204            .field("visibility", &self.visibility)
205            .field("protector", &self.protector)
206            .field("wrapping", &self.wrapping)
207            .field("aliasing", &self.aliasing)
208            .field("padding", &self.padding)
209            .field("contract", &self.contract)
210            .field("align", &self.align)
211            .field("instrument", &self.instrument)
212            .field("exceptions", &self.exceptions)
213            .finish_non_exhaustive()
214    }
215}
216
217/// One function that runs without anything calling it, waiting for the section it goes in.
218///
219/// Held back rather than written where the definition is met, because the order they go in is not
220/// always the order the file defined them: a format with one section for all of them is a format
221/// where the only record of the priority is the position in that section, so they have to be
222/// sorted, and sorting means having all of them.
223#[derive(Debug, Clone, Copy)]
224struct Start {
225    /// The function the entry is the address of.
226    func: Symbol,
227    /// Whether it runs in the run-up to `main` rather than in the run-down after it.
228    before: bool,
229    /// Where in the order the attribute asked for it to go.
230    priority: Priority,
231    /// The definition it came from, for the diagnostic a format with no way to say it needs.
232    span: Span,
233}
234
235impl Start {
236    /// Where this goes among the others, which is the order the entries are written in.
237    ///
238    /// A lower number first, and the unnumbered ones after every numbered one, which is the order
239    /// an ELF linker puts the sections in and therefore the order every format has to come out in
240    /// for the three of them to agree. The sort is stable, so two at the same priority stay in the
241    /// order the file defined them, which is all that decides between them.
242    fn order(&self) -> (u8, u16) {
243        match self.priority {
244            Priority::Numbered(number) => (0, number),
245            Priority::Unnumbered => (1, 0),
246        }
247    }
248}
249
250/// What the walk produced.
251#[derive(Debug)]
252pub struct Lowered {
253    /// The module, which is complete even when something was reported: a construct that is not
254    /// supported yet leaves the rest of the function around it intact.
255    pub module: Module,
256    /// What was reported, in the order it was found.
257    pub diagnostics: Vec<Diagnostic>,
258}
259
260/// Walks a checked translation unit and builds the IR for it.
261///
262/// `name` is the module's name, which is the file the tree came from.
263#[must_use]
264pub fn lower(name: &str, cx: Context<'_>) -> Lowered {
265    let Context {
266        tast,
267        types,
268        target,
269        names,
270        visibility,
271        protector,
272        wrapping,
273        aliasing,
274        padding,
275        contract,
276        align,
277        instrument,
278        exceptions,
279        read,
280    } = cx;
281    let module = Module::new(names.intern(name), target);
282    let reachable = reach::reachable(reach::Decide::new(tast, types, target, names));
283    let mut unit = Unit {
284        tast,
285        types,
286        target,
287        names,
288        visibility,
289        protector,
290        wrapping,
291        aliasing,
292        padding,
293        cliques: 0,
294        tree: aliasing::Tree::default(),
295        contract,
296        align,
297        instrument,
298        exceptions,
299        read,
300        module,
301        diagnostics: Vec::new(),
302        strings: HashMap::new(),
303        anonymous: 0,
304        statics: HashMap::new(),
305        labels: HashMap::new(),
306        done: HashSet::new(),
307        aliases: Vec::new(),
308        sets: Vec::new(),
309        aliased: HashSet::new(),
310        starts: Vec::new(),
311        renamed: HashMap::new(),
312        reachable,
313    };
314    unit.run();
315    Lowered { module: unit.module, diagnostics: unit.diagnostics }
316}
317
318/// The walk over one translation unit, and everything it has built so far.
319pub(crate) struct Unit<'a> {
320    pub(crate) tast: &'a Tast,
321    pub(crate) types: &'a Types,
322    pub(crate) target: &'a TargetInfo,
323    pub(crate) names: &'a mut Interner,
324    /// What a name no declaration said anything about gets. See [`Context::visibility`].
325    visibility: IrVisibility,
326    /// Which functions get a stack protector. See [`Context::protector`].
327    pub(crate) protector: Protector,
328    /// What wraps rather than being undefined. See [`Context::wrapping`].
329    pub(crate) wrapping: Wrapping,
330    /// Whether an access names the type it goes through. See [`Context::aliasing`].
331    aliasing: bool,
332    /// Whether an access says how far the padding after it reaches. See [`Context::padding`].
333    pub(crate) padding: bool,
334    /// How many `restrict` scopes have been handed out, which is a number the whole module shares
335    /// so that no two functions promise different things with the same one. See
336    /// [`restrict`](mod@crate::restrict) for why that matters before there is an inliner.
337    pub(crate) cliques: u16,
338    /// The type based aliasing tree built so far, which is one per module.
339    tree: aliasing::Tree,
340    /// How far a multiply and an addition may be fused. See [`Context::contract`].
341    pub(crate) contract: FpContract,
342    /// What every function is aligned to unless it asked for more. See [`Context::align`].
343    align: Option<u32>,
344    /// Whether the profiling hooks are called. See [`Context::instrument`].
345    pub(crate) instrument: bool,
346    /// Whether an exception may unwind through the unit. See [`Context::exceptions`].
347    pub(crate) exceptions: bool,
348    /// How a file a `.incbin` names is read. See [`Context::read`].
349    read: &'a mut dyn FnMut(&str) -> Result<Vec<u8>, String>,
350    pub(crate) module: Module,
351    pub(crate) diagnostics: Vec<Diagnostic>,
352    /// The global each string literal was emitted as, so that two mentions of one literal are
353    /// one object.
354    strings: HashMap<StrId, Symbol>,
355    /// How many runs of bytes written under no label in an `asm` at file scope have been given a
356    /// name, which is what keeps the next one from being given the same one.
357    anonymous: usize,
358    /// The name each object with no linkage was given.
359    statics: HashMap<DeclId, Symbol>,
360    /// The name each label an image holds the address of was given.
361    ///
362    /// A label is a place inside a function and has no name in the object file, because a jump to
363    /// one is a distance the assembler works out and never a symbol. An image is the one thing
364    /// that cannot do that: it is in another section, so what it holds is a relocation, and a
365    /// relocation names a symbol. So a label an image points at gets one, minted here because the
366    /// image is lowered before the body is walked and the block the label starts does not exist
367    /// yet when the name is first asked for.
368    labels: HashMap<LabelId, Symbol>,
369    /// What has been emitted, because a redeclaration is the same declaration seen twice.
370    done: HashSet<DeclId>,
371    /// The declarations that are a second name for something rather than a thing of their own,
372    /// in the order the file made them.
373    ///
374    /// Held back rather than emitted where they are met, because what an alias points at may be
375    /// written below it and whether anything defines it is a question only the whole file
376    /// answers.
377    aliases: Vec<DeclId>,
378    /// The names a `.set` in an `asm` at file scope gave to something else, with the block each
379    /// one was written in, in the order the file wrote them.
380    ///
381    /// Held back for the reason above and written out beside the aliases, since the two are the
382    /// same thing said two ways: a second symbol at an address this object already has.
383    sets: Vec<(directives::Set, Span)>,
384    /// The symbols something in the file is a second name for.
385    ///
386    /// A `static` function nothing calls is not emitted, and being what an alias points at is a
387    /// reason to emit one that no reference in the file says: the string an alias names is not a
388    /// use of anything as far as the walk over the tree is concerned.
389    aliased: HashSet<Symbol>,
390    /// The functions the file asked to have run without anything calling them, in the order it
391    /// defined them.
392    ///
393    /// Held back rather than emitted where they are met, because the entries go in the order the
394    /// priorities put them and a function written at the top of the file may have asked to run
395    /// last. Only the whole file settles that order.
396    starts: Vec<Start>,
397    /// The assembler name the file gave to a name with linkage, kept by the name that was
398    /// written rather than by the declaration that wrote it.
399    ///
400    /// For [`Unit::library_name`], which knows what the C library calls a function and not what
401    /// this file has said about it. The declaration that renames `memcpy` is a different
402    /// declaration from the implicit one the checker made for `__builtin_memcpy`, so the label
403    /// on the first is never reached from the second, and a program that renames a function and
404    /// then calls the builtin means the call to go to the new name.
405    renamed: HashMap<Symbol, Symbol>,
406    /// What something in the file reaches, which is what decides whether a function with
407    /// internal linkage is emitted at all.
408    reachable: HashSet<DeclId>,
409}
410
411// The debug is by hand and short: a translation unit is not something anybody wants printed as
412// a `{:?}`, and the module has a printer of its own for when they do.
413impl fmt::Debug for Unit<'_> {
414    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
415        f.debug_struct("Unit")
416            .field("module", &self.module.counts())
417            .field("diagnostics", &self.diagnostics.len())
418            .finish()
419    }
420}
421
422impl Unit<'_> {
423    /// The aliasing node an access through `ty` carries, and [`None`] when it carries none.
424    ///
425    /// [`None`] is also every answer under `-fno-strict-aliasing`, which is the whole of what that
426    /// flag does here. See [`aliasing`](mod@crate::aliasing) for which types have a node.
427    pub(crate) fn alias_node(&mut self, ty: TypeId) -> Option<Meta> {
428        if !self.aliasing {
429            return None;
430        }
431        self.tree.node(&mut self.module, self.names, self.types, ty)
432    }
433
434    /// The root of the aliasing tree, which is the node an access that may be punned carries.
435    ///
436    /// The root is `char` and it conflicts with everything, so an access carrying it is an access
437    /// nothing may be reordered across and, in the type plane, a byte nothing has settled the type
438    /// of. `crate::body` says which accesses those are.
439    pub(crate) fn alias_root(&mut self) -> Option<Meta> {
440        if !self.aliasing {
441            return None;
442        }
443        Some(self.tree.root(&mut self.module, self.names))
444    }
445
446    /// Every declaration the file made, in the order it made them.
447    fn run(&mut self) {
448        self.file_asms();
449        self.find_aliased();
450        self.find_renamed();
451        for index in 0..self.tast.top_level().len() {
452            let decl = self.tast.top_level()[index];
453            if !self.done.insert(decl) {
454                continue;
455            }
456            match self.tast[decl].kind {
457                DeclKind::Function => self.function(decl),
458                DeclKind::Object => self.object(decl),
459                // A name for a type is only in the tree at block scope and nothing is emitted
460                // for one.
461                DeclKind::Type => {}
462            }
463        }
464        for index in 0..self.aliases.len() {
465            self.alias(self.aliases[index]);
466        }
467        for index in 0..self.sets.len() {
468            let (set, span) = self.sets[index].clone();
469            self.equated(&set, span);
470        }
471        self.startups();
472    }
473
474    /// The `asm` written at file scope, read into the globals they define.
475    ///
476    /// Ahead of the declarations rather than among them. A block usually names more than one
477    /// thing and means them to be next to each other, the object writer lays globals out in the
478    /// order the module holds them, and adding a block's globals together is what makes them a
479    /// run. A declaration of one of those names below the block then finds a definition already
480    /// there and leaves it alone, which is the division the program wrote: the template says what
481    /// the bytes are and the C declaration says what they are to be read as.
482    fn file_asms(&mut self) {
483        for index in 0..self.tast.file_asms().len() {
484            let asm = self.tast.file_asms()[index];
485            let template = self.spelled(asm.template);
486            let read = match directives::assemble(&template, &mut *self.read) {
487                Ok(read) => read,
488                Err(directives::Failed::Unsupported(what)) => {
489                    self.unsupported(&format!("{what} in an `asm` at file scope"), asm.span);
490                    continue;
491                }
492                // An instruction, which the assembler reads rather than this, so the template is
493                // kept as it was written and the unit is assembled from its listing, where the
494                // template goes in the way gcc puts it into its own. Only on ELF, which is the
495                // syntax the listing reader knows.
496                Err(directives::Failed::Instruction(_))
497                    if self.target.object_format == ObjectFormat::Elf =>
498                {
499                    self.module.add_file_asm(template);
500                    continue;
501                }
502                Err(directives::Failed::Instruction(word)) => {
503                    let what = format!("the instruction '{word}' in an `asm` at file scope");
504                    self.unsupported(&what, asm.span);
505                    continue;
506                }
507                Err(directives::Failed::Missing(name, why)) => {
508                    let message = format!("cannot open '{name}' for reading: {why}");
509                    self.diagnostics.push(Diagnostic::error(message, asm.span).with_code("E0702"));
510                    continue;
511                }
512            };
513            // The name of every global of the block first, because a distance one of them writes
514            // is measured to a place in another of them and a relocation names a symbol, so the
515            // name has to be to hand before the bytes that refer to it are built.
516            let symbols: Vec<Symbol> = read
517                .pieces
518                .iter()
519                .map(|piece| match &piece.name {
520                    Some(name) => self.names.intern(name),
521                    None => {
522                        let name = format!(".Lasm.{}", self.anonymous);
523                        self.anonymous += 1;
524                        self.names.intern(&name)
525                    }
526                })
527                .collect();
528            for (index, piece) in read.pieces.into_iter().enumerate() {
529                self.piece(piece, symbols[index], &symbols);
530            }
531            // Held back until the file has been walked, because a name a block equates may be
532            // defined below the block, and remembered as a name something points at, because a
533            // `static` function an equate is the only reference to is one that has to be emitted.
534            for set in read.sets {
535                let target = self.names.intern(&set.target);
536                self.aliased.insert(target);
537                self.sets.push((set, asm.span));
538            }
539        }
540    }
541
542    /// One global an `asm` at file scope defined, under the name minted for it and with the names
543    /// of the whole block to hand.
544    ///
545    /// The bytes a template writes before it writes any label are a global like the rest and a
546    /// global has to have a name, so one is minted for them. Nothing refers to it by that name, so
547    /// the only thing it has to be is one nothing else takes, and the leading dot keeps it out of
548    /// the symbol table the way the name of a string literal does.
549    fn piece(&mut self, piece: directives::Piece, symbol: Symbol, symbols: &[Symbol]) {
550        let mut global = Global::new(symbol, piece.size, piece.align.max(1));
551        global.linkage = piece.linkage;
552        global.visibility = piece.visibility;
553        let bss = matches!(piece.section, directives::Section::Bss);
554        match piece.section {
555            // Which of the sections the object writer has an answer of its own for. Asking for
556            // `.rodata` by name would produce a second section with that spelling and with the
557            // flags of a writable one, so what is said here is what the global is instead.
558            directives::Section::ReadOnly => global.constant = true,
559            directives::Section::Data | directives::Section::Bss => {}
560            directives::Section::Named(name) => global.section = Some(self.names.intern(&name)),
561            // Refused where the template was read, since what goes in that section is
562            // instructions and there is nothing here that makes one.
563            directives::Section::Text => return,
564        }
565        let mut data = Vec::with_capacity(piece.items.len());
566        if piece.items.is_empty() && bss {
567            // A label at the end of the zero filled section, which has nothing under it and
568            // still has to land there rather than in the section of written bytes. An image of
569            // no zeros is what says so, since being all zeros is how a global asks for that
570            // section and an empty image asks for nothing.
571            data.push(Datum::Zero(0));
572        }
573        for item in piece.items {
574            data.push(match item {
575                directives::Item::Bytes(bytes) => Datum::Bytes(self.module.push_bytes(&bytes)),
576                directives::Item::Int { width, value } => {
577                    let ty = Type::int(u32::from(width) * 8);
578                    Datum::Scalar {
579                        ty,
580                        value: self.module.add_imm(Imm::int(i128::from(value), ty)),
581                    }
582                }
583                directives::Item::Zero(bytes) => Datum::Zero(bytes),
584                // Four bytes holding how far that global is from these bytes, which the reader
585                // said in globals of this block rather than in names because the place it
586                // measures to is usually a label the object file holds no name for.
587                directives::Item::Away { piece, addend } => {
588                    let reloc = Reloc { symbol: symbols[piece], addend, size: 4 };
589                    Datum::Away(self.module.add_reloc(reloc))
590                }
591            });
592        }
593        global.init = Some(self.module.push_data(&data));
594        self.place_global(global);
595    }
596
597    /// Which symbols the file gives a second name to, before anything is emitted.
598    ///
599    /// Ahead of the walk rather than during it, because a `static` function is emitted or not on
600    /// the strength of what reaches it and the alias that reaches one may be written below it.
601    fn find_aliased(&mut self) {
602        for index in 0..self.tast.top_level().len() {
603            let decl = self.tast.top_level()[index];
604            let Some(target) = self.tast[decl].alias else { continue };
605            let spelling = self.spelled(target);
606            let symbol = self.names.intern(&spelling);
607            self.aliased.insert(symbol);
608        }
609    }
610
611    /// Which names the file gave an assembler name of their own, before anything is emitted.
612    ///
613    /// Ahead of the walk for the reason [`Unit::find_aliased`] is: the call to
614    /// `__builtin_memcpy` may be written above the declaration of `memcpy` that renames it, and
615    /// the two spellings are one function.
616    fn find_renamed(&mut self) {
617        for index in 0..self.tast.top_level().len() {
618            let decl = self.tast.top_level()[index];
619            let node = &self.tast[decl];
620            let (linkage, name, label) = (node.linkage, node.name, node.asm_label);
621            if linkage == Linkage::None {
622                continue;
623            }
624            let (Some(name), Some(label)) = (name, label) else { continue };
625            let spelling = self.spelled(label);
626            let symbol = self.names.intern(&spelling);
627            self.renamed.insert(name, symbol);
628        }
629    }
630
631    /// The bytes of a string literal as a name, which is what a symbol in an attribute is.
632    fn spelled(&self, id: StrId) -> String {
633        self.tast[id].elements.iter().filter_map(|&unit| char::from_u32(unit)).collect()
634    }
635
636    /// One object with static storage duration.
637    fn object(&mut self, decl: DeclId) {
638        let tast = self.tast;
639        let node = &tast[decl];
640        let (ty, state, init) = (node.ty, node.state, node.init);
641        let (linkage, duration, alignment) = (node.linkage, node.duration, node.alignment);
642        let span = tast.decl_span(decl);
643        if duration == StorageDuration::Automatic {
644            // A block-scope object with automatic storage is a slot or a value in the function
645            // that declares it, and the body is what makes it. Nothing is emitted here.
646            return;
647        }
648        // A second name for something else is not an object of its own, so nothing is laid out
649        // and no image is built. It is held back until the rest of the file has been walked,
650        // because what it points at may be below it.
651        if node.alias.is_some() {
652            self.aliases.push(decl);
653            return;
654        }
655
656        let symbol = self.symbol_of(decl);
657        let size = repr::size_of(self.types, self.target, ty);
658        let align = alignment.unwrap_or_else(|| repr::align_of(self.types, self.target, ty));
659        let mut global = Global::new(symbol, size, align);
660        global.linkage = self.told(decl, linkage);
661        // A tentative definition counts as one, because it is one: `int x;` at file scope puts a
662        // symbol in this object and the linker never has to look anywhere else for it.
663        global.visibility = self.seen(decl, state != Definition::Declared);
664        global.tls = (duration == StorageDuration::Thread).then_some(TlsModel::GlobalDynamic);
665        global.constant = repr::is_read_only(self.types, ty);
666        global.init = match state {
667            // `extern int x;` and nothing else names an object another translation unit
668            // defines. The global is here so that a reference to it has something to resolve
669            // against, and it has no image, which is what makes it a declaration.
670            Definition::Declared => None,
671            Definition::Tentative => Some(self.zeros(size)),
672            Definition::Defined => {
673                let (data, covered) = self.image(init, size, span);
674                // The object is as large as its image when the image is the larger of the two.
675                // A structure whose last member is a flexible array is the only way that
676                // happens: `sizeof` answers without the array and an initializer that fills it
677                // makes an object big enough to hold what was written. C 6.7.2.1p18 leaves the
678                // size to the implementation, gcc grows the object, and this does the same
679                // rather than hand the linker a size the image does not fit in.
680                global.size = size.max(covered);
681                Some(data)
682            }
683        };
684        self.place_global(global);
685    }
686
687    /// One function, with its body when it has one.
688    fn function(&mut self, decl: DeclId) {
689        let tast = self.tast;
690        let node = &tast[decl];
691        let (ty, linkage, body, align) = (node.ty, node.linkage, node.body, node.alignment);
692        let noreturn = node.flags.contains(DeclFlags::NORETURN);
693        let naked = node.flags.contains(DeclFlags::NAKED);
694        let twice = node.flags.contains(DeclFlags::RETURNS_TWICE);
695        let effects = node.effects;
696        let startup = node.startup;
697        let span = tast.decl_span(decl);
698        if node.name.is_none() {
699            return;
700        }
701        // The same as for an object: a second name is not a function of its own, and it is held
702        // back until what it points at has been emitted.
703        if node.alias.is_some() {
704            self.aliases.push(decl);
705            return;
706        }
707        // Which asks the one question the reference to it asks, so that a declaration that
708        // renamed the symbol renames the definition as well and the two still meet.
709        let name = self.symbol_of(decl);
710        if self.is_dropped(decl, name) {
711            return;
712        }
713        let Some(plan) = self.plan(ty, &[], span) else { return };
714
715        let mut func = Func::new(name, plan.signature.clone());
716        // The name the source spelled, where an assembler name says the symbol is not it. A
717        // declaration of `strstr` renamed to `my_strstr` is a declaration of `strstr` still, and
718        // once the symbol is the only name left there is nothing to find that out again from.
719        if node.asm_label.is_some() {
720            func.spelled = node.name.filter(|&spelled| spelled != name);
721        }
722        // Where the body begins, which is the line a debugger names over the prologue. gcc says the
723        // line the opening brace is on rather than the line the declarator is on, and the two
724        // differ in the style that puts the brace underneath. No instruction in a prologue has a
725        // span of its own, so this is the only place the fact can come from. A declaration has no
726        // body and produces no prologue, so it falls back to the declarator and nothing reads it.
727        func.declared = body.map_or(span, |body| tast.stmt_span(body));
728        // And where the name is written in the definition, which is what a report about the
729        // function as a whole points at. Not `span`, which is the first declaration and is a
730        // prototype at the top of the file as often as not.
731        func.named = tast.definition_span(decl);
732        // The larger of what this function asked for and what the command line asked of all of
733        // them, since the attribute is a requirement and the flag is a preference, and a
734        // preference does not get to move a function off a boundary its own source named.
735        func.align = match (align, self.align) {
736            (Some(mine), Some(everyones)) => Some(mine.max(everyones)),
737            (mine, everyones) => mine.or(everyones),
738        };
739        // The one thing a declaration says that nobody downstream can work out for themselves.
740        // What `abort` does belongs to `abort`, and a translation unit that only declares it has
741        // nothing to look at, so the claim has to travel on the declaration or not at all.
742        if noreturn {
743            func.attrs.set |= AttrSet::NORETURN;
744        }
745        // Which is not a claim about what a call to it does but a fact about how the function
746        // itself is written, so unlike the two around it there is nothing here for a declaration
747        // alone to be useful for. It travels the same way because the attribute is written in the
748        // same places. See [`rucc_codegen`] for what reads it, which is the frame.
749        if naked {
750            func.attrs.set |= AttrSet::NAKED;
751        }
752        // A claim about what a call to it does, like `noreturn`, and it has to travel for the same
753        // reason: `sigsetjmp` is only ever declared here, and the frame of whoever calls it is
754        // what the claim changes. See `rucc_codegen::tail::comes_back` for what reads it.
755        if twice {
756            func.attrs.set |= AttrSet::RETURNS_TWICE;
757        }
758        // And the other one, for the same reason. What a call to `strtol` reads belongs to
759        // `strtol`, and the purity analysis answers opaque for everything it cannot see a body
760        // for, so a unit that only declares the function gets nothing out of it unless the
761        // promise arrives here. `const` says the result comes from the arguments alone, which
762        // is `readnone`, and `pure` says it may read memory, which is `readonly`. The two are
763        // an incompatible pair in the IR and only one of them is ever set.
764        func.attrs.set |= match effects {
765            Effects::Any => AttrSet::NONE,
766            Effects::Pure => AttrSet::READONLY,
767            Effects::Const => AttrSet::READNONE,
768        };
769        // Whether to inline it, which `rucc_opt::inline` reads for `always_inline` at every level
770        // and for a plain `inline` from `-O1` up. The IR will not have both of the first two, so a
771        // name that said both gets the one gcc keeps, which is `always_inline` after a warning that
772        // the other was ignored, and either of them says more than the keyword does.
773        if node.flags.contains(DeclFlags::ALWAYS_INLINE) {
774            func.attrs.set |= AttrSet::ALWAYS_INLINE;
775        } else if node.flags.contains(DeclFlags::NOINLINE) {
776            func.attrs.set |= AttrSet::NOINLINE;
777        } else if node.flags.contains(DeclFlags::DECLARED_INLINE) {
778            func.attrs.set |= AttrSet::INLINE_HINT;
779        }
780        // How often it is called, which `rucc_opt::predict` reads off the callee to make the path
781        // to a call of a cold function the unlikely one. The IR will not have both, and a name
782        // that said both gets `cold`.
783        if node.flags.contains(DeclFlags::COLD) {
784            func.attrs.set |= AttrSet::COLD;
785        } else if node.flags.contains(DeclFlags::HOT) {
786            func.attrs.set |= AttrSet::HOT;
787        }
788        // What a `target` attribute said the function is built for, which the inliner compares
789        // against each caller: a body built for SSE4.2 is not copied into one that is not.
790        func.target = tast.target(decl);
791        // An inline definition this unit calls, which this unit puts a copy of out of line for
792        // every call the inliner leaves alone. See [`Self::out_of_line`].
793        let copied = body.is_some() && self.out_of_line(decl, node.inline);
794        // Under GNU's reading the copy is for the inliner and nothing else. See
795        // [`Self::out_of_line`].
796        if copied && node.flags.contains(DeclFlags::GNU_INLINE) {
797            func.attrs.set |= AttrSet::INLINE_ONLY;
798        }
799        func.linkage = if copied { IrLinkage::LinkOnce } else { self.told(decl, linkage) };
800        // The same question as for an object, and the same answer, with one wrinkle: an inline
801        // definition this unit neither emits nor calls is a declaration here, since C 6.7.4p7
802        // sends the calls to whatever unit holds the external definition, so it is not this
803        // file's to describe. That is the condition the body is lowered under, a few lines below.
804        func.visibility = self.seen(decl, body.is_some() && (node.inline.emits() || copied));
805        // An inline definition is not an external definition, so what goes in the module is the
806        // declaration and not the body. C 6.7.4p7 says the calls in this unit go to the definition
807        // some other unit holds, which is what the declaration gives them, and glibc's headers
808        // rely on it: every one of their inline definitions would otherwise be a second definition
809        // of a name the library already defines. Unless this unit is one of the callers, which is
810        // the case [`Self::out_of_line`] is about.
811        if body.is_some() && (node.inline.emits() || copied) {
812            // `optimize ("no-strict-aliasing")` on the function, which has to be kept in the IR
813            // rather than on the command line because the inliner may copy this body into a
814            // function that is under the rule.
815            let strict = self.aliasing;
816            self.aliasing &= !node.flags.contains(DeclFlags::NO_STRICT_ALIASING);
817            body::lower(self, decl, &mut func, &plan);
818            self.aliasing = strict;
819            // Only for a definition, because an entry is an address and a declaration of something
820            // another file defines has none to put there. gcc reads the attribute off whichever
821            // declaration carried it and then waits for the definition in the same way, which is
822            // why writing `__attribute__((constructor)) void f(void);` in a header costs every
823            // file that includes it nothing.
824            if let Some(priority) = startup.before {
825                self.starts.push(Start { func: name, before: true, priority, span });
826            }
827            if let Some(priority) = startup.after {
828                self.starts.push(Start { func: name, before: false, priority, span });
829            }
830        }
831        self.place_func(func);
832    }
833
834    /// Puts a function in the module under a name something may already be under.
835    ///
836    /// Two declarations of one identifier were merged before this, so the only way one name
837    /// arrives twice is an assembler name that renames one identifier onto another: a
838    /// declaration of `f` renamed to `g` beside a definition of `g` is one symbol written two
839    /// ways, which is what the program asked for and what the linker is going to see. The
840    /// definition wins wherever there is one, since what the declaration is here for is to give
841    /// the calls something to resolve against and the definition does that as well.
842    ///
843    /// A name already carrying a definition keeps it. That is the program defining one symbol
844    /// twice, and the assembler says so with the name in front of it, which is a better message
845    /// than anything available here.
846    fn place_func(&mut self, func: Func) {
847        match self.module.lookup(func.name) {
848            None => {
849                self.module.add_func(func);
850            }
851            Some(SymbolRef::Func(id))
852                if self.module[id].is_declaration() && !func.is_declaration() =>
853            {
854                self.module[id] = func;
855            }
856            Some(_) => {}
857        }
858    }
859
860    /// One declaration that is a second name for something the same file defines.
861    ///
862    /// Emitted after everything else, so the target is looked up in a module that already holds
863    /// whatever the file defines whether it was written above the alias or below it.
864    ///
865    /// The target has to be defined here and not merely declared, which is gcc's rule and is
866    /// what the object format can express: an alias is a symbol at another symbol's address, and
867    /// a name this file does not define has no address for one to be at. A program that writes
868    /// an alias of something in another object wants a reference rather than a definition, and
869    /// what it gets from gcc is this same error rather than a name the linker cannot resolve.
870    fn alias(&mut self, decl: DeclId) {
871        let Some(written) = self.tast[decl].alias else { return };
872        let span = self.tast.decl_span(decl);
873        let name = self.symbol_of(decl);
874        let spelling = self.spelled(written);
875        let target = self.names.intern(&spelling);
876        if self.no_address(name, target, span) {
877            return;
878        }
879        // Something already under this name, which is the program defining one symbol twice. The
880        // definition that is there stands, the way it does for a function and for an object.
881        if self.module.lookup(name).is_some() {
882            return;
883        }
884        let mut alias = Alias::new(name, target);
885        alias.linkage = self.told(decl, self.tast[decl].linkage);
886        // Its own answer, because the attribute is written on the alias and an alias is a symbol
887        // of its own. `weak, alias, visibility("hidden")` is a name a library keeps to itself
888        // while the thing it points at stays exported, which is how glibc writes half of them.
889        // Always a definition. An alias is a symbol this object puts at an address in this object,
890        // and one whose target is merely declared was refused a few lines above.
891        alias.visibility = self.seen(decl, true);
892        self.module.add_alias(alias);
893    }
894
895    /// One name a `.set` in an `asm` at file scope gave to something else.
896    ///
897    /// The same thing as the alias above it and written out the same way, with the two answers
898    /// about the name coming from the directives around the `.set` rather than from an attribute:
899    /// `.globl` and `.weak` say how the linker sees it, `.hidden` and `.protected` say how far it
900    /// reaches, and a name no directive spoke about is local, which is what an assembler does with
901    /// one. A name the file also defines keeps its own definition, which is the rule everything
902    /// else here follows and is what gcc's output shows for a `.set` written above a definition of
903    /// the same name.
904    ///
905    /// A name made by `.symver` is bound the way the name it stands for is, which is what gas
906    /// does, since no directive can speak about a name spelled with an `@` in it.
907    fn equated(&mut self, set: &directives::Set, span: Span) {
908        let name = self.names.intern(&set.name);
909        let mut target = self.names.intern(&set.target);
910        // A target that is itself an alias stands for what that one stands for. xz gives a version
911        // to a name it declared with the alias attribute, and every alias the attributes made was
912        // added before the first of these, so the chain is already there to follow. The count
913        // bounds a cycle, which the attributes refused where they were written.
914        for _ in 0..self.module.aliases().count() {
915            match self.module.lookup(target) {
916                Some(SymbolRef::Alias(id)) if self.module[id].kind == AliasKind::Alias => {
917                    target = self.module[id].target;
918                }
919                _ => break,
920            }
921        }
922        if self.no_address(name, target, span) {
923            return;
924        }
925        // A name the file only declared is one the `.set` gives an address to, and tcc's test
926        // calls a function declared `extern` in C and defined by `.set` in a file-scope `asm`.
927        let declared = match self.module.lookup(name) {
928            None => true,
929            Some(SymbolRef::Func(id)) => self.module[id].is_declaration(),
930            Some(SymbolRef::Global(id)) => self.module[id].is_declaration(),
931            Some(SymbolRef::Alias(_)) => false,
932        };
933        if !declared {
934            return;
935        }
936        let mut alias = Alias::new(name, target);
937        alias.linkage = set.linkage;
938        alias.visibility = set.visibility;
939        if set.versioned {
940            (alias.linkage, alias.visibility) = match self.module.lookup(target) {
941                Some(SymbolRef::Func(id)) => (self.module[id].linkage, self.module[id].visibility),
942                Some(SymbolRef::Global(id)) => {
943                    (self.module[id].linkage, self.module[id].visibility)
944                }
945                _ => (set.linkage, set.visibility),
946            };
947        }
948        self.module.add_alias_over(alias);
949    }
950
951    /// Whether there is no address for a second name to be at, reporting why when there is not.
952    ///
953    /// The target has to be defined here and not merely declared, because an alias is a symbol at
954    /// another symbol's address and a name this file does not define has no address in it. A
955    /// program that writes one of these about something in another object wants a reference rather
956    /// than a definition, and gcc turns that down as well.
957    fn no_address(&mut self, name: Symbol, target: Symbol, span: Span) -> bool {
958        let spelled = self.names.resolve(name).to_owned();
959        if name == target {
960            let what = format!("'{spelled}' is aliased to itself");
961            self.diagnostics.push(Diagnostic::error(what, span).with_code("E0697"));
962            return true;
963        }
964        let defined = match self.module.lookup(target) {
965            Some(SymbolRef::Func(id)) => !self.module[id].is_declaration(),
966            Some(SymbolRef::Global(id)) => self.module[id].init.is_some(),
967            // A chain of them is a thing gcc takes and this does not yet, because resolving one
968            // wants the aliases put in an order that the file they were written in need not be
969            // in. It is reported rather than written out as a name pointing at a name.
970            Some(SymbolRef::Alias(_)) | None => false,
971        };
972        if !defined {
973            let spelling = self.names.resolve(target).to_owned();
974            let what = format!("'{spelled}' is aliased to undefined symbol '{spelling}'");
975            let note = "the target of an alias has to be defined in this same file, since an \
976                        alias is a second name for an address and not a reference to one";
977            let refused = Diagnostic::error(what, span).with_code("E0697");
978            self.diagnostics.push(refused.note(note, span));
979            return true;
980        }
981        false
982    }
983
984    /// The list of functions to run around `main`, written out as the entries that run them.
985    ///
986    /// In priority order rather than in the order the file defined them, because two of the three
987    /// formats get their order from the order the entries are in and only ELF sorts anything at
988    /// link time.
989    fn startups(&mut self) {
990        let mut starts = std::mem::take(&mut self.starts);
991        if self.target.object_format == ObjectFormat::Coff {
992            for start in &mut starts {
993                if !start.before {
994                    *start = self.registrar(start);
995                }
996            }
997        }
998        starts.sort_by_key(Start::order);
999        for start in starts {
1000            self.start_entry(&start);
1001        }
1002    }
1003
1004    /// A constructor that hands a destructor to `atexit`, and the entry that runs it.
1005    ///
1006    /// COFF has a run-up list and no run-down one, so a destructor is registered from the run-up
1007    /// instead, which is what mingw's own CRT does with the `.dtors` it collects. The registration
1008    /// runs at the destructor's own priority, and `atexit` calls what it was given last first, so
1009    /// the destructors come out in the reverse of the order their constructors went in, which is
1010    /// the order gcc's come out in.
1011    fn registrar(&mut self, start: &Start) -> Start {
1012        let called = self.names.resolve(start.func).to_owned();
1013        let name = self.names.intern(&format!("__rucc_atexit.{called}"));
1014        let atexit = self.names.intern("atexit");
1015        let mut func = Func::new(name, Signature::new());
1016        func.linkage = IrLinkage::Internal;
1017        let entry = func.create_block();
1018        let sig = func.add_signature(
1019            Signature::new().with_params(&[Type::PTR]).with_returns(&[Type::int(32)]),
1020        );
1021        let mut build = Builder::new(&mut func, entry);
1022        let what = build.value(
1023            InstData { extra: Extra::Symbol(start.func), ..InstData::new(Opcode::GlobalAddr) },
1024            Type::PTR,
1025        );
1026        build.call(atexit, sig, &[what]);
1027        build.ret(&[]);
1028        self.place_func(func);
1029        Start { func: name, before: true, ..*start }
1030    }
1031
1032    /// One entry, which is a pointer wide object in the section the format runs.
1033    ///
1034    /// A relocation against the function rather than a value, since the address is not known until
1035    /// the link. The object has internal linkage and a name nothing refers to: the only thing that
1036    /// reads it is the CRT walking the section, which finds it by where it is and not by what it is
1037    /// called. gcc emits no symbol at all for one, and a name with a dot in it is the nearest thing
1038    /// to that here, being one no C program can write and therefore one no program collides with.
1039    fn start_entry(&mut self, start: &Start) {
1040        let Some(section) = self.start_section(start) else {
1041            self.no_start(start);
1042            return;
1043        };
1044        let size = u64::from(self.target.pointer_width / 8);
1045        let align = u32::try_from(size).unwrap_or(1);
1046        let called = self.names.resolve(start.func).to_owned();
1047        let which = if start.before { "ctor" } else { "dtor" };
1048        let name = self.names.intern(&format!("__rucc_{which}.{called}"));
1049        let section = self.names.intern(&section);
1050        let mut global = Global::new(name, size, align);
1051        global.linkage = IrLinkage::Internal;
1052        global.section = Some(section);
1053        let size = u32::try_from(size).unwrap_or(0);
1054        let reloc = self.module.add_reloc(Reloc { symbol: start.func, addend: 0, size });
1055        global.init = Some(self.module.push_data(&[Datum::Addr(reloc)]));
1056        self.place_global(global);
1057    }
1058
1059    /// The pointer to the personality routine every landing pad in this unit is run by, which the
1060    /// header of the unwind table reaches through. Made once however many pads there are.
1061    ///
1062    /// gcc makes it a hidden weak object in a group of its own, so that every object of a link
1063    /// shares one. This one is local to the unit, which costs a word per object and needs neither
1064    /// a group nor a weak definition, and what an unwinder reads through it is the same address.
1065    /// It is a pointer rather than the routine itself because the routine is in the C runtime's
1066    /// shared library, and a table in a read only section cannot hold the distance to a name the
1067    /// dynamic linker places: the header holds the distance to this, and this holds the address.
1068    pub(crate) fn personality(&mut self) {
1069        let name = self.names.intern(rucc_ir::PERSONALITY_REF);
1070        if self.module.lookup(name).is_some() {
1071            return;
1072        }
1073        let size = u64::from(self.target.pointer_width / 8);
1074        let align = u32::try_from(size).unwrap_or(1);
1075        let mut global = Global::new(name, size, align);
1076        global.linkage = IrLinkage::Internal;
1077        let routine = self.names.intern(rucc_ir::PERSONALITY);
1078        let size = u32::try_from(size).unwrap_or(0);
1079        let reloc = self.module.add_reloc(Reloc { symbol: routine, addend: 0, size });
1080        global.init = Some(self.module.push_data(&[Datum::Addr(reloc)]));
1081        self.module.add_global(global);
1082    }
1083
1084    /// The section an entry goes in, and [`None`] for a format with no way to ask for one.
1085    ///
1086    /// ELF has both halves and the linker sorts the numbered sections ahead of the plain one, so
1087    /// the number goes in the name and the order comes out right however the files were linked.
1088    ///
1089    /// COFF has the run-up only. The name is sorted by what follows the `$` and the CRT walks
1090    /// everything between the `.CRT$XCA` and `.CRT$XCZ` markers, so a numbered entry goes just
1091    /// after the first marker and an unnumbered one at `U`, which keeps the numbered ones first.
1092    ///
1093    /// Mach-O has the run-up only as well, and it has no sorting at all: the entries run in the
1094    /// order the section holds them, which is the order [`Self::startups`] put them in.
1095    fn start_section(&self, start: &Start) -> Option<String> {
1096        match self.target.object_format {
1097            ObjectFormat::Elf => {
1098                let base = if start.before { ".init_array" } else { ".fini_array" };
1099                Some(match start.priority {
1100                    Priority::Numbered(number) => format!("{base}.{number:05}"),
1101                    Priority::Unnumbered => base.to_owned(),
1102                })
1103            }
1104            ObjectFormat::Coff if start.before => Some(match start.priority {
1105                Priority::Numbered(number) => format!(".CRT$XCA{number:05}"),
1106                Priority::Unnumbered => ".CRT$XCU".to_owned(),
1107            }),
1108            ObjectFormat::MachO if start.before => {
1109                Some("__DATA,__mod_init_func,mod_init_funcs".to_owned())
1110            }
1111            ObjectFormat::Coff | ObjectFormat::MachO | ObjectFormat::Wasm => None,
1112        }
1113    }
1114
1115    /// Reports an attribute this format has nowhere to put.
1116    ///
1117    /// Refused rather than dropped, because the whole point of the attribute is that something
1118    /// else calls the function and a program that quietly does not get its call has no way of
1119    /// noticing until whatever the function set up is missing.
1120    ///
1121    /// The run-down is what is missing on Mach-O. It used to have a terminator list and dyld
1122    /// stopped running it, so clang registers the call with `__cxa_atexit` from a constructor it
1123    /// writes for the purpose. COFF gets the same thing from [`Self::registrar`] with `atexit`,
1124    /// and doing it for Mach-O as well is what would take this message away.
1125    fn no_start(&mut self, start: &Start) {
1126        let which = if start.before { "constructor" } else { "destructor" };
1127        let format = self.target.object_format.as_str();
1128        let what = format!("the '{which}' attribute on a {format} target");
1129        self.unsupported(&what, start.span);
1130    }
1131
1132    /// How far a name reaches outside a shared library, which is what a declaration of it said
1133    /// where one said anything and what the command line asked for where none did.
1134    ///
1135    /// gcc's `-fvisibility=` is written as the default rather than as an override, so the
1136    /// attribute wins wherever it was written, and that is the whole reason a library compiled
1137    /// with `-fvisibility=hidden` can still export the dozen names it means to export.
1138    ///
1139    /// The default reaches what this unit defines and stops there, which is the `defined`
1140    /// argument and is the whole of tamnd/rucc#1234. `-fvisibility=hidden` is a claim about the
1141    /// names this file puts into the library, and a name it only mentions is one it knows nothing
1142    /// about: `stderr` is in libc however the file that reads it was compiled, and calling it
1143    /// hidden tells the linker to resolve it inside this object, which it cannot do. The attribute
1144    /// on a declaration is a different thing and still counts, because a program that writes it
1145    /// has said where the definition is going to come from.
1146    ///
1147    /// Measured against gcc 16.2.0 rather than read off the manual, since the manual says the flag
1148    /// applies to declarations and does not say which ones. For `extern int plain;` beside
1149    /// `__attribute__((visibility("hidden"))) extern int marked;` at `-fPIC -fvisibility=hidden`,
1150    /// gcc writes `plain` as `GLOBAL DEFAULT UND` and reaches it through the global offset table,
1151    /// and writes `marked` as `GLOBAL HIDDEN UND` and reaches it from the instruction pointer.
1152    fn seen(&self, decl: DeclId, defined: bool) -> IrVisibility {
1153        match self.tast[decl].visibility {
1154            Some(Visibility::Default) => IrVisibility::Default,
1155            Some(Visibility::Hidden) => IrVisibility::Hidden,
1156            Some(Visibility::Protected) => IrVisibility::Protected,
1157            None if defined => self.visibility,
1158            None => IrVisibility::Default,
1159        }
1160    }
1161
1162    /// What the linker is told about a name, which is its C linkage unless a declaration of it
1163    /// wrote `weak`.
1164    ///
1165    /// The attribute is refused on internal linkage where it is read, so external is the only
1166    /// thing it can change, and the two things a program means by it are one thing to the linker.
1167    /// On a definition it says another object's definition of the name beats this one, which is
1168    /// how a library ships a default. On a reference to something this file does not define it
1169    /// says the link may leave the name undefined and hand the reference a zero address, which is
1170    /// how a library offers a hook and why zstd's thirty files link at all.
1171    fn told(&self, decl: DeclId, linkage: Linkage) -> IrLinkage {
1172        match linkage {
1173            Linkage::External if self.tast[decl].flags.contains(DeclFlags::WEAK) => IrLinkage::Weak,
1174            Linkage::External => IrLinkage::External,
1175            Linkage::Internal | Linkage::None => IrLinkage::Internal,
1176        }
1177    }
1178
1179    /// Whether a body this unit is not meant to emit has to be emitted anyway, because this unit
1180    /// calls it and has nothing else to send the call to.
1181    ///
1182    /// C 6.7.4p7 says an inline definition is not an external definition, and the bargain it
1183    /// offers is that the call is replaced by the body, so nobody ever has to resolve the name.
1184    /// A compiler that inlines keeps its end of it. This one inlines only a function marked
1185    /// `always_inline`, so any other call left standing is a call to a name no object file
1186    /// defines, and the program fails at the link on a function it can see the body of. micropython is a program that does exactly that:
1187    /// `py/misc.h` writes `MP_COMPRESSED_ROM_TEXT` as `inline __attribute__((always_inline))`,
1188    /// nothing anywhere defines it out of line, and every file that reports an error calls it.
1189    ///
1190    /// So a copy goes out of line, under [`IrLinkage::LinkOnce`]. Every unit that calls one emits
1191    /// its own copy of the same body, the linker keeps one and the rest are discarded, and a unit
1192    /// that holds the real external definition beats all of them because a strong definition
1193    /// beats a weak one. What that costs is object size in the units that call one. What it buys
1194    /// is that the address of the function is the same everywhere and that the program links,
1195    /// which is the whole of what the program was asking for.
1196    ///
1197    /// Only when this unit names it, which is why [`reach`] stopped treating one of these as a
1198    /// root. An unreferenced inline definition is still emitted as nothing at all, which is what
1199    /// keeps a file that includes `stdio.h` from carrying its own `vprintf`, `putchar`, `getchar`
1200    /// and the dozen more glibc writes beside them.
1201    ///
1202    /// Under GNU's reading of `inline` the copy is marked `inline_only`, so the inliner still has
1203    /// the body and nothing emits it. There `extern inline` promises that the external definition
1204    /// is in some other object, and gcc never emits one of these bodies. glibc's `_FORTIFY_SOURCE`
1205    /// wrappers are exactly that: `memcpy` is written `extern inline` under `gnu_inline` with a
1206    /// body that calls `__builtin___memcpy_chk`, which becomes a call to `memcpy` again. That body
1207    /// emitted is a `memcpy` that calls itself, and it wins over the C library's inside the shared
1208    /// object that holds it.
1209    fn out_of_line(&self, decl: DeclId, emission: Emission) -> bool {
1210        !emission.emits() && self.reachable.contains(&decl)
1211    }
1212
1213    /// The same for an object, where a global with no image is the declaration.
1214    fn place_global(&mut self, global: Global) {
1215        match self.module.lookup(global.name) {
1216            None => {
1217                self.module.add_global(global);
1218            }
1219            Some(SymbolRef::Global(id))
1220                if self.module[id].init.is_none() && global.init.is_some() =>
1221            {
1222                self.module[id] = global;
1223            }
1224            Some(_) => {}
1225        }
1226    }
1227
1228    /// Whether this function is one nothing can call, which is the set that is not emitted.
1229    ///
1230    /// A name with internal linkage is not visible to another translation unit, so a definition
1231    /// of one that nothing here refers to is a definition of something that can never run.
1232    /// [`reach`](mod@crate::reach) is what worked out which those are, and an attribute that asks
1233    /// for the definition to be kept has already been read into the answer.
1234    ///
1235    /// A second name for it is the one reason to keep it that the walk over the tree cannot see,
1236    /// since what an alias points at is a string and not a reference to anything. So the symbol
1237    /// is what is asked about here rather than the declaration: an alias names what the linker
1238    /// will look for, which is what a declaration that renamed itself with `__asm__` is under.
1239    ///
1240    /// Nothing is said about it. gcc has `-Wunused-function` for a `static` function nobody
1241    /// wrote a call to, which is a warning about the program, and this is not that: the header
1242    /// that defines six of them is not the file being compiled and its author is not the person
1243    /// reading the output.
1244    fn is_dropped(&self, decl: DeclId, symbol: Symbol) -> bool {
1245        self.tast[decl].linkage != Linkage::External
1246            && !self.reachable.contains(&decl)
1247            && !self.aliased.contains(&symbol)
1248    }
1249
1250    /// How everything a call to this function type hands over travels, and [`None`] for one the
1251    /// walk cannot make.
1252    ///
1253    /// `actual` is the types of the arguments at a call site, which matter only past the end of
1254    /// the prototype: what a variadic argument does is decided from what was written there, and
1255    /// there is no parameter to decide it from. A definition passes nothing for it.
1256    pub(crate) fn plan(&mut self, ty: TypeId, actual: &[TypeId], span: Span) -> Option<Plan> {
1257        self.plan_with(ty, actual, false, span)
1258    }
1259
1260    /// The same, as the call site sees it rather than as the function does.
1261    ///
1262    /// The two differ for a type that is not a prototype. An old style definition is the one of
1263    /// those that knows what its parameters are, and 6.5.2.2p6 checks a call against a prototype
1264    /// and against nothing at all otherwise, so a parameter it disagrees with does not make the
1265    /// call wrong and cannot be what the argument travels as either: the value at the call is
1266    /// the argument's own type and nothing converted it. So a parameter the argument facing it
1267    /// is compatible with is used, which is the usual case and is what makes the call go to the
1268    /// name, and one it is not compatible with gives way to what was actually written. A call
1269    /// like that is undefined behaviour if control reaches it and the file still has to
1270    /// translate, which is the same position [`Body::direct`](crate::body) already takes.
1271    pub(crate) fn call_plan(&mut self, ty: TypeId, actual: &[TypeId], span: Span) -> Option<Plan> {
1272        self.plan_with(ty, actual, true, span)
1273    }
1274
1275    fn plan_with(
1276        &mut self,
1277        ty: TypeId,
1278        actual: &[TypeId],
1279        at_call: bool,
1280        span: Span,
1281    ) -> Option<Plan> {
1282        let canonical = self.types.canonical(ty);
1283        let canonical = match self.types.kind(canonical) {
1284            // A call goes through a pointer to a function, and the type in hand may be either.
1285            TypeKind::Pointer(pointee) => self.types.canonical(pointee),
1286            _ => canonical,
1287        };
1288        let TypeKind::Function(id) = self.types.kind(canonical) else {
1289            self.unsupported("a call through something that is not a function", span);
1290            return None;
1291        };
1292        let signature = self.types.signature(id);
1293        let ret = signature.ret;
1294        // A function declared without a prototype takes what it is given, which is what a
1295        // signature with no parameters and no end to them says. C23 removed these and this is
1296        // what `int f();` means in every dialect before it.
1297        let variadic = signature.variadic || !signature.prototyped;
1298        let params = if at_call && !signature.prototyped {
1299            // An argument past the end of the list has no parameter to travel as, which is what
1300            // a call to an unprototyped function with more arguments than the definition takes
1301            // is, so the list ends where the arguments do.
1302            signature
1303                .params
1304                .iter()
1305                .zip(actual)
1306                .map(|(&param, &arg)| if compatible(self.types, param, arg) { param } else { arg })
1307                .collect()
1308        } else {
1309            signature.params.clone()
1310        };
1311
1312        match abi::plan(self.types, self.target, ret, &params, actual, variadic) {
1313            Ok(plan) => Some(plan),
1314            Err(what) => {
1315                self.unsupported(what, span);
1316                None
1317            }
1318        }
1319    }
1320
1321    /// The image of an initializer: the entries in ascending order, with the gaps zeroed, and
1322    /// how many bytes it covers.
1323    ///
1324    /// The count is the size that was asked for except when a flexible array member was given
1325    /// something to hold, which is the one case where an image is larger than the type it is an
1326    /// image of.
1327    pub(crate) fn image(
1328        &mut self,
1329        init: Option<InitList>,
1330        size: u64,
1331        span: Span,
1332    ) -> (DataList, u64) {
1333        let Some(init) = init else { return (self.zeros(size), size) };
1334        let (data, at) = self.pieces(init, size, span);
1335        (self.module.push_data(&data), at)
1336    }
1337
1338    /// The data an image is made of, before it becomes a [`DataList`].
1339    ///
1340    /// This is apart from [`Self::image`] so that an image can be built inside another one,
1341    /// which is what a compound literal used as a value in an initializer needs.
1342    fn pieces(&mut self, init: InitList, size: u64, span: Span) -> (Vec<Datum>, u64) {
1343        let entries = self.in_image_order(&self.tast[init]);
1344        let mut packed = self.packed(&entries, size);
1345        let mut data: Vec<Datum> = Vec::with_capacity(entries.len());
1346        let mut at = 0;
1347        for entry in entries {
1348            let piece = self.entry(entry, &mut packed, size);
1349            if piece.is_empty() {
1350                continue;
1351            }
1352            let covered: u64 = piece.iter().map(|datum| datum.size(&self.module)).sum();
1353            match entry.offset.cmp(&at) {
1354                Ordering::Greater => data.push(Datum::Zero(entry.offset - at)),
1355                // An entry that begins inside the one before it, which is neither the same
1356                // place nor a later one. A union whose members are initialized through two
1357                // designators is the way to write it. The earlier bytes are already in the
1358                // list and the image cannot take them out again, so this is refused, and
1359                // nothing here is wrong enough to drop the rest of the image.
1360                Ordering::Less => {
1361                    self.unsupported("an initializer that writes over an earlier one", span);
1362                    continue;
1363                }
1364                Ordering::Equal => {}
1365            }
1366            at = entry.offset + covered;
1367            data.extend(piece);
1368        }
1369        if at < size {
1370            // The tail of a partly initialized object, which C says is zero. So is the tail of
1371            // an array the initializer did not fill, and so is every byte of padding.
1372            data.push(Datum::Zero(size - at));
1373            at = size;
1374        }
1375        (data, at)
1376    }
1377
1378    /// The entries an image is written from, which is not the order they were written in.
1379    ///
1380    /// A designator names a place, and the places may be named in any order at all:
1381    /// `{ .b = 2, .a = 1 }` is the same object as `{ .a = 1, .b = 2 }` and C says so in as many
1382    /// words. An image is bytes in ascending order, so the entries are put in that order here.
1383    /// The sort is stable, which is what makes the rest of the rule work: naming one place
1384    /// twice is legal and the last of them is the one that stands, so among the entries at one
1385    /// offset the written order is kept and all but the last are dropped.
1386    ///
1387    /// A bit-field is never dropped, because several of them share one offset without writing
1388    /// over anything. Which bytes they came to is settled by [`Self::packed`] before this runs
1389    /// and the whole run goes in under the first entry that has a bit in it.
1390    fn in_image_order(&self, entries: &[InitEntry]) -> Vec<InitEntry> {
1391        let mut sorted = entries.to_vec();
1392        sorted.sort_by_key(|entry| entry.offset);
1393        let mut kept: Vec<InitEntry> = Vec::with_capacity(sorted.len());
1394        for entry in sorted {
1395            if !entry.is_bit_field() {
1396                let over = |last: &InitEntry| last.offset == entry.offset && !last.is_bit_field();
1397                while kept.last().is_some_and(over) {
1398                    kept.pop();
1399                }
1400            }
1401            kept.push(entry);
1402        }
1403        kept
1404    }
1405
1406    /// What one entry of an initializer puts in the image.
1407    ///
1408    /// A bit-field is not a datum of its own, because two of them can live in one byte and an
1409    /// image is written in bytes. They were put together into their bytes by [`Self::packed`]
1410    /// before this ran, and the whole run of bytes goes in under the first entry that lies in
1411    /// it, which is why a later one in the same run answers with nothing.
1412    ///
1413    /// The zeroes at the end of a run are left off it, and a run that is nothing but zeroes
1414    /// answers with nothing at all. Either way the gap before the next entry covers them, which
1415    /// is the same image and is a smaller one to carry, and it is what keeps an object whose
1416    /// bit-fields are all zero in `.bss`. A zero at the front of a run or inside one stays, since
1417    /// that is where the run starts and what makes it one run. The run comes out of the map
1418    /// whatever is in it, so a later entry lying in it answers with nothing for the usual reason
1419    /// rather than writing the run a second time.
1420    ///
1421    /// An entry is usually one datum and a compound literal read is the reason the answer is a
1422    /// list: that entry is a whole object and puts as many data in as the object it is.
1423    fn entry(&mut self, entry: InitEntry, packed: &mut BTreeMap<u64, u8>, size: u64) -> Vec<Datum> {
1424        if entry.is_bit_field() {
1425            let Some(bytes) = take_run(packed, entry.offset) else { return Vec::new() };
1426            let Some(last) = bytes.iter().rposition(|&byte| byte != 0) else { return Vec::new() };
1427            return vec![Datum::Bytes(self.module.push_bytes(&bytes[..=last]))];
1428        }
1429        if let Some(literal) = self.literal_read(entry.value) {
1430            return self.literal_image(literal, self.tast.expr_span(entry.value));
1431        }
1432        if entry.reverse {
1433            if let Some(reversed) = self.reversed_datum(entry) {
1434                return reversed;
1435            }
1436        }
1437        // How much room is left in the object, which is what a string literal longer than the
1438        // array it initializes is cut down to. An entry that begins where the object ends is the
1439        // initializer of a flexible array member, and there the object grows to hold what was
1440        // written rather than the value being cut to fit, so nothing is taken off it.
1441        let room = if entry.offset < size { size - entry.offset } else { u64::MAX };
1442        if let Some(halves) = self.complex_image(entry.value) {
1443            return halves;
1444        }
1445        self.datum(entry.value, room).into_iter().collect()
1446    }
1447
1448    /// A complex constant as the two data an image holds it in, and [`None`] for anything else.
1449    ///
1450    /// A complex value is two real ones and an image is bytes, so `1.0 + 2.0i` goes in as the two
1451    /// halves one after the other, which is the layout every ABI here already reads it as. It is
1452    /// two data rather than one because a datum is one scalar, and it is here rather than in
1453    /// [`Self::datum`] for the same reason.
1454    fn complex_image(&mut self, value: ExprId) -> Option<Vec<Datum>> {
1455        let ty = self.tast[value].ty;
1456        let part = rucc_types::real_part(self.types, ty)?;
1457        let span = self.tast.expr_span(value);
1458        // Everything below this point answers with something, because the folding reports its own
1459        // failure and asking for the value a second time would report it twice.
1460        let folded = match self.fold(value) {
1461            Some(folded) => folded,
1462            None => return Some(Vec::new()),
1463        };
1464        let Some(ty) = repr::value_type(self.types, self.target, part) else {
1465            self.unsupported("this complex initializer", span);
1466            return Some(Vec::new());
1467        };
1468        // Each half goes in as the half's own type would, which is the bits of a floating value
1469        // and the number of an integer one.
1470        let halves = match folded {
1471            Const::Complex { real, imag } => {
1472                [real, imag].map(|half| Imm::from_bits(half.to_bits()))
1473            }
1474            Const::ComplexInt { real, imag } => [real, imag].map(|half| Imm::int(half, ty)),
1475            _ => {
1476                self.unsupported("this complex initializer", span);
1477                return Some(Vec::new());
1478            }
1479        };
1480        let data = halves
1481            .into_iter()
1482            .map(|half| {
1483                let imm = self.module.add_imm(half);
1484                Datum::Scalar { ty, value: imm }
1485            })
1486            .collect();
1487        Some(data)
1488    }
1489
1490    /// The compound literal an entry reads, if that is what the entry is.
1491    ///
1492    /// Reading an object is a node of its own, so a literal used as a value comes through as a
1493    /// read of a literal. A literal whose address is taken is not a read and is not this: that
1494    /// one folds to an address and goes in as a relocation, with the object it points at emitted
1495    /// on its own.
1496    fn literal_read(&self, value: ExprId) -> Option<DeclId> {
1497        let ExprKind::Convert { kind: Conversion::Lvalue, operand } = self.tast[value].kind else {
1498            return None;
1499        };
1500        match self.tast[operand].kind {
1501            ExprKind::CompoundLiteral(decl) => Some(decl),
1502            _ => None,
1503        }
1504    }
1505
1506    /// The bytes a compound literal contributes where it is read, which are its own image.
1507    ///
1508    /// The literal has static storage duration here, since a file-scope initializer is the only
1509    /// place this is reached from, and C 6.7.11p4 is what lets it stand as a constant element.
1510    /// Its own initializer is built at the offset the entry is at, so the parent image ends up
1511    /// with the literal's bytes laid into it rather than a name pointing at a second object.
1512    fn literal_image(&mut self, literal: DeclId, span: Span) -> Vec<Datum> {
1513        let size = repr::size_of(self.types, self.target, self.tast[literal].ty);
1514        let Some(init) = self.tast[literal].init else {
1515            return if size == 0 { Vec::new() } else { vec![Datum::Zero(size)] };
1516        };
1517        self.pieces(init, size, span).0
1518    }
1519
1520    /// The bit-fields of an initializer, put together into the bytes they lie in.
1521    ///
1522    /// Every byte a field lies in is in the map, whatever the bits it put there are. It is
1523    /// tempting to leave a zero byte out, on the grounds that what an image does not say is zero
1524    /// anyway, and it is wrong: the run a field's bytes make is taken out of the map from the
1525    /// byte the field starts at, so a field whose first byte happens to be zero would have its
1526    /// whole run left behind and `struct { unsigned f : 20; } x = { 0x12300 };` would read as
1527    /// zero. A run that is all zeroes is written as zeroes by [`Self::entry`], so an object that
1528    /// really is zero still costs nothing in the image.
1529    ///
1530    /// A field named twice takes only the bits of the field, so the last of them stands and does
1531    /// not read as the two values together.
1532    fn packed(&mut self, entries: &[InitEntry], size: u64) -> BTreeMap<u64, u8> {
1533        let mut bytes = BTreeMap::new();
1534        for entry in entries.iter().filter(|entry| entry.is_bit_field()) {
1535            let Some(folded) = self.fold(entry.value) else { continue };
1536            let Const::Int(number) = folded else {
1537                let span = self.tast.expr_span(entry.value);
1538                let what = "a bit-field initialized by something that is not an integer";
1539                self.unsupported(what, span);
1540                continue;
1541            };
1542            let width = entry.bit_width;
1543            let ones = if width >= 128 { u128::MAX } else { (1u128 << width) - 1 };
1544            // Which bytes the field lies in and where in them it sits. A reversed field lies in
1545            // the same bytes and is counted from the top of them, and the byte at its address is
1546            // then the most significant of the ones the value is assembled in rather than the
1547            // least, which is why the walk below runs the other way as well.
1548            let span = u64::from((entry.bit_offset + width).div_ceil(8));
1549            let start = if entry.reverse {
1550                u32::try_from(span * 8).unwrap_or(u32::MAX) - entry.bit_offset - width
1551            } else {
1552                entry.bit_offset
1553            };
1554            let mut mask = ones << start;
1555            let mut placed = ((number as u128) & ones) << start;
1556            let mut step = 0;
1557            while mask != 0 && step < span {
1558                let at = if entry.reverse {
1559                    entry.offset + span - 1 - step
1560                } else {
1561                    entry.offset + step
1562                };
1563                if at < size {
1564                    let (bits, keep) = ((placed & 0xff) as u8, !((mask & 0xff) as u8));
1565                    let byte = bytes.entry(at).or_insert(0);
1566                    *byte = (*byte & keep) | bits;
1567                }
1568                mask >>= 8;
1569                placed >>= 8;
1570                step += 1;
1571            }
1572        }
1573        bytes
1574    }
1575
1576    /// What one entry of a record whose scalars are stored the other way round puts in the image.
1577    ///
1578    /// The bytes of the value, written in the order opposite to the target's, which is the whole of
1579    /// what the attribute asks for. It answers with nothing where the ordinary path is already
1580    /// right: a value one byte wide has only one order, and an aggregate is bytes its own members
1581    /// put there in whatever order each of them is stored in.
1582    ///
1583    /// Two things are refused rather than written the wrong way. A complex value is two scalars and
1584    /// this is one, and an address is a number the linker fills in later and there is nowhere to
1585    /// say it goes in backwards. Both are worth an answer one day and neither is worth a wrong one.
1586    fn reversed_datum(&mut self, entry: InitEntry) -> Option<Vec<Datum>> {
1587        let ty = self.tast[entry.value].ty;
1588        let span = self.tast.expr_span(entry.value);
1589        if is_complex(self.types, ty) {
1590            let what = "a complex member of a record whose scalars are stored the other way round";
1591            self.unsupported(what, span);
1592            return Some(Vec::new());
1593        }
1594        let size = repr::size_of(self.types, self.target, ty);
1595        if size < 2 || !is_scalar(self.types, ty) {
1596            return None;
1597        }
1598        let bits = match self.fold(entry.value) {
1599            Some(Const::Int(number)) => number as u128,
1600            Some(Const::Float(number)) => number.to_bits(),
1601            Some(Const::Address(Address { base: Base::Absolute, offset })) => offset as u128,
1602            Some(_) => {
1603                let what = "an address in a record whose scalars are stored the other way round";
1604                self.unsupported(what, span);
1605                return Some(Vec::new());
1606            }
1607            None => return Some(Vec::new()),
1608        };
1609        let take = cap(size).min(16);
1610        let mut bytes = bits.to_le_bytes()[..take].to_vec();
1611        if self.target.little_endian {
1612            bytes.reverse();
1613        }
1614        Some(vec![Datum::Bytes(self.module.push_bytes(&bytes))])
1615    }
1616
1617    /// One entry of an image, given how many bytes are left in the object it goes in.
1618    fn datum(&mut self, value: ExprId, room: u64) -> Option<Datum> {
1619        let tast = self.tast;
1620        let ty = tast[value].ty;
1621        let span = tast.expr_span(value);
1622        if let TypeKind::Array { .. } = self.types.kind(self.types.canonical(ty)) {
1623            // An array in an initializer is a string literal initializing it, because that is
1624            // the only way an array is ever a value. `char s[2] = "hi";` drops the terminator,
1625            // which is the one case where the literal is longer than what it initializes, and
1626            // the front end has already given the value the type of the array it is filling, so
1627            // the type is what says how many of the literal's bytes are part of it. `room` is
1628            // still consulted because a flexible array member is filled by a literal that keeps
1629            // its own type and there is no size in the object for it to be cut to.
1630            let ExprKind::Str(id) = tast[value].kind else {
1631                self.unsupported("this initializer", span);
1632                return None;
1633            };
1634            let bytes = tast[id].bytes(self.target);
1635            let holds = repr::size_of(self.types, self.target, ty);
1636            let take = bytes.len().min(cap(holds)).min(cap(room));
1637            return Some(Datum::Bytes(self.module.push_bytes(&bytes[..take])));
1638        }
1639
1640        let size = repr::size_of(self.types, self.target, ty);
1641        match self.fold(value)? {
1642            Const::Int(number) => {
1643                let ty = repr::value_type(self.types, self.target, ty)?;
1644                // An integer constant of pointer type is a null pointer constant, which is what
1645                // `NULL` is, or an address the program wrote as a number. An image is bytes and
1646                // `ptr` says nothing about how many, so it goes in as the integer it is at the
1647                // width the target's addresses have. An address the linker has to fill in is
1648                // the arm below, and is the only one that stays a pointer.
1649                let ty = if ty.is_ptr() { Type::int(self.target.pointer_width) } else { ty };
1650                let imm = self.module.add_imm(Imm::int(number, ty));
1651                Some(Datum::Scalar { ty, value: imm })
1652            }
1653            Const::Float(number) => {
1654                let ty = repr::value_type(self.types, self.target, ty)?;
1655                let imm = self.module.add_imm(Imm::from_bits(number.to_bits()));
1656                Some(Datum::Scalar { ty, value: imm })
1657            }
1658            // A complex constant is two scalars and this answers with one, so it is not one of
1659            // these. [`Self::complex_image`] puts one in before this is reached.
1660            Const::Complex { .. } | Const::ComplexInt { .. } => None,
1661            // An address into nothing is a number, so it goes into the image as one and there is
1662            // no relocation for the linker to fill in. `static char *p = &((struct S *)0)->f;` is
1663            // a pointer whose value is known here, and the walk that folded it already said so.
1664            Const::Address(Address { base: Base::Absolute, offset }) => {
1665                let ty = repr::value_type(self.types, self.target, ty)?;
1666                let ty = if ty.is_ptr() { Type::int(self.target.pointer_width) } else { ty };
1667                let imm = self.module.add_imm(Imm::int(offset, ty));
1668                Some(Datum::Scalar { ty, value: imm })
1669            }
1670            // Two labels, both named for the image the way one is for `&&l`, and the width is
1671            // the type's since the distance is a number and not an address.
1672            Const::Apart { to, from } => {
1673                let to = self.label_name(to);
1674                let from = self.label_name(from);
1675                let size = u32::try_from(size).unwrap_or(0);
1676                let to = self.module.add_reloc(Reloc { symbol: to, addend: 0, size });
1677                Some(Datum::Apart { to, from })
1678            }
1679            Const::Address(address) => {
1680                let symbol = match address.base {
1681                    Base::Decl(decl) => {
1682                        // A compound literal is an object nothing declares, so the address of
1683                        // one is also the only thing that asks for it to be emitted. Without
1684                        // this the image names a symbol the module never defines and the link
1685                        // is what finds out. Anything with a name of its own is left alone,
1686                        // since the walk over the unit reaches those on its own.
1687                        if self.tast[decl].name.is_none() {
1688                            self.local_static(decl);
1689                        }
1690                        self.symbol_of(decl)
1691                    }
1692                    Base::Str(id) => self.string(id),
1693                    Base::Label(label) => self.label_name(label),
1694                    // Answered above, where it becomes a number rather than a reference.
1695                    Base::Absolute => return None,
1696                };
1697                let addend = i64::try_from(address.offset).unwrap_or(0);
1698                let size = u32::try_from(size).unwrap_or(0);
1699                Some(Datum::Addr(self.module.add_reloc(Reloc { symbol, addend, size })))
1700            }
1701        }
1702    }
1703
1704    /// An image of nothing but zeros, which is what a tentative definition has.
1705    fn zeros(&mut self, size: u64) -> DataList {
1706        if size == 0 {
1707            return DataList::EMPTY;
1708        }
1709        self.module.push_data(&[Datum::Zero(size)])
1710    }
1711
1712    /// The global a string literal is emitted as, making it the first time it is asked for.
1713    pub(crate) fn string(&mut self, id: StrId) -> Symbol {
1714        if let Some(&symbol) = self.strings.get(&id) {
1715            return symbol;
1716        }
1717        let literal = &self.tast[id];
1718        let bytes = literal.bytes(self.target);
1719        let align = literal.encoding.element_width(self.target) / 8;
1720        let symbol = self.names.intern(&format!(".Lstr.{}", self.strings.len()));
1721
1722        let mut global = Global::new(symbol, bytes.len() as u64, align.max(1));
1723        global.linkage = IrLinkage::Internal;
1724        // Not because the type says so, since a literal is an array of `char` and not of
1725        // `const char`, but because writing to one is undefined and every target puts them
1726        // somewhere read-only.
1727        global.constant = true;
1728        let range = self.module.push_bytes(&bytes);
1729        global.init = Some(self.module.push_data(&[Datum::Bytes(range)]));
1730        self.module.add_global(global);
1731        self.strings.insert(id, symbol);
1732        symbol
1733    }
1734
1735    /// The name a label an image holds the address of is known by, minting one the first time.
1736    ///
1737    /// The number is what makes two labels in two functions two names, the same way it does for a
1738    /// `static` inside a function. Nothing but the relocation and the definition the back end
1739    /// writes for it ever reads this, so the spelling only has to be one the object format lets a
1740    /// local symbol have, and the leading dot is what keeps it out of the symbol table on the
1741    /// formats that have the convention.
1742    pub(crate) fn label_name(&mut self, label: LabelId) -> Symbol {
1743        if let Some(&symbol) = self.labels.get(&label) {
1744            return symbol;
1745        }
1746        let symbol = self.names.intern(&format!(".Llbl.{}", self.labels.len()));
1747        self.labels.insert(label, symbol);
1748        symbol
1749    }
1750
1751    /// The name a label was given, or `None` for a label no image points at.
1752    pub(crate) fn named_label(&self, label: LabelId) -> Option<Symbol> {
1753        self.labels.get(&label).copied()
1754    }
1755
1756    /// The name the C library gives a function the program named with the `__builtin_` prefix,
1757    /// and nothing for every other name.
1758    ///
1759    /// `__builtin_abort` is a call to `abort`: the prefix is how a program reaches the function
1760    /// the library promises where a macro or a definition of its own has taken the plain name,
1761    /// so the two spellings are one function and the one the linker will look for is the short
1762    /// one. Which names those are is [`rucc_sema::library_name`]'s to say, since it is the same
1763    /// answer the front end declared them out of.
1764    fn library_name(&mut self, name: Symbol) -> Option<Symbol> {
1765        let library = rucc_sema::library_name(self.names.resolve(name))?;
1766        let symbol = self.names.intern(library);
1767        // And then whatever the file said that name is called in the object file. A program is
1768        // allowed to declare `memcpy` with an assembler name of its own and go on calling
1769        // `__builtin_memcpy`, and what it means by that is the renamed one: the prefix picks the
1770        // function out of the library, it does not ask for a symbol the file has renamed away.
1771        Some(self.renamed.get(&symbol).copied().unwrap_or(symbol))
1772    }
1773
1774    /// The symbol of one of the objects libgcc defines and the program only reads, declared in
1775    /// the module the first time it is asked for.
1776    ///
1777    /// These are `__cpu_model` and `__cpu_features2`, which `__builtin_cpu_supports` and
1778    /// `__builtin_cpu_is` read. The program never declares them, so without this the load would
1779    /// be from a name the module knows nothing about. The declaration is the one gcc makes, an
1780    /// external object with the ordinary visibility and no image, and a declaration the program
1781    /// did write of the same name is left as it is, since it says the same thing.
1782    pub(crate) fn libgcc_object(&mut self, name: &str, size: u64) -> Symbol {
1783        let symbol = self.names.intern(name);
1784        // External, the ordinary visibility and no image, which is what a new global is.
1785        self.place_global(Global::new(symbol, size, 4));
1786        symbol
1787    }
1788
1789    /// The name an object or a function is known by in the object file.
1790    pub(crate) fn symbol_of(&mut self, decl: DeclId) -> Symbol {
1791        let tast = self.tast;
1792        let node = &tast[decl];
1793        // The assembler name a declaration wrote, which is the symbol whatever the identifier
1794        // spells. It stands for a `static` and for a local one as well as for a name the linker
1795        // sees, so it is read before anything else here: a program that renames a name has said
1796        // what the symbol is, and the numbering below is for the ones that have not.
1797        if let Some(label) = node.asm_label {
1798            let spelling: String =
1799                tast[label].elements.iter().filter_map(|&unit| char::from_u32(unit)).collect();
1800            return self.names.intern(&spelling);
1801        }
1802        if node.linkage != Linkage::None {
1803            let Some(name) = node.name else { return self.names.intern(".Lanon") };
1804            return self.library_name(name).unwrap_or(name);
1805        }
1806        if let Some(&symbol) = self.statics.get(&decl) {
1807            return symbol;
1808        }
1809        // A `static` in a function, or a compound literal with static storage duration. The
1810        // number is what makes two of them in two functions two objects.
1811        let base = match node.name {
1812            Some(name) => self.names.resolve(name).to_string(),
1813            None => ".Lanon".to_string(),
1814        };
1815        let symbol = self.names.intern(&format!("{base}.{}", self.statics.len()));
1816        self.statics.insert(decl, symbol);
1817        symbol
1818    }
1819
1820    /// Emits the global for an object with static storage duration declared inside a function.
1821    pub(crate) fn local_static(&mut self, decl: DeclId) {
1822        if !self.done.insert(decl) {
1823            return;
1824        }
1825        match self.tast[decl].kind {
1826            // A function declared inside a body is a declaration of the function, not an
1827            // object with static storage that happens to be one.
1828            DeclKind::Function => self.function(decl),
1829            DeclKind::Object => self.object(decl),
1830            DeclKind::Type => {}
1831        }
1832    }
1833
1834    /// The value of a constant expression, reporting what folding it reported.
1835    ///
1836    /// Everything this is asked about is part of the image of an object that exists before the
1837    /// program runs, which is the one place C23 6.6p10 lets a compiler take more than the rest of
1838    /// 6.6 does, so it asks for the reading the front end already accepted there. Asking the
1839    /// strict way instead would refuse here what was allowed a pass earlier, which is a wrong
1840    /// answer arriving late rather than an extra check.
1841    fn fold(&mut self, expr: ExprId) -> Option<Const> {
1842        let mut eval = Eval::new(self.tast, self.types, self.target, self.names);
1843        let folded = eval.initializer(expr);
1844        let reported = eval.finish();
1845        self.diagnostics.extend(reported);
1846        match folded {
1847            Ok(value) => Some(value),
1848            Err(stop) => {
1849                if !stop.poisoned {
1850                    let span = self.tast.expr_span(stop.at);
1851                    self.unsupported("an initializer this compiler cannot fold", span);
1852                }
1853                None
1854            }
1855        }
1856    }
1857
1858    /// Reports a construct the walk does not build IR for yet.
1859    pub(crate) fn unsupported(&mut self, what: &str, span: Span) {
1860        self.diagnostics.push(
1861            Diagnostic::error(format!("{what} is not supported yet"), span).with_code("E0519"),
1862        );
1863    }
1864
1865    /// Reports a call to a builtin this compiler knows the name of and does nothing with.
1866    ///
1867    /// It is its own message rather than [`Self::unsupported`] because the construct is not the
1868    /// problem: a call is a call, and what is missing is the one function it goes to. The note is
1869    /// what a reader needs, since a builtin is the one name a programmer does not expect to have
1870    /// to provide and the alternative to this message is a linker asking them for it.
1871    pub(crate) fn missing_builtin(&mut self, spelled: &str, span: Span) {
1872        let message = format!("`{spelled}` is not implemented yet");
1873        let note = "a call to it would go to a symbol no object file defines, so this is refused \
1874                    here rather than at the link";
1875        self.diagnostics.push(Diagnostic::error(message, span).with_code("E0686").note(note, span));
1876    }
1877}
1878
1879/// A count of bytes as a length of a slice of them, saturating on a target whose addresses are
1880/// wider than this host's.
1881fn cap(bytes: u64) -> usize {
1882    usize::try_from(bytes).unwrap_or(usize::MAX)
1883}
1884
1885/// The run of bytes a bit-field entry starts, taken out of the map.
1886///
1887/// [`None`] when there is no byte at that offset, which means an earlier entry in the same run
1888/// already took it, since [`Unit::packed`] puts every byte a field lies in into the map.
1889fn take_run(bytes: &mut BTreeMap<u64, u8>, start: u64) -> Option<Vec<u8>> {
1890    let mut run = vec![bytes.remove(&start)?];
1891    let mut at = start + 1;
1892    while let Some(byte) = bytes.remove(&at) {
1893        run.push(byte);
1894        at += 1;
1895    }
1896    Some(run)
1897}