149 Commits

Author SHA1 Message Date
Andrew Kelley
bcf15e39e2 stage2: add owns_tv flag to Module.Decl
Decl objects need to know whether they are the owner of the Type/Value
associated with them, in order to decide whether to destroy the
associated Namespace, Fn, or Var when cleaning up.
2021-05-11 14:17:52 -07:00
Andrew Kelley
dae22a0a1f stage2: struct, union, enum, opaque, error sets get better names
This commit takes advantage of the new "NameStrategy" that is exposed
in the ZIR in order to name Decls after their parent when asked to. This
makes the next failing test case pass.
2021-05-10 22:50:00 -07:00
Andrew Kelley
b9a099e83c stage2: type declarations ZIR encode AnonNameStrategy
which can be either parent, func, or anon. Here's the enum reproduced in
the commit message for convenience:

```zig
pub const NameStrategy = enum(u2) {
    /// Use the same name as the parent declaration name.
    /// e.g. `const Foo = struct {...};`.
    parent,
    /// Use the name of the currently executing comptime function call,
    /// with the current parameters. e.g. `ArrayList(i32)`.
    func,
    /// Create an anonymous name for this declaration.
    /// Like this: "ParentDeclName_struct_69"
    anon,
};
```

With this information in the ZIR, a future commit can improve the
names of structs, unions, enums, and opaques.

In order to accomplish this, the following ZIR instruction forms were
removed and replaced with Extended op codes:

 * struct_decl
 * struct_decl_packed
 * struct_decl_extern
 * union_decl
 * union_decl_packed
 * union_decl_extern
 * enum_decl
 * enum_decl_nonexhaustive

By being extended opcodes, one more u32 is needed, however we more than
make up for it by repurposing the 16 "small" bits to provide shorter
encodings for when decls_len == 0, fields_len == 0, a source node is not
provided, etc. There tends to be no downside, and in fact sometimes
upsides, to using an extended op code when there is a need for flag
bits, which is the case for all three of these. Likewise, the container
layout can be encoded in these bits rather than into the opcode.

The following 4 ZIR instructions were added, netting a total of 4 freed
up ZIR enum tags for future use:

 * opaque_decl_anon
 * opaque_decl_func
 * error_set_decl_anon
 * error_set_decl_func

This is so that opaques and error sets can have the same name hint as
structs, enums, and unions.

`std.builtin.ContainerLayout` gets an explicit integer tag type so that
it can be used inside packed structs.

This commit also makes `Module.Namespace` use a separate set for
anonymous decls, thus allowing anonymous decls to share the same
`Decl.name` as their owner `Decl` objects.
2021-05-10 21:34:43 -07:00
Andrew Kelley
aa0352fad6 Sema: fix @setEvalBranchQuota incorrectly requiring a function body 2021-05-08 14:06:36 -07:00
Andrew Kelley
28353b3159 stage2: fix struct inits not getting fields resolved 2021-05-07 22:16:15 -07:00
Andrew Kelley
d577654e66 stage2: fix stack overflow in @setEvalBranchQuota test case
Some of the reworkings in this branch put us over the limit, on Linux,
where the kernel disregards the fact that we ask for 16 MiB in the ELF
file. So we ask for more stack space in `main`.
2021-05-07 20:03:27 -07:00
Andrew Kelley
81d5104e22 stage2: implement global variables
* Sema: implement global variables
   - Improved global constants to stop needlessly creating a Var
     structure; they can just store the value directly.
   - This required making memory management a bit more sophisticated to
     detect when a Decl owns the Namespace associated with it, for the
     purposes of deinitialization.
 * Decl.name and Namespace decl table keys no longer directly
   reference ZIR; instead they have heap-duped names, so that deleted
   decls, which no longer have any ZIR to reference for their names, can
   be removed from the parent Namespace table.
   - In the future I would like to explore going a different direction
     with this, where the strings would still point to the ZIR however
     they would be removed from their owner Namespace objects during the
     update detection. The design principle here is that the existence
     of incremental compilation as a feature should not incur any cost
     for the use case when it is not used. In this example Decl names
     could simply point to ZIR string table memory, and it is only
     because of incremental compilation that we duplicate their names.
 * AstGen: implement threadlocal variables
 * CLI: call cleanExit after building a compilation so that in release
   modes we don't bother freeing memory or closing file descriptors,
   allowing the OS to do it more efficiently.
 * Avoid calling `freeDecl` in the linker for unreferenced Decl objects.
 * Fix CBE test case expecting the compile error to point to the wrong
   column.
2021-05-07 18:52:11 -07:00
Andrew Kelley
6ac2047142 stage2: implement extern functions 2021-05-07 16:06:25 -07:00
Andrew Kelley
47531b7d93 Sema: support enough to check main calling convention via @typeInfo
After this commit, `pub export fn main() c_int { ... }` will be
correctly detected as the intended entry point, and therefore start code
will not try to export its own conflicting `main` function.

 * Implement basic union support
   - lots of stuff is still TODO, including runtime field access
   - also TODO: resolving the union tag type
   - comptime field access is implemented
 * DRY up some code by using the `Zir.DeclIterator` for skipping over
   decls in structs and unions.
 * Start to clean up Sema with regards to calling `.value()` to find out
   a const value. Instead, Sema code should call one of these two:
   - `resolvePossiblyUndefinedValue` (followed by logic dealing with
     undefined values)
   - `resolveDefinedValue` (a compile error will be emitted if the value
     is undefined)
 * An exported function with an unspecified calling convention gets the
   C calling convention.
 * Implement comptime field access for structs.
 * Add another implementation of "type has one possible value" in Sema.
   This is a bit unfortunate since the logic is duplicated, but the one
   in Type asserts that the types are resolved already, and is
   appropriate to call from codegen, while the one in Sema performs
   type resolution if necessary, reporting any compile errors that occur
   in the process.
2021-05-07 14:18:14 -07:00
Andrew Kelley
a7221ef4e9 Sema: implement @typeInfo for functions
The goal is to get start code to be able to inspect the calling
convention of `main` in order to determine whether to export a main for
libc to call, or to allow the root source file to do it.
2021-05-06 22:30:44 -07:00
Andrew Kelley
7a27f0d80c Sema: restore the extern lib name functionality 2021-05-04 14:40:59 -07:00
Andrew Kelley
edfbf85ecd Sema: implement error sets 2021-05-04 13:58:08 -07:00
Andrew Kelley
3dafec0acd stage2: fix structs and enums setting wrong owner_decl
No more memory leaks.
2021-05-04 11:08:40 -07:00
Andrew Kelley
2ae72c6f09 Sema: implement ExportOptions support in @export
Also fix switch blocks not emitting their AIR code.
2021-05-03 20:05:29 -07:00
Andrew Kelley
69d18ad7f0 ZIR: typeof uses the un_node field not un_tok 2021-05-03 18:47:53 -07:00
Andrew Kelley
95b014caea Sema: implement struct_decl instruction 2021-05-03 18:35:37 -07:00
Andrew Kelley
773902e9de stage2: hook up semantic analysis of struct fields
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`.
2021-05-03 11:46:02 -07:00
Andrew Kelley
807a8b6f75 stage2: make struct field analysis lazy
This commit breaks struct field analysis; will be fixed in a future
commit.
2021-05-02 18:50:01 -07:00
Andrew Kelley
a973c362e5 AstGen: decouple from Module/Compilation
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.
2021-05-02 17:08:19 -07:00
Andrew Kelley
4dd724d06a Sema: fix struct decl decoding ZIR incorrectly 2021-05-01 23:31:26 -07:00
Andrew Kelley
eadcefc124 stage2: dbg_stmt ZIR instructions have line/col
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.
2021-05-01 21:57:52 -07:00
Andrew Kelley
351b57497b stage2: implement function body analysis
now with whole-file-astgen
2021-04-30 23:11:20 -07:00
Andrew Kelley
077b8d3def stage2: introduce new ZIR instruction: arg
* 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.
2021-04-30 21:43:18 -07:00
Andrew Kelley
db7acd83d2 Sema: implement function declarations 2021-04-30 14:36:02 -07:00
Andrew Kelley
2d8d681b5e stage2: un-tangle memory management of Decl and Namespace
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.
2021-04-30 11:07:31 -07:00
Andrew Kelley
8944240aec AstGen: represent global variables directly
Rather than with `block_inline_var`. This matches how function
declarations work and how extern variables work.
2021-04-29 19:56:01 -07:00
Andrew Kelley
86d564eed8 AstGen: implement extern variables 2021-04-29 19:44:51 -07:00
Andrew Kelley
ba9b9cb38d AstGen: implement function prototypes with alignment exprs 2021-04-29 18:25:25 -07:00
Andrew Kelley
47585cbe12 Sema: rename TZIR to AIR
Analyzed Intermediate Representation
2021-04-29 17:26:21 -07:00
Andrew Kelley
478dac5346 Sema: skip analysis of empty enum blocks
For these, the ZIR code has an empty block rather than a block with a
single `break_inline` instruction.
2021-04-29 17:25:10 -07:00
Andrew Kelley
9e49a65e1b AstGen: implement anytype struct fields 2021-04-29 17:13:18 -07:00
Andrew Kelley
55e86b724a AstGen: implement comptime struct fields 2021-04-29 16:57:13 -07:00
Andrew Kelley
0c71d2fdc1 stage2: implement semantic analysis for functions and global vars
* 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.
2021-04-28 22:43:26 -07:00
Andrew Kelley
f86469bc5e stage2: semaDecl properly analyzes the decl block
Also flattened out Decl TypedValue fields into
ty, val, has_tv
and add relevant fields to Decl for alignment and link section.
2021-04-28 16:57:01 -07:00
Andrew Kelley
bfded492f0 stage2: rewire the frontend driver to whole-file-zir
* 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.
2021-04-26 20:41:07 -07:00
Andrew Kelley
ff2ec0dc5a AstGen: implement @Vector 2021-04-24 17:44:07 -07:00
Andrew Kelley
e018e64a53 stage2: move overflow builtin ZIR instructions to Extended
make some more room in our ZIR enum tag space
2021-04-24 17:31:15 -07:00
Andrew Kelley
1592206965 AstGen: implement await and resume
based on @Vexu's code from before
2021-04-24 14:39:44 -07:00
Andrew Kelley
27fa4bc2be AstGen: support struct init with ref result location 2021-04-23 23:40:10 -07:00
Andrew Kelley
d2b06c2612 stage2: remove call_none and call_none_chkused ZIR
These are unproven optimizations and we need some more room in the
`Zir.Inst.Tag` enum for some more syntax.
2021-04-23 22:43:20 -07:00
Andrew Kelley
6b98384e20 stage2: remove dead ZIR instructions
clearing up some enum tag space for future added instructions
2021-04-23 22:40:57 -07:00
Andrew Kelley
fbfae832ea AstGen: emit nosuspend function calls
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`.
2021-04-23 21:12:29 -07:00
Andrew Kelley
9a271347fe AstGen: implement suspend blocks 2021-04-23 20:09:56 -07:00
Andrew Kelley
b40a8efb9a stage2: implement anyframe, anyframe->T and fix assembly
* 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.
2021-04-23 18:35:21 -07:00
Andrew Kelley
715abe8ebe AstGen: implement integers bigger than u64
also get rid of the `optional_type_from_ptr_elem` instruction.
2021-04-22 23:47:31 -07:00
Andrew Kelley
7c453b91b8 AstGen: implement @extern builtin 2021-04-22 16:31:51 -07:00
Andrew Kelley
3d637e6dd2 AstGen: fix @export
Make it properly use `std.builtin.ExportOptions`.
2021-04-22 16:07:58 -07:00
Andrew Kelley
389020009a AstGen: implement alignment on locals 2021-04-21 22:43:57 -07:00
Andrew Kelley
ea00ddfe37 AstGen: implement comptime locals 2021-04-21 20:42:49 -07:00
Andrew Kelley
570ed7b3bf AstGen: implement @bitCast for other result location types 2021-04-21 19:11:36 -07:00