pub struct Context<'a> {
pub tast: &'a Tast,
pub types: &'a Types,
pub target: &'a TargetInfo,
pub names: &'a mut Interner,
pub visibility: Visibility,
pub protector: Protector,
pub wrapping: Wrapping,
pub aliasing: bool,
pub padding: bool,
pub contract: FpContract,
pub read: &'a mut dyn FnMut(&str) -> Result<Vec<u8>, String>,
}Expand description
Everything the walk reads, which is a checked translation unit and the target it is for.
The interner is mutable because the walk invents names the program never wrote: the label a
string literal is emitted under, and the mangled name of a function-scope static.
Fields§
§tast: &'a TastThe typed tree.
types: &'a TypesThe types it points into.
target: &'a TargetInfoWhat is being compiled for, which is where every width and every alignment comes from.
names: &'a mut InternerThe name table.
visibility: VisibilityWhat a name that no declaration of it said anything about gets, which is -fvisibility=.
A fact about the compilation rather than about any declaration, which is why it arrives here rather than on the tree: the checker knows what was written and this knows what the command line asked for, and the answer is the first of those where there is one.
protector: ProtectorWhich functions get a stack protector, which is -fstack-protector and its relatives.
wrapping: WrappingWhat overflows rather than being undefined, which is -fwrapv and its relatives.
A fact about the compilation for the same reason the two above it are: what was written is on the tree and what was asked for is on the command line.
aliasing: boolWhether an access carries the node for the type it goes through, which is
-fstrict-aliasing and is on unless -fno-strict-aliasing cleared it.
Clearing it here rather than in the optimizer is what makes the flag one condition in one
place: an access with no node conflicts with every other access, so a unit built with the
flag off is a unit whose IR says less rather than a unit the passes are told something
extra about. That is also what keeps it right across link time optimization, the way
Context::wrapping is: a body from a unit that named its types and a body from one that
did not keep their own answers when they end up in the same module.
padding: boolWhether an access says how far the padding after it reaches, which is
-fsafety-init=nopadding and is what a build with no safety tier gets too, since nothing
reads the number then.
Here rather than in the safety pass for the reason Context::aliasing is here: what the
number is takes a record’s layout, and the layout is a thing the walk has in hand and the
pass over the IR does not. The pass reads it and does not decide anything, which keeps the
flag one condition in one place and keeps it right across link time optimization.
contract: FpContractHow far a multiply and an addition may be fused into one rounding, which is
-ffp-contract=.
A fact about the compilation like the ones above it, and the one of them that is written
down rather than acted on: it goes onto every function with a body as
rucc_ir::Attrs::fp_contract, because the place that would fuse anything is the code
generator and by the time it runs the command line is gone and the two operations it might
fuse may have come from different statements.
read: &'a mut dyn FnMut(&str) -> Result<Vec<u8>, String>How a file named by a .incbin in an asm at file scope is read, given the name as the
template wrote it and handing back either the bytes or what went wrong.
Passed in rather than reached for, because the walk has no business opening files and because a caller that put its sources somewhere other than a disk has put this file there too. The name is resolved the way an assembler resolves it, which is against the directory the compiler was run in and not against the directory the source was found in.