mirror of
https://github.com/ziglang/zig.git
synced 2024-11-14 16:13:24 +00:00
Merge remote-tracking branch 'origin/master' into llvm12
This commit is contained in:
commit
a4316d5505
@ -87,10 +87,15 @@ option(ZIG_TEST_COVERAGE "Build Zig with test coverage instrumentation" OFF)
|
||||
set(ZIG_TARGET_TRIPLE "native" CACHE STRING "arch-os-abi to output binaries for")
|
||||
set(ZIG_TARGET_MCPU "baseline" CACHE STRING "-mcpu parameter to output binaries for")
|
||||
set(ZIG_EXECUTABLE "" CACHE STRING "(when cross compiling) path to already-built zig binary")
|
||||
set(ZIG_PREFER_LLVM_CONFIG off CACHE BOOL "(when cross compiling) use llvm-config to find target llvm dependencies if needed")
|
||||
set(ZIG_SINGLE_THREADED off CACHE BOOL "limit the zig compiler to use only 1 thread")
|
||||
set(ZIG_OMIT_STAGE2 off CACHE BOOL "omit the stage2 backend from stage1")
|
||||
|
||||
if("${ZIG_TARGET_TRIPLE}" STREQUAL "native")
|
||||
set(ZIG_USE_LLVM_CONFIG ON CACHE BOOL "use llvm-config to find LLVM libraries")
|
||||
else()
|
||||
set(ZIG_USE_LLVM_CONFIG OFF CACHE BOOL "use llvm-config to find LLVM libraries")
|
||||
endif()
|
||||
|
||||
find_package(llvm)
|
||||
find_package(clang)
|
||||
find_package(lld)
|
||||
|
@ -63,7 +63,7 @@ if(ZIG_PREFER_CLANG_CPP_DYLIB)
|
||||
if("${LLVM_CONFIG_VERSION}" VERSION_GREATER 13)
|
||||
message(FATAL_ERROR "expected LLVM 12.x but found ${LLVM_CONFIG_VERSION} using ${LLVM_CONFIG_EXE}")
|
||||
endif()
|
||||
elseif(("${ZIG_TARGET_TRIPLE}" STREQUAL "native") OR ZIG_PREFER_LLVM_CONFIG)
|
||||
elseif(ZIG_USE_LLVM_CONFIG)
|
||||
find_program(LLVM_CONFIG_EXE
|
||||
NAMES llvm-config-12 llvm-config-12.0 llvm-config120 llvm-config12 llvm-config
|
||||
PATHS
|
||||
|
@ -684,7 +684,7 @@ pub fn main() void {
|
||||
{#header_close#}
|
||||
{#header_open|String Literals and Unicode Code Point Literals#}
|
||||
<p>
|
||||
String literals are single-item constant {#link|Pointers#} to null-terminated byte arrays.
|
||||
String literals are constant single-item {#link|Pointers#} to null-terminated byte arrays.
|
||||
The type of string literals encodes both the length, and the fact that they are null-terminated,
|
||||
and thus they can be {#link|coerced|Type Coercion#} to both {#link|Slices#} and
|
||||
{#link|Null-Terminated Pointers|Sentinel-Terminated Pointers#}.
|
||||
@ -1783,7 +1783,7 @@ comptime {
|
||||
expect(message.len == 5);
|
||||
}
|
||||
|
||||
// A string literal is a pointer to an array literal.
|
||||
// A string literal is a single-item pointer to an array literal.
|
||||
const same_message = "hello";
|
||||
|
||||
comptime {
|
||||
@ -1989,15 +1989,15 @@ test "null terminated array" {
|
||||
|
||||
{#header_open|Pointers#}
|
||||
<p>
|
||||
Zig has two kinds of pointers:
|
||||
Zig has two kinds of pointers: single-item and many-item.
|
||||
</p>
|
||||
<ul>
|
||||
<li>{#syntax#}*T{#endsyntax#} - pointer to exactly one item.
|
||||
<li>{#syntax#}*T{#endsyntax#} - single-item pointer to exactly one item.
|
||||
<ul>
|
||||
<li>Supports deref syntax: {#syntax#}ptr.*{#endsyntax#}</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>{#syntax#}[*]T{#endsyntax#} - pointer to unknown number of items.
|
||||
<li>{#syntax#}[*]T{#endsyntax#} - many-item pointer to unknown number of items.
|
||||
<ul>
|
||||
<li>Supports index syntax: {#syntax#}ptr[i]{#endsyntax#}</li>
|
||||
<li>Supports slice syntax: {#syntax#}ptr[start..end]{#endsyntax#}</li>
|
||||
@ -2009,7 +2009,7 @@ test "null terminated array" {
|
||||
</ul>
|
||||
<p>These types are closely related to {#link|Arrays#} and {#link|Slices#}:</p>
|
||||
<ul>
|
||||
<li>{#syntax#}*[N]T{#endsyntax#} - pointer to N items, same as single-item pointer to array.
|
||||
<li>{#syntax#}*[N]T{#endsyntax#} - pointer to N items, same as single-item pointer to an array.
|
||||
<ul>
|
||||
<li>Supports index syntax: {#syntax#}array_ptr[i]{#endsyntax#}</li>
|
||||
<li>Supports slice syntax: {#syntax#}array_ptr[start..end]{#endsyntax#}</li>
|
||||
@ -2038,7 +2038,7 @@ test "address of syntax" {
|
||||
// Dereference a pointer:
|
||||
expect(x_ptr.* == 1234);
|
||||
|
||||
// When you get the address of a const variable, you get a const pointer to a single item.
|
||||
// When you get the address of a const variable, you get a const single-item pointer.
|
||||
expect(@TypeOf(x_ptr) == *const i32);
|
||||
|
||||
// If you want to mutate the value, you'd need an address of a mutable variable:
|
||||
@ -2051,7 +2051,7 @@ test "address of syntax" {
|
||||
|
||||
test "pointer array access" {
|
||||
// Taking an address of an individual element gives a
|
||||
// pointer to a single item. This kind of pointer
|
||||
// single-item pointer. This kind of pointer
|
||||
// does not support pointer arithmetic.
|
||||
var array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
|
||||
const ptr = &array[2];
|
||||
@ -2320,8 +2320,8 @@ test "basic slices" {
|
||||
expect(&slice[0] == &array[0]);
|
||||
expect(slice.len == array.len);
|
||||
|
||||
// Using the address-of operator on a slice gives a pointer to a single
|
||||
// item, while using the `ptr` field gives an unknown length pointer.
|
||||
// Using the address-of operator on a slice gives a single-item pointer,
|
||||
// while using the `ptr` field gives a many-item pointer.
|
||||
expect(@TypeOf(slice.ptr) == [*]i32);
|
||||
expect(@TypeOf(&slice[0]) == *i32);
|
||||
expect(@ptrToInt(slice.ptr) == @ptrToInt(&slice[0]));
|
||||
@ -5244,8 +5244,7 @@ test "*[N]T to []T" {
|
||||
expect(std.mem.eql(f32, x2, &[2]f32{ 1.2, 3.4 }));
|
||||
}
|
||||
|
||||
// Single-item pointers to arrays can be coerced to
|
||||
// unknown length pointers.
|
||||
// Single-item pointers to arrays can be coerced to many-item pointers.
|
||||
test "*[N]T to [*]T" {
|
||||
var buf: [5]u8 = "hello".*;
|
||||
const x: [*]u8 = &buf;
|
||||
@ -9853,7 +9852,7 @@ const c = @cImport({
|
||||
</p>
|
||||
<p>
|
||||
When importing C header files, it is ambiguous whether pointers should be translated as
|
||||
single-item pointers ({#syntax#}*T{#endsyntax#}) or unknown-length pointers ({#syntax#}[*]T{#endsyntax#}).
|
||||
single-item pointers ({#syntax#}*T{#endsyntax#}) or many-item pointers ({#syntax#}[*]T{#endsyntax#}).
|
||||
C pointers are a compromise so that Zig code can utilize translated header files directly.
|
||||
</p>
|
||||
<p>{#syntax#}[*c]T{#endsyntax#} - C pointer.</p>
|
||||
|
@ -835,7 +835,10 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void {
|
||||
std.process.exit(1);
|
||||
}
|
||||
},
|
||||
else => std.process.abort(),
|
||||
else => {
|
||||
log.err("{s} terminated", .{ argv.items[0] });
|
||||
return error.LLDCrashed;
|
||||
},
|
||||
}
|
||||
} else {
|
||||
child.stdin_behavior = .Ignore;
|
||||
|
@ -487,6 +487,53 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {
|
||||
addLLVMFnAttr(llvm_fn, "noreturn");
|
||||
}
|
||||
|
||||
if (!calling_convention_allows_zig_types(cc)) {
|
||||
// A simplistic and desperate attempt at making the compiler respect the
|
||||
// target ABI for return types.
|
||||
// This is just enough to avoid miscompiling the test suite, it will be
|
||||
// better in stage2.
|
||||
ZigType *int_type = return_type->id == ZigTypeIdInt ? return_type :
|
||||
return_type->id == ZigTypeIdEnum ? return_type->data.enumeration.tag_int_type :
|
||||
nullptr;
|
||||
|
||||
if (int_type != nullptr) {
|
||||
const bool is_signed = int_type->data.integral.is_signed;
|
||||
const uint32_t bit_width = int_type->data.integral.bit_count;
|
||||
bool should_extend = false;
|
||||
|
||||
// Rough equivalent of Clang's isPromotableIntegerType.
|
||||
switch (bit_width) {
|
||||
case 1: // bool
|
||||
case 8: // {un,}signed char
|
||||
case 16: // {un,}signed short
|
||||
should_extend = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (g->zig_target->arch) {
|
||||
case ZigLLVM_sparcv9:
|
||||
case ZigLLVM_riscv64:
|
||||
case ZigLLVM_ppc64:
|
||||
case ZigLLVM_ppc64le:
|
||||
// Always extend to the register width.
|
||||
should_extend = bit_width < 64;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// {zero,sign}-extend the result.
|
||||
if (should_extend) {
|
||||
if (is_signed)
|
||||
addLLVMAttr(llvm_fn, 0, "signext");
|
||||
else
|
||||
addLLVMAttr(llvm_fn, 0, "zeroext");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fn->body_node != nullptr) {
|
||||
maybe_export_dll(g, llvm_fn, linkage);
|
||||
|
||||
|
@ -24,6 +24,16 @@ void zig_f32(float);
|
||||
void zig_f64(double);
|
||||
void zig_five_floats(float, float, float, float, float);
|
||||
|
||||
bool zig_ret_bool();
|
||||
uint8_t zig_ret_u8();
|
||||
uint16_t zig_ret_u16();
|
||||
uint32_t zig_ret_u32();
|
||||
uint64_t zig_ret_u64();
|
||||
int8_t zig_ret_i8();
|
||||
int16_t zig_ret_i16();
|
||||
int32_t zig_ret_i32();
|
||||
int64_t zig_ret_i64();
|
||||
|
||||
void zig_ptr(void *);
|
||||
|
||||
void zig_bool(bool);
|
||||
@ -119,6 +129,20 @@ void run_c_tests(void) {
|
||||
assert_or_panic(res.d == 23);
|
||||
assert_or_panic(res.e == 24);
|
||||
}
|
||||
|
||||
{
|
||||
assert_or_panic(zig_ret_bool() == 1);
|
||||
|
||||
assert_or_panic(zig_ret_u8() == 0xff);
|
||||
assert_or_panic(zig_ret_u16() == 0xffff);
|
||||
assert_or_panic(zig_ret_u32() == 0xffffffff);
|
||||
assert_or_panic(zig_ret_u64() == 0xffffffffffffffff);
|
||||
|
||||
assert_or_panic(zig_ret_i8() == -1);
|
||||
assert_or_panic(zig_ret_i16() == -1);
|
||||
assert_or_panic(zig_ret_i32() == -1);
|
||||
assert_or_panic(zig_ret_i64() == -1);
|
||||
}
|
||||
}
|
||||
|
||||
void c_u8(uint8_t x) {
|
||||
@ -236,3 +260,31 @@ void c_big_struct_floats(Vector5 vec) {
|
||||
assert_or_panic(vec.w == 69);
|
||||
assert_or_panic(vec.q == 55);
|
||||
}
|
||||
|
||||
bool c_ret_bool() {
|
||||
return 1;
|
||||
}
|
||||
uint8_t c_ret_u8() {
|
||||
return 0xff;
|
||||
}
|
||||
uint16_t c_ret_u16() {
|
||||
return 0xffff;
|
||||
}
|
||||
uint32_t c_ret_u32() {
|
||||
return 0xffffffff;
|
||||
}
|
||||
uint64_t c_ret_u64() {
|
||||
return 0xffffffffffffffff;
|
||||
}
|
||||
int8_t c_ret_i8() {
|
||||
return -1;
|
||||
}
|
||||
int16_t c_ret_i16() {
|
||||
return -1;
|
||||
}
|
||||
int32_t c_ret_i32() {
|
||||
return -1;
|
||||
}
|
||||
int64_t c_ret_i64() {
|
||||
return -1;
|
||||
}
|
||||
|
@ -284,3 +284,55 @@ test "C ABI structs of floats as parameter" {
|
||||
};
|
||||
c_big_struct_floats(v5);
|
||||
}
|
||||
|
||||
export fn zig_ret_bool() bool {
|
||||
return true;
|
||||
}
|
||||
export fn zig_ret_u8() u8 {
|
||||
return 0xff;
|
||||
}
|
||||
export fn zig_ret_u16() u16 {
|
||||
return 0xffff;
|
||||
}
|
||||
export fn zig_ret_u32() u32 {
|
||||
return 0xffffffff;
|
||||
}
|
||||
export fn zig_ret_u64() u64 {
|
||||
return 0xffffffffffffffff;
|
||||
}
|
||||
export fn zig_ret_i8() i8 {
|
||||
return -1;
|
||||
}
|
||||
export fn zig_ret_i16() i16 {
|
||||
return -1;
|
||||
}
|
||||
export fn zig_ret_i32() i32 {
|
||||
return -1;
|
||||
}
|
||||
export fn zig_ret_i64() i64 {
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern fn c_ret_bool() bool;
|
||||
extern fn c_ret_u8() u8;
|
||||
extern fn c_ret_u16() u16;
|
||||
extern fn c_ret_u32() u32;
|
||||
extern fn c_ret_u64() u64;
|
||||
extern fn c_ret_i8() i8;
|
||||
extern fn c_ret_i16() i16;
|
||||
extern fn c_ret_i32() i32;
|
||||
extern fn c_ret_i64() i64;
|
||||
|
||||
test "C ABI integer return types" {
|
||||
expect(c_ret_bool() == true);
|
||||
|
||||
expect(c_ret_u8() == 0xff);
|
||||
expect(c_ret_u16() == 0xffff);
|
||||
expect(c_ret_u32() == 0xffffffff);
|
||||
expect(c_ret_u64() == 0xffffffffffffffff);
|
||||
|
||||
expect(c_ret_i8() == -1);
|
||||
expect(c_ret_i16() == -1);
|
||||
expect(c_ret_i32() == -1);
|
||||
expect(c_ret_i64() == -1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user