Now that they are lazy, they need to get analyzed in the correct
context, when requested.
This commit also hooks up std.builtin type values being resolved
properly. This is needed, for example, with the `@export` builtin
function, which occurs in start.zig, for `std.builtin.ExportOptions`.
The ZIR code uses the special `Ref.export_options` value, and semantic
analysis has to map this to the corresponding type from `std.builtin`.
AstGen is now completely independent from the rest of the compiler. It
ingests an AST tree and produces ZIR code as the output, without
depending on any of the glue code of the compiler.
In the byteOffset function, compile errors may need to compute the AST
from source bytes in order to resolve source locations. Previously there
were a few lines trying to access the AST before it was loaded. Trivial
fix, just move load the tree at the beginning.
This allows Sema to namespace them separately from function decls with
the same name. Ran into this in std.math.order conflicting with a test
with the same name.
instead of node indexes.
* AstGen: dbg_stmt instructions now have line and column indexes,
relative to the parent declaration. This allows codegen to emit debug
info without having the source bytes, tokens, or AST nodes loaded
in memory.
* ZIR: each decl has the absolute line number. This allows computing
line numbers from offsets without consulting source code bytes.
Memory management: creating a function definition does not prematurely
set the Decl arena. Instead the function is allocated with the general
purpose allocator.
Codegen no longer looks at source code bytes for any reason. They can
remain unloaded from disk.
* AstGen: LocalVal and LocalPtr use string table indexes for their
names. This is more efficient because local variable declarations do
need to include the variable names so that semantic analysis can emit
a compile error if a declaration is shadowed. So we take advantage of
this fact by comparing string table indexes when resolving names.
* The arg ZIR instructions are needed for the above reasoning, as well
as to emit equivalent AIR instructions for debug info.
Now that we have these arg instructions, get rid of the special
`Zir.Inst.Ref` range for parameters. ZIR instructions now refer
to the arg instructions for parameters.
* Move identAsString and strLitAsString from Module.GenZir to AstGen
where they belong.
Before there was this "top_decl" and "tmp_namespace" stack values that
were kludgy and buggy. Now Sema is slightly reworked so that files which
are structs are analyzed with their own Decl and Namespace already set
up.
After this commit there are no memory leaks for a successful build-obj.
Two problems solved:
* The Decl name may be allocated with gpa or it may be a reference to
the ZIR string table.
* The main update() function was freeing the ZIR when we still had
Decl objects referencing it.
* AstGen: add missing `break_inline` for comptime blocks.
* Module: call getTree() in byteOffset(). This generates the AST when
using cached ZIR and compile errors need to be reported.
* Scope.File: distinguish between successful ZIR generation and AIR
generation (when Decls in scope have been scanned).
- `semaFile` correctly avoids doing work twice.
* Implement first pass at `lookupInNamespace`. It has various TODOs
left, such as `usingnamespace`, and setting up Decl dependencies.
We do this by reserving string table indexes 0 and 1 in ZIR to be
special. Decls now have 0 to mean comptime or usingnamespace, and 1 to
mean an unnamed test decl.
* Remove some unused imports in AstGen.zig. I think it would make sense
to start decoupling AstGen from the rest of the compiler code,
similar to how the tokenizer and parser are decoupled.
* AstGen: For decls, move the block_inline instructions to the top of
the function so that they get lower ZIR instruction indexes. With
this, the block_inline instruction index combined with its corresponding
break_inline instruction index can be used to form a ZIR instruction
range. This is useful for allocating an array to map ZIR instructions
to semantically analyzed instructions.
* Module: extract emit-h functionality into a struct, and only allocate
it when emit-h is activated.
* Module: remove the `decl_table` field. This previously was a table of
all Decls in the entire Module. A "name hash" strategy was used to
find decls within a given namespace, using this global table. Now,
each Namespace has its own map of name to children Decls.
- Additionally, there were 3 places that relied on iterating over
decl_table in order to function:
- C backend and SPIR-V backend. These now have their own decl_table
that they keep populated when `updateDecl` and `removeDecl` are
called.
- emit-h. A `decl_table` field has been added to the new GlobalEmitH
struct which is only allocated when emit-h is activated.
* Module: fix ZIR serialization/deserialization bug in debug mode having
to do with the secret safety tag for untagged unions. There is still an
open TODO to investigate a friendlier solution to this problem with
the language.
* Module: improve deserialization of ZIR to allocate only exactly as
much capacity as length in the instructions array so as to not waste
space.
* Module: move `srcHashEql` to `std.zig` to live next to the definition
of `SrcHash` itself.
* Module: re-introduce the logic for scanning top level declarations
within a namespace.
* Compilation: add an `analyze_pkg` Job which is used to kick off the
start of semantic analysis by doing the equivalent of
`_ = @import("std");`. The `analyze_pkg` job is unconditionally added
to the work queue on every update(), with pkg set to the std lib pkg.
* Rename TZIR to AIR in a few places. A more comprehensive rename will
come later.
* Every decl provides a 16 byte source hash which can be used to detect
if the source code for any particular decl has changed.
* Include comptime decls, test decls, and usingnamespace decls in the
decls list of namespaces.
- Tests are encoded as extended functions with is_test bit set.
Notably this exposed an issue with the language having to do with the
secret safety tag on untagged unions. How can we have our cake and eat
it too? Not solved in this commit. I will file a language proposal to
tackle this issue soon.
Fixes a compile error in `std.fs.File.readvAll`.
Inside a nosuspend block, emit function calls as nosuspend calls.
Also inside a comptime block, emit function calls as comptime calls.
Also emit `async foo()` calls as async calls.
Remove compile error for `nosuspend` block inside `suspend` block.
Instead of implicitly treating every `suspend` block also as a
`nosuspend` block (which would make sense), we leave suspension points
as compile errors, to hint to the programmer about accidents. Of course
they may then assert `nosuspend` by introducing a block within their
suspend block.
To make room in `Zir.Inst.Tag` I moved `typeof_peer` and `compile_log`
to `Extended`.
* AstGen: implement `anyframe_literal` and `anyframe_type`.
* Introduce `makeSubBlock` to avoid redundant AstGen code for GenZir
scopes. Allows adding/removing a field without possibility of
accidentally introducing a bug of forgetting to set the new field.
* Add to GenZir `nosuspend_node` and `suspend_node` in preparation for
implementing `suspend` blocks and `nosuspend` blocks.
* AstGen: fix assembly to support clobbers, multiple outputs, and
outputs without `->` syntax.
- `asm` and `asm_volatile` move to `Extended` enum with `small` being
repurposed for a few things. This frees up 2 ZIR tags, 1 of which
is used in this commit and 1 is leftover.
* AstGen: fix `simple_types` incorrectly having multiple conflicting
values for "undefined" and "null".
- Also add "anyframe" to `simple_types`.
* Add `anyframe_type` to type.zig, value.zig and `Zir.Inst.Ref`.
- Also add i128 and u128 types to `Zir.Inst.Ref` and `simple_types`.
* Sema/Zir: Fix incorrect math causing the function body to be messed
up for Extended-encoded functions.
* Zir: support `i32` fields for "extra" payloads.
This commit also reclaims +2 ZIR instruction tags by moving the
following to `extended`:
* func_var_args
* func_extra
* func_extra_var_args
The following ZIR instruction tag is added:
* func_inferred
* AstGen: represent compile errors in ZIR rather than returning
`error.AnalysisFail`.
* ZIR: remove decl_ref and decl_val instructions. These are replaced by
`decl_ref_named` and `decl_val_named`, respectively, which will
probably get renamed in the future to the instructions that were just
deleted.
* AstGen: implement `@This()`, `@fence()`, `@returnAddress()`, and
`@src()`.
* AstGen: struct_decl improved to support fields_len=0 but have decls.
* AstGen: fix missing null bytes after compile error messages.
* SrcLoc: no longer depend on `Decl`. Instead have an explicit field
`parent_decl_node` which is an absolute AST Node index.
* Module: `failed_files` table can have null value, in which case the
key, which is a `*Scope.File`, will have ZIR errors in it.
* ZIR: implement text rendering of struct decls.
* CLI: introduce debug_usage and `zig astgen` command which is enabled
when the compiler is built in debug mode.
This was also an experiment to see if it were easier to implement a new
feature when using the instruction encoder.
Verdict: It's not that much easier, but I think it's certainly much more
readable, because the description of the Instruction annotates what each
field means. Right now, precise knowledge of x86_64 instructions is
still required because things like when to set the 64-bit flag, how to
read x86_64 instruction references, etc. are still not automatically
done for you.
In the future, this interface might make it sligtly easier to write an
assembler for x86_64, by abstracting the bit-fiddling aspects of
instruction encoding.
See #8516.
* AstGen is now done on whole files at once rather than per Decl.
* Introduce a new wait group for AstGen tasks. `performAllTheWork`
waits for all AstGen tasks to be complete before doing Sema,
single-threaded.
- The C object compilation tasks are moved to be spawned after
AstGen, since they only need to complete by the end of
the function.
With this commit, the codebase compiles, but much more reworking is
needed to get things back into a useful state.
* AstGen: emit decl lookup ZIR instructions rather than directly
looking up decls in AstGen. This is necessary because we want to
reuse the same immutable ZIR code for multiple generic instantiations
(and comptime function calls).
* AstGen: fix using members_len instead of fields_len for struct decls.
* structs: the struct_decl ZIR instruction is now also a block. This is
so that the type expressions, default field value expressions, and
alignment expressions can be evaluated in a scope that contains the
decls from the struct namespace itself.
* Add "std" and "builtin" packages to the builtin package.
* Don't try to build glibc, musl, or mingw-w64 when using `-ofmt=c`.
* builtin.zig is generated without `usingnamespace`.
* builtin.zig takes advantage of `std.zig.fmtId` for CPU features.
* A first pass at implementing `usingnamespace`. It's problematic and
should either be deleted, or polished, before merging this branch.
* Sema: allow explicitly specifying the namespace in which to look up
Decls. This is used by `struct_decl` in order to put the decls from
the struct namespace itself in scope when evaluating the type
expressions, default value expressions, and alignment expressions.
* Module: fix `analyzeNamespace` assuming that it is the top-level root
declaration node.
* Sema: implement comptime and runtime cmp operator.
* Sema: implement peer type resolution for enums and enum literals.
* Pull in the changes from master branch:
262e09c482.
* ZIR: complete out simple_ptr_type debug printing