Commit Graph

2909 Commits

Author SHA1 Message Date
Tadeo Kondrak
9270aae071
stage2: fix zero-sized function parameters (#7998) 2021-02-12 15:40:44 -05:00
Andrew Kelley
d3565ed6b4
Merge pull request #7749 from tadeokondrak/6429-callconv-inline
Replace inline fn with callconv(.Inline)
2021-02-11 16:01:58 -08:00
Evan Haas
d98f09e4f6 translate-c: comma operator should introduce a new scope
This prevents inadvertent side-effects when an expression is not evaluated
due to boolean short-circuiting

Fixes #7989
2021-02-12 01:40:43 +02:00
Tadeo Kondrak
bb4f4c043e
test/cli.zig: Remove inline from panic function in testGodboltApi
Might add another line to stack traces there.
2021-02-10 20:22:20 -07:00
Tadeo Kondrak
5dfe0e7e8f
Convert inline fn to callconv(.Inline) everywhere 2021-02-10 20:06:12 -07:00
Evan Haas
a2ec77041b translate-c: call @boolToInt on return value when necessary
In C, if a function has return type `int` and the return expression
is a boolean expression, there is no implicit cast. Therefore the
translated Zig code needs to call @boolToInt() on the result.

Written with feedback from @Vexu

Fixes #6215
2021-02-10 20:23:27 +02:00
Jonathan Marler
1480c42806 require specifier for arrayish types 2021-02-09 22:25:52 -08:00
Evan Haas
221f1d898c translate-c: Improve function pointer handling
Omit address-of operator if operand is a function.

Improve handling of function-call translation when using function pointers

Fixes #4124
2021-02-08 10:15:00 +02:00
Andrew Kelley
1517ed0a5e
Merge pull request #7895 from Luukdegram/wasm-control-flow
stage2: wasm control flow
2021-02-01 12:29:22 -08:00
Veikka Tuominen
3ec5c9a3bc
stage2 cbe: implement not and some bitwise ops 2021-02-01 08:48:24 +02:00
Veikka Tuominen
106520329e
stage2 cbe: implement switchbr 2021-02-01 08:48:22 +02:00
Veikka Tuominen
258f3ec5ec
stage2 cbe: block results 2021-02-01 08:47:25 +02:00
Veikka Tuominen
bdfe3aeab8
stage2 cbe: condbr and breaks 2021-02-01 08:47:25 +02:00
Andrew Kelley
0f5eda973e stage2: delete astgen for switch expressions
The astgen for switch expressions did not respect the ZIR rules of only
referencing instructions that are in scope:

  %14 = block_comptime_flat({
    %15 = block_comptime_flat({
      %16 = const(TypedValue{ .ty = comptime_int, .val = 1})
    })
    %17 = block_comptime_flat({
      %18 = const(TypedValue{ .ty = comptime_int, .val = 2})
    })
  })
  %19 = block({
    %20 = ref(%5)
    %21 = deref(%20)
    %22 = switchbr(%20, [%15, %17], {
      %15 => {
        %23 = const(TypedValue{ .ty = comptime_int, .val = 1})
        %24 = store(%10, %23)
        %25 = const(TypedValue{ .ty = void, .val = {}})
        %26 = break("label_19", %25)
      },
      %17 => {
        %27 = const(TypedValue{ .ty = comptime_int, .val = 2})
        %28 = store(%10, %27)
        %29 = const(TypedValue{ .ty = void, .val = {}})
        %30 = break("label_19", %29)
      }
    }, {
      %31 = unreachable_safe()
    }, special_prong=else)
  })

In this snippet you can see that the comptime expr referenced %15 and
%17 which are not in scope. There also was no test coverage for runtime
switch expressions.

Switch expressions will have to be re-introduced to follow these rules
and with some test coverage. There is some usable code being deleted in
this commit; it will be useful to reference when re-implementing switch
later.

A few more improvements to do while we're at it:
 * only use .ref result loc on switch target if any prongs obtain the
   payload with |*syntax|
   - this improvement should be done to if, while, and for as well.
   - this will remove the needless ref/deref instructions above
 * remove switchbr and add switch_block, which is both a block and a
   switch branch.
   - similarly we should remove loop and add loop_block.

This commit introduces a "force_comptime" flag into the GenZIR
scope. The main purpose of this will be to choose the "comptime"
variants of certain key zir instructions, such as function calls and
branches. We will be moving away from using the block_comptime_flat
ZIR instruction, and eventually deleting it.

This commit also contains miscellaneous fixes to this branch that bring
it to the state of passing all the tests.
2021-01-31 21:09:22 -07:00
Tadeo Kondrak
0b5f3c2ef9
Replace @TagType uses, mostly with std.meta.Tag 2021-01-30 22:26:44 +02:00
Michael Dusan
f9b85c6e50 stage1: add error for slice.len incr beyond bounds
comptime direct slice.len increment dodges bounds checking but
we can emit an error for it, at least in the simple case.

- promote original assert to compile-error
- add test case

closes #7810
2021-01-30 11:19:25 +02:00
Evan Haas
1ed8c54cd3 translate-c: add wide string literal support
Adds support for wide, UTF-16, and UTF-32 string literals. If used to initialize
an incomplete array, the same logic as narrow strings is used. Otherwise they
are translated as global "anonymous" arrays of the relevant underlying char type.
A dot is used in the name to ensure the generated names do not conflict with any
other names in the translated program.

For example:

```c
void my_fn() {
    const uint32_t *foo = U"foo";
}
```

becomes:
```zig
const @"zig.UTF32_string_2" = [4]c_uint{
    '\u{66}',
    '\u{6f}',
    '\u{6f}',
    0,
};
pub export fn my_fn() void {
    var foo: [*c]const u32 = &@"zig.UTF32_string_2";
}
```
2021-01-26 21:13:06 -08:00
Luuk de Gram
cc46c1b902
Add tests, fix locals that are created in blocks like loops, and handle all breaks correctly 2021-01-26 19:47:15 +01:00
Timon Kruiper
e23bc1f76a render: fix bug when rendering struct initializer with length 1
This crashed the compiler when running translate-c. See the added test.
2021-01-25 10:40:00 -08:00
Evan Haas
57b2176e28 translate-c: Improve array support
1. For incomplete arrays with initializer list (`int x[] = {1};`) use the
initializer size as the array size.

2. For arrays initialized with a string literal translate it as an array
of character literals instead of `[*c]const u8`

3. Don't crash if an empty initializer is used for an incomplete array.

4. Add a test for multi-character character constants

Additionally lay some groundwork for supporting wide string literals.

fixes #4831 #7832 #7842
2021-01-25 10:37:23 -08:00
Evan Haas
bea791b639 translate-c: fix variadic function calls
1702b413 introduced a bug with variadic function calls - trying to access the
paramType of non-existent parameters.
2021-01-20 22:26:18 -08:00
Jakub Konka
0e56d4cc02 stage2: converge x86_64 and aarch64 tests on macOS 2021-01-19 22:39:49 +01:00
Andrew Kelley
287f640cc9 stage2: ELF: fix crash when only 1 function and it gets updated 2021-01-19 14:08:43 -07:00
Andrew Kelley
30a824cb9e astgen: eliminate rlWrapPtr and all its callsites
The following AST avoids unnecessary derefs now:
 * error set decl
 * field access
 * array access
 * for loops: replace ensure_indexable and deref on the len_ptr with a
   special purpose ZIR instruction called indexable_ptr_len.

Added an error note when for loop operand is the wrong type.

I also accidentally implemented `@field`.
2021-01-19 00:38:53 -07:00
g-w1
3c2a9220ed stage2: fix orelse at comptime
There was just some untested code that did not work. .isnull -> .isnonnull
and I had to add a .ref resultloc to make types match up.
2021-01-18 19:29:18 -07:00
Andrew Kelley
46dd058d59
Merge pull request #7797 from Luukdegram/wasm-refactor
stage2: wasm - Refactor codegen for wasm similar to other backends
2021-01-18 12:35:52 -08:00
Evan Haas
c3dadfa95b translate-c: Add Wide, UTF-16, and UTF-32 character literals
Add support for L'<wchar_t>', u'<char16_t>', and U'<char32_t>'. Currently
this just translates wide char literals to \u{NNNNNN} escape codes
(e.g. U'💯' -> '\u{1f4af}')

Another approach would be to emit UTF-8 encoded character literals
directly, but in my opinion this approaches Unicode-complete because it
would require knowledge of which Unicode codepoints have graphical
representations for the emitted source to be readable.

We could also just emit integer literals, but the current method makes
it clear that we have translated a wide character literal and not just
an integer constant.
2021-01-18 11:05:51 -08:00
Jakub Konka
3562edf137 macho: improve x86_64 tests; clean fixups on error
When codegen ends in failure, we need to manually clean up any fixups
that may have been gathered during that `codegen.generateSymbol` call.
Otherwise, we will end trapping.
2021-01-17 16:01:16 +01:00
Jakub Konka
b25cf7db02 stage2 aarch64: add basic function pro/epilogue
Fix typo in `nop` implementation.
Simplify `aarch64` macOS tests.
2021-01-17 14:57:53 +01:00
Andrew Kelley
8deb21c58a stage2: add compile error for label redefinition
Also fix incorrectly destroying notes.

This work is based on Vexu's patch in #7555.
2021-01-17 00:15:25 -07:00
Andrew Kelley
8c9ac4db97 stage2: implement error notes and regress -femit-zir
* Implement error notes
   - note: other symbol exported here
   - note: previous else prong is here
   - note: previous '_' prong is here
 * Add Compilation.CObject.ErrorMsg. This object properly converts to
   AllErrors.Message when the time comes.
 * Add Compilation.CObject.failure_retryable. Properly handles
   out-of-memory and other transient failures.
 * Introduce Module.SrcLoc which has not only a byte offset but also
   references the file which the byte offset applies to.
 * Scope.Block now contains both a pointer to the "owner" Decl and the
   "source" Decl. As an example, during inline function call, the
   "owner" will be the Decl of the caller and the "source" will be the
   Decl of the callee.
 * Module.ErrorMsg now sports a `file_scope` field so that notes can
   refer to source locations in a file other than the parent error
   message.
 * Some instances where a `*Scope` was stored, now store a
   `*Scope.Container`.
 * Some methods in the `Scope` namespace were moved to the more specific
   type, since there was only an implementation for one particular tag.
   - `removeDecl` moved to `Scope.Container`
   - `destroy` moved to `Scope.File`
 * Two kinds of Scope deleted:
   - zir_module
   - decl
 * astgen: properly use DeclVal / DeclRef. DeclVal was incorrectly
   changed to be a reference; this commit fixes it. Fewer ZIR
   instructions processed as a result.
   - declval_in_module is renamed to declval
   - previous declval ZIR instruction is deleted; it was only for .zir
     files.
 * Test harness: friendlier diagnostics when an unexpected set of errors
   is encountered.
 * zir_sema: fix analyzeInstBlockFlat by properly calling resolvingInst
   on the last zir instruction in the block.

Compile log implementation:
 * Write to a buffer rather than directly to stderr.
 * Only keep track of 1 callsite per Decl.
 * No longer mutate the ZIR Inst struct data.
 * "Compile log statement found" errors are only emitted when there are
   no other compile errors.

-femit-zir and support for .zir source files is regressed. If we wanted
to support this again, outputting .zir would need to be done as yet
another backend rather than in the haphazard way it was previously
implemented.

For parsing .zir, it was implemented previously in a way that was not
helpful for debugging. We need tighter integration with the test harness
for it to be useful; so clearly a rewrite is needed. Given that a
rewrite is needed, and it was getting in the way of progress and
organization of the rest of stage2, I regressed the feature.
2021-01-16 22:51:01 -07:00
Luuk de Gram
6c19aeddca
Add tests and move tests to wasm's own file 2021-01-16 14:58:04 +01:00
Jakub Konka
b204ea0349 macho: ensure that strtab always follows symtab
In rare occassions, it may happen that string table is allocated free
space preceeding symbol table. This is an error in the eyes of the `dyld`
dynamic loader and thus has to forbidden by the linker.
2021-01-15 23:22:28 +01:00
Evan Haas
1702b413f7 translate-c: ensure bools are cast to int when necessary
Fixes two scenarios where @boolToInt() calls were missing:

1. Boolean expression cast to different-size int (char, long, etc)
2. Boolean expression used as parameter for function with int argument
2021-01-15 12:35:54 -08:00
Jakub Konka
4ffa8952cc macho: add x86_64 tests 2021-01-13 23:55:56 +01:00
Jakub Konka
7d40aaad2b macho: document more code + add test case 2021-01-13 23:55:18 +01:00
Andrew Kelley
025f1559a0
Merge pull request #7200 from Vexu/arr
Type coercion for pointers to anon literals
2021-01-11 16:09:28 -08:00
Timon Kruiper
e1d8073d2f stage2: add support for loops in LLVM backend
A simple `while(true) {}` loop generates the following LLVMIR:
```
define i32 @main() {
Entry:
  br label %Loop

Loop:                                 ; preds = %Loop, %Entry
  br label %Loop
}
```

Also implement TZIR printing for loops and add a corresponding test.
2021-01-10 17:47:34 -08:00
Andrew Kelley
5c49a137d5
Merge pull request #7725 from FireFox317/even-more-llvm
stage2: initial implementation of control flow in LLVM backend + TZIR printing
2021-01-09 12:32:10 -08:00
Timon Kruiper
56c059077c stage2: add initial impl of control flow in LLVM backend
The following TZIR instrutions have been implemented in the backend:
- all cmp operators (lt, lte, gt, gte, eq, neq)
- block
- br
- condbr

The following LLVMIR is generated for a simple assert function:
```
define void @assert(i1 %0) {
Entry:
  %1 = alloca i1, align 1
  store i1 %0, i1* %1, align 1
  %2 = load i1, i1* %1, align 1
  %3 = xor i1 %2, true
  br i1 %3, label %Then, label %Else

Then:                                             ; preds = %Entry
  call void @llvm.debugtrap()
  unreachable

Else:                                             ; preds = %Entry
  br label %Block

Block:                                            ; preds = %Else
  ret void
}
```

See tests for more examples.
2021-01-08 19:30:52 +01:00
Jay Petacat
a9b505fa77 Reduce use of deprecated IO types
Related: #4917
2021-01-07 23:48:58 -08:00
Andrew Kelley
76870a2265
Merge pull request #7700 from FireFox317/more-stage2-stuff-llvm
stage2: improvements to LLVM backend
2021-01-06 16:06:32 -08:00
Andrew Kelley
efe94a9a12 stage2: C backend: support unused Decls 2021-01-06 16:47:09 -07:00
Timon Kruiper
b1cfa923be stage2: rename and move files related to LLVM backend 2021-01-06 10:52:20 +01:00
Timon Kruiper
70f6d16ae2 stage2: add initial impl for generating global decls in LLVM backend
Also adds support for extern functions, simple pointer and simple array
types and values.

A simple hello world now compiles:
`zig build-exe example.zig -fLLVM -lc`
```
extern fn puts(s: [*:0]const u8) c_int;
export fn main() c_int {
    _ = puts("hello world!");
    return 0;
}
```
2021-01-06 10:52:07 +01:00
g-w1
ab5f7b5156 stage2: add compile log statement 2021-01-05 18:43:41 -07:00
Andrew Kelley
1a2dd85570 stage2: C backend: re-implement emit-h
and also mark functions as `extern "C"` as appropriate to support c++
compilers.
2021-01-05 17:41:14 -07:00
Andrew Kelley
cd95444e47 stage2: C backend: remove format() hackery
All C backend tests passing now, except for emit-h tests. Next task in
the branch is to restore emit-h.
2021-01-05 17:41:14 -07:00
Andrew Kelley
7b8cede61f stage2: rework the C backend
* std.ArrayList gains `moveToUnmanaged` and dead code
   `ArrayListUnmanaged.appendWrite` is deleted.
 * emit_h state is attached to Module rather than Compilation.
 * remove the implementation of emit-h because it did not properly
   integrate with incremental compilation. I will re-implement it
   in a follow-up commit.
 * Compilation: use the .codegen_failure tag rather than
   .dependency_failure tag for when `bin_file.updateDecl` fails.

C backend:
 * Use a CValue tagged union instead of strings for C values.
 * Cleanly separate state into Object and DeclGen:
   - Object is present only when generating a .c file
   - DeclGen is present for both generating a .c and .h
 * Move some functions into their respective Object/DeclGen namespace.
 * Forward decls are managed by the incremental compilation frontend; C
   backend no longer renders function signatures based on callsites.
   For simplicity, all functions always get forward decls.
 * Constants are managed by the incremental compilation frontend. C
   backend no longer has a "constants" section.
 * Participate in incremental compilation. Each Decl gets an ArrayList
   for its generated C code and it is updated when the Decl is updated.
   During flush(), all these are joined together in the output file.
 * The new CValue tagged union is used to clean up using of assigning to
   locals without an additional pointer local.
 * Fix bug with bitcast of non-pointers making the memcpy destination
   immutable.
2021-01-05 17:41:14 -07:00
Noam Preil
9360e5887c integrate CBE with Compilation.update pipeline (closes #7589)
* CBE buffers are only valid during a flush()
* the file is reopened and truncated during each flush()
* CBE now explicitly ignores updateDecl and deleteDecl
* CBE updateDecl is gone
* test case is enabled
2021-01-05 17:41:14 -07:00