Previously, stage2 used a global decl_table for all Decl objects, keyed
by a 16-byte name hash that was hopefully unique. Now, there is a tree
of Namespace objects that own their named Decl objects.
Conflicts:
* build.zig
* src/Compilation.zig
* src/codegen/spirv/spec.zig
* src/link/SpirV.zig
* test/stage2/darwin.zig
- this one might be problematic; start.zig looks for `main` in the
root source file, not `_main`. Not sure why there is an underscore
there in master branch.
* `-lc++` now implies `-lc`.
* `-lunwind` is now pulled out into a separate `link_libunwind` flag in
the frontend driver code. This allows a project to request zig to
provide libunwind even if the default situation that causes it to be
implicitly added, is not active.
* build.zig: ask for -lunwind when building the self-hosted compiler on
Linux. Otherwise we get linker errors with unresolved symbols to
libunwind.
Conflicts:
* lib/std/os/linux.zig
* lib/std/os/windows/bits.zig
* src/Module.zig
* src/Sema.zig
* test/stage2/test.zig
Mainly I wanted Jakub's new macOS code for respecting stack size, since
we now depend on it for debug builds able to pass one of the test cases
for recursive comptime function calls with `@setEvalBranchQuota`.
The conflicts were all trivial.
The CPU detection code is nearly at feature parity, we do support
detecting the native CPU on Sparc systems and macos, our ARM/AArch64
model list is quite comprehensive and so is our PPC one.
The only missing pieces are:
- ARM32 detection on Darwin hosts (I don't think anybody is planning on
running the compiler on a old-ass iPhone)
- s390x detection on Linux hosts, this can be easily added at a later
stage.
* File stores `root_decl: Decl` instead of `namespace: *Namespace`.
This maps more cleanly to the actual ownership, since the `File` does
own the root decl, but it does not directly own the `Namespace`.
* `semaFile` completes the creation of the `Decl` even when semantic
analysis fails. The `analysis` field of the `Decl` will contain the
results of semantic analysis. This prevents cleaning up of memory
still referenced by other Decl objects.
* `semaDecl` sets `Struct.zir_index` of the root struct decl, which
fixes use of undefined value in case the first update contained a ZIR
compile error.
Some of the reworkings in this branch put us over the limit, on Linux,
where the kernel disregards the fact that we ask for 16 MiB in the ELF
file. So we ask for more stack space in `main`.
* 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.
AstGen is now completely independent from the rest of the compiler. It
ingests an AST tree and produces ZIR code as the output, without
depending on any of the glue code of the compiler.
Conflicts:
lib/std/crypto/25519/field.zig
lib/std/crypto/poly1305.zig
I had resolved those by removing `comptime` but master branch decided to
make the parameters `comptime`.
This also pulls in the updated default `zig build` install directory.
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`.
* 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.
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
* free Module.Fn ZIR code when destroying the owner Decl
* unreachable_safe and unreachable_unsafe are collapsed into one ZIR
instruction with a safety flag.
* astgen: emit an unreachable instruction for unreachable literals
* don't forget to call deinit on ZIR code
* astgen: implement some builtin functions
Now reading a source file and decoding it from UTF-16LE to UTF-8 is
done in a single function. Error messages are improved, and an error is
emitted when the source file has a BOM not supported (UTF-16BE, UTF-32).
Please note that the BOM of UTF-32 is composed of the same bytes as the
BOM of UTF-16 followed by a null character. Therefore a source file in
UTF-16LE starting with a null byte will be interpreted as an UTF-32, and
rejeted because of an invalid format. In pratice this is not a problem,
as the code would have been rejected later anyway because of the null
character.
Fixes#2820
After reading the source code, the first two bytes are inspected, and
if they correspond to a UTF-16 BOM in little-endian order, the source
code is converted to UTF-8.
A warning is emitted when using the debug option --debug-log when the compiler
was not compiled using the build option -Dlog. Additionnaly, the scopes are not
added to log_scopes as they have no effect.
Clang docs say:
> Like -MMD, but also implies -E and writes to stdout by default.
Previously, Zig handled this option by forwarding it directly to Clang,
and disabling depfiles. However this did not adhere to Clang's documented
behavior of these flags.
Now, in addition to being forwarded directly to Clang, `-MM` also
sets c_out_mode = .preprocessor, just like `-E`.
Another issue I noticed is that Zig did not recognize the aliases for
-MG, -MM, or -MMD. The aliases are now recognized.
The presence of ZIG_VERBOSE_LINK now enables --verbose-link.
The presence of ZIG_VERBOSE_CC now enables --verbose-cc.
These are useful when debugging usage of `zig cc` which does not have
CLI flags for these options, since they are not valid C compiler flags.