68 Commits

Author SHA1 Message Date
Andrew Kelley
f378b0adce stage2: comptime function with the same args is memoized
* Introduce `memoized_calls` to `Module` which stores all the comptime
   function calls that are cached. It is keyed on the `*Fn` and the
   comptime arguments, but it does not yet properly detect comptime function
   pointers and avoid memoizing in this case. So it will have false
   positives for when a comptime function call mutates data through a
   pointer parameter.
 * Sema: Add a new helper function: `resolveConstMaybeUndefVal`
 * Value: add `enumToInt` method and use it in `zirEnumToInt`. It is
   also used by the hashing function.
 * Value: fix representation of optionals to match error unions.
   Previously it would not handle nested optionals correctly. Now it
   matches the memory layout of error unions and supports nested
   optionals properly. This required changes in all the backends for
   generating optional constants.
 * TypedValue gains `eql` and `hash` methods.
 * Value: Implement hashing for floats, optionals, and enums.
   Additionally, the zig type tag is added to the hash, where it was not
   previously, so that values of differing types will get different
   hashes.
2021-08-21 20:47:42 -07:00
Andrew Kelley
0cd361219c stage2: field type expressions support referencing locals
The big change in this commit is making `semaDecl` resolve the fields if
the Decl ends up being a struct or union. It needs to do this while
the `Sema` is still in scope, because it will have the resolved AIR
instructions that the field type expressions possibly reference. We do
this after the decl is populated and set to `complete` so that a `Decl`
may reference itself.

Everything else is fixes and improvements to make the test suite pass
again after making this change.

 * New AIR instruction: `ptr_elem_ptr`
   - Implemented for LLVM backend
 * New Type tag: `type_info` which represents `std.builtin.TypeInfo`. It
   is used by AstGen for the operand type of `@Type`.
 * ZIR instruction `set_float_mode` uses `coerced_ty` to avoid
   superfluous `as` instruction on operand.
 * ZIR instruction `Type` uses `coerced_ty` to properly handle result
   location type of operand.

 * Fix two instances of `enum_nonexhaustive` Value Tag not handled
   properly - it should generally be handled the same as `enum_full`.
 * Fix struct and union field resolution not copying Type and Value
   objects into its Decl arena.
 * Fix enum tag value resolution discarding the ZIR=>AIR instruction map
   for the child Sema, when they still needed to be accessed.
 * Fix `zirResolveInferredAlloc` use-after-free in the AIR instructions
   data array.
 * Fix `elemPtrArray` not respecting const/mutable attribute of pointer
   in the result type.
 * Fix LLVM backend crashing when `updateDeclExports` is called before
   `updateDecl`/`updateFunc` (which is, according to the API, perfectly
   legal for the frontend to do).
 * Fix LLVM backend handling element pointer of pointer-to-array. It
   needed another index in the GEP otherwise LLVM saw the wrong type.
 * Fix LLVM test cases not returning 0 from main, causing test failures.
   Fixes a regression introduced in
   6a5094872f10acc629543cc7f10533b438d0283a.

 * Implement comptime shift-right.
 * Implement `@Type` for integers and `@TypeInfo` for integers.
 * Implement union initialization syntax.
 * Implement `zirFieldType` for unions.
 * Implement `elemPtrArray` for a runtime-known operand.

 * Make `zirLog2IntType` support RHS of shift being `comptime_int`. In
   this case it returns `comptime_int`.

The motivating test case for this commit was originally:

```zig
test "example" {
    var l: List(10) = undefined;
    l.array[1] = 1;
}

fn List(comptime L: usize) type {
    var T = u8;
    return struct {
        array: [L]T,
    };
}
```

However I changed it to:

```zig
test "example" {
    var l: List = undefined;
    l.array[1] = 1;
}

const List = blk: {
    const T = [10]u8;
    break :blk struct {
        array: T,
    };
};
```

Which ended up being a similar, smaller problem. The former test case
will require a similar solution in the implementation of comptime
function calls - checking if the result of the function call is a struct
or union, and using the child `Sema` before it is destroyed to resolve
the fields.
2021-08-20 15:41:57 -07:00
Andrew Kelley
799fedf612 stage2: pass some error union tests
* Value: rename `error_union` to `eu_payload` and clarify the intended
   usage in the doc comments. The way error unions is represented with
   Value is fixed to not have ambiguous values.
 * Fix codegen for error union constants in all the backends.
 * Implement the AIR instructions having to do with error unions in the
   LLVM backend.
2021-08-07 20:34:28 -07:00
Andrew Kelley
e9e3a29946 stage2: implement generic function memoization
Module has a new field `monomorphed_funcs` which stores the set of
`*Module.Fn` objects which are generic function instantiations.
The hash is based on hashes of comptime values of parameters known to be
comptime based on an explicit comptime keyword or must-be-comptime
type expressions that can be evaluated without performing monomorphization.
This allows function calls to be semantically analyzed cheaply for
generic functions which are already instantiated.

The table is updated with a single `getOrPutAdapted` in the semantic
analysis of `call` instructions, by pre-allocating the `Fn` object and
passing it to the child `Sema`.
2021-08-05 16:37:21 -07:00
Andrew Kelley
d4468affb7 stage2 generics improvements: anytype and param type exprs
AstGen result locations now have a `coerced_ty` tag which is the same as
`ty` except it assumes that Sema will do a coercion, so it does not
redundantly add an `as` instruction into the ZIR code. This results in
cleaner ZIR and about a 14% reduction of ZIR bytes.

param and param_comptime ZIR instructions now have a block body for
their type expressions. This allows Sema to skip evaluation of the
block in the case that the parameter is comptime-provided. It also
allows a new mechanism to function: when evaluating type expressions of
generic functions, if it would depend on another parameter, it returns
`error.GenericPoison` which bubbles up and then is caught by the
param/param_comptime instruction and then handled.

This allows parameters to be evaluated independently so that the type
info for functions which have comptime or anytype parameters will still
have types populated for parameters that do not depend on values of
previous parameters (because evaluation of their param blocks will return
successfully instead of `error.GenericPoison`).

It also makes iteration over the block that contains function parameters
slightly more efficient since it now only contains the param
instructions.

Finally, it fixes the case where a generic function type expression contains
a function prototype. Formerly, this situation would cause shared state
to clobber each other; now it is in a proper tree structure so that
can't happen. This fix also required adding a field to Sema
`comptime_args_fn_inst` to make sure that the `comptime_args` field
passed into Sema is applied to the correct `func` instruction.

Source location for `node_offset_asm_ret_ty` is fixed; it was pointing at
the asm output name rather than the return type as intended.

Generic function instantiation is fixed, notably with respect to
parameter type expressions that depend on previous parameters, and with
respect to types which must be always comptime-known. This involves
passing all the comptime arguments at a callsite of a generic function,
and allowing the generic function semantic analysis to coerce the values
to the proper types (since it has access to the evaluated parameter type
expressions) and then decide based on the type whether the parameter is
runtime known or not. In the case of explicitly marked `comptime`
parameters, there is a check at the semantic analysis of the `call`
instruction.

Semantic analysis of `call` instructions does type coercion on the
arguments, which is needed both for generic functions and to make up for
using `coerced_ty` result locations (mentioned above).

Tasks left in this branch:
 * Implement the memoization table.
 * Add test coverage.
 * Improve error reporting and source locations for compile errors.
2021-08-04 21:11:31 -07:00
Andrew Kelley
ddf14323ea stage2: implement @truncate 2021-08-01 16:13:58 -07:00
Andrew Kelley
6ae0825e7f Sema: implement comptime variables
Sema now properly handles alloc_inferred and alloc_inferred_mut ZIR
instructions inside a comptime execution context. In this case it
creates Decl objects and points to them with the new `decl_ref_mut`
Value Tag. `storePtr` is updated to mutate such Decl types and values.
In this case it destroys the old arena and makes a new one, preventing
memory growth during comptime code execution.

Additionally:

 * Fix `storePtr` to emit a compile error for a pointer comptime-known
   to be undefined.
 * Fix `storePtr` to emit runtime instructions for all the cases that a
   pointer is comptime-known but does not support comptime
   dereferencing, such as `@intToPtr` on a hard-coded address, or an
   extern function.
 * Fix `ret_coerce` not coercing inside inline function call context.
2021-08-01 12:36:04 -07:00
Andrew Kelley
507dc1f2e7 stage2: fix hashing and comparison design flaw with Value
* `Value.toType` accepts a buffer parameter instead of an allocator
   parameter and can no longer fail.
 * Module: remove the unused `mod: *Module` parameter from various
   functions.
 * `Value.compare` now accepts a `Type` parameter which indicates the
   type of both operands. There is also a `Value.compareHetero` which
   accepts only Value parameters and supports comparing mixed types.
   Likewise, `Value.eql` requires a `Type` parameter.
 * `Value.hash` is removed; instead the hash map context structs now
   have a `ty: Type` field, and the hash function lives there, where it
   has access to a Value's Type when it computes a hash.
   - This allowed the hash function to be greatly simplified and sound
     in the sense that the same Values, even with different
     representations, always hash to the same thing.
 * Sema: Fix source location of zirCmp when an operand is runtime known
   but needs to be comptime known.
 * Remove unused target parameter from `Value.floatCast`.
2021-07-30 16:17:59 -07:00
Andrew Kelley
040c6eaaa0 stage2: garbage collect unused anon decls
After this change, the frontend and backend cooperate to keep track of
which Decls are actually emitted into the machine code. When any backend
sees a `decl_ref` Value, it must mark the corresponding Decl `alive`
field to true.

This prevents unused comptime data from spilling into the output object
files. For example, if you do an `inline for` loop, previously, any
intermediate value calculations would have gone into the object file.
Now they are garbage collected immediately after the owner Decl has its
machine code generated.

In the frontend, when it is time to send a Decl to the linker, if it has
not been marked "alive" then it is deleted instead.

Additional improvements:
 * Resolve type ABI layouts after successful semantic analysis of a
   Decl. This is needed so that the backend has access to struct fields.
 * Sema: fix incorrect logic in resolveMaybeUndefVal. It should return
   "not comptime known" instead of a compile error for global variables.
 * `Value.pointerDeref` now returns `null` in the case that the pointer
   deref cannot happen at compile-time. This is true for global
   variables, for example. Another example is if a comptime known
   pointer has a hard coded address value.
 * Binary arithmetic sets the requireRuntimeBlock source location to the
   lhs_src or rhs_src as appropriate instead of on the operator node.
 * Fix LLVM codegen for slice_elem_val which had the wrong logic for
   when the operand was not a pointer.

As noted in the comment in the implementation of deleteUnusedDecl, a
future improvement will be to rework the frontend/linker interface to
remove the frontend's responsibility of calling allocateDeclIndexes.

I discovered some issues with the plan9 linker backend that are related
to this, and worked around them for now.
2021-07-29 19:30:37 -07:00
Andrew Kelley
a5c6e51f03 stage2: more principled approach to comptime references
* AIR no longer has a `variables` array. Instead of the `varptr`
   instruction, Sema emits a constant with a `decl_ref`.
 * AIR no longer has a `ref` instruction. There is no longer any
   instruction that takes a value and returns a pointer to it. If this
   is desired, Sema must either create an anynomous Decl and return a
   constant `decl_ref`, or in the case of a runtime value, emit an
   `alloc` instruction, `store` the value to it, and then return the
   `alloc`.
 * The `ref_val` Value Tag is eliminated. `decl_ref` should be used
   instead. Also added is `eu_payload_ptr` which points to the payload
   of an error union, given an error union pointer.

In general, Sema should avoid calling `analyzeRef` if it can be helped.
For example in the case of field_val and elem_val, there should never be
a reason to create a temporary (alloc or decl). Recent previous commits
made progress along that front.

There is a new abstraction in Sema, which looks like this:

    var anon_decl = try block.startAnonDecl();
    defer anon_decl.deinit();
    // here 'anon_decl.arena()` may be used
    const decl = try anon_decl.finish(ty, val);
    // decl is typically now used with `decl_ref`.

This pattern is used to upgrade `ref_val` usages to `decl_ref` usages.

Additional improvements:

 * Sema: fix source location resolution for calling convention
   expression.
 * Sema: properly report "unable to resolve comptime value" for loads of
   global variables. There is now a set of functions which can be
   called if the callee wants to obtain the Value even if the tag is
   `variable` (indicating comptime-known address but runtime-known value).
 * Sema: `coerce` resolves builtin types before checking equality.
 * Sema: fix `u1_type` missing from `addType`, making this type have a
   slightly more efficient representation in AIR.
 * LLVM backend: fix `genTypedValue` for tags `decl_ref` and `variable`
   to properly do an LLVMConstBitCast.
 * Remove unused parameter from `Value.toEnum`.

After this commit, some test cases are no longer passing. This is due to
the more principled approach to comptime references causing more
anonymous decls to get sent to the linker for codegen. However, in all
these cases the decls are not actually referenced by the runtime machine
code. A future commit in this branch will implement garbage collection
of decls so that unused decls do not get sent to the linker for codegen.
This will make the tests go back to passing.
2021-07-29 15:59:51 -07:00
Andrew Kelley
dc88864c97 stage2: implement @boolToInt
This is the first commit in which some behavior tests are passing for
both stage1 and stage2.
2021-07-27 17:08:37 -07:00
Andrew Kelley
a8e964eadd stage2: zig test now works with the LLVM backend
Frontend improvements:

 * When compiling in `zig test` mode, put a task on the work queue to
   analyze the main package root file. Normally, start code does
   `_ = import("root");` to make Zig analyze the user's code, however in
   the case of `zig test`, the root source file is the test runner.
   Without this change, no tests are picked up.
 * In the main pipeline, once semantic analysis is finished, if there
   are no compile errors, populate the `test_functions` Decl with the
   set of test functions picked up from semantic analysis.
 * Value: add `array` and `slice` Tags.

LLVM backend improvements:

 * Fix incremental updates of globals. Previously the
   value of a global would not get replaced with a new value.
 * Fix LLVM type of arrays. They were incorrectly sending
   the ABI size as the element count.
 * Remove the FuncGen parameter from genTypedValue. This function is for
   generating global constants and there is no function available when
   it is being called.
   - The `ref_val` case is now commented out. I'd like to eliminate
     `ref_val` as one of the possible Value Tags. Instead it should
     always be done via `decl_ref`.
 * Implement constant value generation for slices, arrays, and structs.
 * Constant value generation for functions supports the `decl_ref` tag.
2021-07-27 14:19:53 -07:00
Andrew Kelley
eadbee2041 stage2: first pass at printing AIR/Liveness to text
* some instructions are not implemented yet
 * fix off-by-1 in Air.getMainBody
 * Compilation: use `@import("builtin")` rather than `std.builtin`
   for the values that are different for different build configurations.
 * Sema: avoid calling `addType` in between
   air_instructions.ensureUnusedCapacity and corresponding
   appendAssumeCapacity because it can possibly add an instruction.
 * Value: functions print their names
2021-07-20 12:19:16 -07:00
Andrew Kelley
12c10139e3 Sema: finish reworking for AIR memory layout except switch 2021-07-20 12:19:16 -07:00
Andrew Kelley
c09b973ec2 stage2: compile error fixes for AIR memory layout branch
Now the branch is compiling again, provided that one uses
`-Dskip-non-native`, but many code paths are disabled. The code paths
can now be re-enabled one at a time and updated to conform to the new
AIR memory layout.
2021-07-20 12:19:16 -07:00
Andrew Kelley
5d6f7b44c1 stage2: rework AIR memory layout
This commit changes the AIR file and the documentation of the memory
layout. The actual work of modifying the surrounding code (in Sema and
codegen) is not yet done.
2021-07-20 12:18:14 -07:00
Andrew Kelley
13f04e3012 stage2: implement @panic and beginnigs of inferred error sets
* ZIR: add two instructions:
   - ret_err_value_code
   - ret_err_value
 * AstGen: add countDefers and utilize it to emit more efficient ZIR for
   return expressions in the presence of defers.
 * AstGen: implement |err| payloads for `errdefer` syntax.
   - There is not an "unused capture" error for it yet.
 * AstGen: `return error.Foo` syntax gets a hot path in return
   expressions, using the new ZIR instructions. This also is part of
   implementing inferred error sets, since we need to tell Sema to add
   an error value to the inferred error set before it gets coerced.
 * Sema: implement `@setCold`.
   - Implement `@setCold` support for C backend.
 * `@panic` and regular safety panics such as `unreachable` now properly
   invoke `std.builtin.panic`.
 * C backend: improve pointer and function value rendering.
 * C linker: fix redundant typedefs.
 * Add Type.error_set_inferred.
 * Fix Value.format for enum_literal, enum_field_index, bytes.
 * Remove the C backend test that checks for identical text

I measured a 14% reduction in Total ZIR Bytes from master branch
for std/os.zig.
2021-07-07 00:39:23 -07:00
Jacob G-W
9fffffb07b fix code broken from previous commit 2021-06-21 17:03:03 -07:00
g-w1
e13a182990
stage2 Sema: implement @intToPtr (#9144)
Co-authored-by: Veikka Tuominen <git@vexu.eu>
2021-06-21 18:47:34 +03:00
Veikka Tuominen
7efd7bc3b8 stage2: implement comptime variables 2021-06-07 22:15:56 +03:00
Martin Wickham
fc9430f567 Breaking hash map changes for 0.8.0
- hash/eql functions moved into a Context object
- *Context functions pass an explicit context
- *Adapted functions pass specialized keys and contexts
- new getPtr() function returns a pointer to value
- remove functions renamed to fetchRemove
- new remove functions return bool
- removeAssertDiscard deleted, use assert(remove(...)) instead
- Keys and values are stored in separate arrays
- Entry is now {*K, *V}, the new KV is {K, V}
- BufSet/BufMap functions renamed to match other set/map types
- fixed iterating-while-modifying bug in src/link/C.zig
2021-06-03 17:02:16 -05:00
Andrew Kelley
79dee75b1c stage2: rename ir.zig to air.zig
We've settled on the nomenclature for the artifacts the compiler
pipeline produces:

1. Tokens
2. AST (Abstract Syntax Tree)
3. ZIR (Zig Intermediate Representation)
4. AIR (Analyzed Intermediate Representation)
5. Machine Code

Renaming `ir` identifiers to `air` will come with the inevitable
air-memory-layout branch that I plan to start after the 0.8.0 release.
2021-05-22 14:29:16 -07:00
Andrew Kelley
5619ce2406 Merge remote-tracking branch 'origin/master' into stage2-whole-file-astgen
Conflicts:
 * doc/langref.html.in
 * lib/std/enums.zig
 * lib/std/fmt.zig
 * lib/std/hash/auto_hash.zig
 * lib/std/math.zig
 * lib/std/mem.zig
 * lib/std/meta.zig
 * test/behavior/alignof.zig
 * test/behavior/bitcast.zig
 * test/behavior/bugs/1421.zig
 * test/behavior/cast.zig
 * test/behavior/ptrcast.zig
 * test/behavior/type_info.zig
 * test/behavior/vector.zig

Master branch added `try` to a bunch of testing function calls, and some
lines also had changed how to refer to the native architecture and other
`@import("builtin")` stuff.
2021-05-08 14:45:21 -07:00
Veikka Tuominen
42a95197f3 update usage of std.testing in stage2 2021-05-08 15:15:30 +03: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
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
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
95b014caea Sema: implement struct_decl instruction 2021-05-03 18:35:37 -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
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
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
ae495de54d AstGen: implement all the builtin functions 2021-04-18 22:38:41 -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
b40d36c90b stage2: implement simple enums
A simple enum is an enum which has an automatic integer tag type,
all tag values automatically assigned, and no top level declarations.
Such enums are created directly in AstGen and shared by all the
generic/comptime instantiations of the surrounding ZIR code. This
commit implements, but does not yet add any test cases for, simple enums.

A full enum is an enum for which any of the above conditions are not
true. Full enums are created in Sema, and therefore will create a unique
type per generic/comptime instantiation. This commit does not implement
full enums. However the `enum_decl_nonexhaustive` ZIR instruction is
added and the respective Type functions are filled out.

This commit makes an improvement to ZIR code, removing the decls array
and removing the decl_map from AstGen. Instead, decl_ref and
decl_val ZIR instructions index into the `owner_decl.dependencies`
ArrayHashMap. We already need this dependencies array for incremental
compilation purposes, and so repurposing it to also use it for ZIR decl
indexes makes for efficient memory usage.

Similarly, this commit fixes up incorrect memory management by removing
the `const` ZIR instruction. The two places it was used stored memory in
the AstGen arena, which may get freed after Sema. Now it properly sets
up a new anonymous Decl for error sets and uses a normal decl_val
instruction.

The other usage of `const` ZIR instruction was float literals. These are
now changed to use `float` ZIR instruction when the value fits inside
`zir.Inst.Data` and `float128` otherwise.

AstGen + Sema: implement int_to_enum and enum_to_int. No tests yet; I expect to
have to make some fixes before they will pass tests. Will do that in the
branch before merging.

AstGen: fix struct astgen incorrectly counting decls as fields.

Type/Value: give up on trying to exhaustively list every tag all the
time. This makes the file more manageable. Also found a bug with
i128/u128 this way, since the name of the function was more obvious when
looking at the tag values.

Type: implement abiAlignment and abiSize for structs. This will need to
get more sophisticated at some point, but for now it is progress.

Value: add new `enum_field_index` tag.
Value: add hash_u32, needed when using ArrayHashMap.
2021-04-06 18:17:37 -07:00
Andrew Kelley
8ebfdc14f6 stage2: implement structs in the frontend
New ZIR instructions:
 * struct_decl_packed
 * struct_decl_extern

New TZIR instruction: struct_field_ptr

Introduce `Module.Struct`. It uses `Value` to store default values and
abi alignments.

Implemented Sema.analyzeStructFieldPtr and zirStructDecl.

Some stuff I changed from `@panic("TODO")` to `log.warn("TODO")`.
It's becoming more clear that we need the lazy value mechanism soon;
Type is becoming unruly, and some of these functions have too much logic
given that they don't have any context for memory management or error
reporting.
2021-04-01 22:39:09 -07:00
Andrew Kelley
8f469c1127 stage2: fix error sets 2021-03-28 19:40:21 -07:00
Andrew Kelley
be673e6793 stage2: implement inttype ZIR
also add i128 and u128 to const inst list
2021-03-23 16:12:26 -07:00
Isaac Freund
9f0b9b8da1
stage2: remove all async related code
The current plan is to avoid using async and related features in the
stage2 compiler so that we can bootstrap before implementing them.

Having this untested and incomplete code in the codebase increases
friction while working on stage2, in particular when preforming
larger refactors such as the current zir memory layout rework.

Therefore remove all async related code, leaving only error messages
in astgen.
2021-03-23 00:23:41 +01:00
Andrew Kelley
aef3e534f5 stage2: *WIP*: rework ZIR memory layout; overhaul source locations
The memory layout for ZIR instructions is completely reworked. See
zir.zig for those changes. Some new types:

 * `zir.Code`: a "finished" set of ZIR instructions. Instead of allocating
   each instruction independently, there is now a Tag and 8 bytes of
   data available for all ZIR instructions. Small instructions fit
   within these 8 bytes; larger ones use 4 bytes for an index into
   `extra`. There is also `string_bytes` so that we can have 4 byte
   references to strings. `zir.Inst.Tag` describes how to interpret
   those 8 bytes of data.
   - This is shared by all `Block` scopes.

 * `Module.WipZirCode`: represents an in-progress `zir.Code`. In this
   structure, the arrays are mutable, and get resized as we add/delete
   things. There is extra state to keep track of things. This struct is
   stored on the stack. Once it is finished, it produces an immutable
   `zir.Code`, which will remain on the heap for the duration of a
   function's existence.
   - This is shared by all `GenZir` scopes.

 * `Sema`: represents in-progress semantic analysis of a `zir.Code`.
   This data is stored on the stack and is shared among all `Block`
   scopes. It is now the main "self" argument to everything in the file
   that was previously named `zir_sema.zig`.
   Additionally, I moved some logic that was in `Module` into here.

`Module.Fn` now stores its parameter names inside the `zir.Code`,
instead of inside ZIR instructions. When the TZIR memory layout
reworking time comes, codegen will be able to reference this data
directly instead of duplicating it.

astgen.zig is (so far) almost entirely untouched, but nearly all of it
will need to be reworked to adhere to this new memory layout structure.

I have no benchmarks to report yet, as I am still working through
compile errors and fixing various things that I broke in this branch.

Overhaul of Source Locations:

Previously we used `usize` everywhere to mean byte offset, but sometimes
also mean other stuff. This was error prone and also made us do
unnecessary work, and store unnecessary bytes in memory.

Now there are more types involved into source locations, and more ways
to describe a source location.

 * AllErrors.Message: embrace the assumption that files always have less
   than 2 << 32 bytes.
 * SrcLoc gets more complicated, to model more complicated source
   locations.
 * Introduce LazySrcLoc, which can model interesting source locations
   with very little stored state. Useful for avoiding doing unnecessary
   work when no compile errors occur.

Also, previously, we had `src: usize` on every ZIR instruction. This is
no longer the case. Each instruction now determines whether it even cares
about source location, and if so, how that source location is stored.
This requires more careful work inside `Sema`, but it results in fewer
bytes stored on the heap, without compromising accuracy and power of
compile error messages.

Miscellaneous:

 * std.zig: string literals have more helpful result values for
   reporting errors. There is now a lower level API and a higher level
   API.
   - side note: I noticed that the string literal logic needs some love.
     There is some unnecessarily hacky code there.
 * cut & pasted some TZIR logic that was in zir.zig to ir.zig. This
   probably broke stuff and needs to get fixed.
 * Removed type/Enum.zig, type/Union.zig, and type/Struct.zig. I don't
   think this quite how this code will be organized. Need some more
   careful planning about how to implement structs, unions, enums. They
   need to be independent Decls, just like a top level function.
2021-03-16 00:03:22 -07:00
jacob gw
2ebeb0dbf3 stage2: remove error number from error set map
This saves memory since it is already stored in module
as well as allowing for better threading.
Part 2 of what is outlined in #8079.
2021-03-03 11:49:54 -08:00
jacob gw
58b14d01ae stage2: remove value field from error
This saves memory and from what I have heard allows threading
to be easier.
2021-02-28 22:01:13 +02:00
Andrew Kelley
fd208d9d59 stage2: implement the error_value AST tag 2021-02-25 18:21:22 -07:00
g-w1
153c97ac9e improve stage2 to allow catch at comptime:
* add error_union value tag.
* add analyzeIsErr
* add Value.isError
* add TZIR wrap_errunion_payload and wrap_errunion_err for
  wrapping from T -> E!T and E -> E!T
* add anlyzeInstUnwrapErrCode and analyzeInstUnwrapErr
* add analyzeInstEnsureErrPayloadVoid:
* add wrapErrorUnion
* add comptime error comparison for tests
* tests!
2021-02-25 16:41:16 -08:00
Tadeo Kondrak
0b5f3c2ef9
Replace @TagType uses, mostly with std.meta.Tag 2021-01-30 22:26:44 +02:00
Andrew Kelley
29c9d5896c Merge branch 'Stage2 begin implementing container types' 2021-01-11 16:25:21 -07:00
Jonathan Marler
31802c6c68 remove z/Z format specifiers
Zig's format system is flexible enough to add custom formatters.  This PR removes the new z/Z format specifiers that were added for printing Zig identifiers and replaces them with custom formatters.
2021-01-07 23:49:22 -08:00
Andrew Kelley
fea8659b82 stage2: comptime function calls
* Function calls that happen in a comptime scope get called at
   compile-time. We do this by putting the parameters in place as
   constant values and then running regular function analysis on the
   body.
 * Added `Scope.Block.dump()` for debugging purposes.
 * Fixed some code to call `identifierTokenString` rather than
   `tokenSlice`, making it work for `@""` syntax.
 * Implemented `Value.copy` for big integers.

Follow-up issues to tackle:
 * Adding compile errors to the callsite instead of the callee Decl.
 * Proper error notes for "called from here".
   - Related: #7555
 * Branch quotas.
 * ZIR support?
2021-01-02 19:10:11 -07:00
LemonBoy
1c13ca5a05 stage2: Use {s} instead of {} when formatting strings 2021-01-02 17:12:57 -07:00