In strictly conforming C, identifiers cannot container dollar signs.
However GCC and Clang allow them by default, so translate-c should
handle them. See http://gcc.gnu.org/onlinedocs/cpp/Tokenization.html
I encountered this in the wild in windows.h
Fixes#7585
`@setEvalBranchQuota` can be called before the comptime/inline call
stack is created.
For example:
```zig
@setEvalBranchQuota(100);
comptime {
while (true) {}
}
```
Here we need to set the branch_quota before the comptime block creates a
scope for the branch_count.
If a static function is defined with no argument list and no prototype
is given, it should be treated as a function that takes no arguments
rather than as a variadic function.
Fixes#7594
To make sure that we don't have to rebuild libc for every case, we now
have a seperate cache directory for the global cache, which remains
the same between test runs.
Also make sure to destory the Compilation before executing a child process,
otherwise the compiler deadlocks. (#7596)
zir.Inst no longer has an `analyzed_inst` field. This is previously how
we mapped ZIR to their TZIR counterparts, however with the way inline
and comptime function calls work, we can potentially have the same ZIR
structure being analyzed by multiple different analyses, such as during
a recursive inline function call. This would cause the `analyzed_inst`
field to become clobbered. So instead, we use a table to map the
instructions to their semantically analyzed counterparts. This will help
with multi-threaded compilation as well.
Scope.Block.Inlining is split into 2 different layers of "sharedness".
The first layer is shared by the whole inline/comptime function call
stack. It contains the callsite where something is being inlined and the
branch count/quota. The second layer is different per function call but
shared by all the blocks within the function being inlined.
Add support for debug dumping br and brvoid TZIR instructions.
Remove the "unreachable code" error. It was happening even for this case:
```zig
if (comptime_condition) return;
bar(); // error: unreachable code
```
We will need smarter logic for when it is legal to emit this compile
error.
Remove the ZIR test cases. These are redundant with other higher level
Zig source tests we have, and maintaining support for ZIRModule as a
first-class top level abstraction is getting in the way of clean
compiler design for the main use case. We will have ZIR/TZIR based test
cases someday to help with testing optimization passes and ZIR to TZIR
analysis, but as is, these test cases are not accomplishing that, and
they are getting in the way.
* scopes properly inherit inlining information
* compile errors of inline function calls are properly attached to the
caller rather than the callee.
- added a test case for this
* --watch still opens a repl if compile errors happen.
Instead of freeing ZIR after semantic analysis, we keep it around so
that it can be used for comptime calls, inline calls, and generic
function calls. ZIR memory is now managed by the Decl arena.
Debug dump() functions are conditionally compiled; only available in
Debug builds of the compiler.
Add a test for an inline function call.
* remove the -Ddump-zir thing. that's handled through --verbose-ir
* rework Fn to have an is_inline flag without requiring any more memory
on the heap per function.
* implement a rough first version of dumping typed zir (tzir) which is
a lot more helpful for debugging than what we had before. We don't
have a way to parse it though.
* keep track of whether the inline-ness of a function changes because
if it does we have to go update callsites.
* add compile error for inline and export used together.
inline function calls and comptime function calls are implemented the
same way. A block instruction is set up to capture the result, and then
a scope is set up that has a flag for is_comptime and some state if the
scope is being inlined.
when analyzing `ret` instructions, zig looks for inlining state in the
scope, and if found, treats `ret` as a `break` instruction instead, with
the target block being the one set up at the inline callsite.
Follow-up items:
* Complete out the debug TZIR dumping code.
* Don't redundantly generate ZIR for each inline/comptime function
call. Instead we should add a new state enum tag to Fn.
* comptime and inlining branch quotas.
* Add more test cases.
* 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?
This patch introduces the following new things:
Types:
- inferred_alloc
- This is a special value that tracks a set of types that have been stored
to an inferred allocation. It does not support most of the normal type queries.
However it does respond to `isConstPtr`, `ptrSize`, `zigTypeTag`, etc.
- The payload for this type simply points to the corresponding Value
payload.
Values:
- inferred_alloc
- This is a special value that tracks a set of types that have been stored
to an inferred allocation. It does not support any of the normal value queries.
ZIR instructions:
- store_to_inferred_ptr,
- Same as `store` but the type of the value being stored will be used to infer
the pointer type.
- resolve_inferred_alloc
- Each `store_to_inferred_ptr` puts the type of the stored value into a set,
and then `resolve_inferred_alloc` triggers peer type resolution on the set.
The operand is a `alloc_inferred` or `alloc_inferred_mut` instruction, which
is the allocation that needs to have its type inferred.
Changes to the C backend:
* Implements the bitcast instruction. If the source and dest types
are both pointers, uses a cast, otherwise uses memcpy.
* Tests are run with -Wno-declaration-after-statement. Someday we can
conform to this but not today.
In ZIR form it looks like this:
```zir
fn_body main { // unanalyzed
%0 = dbg_stmt()
=>%1 = alloc_inferred()
%2 = declval_in_module(Decl(add))
%3 = deref(%2)
%4 = param_type(%3, 0)
%5 = const(TypedValue{ .ty = comptime_int, .val = 1})
%6 = as(%4, %5)
%7 = param_type(%3, 1)
%8 = const(TypedValue{ .ty = comptime_int, .val = 2})
%9 = as(%7, %8)
%10 = call(%3, [%6, %9], modifier=auto)
=>%11 = store_to_inferred_ptr(%1, %10)
=>%12 = resolve_inferred_alloc(%1)
%13 = dbg_stmt()
%14 = ret_type()
%15 = const(TypedValue{ .ty = comptime_int, .val = 3})
%16 = sub(%10, %15)
%17 = as(%14, %16)
%18 = return(%17)
} // fn_body main
```
I have not played around with very many test cases yet. Some interesting
ones that I want to look at before merging:
```zig
var x = blk: {
var y = foo();
y.a = 1;
break :blk y;
};
```
In the above test case, x and y are supposed to alias.
```zig
var x = if (bar()) blk: {
var y = foo();
y.a = 1;
break :blk y;
} else blk: {
var z = baz();
z.b = 1;
break :blk z;
};
```
In the above test case, x, y, and z are supposed to alias.
I also haven't tested with `var` instead of `const` yet.
* Module: improve doc comments
* C backend: improve const-correctness
* C backend: introduce renderTypeAndName
* C backend: put `static` on functions when appropriate
* C backend: fix not handling errors in genBinOp
* C backend: handle more IR instructions
- alloc, store, boolean comparisons, ret_ptr
* C backend: call instruction properly stores its result
* test harness: ensure execution tests have empty stderr
The addition of `addDeclErr` introduced a memory leak at every call
site, and I also would like to push back on having more than 1
compilation error per `Decl`.
This reverts commit 1634d45f1d53c8d7bfefa56ab4d2fa4cc8218b6d.
Previously casting a bool to an int would result in the following Zig code:
@intCast(c_int, @bitCast(i1, @intCast(u1, @boolToInt(b))));
This is incorrect if `b` is true, since bitcasting a `u1` with the value 1
to an `i1` will result in the value -1. Instead, generate the following code:
@as(c_int, @boolToInt(b));
Since @boolToInt returns a `u1`, this is only disallowed if the destination
type is one-bit and signed, which can only happen if it's a bitfield
(currently not supported by translate-c)
Making the enum type share the scope with the parent union means every
declaration "bleeds" into the enum scope.
Let's mint a fresh empty scope for the enum type.
Thanks to @Vexu for the test case.
Closes#7532
* stage2: add @TypeOf
* stage2: discriminate on what type of @builtinCall in nodeMayNeedMemoryLocation
* merge upstream into my stash
* add type equality to make easier to test and defer free the types
* remove addDeclErr, I dont know why I added it, its from a different branch that im working on
* add tests
* update error message to match stage1
* use ComptimeStringMap and update which nodes don't need memory from vexu's suggestions
* fix typo
Co-authored-by: Veikka Tuominen <git@vexu.eu>
* make @TypeOf(single_arg) go to .typeof zir inst and add test for that
* unioninit, as, reduce change mayneedmemorylocation
Co-authored-by: Veikka Tuominen <git@vexu.eu>
C compiler intrinsics can only appear as part of a function call. When called
they are implicitly cast to a function pointer; treat this as a non-null
pointer so that it emits as a regular Zig function call.
Put `pub usingnamespace @import("std").c.builtins;` at the top of translated
C files so that they will have access to builtin functions defined there.
Fixes#6707