443 Commits

Author SHA1 Message Date
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
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
d36a31ba75 stage2: fix scanDecls not advancing the field bits
Also fix `semaFile` not handling compile errors properly.
2021-04-28 23:16: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
3462193d30 stage2: prepare for mainining Decl references to ZIR indexes 2021-04-28 16:57:01 -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
fa6bb4b662 Sema: do not analyze test decls when not in test mode
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.
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
91c317bb9a AstGen: improved handling of declarations
* 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.
2021-04-26 17:36:28 -07:00
Andrew Kelley
56226449d2 stage2: pre-open ZIR cache dir handles
So that we do not needlessly open and close the ZIR cache dir handles in
each AstGen operation.
2021-04-25 10:43:07 -07:00
Andrew Kelley
015cd79f89 stage2: implement caching for ZIR code
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`.
2021-04-25 00:02:58 -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
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
2d290d6f82 stage2: write out builtin.zig before spawning AstGen tasks
Otherwise it's possible for AstGen to get FileNotFound when trying to
eager-load `import("builtin")`.
2021-04-22 22:35:18 -07:00
Andrew Kelley
389020009a AstGen: implement alignment on locals 2021-04-21 22:43:57 -07:00
Andrew Kelley
a62db38d90 AstGen: implement defer for break 2021-04-20 17:04:11 -07:00
Andrew Kelley
a59bcae59f AstGen: basic defer implementation 2021-04-20 17:04:11 -07:00
Andrew Kelley
e315120b79 AstGen: implement array initialization expressions 2021-04-19 23:23:24 -07:00
Andrew Kelley
2083208f19 AstGen: implement functions with inferred error sets
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
2021-04-19 15:03:41 -07:00
Andrew Kelley
ae495de54d AstGen: implement all the builtin functions 2021-04-18 22:38:41 -07:00
Andrew Kelley
e13fc6b119 stage2: make @import relative to the current file
previously, it was incorrectly relative to the package directory
2021-04-16 19:45:58 -07:00
Andrew Kelley
5ff45b3f44 stage2: use import list from ZIR to queue up more AstGen tasks 2021-04-16 17:28:28 -07:00
Andrew Kelley
01b4bf34ea stage2: AstGen improvements
* 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.
2021-04-16 14:48:10 -07:00
gracefu
c4b83ea021
stage2 x86_64: implement integer mul
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.
2021-04-16 15:21:17 +08:00
Andrew Kelley
8387307807 AstGen: implement global variable decls 2021-04-15 20:34:21 -07:00
Andrew Kelley
3114115348 stage2: preliminary reworking for whole-file-AstGen
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.
2021-04-15 19:06:39 -07:00
Andrew Kelley
9088d40e83 stage2: rename zir to Zir
since it now uses top level fields
2021-04-15 19:06:39 -07:00
Andrew Kelley
0170a242bb stage2: move zir.Code to become root level fields of zir.zig
next commit will do the rename
2021-04-15 19:06:39 -07:00
Andrew Kelley
df983b30d2 stage2: implement comptime division 2021-04-15 19:06:39 -07:00
Andrew Kelley
bcfebb4b2b stage2: improvements aimed at std lib integration
* 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:
   262e09c482d98a78531c049a18b7f24146fe157f.
 * ZIR: complete out simple_ptr_type debug printing
2021-04-15 19:06:39 -07:00
Andrew Kelley
a4bb7c8bb1 stage2: remove redundant source hash 2021-04-15 19:06:39 -07:00
Andrew Kelley
f458192e56 stage2: entry point via std lib and proper updated file detection
Instead of Module setting up the root_scope with the root source file,
instead, Module relies on the package table graph being set up properly,
and inside `update()`, it does the equivalent of `_ = @import("std");`.
This, in term, imports start.zig, which has the logic to call main (or
not). `Module` no longer has `root_scope` - the root source file is no
longer special, it's just in the package table mapped to "root".

I also went ahead and implemented proper detection of updated files.
mtime, inode, size, and source hash are kept in `Scope.File`.
During an update, iterate over `import_table` and stat each file to find
out which ones are updated.

The source hash is redundant with the source hash used by the struct
decl that corresponds to the file, so it should be removed in a future
commit before merging the branch.

 * AstGen: add "previously declared here" notes for variables shadowing
   decls.
 * Parse imports as structs. Module now calls `AstGen.structDeclInner`,
   which is called by `AstGen.containerDecl`.
   - `importFile` is a bit kludgy with how it handles the top level Decl
     that kinda gets merged into the struct decl at the end of the
     function. Be on the look out for bugs related to that as well as
     possibly cleaner ways to implement this.
 * Module: factor out lookupDeclName into lookupIdentifier and lookupNa
 * Rename `Scope.Container` to `Scope.Namespace`.
 * Delete some dead code.

This branch won't work until `usingnamespace` is implemented because it
relies on `@import("builtin").OutputMode` and `OutputMode` comes from a
`usingnamespace`.
2021-04-15 19:06:39 -07:00
jacob gw
0d92bd474f stage2: fix case where public variables did not work 2021-04-09 11:54:38 -07:00
Andrew Kelley
f75cdd1acd
Merge pull request #8470 from ziglang/stage2-start
stage2: blaze the trail for std lib integration
2021-04-09 10:15:46 -07:00
jacob gw
afe5862111 stage2: add error for private decls accessed from other files 2021-04-09 10:05:15 -07:00
Andrew Kelley
1b702f8ddb stage2: fix the memory leaks 2021-04-08 20:52:02 -07:00
Andrew Kelley
61b868f9a5 stage2: simplify Decl src_node field
Also fix "previous definition here" error notes to be correct.
2021-04-08 20:37:19 -07:00
Andrew Kelley
482b995a49 stage2: blaze the trail for std lib integration
This branch adds "builtin" and "std" to the import table when using the
self-hosted backend.

"builtin" gains one additional item:

```
pub const zig_is_stage2 = true; // false when using stage1 backend
```

This allows the std lib to do conditional compilation based on detecting
which backend is being used. This will be removed from builtin as soon
as self-hosted catches up to feature parity with stage1.
Keep a sharp eye out - people are going to be tempted to abuse this.
The general rule of thumb is do not use `builtin.zig_is_stage2`. However
this commit breaks the rule so that we can gain limited start.zig support
as we incrementally improve the self-hosted compiler.

This commit also implements `fullyQualifiedNameHash` and related
functionality, which effectively puts all Decls in their proper
namespaces. `fullyQualifiedName` is not yet implemented.

Stop printing "todo" log messages for test decls unless we are in test
mode.

Add "previous definition here" error notes for Decl name collisions.

This commit does not bring us yet to a newly passing test case.

Here's what I'm working towards:

```zig
const std = @import("std");

export fn main() c_int {
    const a = std.fs.base64_alphabet[0];
    return a - 'A';
}
```

Current output:

```
$ ./zig-cache/bin/zig build-exe test.zig
test.zig:3:1: error: TODO implement more analyze elemptr
zig-cache/lib/zig/std/start.zig:38:46: error: TODO implement structInitExpr ty
```

So the next steps are clear:
 * Sema: improve elemptr
 * AstGen: implement structInitExpr
2021-04-08 19:05:05 -07:00
Luuk de Gram
ff5774d93d
Refactor link/wasm.zig to use offset table
This refactor inserts an offset table into wasm's data section
where each offset points to the actual data region.
This means we can keep offset indexes consistant and do not
have to perform any computer to determine where in the data section
something like a static string exists. Instead during runtime
it will load the data offset onto the stack.
2021-04-08 22:47:08 +02:00
Luuk de Gram
1bd5552fc1
Calculate data length to ensure correct pointer offsets 2021-04-08 22:47:08 +02:00
Andrew Kelley
b9e508c410 stage2: revert to only has_decl and export ZIR support
Reverting most of the code from the previous commits in this branch.
Will pull in the code with modifications bit by bit.
2021-04-08 11:29:31 -07:00
Timon Kruiper
a483e38df6 stage2: fix bug where invalid ZIR was generated
The following code caused an assertion to be hit:
```
pub fn main() void {
    var e: anyerror!c_int = error.Foo;
    const i = e catch 69;
    assert(69 - i == 0);
}
```
2021-04-08 14:23:18 +02:00
Timon Kruiper
ac14b52e85 stage2: add support for start.zig
This adds a simplified start2.zig that the current stage2 compiler is
able to generate code for.
2021-04-08 14:23:18 +02:00
Timon Kruiper
272fe0cbfe stage2: fix bug in ZIR gen of global comptime block
A global comptime block did not end with a break_inline instruction
which caused an assertion to be hit.
2021-04-08 14:20:40 +02:00
Andrew Kelley
e730172e47 stage2: fix switch validation of handling all enum values
There were several problems, all fixed:
 * AstGen was storing field names as references to the original
   source code bytes. However, that data would be destroyed when the
   source file is updated. Now, it correctly stores the field names in
   the Decl arena for the enum. The same fix applies to error set field
   names.
 * Sema was missing a memset inside `analyzeSwitch`, leaving the "seen
   enum fields" array with undefined memory. Now that they are all
   properly set to null, the validation works.
 * Moved the "enum declared here" note to the end. It looked weird
   interrupting the notes for which enum values were missing.
2021-04-07 22:02:45 -07:00
Andrew Kelley
12087d4cba stage2: fix incremental compilation handling of parse errors
Before, incremental compilation would crash when trying to emit compile
errors for the update after introducing a parse error.

Parse errors are handled by not invalidating any existing semantic
analysis. However, only the parse error must be reported, with all the
other errors suppressed. Once the parse error is fixed, the new file can
be treated as an update to the previously-succeeded update.
2021-04-07 20:36:01 -07:00