161 Commits

Author SHA1 Message Date
Emily Bellows
674932e503 C backend: implement ?void, and other zero sized types 2021-11-02 12:45:29 -04:00
Andrew Kelley
d2f9646d98 C backend: fix enough that zig test works
* test_functions: properly add dependencies of the array on test
   functions and test names so that the order comes out correctly.
 * fix lowering of struct literals to add parentheses around the type
   name.
 * omit const qualifier in slices because otherwise slices cannot be
   reassigned even when they are local variables.
 * special case pointer to functions and double pointer to functions in
   renderTypeAndName. This code will need to be cleaned up but for now
   it helps us make progress on other C backend stuff.
 * fix slice element access to lower to `.ptr[` instead of `[`.
 * airSliceElemVal: respect volatile slices
2021-10-28 15:59:14 -07:00
Andrew Kelley
c6b3d06535 Sema: improved C pointers and casting
* C pointer types always have allowzero set to true but they omit the
   word allowzero when printed.
 * Implement coercion from C pointers to other pointers.
 * Implement in-memory coercion for slices and pointer-like optionals.
 * Make slicing a C pointer drop the allowzero bit.
 * Value representation for pointer-like optionals is now allowed to use
   pointer tag values in addition to the `opt_payload` tag.
2021-10-26 13:46:27 -07:00
Andrew Kelley
6df26a37d1 Sema: fix coercion from union to its own tag
I had reversed the tag type / union type arguments.
2021-10-26 12:03:15 -07:00
Andrew Kelley
df198ea60e
Merge pull request #10034 from Snektron/stage2-slice
stage2: slice and optional improvements
2021-10-25 19:41:19 -04:00
Robin Voetter
21bf3b8066 stage2: runtime c pointer null comparison 2021-10-26 01:24:14 +02:00
Andrew Kelley
8509e7111d stage2: fix switch on tagged union capture-by-pointer
* AstGen: always use `typeof` and never `typeof_elem` on the
   `switch_cond`/`switch_cond_ref` instruction because both variants
   return a value and not a pointer.
   - Delete the `typeof_elem` ZIR instruction since it is no longer
     needed.
 * Sema: validateUnionInit now recognizes a comptime mutable value and
   no longer emits a compile error saying "cannot evaluate constant
   expression"
   - Still to-do is detecting comptime union values in a function that
     is not being executed at compile-time.
     - This is still to-do for structs too.
 * Sema: when emitting a call AIR instruction, call resolveTypeLayout on
   all the parameter types as well as the return type.
 * `Type.structFieldOffset` now works for unions in addition to structs.
2021-10-25 15:11:21 -07:00
Andrew Kelley
22b4c9e1a9 stage2: implement more C pointer Sema and comptime ptr arith 2021-10-23 19:47:32 -07:00
Andrew Kelley
0a6851cc6d stage2: implement comptime loads through casted pointers 2021-10-21 22:56:11 -07:00
Robin Voetter
09c7d5aebc stage2: elemPtr for slices
* Restructure elemPtr a bit
* New AIR instruction: slice_elem_ptr, which returns a pointer to an element of a slice
* Value: adapt elemPtr to work on slices
2021-10-21 16:24:18 +02:00
Andrew Kelley
a0e195120d stage2: implement slicing
* New AIR instruction: slice, which constructs a slice out of a pointer
   and a length.
 * AstGen: use `coerced_ty` for start and end expressions, use `none`
   for the sentinel, and don't try to load the result of the slice
   operation because it returns a by-value result.
 * Sema: pointer arithmetic is extracted into analyzePointerArithmetic
   and it is used by the implementation of slice.
   - Also I implemented comptime pointer addition.
 * Sema: extract logic into analyzeSlicePtr, analyzeSliceLen and use them
   inside the slice semantic analysis.
   - The approach in stage2 is much cleaner than stage1 because it uses
     more granular analysis calls for obtaining the slice pointer, doing
     arithmetic on it, and checking if the length is comptime-known.
 * Sema: use the slice Value Tag for slices when doing coercion from
   pointer-to-array.
 * LLVM backend: detect when emitting a GEP instruction into a
   pointer-to-array and add the extra index that is required.
 * Type: ptrAlignment for c_void returns 0.
 * Implement Value.hash and Value.eql for slices.
 * Remove accidentally duplicated behavior test.
2021-10-20 21:45:11 -07:00
Andrew Kelley
c1508c98f4 stage2 minor cleanups 2021-10-19 19:38:43 -07:00
Robin Voetter
d6f048c456 stage2: make (typeHas)OnePossibleValue return the right value 2021-10-20 03:44:02 +02:00
Andrew Kelley
bea447a637 stage2: fix coercion of error set to error union
When returning an error set or an error union from a function which has
an inferred error set, it populates the error names in addition to the
set of functions. This can have false negatives, meaning that after
checking the map of an unresolved error set, one must do full error set
resolution before emitting a compile error.
2021-10-18 15:45:11 -07:00
Meghan Denny
0ef2e2520a stage2: implement @hasField
struct and union are kept in stage1 because struct/unionFieldCount are returning zero
2021-10-17 21:42:22 -07:00
Andrew Kelley
07691db3ae stage2: fix handling of error unions as return type
* LLVM backend: fix phi instruction not respecting `isByRef`
   - Also fix `is_non_null` not respecting `isByRef`
 * Type: implement abiSize for error unions
2021-10-17 15:36:12 -07:00
Andrew Kelley
6534f2ef4f stage2: implement error wrapping
* Sema: fix returned operands not coercing to the function return type
   in some cases.
   - When returning an error or an error union from a function with an
     inferred error set, it will now populate the inferred error set.
   - Implement error set coercion for the common case of inferred error
     set to inferred error set, without forcing a full resolution.
 * LLVM backend: update instruction lowering that handles error unions
   to respect `isByRef`.
   - Also implement `wrap_err_union_err`.
2021-10-17 14:55:32 -07:00
Andrew Kelley
127cd06ba1 stage2: add haveFieldTypes() assertions
This will help with contributions such as #9966.
2021-10-17 10:59:40 -07:00
Andrew Kelley
fdd11f6cee Sema: coercion from error sets to anyerror 2021-10-16 12:41:03 -07:00
Andrew Kelley
682cdeceaa stage2: optional comparison and 0-bit payloads
* Sema: implement peer type resolution for optionals and null.
 * Rename `Module.optionalType` to `Type.optional`.
 * LLVM backend: re-use anonymous values. This is especially useful when
   isByRef()=true because it means re-using the same generated LLVM globals.
 * LLVM backend: rework the implementation of is_null and is_non_null
   AIR instructions. Generate slightly better LLVM code, and also fix
   the behavior for optionals whose payload type is 0-bit.
 * LLVM backend: improve `cmp` AIR instruction lowering to support
   pointer-like optionals.
 * `Value`: implement support for equality-checking optionals.
2021-10-15 18:37:09 -07:00
Andrew Kelley
186126c2a4 stage2: make hasCodeGenBits() always true for pointers
* LLVM backend: The `alloc` AIR instruction as well as pointer
   constants which point to a 0-bit element type now call a common
   codepath to produce a `*const llvm.Value` which is a non-zero pointer
   with a bogus-but-properly-aligned address.
 * LLVM backend: improve the lowering of optional types.
 * Type: `hasCodeGenBits()` now returns `true` for pointers even when
   it returns `false` for their element types.

Effectively, #6706 is now implemented in stage2 but not stage1.
2021-10-15 17:17:59 -07:00
Andrew Kelley
55eea3b045 stage2: implement @minimum and @maximum, including vectors
* std.os: take advantage of `@minimum`. It's probably time to
   deprecate `std.min` and `std.max`.
 * New AIR instructions: min and max
 * Introduce SIMD vector support to stage2
 * Add `@Type` support for vectors
 * Sema: add `checkSimdBinOp` which can be re-used for other arithmatic
   operators that want to support vectors.
 * Implement coercion from vectors to arrays.
   - In backends this is handled with bitcast for vector to array,
     however maybe we want to reduce the amount of branching by
     introducing an explicit AIR instruction for it in the future.
 * LLVM backend: implement lowering vector types
 * Sema: Implement `slice.ptr` at comptime
 * Value: improve `numberMin` and `numberMax` to support floats in
   addition to integers, and make them behave properly in the presence
   of NaN.
2021-10-14 21:17:30 -07:00
Andrew Kelley
8b88274781 stage2: improved union support
* `Module.Union.getFullyQualifiedName` returns a sentinel-terminated
   slice so that backends that need null-termination do not need an
   additional copy.
 * Module.Union: implement a `getLayout` function which returns
   information about ABI size and alignment so that the LLVM backend can
   properly lower union types into llvm types.
 * Sema: `resolveType` now returns `error.GenericPoison` rather than a
   Type with tag `generic_poison`. Callsites that want to allow that
   need to bypass this higher-level function.
 * Sema: implement coercion of enums and enum literals to unions.
 * Sema: fix comptime mutation of pointers to unions
 * LLVM backend: fully implement proper lowering of union types and
   values according to the union layout, and update the handling of AIR
   instructions that deal with unions to support union layouts.
 * LLVM backend: handle `decl_ref_mut`
   - Maybe this should be unreachable since comptime vars should be
     changed to be non-mutable when they go out of scope, but it's
     harmless for the LLVM backend to support lowering the value.
 * Type: fix `requiresComptime` for optionals, pointers, and some other
   types. This function is still wrong for structs, unions, and enums.
2021-10-14 17:44:46 -07:00
Andrew Kelley
0d4a94f32f stage2: improve handling of 0-bit types and arrays
* Make `alloc` AIR instructions call `resolveTypeLayout`.
 * `Sema.zirResolveInferredAlloc` now calls `requireRuntimeBlock` in the
   case that it operates on a non-comptime instruction.
 * `Type.abiSize` and `Type.abiAlignment` now return 0 for `void`
 * Sema: implement `resolveTypeFields` for unions.
 * LLVM Backend: support `ptr_elem_ptr` when the element type is 0-bit.
 * Type: improve `abiAlignment` implementation for structs to properly
   handle fields with non-default alignment.
 * Value: implement hashing array, vector, and structs.
2021-10-13 21:20:38 -07:00
Andrew Kelley
b0f80ef0d5 stage2: remove use of builtin.stage2_arch workaround
The LLVM backend no longer needs this hack! However, the other backends
still do. So there are still some traces of this workaround in use for now.
2021-10-13 18:43:43 -07:00
Andrew Kelley
df7d6d263e stage2: implement opaque declarations
* Module: implement opaque type namespace lookup
 * Add `Type.type` for convenience
 * Sema: fix `validateVarType` for pointer-to-opaque
 * x86_64 ABI: implement support for pointers
 * LLVM backend: fix lowering of opaque types
 * Type: implement equality checking for opaques
2021-10-13 17:53:28 -07:00
Andrew Kelley
da7fcfd158 stage2: implement Sema for elemVal for comptime slice 2021-10-13 16:31:07 -07:00
Andrew Kelley
a3104a4a78 stage2: fix comptime stores and sentinel-terminated arrays
* ZIR: the `array_type_sentinel` now has a source node attached to it
   for proper error reporting.
 * Refactor: move `Module.arrayType` to `Type.array`
 * Value: the `bytes` and `array` tags now include the sentinel, if the
   type has one. This simplifies comptime evaluation logic.
 * Sema: fix `zirStructInitEmpty` to properly handle when the type is
   void or a sentinel-terminated array. This handles the syntax `void{}`
   and `[0:X]T{}`.
 * Sema: fix the logic for reporting "cannot store runtime value in
   compile time variable" as well as for emitting a runtime store when a
   pointer value is comptime known but it is a global variable.
 * Sema: implement elemVal for double pointer to array. This can happen
   with this code for example: `var a: *[1]u8 = undefined; _ = a[0];`
 * Sema: Rework the `storePtrVal` function to properly handle nested
   structs and arrays.
   - Also it now handles comptime stores through a bitcasted pointer.
     When the pointer element type and the type according to the Decl
     don't match, the element value is bitcasted before storage.
2021-10-12 21:38:46 -07:00
Andrew Kelley
6d6cf59847 stage2: support nested structs and arrays and sret
* Add AIR instructions: ret_ptr, ret_load
   - This allows Sema to be blissfully unaware of the backend's decision
     to implement by-val/by-ref semantics for struct/union/array types.
     Backends can lower these simply as alloc, load, ret instructions,
     or they can take advantage of them to use a result pointer.
 * Add AIR instruction: array_elem_val
   - Allows for better codegen for `Sema.elemVal`.
 * Implement calculation of ABI alignment and ABI size for unions.
 * Before appending the following AIR instructions to a block,
   resolveTypeLayout is called on the type:
   - call - return type
   - ret - return type
   - store_ptr - elem type
 * Sema: fix memory leak in `zirArrayInit` and other cleanups to this
   function.
 * x86_64: implement the full x86_64 C ABI according to the spec
 * Type: implement `intInfo` for error sets.
 * Type: implement `intTagType` for tagged unions.

The Zig type tag `Fn` is now used exclusively for function bodies.
Function pointers are modeled as `*const T` where `T` is a `Fn` type.
 * The `call` AIR instruction now allows a function pointer operand as
   well as a function operand.
 * Sema now has a coercion from function body to function pointer.
 * Function type syntax, e.g. `fn()void`, now returns zig tag type of
   Pointer with child Fn, rather than Fn directly.
   - I think this should probably be reverted. Will discuss the lang
     specs before doing this. Idea being that function pointers would
     need to be specified as `*const fn()void` rather than `fn() void`.

LLVM backend:
 * Enable calling the panic handler (previously this just
   emitted `@breakpoint()` since the backend could not handle the panic
   function).
 * Implement sret
 * Introduce `isByRef` and implement it for structs and arrays. Types
   that are `isByRef` are now passed as pointers to functions, and e.g.
   `elem_val` will return a pointer instead of doing a load.
 * Move the function type creating code from `resolveLlvmFunction` to
   `llvmType` where it belongs; now there is only 1 instance of this
   logic instead of two.
 * Add the `nonnull` attribute to non-optional pointer parameters.
 * Fix `resolveGlobalDecl` not using fully-qualified names and not using
   the `decl_map`.
 * Implement `genTypedValue` for pointer-like optionals.
 * Fix memory leak when lowering `block` instruction and OOM occurs.
 * Implement volatile checks where relevant.
2021-10-11 11:39:12 -07:00
Andrew Kelley
e16ddad49f stage2: enum fixes
* Sema: fix a missing copy on enum tag values
 * LLVM backend: fix lowering of enum constant values for enums with
   specified tag values.
 * Value: fix enumToInt for `enum_numbered` cases.

The float widening behavior tests which rely on compiler-rt symbols are
now passing.
2021-10-05 23:05:14 -07:00
Andrew Kelley
cb616cb797 stage2: implement runtime @intToEnum
* Update AIR instruction `intcast` to allow the dest type to be an
   enum.
 * LLVM backend: update `intcast` to support when the bit counts of
   operand and dest type are the same. This was already a requirement of
   the instruction previously.
 * Type: `intInfo` supports the case when the type is an enum, and
   retrieves the info for the integer tag type. This makes it pretty
   easy for backends to implement `intcast` without having to care
   explicitly that the new type is an enum. As a bonus, simple enums
   never have to go through the type system; their signedness and bit
   count are computed directly.

The "int to enum" behavior test case is now passing for stage2 in the
LLVM backend.
2021-10-05 21:38:47 -07:00
Andrew Kelley
ac2333ee63 stage2: fix Type max/min int calculation
This was an attempt to move saturating_arithmetic.zig to the "passing
for stage2" section, which did not pan out due to the discovery of 2
prerequisite items that need to be done, but I did make a bug fix along
the way of the calculation of max/min integers.

This commit also simplifies the saturating arithmetic behavior tests to
depend on less of the zig language that is not related to saturating
arithmetic.
2021-10-04 12:23:49 -07:00
Robin Voetter
96f095987f Adapt Type.minInt and maxInt to use setTwosCompLimit 2021-10-04 11:25:29 +02:00
Andrew Kelley
a41f812bdb C backend: fix lowering of struct types
with fields which are function pointers.
Before the name was in the wrong place.
2021-10-03 13:28:51 -07:00
Andrew Kelley
86c265aec8 stage2: Type: fix eql impl for error unions
Also implement renderFullyQualifiedName.
2021-10-03 12:49:57 -07:00
Martin Wickham
272bad3f12 Delete Module.Scope, move Block into Sema 2021-10-02 15:21:49 -05:00
Andrew Kelley
bdbedff910 stage2: LLVM backend: properly set module target data
Also fix tripping LLVM assert having to do with 0 bit integers.
stage2 behavior tests now run clean in a debug build of llvm 12.
2021-09-29 15:33:45 -07:00
Andrew Kelley
ea6706b6f4 stage2: LLVM backend: implement struct type fwd decls
Makes struct types able to refer to themselves.
2021-09-29 14:04:52 -07:00
Andrew Kelley
99961f22dc stage2: enable building compiler_rt when using LLVM backend
* AstGen: fix emitting `store_to_inferred_ptr` when it should be emitting
   `store` for a variable that has an explicit alignment.
 * Compilation: fix a couple memory leaks
 * Sema: implement support for locals that have specified alignment.
 * Sema: implement `@intCast` when it needs to emit an AIR instruction.
 * Sema: implement `@alignOf`
 * Implement debug printing for extended alloc ZIR instructions.
2021-09-29 00:13:21 -07:00
Andrew Kelley
33e77f127d stage2: implement @clz and @ctz
Also improve the LLVM backend to support lowering bigints to LLVM
values.

Moves over a bunch of math.zig test cases to the "passing for stage2"
section.
2021-09-28 22:38:51 -07:00
Martin Wickham
1cc5d4e758
Stage 2: Support inst.func() syntax (#9827)
* Merge call zir instructions to make space for field_call
* Fix bug with comptime known anytype args
* Delete the param_type zir instruction
* Move some passing tests to stage 2
* Implement a.b() function calls
* Add field_call_bind support for call and field builtins
2021-09-28 12:00:35 -05:00
Andrew Kelley
09e1f37cb6 stage2: implement union coercion to its own tag
* AIR: add `get_union_tag` instruction
   - implement in LLVM backend
 * Sema: implement == and != for union and enum literal
   - Also implement coercion from union to its own tag type
 * Value: implement hashing for union values

The motivating example is this snippet:

    comptime assert(@typeInfo(T) == .Float);

This was the next blocker for stage2 building compiler-rt.
Now it is switch at compile-time on an integer.
2021-09-27 23:11:00 -07:00
Andrew Kelley
c0aa4a1a42 stage2: implement basic unions
* AIR instructions struct_field_ptr and related functions now are also
   emitted by the frontend for unions. Backends must inspect the type
   of the pointer operand to lower the instructions correctly.
   - These will be renamed to `agg_field_ptr` (short for "aggregate") in
     the future.
 * Introduce the new `set_union_tag` AIR instruction.
 * Introduce `Module.EnumNumbered` and associated `Type` methods. This
   is for enums which have no decls, but do have the possibility of
   overriding the integer tag type and tag values.
 * Sema: Implement support for union tag types in both the
   auto-generated and explicitly-provided cases, as well as explicitly
   provided enum tag values in union declarations.
 * LLVM backend: implement lowering union types, union field pointer
   instructions, and the new `set_union_tag` instruction.
2021-09-27 19:53:29 -07:00
Andrew Kelley
1f2f9f05c2 stage2: implement zirCoerceResultPtr
and remove Module.simplePtrType and Module.ptrType in favor of `Type.ptr`.
2021-09-25 22:18:43 -07:00
Andrew Kelley
04366576ea stage2: implement @sizeOf for non-packed structs 2021-09-25 17:54:52 -07:00
Andrew Kelley
42aa1ea115 stage2: implement @memset and @memcpy builtins 2021-09-24 17:33:06 -07:00
Stephen Gregoratto
87fd502fb6 Initial bringup of the Solaris/Illumos port 2021-09-24 14:06:16 -04:00
Josh Soref
664941bf14
Spelling corrections (#9833)
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
Co-authored-by: Josh Soref <jsoref@users.noreply.github.com>
2021-09-24 13:39:20 -04:00
Andrew Kelley
e03095f167 stage2: remove 2 assertions that were too aggressive
* `Type.hasCodeGenBits` this function is used to find out if it ever
   got sent to a linker backend for lowering. In the case that a struct
   never has its struct fields resolved, this will be false. In such a
   case, no corresponding `freeDecl` needs to be issued to the linker
   backend. So instead of asserting the fields of a struct are resolved,
   this function now returns `false` for this case.

 * `Module.clearDecl` there was logic that asserted when there is no
   outdated_decls map, any dependants of a Decl being cleared had to be
   in the deletion set. However there is a possible scenario where the
   dependant is not in the deletion set *yet* because there is a Decl
   which depends on it, about to be deleted. If it were added to an
   outdated_decls map, it would be subsequently removed from the map
   when it gets deleted recursively through its dependency being
   deleted.

These issues were uncovered via unrelated changes which are the two
commits immediately preceding this one.
2021-09-22 19:05:56 -07:00
Andrew Kelley
5913140b6b stage2: free Sema's arena after generating machine code
Previously, linker backends or machine code backends were able to hold
on to references to inside Sema's temporary arena. However there can
be large objects stored there that we want to free after machine code is
generated.

The primary change in this commit is to use a temporary arena for Sema
of function bodies that gets freed after machine code backend finishes
handling `updateFunc` (at the same time that Air and Liveness get freed).

The other changes in this commit are fixing issues that fell out from
the primary change.

 * The C linker backend is rewritten to handle updateDecl and updateFunc
   separately. Also, all Decl updates get access to typedefs and
   fwd_decls, not only functions.
 * The C linker backend is updated to the new API that does not depend
   on allocateDeclIndexes and does not have to handle garbage collected
   decls.
 * The C linker backend uses an arena for Type/Value objects that
   `typedefs` references. These can be garbage collected every so often
   after flush(), however that garbage collection code is not
   implemented at this time. It will be pretty simple, just allocate a
   new arena, copy all the Type objects to it, update the keys of the
   hash map, free the old arena.
 * Sema: fix a handful of instances of not copying Type/Value objects
   from the temporary arena into the appropriate Decl arena.
 * Type: fix some function types not reporting hasCodeGenBits()
   correctly.
2021-09-21 15:23:29 -07:00