Notably, Value.eql and Value.hash are improved to treat NaN as equal to
itself, so that Type/Value can be hash map keys. Likewise float hashing
normalizes the float value before computing the hash.
* Sema: fix `zirTypeInfo` allocating with the wrong arenas for some
stuff.
* LLVM: split `airDbgInline` into two functions, one for each AIR tag.
- remove the redundant copy to type_map_arena. This is the first
thing that lowerDebugType does so this hack was probably just
accidentally avoiding UB (which is still present prior to this
commit).
- don't store an inline fn inst into the di_map for the generic
decl.
- use a dummy function type for the debug info to avoid whatever UB
is happening.
- we are now ignoring the function type passed in with the
dbg_inline_begin and dbg_inline_end.
* behavior tests: prepare the vector tests to be enabled one at a time.
Mitigates #11199.
Adds the sentinel element to the type name to avoid ambiguous
declarations, and outputs the sentinel element (if needed) even in what
would otherwise be empty arrays.
This involved some significant reworking in order to introduce the
concept of "forward declarations" to the system to break dependency
loops.
The `lowerDebugType` function now takes an `enum { full, fwd }` and is moved
from `DeclGen` to `Object` so that it can be called from `flushModule`.
`DITypeMap` is now an `ArrayHashMap` instead of a `HashMap` so that we can
iterate over the entries in `flushModule` and finalize the forward decl
DITypes into full DITypes.
`DITypeMap` now stores `AnnotatedDITypePtr` values instead of
`*DIType` values. This is an abstraction around a `usize` which assumes
the pointers will be at least 2 bytes aligned and uses the least
significant bit to store whether it is forward decl or a fully resolved
debug info type.
`lowerDebugTypeImpl` is extracted out from `lowerDebugType` and it has a
mechanism for completing a forward decl DIType to a fully resolved one.
The function now contains lowering for struct types. Closes#11095.
There is a workaround for struct types which have not had
`resolveFieldTypes` called in Sema, even by the time `flushModule` is
called. This is a deficiency of Sema that should be addressed, and the
workaround removed. I think Sema needs a new mechanism to queue up type
resolution work instead of doing it in-line, so that it does not cause
false dependency loops. We already have one failing behavior test
because of a false dependency loop.
This resolves https://github.com/ziglang/zig/issues/11159
The problem was that:
1. We were not correctly deleting the field stores after recognizing
that an array initializer was a comptime-known value.
2. LLVM was not checking that the final type had no runtime bits, and
so would generate an invalid store.
This also adds several test cases for related bugs, just to check these
in for later work.
* don't store `has_well_defined_layout` in memory.
* remove struct `hasWellDefinedLayout` logic. it's just
`layout != .Auto`. This means we only need one implementation, in
Type.
* fix some of the cases being wrong in `hasWellDefinedLayout`, such as
optional pointers.
* move `tag_ty_inferred` field into a position that makes it more
obvious how the struct layout will be done. Also we don't have a
compiler that intelligently moves fields around so this layout is
better.
* Sema: don't `resolveTypeLayout` in `zirCoerceResultPtr` unless
necessary.
* Rename `ComptimePtrLoadKit` `target` field to `pointee` to avoid
confusion with `target`.
We need to make sure that we bitcast our pointers correctly before
we use get_element_ptr to compute the offset for the parent
pointer.
This also includes a small fix-up for a problem where ptrs to const
i64/u64 were not using the correct type in >1-level decl chains
(where we call lowerParentPtr recursively)
LLVM backend: generate DIGlobalVariable's for non-function globals and
rename linkage names when exporting functions and globals.
zig_llvm.cpp: add some wrappers to convert a handful of DI classes
into DINode's since DIGlobalVariable is not a DIScope like the others.
zig_llvm.cpp: add some wrappers to allow replacing the LinkageName of
DISubprogram and DIGlobalVariable.
zig_llvm.cpp: fix DI class mixup causing nonsense reinterpret_cast.
The end result is that GDB is now usable since you now no longer need
to manually cast every global nor fully qualify every export.
It is possible for the value length to be longer than the type because
we allow in-memory coercing of types such as `[5:0]u8` to `[5]u8`. In
such a case, the value length is 6 but the type length if 5.
The `.repeated` value type already got this right, so this is extending
similar logic out to `.aggregate` and `.bytes`. Both scenarios are
tested in behavior tests.
Fixes#11165
This also surfaces the fact that clz, ctz and popCount didn't actually
support 128 bit integers, despite what was claimed by
226fcd7c709ec664c5d883042cf7beb3026f66cb. This was partially hidden by
the fact that the test code for popCount only exercised 128 bit integers
in a comptime context. This commit duplicates that test case for runtime
ints too.
This parameter is only currently needed by zig_byte_swap() and
zig_bit_reverse(). This commit adds an option to airBuiltinCall() to
allow emitting the signedness information only when needed, removing
this unused parameter from the other builtins.
This should cover not only integers, as done in
87744a7ea9a2449764a110da4210d7750e3938ee, but also void, enums with a
single field, etc...
Co-authored-by: Andrew Kelley <andrew@ziglang.org>
This folds the airCountZeroes() code from
226fcd7c709ec664c5d883042cf7beb3026f66cb back into airBuiltinCall(),
since most of these builtins happen to require the same arguments and
can be unified under a common function signature.
This was already done for void types, and needs to be done for 0 bit
integer types as well to align the rendered function signatures with the
effective size of extra.data.args_len as seen by airCall().
Adds 2 new AIR instructions:
* dbg_var_ptr
* dbg_var_val
Sema no longer emits dbg_stmt AIR instructions when strip=true.
LLVM backend: fixed lowerPtrToVoid when calling ptrAlignment on
the element type is problematic.
LLVM backend: fixed alloca instructions improperly getting debug
location annotated, causing chaotic debug info behavior.
zig_llvm.cpp: fixed incorrect bindings for a function that should use
unsigned integers for line and column.
A bunch of C test cases regressed because the new dbg_var AIR
instructions caused their operands to be alive, exposing latent bugs.
Mostly it's just a problem that the C backend lowers mutable
and const slices to the same C type, so we need to represent that in the
C backend instead of printing two duplicate typedefs.
* use the real start code for LLVM backend with x86_64-linux
- there is still a check for zig_backend after initializing the TLS
area to skip some stuff.
* introduce new AIR instructions and implement them for the LLVM
backend. They are the same as `call` except with a modifier.
- call_always_tail
- call_never_tail
- call_never_inline
* LLVM backend calls hasRuntimeBitsIgnoringComptime in more places to
avoid unnecessarily depending on comptimeOnly being resolved for some
types.
* LLVM backend: remove duplicate code for setting linkage and value
name. The canonical place for this is in `updateDeclExports`.
* LLVM backend: do some assembly template massaging to make `%%`
rendered as `%`. More hacks will be needed to make inline assembly
catch up with stage1.
This required adjusting `Type.nameAlloc` to be used with a
general-purpose allocator and added `Type.nameAllocArena` for the arena
use case (avoids allocation sometimes).
Previously, we did this so that we could insert a debug variable
declaration intrinsic on the alloca. But there is a dbg.value intrinsic
for declaring variables that are values.
* mul_add AIR instruction: use `pl_op` instead of `ty_pl`. The type is
always the same as the operand; no need to waste bytes redundantly
storing the type.
* AstGen: use coerced_ty for all the operands except for one which we
use to communicate the type.
* Sema: use the correct source location for requireRuntimeBlock in
handling of `@mulAdd`.
* native backends: handle liveness even for the functions that are
TODO.
* C backend: implement `@mulAdd`. It lowers to libc calls.
* LLVM backend: make `@mulAdd` handle all float types.
- improved fptrunc and fpext to handle f80 with compiler-rt calls.
* Value.mulAdd: handle all float types and use the `@mulAdd` builtin.
* behavior tests: revert the changes to testing `@mulAdd`. These
changes broke the test coverage, making it only tested at
compile-time.
Improved f80 support:
* std.math.fma handles f80
* move fma functions from freestanding libc to compiler-rt
- add __fmax and fmal
- make __fmax and fmaq only exported when they don't alias fmal.
- make their linkage weak just like the rest of compiler-rt symbols.
* removed `longDoubleIsF128` and replaced it with `longDoubleIs` which
takes a type as a parameter. The implementation is now more accurate
and handles more targets. Similarly, in stage2 the function
CTypes.sizeInBits is more accurate for long double for more targets.