40 Commits

Author SHA1 Message Date
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
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
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
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
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
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
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
Evan Haas
d95724454c Allow dollar sign $ in identifiers in translate-c
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
2021-01-04 14:14:04 -08:00
Evan Haas
5cc131030c Static function declarations with no prototype should not be variadic
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
2021-01-03 15:08:32 -08:00
Evan Haas
830bc41b1f Correctly cast bool to signed int in translate-c
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)
2020-12-25 14:38:31 +02:00
Evan Haas
ccdb81fb31 Improve handling of C compiler intrinsics in translate-c
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
2020-12-22 23:59:30 +02:00
Veikka Tuominen
d3a57b96a9 translate-c: detect parenthesized string literals 2020-12-16 12:13:23 +02:00
Evan Haas
55cac65f95 Support casting enums to all int types.
In C, enums are represented as signed integers, so casting from an enum to an integer
should use the "cast integer to integer" translation code path. Previously it used the
"cast enum to generic non-enum" code path, because enums were not being treated as integers.
Ultimately this can produce zig code that fails to compile if the destination type does not
support the full range of enum values (e.g. translated C code that casts an enum value to an
unsigned integer would fail to compile since enums are signed integers, and unsigned integers
cannot represent the full range of values that signed ones can).

One interesting thing that came up during testing is that the implicit enum-to-int cast that
occurs when an enum is used in a boolean expression was parsed as an (int) by some versions of
the zig compiler, and an (unsigned int) cast by others. Specifically, the following code:

```c
	enum Foo {Bar, Baz};
	// ...
	enum Foo foo = Bar;
	if (0 || foo) {
		// do something
	}
```

When tested on MacOS, Linux, and Windows using a compiler built from the Windows Zig Compiler
Dev Kit, the above code would emit a cast to c_uint:

`if (false or (@bitCast(c_uint, @enumToInt(foo)) != 0)) {}`

However when tested on Windows with a Zig compiler built using MSVC, it produces:

`if (false or (@bitCast(c_int, @enumToInt(foo)) != 0)) {}`

In this particular case I don't think it matters, since a c_int and c_uint will have the same
representation for zero, but I'm not sure if this is ultimately the result of
implementation-defined behavior or something else.

Because of this, I added explicit casts in the `translate_c.zig` tests, to ensure that the
emitted zig source exactly matches across platforms. I also added a behavior test in
`run_translated_c.zig` that uses the old implicit casts from `translate_c.zig` to ensure
that the emitted Zig code behaves the same as the C code regardless of what cast is used.
2020-12-10 15:47:56 -05:00
Tadeo Kondrak
82273f1a2a translate_c: fix shadowing on nested blocks 2020-08-31 20:29:57 +03:00
Vexu
a553947a51
translate-c: correctly put static and extern local variables in global scope 2020-08-20 10:45:55 +03:00
Vexu
13e472aa2a
translate-c: add return if one is needed 2020-08-13 18:40:14 +03:00
Ian Simonson
70cc1751ca Translate-c fix rhs not cast on array access
Closes #5671. Checks if the rhs is integral and of
differing or the same signedness. If they are different
does an @intCast to the lhs type
2020-07-02 14:05:12 +00:00
Vexu
cd5b7b9e1d
translate-c: use correct scope in for loop condition 2020-05-27 14:14:17 +03:00
Vexu
c0b269bf46
translate-c: small patch to fix bultin type detection 2020-05-06 11:48:46 +03:00
Matthew Knight
db4833d4d6 moved duplicated code to common functions 2020-05-04 23:45:31 -07:00
Matthew Knight
c5198bd76f added scoped typedef to translate-c 2020-05-02 20:22:43 -07:00
Ian Simonson
e6fa0beb33 Translate-C convert bools to int in complex expressions
Pre-requisite for having a test case for #5062
In complex C statements which are outside of macros,
it is valid C to perform e.g. a bitor between an
integer and a boolean `5 | (8 == 9)`

Currently this results in a zig error after translating
as `c_int | bool` is invalid Zig.

Detects if a sub-expression of a numeric operator is
boolean and if so converts it to int
2020-04-30 12:48:27 +10:00
Andrew Kelley
9e60c89601
Revert "Translate C: Group generated casts"
This reverts commit 895672b3f96aab1f5bad3446f5186a047f29412c.
2020-03-08 03:53:06 -04:00
Lachlan Easton
895672b3f9 Translate C: Group generated casts
Translate C: Put an alignCast in c style pointer casts to allow opaque types to cast properly in C macros

Translate C: add test case for aligning opaque types in pointer casts

Translate C: Fix @typeId -> @typeInfo

Add test case to run_translated_c for casting from pointer to opaque type
2020-03-07 03:26:42 -05:00
LemonBoy
c944865fc7 Generate compilable code for array inits
The compiler still doesn't like too much the newfangled anonymous arrays
so let's use the old-style declarations.

Closes #4181
2020-01-30 19:45:08 +01:00
LemonBoy
570ffc470e Handle forward-declared functions
Closes #4130
2020-01-10 16:34:40 -05:00
travisstaloch
3f98756f85 Fix translation of signed array indices (#4113)
* cast only if the index is long long or signed
* cast long long to usize rather than c_uint

closes #4075
2020-01-10 00:08:24 -05:00
Rocknest
4613e4d15f Fix C struct with function pointer member and typedefs mistranslated (#4122)
fixes #4118
2020-01-09 13:38:31 -05:00
LemonBoy
6a72eb1541 Use abort() instead of assert()
Let's see if the Windows/MacOS CI like this more...
2020-01-08 10:31:11 +01:00
LemonBoy
5b34697b21 Cast integer literals to their specified type 2020-01-08 10:19:04 +01:00
LemonBoy
fd7e69a2c0 More translate-c fixes
* Translate OpaqueValueExpr
* Translate BinaryConditionalOperator
* Fix translation of boolean->int casts
* Reoder some tokens to avoid rendering errors
2020-01-08 08:43:37 +01:00
via
9390e8b848 Preserve packed attribute in C translated struct (#4085)
* Preserve packed attribute in C translated struct

* Add tests for packed C struct
2020-01-07 02:36:07 -05:00
LemonBoy
7e7d0e1ffa
Better handling of decayed arrays to pointers 2020-01-06 19:32:53 -05:00
Andrew Kelley
baaef7ed97
Merge pull request #4083 from LemonBoy/better-stdbool
Better _Bool translation
2020-01-06 19:21:55 -05:00
LemonBoy
62413da9d3
Add run-translated-c test & fix one more edge case 2020-01-06 19:17:47 -05:00
Tadeo Kondrak
f83b02a581 translate-c: use @intToPtr to cast away qualifiers 2020-01-06 19:09:49 -05:00
LemonBoy
eca294cd23 Add run-translated-c test 2020-01-06 00:18:26 +01:00
Andrew Kelley
14fcfe2981
translate-c supports --cache on
this will be used to provide a zig build step
2020-01-03 22:11:19 -05:00
Andrew Kelley
695c8f756b
add test harness for "run translated C" tests 2020-01-03 00:26:12 -05:00