This patch adds support for passing CFLAGS added in #cgo lines of the
CGo preprocessing phase to the compiler when compiling C files inside
packages. This is expected and convenient but didn't work before.
This doesn't yet add support for actually making use of variadic
functions, but at least allows (unintended) variadic functions like the
following to work:
void foo();
The main change is in building the libraries, where -fshort-enums was
passed on RISC-V while other C files weren't compiled with this setting.
Note: the test already passed before this change, but it seems like a
good idea to explicitly test for enum size consistency.
There is also not a particular reason not to pass -fshort-enums on
RISC-V. Perhaps it's better to do it there too (on baremetal targets
that don't have to worry about binary compatibility).
This is necessary for better CGo support on bare metal. Existing
libraries expect to be able to include parts of libc and expect to be
able to link to those symbols.
Because with this all targets have a working libc, it is now possible to
add tests to check that a libc in fact works basically.
Not all parts of picolibc are included, such as the math or stdio parts.
These should be added later, when needed.
This commit also avoids the need for the custom memcpy/memset/memcmp
symbols that are sometimes emitted by LLVM. The C library will take care
of that.
Instead of putting the magic in the AST, generate regular accessor
methods. This avoids a number of special cases in the compiler, and
avoids missing any of them.
The resulting union accesses are somewhat clunkier to use, but the
compiler implementation has far less coupling between the CGo
implementation and the IR generator.
Enum types are implemented as named types (with possible accompanying
typedefs as type aliases). The constants inside the enums are treated as
Go constants like in the Go toolchain.
This is a big commit that does a few things:
* It moves CGo processing into a separate package. It never really
belonged in the loader package, and certainly not now that the
loader package may be refactored into a driver package.
* It adds support for multiple CGo files (files that import package
"C") in a single package. Previously, this led to multiple
definition errors in the Go typecheck phase because certain C
symbols were defined multiple times in all the files. Now it
generates a new fake AST that defines these, to avoid multiple
definition errors.
* It improves debug info in a few edge cases that are probably not
relevant outside of bugs in cgo itself.
Only try to convert the C symbols to their Go equivalents that are
actually referenced by the Go code with C.<somesymbol>. This avoids
having to support all possible C types, which is difficult because of
oddities like `typedef void` or `__builtin_va_list`. Especially
__builtin_va_list, which varies between targets.
These types (called elaborated types in C) are used as part of linked
lists, among others.
This is part an extra feature (to be compatible with CGo C.struct_
types) and part a bugfix: linked lists would result in endless recursion
leading to a stack overflow.
Unions are somewhat hard to implement in Go because they are not a
native type. But it is actually possible with some compiler magic.
This commit inserts a special "C union" field at the start of a struct
to indicate that it is a union. As such a field cannot be written
directly in Go, this is a useful to distinguish structs and unions.