From 627b52fe654a7506861d3cbefb705803bd0c5102 Mon Sep 17 00:00:00 2001
From: kristopher tate
Date: Sat, 6 Apr 2019 16:31:28 +0900
Subject: src/ir.cpp: don't call-out to analyze_type_expr;
replaces `analyze_type_expr` with `ir_analyze_type_expr`
---
src/ir.cpp | 32 +++++++++++++++++++++++++++-----
1 file changed, 27 insertions(+), 5 deletions(-)
(limited to 'src/ir.cpp')
diff --git a/src/ir.cpp b/src/ir.cpp
index c572e3c885..de4543df4e 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -356,6 +356,28 @@ static void ir_ref_var(ZigVar *var) {
var->ref_count += 1;
}
+ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) {
+ ConstExprValue *result = ir_eval_const_value( ira->codegen
+ , scope
+ , node
+ , ira->codegen->builtin_types.entry_type
+ , ira->new_irb.exec->backward_branch_count
+ , ira->new_irb.exec->backward_branch_quota
+ , nullptr
+ , nullptr
+ , node
+ , nullptr
+ , ira->new_irb.exec
+ , nullptr
+ );
+
+ if (type_is_invalid(result->type))
+ return ira->codegen->builtin_types.entry_invalid;
+
+ assert(result->special != ConstValSpecialRuntime);
+ return result->data.x_type;
+}
+
static IrBasicBlock *ir_create_basic_block(IrBuilder *irb, Scope *scope, const char *name_hint) {
IrBasicBlock *result = allocate(1);
result->scope = scope;
@@ -13875,7 +13897,7 @@ static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node
IrInstruction *casted_arg;
if (param_decl_node->data.param_decl.var_token == nullptr) {
AstNode *param_type_node = param_decl_node->data.param_decl.type;
- ZigType *param_type = analyze_type_expr(ira->codegen, *exec_scope, param_type_node);
+ ZigType *param_type = ir_analyze_type_expr(ira, *exec_scope, param_type_node);
if (type_is_invalid(param_type))
return false;
@@ -13915,7 +13937,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
} else {
if (param_decl_node->data.param_decl.var_token == nullptr) {
AstNode *param_type_node = param_decl_node->data.param_decl.type;
- ZigType *param_type = analyze_type_expr(ira->codegen, *child_scope, param_type_node);
+ ZigType *param_type = ir_analyze_type_expr(ira, *child_scope, param_type_node);
if (type_is_invalid(param_type))
return false;
@@ -14296,7 +14318,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
}
AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type;
- ZigType *specified_return_type = analyze_type_expr(ira->codegen, exec_scope, return_type_node);
+ ZigType *specified_return_type = ir_analyze_type_expr(ira, exec_scope, return_type_node);
if (type_is_invalid(specified_return_type))
return ira->codegen->invalid_instruction;
ZigType *return_type;
@@ -14532,7 +14554,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
if (fn_proto_node->data.fn_proto.return_var_token == nullptr) {
AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type;
- ZigType *specified_return_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, return_type_node);
+ ZigType *specified_return_type = ir_analyze_type_expr(ira, impl_fn->child_scope, return_type_node);
if (type_is_invalid(specified_return_type))
return ira->codegen->invalid_instruction;
if (fn_proto_node->data.fn_proto.auto_err_set) {
@@ -14559,7 +14581,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call
if (call_instruction->is_async) {
AstNode *async_allocator_type_node = fn_proto_node->data.fn_proto.async_allocator_type;
if (async_allocator_type_node != nullptr) {
- ZigType *async_allocator_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, async_allocator_type_node);
+ ZigType *async_allocator_type = ir_analyze_type_expr(ira, impl_fn->child_scope, async_allocator_type_node);
if (type_is_invalid(async_allocator_type))
return ira->codegen->invalid_instruction;
inst_fn_type_id.async_allocator_type = async_allocator_type;
--
cgit v1.2.3
From 68d7e4a1b60a52b59bc148a81458a89b9b739ab1 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Sat, 13 Apr 2019 16:53:53 -0400
Subject: better handle quota of setEvalBranchQuota
Now that c58b80203443dcbf8b737ebdaa1f17fb20c77711 has removed
the "top of the comptime stack" requirement, the branch quota
can be modified somewhere other than the top of the comptime stack.
This means that the quota of a parent IrExecutable has to be
modifiable by an instruction in the child.
Closes #2261
---
src/all_types.hpp | 3 ++-
src/analyze.cpp | 7 +++++--
src/ir.cpp | 34 +++++++++++++---------------------
src/ir.hpp | 2 +-
4 files changed, 21 insertions(+), 25 deletions(-)
(limited to 'src/ir.cpp')
diff --git a/src/all_types.hpp b/src/all_types.hpp
index 92faad1e03..39bccddc3f 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -55,7 +55,7 @@ struct IrExecutable {
size_t mem_slot_count;
size_t next_debug_id;
size_t *backward_branch_count;
- size_t backward_branch_quota;
+ size_t *backward_branch_quota;
ZigFn *fn_entry;
Buf *c_import_buf;
AstNode *source_node;
@@ -1350,6 +1350,7 @@ struct ZigFn {
IrExecutable ir_executable;
IrExecutable analyzed_executable;
size_t prealloc_bbc;
+ size_t prealloc_backward_branch_quota;
AstNode **param_source_nodes;
Buf **param_names;
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 394364c68f..730c52c927 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -969,8 +969,9 @@ static ConstExprValue *analyze_const_value(CodeGen *g, Scope *scope, AstNode *no
Buf *type_name)
{
size_t backward_branch_count = 0;
+ size_t backward_branch_quota = default_backward_branch_quota;
return ir_eval_const_value(g, scope, node, type_entry,
- &backward_branch_count, default_backward_branch_quota,
+ &backward_branch_count, &backward_branch_quota,
nullptr, nullptr, node, type_name, nullptr, nullptr);
}
@@ -2623,9 +2624,11 @@ static void get_fully_qualified_decl_name(Buf *buf, Tld *tld) {
ZigFn *create_fn_raw(CodeGen *g, FnInline inline_value) {
ZigFn *fn_entry = allocate(1);
+ fn_entry->prealloc_backward_branch_quota = default_backward_branch_quota;
+
fn_entry->codegen = g;
fn_entry->analyzed_executable.backward_branch_count = &fn_entry->prealloc_bbc;
- fn_entry->analyzed_executable.backward_branch_quota = default_backward_branch_quota;
+ fn_entry->analyzed_executable.backward_branch_quota = &fn_entry->prealloc_backward_branch_quota;
fn_entry->analyzed_executable.fn_entry = fn_entry;
fn_entry->ir_executable.fn_entry = fn_entry;
fn_entry->fn_inline = inline_value;
diff --git a/src/ir.cpp b/src/ir.cpp
index de4543df4e..3d4ab45dc9 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -357,19 +357,9 @@ static void ir_ref_var(ZigVar *var) {
}
ZigType *ir_analyze_type_expr(IrAnalyze *ira, Scope *scope, AstNode *node) {
- ConstExprValue *result = ir_eval_const_value( ira->codegen
- , scope
- , node
- , ira->codegen->builtin_types.entry_type
- , ira->new_irb.exec->backward_branch_count
- , ira->new_irb.exec->backward_branch_quota
- , nullptr
- , nullptr
- , node
- , nullptr
- , ira->new_irb.exec
- , nullptr
- );
+ ConstExprValue *result = ir_eval_const_value(ira->codegen, scope, node, ira->codegen->builtin_types.entry_type,
+ ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, nullptr,
+ node, nullptr, ira->new_irb.exec, nullptr);
if (type_is_invalid(result->type))
return ira->codegen->builtin_types.entry_invalid;
@@ -7965,7 +7955,7 @@ static ConstExprValue *ir_exec_const_result(CodeGen *codegen, IrExecutable *exec
return &codegen->invalid_instruction->value;
}
}
- return &codegen->invalid_instruction->value;
+ zig_unreachable();
}
static bool ir_emit_global_runtime_side_effect(IrAnalyze *ira, IrInstruction *source_instruction) {
@@ -10227,16 +10217,18 @@ static IrInstruction *ir_unreach_error(IrAnalyze *ira) {
static bool ir_emit_backward_branch(IrAnalyze *ira, IrInstruction *source_instruction) {
size_t *bbc = ira->new_irb.exec->backward_branch_count;
- size_t quota = ira->new_irb.exec->backward_branch_quota;
+ size_t *quota = ira->new_irb.exec->backward_branch_quota;
// If we're already over quota, we've already given an error message for this.
- if (*bbc > quota) {
+ if (*bbc > *quota) {
+ assert(ira->codegen->errors.length > 0);
return false;
}
*bbc += 1;
- if (*bbc > quota) {
- ir_add_error(ira, source_instruction, buf_sprintf("evaluation exceeded %" ZIG_PRI_usize " backwards branches", quota));
+ if (*bbc > *quota) {
+ ir_add_error(ira, source_instruction,
+ buf_sprintf("evaluation exceeded %" ZIG_PRI_usize " backwards branches", *quota));
return false;
}
return true;
@@ -10317,7 +10309,7 @@ static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, Un
}
ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
- ZigType *expected_type, size_t *backward_branch_count, size_t backward_branch_quota,
+ ZigType *expected_type, size_t *backward_branch_count, size_t *backward_branch_quota,
ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name,
IrExecutable *parent_exec, AstNode *expected_type_source_node)
{
@@ -18983,8 +18975,8 @@ static IrInstruction *ir_analyze_instruction_set_eval_branch_quota(IrAnalyze *ir
if (!ir_resolve_usize(ira, instruction->new_quota->child, &new_quota))
return ira->codegen->invalid_instruction;
- if (new_quota > ira->new_irb.exec->backward_branch_quota) {
- ira->new_irb.exec->backward_branch_quota = new_quota;
+ if (new_quota > *ira->new_irb.exec->backward_branch_quota) {
+ *ira->new_irb.exec->backward_branch_quota = new_quota;
}
return ir_const_void(ira, &instruction->base);
diff --git a/src/ir.hpp b/src/ir.hpp
index 0b85ad2c55..4fb7552212 100644
--- a/src/ir.hpp
+++ b/src/ir.hpp
@@ -14,7 +14,7 @@ bool ir_gen(CodeGen *g, AstNode *node, Scope *scope, IrExecutable *ir_executable
bool ir_gen_fn(CodeGen *g, ZigFn *fn_entry);
ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node,
- ZigType *expected_type, size_t *backward_branch_count, size_t backward_branch_quota,
+ ZigType *expected_type, size_t *backward_branch_count, size_t *backward_branch_quota,
ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name,
IrExecutable *parent_exec, AstNode *expected_type_source_node);
--
cgit v1.2.3
From a2d8f03092419853b6bbcee45ea759ae994cc2d5 Mon Sep 17 00:00:00 2001
From: Shritesh Bhattarai
Date: Sat, 13 Apr 2019 22:28:58 -0500
Subject: support extern "wasi" functions
---
src/ir.cpp | 9 ++++++++-
std/os/wasi/core.zig | 6 +++---
2 files changed, 11 insertions(+), 4 deletions(-)
(limited to 'src/ir.cpp')
diff --git a/src/ir.cpp b/src/ir.cpp
index de4543df4e..73a24a815a 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -15836,6 +15836,13 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name,
ira->codegen->reported_bad_link_libc_error = true;
}
+ bool is_wasi = ira->codegen->zig_target->os == OsWASI;
+ if (!is_wasi && buf_eql_str(lib_name, "wasi")) {
+ ir_add_error_node(ira, source_node,
+ buf_sprintf("linking against wasi libarry"));
+ ira->codegen->reported_bad_link_libc_error = true;
+ }
+
LinkLib *link_lib = add_link_lib(ira->codegen, lib_name);
for (size_t i = 0; i < link_lib->symbols.length; i += 1) {
Buf *existing_symbol_name = link_lib->symbols.at(i);
@@ -15844,7 +15851,7 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name,
}
}
- if (!is_libc && !ira->codegen->have_pic && !ira->codegen->reported_bad_link_libc_error) {
+ if (!is_libc && !ira->codegen->have_pic && !ira->codegen->reported_bad_link_libc_error && !is_wasi) {
ErrorMsg *msg = ir_add_error_node(ira, source_node,
buf_sprintf("dependency on dynamic library '%s' requires enabling Position Independent Code",
buf_ptr(lib_name)));
diff --git a/std/os/wasi/core.zig b/std/os/wasi/core.zig
index 18c32837e9..cda06cdce5 100644
--- a/std/os/wasi/core.zig
+++ b/std/os/wasi/core.zig
@@ -10,8 +10,8 @@ pub const __wasi_ciovec_t = extern struct {
pub const __WASI_SIGABRT: __wasi_signal_t = 6;
-pub extern fn __wasi_proc_raise(sig: __wasi_signal_t) __wasi_errno_t;
+pub extern "wasi" fn __wasi_proc_raise(sig: __wasi_signal_t) __wasi_errno_t;
-pub extern fn __wasi_proc_exit(rval: __wasi_exitcode_t) noreturn;
+pub extern "wasi" fn __wasi_proc_exit(rval: __wasi_exitcode_t) noreturn;
-pub extern fn __wasi_fd_write(fd: __wasi_fd_t, iovs: *const __wasi_ciovec_t, iovs_len: usize, nwritten: *usize) __wasi_errno_t;
+pub extern "wasi" fn __wasi_fd_write(fd: __wasi_fd_t, iovs: *const __wasi_ciovec_t, iovs_len: usize, nwritten: *usize) __wasi_errno_t;
--
cgit v1.2.3
From ecd0f8925447074307e8795bb8d6f9f6277a1a26 Mon Sep 17 00:00:00 2001
From: Shritesh Bhattarai
Date: Sat, 13 Apr 2019 23:49:02 -0500
Subject: wasi: better extern wasi logic
---
src/ir.cpp | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
(limited to 'src/ir.cpp')
diff --git a/src/ir.cpp b/src/ir.cpp
index 73a24a815a..2cafc1edd0 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -15836,10 +15836,10 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name,
ira->codegen->reported_bad_link_libc_error = true;
}
- bool is_wasi = ira->codegen->zig_target->os == OsWASI;
- if (!is_wasi && buf_eql_str(lib_name, "wasi")) {
+ bool is_wasi = buf_eql_str(lib_name, "wasi");
+ if (is_wasi && ira->codegen->zig_target->os != OsWASI) {
ir_add_error_node(ira, source_node,
- buf_sprintf("linking against wasi libarry"));
+ buf_sprintf("linking against wasi library"));
ira->codegen->reported_bad_link_libc_error = true;
}
@@ -15851,7 +15851,7 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name,
}
}
- if (!is_libc && !ira->codegen->have_pic && !ira->codegen->reported_bad_link_libc_error && !is_wasi) {
+ if (!is_libc && !is_wasi && !ira->codegen->have_pic && !ira->codegen->reported_bad_link_libc_error) {
ErrorMsg *msg = ir_add_error_node(ira, source_node,
buf_sprintf("dependency on dynamic library '%s' requires enabling Position Independent Code",
buf_ptr(lib_name)));
--
cgit v1.2.3
From 9465c6d5385dff70d41142f509fcdf074269a905 Mon Sep 17 00:00:00 2001
From: Shritesh Bhattarai
Date: Mon, 15 Apr 2019 16:59:34 -0500
Subject: link: exemption for wasm instead of wasi
---
src/ir.cpp | 9 +--------
1 file changed, 1 insertion(+), 8 deletions(-)
(limited to 'src/ir.cpp')
diff --git a/src/ir.cpp b/src/ir.cpp
index db45496f3f..a3d08b5327 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -15828,13 +15828,6 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name,
ira->codegen->reported_bad_link_libc_error = true;
}
- bool is_wasi = buf_eql_str(lib_name, "wasi");
- if (is_wasi && ira->codegen->zig_target->os != OsWASI) {
- ir_add_error_node(ira, source_node,
- buf_sprintf("linking against wasi library"));
- ira->codegen->reported_bad_link_libc_error = true;
- }
-
LinkLib *link_lib = add_link_lib(ira->codegen, lib_name);
for (size_t i = 0; i < link_lib->symbols.length; i += 1) {
Buf *existing_symbol_name = link_lib->symbols.at(i);
@@ -15843,7 +15836,7 @@ static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name,
}
}
- if (!is_libc && !is_wasi && !ira->codegen->have_pic && !ira->codegen->reported_bad_link_libc_error) {
+ if (!is_libc && !target_is_wasm(ira->codegen->zig_target) && !ira->codegen->have_pic && !ira->codegen->reported_bad_link_libc_error) {
ErrorMsg *msg = ir_add_error_node(ira, source_node,
buf_sprintf("dependency on dynamic library '%s' requires enabling Position Independent Code",
buf_ptr(lib_name)));
--
cgit v1.2.3
From a44ad08954d9646f9fb1db6f1c167dd966b196a2 Mon Sep 17 00:00:00 2001
From: LemonBoy
Date: Sat, 20 Apr 2019 11:41:38 +0200
Subject: Add some zig_panic for 80-bit float codepaths
---
src/ir.cpp | 6 ++++++
1 file changed, 6 insertions(+)
(limited to 'src/ir.cpp')
diff --git a/src/ir.cpp b/src/ir.cpp
index a3d08b5327..71f39d7f90 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -8100,6 +8100,8 @@ static void float_init_bigfloat(ConstExprValue *dest_val, BigFloat *bigfloat) {
case 64:
dest_val->data.x_f64 = bigfloat_to_f64(bigfloat);
break;
+ case 80:
+ zig_panic("TODO");
case 128:
dest_val->data.x_f128 = bigfloat_to_f128(bigfloat);
break;
@@ -9961,6 +9963,8 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_
case 64:
const_val->data.x_f64 = bigfloat_to_f64(&other_val->data.x_bigfloat);
break;
+ case 80:
+ zig_panic("TODO");
case 128:
const_val->data.x_f128 = bigfloat_to_f128(&other_val->data.x_bigfloat);
break;
@@ -9990,6 +9994,8 @@ static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_
case 64:
const_val->data.x_f64 = bigfloat_to_f64(&bigfloat);
break;
+ case 80:
+ zig_panic("TODO");
case 128:
const_val->data.x_f128 = bigfloat_to_f128(&bigfloat);
break;
--
cgit v1.2.3
From 1a2e02e267216bb35937d25598c773255d830b25 Mon Sep 17 00:00:00 2001
From: Jimmi HC
Date: Wed, 24 Apr 2019 15:04:58 +0200
Subject: fixed #2356
const_ptr_pointee_unchecked did not take into account that if the
pointer is zero sized, then const_val->data.x_ptr.special would be
ConstPtrSpecialInvalid. This commit fixes this by also checking
that the child type of the pointer only have one possible value
and just returns that value.
---
src/ir.cpp | 13 +++++++++++++
test/stage1/behavior.zig | 1 +
test/stage1/behavior/bugs/2346.zig | 6 ++++++
3 files changed, 20 insertions(+)
create mode 100644 test/stage1/behavior/bugs/2346.zig
(limited to 'src/ir.cpp')
diff --git a/src/ir.cpp b/src/ir.cpp
index a3d08b5327..e5192cf347 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -188,6 +188,19 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c
assert(get_src_ptr_type(const_val->type) != nullptr);
assert(const_val->special == ConstValSpecialStatic);
ConstExprValue *result;
+
+ switch (type_has_one_possible_value(g, const_val->type->data.pointer.child_type)) {
+ case OnePossibleValueInvalid:
+ zig_unreachable();
+ case OnePossibleValueYes:
+ result = create_const_vals(1);
+ result->type = const_val->type->data.pointer.child_type;
+ result->special = ConstValSpecialStatic;
+ return result;
+ case OnePossibleValueNo:
+ break;
+ }
+
switch (const_val->data.x_ptr.special) {
case ConstPtrSpecialInvalid:
zig_unreachable();
diff --git a/test/stage1/behavior.zig b/test/stage1/behavior.zig
index bdd2273c34..85dd606872 100644
--- a/test/stage1/behavior.zig
+++ b/test/stage1/behavior.zig
@@ -24,6 +24,7 @@ comptime {
_ = @import("behavior/bugs/1851.zig");
_ = @import("behavior/bugs/1914.zig");
_ = @import("behavior/bugs/2006.zig");
+ _ = @import("behavior/bugs/2346.zig");
_ = @import("behavior/bugs/394.zig");
_ = @import("behavior/bugs/421.zig");
_ = @import("behavior/bugs/529.zig");
diff --git a/test/stage1/behavior/bugs/2346.zig b/test/stage1/behavior/bugs/2346.zig
new file mode 100644
index 0000000000..3d76fc4bfe
--- /dev/null
+++ b/test/stage1/behavior/bugs/2346.zig
@@ -0,0 +1,6 @@
+test "" {
+ const a: *void = undefined;
+ const b: *[1]void = a;
+ const c: *[0]u8 = undefined;
+ const d: []u8 = c;
+}
\ No newline at end of file
--
cgit v1.2.3
From fb2acaff067dd6b385de7f2bd2726bdfebbf841f Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Wed, 24 Apr 2019 22:31:53 -0400
Subject: `@sizeOf` returns 0 for comptime types
This defines `@sizeOf` to be the runtime size of a type, which means
that it is zero for types such as comptime_int, type, and (enum
literal).
See #2209
---
doc/langref.html.in | 4 ++++
src/ir.cpp | 10 +++++-----
test/compile_errors.zig | 9 +++++++++
test/stage1/behavior/sizeof_and_typeof.zig | 7 +++++++
4 files changed, 25 insertions(+), 5 deletions(-)
(limited to 'src/ir.cpp')
diff --git a/doc/langref.html.in b/doc/langref.html.in
index 7217d4786e..7b3d7f3dd1 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -7275,6 +7275,10 @@ test "@setRuntimeSafety" {
consider whether you want to use {#syntax#}@sizeOf(T){#endsyntax#} or
{#syntax#}@typeInfo(T).Int.bits{#endsyntax#}.
+
+ This function measures the size at runtime. For types that are disallowed at runtime, such as
+ {#syntax#}comptime_int{#endsyntax#} and {#syntax#}type{#endsyntax#}, the result is {#syntax#}0{#endsyntax#}.
+
{#see_also|@typeInfo#}
{#header_close#}
diff --git a/src/ir.cpp b/src/ir.cpp
index f3435ccb17..62eadeb43f 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -16729,16 +16729,16 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira,
case ZigTypeIdUnreachable:
case ZigTypeIdUndefined:
case ZigTypeIdNull:
- case ZigTypeIdComptimeFloat:
- case ZigTypeIdComptimeInt:
- case ZigTypeIdEnumLiteral:
case ZigTypeIdBoundFn:
- case ZigTypeIdMetaType:
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
- ir_add_error_node(ira, size_of_instruction->base.source_node,
+ ir_add_error_node(ira, type_value->source_node,
buf_sprintf("no size available for type '%s'", buf_ptr(&type_entry->name)));
return ira->codegen->invalid_instruction;
+ case ZigTypeIdMetaType:
+ case ZigTypeIdEnumLiteral:
+ case ZigTypeIdComptimeFloat:
+ case ZigTypeIdComptimeInt:
case ZigTypeIdVoid:
case ZigTypeIdBool:
case ZigTypeIdInt:
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index 0d30bd7175..60d1a9ac89 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -2,6 +2,15 @@ const tests = @import("tests.zig");
const builtin = @import("builtin");
pub fn addCases(cases: *tests.CompileErrorContext) void {
+ cases.add(
+ "@sizeOf bad type",
+ \\export fn entry() void {
+ \\ _ = @sizeOf(@typeOf(null));
+ \\}
+ ,
+ "tmp.zig:2:17: error: no size available for type '(null)'",
+ );
+
cases.add(
"Generic function where return type is self-referenced",
\\fn Foo(comptime T: type) Foo(T) {
diff --git a/test/stage1/behavior/sizeof_and_typeof.zig b/test/stage1/behavior/sizeof_and_typeof.zig
index 58a6c81759..cfad311e06 100644
--- a/test/stage1/behavior/sizeof_and_typeof.zig
+++ b/test/stage1/behavior/sizeof_and_typeof.zig
@@ -67,3 +67,10 @@ test "@bitOffsetOf" {
expect(@byteOffsetOf(A, "f") * 8 == @bitOffsetOf(A, "f"));
expect(@byteOffsetOf(A, "g") * 8 == @bitOffsetOf(A, "g"));
}
+
+test "@sizeOf on compile-time types" {
+ expect(@sizeOf(comptime_int) == 0);
+ expect(@sizeOf(comptime_float) == 0);
+ expect(@sizeOf(@typeOf(.hi)) == 0);
+ expect(@sizeOf(@typeOf(type)) == 0);
+}
--
cgit v1.2.3
From 976080462cf62f6f112d38176b99e5bb8a57bf37 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Sun, 21 Apr 2019 17:24:58 -0400
Subject: translate-c: a little closer to self-hosted implementation
---
CMakeLists.txt | 1 +
src-self-hosted/clang.zig | 944 ++++++++++++++++++++++++++++++++++++++++
src-self-hosted/stage1.zig | 95 +++-
src-self-hosted/translate_c.zig | 11 +-
src/analyze.cpp | 2 +-
src/analyze.hpp | 2 +
src/ast_render.cpp | 4 +-
src/ast_render.hpp | 2 +-
src/codegen.cpp | 271 +++++++-----
src/codegen.hpp | 3 +-
src/error.cpp | 4 +
src/error.hpp | 44 +-
src/ir.cpp | 22 +-
src/main.cpp | 3 +-
src/translate_c.cpp | 94 +---
src/translate_c.hpp | 4 +-
src/userland.cpp | 10 +-
src/userland.h | 72 ++-
src/zig_clang.h | 167 +++----
std/c.zig | 4 +
std/io.zig | 30 +-
std/io/c_out_stream.zig | 44 ++
22 files changed, 1467 insertions(+), 366 deletions(-)
create mode 100644 src-self-hosted/clang.zig
create mode 100644 std/io/c_out_stream.zig
(limited to 'src/ir.cpp')
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4f8ae390ab..f3911699f5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -508,6 +508,7 @@ set(ZIG_STD_FILES
"heap.zig"
"io.zig"
"io/seekable_stream.zig"
+ "io/c_out_stream.zig"
"json.zig"
"lazy_init.zig"
"linked_list.zig"
diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig
new file mode 100644
index 0000000000..6f7c7eb853
--- /dev/null
+++ b/src-self-hosted/clang.zig
@@ -0,0 +1,944 @@
+pub const struct_ZigClangAPValue = @OpaqueType();
+pub const struct_ZigClangAPSInt = @OpaqueType();
+pub const struct_ZigClangASTContext = @OpaqueType();
+pub const struct_ZigClangASTUnit = @OpaqueType();
+pub const struct_ZigClangArraySubscriptExpr = @OpaqueType();
+pub const struct_ZigClangArrayType = @OpaqueType();
+pub const struct_ZigClangAttributedType = @OpaqueType();
+pub const struct_ZigClangBinaryOperator = @OpaqueType();
+pub const struct_ZigClangBreakStmt = @OpaqueType();
+pub const struct_ZigClangBuiltinType = @OpaqueType();
+pub const struct_ZigClangCStyleCastExpr = @OpaqueType();
+pub const struct_ZigClangCallExpr = @OpaqueType();
+pub const struct_ZigClangCaseStmt = @OpaqueType();
+pub const struct_ZigClangCompoundAssignOperator = @OpaqueType();
+pub const struct_ZigClangCompoundStmt = @OpaqueType();
+pub const struct_ZigClangConditionalOperator = @OpaqueType();
+pub const struct_ZigClangConstantArrayType = @OpaqueType();
+pub const struct_ZigClangContinueStmt = @OpaqueType();
+pub const struct_ZigClangDecayedType = @OpaqueType();
+pub const struct_ZigClangDecl = @OpaqueType();
+pub const struct_ZigClangDeclRefExpr = @OpaqueType();
+pub const struct_ZigClangDeclStmt = @OpaqueType();
+pub const struct_ZigClangDefaultStmt = @OpaqueType();
+pub const struct_ZigClangDiagnosticOptions = @OpaqueType();
+pub const struct_ZigClangDiagnosticsEngine = @OpaqueType();
+pub const struct_ZigClangDoStmt = @OpaqueType();
+pub const struct_ZigClangElaboratedType = @OpaqueType();
+pub const struct_ZigClangEnumConstantDecl = @OpaqueType();
+pub const struct_ZigClangEnumDecl = @OpaqueType();
+pub const struct_ZigClangEnumType = @OpaqueType();
+pub const struct_ZigClangExpr = @OpaqueType();
+pub const struct_ZigClangFieldDecl = @OpaqueType();
+pub const struct_ZigClangFileID = @OpaqueType();
+pub const struct_ZigClangForStmt = @OpaqueType();
+pub const struct_ZigClangFullSourceLoc = @OpaqueType();
+pub const struct_ZigClangFunctionDecl = @OpaqueType();
+pub const struct_ZigClangFunctionProtoType = @OpaqueType();
+pub const struct_ZigClangIfStmt = @OpaqueType();
+pub const struct_ZigClangImplicitCastExpr = @OpaqueType();
+pub const struct_ZigClangIncompleteArrayType = @OpaqueType();
+pub const struct_ZigClangIntegerLiteral = @OpaqueType();
+pub const struct_ZigClangMacroDefinitionRecord = @OpaqueType();
+pub const struct_ZigClangMemberExpr = @OpaqueType();
+pub const struct_ZigClangNamedDecl = @OpaqueType();
+pub const struct_ZigClangNone = @OpaqueType();
+pub const struct_ZigClangPCHContainerOperations = @OpaqueType();
+pub const struct_ZigClangParenExpr = @OpaqueType();
+pub const struct_ZigClangParenType = @OpaqueType();
+pub const struct_ZigClangParmVarDecl = @OpaqueType();
+pub const struct_ZigClangPointerType = @OpaqueType();
+pub const struct_ZigClangPreprocessedEntity = @OpaqueType();
+pub const struct_ZigClangRecordDecl = @OpaqueType();
+pub const struct_ZigClangRecordType = @OpaqueType();
+pub const struct_ZigClangReturnStmt = @OpaqueType();
+pub const struct_ZigClangSkipFunctionBodiesScope = @OpaqueType();
+pub const struct_ZigClangSourceManager = @OpaqueType();
+pub const struct_ZigClangSourceRange = @OpaqueType();
+pub const struct_ZigClangStmt = @OpaqueType();
+pub const struct_ZigClangStorageClass = @OpaqueType();
+pub const struct_ZigClangStringLiteral = @OpaqueType();
+pub const struct_ZigClangStringRef = @OpaqueType();
+pub const struct_ZigClangSwitchStmt = @OpaqueType();
+pub const struct_ZigClangTagDecl = @OpaqueType();
+pub const struct_ZigClangType = @OpaqueType();
+pub const struct_ZigClangTypedefNameDecl = @OpaqueType();
+pub const struct_ZigClangTypedefType = @OpaqueType();
+pub const struct_ZigClangUnaryExprOrTypeTraitExpr = @OpaqueType();
+pub const struct_ZigClangUnaryOperator = @OpaqueType();
+pub const struct_ZigClangValueDecl = @OpaqueType();
+pub const struct_ZigClangVarDecl = @OpaqueType();
+pub const struct_ZigClangWhileStmt = @OpaqueType();
+pub const ZigClangBO_PtrMemD = enum_ZigClangBO._PtrMemD;
+pub const ZigClangBO_PtrMemI = enum_ZigClangBO._PtrMemI;
+pub const ZigClangBO_Mul = enum_ZigClangBO._Mul;
+pub const ZigClangBO_Div = enum_ZigClangBO._Div;
+pub const ZigClangBO_Rem = enum_ZigClangBO._Rem;
+pub const ZigClangBO_Add = enum_ZigClangBO._Add;
+pub const ZigClangBO_Sub = enum_ZigClangBO._Sub;
+pub const ZigClangBO_Shl = enum_ZigClangBO._Shl;
+pub const ZigClangBO_Shr = enum_ZigClangBO._Shr;
+pub const ZigClangBO_Cmp = enum_ZigClangBO._Cmp;
+pub const ZigClangBO_LT = enum_ZigClangBO._LT;
+pub const ZigClangBO_GT = enum_ZigClangBO._GT;
+pub const ZigClangBO_LE = enum_ZigClangBO._LE;
+pub const ZigClangBO_GE = enum_ZigClangBO._GE;
+pub const ZigClangBO_EQ = enum_ZigClangBO._EQ;
+pub const ZigClangBO_NE = enum_ZigClangBO._NE;
+pub const ZigClangBO_And = enum_ZigClangBO._And;
+pub const ZigClangBO_Xor = enum_ZigClangBO._Xor;
+pub const ZigClangBO_Or = enum_ZigClangBO._Or;
+pub const ZigClangBO_LAnd = enum_ZigClangBO._LAnd;
+pub const ZigClangBO_LOr = enum_ZigClangBO._LOr;
+pub const ZigClangBO_Assign = enum_ZigClangBO._Assign;
+pub const ZigClangBO_MulAssign = enum_ZigClangBO._MulAssign;
+pub const ZigClangBO_DivAssign = enum_ZigClangBO._DivAssign;
+pub const ZigClangBO_RemAssign = enum_ZigClangBO._RemAssign;
+pub const ZigClangBO_AddAssign = enum_ZigClangBO._AddAssign;
+pub const ZigClangBO_SubAssign = enum_ZigClangBO._SubAssign;
+pub const ZigClangBO_ShlAssign = enum_ZigClangBO._ShlAssign;
+pub const ZigClangBO_ShrAssign = enum_ZigClangBO._ShrAssign;
+pub const ZigClangBO_AndAssign = enum_ZigClangBO._AndAssign;
+pub const ZigClangBO_XorAssign = enum_ZigClangBO._XorAssign;
+pub const ZigClangBO_OrAssign = enum_ZigClangBO._OrAssign;
+pub const ZigClangBO_Comma = enum_ZigClangBO._Comma;
+pub const enum_ZigClangBO = extern enum {
+ _PtrMemD,
+ _PtrMemI,
+ _Mul,
+ _Div,
+ _Rem,
+ _Add,
+ _Sub,
+ _Shl,
+ _Shr,
+ _Cmp,
+ _LT,
+ _GT,
+ _LE,
+ _GE,
+ _EQ,
+ _NE,
+ _And,
+ _Xor,
+ _Or,
+ _LAnd,
+ _LOr,
+ _Assign,
+ _MulAssign,
+ _DivAssign,
+ _RemAssign,
+ _AddAssign,
+ _SubAssign,
+ _ShlAssign,
+ _ShrAssign,
+ _AndAssign,
+ _XorAssign,
+ _OrAssign,
+ _Comma,
+};
+pub const ZigClangUO_PostInc = enum_ZigClangUO._PostInc;
+pub const ZigClangUO_PostDec = enum_ZigClangUO._PostDec;
+pub const ZigClangUO_PreInc = enum_ZigClangUO._PreInc;
+pub const ZigClangUO_PreDec = enum_ZigClangUO._PreDec;
+pub const ZigClangUO_AddrOf = enum_ZigClangUO._AddrOf;
+pub const ZigClangUO_Deref = enum_ZigClangUO._Deref;
+pub const ZigClangUO_Plus = enum_ZigClangUO._Plus;
+pub const ZigClangUO_Minus = enum_ZigClangUO._Minus;
+pub const ZigClangUO_Not = enum_ZigClangUO._Not;
+pub const ZigClangUO_LNot = enum_ZigClangUO._LNot;
+pub const ZigClangUO_Real = enum_ZigClangUO._Real;
+pub const ZigClangUO_Imag = enum_ZigClangUO._Imag;
+pub const ZigClangUO_Extension = enum_ZigClangUO._Extension;
+pub const ZigClangUO_Coawait = enum_ZigClangUO._Coawait;
+pub const enum_ZigClangUO = extern enum {
+ _PostInc,
+ _PostDec,
+ _PreInc,
+ _PreDec,
+ _AddrOf,
+ _Deref,
+ _Plus,
+ _Minus,
+ _Not,
+ _LNot,
+ _Real,
+ _Imag,
+ _Extension,
+ _Coawait,
+};
+pub const ZigClangType_Builtin = enum_ZigClangTypeClass.ZigClangType_Builtin;
+pub const ZigClangType_Complex = enum_ZigClangTypeClass.ZigClangType_Complex;
+pub const ZigClangType_Pointer = enum_ZigClangTypeClass.ZigClangType_Pointer;
+pub const ZigClangType_BlockPointer = enum_ZigClangTypeClass.ZigClangType_BlockPointer;
+pub const ZigClangType_LValueReference = enum_ZigClangTypeClass.ZigClangType_LValueReference;
+pub const ZigClangType_RValueReference = enum_ZigClangTypeClass.ZigClangType_RValueReference;
+pub const ZigClangType_MemberPointer = enum_ZigClangTypeClass.ZigClangType_MemberPointer;
+pub const ZigClangType_ConstantArray = enum_ZigClangTypeClass.ZigClangType_ConstantArray;
+pub const ZigClangType_IncompleteArray = enum_ZigClangTypeClass.ZigClangType_IncompleteArray;
+pub const ZigClangType_VariableArray = enum_ZigClangTypeClass.ZigClangType_VariableArray;
+pub const ZigClangType_DependentSizedArray = enum_ZigClangTypeClass.ZigClangType_DependentSizedArray;
+pub const ZigClangType_DependentSizedExtVector = enum_ZigClangTypeClass.ZigClangType_DependentSizedExtVector;
+pub const ZigClangType_DependentAddressSpace = enum_ZigClangTypeClass.ZigClangType_DependentAddressSpace;
+pub const ZigClangType_Vector = enum_ZigClangTypeClass.ZigClangType_Vector;
+pub const ZigClangType_DependentVector = enum_ZigClangTypeClass.ZigClangType_DependentVector;
+pub const ZigClangType_ExtVector = enum_ZigClangTypeClass.ZigClangType_ExtVector;
+pub const ZigClangType_FunctionProto = enum_ZigClangTypeClass.ZigClangType_FunctionProto;
+pub const ZigClangType_FunctionNoProto = enum_ZigClangTypeClass.ZigClangType_FunctionNoProto;
+pub const ZigClangType_UnresolvedUsing = enum_ZigClangTypeClass.ZigClangType_UnresolvedUsing;
+pub const ZigClangType_Paren = enum_ZigClangTypeClass.ZigClangType_Paren;
+pub const ZigClangType_Typedef = enum_ZigClangTypeClass.ZigClangType_Typedef;
+pub const ZigClangType_Adjusted = enum_ZigClangTypeClass.ZigClangType_Adjusted;
+pub const ZigClangType_Decayed = enum_ZigClangTypeClass.ZigClangType_Decayed;
+pub const ZigClangType_TypeOfExpr = enum_ZigClangTypeClass.ZigClangType_TypeOfExpr;
+pub const ZigClangType_TypeOf = enum_ZigClangTypeClass.ZigClangType_TypeOf;
+pub const ZigClangType_Decltype = enum_ZigClangTypeClass.ZigClangType_Decltype;
+pub const ZigClangType_UnaryTransform = enum_ZigClangTypeClass.ZigClangType_UnaryTransform;
+pub const ZigClangType_Record = enum_ZigClangTypeClass.ZigClangType_Record;
+pub const ZigClangType_Enum = enum_ZigClangTypeClass.ZigClangType_Enum;
+pub const ZigClangType_Elaborated = enum_ZigClangTypeClass.ZigClangType_Elaborated;
+pub const ZigClangType_Attributed = enum_ZigClangTypeClass.ZigClangType_Attributed;
+pub const ZigClangType_TemplateTypeParm = enum_ZigClangTypeClass.ZigClangType_TemplateTypeParm;
+pub const ZigClangType_SubstTemplateTypeParm = enum_ZigClangTypeClass.ZigClangType_SubstTemplateTypeParm;
+pub const ZigClangType_SubstTemplateTypeParmPack = enum_ZigClangTypeClass.ZigClangType_SubstTemplateTypeParmPack;
+pub const ZigClangType_TemplateSpecialization = enum_ZigClangTypeClass.ZigClangType_TemplateSpecialization;
+pub const ZigClangType_Auto = enum_ZigClangTypeClass.ZigClangType_Auto;
+pub const ZigClangType_DeducedTemplateSpecialization = enum_ZigClangTypeClass.ZigClangType_DeducedTemplateSpecialization;
+pub const ZigClangType_InjectedClassName = enum_ZigClangTypeClass.ZigClangType_InjectedClassName;
+pub const ZigClangType_DependentName = enum_ZigClangTypeClass.ZigClangType_DependentName;
+pub const ZigClangType_DependentTemplateSpecialization = enum_ZigClangTypeClass.ZigClangType_DependentTemplateSpecialization;
+pub const ZigClangType_PackExpansion = enum_ZigClangTypeClass.ZigClangType_PackExpansion;
+pub const ZigClangType_ObjCTypeParam = enum_ZigClangTypeClass.ZigClangType_ObjCTypeParam;
+pub const ZigClangType_ObjCObject = enum_ZigClangTypeClass.ZigClangType_ObjCObject;
+pub const ZigClangType_ObjCInterface = enum_ZigClangTypeClass.ZigClangType_ObjCInterface;
+pub const ZigClangType_ObjCObjectPointer = enum_ZigClangTypeClass.ZigClangType_ObjCObjectPointer;
+pub const ZigClangType_Pipe = enum_ZigClangTypeClass.ZigClangType_Pipe;
+pub const ZigClangType_Atomic = enum_ZigClangTypeClass.ZigClangType_Atomic;
+pub const enum_ZigClangTypeClass = extern enum {
+ ZigClangType_Builtin,
+ ZigClangType_Complex,
+ ZigClangType_Pointer,
+ ZigClangType_BlockPointer,
+ ZigClangType_LValueReference,
+ ZigClangType_RValueReference,
+ ZigClangType_MemberPointer,
+ ZigClangType_ConstantArray,
+ ZigClangType_IncompleteArray,
+ ZigClangType_VariableArray,
+ ZigClangType_DependentSizedArray,
+ ZigClangType_DependentSizedExtVector,
+ ZigClangType_DependentAddressSpace,
+ ZigClangType_Vector,
+ ZigClangType_DependentVector,
+ ZigClangType_ExtVector,
+ ZigClangType_FunctionProto,
+ ZigClangType_FunctionNoProto,
+ ZigClangType_UnresolvedUsing,
+ ZigClangType_Paren,
+ ZigClangType_Typedef,
+ ZigClangType_Adjusted,
+ ZigClangType_Decayed,
+ ZigClangType_TypeOfExpr,
+ ZigClangType_TypeOf,
+ ZigClangType_Decltype,
+ ZigClangType_UnaryTransform,
+ ZigClangType_Record,
+ ZigClangType_Enum,
+ ZigClangType_Elaborated,
+ ZigClangType_Attributed,
+ ZigClangType_TemplateTypeParm,
+ ZigClangType_SubstTemplateTypeParm,
+ ZigClangType_SubstTemplateTypeParmPack,
+ ZigClangType_TemplateSpecialization,
+ ZigClangType_Auto,
+ ZigClangType_DeducedTemplateSpecialization,
+ ZigClangType_InjectedClassName,
+ ZigClangType_DependentName,
+ ZigClangType_DependentTemplateSpecialization,
+ ZigClangType_PackExpansion,
+ ZigClangType_ObjCTypeParam,
+ ZigClangType_ObjCObject,
+ ZigClangType_ObjCInterface,
+ ZigClangType_ObjCObjectPointer,
+ ZigClangType_Pipe,
+ ZigClangType_Atomic,
+};
+pub const ZigClangStmt_NoStmtClass = enum_ZigClangStmtClass.ZigClangStmt_NoStmtClass;
+pub const ZigClangStmt_GCCAsmStmtClass = enum_ZigClangStmtClass.ZigClangStmt_GCCAsmStmtClass;
+pub const ZigClangStmt_MSAsmStmtClass = enum_ZigClangStmtClass.ZigClangStmt_MSAsmStmtClass;
+pub const ZigClangStmt_AttributedStmtClass = enum_ZigClangStmtClass.ZigClangStmt_AttributedStmtClass;
+pub const ZigClangStmt_BreakStmtClass = enum_ZigClangStmtClass.ZigClangStmt_BreakStmtClass;
+pub const ZigClangStmt_CXXCatchStmtClass = enum_ZigClangStmtClass.ZigClangStmt_CXXCatchStmtClass;
+pub const ZigClangStmt_CXXForRangeStmtClass = enum_ZigClangStmtClass.ZigClangStmt_CXXForRangeStmtClass;
+pub const ZigClangStmt_CXXTryStmtClass = enum_ZigClangStmtClass.ZigClangStmt_CXXTryStmtClass;
+pub const ZigClangStmt_CapturedStmtClass = enum_ZigClangStmtClass.ZigClangStmt_CapturedStmtClass;
+pub const ZigClangStmt_CompoundStmtClass = enum_ZigClangStmtClass.ZigClangStmt_CompoundStmtClass;
+pub const ZigClangStmt_ContinueStmtClass = enum_ZigClangStmtClass.ZigClangStmt_ContinueStmtClass;
+pub const ZigClangStmt_CoreturnStmtClass = enum_ZigClangStmtClass.ZigClangStmt_CoreturnStmtClass;
+pub const ZigClangStmt_CoroutineBodyStmtClass = enum_ZigClangStmtClass.ZigClangStmt_CoroutineBodyStmtClass;
+pub const ZigClangStmt_DeclStmtClass = enum_ZigClangStmtClass.ZigClangStmt_DeclStmtClass;
+pub const ZigClangStmt_DoStmtClass = enum_ZigClangStmtClass.ZigClangStmt_DoStmtClass;
+pub const ZigClangStmt_BinaryConditionalOperatorClass = enum_ZigClangStmtClass.ZigClangStmt_BinaryConditionalOperatorClass;
+pub const ZigClangStmt_ConditionalOperatorClass = enum_ZigClangStmtClass.ZigClangStmt_ConditionalOperatorClass;
+pub const ZigClangStmt_AddrLabelExprClass = enum_ZigClangStmtClass.ZigClangStmt_AddrLabelExprClass;
+pub const ZigClangStmt_ArrayInitIndexExprClass = enum_ZigClangStmtClass.ZigClangStmt_ArrayInitIndexExprClass;
+pub const ZigClangStmt_ArrayInitLoopExprClass = enum_ZigClangStmtClass.ZigClangStmt_ArrayInitLoopExprClass;
+pub const ZigClangStmt_ArraySubscriptExprClass = enum_ZigClangStmtClass.ZigClangStmt_ArraySubscriptExprClass;
+pub const ZigClangStmt_ArrayTypeTraitExprClass = enum_ZigClangStmtClass.ZigClangStmt_ArrayTypeTraitExprClass;
+pub const ZigClangStmt_AsTypeExprClass = enum_ZigClangStmtClass.ZigClangStmt_AsTypeExprClass;
+pub const ZigClangStmt_AtomicExprClass = enum_ZigClangStmtClass.ZigClangStmt_AtomicExprClass;
+pub const ZigClangStmt_BinaryOperatorClass = enum_ZigClangStmtClass.ZigClangStmt_BinaryOperatorClass;
+pub const ZigClangStmt_CompoundAssignOperatorClass = enum_ZigClangStmtClass.ZigClangStmt_CompoundAssignOperatorClass;
+pub const ZigClangStmt_BlockExprClass = enum_ZigClangStmtClass.ZigClangStmt_BlockExprClass;
+pub const ZigClangStmt_CXXBindTemporaryExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXBindTemporaryExprClass;
+pub const ZigClangStmt_CXXBoolLiteralExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXBoolLiteralExprClass;
+pub const ZigClangStmt_CXXConstructExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXConstructExprClass;
+pub const ZigClangStmt_CXXTemporaryObjectExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXTemporaryObjectExprClass;
+pub const ZigClangStmt_CXXDefaultArgExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXDefaultArgExprClass;
+pub const ZigClangStmt_CXXDefaultInitExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXDefaultInitExprClass;
+pub const ZigClangStmt_CXXDeleteExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXDeleteExprClass;
+pub const ZigClangStmt_CXXDependentScopeMemberExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXDependentScopeMemberExprClass;
+pub const ZigClangStmt_CXXFoldExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXFoldExprClass;
+pub const ZigClangStmt_CXXInheritedCtorInitExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXInheritedCtorInitExprClass;
+pub const ZigClangStmt_CXXNewExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXNewExprClass;
+pub const ZigClangStmt_CXXNoexceptExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXNoexceptExprClass;
+pub const ZigClangStmt_CXXNullPtrLiteralExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXNullPtrLiteralExprClass;
+pub const ZigClangStmt_CXXPseudoDestructorExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXPseudoDestructorExprClass;
+pub const ZigClangStmt_CXXScalarValueInitExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXScalarValueInitExprClass;
+pub const ZigClangStmt_CXXStdInitializerListExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXStdInitializerListExprClass;
+pub const ZigClangStmt_CXXThisExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXThisExprClass;
+pub const ZigClangStmt_CXXThrowExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXThrowExprClass;
+pub const ZigClangStmt_CXXTypeidExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXTypeidExprClass;
+pub const ZigClangStmt_CXXUnresolvedConstructExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXUnresolvedConstructExprClass;
+pub const ZigClangStmt_CXXUuidofExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXUuidofExprClass;
+pub const ZigClangStmt_CallExprClass = enum_ZigClangStmtClass.ZigClangStmt_CallExprClass;
+pub const ZigClangStmt_CUDAKernelCallExprClass = enum_ZigClangStmtClass.ZigClangStmt_CUDAKernelCallExprClass;
+pub const ZigClangStmt_CXXMemberCallExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXMemberCallExprClass;
+pub const ZigClangStmt_CXXOperatorCallExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXOperatorCallExprClass;
+pub const ZigClangStmt_UserDefinedLiteralClass = enum_ZigClangStmtClass.ZigClangStmt_UserDefinedLiteralClass;
+pub const ZigClangStmt_CStyleCastExprClass = enum_ZigClangStmtClass.ZigClangStmt_CStyleCastExprClass;
+pub const ZigClangStmt_CXXFunctionalCastExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXFunctionalCastExprClass;
+pub const ZigClangStmt_CXXConstCastExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXConstCastExprClass;
+pub const ZigClangStmt_CXXDynamicCastExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXDynamicCastExprClass;
+pub const ZigClangStmt_CXXReinterpretCastExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXReinterpretCastExprClass;
+pub const ZigClangStmt_CXXStaticCastExprClass = enum_ZigClangStmtClass.ZigClangStmt_CXXStaticCastExprClass;
+pub const ZigClangStmt_ObjCBridgedCastExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCBridgedCastExprClass;
+pub const ZigClangStmt_ImplicitCastExprClass = enum_ZigClangStmtClass.ZigClangStmt_ImplicitCastExprClass;
+pub const ZigClangStmt_CharacterLiteralClass = enum_ZigClangStmtClass.ZigClangStmt_CharacterLiteralClass;
+pub const ZigClangStmt_ChooseExprClass = enum_ZigClangStmtClass.ZigClangStmt_ChooseExprClass;
+pub const ZigClangStmt_CompoundLiteralExprClass = enum_ZigClangStmtClass.ZigClangStmt_CompoundLiteralExprClass;
+pub const ZigClangStmt_ConvertVectorExprClass = enum_ZigClangStmtClass.ZigClangStmt_ConvertVectorExprClass;
+pub const ZigClangStmt_CoawaitExprClass = enum_ZigClangStmtClass.ZigClangStmt_CoawaitExprClass;
+pub const ZigClangStmt_CoyieldExprClass = enum_ZigClangStmtClass.ZigClangStmt_CoyieldExprClass;
+pub const ZigClangStmt_DeclRefExprClass = enum_ZigClangStmtClass.ZigClangStmt_DeclRefExprClass;
+pub const ZigClangStmt_DependentCoawaitExprClass = enum_ZigClangStmtClass.ZigClangStmt_DependentCoawaitExprClass;
+pub const ZigClangStmt_DependentScopeDeclRefExprClass = enum_ZigClangStmtClass.ZigClangStmt_DependentScopeDeclRefExprClass;
+pub const ZigClangStmt_DesignatedInitExprClass = enum_ZigClangStmtClass.ZigClangStmt_DesignatedInitExprClass;
+pub const ZigClangStmt_DesignatedInitUpdateExprClass = enum_ZigClangStmtClass.ZigClangStmt_DesignatedInitUpdateExprClass;
+pub const ZigClangStmt_ExpressionTraitExprClass = enum_ZigClangStmtClass.ZigClangStmt_ExpressionTraitExprClass;
+pub const ZigClangStmt_ExtVectorElementExprClass = enum_ZigClangStmtClass.ZigClangStmt_ExtVectorElementExprClass;
+pub const ZigClangStmt_FixedPointLiteralClass = enum_ZigClangStmtClass.ZigClangStmt_FixedPointLiteralClass;
+pub const ZigClangStmt_FloatingLiteralClass = enum_ZigClangStmtClass.ZigClangStmt_FloatingLiteralClass;
+pub const ZigClangStmt_ConstantExprClass = enum_ZigClangStmtClass.ZigClangStmt_ConstantExprClass;
+pub const ZigClangStmt_ExprWithCleanupsClass = enum_ZigClangStmtClass.ZigClangStmt_ExprWithCleanupsClass;
+pub const ZigClangStmt_FunctionParmPackExprClass = enum_ZigClangStmtClass.ZigClangStmt_FunctionParmPackExprClass;
+pub const ZigClangStmt_GNUNullExprClass = enum_ZigClangStmtClass.ZigClangStmt_GNUNullExprClass;
+pub const ZigClangStmt_GenericSelectionExprClass = enum_ZigClangStmtClass.ZigClangStmt_GenericSelectionExprClass;
+pub const ZigClangStmt_ImaginaryLiteralClass = enum_ZigClangStmtClass.ZigClangStmt_ImaginaryLiteralClass;
+pub const ZigClangStmt_ImplicitValueInitExprClass = enum_ZigClangStmtClass.ZigClangStmt_ImplicitValueInitExprClass;
+pub const ZigClangStmt_InitListExprClass = enum_ZigClangStmtClass.ZigClangStmt_InitListExprClass;
+pub const ZigClangStmt_IntegerLiteralClass = enum_ZigClangStmtClass.ZigClangStmt_IntegerLiteralClass;
+pub const ZigClangStmt_LambdaExprClass = enum_ZigClangStmtClass.ZigClangStmt_LambdaExprClass;
+pub const ZigClangStmt_MSPropertyRefExprClass = enum_ZigClangStmtClass.ZigClangStmt_MSPropertyRefExprClass;
+pub const ZigClangStmt_MSPropertySubscriptExprClass = enum_ZigClangStmtClass.ZigClangStmt_MSPropertySubscriptExprClass;
+pub const ZigClangStmt_MaterializeTemporaryExprClass = enum_ZigClangStmtClass.ZigClangStmt_MaterializeTemporaryExprClass;
+pub const ZigClangStmt_MemberExprClass = enum_ZigClangStmtClass.ZigClangStmt_MemberExprClass;
+pub const ZigClangStmt_NoInitExprClass = enum_ZigClangStmtClass.ZigClangStmt_NoInitExprClass;
+pub const ZigClangStmt_OMPArraySectionExprClass = enum_ZigClangStmtClass.ZigClangStmt_OMPArraySectionExprClass;
+pub const ZigClangStmt_ObjCArrayLiteralClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCArrayLiteralClass;
+pub const ZigClangStmt_ObjCAvailabilityCheckExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCAvailabilityCheckExprClass;
+pub const ZigClangStmt_ObjCBoolLiteralExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCBoolLiteralExprClass;
+pub const ZigClangStmt_ObjCBoxedExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCBoxedExprClass;
+pub const ZigClangStmt_ObjCDictionaryLiteralClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCDictionaryLiteralClass;
+pub const ZigClangStmt_ObjCEncodeExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCEncodeExprClass;
+pub const ZigClangStmt_ObjCIndirectCopyRestoreExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCIndirectCopyRestoreExprClass;
+pub const ZigClangStmt_ObjCIsaExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCIsaExprClass;
+pub const ZigClangStmt_ObjCIvarRefExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCIvarRefExprClass;
+pub const ZigClangStmt_ObjCMessageExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCMessageExprClass;
+pub const ZigClangStmt_ObjCPropertyRefExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCPropertyRefExprClass;
+pub const ZigClangStmt_ObjCProtocolExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCProtocolExprClass;
+pub const ZigClangStmt_ObjCSelectorExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCSelectorExprClass;
+pub const ZigClangStmt_ObjCStringLiteralClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCStringLiteralClass;
+pub const ZigClangStmt_ObjCSubscriptRefExprClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCSubscriptRefExprClass;
+pub const ZigClangStmt_OffsetOfExprClass = enum_ZigClangStmtClass.ZigClangStmt_OffsetOfExprClass;
+pub const ZigClangStmt_OpaqueValueExprClass = enum_ZigClangStmtClass.ZigClangStmt_OpaqueValueExprClass;
+pub const ZigClangStmt_UnresolvedLookupExprClass = enum_ZigClangStmtClass.ZigClangStmt_UnresolvedLookupExprClass;
+pub const ZigClangStmt_UnresolvedMemberExprClass = enum_ZigClangStmtClass.ZigClangStmt_UnresolvedMemberExprClass;
+pub const ZigClangStmt_PackExpansionExprClass = enum_ZigClangStmtClass.ZigClangStmt_PackExpansionExprClass;
+pub const ZigClangStmt_ParenExprClass = enum_ZigClangStmtClass.ZigClangStmt_ParenExprClass;
+pub const ZigClangStmt_ParenListExprClass = enum_ZigClangStmtClass.ZigClangStmt_ParenListExprClass;
+pub const ZigClangStmt_PredefinedExprClass = enum_ZigClangStmtClass.ZigClangStmt_PredefinedExprClass;
+pub const ZigClangStmt_PseudoObjectExprClass = enum_ZigClangStmtClass.ZigClangStmt_PseudoObjectExprClass;
+pub const ZigClangStmt_ShuffleVectorExprClass = enum_ZigClangStmtClass.ZigClangStmt_ShuffleVectorExprClass;
+pub const ZigClangStmt_SizeOfPackExprClass = enum_ZigClangStmtClass.ZigClangStmt_SizeOfPackExprClass;
+pub const ZigClangStmt_StmtExprClass = enum_ZigClangStmtClass.ZigClangStmt_StmtExprClass;
+pub const ZigClangStmt_StringLiteralClass = enum_ZigClangStmtClass.ZigClangStmt_StringLiteralClass;
+pub const ZigClangStmt_SubstNonTypeTemplateParmExprClass = enum_ZigClangStmtClass.ZigClangStmt_SubstNonTypeTemplateParmExprClass;
+pub const ZigClangStmt_SubstNonTypeTemplateParmPackExprClass = enum_ZigClangStmtClass.ZigClangStmt_SubstNonTypeTemplateParmPackExprClass;
+pub const ZigClangStmt_TypeTraitExprClass = enum_ZigClangStmtClass.ZigClangStmt_TypeTraitExprClass;
+pub const ZigClangStmt_TypoExprClass = enum_ZigClangStmtClass.ZigClangStmt_TypoExprClass;
+pub const ZigClangStmt_UnaryExprOrTypeTraitExprClass = enum_ZigClangStmtClass.ZigClangStmt_UnaryExprOrTypeTraitExprClass;
+pub const ZigClangStmt_UnaryOperatorClass = enum_ZigClangStmtClass.ZigClangStmt_UnaryOperatorClass;
+pub const ZigClangStmt_VAArgExprClass = enum_ZigClangStmtClass.ZigClangStmt_VAArgExprClass;
+pub const ZigClangStmt_ForStmtClass = enum_ZigClangStmtClass.ZigClangStmt_ForStmtClass;
+pub const ZigClangStmt_GotoStmtClass = enum_ZigClangStmtClass.ZigClangStmt_GotoStmtClass;
+pub const ZigClangStmt_IfStmtClass = enum_ZigClangStmtClass.ZigClangStmt_IfStmtClass;
+pub const ZigClangStmt_IndirectGotoStmtClass = enum_ZigClangStmtClass.ZigClangStmt_IndirectGotoStmtClass;
+pub const ZigClangStmt_LabelStmtClass = enum_ZigClangStmtClass.ZigClangStmt_LabelStmtClass;
+pub const ZigClangStmt_MSDependentExistsStmtClass = enum_ZigClangStmtClass.ZigClangStmt_MSDependentExistsStmtClass;
+pub const ZigClangStmt_NullStmtClass = enum_ZigClangStmtClass.ZigClangStmt_NullStmtClass;
+pub const ZigClangStmt_OMPAtomicDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPAtomicDirectiveClass;
+pub const ZigClangStmt_OMPBarrierDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPBarrierDirectiveClass;
+pub const ZigClangStmt_OMPCancelDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPCancelDirectiveClass;
+pub const ZigClangStmt_OMPCancellationPointDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPCancellationPointDirectiveClass;
+pub const ZigClangStmt_OMPCriticalDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPCriticalDirectiveClass;
+pub const ZigClangStmt_OMPFlushDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPFlushDirectiveClass;
+pub const ZigClangStmt_OMPDistributeDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPDistributeDirectiveClass;
+pub const ZigClangStmt_OMPDistributeParallelForDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPDistributeParallelForDirectiveClass;
+pub const ZigClangStmt_OMPDistributeParallelForSimdDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPDistributeParallelForSimdDirectiveClass;
+pub const ZigClangStmt_OMPDistributeSimdDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPDistributeSimdDirectiveClass;
+pub const ZigClangStmt_OMPForDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPForDirectiveClass;
+pub const ZigClangStmt_OMPForSimdDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPForSimdDirectiveClass;
+pub const ZigClangStmt_OMPParallelForDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPParallelForDirectiveClass;
+pub const ZigClangStmt_OMPParallelForSimdDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPParallelForSimdDirectiveClass;
+pub const ZigClangStmt_OMPSimdDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPSimdDirectiveClass;
+pub const ZigClangStmt_OMPTargetParallelForSimdDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetParallelForSimdDirectiveClass;
+pub const ZigClangStmt_OMPTargetSimdDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetSimdDirectiveClass;
+pub const ZigClangStmt_OMPTargetTeamsDistributeDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetTeamsDistributeDirectiveClass;
+pub const ZigClangStmt_OMPTargetTeamsDistributeParallelForDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetTeamsDistributeParallelForDirectiveClass;
+pub const ZigClangStmt_OMPTargetTeamsDistributeParallelForSimdDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetTeamsDistributeParallelForSimdDirectiveClass;
+pub const ZigClangStmt_OMPTargetTeamsDistributeSimdDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetTeamsDistributeSimdDirectiveClass;
+pub const ZigClangStmt_OMPTaskLoopDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTaskLoopDirectiveClass;
+pub const ZigClangStmt_OMPTaskLoopSimdDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTaskLoopSimdDirectiveClass;
+pub const ZigClangStmt_OMPTeamsDistributeDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTeamsDistributeDirectiveClass;
+pub const ZigClangStmt_OMPTeamsDistributeParallelForDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTeamsDistributeParallelForDirectiveClass;
+pub const ZigClangStmt_OMPTeamsDistributeParallelForSimdDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTeamsDistributeParallelForSimdDirectiveClass;
+pub const ZigClangStmt_OMPTeamsDistributeSimdDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTeamsDistributeSimdDirectiveClass;
+pub const ZigClangStmt_OMPMasterDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPMasterDirectiveClass;
+pub const ZigClangStmt_OMPOrderedDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPOrderedDirectiveClass;
+pub const ZigClangStmt_OMPParallelDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPParallelDirectiveClass;
+pub const ZigClangStmt_OMPParallelSectionsDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPParallelSectionsDirectiveClass;
+pub const ZigClangStmt_OMPSectionDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPSectionDirectiveClass;
+pub const ZigClangStmt_OMPSectionsDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPSectionsDirectiveClass;
+pub const ZigClangStmt_OMPSingleDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPSingleDirectiveClass;
+pub const ZigClangStmt_OMPTargetDataDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetDataDirectiveClass;
+pub const ZigClangStmt_OMPTargetDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetDirectiveClass;
+pub const ZigClangStmt_OMPTargetEnterDataDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetEnterDataDirectiveClass;
+pub const ZigClangStmt_OMPTargetExitDataDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetExitDataDirectiveClass;
+pub const ZigClangStmt_OMPTargetParallelDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetParallelDirectiveClass;
+pub const ZigClangStmt_OMPTargetParallelForDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetParallelForDirectiveClass;
+pub const ZigClangStmt_OMPTargetTeamsDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetTeamsDirectiveClass;
+pub const ZigClangStmt_OMPTargetUpdateDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTargetUpdateDirectiveClass;
+pub const ZigClangStmt_OMPTaskDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTaskDirectiveClass;
+pub const ZigClangStmt_OMPTaskgroupDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTaskgroupDirectiveClass;
+pub const ZigClangStmt_OMPTaskwaitDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTaskwaitDirectiveClass;
+pub const ZigClangStmt_OMPTaskyieldDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTaskyieldDirectiveClass;
+pub const ZigClangStmt_OMPTeamsDirectiveClass = enum_ZigClangStmtClass.ZigClangStmt_OMPTeamsDirectiveClass;
+pub const ZigClangStmt_ObjCAtCatchStmtClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCAtCatchStmtClass;
+pub const ZigClangStmt_ObjCAtFinallyStmtClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCAtFinallyStmtClass;
+pub const ZigClangStmt_ObjCAtSynchronizedStmtClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCAtSynchronizedStmtClass;
+pub const ZigClangStmt_ObjCAtThrowStmtClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCAtThrowStmtClass;
+pub const ZigClangStmt_ObjCAtTryStmtClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCAtTryStmtClass;
+pub const ZigClangStmt_ObjCAutoreleasePoolStmtClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCAutoreleasePoolStmtClass;
+pub const ZigClangStmt_ObjCForCollectionStmtClass = enum_ZigClangStmtClass.ZigClangStmt_ObjCForCollectionStmtClass;
+pub const ZigClangStmt_ReturnStmtClass = enum_ZigClangStmtClass.ZigClangStmt_ReturnStmtClass;
+pub const ZigClangStmt_SEHExceptStmtClass = enum_ZigClangStmtClass.ZigClangStmt_SEHExceptStmtClass;
+pub const ZigClangStmt_SEHFinallyStmtClass = enum_ZigClangStmtClass.ZigClangStmt_SEHFinallyStmtClass;
+pub const ZigClangStmt_SEHLeaveStmtClass = enum_ZigClangStmtClass.ZigClangStmt_SEHLeaveStmtClass;
+pub const ZigClangStmt_SEHTryStmtClass = enum_ZigClangStmtClass.ZigClangStmt_SEHTryStmtClass;
+pub const ZigClangStmt_CaseStmtClass = enum_ZigClangStmtClass.ZigClangStmt_CaseStmtClass;
+pub const ZigClangStmt_DefaultStmtClass = enum_ZigClangStmtClass.ZigClangStmt_DefaultStmtClass;
+pub const ZigClangStmt_SwitchStmtClass = enum_ZigClangStmtClass.ZigClangStmt_SwitchStmtClass;
+pub const ZigClangStmt_WhileStmtClass = enum_ZigClangStmtClass.ZigClangStmt_WhileStmtClass;
+pub const enum_ZigClangStmtClass = extern enum {
+ ZigClangStmt_NoStmtClass = 0,
+ ZigClangStmt_GCCAsmStmtClass = 1,
+ ZigClangStmt_MSAsmStmtClass = 2,
+ ZigClangStmt_AttributedStmtClass = 3,
+ ZigClangStmt_BreakStmtClass = 4,
+ ZigClangStmt_CXXCatchStmtClass = 5,
+ ZigClangStmt_CXXForRangeStmtClass = 6,
+ ZigClangStmt_CXXTryStmtClass = 7,
+ ZigClangStmt_CapturedStmtClass = 8,
+ ZigClangStmt_CompoundStmtClass = 9,
+ ZigClangStmt_ContinueStmtClass = 10,
+ ZigClangStmt_CoreturnStmtClass = 11,
+ ZigClangStmt_CoroutineBodyStmtClass = 12,
+ ZigClangStmt_DeclStmtClass = 13,
+ ZigClangStmt_DoStmtClass = 14,
+ ZigClangStmt_BinaryConditionalOperatorClass = 15,
+ ZigClangStmt_ConditionalOperatorClass = 16,
+ ZigClangStmt_AddrLabelExprClass = 17,
+ ZigClangStmt_ArrayInitIndexExprClass = 18,
+ ZigClangStmt_ArrayInitLoopExprClass = 19,
+ ZigClangStmt_ArraySubscriptExprClass = 20,
+ ZigClangStmt_ArrayTypeTraitExprClass = 21,
+ ZigClangStmt_AsTypeExprClass = 22,
+ ZigClangStmt_AtomicExprClass = 23,
+ ZigClangStmt_BinaryOperatorClass = 24,
+ ZigClangStmt_CompoundAssignOperatorClass = 25,
+ ZigClangStmt_BlockExprClass = 26,
+ ZigClangStmt_CXXBindTemporaryExprClass = 27,
+ ZigClangStmt_CXXBoolLiteralExprClass = 28,
+ ZigClangStmt_CXXConstructExprClass = 29,
+ ZigClangStmt_CXXTemporaryObjectExprClass = 30,
+ ZigClangStmt_CXXDefaultArgExprClass = 31,
+ ZigClangStmt_CXXDefaultInitExprClass = 32,
+ ZigClangStmt_CXXDeleteExprClass = 33,
+ ZigClangStmt_CXXDependentScopeMemberExprClass = 34,
+ ZigClangStmt_CXXFoldExprClass = 35,
+ ZigClangStmt_CXXInheritedCtorInitExprClass = 36,
+ ZigClangStmt_CXXNewExprClass = 37,
+ ZigClangStmt_CXXNoexceptExprClass = 38,
+ ZigClangStmt_CXXNullPtrLiteralExprClass = 39,
+ ZigClangStmt_CXXPseudoDestructorExprClass = 40,
+ ZigClangStmt_CXXScalarValueInitExprClass = 41,
+ ZigClangStmt_CXXStdInitializerListExprClass = 42,
+ ZigClangStmt_CXXThisExprClass = 43,
+ ZigClangStmt_CXXThrowExprClass = 44,
+ ZigClangStmt_CXXTypeidExprClass = 45,
+ ZigClangStmt_CXXUnresolvedConstructExprClass = 46,
+ ZigClangStmt_CXXUuidofExprClass = 47,
+ ZigClangStmt_CallExprClass = 48,
+ ZigClangStmt_CUDAKernelCallExprClass = 49,
+ ZigClangStmt_CXXMemberCallExprClass = 50,
+ ZigClangStmt_CXXOperatorCallExprClass = 51,
+ ZigClangStmt_UserDefinedLiteralClass = 52,
+ ZigClangStmt_CStyleCastExprClass = 53,
+ ZigClangStmt_CXXFunctionalCastExprClass = 54,
+ ZigClangStmt_CXXConstCastExprClass = 55,
+ ZigClangStmt_CXXDynamicCastExprClass = 56,
+ ZigClangStmt_CXXReinterpretCastExprClass = 57,
+ ZigClangStmt_CXXStaticCastExprClass = 58,
+ ZigClangStmt_ObjCBridgedCastExprClass = 59,
+ ZigClangStmt_ImplicitCastExprClass = 60,
+ ZigClangStmt_CharacterLiteralClass = 61,
+ ZigClangStmt_ChooseExprClass = 62,
+ ZigClangStmt_CompoundLiteralExprClass = 63,
+ ZigClangStmt_ConvertVectorExprClass = 64,
+ ZigClangStmt_CoawaitExprClass = 65,
+ ZigClangStmt_CoyieldExprClass = 66,
+ ZigClangStmt_DeclRefExprClass = 67,
+ ZigClangStmt_DependentCoawaitExprClass = 68,
+ ZigClangStmt_DependentScopeDeclRefExprClass = 69,
+ ZigClangStmt_DesignatedInitExprClass = 70,
+ ZigClangStmt_DesignatedInitUpdateExprClass = 71,
+ ZigClangStmt_ExpressionTraitExprClass = 72,
+ ZigClangStmt_ExtVectorElementExprClass = 73,
+ ZigClangStmt_FixedPointLiteralClass = 74,
+ ZigClangStmt_FloatingLiteralClass = 75,
+ ZigClangStmt_ConstantExprClass = 76,
+ ZigClangStmt_ExprWithCleanupsClass = 77,
+ ZigClangStmt_FunctionParmPackExprClass = 78,
+ ZigClangStmt_GNUNullExprClass = 79,
+ ZigClangStmt_GenericSelectionExprClass = 80,
+ ZigClangStmt_ImaginaryLiteralClass = 81,
+ ZigClangStmt_ImplicitValueInitExprClass = 82,
+ ZigClangStmt_InitListExprClass = 83,
+ ZigClangStmt_IntegerLiteralClass = 84,
+ ZigClangStmt_LambdaExprClass = 85,
+ ZigClangStmt_MSPropertyRefExprClass = 86,
+ ZigClangStmt_MSPropertySubscriptExprClass = 87,
+ ZigClangStmt_MaterializeTemporaryExprClass = 88,
+ ZigClangStmt_MemberExprClass = 89,
+ ZigClangStmt_NoInitExprClass = 90,
+ ZigClangStmt_OMPArraySectionExprClass = 91,
+ ZigClangStmt_ObjCArrayLiteralClass = 92,
+ ZigClangStmt_ObjCAvailabilityCheckExprClass = 93,
+ ZigClangStmt_ObjCBoolLiteralExprClass = 94,
+ ZigClangStmt_ObjCBoxedExprClass = 95,
+ ZigClangStmt_ObjCDictionaryLiteralClass = 96,
+ ZigClangStmt_ObjCEncodeExprClass = 97,
+ ZigClangStmt_ObjCIndirectCopyRestoreExprClass = 98,
+ ZigClangStmt_ObjCIsaExprClass = 99,
+ ZigClangStmt_ObjCIvarRefExprClass = 100,
+ ZigClangStmt_ObjCMessageExprClass = 101,
+ ZigClangStmt_ObjCPropertyRefExprClass = 102,
+ ZigClangStmt_ObjCProtocolExprClass = 103,
+ ZigClangStmt_ObjCSelectorExprClass = 104,
+ ZigClangStmt_ObjCStringLiteralClass = 105,
+ ZigClangStmt_ObjCSubscriptRefExprClass = 106,
+ ZigClangStmt_OffsetOfExprClass = 107,
+ ZigClangStmt_OpaqueValueExprClass = 108,
+ ZigClangStmt_UnresolvedLookupExprClass = 109,
+ ZigClangStmt_UnresolvedMemberExprClass = 110,
+ ZigClangStmt_PackExpansionExprClass = 111,
+ ZigClangStmt_ParenExprClass = 112,
+ ZigClangStmt_ParenListExprClass = 113,
+ ZigClangStmt_PredefinedExprClass = 114,
+ ZigClangStmt_PseudoObjectExprClass = 115,
+ ZigClangStmt_ShuffleVectorExprClass = 116,
+ ZigClangStmt_SizeOfPackExprClass = 117,
+ ZigClangStmt_StmtExprClass = 118,
+ ZigClangStmt_StringLiteralClass = 119,
+ ZigClangStmt_SubstNonTypeTemplateParmExprClass = 120,
+ ZigClangStmt_SubstNonTypeTemplateParmPackExprClass = 121,
+ ZigClangStmt_TypeTraitExprClass = 122,
+ ZigClangStmt_TypoExprClass = 123,
+ ZigClangStmt_UnaryExprOrTypeTraitExprClass = 124,
+ ZigClangStmt_UnaryOperatorClass = 125,
+ ZigClangStmt_VAArgExprClass = 126,
+ ZigClangStmt_ForStmtClass = 127,
+ ZigClangStmt_GotoStmtClass = 128,
+ ZigClangStmt_IfStmtClass = 129,
+ ZigClangStmt_IndirectGotoStmtClass = 130,
+ ZigClangStmt_LabelStmtClass = 131,
+ ZigClangStmt_MSDependentExistsStmtClass = 132,
+ ZigClangStmt_NullStmtClass = 133,
+ ZigClangStmt_OMPAtomicDirectiveClass = 134,
+ ZigClangStmt_OMPBarrierDirectiveClass = 135,
+ ZigClangStmt_OMPCancelDirectiveClass = 136,
+ ZigClangStmt_OMPCancellationPointDirectiveClass = 137,
+ ZigClangStmt_OMPCriticalDirectiveClass = 138,
+ ZigClangStmt_OMPFlushDirectiveClass = 139,
+ ZigClangStmt_OMPDistributeDirectiveClass = 140,
+ ZigClangStmt_OMPDistributeParallelForDirectiveClass = 141,
+ ZigClangStmt_OMPDistributeParallelForSimdDirectiveClass = 142,
+ ZigClangStmt_OMPDistributeSimdDirectiveClass = 143,
+ ZigClangStmt_OMPForDirectiveClass = 144,
+ ZigClangStmt_OMPForSimdDirectiveClass = 145,
+ ZigClangStmt_OMPParallelForDirectiveClass = 146,
+ ZigClangStmt_OMPParallelForSimdDirectiveClass = 147,
+ ZigClangStmt_OMPSimdDirectiveClass = 148,
+ ZigClangStmt_OMPTargetParallelForSimdDirectiveClass = 149,
+ ZigClangStmt_OMPTargetSimdDirectiveClass = 150,
+ ZigClangStmt_OMPTargetTeamsDistributeDirectiveClass = 151,
+ ZigClangStmt_OMPTargetTeamsDistributeParallelForDirectiveClass = 152,
+ ZigClangStmt_OMPTargetTeamsDistributeParallelForSimdDirectiveClass = 153,
+ ZigClangStmt_OMPTargetTeamsDistributeSimdDirectiveClass = 154,
+ ZigClangStmt_OMPTaskLoopDirectiveClass = 155,
+ ZigClangStmt_OMPTaskLoopSimdDirectiveClass = 156,
+ ZigClangStmt_OMPTeamsDistributeDirectiveClass = 157,
+ ZigClangStmt_OMPTeamsDistributeParallelForDirectiveClass = 158,
+ ZigClangStmt_OMPTeamsDistributeParallelForSimdDirectiveClass = 159,
+ ZigClangStmt_OMPTeamsDistributeSimdDirectiveClass = 160,
+ ZigClangStmt_OMPMasterDirectiveClass = 161,
+ ZigClangStmt_OMPOrderedDirectiveClass = 162,
+ ZigClangStmt_OMPParallelDirectiveClass = 163,
+ ZigClangStmt_OMPParallelSectionsDirectiveClass = 164,
+ ZigClangStmt_OMPSectionDirectiveClass = 165,
+ ZigClangStmt_OMPSectionsDirectiveClass = 166,
+ ZigClangStmt_OMPSingleDirectiveClass = 167,
+ ZigClangStmt_OMPTargetDataDirectiveClass = 168,
+ ZigClangStmt_OMPTargetDirectiveClass = 169,
+ ZigClangStmt_OMPTargetEnterDataDirectiveClass = 170,
+ ZigClangStmt_OMPTargetExitDataDirectiveClass = 171,
+ ZigClangStmt_OMPTargetParallelDirectiveClass = 172,
+ ZigClangStmt_OMPTargetParallelForDirectiveClass = 173,
+ ZigClangStmt_OMPTargetTeamsDirectiveClass = 174,
+ ZigClangStmt_OMPTargetUpdateDirectiveClass = 175,
+ ZigClangStmt_OMPTaskDirectiveClass = 176,
+ ZigClangStmt_OMPTaskgroupDirectiveClass = 177,
+ ZigClangStmt_OMPTaskwaitDirectiveClass = 178,
+ ZigClangStmt_OMPTaskyieldDirectiveClass = 179,
+ ZigClangStmt_OMPTeamsDirectiveClass = 180,
+ ZigClangStmt_ObjCAtCatchStmtClass = 181,
+ ZigClangStmt_ObjCAtFinallyStmtClass = 182,
+ ZigClangStmt_ObjCAtSynchronizedStmtClass = 183,
+ ZigClangStmt_ObjCAtThrowStmtClass = 184,
+ ZigClangStmt_ObjCAtTryStmtClass = 185,
+ ZigClangStmt_ObjCAutoreleasePoolStmtClass = 186,
+ ZigClangStmt_ObjCForCollectionStmtClass = 187,
+ ZigClangStmt_ReturnStmtClass = 188,
+ ZigClangStmt_SEHExceptStmtClass = 189,
+ ZigClangStmt_SEHFinallyStmtClass = 190,
+ ZigClangStmt_SEHLeaveStmtClass = 191,
+ ZigClangStmt_SEHTryStmtClass = 192,
+ ZigClangStmt_CaseStmtClass = 193,
+ ZigClangStmt_DefaultStmtClass = 194,
+ ZigClangStmt_SwitchStmtClass = 195,
+ ZigClangStmt_WhileStmtClass = 196,
+};
+pub const ZigClangCK_Dependent = enum_ZigClangCK._Dependent;
+pub const ZigClangCK_BitCast = enum_ZigClangCK._BitCast;
+pub const ZigClangCK_LValueBitCast = enum_ZigClangCK._LValueBitCast;
+pub const ZigClangCK_LValueToRValue = enum_ZigClangCK._LValueToRValue;
+pub const ZigClangCK_NoOp = enum_ZigClangCK._NoOp;
+pub const ZigClangCK_BaseToDerived = enum_ZigClangCK._BaseToDerived;
+pub const ZigClangCK_DerivedToBase = enum_ZigClangCK._DerivedToBase;
+pub const ZigClangCK_UncheckedDerivedToBase = enum_ZigClangCK._UncheckedDerivedToBase;
+pub const ZigClangCK_Dynamic = enum_ZigClangCK._Dynamic;
+pub const ZigClangCK_ToUnion = enum_ZigClangCK._ToUnion;
+pub const ZigClangCK_ArrayToPointerDecay = enum_ZigClangCK._ArrayToPointerDecay;
+pub const ZigClangCK_FunctionToPointerDecay = enum_ZigClangCK._FunctionToPointerDecay;
+pub const ZigClangCK_NullToPointer = enum_ZigClangCK._NullToPointer;
+pub const ZigClangCK_NullToMemberPointer = enum_ZigClangCK._NullToMemberPointer;
+pub const ZigClangCK_BaseToDerivedMemberPointer = enum_ZigClangCK._BaseToDerivedMemberPointer;
+pub const ZigClangCK_DerivedToBaseMemberPointer = enum_ZigClangCK._DerivedToBaseMemberPointer;
+pub const ZigClangCK_MemberPointerToBoolean = enum_ZigClangCK._MemberPointerToBoolean;
+pub const ZigClangCK_ReinterpretMemberPointer = enum_ZigClangCK._ReinterpretMemberPointer;
+pub const ZigClangCK_UserDefinedConversion = enum_ZigClangCK._UserDefinedConversion;
+pub const ZigClangCK_ConstructorConversion = enum_ZigClangCK._ConstructorConversion;
+pub const ZigClangCK_IntegralToPointer = enum_ZigClangCK._IntegralToPointer;
+pub const ZigClangCK_PointerToIntegral = enum_ZigClangCK._PointerToIntegral;
+pub const ZigClangCK_PointerToBoolean = enum_ZigClangCK._PointerToBoolean;
+pub const ZigClangCK_ToVoid = enum_ZigClangCK._ToVoid;
+pub const ZigClangCK_VectorSplat = enum_ZigClangCK._VectorSplat;
+pub const ZigClangCK_IntegralCast = enum_ZigClangCK._IntegralCast;
+pub const ZigClangCK_IntegralToBoolean = enum_ZigClangCK._IntegralToBoolean;
+pub const ZigClangCK_IntegralToFloating = enum_ZigClangCK._IntegralToFloating;
+pub const ZigClangCK_FixedPointCast = enum_ZigClangCK._FixedPointCast;
+pub const ZigClangCK_FixedPointToBoolean = enum_ZigClangCK._FixedPointToBoolean;
+pub const ZigClangCK_FloatingToIntegral = enum_ZigClangCK._FloatingToIntegral;
+pub const ZigClangCK_FloatingToBoolean = enum_ZigClangCK._FloatingToBoolean;
+pub const ZigClangCK_BooleanToSignedIntegral = enum_ZigClangCK._BooleanToSignedIntegral;
+pub const ZigClangCK_FloatingCast = enum_ZigClangCK._FloatingCast;
+pub const ZigClangCK_CPointerToObjCPointerCast = enum_ZigClangCK._CPointerToObjCPointerCast;
+pub const ZigClangCK_BlockPointerToObjCPointerCast = enum_ZigClangCK._BlockPointerToObjCPointerCast;
+pub const ZigClangCK_AnyPointerToBlockPointerCast = enum_ZigClangCK._AnyPointerToBlockPointerCast;
+pub const ZigClangCK_ObjCObjectLValueCast = enum_ZigClangCK._ObjCObjectLValueCast;
+pub const ZigClangCK_FloatingRealToComplex = enum_ZigClangCK._FloatingRealToComplex;
+pub const ZigClangCK_FloatingComplexToReal = enum_ZigClangCK._FloatingComplexToReal;
+pub const ZigClangCK_FloatingComplexToBoolean = enum_ZigClangCK._FloatingComplexToBoolean;
+pub const ZigClangCK_FloatingComplexCast = enum_ZigClangCK._FloatingComplexCast;
+pub const ZigClangCK_FloatingComplexToIntegralComplex = enum_ZigClangCK._FloatingComplexToIntegralComplex;
+pub const ZigClangCK_IntegralRealToComplex = enum_ZigClangCK._IntegralRealToComplex;
+pub const ZigClangCK_IntegralComplexToReal = enum_ZigClangCK._IntegralComplexToReal;
+pub const ZigClangCK_IntegralComplexToBoolean = enum_ZigClangCK._IntegralComplexToBoolean;
+pub const ZigClangCK_IntegralComplexCast = enum_ZigClangCK._IntegralComplexCast;
+pub const ZigClangCK_IntegralComplexToFloatingComplex = enum_ZigClangCK._IntegralComplexToFloatingComplex;
+pub const ZigClangCK_ARCProduceObject = enum_ZigClangCK._ARCProduceObject;
+pub const ZigClangCK_ARCConsumeObject = enum_ZigClangCK._ARCConsumeObject;
+pub const ZigClangCK_ARCReclaimReturnedObject = enum_ZigClangCK._ARCReclaimReturnedObject;
+pub const ZigClangCK_ARCExtendBlockObject = enum_ZigClangCK._ARCExtendBlockObject;
+pub const ZigClangCK_AtomicToNonAtomic = enum_ZigClangCK._AtomicToNonAtomic;
+pub const ZigClangCK_NonAtomicToAtomic = enum_ZigClangCK._NonAtomicToAtomic;
+pub const ZigClangCK_CopyAndAutoreleaseBlockObject = enum_ZigClangCK._CopyAndAutoreleaseBlockObject;
+pub const ZigClangCK_BuiltinFnToFnPtr = enum_ZigClangCK._BuiltinFnToFnPtr;
+pub const ZigClangCK_ZeroToOCLOpaqueType = enum_ZigClangCK._ZeroToOCLOpaqueType;
+pub const ZigClangCK_AddressSpaceConversion = enum_ZigClangCK._AddressSpaceConversion;
+pub const ZigClangCK_IntToOCLSampler = enum_ZigClangCK._IntToOCLSampler;
+pub const enum_ZigClangCK = extern enum {
+ _Dependent,
+ _BitCast,
+ _LValueBitCast,
+ _LValueToRValue,
+ _NoOp,
+ _BaseToDerived,
+ _DerivedToBase,
+ _UncheckedDerivedToBase,
+ _Dynamic,
+ _ToUnion,
+ _ArrayToPointerDecay,
+ _FunctionToPointerDecay,
+ _NullToPointer,
+ _NullToMemberPointer,
+ _BaseToDerivedMemberPointer,
+ _DerivedToBaseMemberPointer,
+ _MemberPointerToBoolean,
+ _ReinterpretMemberPointer,
+ _UserDefinedConversion,
+ _ConstructorConversion,
+ _IntegralToPointer,
+ _PointerToIntegral,
+ _PointerToBoolean,
+ _ToVoid,
+ _VectorSplat,
+ _IntegralCast,
+ _IntegralToBoolean,
+ _IntegralToFloating,
+ _FixedPointCast,
+ _FixedPointToBoolean,
+ _FloatingToIntegral,
+ _FloatingToBoolean,
+ _BooleanToSignedIntegral,
+ _FloatingCast,
+ _CPointerToObjCPointerCast,
+ _BlockPointerToObjCPointerCast,
+ _AnyPointerToBlockPointerCast,
+ _ObjCObjectLValueCast,
+ _FloatingRealToComplex,
+ _FloatingComplexToReal,
+ _FloatingComplexToBoolean,
+ _FloatingComplexCast,
+ _FloatingComplexToIntegralComplex,
+ _IntegralRealToComplex,
+ _IntegralComplexToReal,
+ _IntegralComplexToBoolean,
+ _IntegralComplexCast,
+ _IntegralComplexToFloatingComplex,
+ _ARCProduceObject,
+ _ARCConsumeObject,
+ _ARCReclaimReturnedObject,
+ _ARCExtendBlockObject,
+ _AtomicToNonAtomic,
+ _NonAtomicToAtomic,
+ _CopyAndAutoreleaseBlockObject,
+ _BuiltinFnToFnPtr,
+ _ZeroToOCLOpaqueType,
+ _AddressSpaceConversion,
+ _IntToOCLSampler,
+};
+pub const ZigClangAPValueUninitialized = enum_ZigClangAPValueKind.ZigClangAPValueUninitialized;
+pub const ZigClangAPValueInt = enum_ZigClangAPValueKind.ZigClangAPValueInt;
+pub const ZigClangAPValueFloat = enum_ZigClangAPValueKind.ZigClangAPValueFloat;
+pub const ZigClangAPValueComplexInt = enum_ZigClangAPValueKind.ZigClangAPValueComplexInt;
+pub const ZigClangAPValueComplexFloat = enum_ZigClangAPValueKind.ZigClangAPValueComplexFloat;
+pub const ZigClangAPValueLValue = enum_ZigClangAPValueKind.ZigClangAPValueLValue;
+pub const ZigClangAPValueVector = enum_ZigClangAPValueKind.ZigClangAPValueVector;
+pub const ZigClangAPValueArray = enum_ZigClangAPValueKind.ZigClangAPValueArray;
+pub const ZigClangAPValueStruct = enum_ZigClangAPValueKind.ZigClangAPValueStruct;
+pub const ZigClangAPValueUnion = enum_ZigClangAPValueKind.ZigClangAPValueUnion;
+pub const ZigClangAPValueMemberPointer = enum_ZigClangAPValueKind.ZigClangAPValueMemberPointer;
+pub const ZigClangAPValueAddrLabelDiff = enum_ZigClangAPValueKind.ZigClangAPValueAddrLabelDiff;
+pub const enum_ZigClangAPValueKind = extern enum {
+ ZigClangAPValueUninitialized,
+ ZigClangAPValueInt,
+ ZigClangAPValueFloat,
+ ZigClangAPValueComplexInt,
+ ZigClangAPValueComplexFloat,
+ ZigClangAPValueLValue,
+ ZigClangAPValueVector,
+ ZigClangAPValueArray,
+ ZigClangAPValueStruct,
+ ZigClangAPValueUnion,
+ ZigClangAPValueMemberPointer,
+ ZigClangAPValueAddrLabelDiff,
+};
+pub extern fn ZigClangSourceManager_getSpellingLoc(arg0: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) struct_ZigClangSourceLocation;
+pub extern fn ZigClangSourceManager_getFilename(arg0: ?*const struct_ZigClangSourceManager, SpellingLoc: struct_ZigClangSourceLocation) [*c]const u8;
+pub extern fn ZigClangSourceManager_getSpellingLineNumber(arg0: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) c_uint;
+pub extern fn ZigClangSourceManager_getSpellingColumnNumber(arg0: ?*const struct_ZigClangSourceManager, Loc: struct_ZigClangSourceLocation) c_uint;
+pub extern fn ZigClangSourceManager_getCharacterData(arg0: ?*const struct_ZigClangSourceManager, SL: struct_ZigClangSourceLocation) [*c]const u8;
+pub extern fn ZigClangASTContext_getPointerType(arg0: ?*const struct_ZigClangASTContext, T: struct_ZigClangQualType) struct_ZigClangQualType;
+pub extern fn ZigClangASTUnit_getASTContext(arg0: ?*struct_ZigClangASTUnit) ?*struct_ZigClangASTContext;
+pub extern fn ZigClangASTUnit_getSourceManager(arg0: ?*struct_ZigClangASTUnit) ?*struct_ZigClangSourceManager;
+pub extern fn ZigClangASTUnit_visitLocalTopLevelDecls(arg0: ?*struct_ZigClangASTUnit, context: ?*c_void, Fn: ?extern fn (?*c_void, ?*const struct_ZigClangDecl) bool) bool;
+pub extern fn ZigClangRecordType_getDecl(record_ty: ?*const struct_ZigClangRecordType) ?*const struct_ZigClangRecordDecl;
+pub extern fn ZigClangEnumType_getDecl(record_ty: ?*const struct_ZigClangEnumType) ?*const struct_ZigClangEnumDecl;
+pub extern fn ZigClangRecordDecl_getCanonicalDecl(record_decl: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangTagDecl;
+pub extern fn ZigClangEnumDecl_getCanonicalDecl(arg0: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangTagDecl;
+pub extern fn ZigClangTypedefNameDecl_getCanonicalDecl(arg0: ?*const struct_ZigClangTypedefNameDecl) ?*const struct_ZigClangTypedefNameDecl;
+pub extern fn ZigClangRecordDecl_getDefinition(arg0: ?*const struct_ZigClangRecordDecl) ?*const struct_ZigClangRecordDecl;
+pub extern fn ZigClangEnumDecl_getDefinition(arg0: ?*const struct_ZigClangEnumDecl) ?*const struct_ZigClangEnumDecl;
+pub extern fn ZigClangRecordDecl_getLocation(arg0: ?*const struct_ZigClangRecordDecl) struct_ZigClangSourceLocation;
+pub extern fn ZigClangEnumDecl_getLocation(arg0: ?*const struct_ZigClangEnumDecl) struct_ZigClangSourceLocation;
+pub extern fn ZigClangTypedefNameDecl_getLocation(arg0: ?*const struct_ZigClangTypedefNameDecl) struct_ZigClangSourceLocation;
+pub extern fn ZigClangRecordDecl_isUnion(record_decl: ?*const struct_ZigClangRecordDecl) bool;
+pub extern fn ZigClangRecordDecl_isStruct(record_decl: ?*const struct_ZigClangRecordDecl) bool;
+pub extern fn ZigClangRecordDecl_isAnonymousStructOrUnion(record_decl: ?*const struct_ZigClangRecordDecl) bool;
+pub extern fn ZigClangEnumDecl_getIntegerType(arg0: ?*const struct_ZigClangEnumDecl) struct_ZigClangQualType;
+pub extern fn ZigClangDecl_getName_bytes_begin(decl: ?*const struct_ZigClangDecl) [*c]const u8;
+pub extern fn ZigClangSourceLocation_eq(a: struct_ZigClangSourceLocation, b: struct_ZigClangSourceLocation) bool;
+pub extern fn ZigClangTypedefType_getDecl(arg0: ?*const struct_ZigClangTypedefType) ?*const struct_ZigClangTypedefNameDecl;
+pub extern fn ZigClangTypedefNameDecl_getUnderlyingType(arg0: ?*const struct_ZigClangTypedefNameDecl) struct_ZigClangQualType;
+pub extern fn ZigClangQualType_getCanonicalType(arg0: struct_ZigClangQualType) struct_ZigClangQualType;
+pub extern fn ZigClangQualType_getTypePtr(arg0: struct_ZigClangQualType) ?*const struct_ZigClangType;
+pub extern fn ZigClangQualType_addConst(arg0: [*c]struct_ZigClangQualType) void;
+pub extern fn ZigClangQualType_eq(arg0: struct_ZigClangQualType, arg1: struct_ZigClangQualType) bool;
+pub extern fn ZigClangQualType_isConstQualified(arg0: struct_ZigClangQualType) bool;
+pub extern fn ZigClangQualType_isVolatileQualified(arg0: struct_ZigClangQualType) bool;
+pub extern fn ZigClangQualType_isRestrictQualified(arg0: struct_ZigClangQualType) bool;
+pub extern fn ZigClangType_getTypeClass(self: ?*const struct_ZigClangType) enum_ZigClangTypeClass;
+pub extern fn ZigClangType_isVoidType(self: ?*const struct_ZigClangType) bool;
+pub extern fn ZigClangType_getTypeClassName(self: ?*const struct_ZigClangType) [*c]const u8;
+pub extern fn ZigClangStmt_getBeginLoc(self: ?*const struct_ZigClangStmt) struct_ZigClangSourceLocation;
+pub extern fn ZigClangStmt_getStmtClass(self: ?*const struct_ZigClangStmt) enum_ZigClangStmtClass;
+pub extern fn ZigClangStmt_classof_Expr(self: ?*const struct_ZigClangStmt) bool;
+pub extern fn ZigClangExpr_getStmtClass(self: ?*const struct_ZigClangExpr) enum_ZigClangStmtClass;
+pub extern fn ZigClangExpr_getType(self: ?*const struct_ZigClangExpr) struct_ZigClangQualType;
+pub extern fn ZigClangExpr_getBeginLoc(self: ?*const struct_ZigClangExpr) struct_ZigClangSourceLocation;
+pub extern fn ZigClangAPValue_getKind(self: ?*const struct_ZigClangAPValue) enum_ZigClangAPValueKind;
+pub extern fn ZigClangAPValue_getInt(self: ?*const struct_ZigClangAPValue) ?*const struct_ZigClangAPSInt;
+pub extern fn ZigClangAPValue_getArrayInitializedElts(self: ?*const struct_ZigClangAPValue) c_uint;
+pub extern fn ZigClangAPValue_getArrayInitializedElt(self: ?*const struct_ZigClangAPValue, i: c_uint) ?*const struct_ZigClangAPValue;
+pub extern fn ZigClangAPValue_getArrayFiller(self: ?*const struct_ZigClangAPValue) ?*const struct_ZigClangAPValue;
+pub extern fn ZigClangAPValue_getArraySize(self: ?*const struct_ZigClangAPValue) c_uint;
+pub extern fn ZigClangAPValue_getLValueBase(self: ?*const struct_ZigClangAPValue) struct_ZigClangAPValueLValueBase;
+pub extern fn ZigClangAPSInt_isSigned(self: ?*const struct_ZigClangAPSInt) bool;
+pub extern fn ZigClangAPSInt_isNegative(self: ?*const struct_ZigClangAPSInt) bool;
+pub extern fn ZigClangAPSInt_negate(self: ?*const struct_ZigClangAPSInt) ?*const struct_ZigClangAPSInt;
+pub extern fn ZigClangAPSInt_free(self: ?*const struct_ZigClangAPSInt) void;
+pub extern fn ZigClangAPSInt_getRawData(self: ?*const struct_ZigClangAPSInt) [*c]const u64;
+pub extern fn ZigClangAPSInt_getNumWords(self: ?*const struct_ZigClangAPSInt) c_uint;
+pub extern fn ZigClangAPValueLValueBase_dyn_cast_Expr(self: struct_ZigClangAPValueLValueBase) ?*const struct_ZigClangExpr;
+pub const ZigClangSourceLocation = struct_ZigClangSourceLocation;
+pub const ZigClangQualType = struct_ZigClangQualType;
+pub const ZigClangAPValueLValueBase = struct_ZigClangAPValueLValueBase;
+pub const ZigClangAPValue = struct_ZigClangAPValue;
+pub const ZigClangAPSInt = struct_ZigClangAPSInt;
+pub const ZigClangASTContext = struct_ZigClangASTContext;
+pub const ZigClangASTUnit = struct_ZigClangASTUnit;
+pub const ZigClangArraySubscriptExpr = struct_ZigClangArraySubscriptExpr;
+pub const ZigClangArrayType = struct_ZigClangArrayType;
+pub const ZigClangAttributedType = struct_ZigClangAttributedType;
+pub const ZigClangBinaryOperator = struct_ZigClangBinaryOperator;
+pub const ZigClangBreakStmt = struct_ZigClangBreakStmt;
+pub const ZigClangBuiltinType = struct_ZigClangBuiltinType;
+pub const ZigClangCStyleCastExpr = struct_ZigClangCStyleCastExpr;
+pub const ZigClangCallExpr = struct_ZigClangCallExpr;
+pub const ZigClangCaseStmt = struct_ZigClangCaseStmt;
+pub const ZigClangCompoundAssignOperator = struct_ZigClangCompoundAssignOperator;
+pub const ZigClangCompoundStmt = struct_ZigClangCompoundStmt;
+pub const ZigClangConditionalOperator = struct_ZigClangConditionalOperator;
+pub const ZigClangConstantArrayType = struct_ZigClangConstantArrayType;
+pub const ZigClangContinueStmt = struct_ZigClangContinueStmt;
+pub const ZigClangDecayedType = struct_ZigClangDecayedType;
+pub const ZigClangDecl = struct_ZigClangDecl;
+pub const ZigClangDeclRefExpr = struct_ZigClangDeclRefExpr;
+pub const ZigClangDeclStmt = struct_ZigClangDeclStmt;
+pub const ZigClangDefaultStmt = struct_ZigClangDefaultStmt;
+pub const ZigClangDiagnosticOptions = struct_ZigClangDiagnosticOptions;
+pub const ZigClangDiagnosticsEngine = struct_ZigClangDiagnosticsEngine;
+pub const ZigClangDoStmt = struct_ZigClangDoStmt;
+pub const ZigClangElaboratedType = struct_ZigClangElaboratedType;
+pub const ZigClangEnumConstantDecl = struct_ZigClangEnumConstantDecl;
+pub const ZigClangEnumDecl = struct_ZigClangEnumDecl;
+pub const ZigClangEnumType = struct_ZigClangEnumType;
+pub const ZigClangExpr = struct_ZigClangExpr;
+pub const ZigClangFieldDecl = struct_ZigClangFieldDecl;
+pub const ZigClangFileID = struct_ZigClangFileID;
+pub const ZigClangForStmt = struct_ZigClangForStmt;
+pub const ZigClangFullSourceLoc = struct_ZigClangFullSourceLoc;
+pub const ZigClangFunctionDecl = struct_ZigClangFunctionDecl;
+pub const ZigClangFunctionProtoType = struct_ZigClangFunctionProtoType;
+pub const ZigClangIfStmt = struct_ZigClangIfStmt;
+pub const ZigClangImplicitCastExpr = struct_ZigClangImplicitCastExpr;
+pub const ZigClangIncompleteArrayType = struct_ZigClangIncompleteArrayType;
+pub const ZigClangIntegerLiteral = struct_ZigClangIntegerLiteral;
+pub const ZigClangMacroDefinitionRecord = struct_ZigClangMacroDefinitionRecord;
+pub const ZigClangMemberExpr = struct_ZigClangMemberExpr;
+pub const ZigClangNamedDecl = struct_ZigClangNamedDecl;
+pub const ZigClangNone = struct_ZigClangNone;
+pub const ZigClangPCHContainerOperations = struct_ZigClangPCHContainerOperations;
+pub const ZigClangParenExpr = struct_ZigClangParenExpr;
+pub const ZigClangParenType = struct_ZigClangParenType;
+pub const ZigClangParmVarDecl = struct_ZigClangParmVarDecl;
+pub const ZigClangPointerType = struct_ZigClangPointerType;
+pub const ZigClangPreprocessedEntity = struct_ZigClangPreprocessedEntity;
+pub const ZigClangRecordDecl = struct_ZigClangRecordDecl;
+pub const ZigClangRecordType = struct_ZigClangRecordType;
+pub const ZigClangReturnStmt = struct_ZigClangReturnStmt;
+pub const ZigClangSkipFunctionBodiesScope = struct_ZigClangSkipFunctionBodiesScope;
+pub const ZigClangSourceManager = struct_ZigClangSourceManager;
+pub const ZigClangSourceRange = struct_ZigClangSourceRange;
+pub const ZigClangStmt = struct_ZigClangStmt;
+pub const ZigClangStorageClass = struct_ZigClangStorageClass;
+pub const ZigClangStringLiteral = struct_ZigClangStringLiteral;
+pub const ZigClangStringRef = struct_ZigClangStringRef;
+pub const ZigClangSwitchStmt = struct_ZigClangSwitchStmt;
+pub const ZigClangTagDecl = struct_ZigClangTagDecl;
+pub const ZigClangType = struct_ZigClangType;
+pub const ZigClangTypedefNameDecl = struct_ZigClangTypedefNameDecl;
+pub const ZigClangTypedefType = struct_ZigClangTypedefType;
+pub const ZigClangUnaryExprOrTypeTraitExpr = struct_ZigClangUnaryExprOrTypeTraitExpr;
+pub const ZigClangUnaryOperator = struct_ZigClangUnaryOperator;
+pub const ZigClangValueDecl = struct_ZigClangValueDecl;
+pub const ZigClangVarDecl = struct_ZigClangVarDecl;
+pub const ZigClangWhileStmt = struct_ZigClangWhileStmt;
+pub const ZigClangBO = enum_ZigClangBO;
+pub const ZigClangUO = enum_ZigClangUO;
+pub const ZigClangTypeClass = enum_ZigClangTypeClass;
+pub const ZigClangStmtClass = enum_ZigClangStmtClass;
+pub const ZigClangCK = enum_ZigClangCK;
+pub const ZigClangAPValueKind = enum_ZigClangAPValueKind;
diff --git a/src-self-hosted/stage1.zig b/src-self-hosted/stage1.zig
index f87c8a0e70..cf5f06c285 100644
--- a/src-self-hosted/stage1.zig
+++ b/src-self-hosted/stage1.zig
@@ -1,8 +1,7 @@
// This is Zig code that is used by both stage1 and stage2.
// The prototypes in src/userland.h must match these definitions.
-comptime {
- _ = @import("translate_c.zig");
-}
+
+const std = @import("std");
pub const info_zen =
\\
@@ -29,3 +28,93 @@ export fn stage2_zen(ptr: *[*]const u8, len: *usize) void {
export fn stage2_panic(ptr: [*]const u8, len: usize) void {
@panic(ptr[0..len]);
}
+
+const TranslateMode = extern enum {
+ import,
+ translate,
+};
+
+const Error = extern enum {
+ None,
+ OutOfMemory,
+ InvalidFormat,
+ SemanticAnalyzeFail,
+ AccessDenied,
+ Interrupted,
+ SystemResources,
+ FileNotFound,
+ FileSystem,
+ FileTooBig,
+ DivByZero,
+ Overflow,
+ PathAlreadyExists,
+ Unexpected,
+ ExactDivRemainder,
+ NegativeDenominator,
+ ShiftedOutOneBits,
+ CCompileErrors,
+ EndOfFile,
+ IsDir,
+ NotDir,
+ UnsupportedOperatingSystem,
+ SharingViolation,
+ PipeBusy,
+ PrimitiveTypeNotFound,
+ CacheUnavailable,
+ PathTooLong,
+ CCompilerCannotFindFile,
+ ReadingDepFile,
+ InvalidDepFile,
+ MissingArchitecture,
+ MissingOperatingSystem,
+ UnknownArchitecture,
+ UnknownOperatingSystem,
+ UnknownABI,
+ InvalidFilename,
+ DiskQuota,
+ DiskSpace,
+ UnexpectedWriteFailure,
+ UnexpectedSeekFailure,
+ UnexpectedFileTruncationFailure,
+ Unimplemented,
+ OperationAborted,
+ BrokenPipe,
+ NoSpaceLeft,
+};
+
+const FILE = std.c.FILE;
+const ast = std.zig.ast;
+
+/// Args should have a null terminating last arg.
+export fn stage2_translate_c(
+ out_ast: **ast.Tree,
+ args_begin: [*]?[*]const u8,
+ args_end: [*]?[*]const u8,
+ mode: TranslateMode,
+) Error {
+ const translate_c = @import("translate_c.zig");
+ out_ast.* = translate_c.translate(args_begin, args_end, switch (mode) {
+ .import => translate_c.Mode.import,
+ .translate => translate_c.Mode.translate,
+ }) catch |err| switch (err) {
+ error.Unimplemented => return Error.Unimplemented,
+ };
+ return Error.None;
+}
+
+export fn stage2_render_ast(tree: *ast.Tree, output_file: *FILE) Error {
+ const c_out_stream = &std.io.COutStream.init(output_file).stream;
+ _ = std.zig.render(std.heap.c_allocator, c_out_stream, tree) catch |e| switch (e) {
+ error.SystemResources => return Error.SystemResources,
+ error.OperationAborted => return Error.OperationAborted,
+ error.BrokenPipe => return Error.BrokenPipe,
+ error.DiskQuota => return Error.DiskQuota,
+ error.FileTooBig => return Error.FileTooBig,
+ error.NoSpaceLeft => return Error.NoSpaceLeft,
+ error.AccessDenied => return Error.AccessDenied,
+ error.OutOfMemory => return Error.OutOfMemory,
+ error.Unexpected => return Error.Unexpected,
+ error.InputOutput => return Error.FileSystem,
+ };
+ return Error.None;
+}
diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig
index e182a5a994..c2d943b1ff 100644
--- a/src-self-hosted/translate_c.zig
+++ b/src-self-hosted/translate_c.zig
@@ -2,7 +2,14 @@
// and stage2. Currently it's not used by anything, as it's not feature complete.
const std = @import("std");
+const ast = std.zig.ast;
+use @import("clang.zig");
-export fn stage2_translate_c() void {
- std.debug.panic("unimplemented");
+pub const Mode = enum {
+ import,
+ translate,
+};
+
+pub fn translate(args_begin: [*]?[*]const u8, args_end: [*]?[*]const u8, mode: Mode) !*ast.Tree {
+ return error.Unimplemented;
}
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 64cf8f2321..158a4bc94f 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -3725,7 +3725,7 @@ static void analyze_fn_body(CodeGen *g, ZigFn *fn_table_entry) {
}
if (g->verbose_ir) {
fprintf(stderr, "\n");
- ast_render(g, stderr, fn_table_entry->body_node, 4);
+ ast_render(stderr, fn_table_entry->body_node, 4);
fprintf(stderr, "\n{ // (IR)\n");
ir_print(g, stderr, &fn_table_entry->ir_executable, 4);
fprintf(stderr, "}\n");
diff --git a/src/analyze.hpp b/src/analyze.hpp
index a3246fdf4d..cde9f2d321 100644
--- a/src/analyze.hpp
+++ b/src/analyze.hpp
@@ -247,4 +247,6 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose
LLVMTypeRef get_llvm_type(CodeGen *g, ZigType *type);
ZigLLVMDIType *get_llvm_di_type(CodeGen *g, ZigType *type);
+void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_path, bool translate_c);
+
#endif
diff --git a/src/ast_render.cpp b/src/ast_render.cpp
index f66a47600e..95ae216f70 100644
--- a/src/ast_render.cpp
+++ b/src/ast_render.cpp
@@ -296,7 +296,6 @@ void ast_print(FILE *f, AstNode *node, int indent) {
struct AstRender {
- CodeGen *codegen;
int indent;
int indent_size;
FILE *f;
@@ -1170,9 +1169,8 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
}
-void ast_render(CodeGen *codegen, FILE *f, AstNode *node, int indent_size) {
+void ast_render(FILE *f, AstNode *node, int indent_size) {
AstRender ar = {0};
- ar.codegen = codegen;
ar.f = f;
ar.indent_size = indent_size;
ar.indent = 0;
diff --git a/src/ast_render.hpp b/src/ast_render.hpp
index 1652156eee..cf70b04694 100644
--- a/src/ast_render.hpp
+++ b/src/ast_render.hpp
@@ -15,6 +15,6 @@
void ast_print(FILE *f, AstNode *node, int indent);
-void ast_render(CodeGen *codegen, FILE *f, AstNode *node, int indent_size);
+void ast_render(FILE *f, AstNode *node, int indent_size);
#endif
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 6075fb6881..b4ea0a9a96 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -8153,7 +8153,128 @@ static void detect_libc(CodeGen *g) {
}
}
-AstNode *codegen_translate_c(CodeGen *g, Buf *full_path, bool use_userland_implementation) {
+// does not add the "cc" arg
+void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_path, bool translate_c) {
+ if (out_dep_path != nullptr) {
+ args.append("-MD");
+ args.append("-MV");
+ args.append("-MF");
+ args.append(out_dep_path);
+ }
+
+ args.append("-nostdinc");
+ args.append("-fno-spell-checking");
+
+ if (translate_c) {
+ // TODO these args shouldn't be special from the non-translate-c args, probably.
+ args.append("-nobuiltininc");
+ args.append("-nostdinc++");
+ if (g->libc_link_lib == nullptr) {
+ args.append("-nolibc");
+ }
+
+ // this gives us access to preprocessing entities, presumably at
+ // the cost of performance
+ args.append("-Xclang");
+ args.append("-detailed-preprocessing-record");
+ } else {
+ switch (g->err_color) {
+ case ErrColorAuto:
+ break;
+ case ErrColorOff:
+ args.append("-fno-color-diagnostics");
+ args.append("-fno-caret-diagnostics");
+ break;
+ case ErrColorOn:
+ args.append("-fcolor-diagnostics");
+ args.append("-fcaret-diagnostics");
+ break;
+ }
+ }
+
+ args.append("-isystem");
+ args.append(buf_ptr(g->zig_c_headers_dir));
+
+ for (size_t i = 0; i < g->libc_include_dir_len; i += 1) {
+ Buf *include_dir = g->libc_include_dir_list[i];
+ args.append("-isystem");
+ args.append(buf_ptr(include_dir));
+ }
+
+ if (g->zig_target->is_native) {
+ args.append("-march=native");
+ } else {
+ args.append("-target");
+ args.append(buf_ptr(&g->triple_str));
+ }
+ if (g->zig_target->os == OsFreestanding) {
+ args.append("-ffreestanding");
+ }
+
+ if (!g->strip_debug_symbols) {
+ args.append("-g");
+ }
+
+ switch (g->build_mode) {
+ case BuildModeDebug:
+ // windows c runtime requires -D_DEBUG if using debug libraries
+ args.append("-D_DEBUG");
+
+ if (g->libc_link_lib != nullptr) {
+ args.append("-fstack-protector-strong");
+ args.append("--param");
+ args.append("ssp-buffer-size=4");
+ } else {
+ args.append("-fno-stack-protector");
+ }
+ args.append("-fno-omit-frame-pointer");
+ break;
+ case BuildModeSafeRelease:
+ // See the comment in the BuildModeFastRelease case for why we pass -O2 rather
+ // than -O3 here.
+ args.append("-O2");
+ if (g->libc_link_lib != nullptr) {
+ args.append("-D_FORTIFY_SOURCE=2");
+ args.append("-fstack-protector-strong");
+ args.append("--param");
+ args.append("ssp-buffer-size=4");
+ } else {
+ args.append("-fno-stack-protector");
+ }
+ args.append("-fomit-frame-pointer");
+ break;
+ case BuildModeFastRelease:
+ args.append("-DNDEBUG");
+ // Here we pass -O2 rather than -O3 because, although we do the equivalent of
+ // -O3 in Zig code, the justification for the difference here is that Zig
+ // has better detection and prevention of undefined behavior, so -O3 is safer for
+ // Zig code than it is for C code. Also, C programmers are used to their code
+ // running in -O2 and thus the -O3 path has been tested less.
+ args.append("-O2");
+ args.append("-fno-stack-protector");
+ args.append("-fomit-frame-pointer");
+ break;
+ case BuildModeSmallRelease:
+ args.append("-DNDEBUG");
+ args.append("-Os");
+ args.append("-fno-stack-protector");
+ args.append("-fomit-frame-pointer");
+ break;
+ }
+
+ if (target_supports_fpic(g->zig_target) && g->have_pic) {
+ args.append("-fPIC");
+ }
+
+ for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) {
+ args.append(g->clang_argv[arg_i]);
+ }
+
+
+}
+
+void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_userland_implementation) {
+ Error err;
Buf *src_basename = buf_alloc();
Buf *src_dirname = buf_alloc();
os_path_split(full_path, src_dirname, src_basename);
@@ -8165,30 +8286,45 @@ AstNode *codegen_translate_c(CodeGen *g, Buf *full_path, bool use_userland_imple
init(g);
+ Stage2TranslateMode trans_mode = buf_ends_with_str(full_path, ".h") ?
+ Stage2TranslateModeImport : Stage2TranslateModeTranslate;
+
+
+ ZigList clang_argv = {0};
+ add_cc_args(g, clang_argv, nullptr, true);
+
+ clang_argv.append("-c");
+ clang_argv.append(buf_ptr(full_path));
+
+ clang_argv.append(nullptr); // to make the [start...end] argument work
+
if (use_userland_implementation) {
- // TODO improve this
- stage2_translate_c();
- zig_panic("TODO");
- }
+ Stage2Ast *ast;
+ if ((err = stage2_translate_c(&ast, &clang_argv.at(0), &clang_argv.last(), trans_mode))) {
+ zig_panic("TODO");
+ }
+ stage2_render_ast(ast, out_file);
+ } else {
+ ZigList errors = {0};
+ AstNode *root_node;
- ZigList errors = {0};
- AstNode *root_node;
- Error err = parse_h_file(&root_node, &errors, buf_ptr(full_path), g, nullptr);
+ err = parse_h_file(g, &root_node, &clang_argv.at(0), &clang_argv.last(), trans_mode, &errors);
- if (err == ErrorCCompileErrors && errors.length > 0) {
- for (size_t i = 0; i < errors.length; i += 1) {
- ErrorMsg *err_msg = errors.at(i);
- print_err_msg(err_msg, g->err_color);
+ if (err == ErrorCCompileErrors && errors.length > 0) {
+ for (size_t i = 0; i < errors.length; i += 1) {
+ ErrorMsg *err_msg = errors.at(i);
+ print_err_msg(err_msg, g->err_color);
+ }
+ exit(1);
}
- exit(1);
- }
- if (err) {
- fprintf(stderr, "unable to parse C file: %s\n", err_str(err));
- exit(1);
- }
+ if (err) {
+ fprintf(stderr, "unable to parse C file: %s\n", err_str(err));
+ exit(1);
+ }
- return root_node;
+ ast_render(out_file, root_node, 4);
+ }
}
static ZigType *add_special_code(CodeGen *g, ZigPackage *package, const char *basename) {
@@ -8507,93 +8643,7 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) {
args.append("cc");
Buf *out_dep_path = buf_sprintf("%s.d", buf_ptr(out_obj_path));
- args.append("-MD");
- args.append("-MV");
- args.append("-MF");
- args.append(buf_ptr(out_dep_path));
-
- args.append("-nostdinc");
- args.append("-fno-spell-checking");
-
- switch (g->err_color) {
- case ErrColorAuto:
- break;
- case ErrColorOff:
- args.append("-fno-color-diagnostics");
- args.append("-fno-caret-diagnostics");
- break;
- case ErrColorOn:
- args.append("-fcolor-diagnostics");
- args.append("-fcaret-diagnostics");
- break;
- }
-
- args.append("-isystem");
- args.append(buf_ptr(g->zig_c_headers_dir));
-
- for (size_t i = 0; i < g->libc_include_dir_len; i += 1) {
- Buf *include_dir = g->libc_include_dir_list[i];
- args.append("-isystem");
- args.append(buf_ptr(include_dir));
- }
-
- if (g->zig_target->is_native) {
- args.append("-march=native");
- } else {
- args.append("-target");
- args.append(buf_ptr(&g->triple_str));
- }
- if (g->zig_target->os == OsFreestanding) {
- args.append("-ffreestanding");
- }
-
- if (!g->strip_debug_symbols) {
- args.append("-g");
- }
-
- switch (g->build_mode) {
- case BuildModeDebug:
- if (g->libc_link_lib != nullptr) {
- args.append("-fstack-protector-strong");
- args.append("--param");
- args.append("ssp-buffer-size=4");
- } else {
- args.append("-fno-stack-protector");
- }
- args.append("-fno-omit-frame-pointer");
- break;
- case BuildModeSafeRelease:
- // See the comment in the BuildModeFastRelease case for why we pass -O2 rather
- // than -O3 here.
- args.append("-O2");
- if (g->libc_link_lib != nullptr) {
- args.append("-D_FORTIFY_SOURCE=2");
- args.append("-fstack-protector-strong");
- args.append("--param");
- args.append("ssp-buffer-size=4");
- } else {
- args.append("-fno-stack-protector");
- }
- args.append("-fomit-frame-pointer");
- break;
- case BuildModeFastRelease:
- args.append("-DNDEBUG");
- // Here we pass -O2 rather than -O3 because, although we do the equivalent of
- // -O3 in Zig code, the justification for the difference here is that Zig
- // has better detection and prevention of undefined behavior, so -O3 is safer for
- // Zig code than it is for C code. Also, C programmers are used to their code
- // running in -O2 and thus the -O3 path has been tested less.
- args.append("-O2");
- args.append("-fno-stack-protector");
- args.append("-fomit-frame-pointer");
- break;
- case BuildModeSmallRelease:
- args.append("-DNDEBUG");
- args.append("-Os");
- args.append("-fno-stack-protector");
- args.append("-fomit-frame-pointer");
- break;
- }
+ add_cc_args(g, args, buf_ptr(out_dep_path), false);
args.append("-o");
args.append(buf_ptr(out_obj_path));
@@ -8601,19 +8651,10 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) {
args.append("-c");
args.append(buf_ptr(c_source_file));
- if (target_supports_fpic(g->zig_target) && g->have_pic) {
- args.append("-fPIC");
- }
-
- for (size_t arg_i = 0; arg_i < g->clang_argv_len; arg_i += 1) {
- args.append(g->clang_argv[arg_i]);
- }
-
for (size_t arg_i = 0; arg_i < c_file->args.length; arg_i += 1) {
args.append(c_file->args.at(arg_i));
}
-
if (g->verbose_cc) {
print_zig_cc_cmd("zig", &args);
}
diff --git a/src/codegen.hpp b/src/codegen.hpp
index d6149bf5d2..88c7353cad 100644
--- a/src/codegen.hpp
+++ b/src/codegen.hpp
@@ -12,6 +12,7 @@
#include "errmsg.hpp"
#include "target.hpp"
#include "libc_installation.hpp"
+#include "userland.h"
#include
@@ -50,7 +51,7 @@ ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const c
void codegen_add_assembly(CodeGen *g, Buf *path);
void codegen_add_object(CodeGen *g, Buf *object_path);
-AstNode *codegen_translate_c(CodeGen *g, Buf *path, bool use_userland_implementation);
+void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_userland_implementation);
Buf *codegen_generate_builtin_source(CodeGen *g);
diff --git a/src/error.cpp b/src/error.cpp
index 84b78aba1b..69676f9cf5 100644
--- a/src/error.cpp
+++ b/src/error.cpp
@@ -50,6 +50,10 @@ const char *err_str(Error err) {
case ErrorUnexpectedWriteFailure: return "unexpected write failure";
case ErrorUnexpectedSeekFailure: return "unexpected seek failure";
case ErrorUnexpectedFileTruncationFailure: return "unexpected file truncation failure";
+ case ErrorUnimplemented: return "unimplemented";
+ case ErrorOperationAborted: return "operation aborted";
+ case ErrorBrokenPipe: return "broken pipe";
+ case ErrorNoSpaceLeft: return "no space left";
}
return "(invalid error)";
}
diff --git a/src/error.hpp b/src/error.hpp
index 75ee801112..3ff36e1a5f 100644
--- a/src/error.hpp
+++ b/src/error.hpp
@@ -8,49 +8,7 @@
#ifndef ERROR_HPP
#define ERROR_HPP
-enum Error {
- ErrorNone,
- ErrorNoMem,
- ErrorInvalidFormat,
- ErrorSemanticAnalyzeFail,
- ErrorAccess,
- ErrorInterrupted,
- ErrorSystemResources,
- ErrorFileNotFound,
- ErrorFileSystem,
- ErrorFileTooBig,
- ErrorDivByZero,
- ErrorOverflow,
- ErrorPathAlreadyExists,
- ErrorUnexpected,
- ErrorExactDivRemainder,
- ErrorNegativeDenominator,
- ErrorShiftedOutOneBits,
- ErrorCCompileErrors,
- ErrorEndOfFile,
- ErrorIsDir,
- ErrorNotDir,
- ErrorUnsupportedOperatingSystem,
- ErrorSharingViolation,
- ErrorPipeBusy,
- ErrorPrimitiveTypeNotFound,
- ErrorCacheUnavailable,
- ErrorPathTooLong,
- ErrorCCompilerCannotFindFile,
- ErrorReadingDepFile,
- ErrorInvalidDepFile,
- ErrorMissingArchitecture,
- ErrorMissingOperatingSystem,
- ErrorUnknownArchitecture,
- ErrorUnknownOperatingSystem,
- ErrorUnknownABI,
- ErrorInvalidFilename,
- ErrorDiskQuota,
- ErrorDiskSpace,
- ErrorUnexpectedWriteFailure,
- ErrorUnexpectedSeekFailure,
- ErrorUnexpectedFileTruncationFailure,
-};
+#include "userland.h"
const char *err_str(Error err);
diff --git a/src/ir.cpp b/src/ir.cpp
index 62eadeb43f..105dd0c3d6 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -10350,7 +10350,7 @@ ConstExprValue *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *nod
if (codegen->verbose_ir) {
fprintf(stderr, "\nSource: ");
- ast_render(codegen, stderr, node, 4);
+ ast_render(stderr, node, 4);
fprintf(stderr, "\n{ // (IR)\n");
ir_print(codegen, stderr, ir_executable, 2);
fprintf(stderr, "}\n");
@@ -19092,11 +19092,23 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
fprintf(stderr, "@cImport source: %s\n", buf_ptr(&tmp_c_file_path));
}
- ZigList errors = {0};
-
Buf *tmp_dep_file = buf_sprintf("%s.d", buf_ptr(&tmp_c_file_path));
+
+ ZigList clang_argv = {0};
+
+ add_cc_args(ira->codegen, clang_argv, buf_ptr(tmp_dep_file), true);
+
+ clang_argv.append("-c");
+ clang_argv.append(buf_ptr(&tmp_c_file_path));
+
+ clang_argv.append(nullptr); // to make the [start...end] argument work
+
+ ZigList errors = {0};
AstNode *root_node;
- if ((err = parse_h_file(&root_node, &errors, buf_ptr(&tmp_c_file_path), ira->codegen, tmp_dep_file))) {
+
+ if ((err = parse_h_file(ira->codegen, &root_node, &clang_argv.at(0), &clang_argv.last(),
+ Stage2TranslateModeImport, &errors)))
+ {
if (err != ErrorCCompileErrors) {
ir_add_error_node(ira, node, buf_sprintf("C import failed: %s", err_str(err)));
return ira->codegen->invalid_instruction;
@@ -19139,7 +19151,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
buf_sprintf("C import failed: unable to open output file: %s", strerror(errno)));
return ira->codegen->invalid_instruction;
}
- ast_render(ira->codegen, out_file, root_node, 4);
+ ast_render(out_file, root_node, 4);
if (fclose(out_file) != 0) {
ir_add_error_node(ira, node,
buf_sprintf("C import failed: unable to write to output file: %s", strerror(errno)));
diff --git a/src/main.cpp b/src/main.cpp
index 8cbc9b0d8c..2b65999e3b 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1188,8 +1188,7 @@ int main(int argc, char **argv) {
zig_unreachable();
}
} else if (cmd == CmdTranslateC || cmd == CmdTranslateCUserland) {
- AstNode *root_node = codegen_translate_c(g, in_file_buf, cmd == CmdTranslateCUserland);
- ast_render(g, stdout, root_node, 4);
+ codegen_translate_c(g, in_file_buf, stdout, cmd == CmdTranslateCUserland);
if (timing_info)
codegen_print_timing_report(g, stderr);
return EXIT_SUCCESS;
diff --git a/src/translate_c.cpp b/src/translate_c.cpp
index f4f1055ed9..d19083ce73 100644
--- a/src/translate_c.cpp
+++ b/src/translate_c.cpp
@@ -5018,14 +5018,14 @@ static void process_preprocessor_entities(Context *c, ZigClangASTUnit *zunit) {
}
}
-Error parse_h_file(AstNode **out_root_node, ZigList *errors, const char *target_file,
- CodeGen *codegen, Buf *tmp_dep_file)
+Error parse_h_file(CodeGen *codegen, AstNode **out_root_node, const char **args_begin, const char **args_end,
+ Stage2TranslateMode mode, ZigList *errors)
{
Context context = {0};
Context *c = &context;
c->warnings_on = codegen->verbose_cimport;
c->errors = errors;
- if (buf_ends_with_str(buf_create_from_str(target_file), ".h")) {
+ if (mode == Stage2TranslateModeImport) {
c->visib_mod = VisibModPub;
c->want_export = false;
} else {
@@ -5039,92 +5039,6 @@ Error parse_h_file(AstNode **out_root_node, ZigList *errors, const c
c->codegen = codegen;
c->global_scope = trans_scope_root_create(c);
- ZigList clang_argv = {0};
-
- clang_argv.append("-x");
- clang_argv.append("c");
-
- if (tmp_dep_file != nullptr) {
- clang_argv.append("-MD");
- clang_argv.append("-MV");
- clang_argv.append("-MF");
- clang_argv.append(buf_ptr(tmp_dep_file));
- }
-
- if (c->codegen->zig_target->is_native) {
- char *ZIG_PARSEC_CFLAGS = getenv("ZIG_NATIVE_PARSEC_CFLAGS");
- if (ZIG_PARSEC_CFLAGS) {
- Buf tmp_buf = BUF_INIT;
- char *start = ZIG_PARSEC_CFLAGS;
- char *space = strstr(start, " ");
- while (space) {
- if (space - start > 0) {
- buf_init_from_mem(&tmp_buf, start, space - start);
- clang_argv.append(buf_ptr(buf_create_from_buf(&tmp_buf)));
- }
- start = space + 1;
- space = strstr(start, " ");
- }
- buf_init_from_str(&tmp_buf, start);
- clang_argv.append(buf_ptr(buf_create_from_buf(&tmp_buf)));
- }
- }
-
- clang_argv.append("-nobuiltininc");
- clang_argv.append("-nostdinc");
- clang_argv.append("-nostdinc++");
- if (codegen->libc_link_lib == nullptr) {
- clang_argv.append("-nolibc");
- }
-
- clang_argv.append("-isystem");
- clang_argv.append(buf_ptr(codegen->zig_c_headers_dir));
-
- for (size_t i = 0; i < codegen->libc_include_dir_len; i += 1) {
- Buf *include_dir = codegen->libc_include_dir_list[i];
- clang_argv.append("-isystem");
- clang_argv.append(buf_ptr(include_dir));
- }
-
- // windows c runtime requires -D_DEBUG if using debug libraries
- if (codegen->build_mode == BuildModeDebug) {
- clang_argv.append("-D_DEBUG");
- }
-
- for (size_t i = 0; i < codegen->clang_argv_len; i += 1) {
- clang_argv.append(codegen->clang_argv[i]);
- }
-
- // we don't need spell checking and it slows things down
- clang_argv.append("-fno-spell-checking");
-
- // this gives us access to preprocessing entities, presumably at
- // the cost of performance
- clang_argv.append("-Xclang");
- clang_argv.append("-detailed-preprocessing-record");
-
- if (c->codegen->zig_target->is_native) {
- clang_argv.append("-march=native");
- } else {
- clang_argv.append("-target");
- clang_argv.append(buf_ptr(&c->codegen->triple_str));
- }
- if (c->codegen->zig_target->os == OsFreestanding) {
- clang_argv.append("-ffreestanding");
- }
-
- clang_argv.append(target_file);
-
- if (codegen->verbose_cc) {
- fprintf(stderr, "clang");
- for (size_t i = 0; i < clang_argv.length; i += 1) {
- fprintf(stderr, " %s", clang_argv.at(i));
- }
- fprintf(stderr, "\n");
- }
-
- // to make the [start...end] argument work
- clang_argv.append(nullptr);
clang::IntrusiveRefCntPtr diags(clang::CompilerInstance::createDiagnostics(new clang::DiagnosticOptions));
@@ -5139,7 +5053,7 @@ Error parse_h_file(AstNode **out_root_node, ZigList *errors, const c
const char *resources_path = buf_ptr(codegen->zig_c_headers_dir);
std::unique_ptr err_unit;
ZigClangASTUnit *ast_unit = reinterpret_cast(clang::ASTUnit::LoadFromCommandLine(
- &clang_argv.at(0), &clang_argv.last(),
+ args_begin, args_end,
pch_container_ops, diags, resources_path,
only_local_decls, capture_diagnostics, clang::None, true, 0, clang::TU_Complete,
false, false, allow_pch_with_compiler_errors, clang::SkipFunctionBodiesScope::None,
diff --git a/src/translate_c.hpp b/src/translate_c.hpp
index 21461d2813..b6e4b6bcbb 100644
--- a/src/translate_c.hpp
+++ b/src/translate_c.hpp
@@ -11,7 +11,7 @@
#include "all_types.hpp"
-Error parse_h_file(AstNode **out_root_node, ZigList *errors, const char *target_file,
- CodeGen *codegen, Buf *tmp_dep_file);
+Error parse_h_file(CodeGen *codegen, AstNode **out_root_node, const char **args_begin, const char **args_end,
+ Stage2TranslateMode mode, ZigList *errors);
#endif
diff --git a/src/userland.cpp b/src/userland.cpp
index 6c56bceaa0..9935d5c04a 100644
--- a/src/userland.cpp
+++ b/src/userland.cpp
@@ -2,11 +2,14 @@
// src-self-hosted/stage1.zig
#include "userland.h"
+#include "ast_render.hpp"
#include
#include
#include
-void stage2_translate_c(void) {
+Error stage2_translate_c(struct Stage2Ast **out_ast,
+ const char **args_begin, const char **args_end, enum Stage2TranslateMode mode)
+{
const char *msg = "stage0 called stage2_translate_c";
stage2_panic(msg, strlen(msg));
}
@@ -22,3 +25,8 @@ void stage2_panic(const char *ptr, size_t len) {
fflush(stderr);
abort();
}
+
+void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file) {
+ const char *msg = "stage0 called stage2_render_ast";
+ stage2_panic(msg, strlen(msg));
+}
diff --git a/src/userland.h b/src/userland.h
index a01bcc62c3..35fd46942b 100644
--- a/src/userland.h
+++ b/src/userland.h
@@ -9,6 +9,7 @@
#define ZIG_USERLAND_H
#include
+#include
#ifdef __cplusplus
#define ZIG_USERLAND_EXTERN_C extern "C"
@@ -16,10 +17,77 @@
#define ZIG_USERLAND_EXTERN_C
#endif
-ZIG_USERLAND_EXTERN_C void stage2_translate_c(void);
+#if defined(_MSC_VER)
+#define ZIG_USERLAND_ATTRIBUTE_NORETURN __declspec(noreturn)
+#else
+#define ZIG_USERLAND_ATTRIBUTE_NORETURN __attribute__((noreturn))
+#endif
+
+// The types and declarations in this file must match both those in userland.cpp and
+// src-self-hosted/stage1.zig.
+
+enum Error {
+ ErrorNone,
+ ErrorNoMem,
+ ErrorInvalidFormat,
+ ErrorSemanticAnalyzeFail,
+ ErrorAccess,
+ ErrorInterrupted,
+ ErrorSystemResources,
+ ErrorFileNotFound,
+ ErrorFileSystem,
+ ErrorFileTooBig,
+ ErrorDivByZero,
+ ErrorOverflow,
+ ErrorPathAlreadyExists,
+ ErrorUnexpected,
+ ErrorExactDivRemainder,
+ ErrorNegativeDenominator,
+ ErrorShiftedOutOneBits,
+ ErrorCCompileErrors,
+ ErrorEndOfFile,
+ ErrorIsDir,
+ ErrorNotDir,
+ ErrorUnsupportedOperatingSystem,
+ ErrorSharingViolation,
+ ErrorPipeBusy,
+ ErrorPrimitiveTypeNotFound,
+ ErrorCacheUnavailable,
+ ErrorPathTooLong,
+ ErrorCCompilerCannotFindFile,
+ ErrorReadingDepFile,
+ ErrorInvalidDepFile,
+ ErrorMissingArchitecture,
+ ErrorMissingOperatingSystem,
+ ErrorUnknownArchitecture,
+ ErrorUnknownOperatingSystem,
+ ErrorUnknownABI,
+ ErrorInvalidFilename,
+ ErrorDiskQuota,
+ ErrorDiskSpace,
+ ErrorUnexpectedWriteFailure,
+ ErrorUnexpectedSeekFailure,
+ ErrorUnexpectedFileTruncationFailure,
+ ErrorUnimplemented,
+ ErrorOperationAborted,
+ ErrorBrokenPipe,
+ ErrorNoSpaceLeft,
+};
+
+enum Stage2TranslateMode {
+ Stage2TranslateModeImport,
+ Stage2TranslateModeTranslate,
+};
+
+struct Stage2Ast;
+
+ZIG_USERLAND_EXTERN_C Error stage2_translate_c(struct Stage2Ast **out_ast,
+ const char **args_begin, const char **args_end, enum Stage2TranslateMode mode);
+
+ZIG_USERLAND_EXTERN_C void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file);
ZIG_USERLAND_EXTERN_C void stage2_zen(const char **ptr, size_t *len);
-ZIG_USERLAND_EXTERN_C void stage2_panic(const char *ptr, size_t len);
+ZIG_USERLAND_EXTERN_C ZIG_USERLAND_ATTRIBUTE_NORETURN void stage2_panic(const char *ptr, size_t len);
#endif
diff --git a/src/zig_clang.h b/src/zig_clang.h
index 78d6e1589d..148ee34f51 100644
--- a/src/zig_clang.h
+++ b/src/zig_clang.h
@@ -9,6 +9,7 @@
#define ZIG_ZIG_CLANG_H
#include
+#include
#ifdef __cplusplus
#define ZIG_EXTERN_C extern "C"
@@ -17,8 +18,8 @@
#endif
// ATTENTION: If you modify this file, be sure to update the corresponding
-// extern function declarations in the self-hosted compiler.
-// Note: not yet, we don't have the corresponding clang.zig yet.
+// extern function declarations in the self-hosted compiler file
+// src-self-hosted/clang.zig.
struct ZigClangSourceLocation {
unsigned ID;
@@ -486,86 +487,86 @@ enum ZigClangAPValueKind {
ZigClangAPValueAddrLabelDiff,
};
-ZIG_EXTERN_C ZigClangSourceLocation ZigClangSourceManager_getSpellingLoc(const ZigClangSourceManager *,
- ZigClangSourceLocation Loc);
-ZIG_EXTERN_C const char *ZigClangSourceManager_getFilename(const ZigClangSourceManager *,
- ZigClangSourceLocation SpellingLoc);
-ZIG_EXTERN_C unsigned ZigClangSourceManager_getSpellingLineNumber(const ZigClangSourceManager *,
- ZigClangSourceLocation Loc);
-ZIG_EXTERN_C unsigned ZigClangSourceManager_getSpellingColumnNumber(const ZigClangSourceManager *,
- ZigClangSourceLocation Loc);
-ZIG_EXTERN_C const char* ZigClangSourceManager_getCharacterData(const ZigClangSourceManager *,
- ZigClangSourceLocation SL);
-
-ZIG_EXTERN_C ZigClangQualType ZigClangASTContext_getPointerType(const ZigClangASTContext*, ZigClangQualType T);
-
-ZIG_EXTERN_C ZigClangASTContext *ZigClangASTUnit_getASTContext(ZigClangASTUnit *);
-ZIG_EXTERN_C ZigClangSourceManager *ZigClangASTUnit_getSourceManager(ZigClangASTUnit *);
-ZIG_EXTERN_C bool ZigClangASTUnit_visitLocalTopLevelDecls(ZigClangASTUnit *, void *context,
- bool (*Fn)(void *context, const ZigClangDecl *decl));
-
-ZIG_EXTERN_C const ZigClangRecordDecl *ZigClangRecordType_getDecl(const ZigClangRecordType *record_ty);
-ZIG_EXTERN_C const ZigClangEnumDecl *ZigClangEnumType_getDecl(const ZigClangEnumType *record_ty);
-
-ZIG_EXTERN_C const ZigClangTagDecl *ZigClangRecordDecl_getCanonicalDecl(const ZigClangRecordDecl *record_decl);
-ZIG_EXTERN_C const ZigClangTagDecl *ZigClangEnumDecl_getCanonicalDecl(const ZigClangEnumDecl *);
-ZIG_EXTERN_C const ZigClangTypedefNameDecl *ZigClangTypedefNameDecl_getCanonicalDecl(const ZigClangTypedefNameDecl *);
-
-ZIG_EXTERN_C const ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const ZigClangRecordDecl *);
-ZIG_EXTERN_C const ZigClangEnumDecl *ZigClangEnumDecl_getDefinition(const ZigClangEnumDecl *);
-
-ZIG_EXTERN_C ZigClangSourceLocation ZigClangRecordDecl_getLocation(const ZigClangRecordDecl *);
-ZIG_EXTERN_C ZigClangSourceLocation ZigClangEnumDecl_getLocation(const ZigClangEnumDecl *);
-ZIG_EXTERN_C ZigClangSourceLocation ZigClangTypedefNameDecl_getLocation(const ZigClangTypedefNameDecl *);
-
-ZIG_EXTERN_C bool ZigClangRecordDecl_isUnion(const ZigClangRecordDecl *record_decl);
-ZIG_EXTERN_C bool ZigClangRecordDecl_isStruct(const ZigClangRecordDecl *record_decl);
-ZIG_EXTERN_C bool ZigClangRecordDecl_isAnonymousStructOrUnion(const ZigClangRecordDecl *record_decl);
-
-ZIG_EXTERN_C ZigClangQualType ZigClangEnumDecl_getIntegerType(const ZigClangEnumDecl *);
-
-ZIG_EXTERN_C const char *ZigClangDecl_getName_bytes_begin(const ZigClangDecl *decl);
-
-ZIG_EXTERN_C bool ZigClangSourceLocation_eq(ZigClangSourceLocation a, ZigClangSourceLocation b);
-
-ZIG_EXTERN_C const ZigClangTypedefNameDecl *ZigClangTypedefType_getDecl(const ZigClangTypedefType *);
-ZIG_EXTERN_C ZigClangQualType ZigClangTypedefNameDecl_getUnderlyingType(const ZigClangTypedefNameDecl *);
-
-ZIG_EXTERN_C ZigClangQualType ZigClangQualType_getCanonicalType(ZigClangQualType);
-ZIG_EXTERN_C const ZigClangType *ZigClangQualType_getTypePtr(ZigClangQualType);
-ZIG_EXTERN_C void ZigClangQualType_addConst(ZigClangQualType *);
-ZIG_EXTERN_C bool ZigClangQualType_eq(ZigClangQualType, ZigClangQualType);
-ZIG_EXTERN_C bool ZigClangQualType_isConstQualified(ZigClangQualType);
-ZIG_EXTERN_C bool ZigClangQualType_isVolatileQualified(ZigClangQualType);
-ZIG_EXTERN_C bool ZigClangQualType_isRestrictQualified(ZigClangQualType);
-
-ZIG_EXTERN_C ZigClangTypeClass ZigClangType_getTypeClass(const ZigClangType *self);
-ZIG_EXTERN_C bool ZigClangType_isVoidType(const ZigClangType *self);
-ZIG_EXTERN_C const char *ZigClangType_getTypeClassName(const ZigClangType *self);
-
-ZIG_EXTERN_C ZigClangSourceLocation ZigClangStmt_getBeginLoc(const ZigClangStmt *self);
-ZIG_EXTERN_C ZigClangStmtClass ZigClangStmt_getStmtClass(const ZigClangStmt *self);
-ZIG_EXTERN_C bool ZigClangStmt_classof_Expr(const ZigClangStmt *self);
-
-ZIG_EXTERN_C ZigClangStmtClass ZigClangExpr_getStmtClass(const ZigClangExpr *self);
-ZIG_EXTERN_C ZigClangQualType ZigClangExpr_getType(const ZigClangExpr *self);
-ZIG_EXTERN_C ZigClangSourceLocation ZigClangExpr_getBeginLoc(const ZigClangExpr *self);
-
-ZIG_EXTERN_C ZigClangAPValueKind ZigClangAPValue_getKind(const ZigClangAPValue *self);
-ZIG_EXTERN_C const ZigClangAPSInt *ZigClangAPValue_getInt(const ZigClangAPValue *self);
-ZIG_EXTERN_C unsigned ZigClangAPValue_getArrayInitializedElts(const ZigClangAPValue *self);
-ZIG_EXTERN_C const ZigClangAPValue *ZigClangAPValue_getArrayInitializedElt(const ZigClangAPValue *self, unsigned i);
-ZIG_EXTERN_C const ZigClangAPValue *ZigClangAPValue_getArrayFiller(const ZigClangAPValue *self);
-ZIG_EXTERN_C unsigned ZigClangAPValue_getArraySize(const ZigClangAPValue *self);
-ZIG_EXTERN_C ZigClangAPValueLValueBase ZigClangAPValue_getLValueBase(const ZigClangAPValue *self);
-
-ZIG_EXTERN_C bool ZigClangAPSInt_isSigned(const ZigClangAPSInt *self);
-ZIG_EXTERN_C bool ZigClangAPSInt_isNegative(const ZigClangAPSInt *self);
-ZIG_EXTERN_C const ZigClangAPSInt *ZigClangAPSInt_negate(const ZigClangAPSInt *self);
-ZIG_EXTERN_C void ZigClangAPSInt_free(const ZigClangAPSInt *self);
-ZIG_EXTERN_C const uint64_t *ZigClangAPSInt_getRawData(const ZigClangAPSInt *self);
-ZIG_EXTERN_C unsigned ZigClangAPSInt_getNumWords(const ZigClangAPSInt *self);
-
-ZIG_EXTERN_C const ZigClangExpr *ZigClangAPValueLValueBase_dyn_cast_Expr(ZigClangAPValueLValueBase self);
+ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangSourceManager_getSpellingLoc(const struct ZigClangSourceManager *,
+ struct ZigClangSourceLocation Loc);
+ZIG_EXTERN_C const char *ZigClangSourceManager_getFilename(const struct ZigClangSourceManager *,
+ struct ZigClangSourceLocation SpellingLoc);
+ZIG_EXTERN_C unsigned ZigClangSourceManager_getSpellingLineNumber(const struct ZigClangSourceManager *,
+ struct ZigClangSourceLocation Loc);
+ZIG_EXTERN_C unsigned ZigClangSourceManager_getSpellingColumnNumber(const struct ZigClangSourceManager *,
+ struct ZigClangSourceLocation Loc);
+ZIG_EXTERN_C const char* ZigClangSourceManager_getCharacterData(const struct ZigClangSourceManager *,
+ struct ZigClangSourceLocation SL);
+
+ZIG_EXTERN_C struct ZigClangQualType ZigClangASTContext_getPointerType(const struct ZigClangASTContext*, struct ZigClangQualType T);
+
+ZIG_EXTERN_C struct ZigClangASTContext *ZigClangASTUnit_getASTContext(struct ZigClangASTUnit *);
+ZIG_EXTERN_C struct ZigClangSourceManager *ZigClangASTUnit_getSourceManager(struct ZigClangASTUnit *);
+ZIG_EXTERN_C bool ZigClangASTUnit_visitLocalTopLevelDecls(struct ZigClangASTUnit *, void *context,
+ bool (*Fn)(void *context, const struct ZigClangDecl *decl));
+
+ZIG_EXTERN_C const struct ZigClangRecordDecl *ZigClangRecordType_getDecl(const struct ZigClangRecordType *record_ty);
+ZIG_EXTERN_C const struct ZigClangEnumDecl *ZigClangEnumType_getDecl(const struct ZigClangEnumType *record_ty);
+
+ZIG_EXTERN_C const struct ZigClangTagDecl *ZigClangRecordDecl_getCanonicalDecl(const struct ZigClangRecordDecl *record_decl);
+ZIG_EXTERN_C const struct ZigClangTagDecl *ZigClangEnumDecl_getCanonicalDecl(const struct ZigClangEnumDecl *);
+ZIG_EXTERN_C const struct ZigClangTypedefNameDecl *ZigClangTypedefNameDecl_getCanonicalDecl(const struct ZigClangTypedefNameDecl *);
+
+ZIG_EXTERN_C const struct ZigClangRecordDecl *ZigClangRecordDecl_getDefinition(const struct ZigClangRecordDecl *);
+ZIG_EXTERN_C const struct ZigClangEnumDecl *ZigClangEnumDecl_getDefinition(const struct ZigClangEnumDecl *);
+
+ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangRecordDecl_getLocation(const struct ZigClangRecordDecl *);
+ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangEnumDecl_getLocation(const struct ZigClangEnumDecl *);
+ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangTypedefNameDecl_getLocation(const struct ZigClangTypedefNameDecl *);
+
+ZIG_EXTERN_C bool ZigClangRecordDecl_isUnion(const struct ZigClangRecordDecl *record_decl);
+ZIG_EXTERN_C bool ZigClangRecordDecl_isStruct(const struct ZigClangRecordDecl *record_decl);
+ZIG_EXTERN_C bool ZigClangRecordDecl_isAnonymousStructOrUnion(const struct ZigClangRecordDecl *record_decl);
+
+ZIG_EXTERN_C struct ZigClangQualType ZigClangEnumDecl_getIntegerType(const struct ZigClangEnumDecl *);
+
+ZIG_EXTERN_C const char *ZigClangDecl_getName_bytes_begin(const struct ZigClangDecl *decl);
+
+ZIG_EXTERN_C bool ZigClangSourceLocation_eq(struct ZigClangSourceLocation a, struct ZigClangSourceLocation b);
+
+ZIG_EXTERN_C const struct ZigClangTypedefNameDecl *ZigClangTypedefType_getDecl(const struct ZigClangTypedefType *);
+ZIG_EXTERN_C struct ZigClangQualType ZigClangTypedefNameDecl_getUnderlyingType(const struct ZigClangTypedefNameDecl *);
+
+ZIG_EXTERN_C struct ZigClangQualType ZigClangQualType_getCanonicalType(struct ZigClangQualType);
+ZIG_EXTERN_C const struct ZigClangType *ZigClangQualType_getTypePtr(struct ZigClangQualType);
+ZIG_EXTERN_C void ZigClangQualType_addConst(struct ZigClangQualType *);
+ZIG_EXTERN_C bool ZigClangQualType_eq(struct ZigClangQualType, struct ZigClangQualType);
+ZIG_EXTERN_C bool ZigClangQualType_isConstQualified(struct ZigClangQualType);
+ZIG_EXTERN_C bool ZigClangQualType_isVolatileQualified(struct ZigClangQualType);
+ZIG_EXTERN_C bool ZigClangQualType_isRestrictQualified(struct ZigClangQualType);
+
+ZIG_EXTERN_C enum ZigClangTypeClass ZigClangType_getTypeClass(const struct ZigClangType *self);
+ZIG_EXTERN_C bool ZigClangType_isVoidType(const struct ZigClangType *self);
+ZIG_EXTERN_C const char *ZigClangType_getTypeClassName(const struct ZigClangType *self);
+
+ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangStmt_getBeginLoc(const struct ZigClangStmt *self);
+ZIG_EXTERN_C enum ZigClangStmtClass ZigClangStmt_getStmtClass(const struct ZigClangStmt *self);
+ZIG_EXTERN_C bool ZigClangStmt_classof_Expr(const struct ZigClangStmt *self);
+
+ZIG_EXTERN_C enum ZigClangStmtClass ZigClangExpr_getStmtClass(const struct ZigClangExpr *self);
+ZIG_EXTERN_C struct ZigClangQualType ZigClangExpr_getType(const struct ZigClangExpr *self);
+ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangExpr_getBeginLoc(const struct ZigClangExpr *self);
+
+ZIG_EXTERN_C enum ZigClangAPValueKind ZigClangAPValue_getKind(const struct ZigClangAPValue *self);
+ZIG_EXTERN_C const struct ZigClangAPSInt *ZigClangAPValue_getInt(const struct ZigClangAPValue *self);
+ZIG_EXTERN_C unsigned ZigClangAPValue_getArrayInitializedElts(const struct ZigClangAPValue *self);
+ZIG_EXTERN_C const struct ZigClangAPValue *ZigClangAPValue_getArrayInitializedElt(const struct ZigClangAPValue *self, unsigned i);
+ZIG_EXTERN_C const struct ZigClangAPValue *ZigClangAPValue_getArrayFiller(const struct ZigClangAPValue *self);
+ZIG_EXTERN_C unsigned ZigClangAPValue_getArraySize(const struct ZigClangAPValue *self);
+ZIG_EXTERN_C struct ZigClangAPValueLValueBase ZigClangAPValue_getLValueBase(const struct ZigClangAPValue *self);
+
+ZIG_EXTERN_C bool ZigClangAPSInt_isSigned(const struct ZigClangAPSInt *self);
+ZIG_EXTERN_C bool ZigClangAPSInt_isNegative(const struct ZigClangAPSInt *self);
+ZIG_EXTERN_C const struct ZigClangAPSInt *ZigClangAPSInt_negate(const struct ZigClangAPSInt *self);
+ZIG_EXTERN_C void ZigClangAPSInt_free(const struct ZigClangAPSInt *self);
+ZIG_EXTERN_C const uint64_t *ZigClangAPSInt_getRawData(const struct ZigClangAPSInt *self);
+ZIG_EXTERN_C unsigned ZigClangAPSInt_getNumWords(const struct ZigClangAPSInt *self);
+
+ZIG_EXTERN_C const struct ZigClangExpr *ZigClangAPValueLValueBase_dyn_cast_Expr(struct ZigClangAPValueLValueBase self);
#endif
diff --git a/std/c.zig b/std/c.zig
index acff9229d1..ecbc55890a 100644
--- a/std/c.zig
+++ b/std/c.zig
@@ -12,6 +12,10 @@ pub use switch (builtin.os) {
// TODO https://github.com/ziglang/zig/issues/265 on this whole file
+pub const FILE = @OpaqueType();
+pub extern "c" fn fwrite(ptr: [*]const u8, size_of_type: usize, item_count: usize, stream: *FILE) usize;
+pub extern "c" fn fread(ptr: [*]u8, size_of_type: usize, item_count: usize, stream: *FILE) usize;
+
pub extern "c" fn abort() noreturn;
pub extern "c" fn exit(code: c_int) noreturn;
pub extern "c" fn isatty(fd: c_int) c_int;
diff --git a/std/io.zig b/std/io.zig
index afbd8198fd..5ad35c91fb 100644
--- a/std/io.zig
+++ b/std/io.zig
@@ -36,6 +36,7 @@ pub fn getStdIn() GetStdIoErrs!File {
}
pub const SeekableStream = @import("io/seekable_stream.zig").SeekableStream;
+pub const COutStream = @import("io/c_out_stream.zig").COutStream;
pub fn InStream(comptime ReadError: type) type {
return struct {
@@ -1089,8 +1090,10 @@ test "io.readLineSliceFrom" {
}
pub const Packing = enum {
- Byte, /// Pack data to byte alignment
- Bit, /// Pack data to bit alignment
+ /// Pack data to byte alignment
+ Byte,
+ /// Pack data to bit alignment
+ Bit,
};
/// Creates a deserializer that deserializes types from any stream.
@@ -1111,10 +1114,12 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
pub const Stream = InStream(Error);
pub fn init(in_stream: *Stream) Self {
- return Self{ .in_stream = switch (packing) {
- .Bit => BitInStream(endian, Stream.Error).init(in_stream),
- .Byte => in_stream,
- } };
+ return Self{
+ .in_stream = switch (packing) {
+ .Bit => BitInStream(endian, Stream.Error).init(in_stream),
+ .Byte => in_stream,
+ },
+ };
}
pub fn alignToByte(self: *Self) void {
@@ -1281,7 +1286,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
ptr.* = null;
return;
}
-
+
ptr.* = OC(undefined); //make it non-null so the following .? is guaranteed safe
const val_ptr = &ptr.*.?;
try self.deserializeInto(val_ptr);
@@ -1320,10 +1325,12 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co
pub const Stream = OutStream(Error);
pub fn init(out_stream: *Stream) Self {
- return Self{ .out_stream = switch (packing) {
- .Bit => BitOutStream(endian, Stream.Error).init(out_stream),
- .Byte => out_stream,
- } };
+ return Self{
+ .out_stream = switch (packing) {
+ .Bit => BitOutStream(endian, Stream.Error).init(out_stream),
+ .Byte => out_stream,
+ },
+ };
}
/// Flushes any unwritten bits to the stream
@@ -1450,4 +1457,3 @@ test "import io tests" {
_ = @import("io_test.zig");
}
}
-
diff --git a/std/io/c_out_stream.zig b/std/io/c_out_stream.zig
new file mode 100644
index 0000000000..398668979e
--- /dev/null
+++ b/std/io/c_out_stream.zig
@@ -0,0 +1,44 @@
+const std = @import("../std.zig");
+const OutStream = std.io.OutStream;
+const builtin = @import("builtin");
+const posix = std.os.posix;
+
+/// TODO make std.os.FILE use *FILE when linking libc and this just becomes
+/// std.io.FileOutStream because std.os.File.write would do this when linking
+/// libc.
+pub const COutStream = struct {
+ pub const Error = std.os.File.WriteError;
+ pub const Stream = OutStream(Error);
+
+ stream: Stream,
+ c_file: *std.c.FILE,
+
+ pub fn init(c_file: *std.c.FILE) COutStream {
+ return COutStream{
+ .c_file = c_file,
+ .stream = Stream{ .writeFn = writeFn },
+ };
+ }
+
+ fn writeFn(out_stream: *Stream, bytes: []const u8) Error!void {
+ const self = @fieldParentPtr(COutStream, "stream", out_stream);
+ const amt_written = std.c.fwrite(bytes.ptr, 1, bytes.len, self.c_file);
+ if (amt_written == bytes.len) return;
+ const errno = std.c._errno().*;
+ switch (errno) {
+ 0 => unreachable,
+ posix.EINVAL => unreachable,
+ posix.EFAULT => unreachable,
+ posix.EAGAIN => unreachable, // this is a blocking API
+ posix.EBADF => unreachable, // always a race condition
+ posix.EDESTADDRREQ => unreachable, // connect was never called
+ posix.EDQUOT => return error.DiskQuota,
+ posix.EFBIG => return error.FileTooBig,
+ posix.EIO => return error.InputOutput,
+ posix.ENOSPC => return error.NoSpaceLeft,
+ posix.EPERM => return error.AccessDenied,
+ posix.EPIPE => return error.BrokenPipe,
+ else => return std.os.unexpectedErrorPosix(@intCast(usize, errno)),
+ }
+ }
+};
--
cgit v1.2.3
From 712274997e80a93bdfe204f2238c4cfaac72a5b8 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Sun, 21 Apr 2019 19:37:39 -0400
Subject: translate-c: unify API for self-hosted and C++ translate-c
See #1964
---
src-self-hosted/clang.zig | 17 ++++++
src-self-hosted/main.zig | 18 ++++++-
src-self-hosted/stage1.zig | 35 ++++++-------
src-self-hosted/translate_c.zig | 13 ++++-
src/codegen.cpp | 49 +++++++++++-------
src/ir.cpp | 19 ++++---
src/translate_c.cpp | 86 ++++--------------------------
src/translate_c.hpp | 6 ++-
src/userland.cpp | 9 +++-
src/userland.h | 46 +++++++++++++----
src/zig_clang.cpp | 112 ++++++++++++++++++++++++++++++++++++++++
src/zig_clang.h | 14 ++---
12 files changed, 281 insertions(+), 143 deletions(-)
(limited to 'src/ir.cpp')
diff --git a/src-self-hosted/clang.zig b/src-self-hosted/clang.zig
index 6f7c7eb853..a9cf06f8a5 100644
--- a/src-self-hosted/clang.zig
+++ b/src-self-hosted/clang.zig
@@ -862,6 +862,7 @@ pub extern fn ZigClangAPSInt_free(self: ?*const struct_ZigClangAPSInt) void;
pub extern fn ZigClangAPSInt_getRawData(self: ?*const struct_ZigClangAPSInt) [*c]const u64;
pub extern fn ZigClangAPSInt_getNumWords(self: ?*const struct_ZigClangAPSInt) c_uint;
pub extern fn ZigClangAPValueLValueBase_dyn_cast_Expr(self: struct_ZigClangAPValueLValueBase) ?*const struct_ZigClangExpr;
+pub extern fn ZigClangASTUnit_delete(arg0: ?*struct_ZigClangASTUnit) void;
pub const ZigClangSourceLocation = struct_ZigClangSourceLocation;
pub const ZigClangQualType = struct_ZigClangQualType;
pub const ZigClangAPValueLValueBase = struct_ZigClangAPValueLValueBase;
@@ -942,3 +943,19 @@ pub const ZigClangTypeClass = enum_ZigClangTypeClass;
pub const ZigClangStmtClass = enum_ZigClangStmtClass;
pub const ZigClangCK = enum_ZigClangCK;
pub const ZigClangAPValueKind = enum_ZigClangAPValueKind;
+
+pub const Stage2ErrorMsg = extern struct {
+ filename_ptr: ?[*]const u8,
+ filename_len: usize,
+ msg_ptr: [*]const u8,
+ msg_len: usize,
+ // valid until the ASTUnit is freed
+ source: ?[*]const u8,
+ // 0 based
+ line: c_uint,
+ // 0 based
+ column: c_uint,
+ // byte offset into source
+ offset: c_uint,
+};
+pub extern fn ZigClangErrorMsg_delete(ptr: [*c]Stage2ErrorMsg, len: usize) void;
diff --git a/src-self-hosted/main.zig b/src-self-hosted/main.zig
index 361afc80e3..759a84cb34 100644
--- a/src-self-hosted/main.zig
+++ b/src-self-hosted/main.zig
@@ -858,7 +858,23 @@ fn cmdHelp(allocator: *Allocator, args: []const []const u8) !void {
try stdout.write(usage);
}
-const info_zen = @import("stage1.zig").info_zen;
+pub const info_zen =
+ \\
+ \\ * Communicate intent precisely.
+ \\ * Edge cases matter.
+ \\ * Favor reading code over writing code.
+ \\ * Only one obvious way to do things.
+ \\ * Runtime crashes are better than bugs.
+ \\ * Compile errors are better than runtime crashes.
+ \\ * Incremental improvements.
+ \\ * Avoid local maximums.
+ \\ * Reduce the amount one must remember.
+ \\ * Minimize energy spent on coding style.
+ \\ * Together we serve end users.
+ \\
+ \\
+;
+
fn cmdZen(allocator: *Allocator, args: []const []const u8) !void {
try stdout.write(info_zen);
}
diff --git a/src-self-hosted/stage1.zig b/src-self-hosted/stage1.zig
index cf5f06c285..53bc1eeb69 100644
--- a/src-self-hosted/stage1.zig
+++ b/src-self-hosted/stage1.zig
@@ -3,37 +3,25 @@
const std = @import("std");
-pub const info_zen =
- \\
- \\ * Communicate intent precisely.
- \\ * Edge cases matter.
- \\ * Favor reading code over writing code.
- \\ * Only one obvious way to do things.
- \\ * Runtime crashes are better than bugs.
- \\ * Compile errors are better than runtime crashes.
- \\ * Incremental improvements.
- \\ * Avoid local maximums.
- \\ * Reduce the amount one must remember.
- \\ * Minimize energy spent on coding style.
- \\ * Together we serve end users.
- \\
- \\
-;
-
+// ABI warning
export fn stage2_zen(ptr: *[*]const u8, len: *usize) void {
+ const info_zen = @import("main.zig").info_zen;
ptr.* = &info_zen;
len.* = info_zen.len;
}
+// ABI warning
export fn stage2_panic(ptr: [*]const u8, len: usize) void {
@panic(ptr[0..len]);
}
+// ABI warning
const TranslateMode = extern enum {
import,
translate,
};
+// ABI warning
const Error = extern enum {
None,
OutOfMemory,
@@ -84,24 +72,33 @@ const Error = extern enum {
const FILE = std.c.FILE;
const ast = std.zig.ast;
+const translate_c = @import("translate_c.zig");
/// Args should have a null terminating last arg.
export fn stage2_translate_c(
out_ast: **ast.Tree,
+ out_errors_ptr: *[*]translate_c.ClangErrMsg,
+ out_errors_len: *usize,
args_begin: [*]?[*]const u8,
args_end: [*]?[*]const u8,
mode: TranslateMode,
+ resources_path: [*]const u8,
) Error {
- const translate_c = @import("translate_c.zig");
+ var errors: []translate_c.ClangErrMsg = undefined;
out_ast.* = translate_c.translate(args_begin, args_end, switch (mode) {
.import => translate_c.Mode.import,
.translate => translate_c.Mode.translate,
- }) catch |err| switch (err) {
+ }, &errors) catch |err| switch (err) {
error.Unimplemented => return Error.Unimplemented,
};
+
return Error.None;
}
+export fn stage2_free_clang_errors(errors_ptr: [*]translate_c.ClangErrMsg, errors_len: usize) void {
+ translate_c.freeErrors(errors_ptr[0..errors_len]);
+}
+
export fn stage2_render_ast(tree: *ast.Tree, output_file: *FILE) Error {
const c_out_stream = &std.io.COutStream.init(output_file).stream;
_ = std.zig.render(std.heap.c_allocator, c_out_stream, tree) catch |e| switch (e) {
diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig
index c2d943b1ff..b2dcfffeb3 100644
--- a/src-self-hosted/translate_c.zig
+++ b/src-self-hosted/translate_c.zig
@@ -10,6 +10,17 @@ pub const Mode = enum {
translate,
};
-pub fn translate(args_begin: [*]?[*]const u8, args_end: [*]?[*]const u8, mode: Mode) !*ast.Tree {
+pub const ClangErrMsg = Stage2ErrorMsg;
+
+pub fn translate(
+ args_begin: [*]?[*]const u8,
+ args_end: [*]?[*]const u8,
+ mode: Mode,
+ errors: *[]ClangErrMsg,
+) !*ast.Tree {
return error.Unimplemented;
}
+
+pub fn freeErrors(errors: []ClangErrMsg) void {
+ ZigClangErrorMsg_delete(errors.ptr, errors.len);
+}
diff --git a/src/codegen.cpp b/src/codegen.cpp
index b4ea0a9a96..27e2195a3c 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -8298,31 +8298,42 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_us
clang_argv.append(nullptr); // to make the [start...end] argument work
+ const char *resources_path = buf_ptr(g->zig_c_headers_dir);
+ Stage2ErrorMsg *errors_ptr;
+ size_t errors_len;
+ Stage2Ast *ast;
+ AstNode *root_node;
+
if (use_userland_implementation) {
- Stage2Ast *ast;
- if ((err = stage2_translate_c(&ast, &clang_argv.at(0), &clang_argv.last(), trans_mode))) {
- zig_panic("TODO");
- }
- stage2_render_ast(ast, out_file);
+ err = stage2_translate_c(&ast, &errors_ptr, &errors_len,
+ &clang_argv.at(0), &clang_argv.last(), trans_mode, resources_path);
} else {
- ZigList errors = {0};
- AstNode *root_node;
-
- err = parse_h_file(g, &root_node, &clang_argv.at(0), &clang_argv.last(), trans_mode, &errors);
+ err = parse_h_file(g, &root_node, &errors_ptr, &errors_len, &clang_argv.at(0), &clang_argv.last(),
+ trans_mode, resources_path);
+ }
- if (err == ErrorCCompileErrors && errors.length > 0) {
- for (size_t i = 0; i < errors.length; i += 1) {
- ErrorMsg *err_msg = errors.at(i);
- print_err_msg(err_msg, g->err_color);
- }
- exit(1);
+ if (err == ErrorCCompileErrors && errors_len > 0) {
+ for (size_t i = 0; i < errors_len; i += 1) {
+ Stage2ErrorMsg *clang_err = &errors_ptr[i];
+ ErrorMsg *err_msg = err_msg_create_with_offset(
+ clang_err->filename_ptr ?
+ buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(),
+ clang_err->line, clang_err->column, clang_err->offset, clang_err->source,
+ buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len));
+ print_err_msg(err_msg, g->err_color);
}
+ exit(1);
+ }
- if (err) {
- fprintf(stderr, "unable to parse C file: %s\n", err_str(err));
- exit(1);
- }
+ if (err) {
+ fprintf(stderr, "unable to parse C file: %s\n", err_str(err));
+ exit(1);
+ }
+
+ if (use_userland_implementation) {
+ stage2_render_ast(ast, out_file);
+ } else {
ast_render(out_file, root_node, 4);
}
}
diff --git a/src/ir.cpp b/src/ir.cpp
index 105dd0c3d6..3f74741995 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -19103,25 +19103,32 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
clang_argv.append(nullptr); // to make the [start...end] argument work
- ZigList errors = {0};
AstNode *root_node;
+ Stage2ErrorMsg *errors_ptr;
+ size_t errors_len;
- if ((err = parse_h_file(ira->codegen, &root_node, &clang_argv.at(0), &clang_argv.last(),
- Stage2TranslateModeImport, &errors)))
+ const char *resources_path = buf_ptr(ira->codegen->zig_c_headers_dir);
+
+ if ((err = parse_h_file(ira->codegen, &root_node, &errors_ptr, &errors_len,
+ &clang_argv.at(0), &clang_argv.last(), Stage2TranslateModeImport, resources_path)))
{
if (err != ErrorCCompileErrors) {
ir_add_error_node(ira, node, buf_sprintf("C import failed: %s", err_str(err)));
return ira->codegen->invalid_instruction;
}
- assert(errors.length > 0);
ErrorMsg *parent_err_msg = ir_add_error_node(ira, node, buf_sprintf("C import failed"));
if (ira->codegen->libc_link_lib == nullptr) {
add_error_note(ira->codegen, parent_err_msg, node,
buf_sprintf("libc headers not available; compilation does not link against libc"));
}
- for (size_t i = 0; i < errors.length; i += 1) {
- ErrorMsg *err_msg = errors.at(i);
+ for (size_t i = 0; i < errors_len; i += 1) {
+ Stage2ErrorMsg *clang_err = &errors_ptr[i];
+ ErrorMsg *err_msg = err_msg_create_with_offset(
+ clang_err->filename_ptr ?
+ buf_create_from_mem(clang_err->filename_ptr, clang_err->filename_len) : buf_alloc(),
+ clang_err->line, clang_err->column, clang_err->offset, clang_err->source,
+ buf_create_from_mem(clang_err->msg_ptr, clang_err->msg_len));
err_msg_add_note(parent_err_msg, err_msg);
}
diff --git a/src/translate_c.cpp b/src/translate_c.cpp
index d19083ce73..1c8d8e51b3 100644
--- a/src/translate_c.cpp
+++ b/src/translate_c.cpp
@@ -76,10 +76,9 @@ struct TransScopeWhile {
};
struct Context {
- ZigList *errors;
+ AstNode *root;
VisibMod visib_mod;
bool want_export;
- AstNode *root;
HashMap decl_table;
HashMap macro_table;
HashMap global_table;
@@ -5018,13 +5017,14 @@ static void process_preprocessor_entities(Context *c, ZigClangASTUnit *zunit) {
}
}
-Error parse_h_file(CodeGen *codegen, AstNode **out_root_node, const char **args_begin, const char **args_end,
- Stage2TranslateMode mode, ZigList *errors)
+Error parse_h_file(CodeGen *codegen, AstNode **out_root_node,
+ Stage2ErrorMsg **errors_ptr, size_t *errors_len,
+ const char **args_begin, const char **args_end,
+ Stage2TranslateMode mode, const char *resources_path)
{
Context context = {0};
Context *c = &context;
c->warnings_on = codegen->verbose_cimport;
- c->errors = errors;
if (mode == Stage2TranslateModeImport) {
c->visib_mod = VisibModPub;
c->want_export = false;
@@ -5039,78 +5039,10 @@ Error parse_h_file(CodeGen *codegen, AstNode **out_root_node, const char **args_
c->codegen = codegen;
c->global_scope = trans_scope_root_create(c);
-
- clang::IntrusiveRefCntPtr diags(clang::CompilerInstance::createDiagnostics(new clang::DiagnosticOptions));
-
- std::shared_ptr pch_container_ops = std::make_shared();
-
- bool only_local_decls = true;
- bool capture_diagnostics = true;
- bool user_files_are_volatile = true;
- bool allow_pch_with_compiler_errors = false;
- bool single_file_parse = false;
- bool for_serialization = false;
- const char *resources_path = buf_ptr(codegen->zig_c_headers_dir);
- std::unique_ptr err_unit;
- ZigClangASTUnit *ast_unit = reinterpret_cast(clang::ASTUnit::LoadFromCommandLine(
- args_begin, args_end,
- pch_container_ops, diags, resources_path,
- only_local_decls, capture_diagnostics, clang::None, true, 0, clang::TU_Complete,
- false, false, allow_pch_with_compiler_errors, clang::SkipFunctionBodiesScope::None,
- single_file_parse, user_files_are_volatile, for_serialization, clang::None, &err_unit,
- nullptr));
-
- // Early failures in LoadFromCommandLine may return with ErrUnit unset.
- if (!ast_unit && !err_unit) {
- return ErrorFileSystem;
- }
-
- if (diags->getClient()->getNumErrors() > 0) {
- if (ast_unit) {
- err_unit = std::unique_ptr(reinterpret_cast(ast_unit));
- }
-
- for (clang::ASTUnit::stored_diag_iterator it = err_unit->stored_diag_begin(),
- it_end = err_unit->stored_diag_end();
- it != it_end; ++it)
- {
- switch (it->getLevel()) {
- case clang::DiagnosticsEngine::Ignored:
- case clang::DiagnosticsEngine::Note:
- case clang::DiagnosticsEngine::Remark:
- case clang::DiagnosticsEngine::Warning:
- continue;
- case clang::DiagnosticsEngine::Error:
- case clang::DiagnosticsEngine::Fatal:
- break;
- }
- llvm::StringRef msg_str_ref = it->getMessage();
- Buf *msg = string_ref_to_buf(msg_str_ref);
- clang::FullSourceLoc fsl = it->getLocation();
- if (fsl.hasManager()) {
- clang::FileID file_id = fsl.getFileID();
- clang::StringRef filename = fsl.getManager().getFilename(fsl);
- unsigned line = fsl.getSpellingLineNumber() - 1;
- unsigned column = fsl.getSpellingColumnNumber() - 1;
- unsigned offset = fsl.getManager().getFileOffset(fsl);
- const char *source = (const char *)fsl.getManager().getBufferData(file_id).bytes_begin();
- Buf *path;
- if (filename.empty()) {
- path = buf_alloc();
- } else {
- path = string_ref_to_buf(filename);
- }
-
- ErrorMsg *err_msg = err_msg_create_with_offset(path, line, column, offset, source, msg);
-
- c->errors->append(err_msg);
- } else {
- // NOTE the only known way this gets triggered right now is if you have a lot of errors
- // clang emits "too many errors emitted, stopping now"
- fprintf(stderr, "unexpected error from clang: %s\n", buf_ptr(msg));
- }
- }
-
+ ZigClangASTUnit *ast_unit = ZigClangLoadFromCommandLine(args_begin, args_end, errors_ptr, errors_len,
+ resources_path);
+ if (ast_unit == nullptr) {
+ if (*errors_len == 0) return ErrorNoMem;
return ErrorCCompileErrors;
}
diff --git a/src/translate_c.hpp b/src/translate_c.hpp
index b6e4b6bcbb..4eac26ddb5 100644
--- a/src/translate_c.hpp
+++ b/src/translate_c.hpp
@@ -11,7 +11,9 @@
#include "all_types.hpp"
-Error parse_h_file(CodeGen *codegen, AstNode **out_root_node, const char **args_begin, const char **args_end,
- Stage2TranslateMode mode, ZigList *errors);
+Error parse_h_file(CodeGen *codegen, AstNode **out_root_node,
+ Stage2ErrorMsg **errors_ptr, size_t *errors_len,
+ const char **args_begin, const char **args_end,
+ Stage2TranslateMode mode, const char *resources_path);
#endif
diff --git a/src/userland.cpp b/src/userland.cpp
index 9935d5c04a..fad1450f0d 100644
--- a/src/userland.cpp
+++ b/src/userland.cpp
@@ -8,12 +8,19 @@
#include
Error stage2_translate_c(struct Stage2Ast **out_ast,
- const char **args_begin, const char **args_end, enum Stage2TranslateMode mode)
+ struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len,
+ const char **args_begin, const char **args_end, enum Stage2TranslateMode mode,
+ const char *resources_path)
{
const char *msg = "stage0 called stage2_translate_c";
stage2_panic(msg, strlen(msg));
}
+void stage2_free_clang_errors(struct Stage2ErrorMsg *ptr, size_t len) {
+ const char *msg = "stage0 called stage2_free_clang_errors";
+ stage2_panic(msg, strlen(msg));
+}
+
void stage2_zen(const char **ptr, size_t *len) {
const char *msg = "stage0 called stage2_zen";
stage2_panic(msg, strlen(msg));
diff --git a/src/userland.h b/src/userland.h
index 35fd46942b..ba797d8b25 100644
--- a/src/userland.h
+++ b/src/userland.h
@@ -12,20 +12,21 @@
#include
#ifdef __cplusplus
-#define ZIG_USERLAND_EXTERN_C extern "C"
+#define ZIG_EXTERN_C extern "C"
#else
-#define ZIG_USERLAND_EXTERN_C
+#define ZIG_EXTERN_C
#endif
#if defined(_MSC_VER)
-#define ZIG_USERLAND_ATTRIBUTE_NORETURN __declspec(noreturn)
+#define ZIG_ATTRIBUTE_NORETURN __declspec(noreturn)
#else
-#define ZIG_USERLAND_ATTRIBUTE_NORETURN __attribute__((noreturn))
+#define ZIG_ATTRIBUTE_NORETURN __attribute__((noreturn))
#endif
-// The types and declarations in this file must match both those in userland.cpp and
-// src-self-hosted/stage1.zig.
+// ABI warning: the types and declarations in this file must match both those in
+// userland.cpp and src-self-hosted/stage1.zig.
+// ABI warning
enum Error {
ErrorNone,
ErrorNoMem,
@@ -74,20 +75,43 @@ enum Error {
ErrorNoSpaceLeft,
};
+// ABI warning
enum Stage2TranslateMode {
Stage2TranslateModeImport,
Stage2TranslateModeTranslate,
};
+// ABI warning
+struct Stage2ErrorMsg {
+ const char *filename_ptr; // can be null
+ size_t filename_len;
+ const char *msg_ptr;
+ size_t msg_len;
+ const char *source; // valid until the ASTUnit is freed. can be null
+ unsigned line; // 0 based
+ unsigned column; // 0 based
+ unsigned offset; // byte offset into source
+};
+
+// ABI warning
struct Stage2Ast;
-ZIG_USERLAND_EXTERN_C Error stage2_translate_c(struct Stage2Ast **out_ast,
- const char **args_begin, const char **args_end, enum Stage2TranslateMode mode);
+// ABI warning
+ZIG_EXTERN_C enum Error stage2_translate_c(struct Stage2Ast **out_ast,
+ struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len,
+ const char **args_begin, const char **args_end, enum Stage2TranslateMode mode,
+ const char *resources_path);
+
+// ABI warning
+ZIG_EXTERN_C void stage2_free_clang_errors(struct Stage2ErrorMsg *ptr, size_t len);
-ZIG_USERLAND_EXTERN_C void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file);
+// ABI warning
+ZIG_EXTERN_C void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file);
-ZIG_USERLAND_EXTERN_C void stage2_zen(const char **ptr, size_t *len);
+// ABI warning
+ZIG_EXTERN_C void stage2_zen(const char **ptr, size_t *len);
-ZIG_USERLAND_EXTERN_C ZIG_USERLAND_ATTRIBUTE_NORETURN void stage2_panic(const char *ptr, size_t len);
+// ABI warning
+ZIG_EXTERN_C ZIG_ATTRIBUTE_NORETURN void stage2_panic(const char *ptr, size_t len);
#endif
diff --git a/src/zig_clang.cpp b/src/zig_clang.cpp
index 6142c808ad..cc79941190 100644
--- a/src/zig_clang.cpp
+++ b/src/zig_clang.cpp
@@ -1147,3 +1147,115 @@ ZigClangAPValueLValueBase ZigClangAPValue_getLValueBase(const ZigClangAPValue *s
clang::APValue::LValueBase lval_base = casted->getLValueBase();
return bitcast(lval_base);
}
+
+ZigClangASTUnit *ZigClangLoadFromCommandLine(const char **args_begin, const char **args_end,
+ struct Stage2ErrorMsg **errors_ptr, size_t *errors_len, const char *resources_path)
+{
+ clang::IntrusiveRefCntPtr diags(clang::CompilerInstance::createDiagnostics(new clang::DiagnosticOptions));
+
+ std::shared_ptr pch_container_ops = std::make_shared();
+
+ bool only_local_decls = true;
+ bool capture_diagnostics = true;
+ bool user_files_are_volatile = true;
+ bool allow_pch_with_compiler_errors = false;
+ bool single_file_parse = false;
+ bool for_serialization = false;
+ std::unique_ptr *err_unit = new std::unique_ptr();
+ clang::ASTUnit *ast_unit = clang::ASTUnit::LoadFromCommandLine(
+ args_begin, args_end,
+ pch_container_ops, diags, resources_path,
+ only_local_decls, capture_diagnostics, clang::None, true, 0, clang::TU_Complete,
+ false, false, allow_pch_with_compiler_errors, clang::SkipFunctionBodiesScope::None,
+ single_file_parse, user_files_are_volatile, for_serialization, clang::None, err_unit,
+ nullptr);
+
+ // Early failures in LoadFromCommandLine may return with ErrUnit unset.
+ if (!ast_unit && !err_unit) {
+ return nullptr;
+ }
+
+ if (diags->getClient()->getNumErrors() > 0) {
+ if (ast_unit) {
+ *err_unit = std::unique_ptr(ast_unit);
+ }
+
+ size_t cap = 4;
+ *errors_len = 0;
+ *errors_ptr = reinterpret_cast(malloc(cap * sizeof(Stage2ErrorMsg)));
+ if (*errors_ptr == nullptr) {
+ return nullptr;
+ }
+
+ for (clang::ASTUnit::stored_diag_iterator it = (*err_unit)->stored_diag_begin(),
+ it_end = (*err_unit)->stored_diag_end();
+ it != it_end; ++it)
+ {
+ switch (it->getLevel()) {
+ case clang::DiagnosticsEngine::Ignored:
+ case clang::DiagnosticsEngine::Note:
+ case clang::DiagnosticsEngine::Remark:
+ case clang::DiagnosticsEngine::Warning:
+ continue;
+ case clang::DiagnosticsEngine::Error:
+ case clang::DiagnosticsEngine::Fatal:
+ break;
+ }
+ llvm::StringRef msg_str_ref = it->getMessage();
+ if (*errors_len >= cap) {
+ cap *= 2;
+ Stage2ErrorMsg *new_errors = reinterpret_cast(
+ realloc(*errors_ptr, cap * sizeof(Stage2ErrorMsg)));
+ if (new_errors == nullptr) {
+ free(*errors_ptr);
+ *errors_ptr = nullptr;
+ *errors_len = 0;
+ return nullptr;
+ }
+ *errors_ptr = new_errors;
+ }
+ Stage2ErrorMsg *msg = *errors_ptr + *errors_len;
+ *errors_len += 1;
+ msg->msg_ptr = (const char *)msg_str_ref.bytes_begin();
+ msg->msg_len = msg_str_ref.size();
+
+ clang::FullSourceLoc fsl = it->getLocation();
+ if (fsl.hasManager()) {
+ clang::FileID file_id = fsl.getFileID();
+ clang::StringRef filename = fsl.getManager().getFilename(fsl);
+ if (filename.empty()) {
+ msg->filename_ptr = nullptr;
+ } else {
+ msg->filename_ptr = (const char *)filename.bytes_begin();
+ msg->filename_len = filename.size();
+ }
+ msg->source = (const char *)fsl.getManager().getBufferData(file_id).bytes_begin();
+ msg->line = fsl.getSpellingLineNumber() - 1;
+ msg->column = fsl.getSpellingColumnNumber() - 1;
+ msg->offset = fsl.getManager().getFileOffset(fsl);
+ } else {
+ // The only known way this gets triggered right now is if you have a lot of errors
+ // clang emits "too many errors emitted, stopping now"
+ msg->filename_ptr = nullptr;
+ msg->source = nullptr;
+ }
+ }
+
+ if (*errors_len == 0) {
+ free(*errors_ptr);
+ *errors_ptr = nullptr;
+ }
+
+ return nullptr;
+ }
+
+ return reinterpret_cast(ast_unit);
+}
+
+void ZigClangErrorMsg_delete(Stage2ErrorMsg *ptr, size_t len) {
+ free(ptr);
+}
+
+void ZigClangASTUnit_delete(struct ZigClangASTUnit *self) {
+ delete reinterpret_cast(self);
+}
diff --git a/src/zig_clang.h b/src/zig_clang.h
index 148ee34f51..f237449527 100644
--- a/src/zig_clang.h
+++ b/src/zig_clang.h
@@ -8,15 +8,10 @@
#ifndef ZIG_ZIG_CLANG_H
#define ZIG_ZIG_CLANG_H
+#include "userland.h"
#include
#include
-#ifdef __cplusplus
-#define ZIG_EXTERN_C extern "C"
-#else
-#define ZIG_EXTERN_C
-#endif
-
// ATTENTION: If you modify this file, be sure to update the corresponding
// extern function declarations in the self-hosted compiler file
// src-self-hosted/clang.zig.
@@ -500,6 +495,13 @@ ZIG_EXTERN_C const char* ZigClangSourceManager_getCharacterData(const struct Zig
ZIG_EXTERN_C struct ZigClangQualType ZigClangASTContext_getPointerType(const struct ZigClangASTContext*, struct ZigClangQualType T);
+
+// Can return null.
+ZIG_EXTERN_C struct ZigClangASTUnit *ZigClangLoadFromCommandLine(const char **args_begin, const char **args_end,
+ struct Stage2ErrorMsg **errors_ptr, size_t *errors_len, const char *resources_path);
+ZIG_EXTERN_C void ZigClangASTUnit_delete(struct ZigClangASTUnit *);
+ZIG_EXTERN_C void ZigClangErrorMsg_delete(struct Stage2ErrorMsg *ptr, size_t len);
+
ZIG_EXTERN_C struct ZigClangASTContext *ZigClangASTUnit_getASTContext(struct ZigClangASTUnit *);
ZIG_EXTERN_C struct ZigClangSourceManager *ZigClangASTUnit_getSourceManager(struct ZigClangASTUnit *);
ZIG_EXTERN_C bool ZigClangASTUnit_visitLocalTopLevelDecls(struct ZigClangASTUnit *, void *context,
--
cgit v1.2.3
From e1bf74fca3de7943b8f7c15be4da3dbc8e3da17e Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Sun, 21 Apr 2019 20:19:48 -0400
Subject: translate-c: put -x c back in there, it's necessary
---
src/codegen.cpp | 21 +++++++++++++--------
src/ir.cpp | 9 ++++++++-
src/translate_c.cpp | 2 ++
3 files changed, 23 insertions(+), 9 deletions(-)
(limited to 'src/ir.cpp')
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 27e2195a3c..8d39c60ef7 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -8155,6 +8155,11 @@ static void detect_libc(CodeGen *g) {
// does not add the "cc" arg
void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_path, bool translate_c) {
+ if (translate_c) {
+ args.append("-x");
+ args.append("c");
+ }
+
if (out_dep_path != nullptr) {
args.append("-MD");
args.append("-MV");
@@ -8166,13 +8171,6 @@ void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_pa
args.append("-fno-spell-checking");
if (translate_c) {
- // TODO these args shouldn't be special from the non-translate-c args, probably.
- args.append("-nobuiltininc");
- args.append("-nostdinc++");
- if (g->libc_link_lib == nullptr) {
- args.append("-nolibc");
- }
-
// this gives us access to preprocessing entities, presumably at
// the cost of performance
args.append("-Xclang");
@@ -8293,9 +8291,16 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file, bool use_us
ZigList clang_argv = {0};
add_cc_args(g, clang_argv, nullptr, true);
- clang_argv.append("-c");
clang_argv.append(buf_ptr(full_path));
+ if (g->verbose_cc) {
+ fprintf(stderr, "clang");
+ for (size_t i = 0; i < clang_argv.length; i += 1) {
+ fprintf(stderr, " %s", clang_argv.at(i));
+ }
+ fprintf(stderr, "\n");
+ }
+
clang_argv.append(nullptr); // to make the [start...end] argument work
const char *resources_path = buf_ptr(g->zig_c_headers_dir);
diff --git a/src/ir.cpp b/src/ir.cpp
index 3f74741995..a2bd72b197 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -19098,9 +19098,16 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct
add_cc_args(ira->codegen, clang_argv, buf_ptr(tmp_dep_file), true);
- clang_argv.append("-c");
clang_argv.append(buf_ptr(&tmp_c_file_path));
+ if (ira->codegen->verbose_cc) {
+ fprintf(stderr, "clang");
+ for (size_t i = 0; i < clang_argv.length; i += 1) {
+ fprintf(stderr, " %s", clang_argv.at(i));
+ }
+ fprintf(stderr, "\n");
+ }
+
clang_argv.append(nullptr); // to make the [start...end] argument work
AstNode *root_node;
diff --git a/src/translate_c.cpp b/src/translate_c.cpp
index 1c8d8e51b3..f8e57098a6 100644
--- a/src/translate_c.cpp
+++ b/src/translate_c.cpp
@@ -5060,5 +5060,7 @@ Error parse_h_file(CodeGen *codegen, AstNode **out_root_node,
*out_root_node = c->root;
+ ZigClangASTUnit_delete(ast_unit);
+
return ErrorNone;
}
--
cgit v1.2.3
From 9902b604cb01072d4599035b59724731cf03fdbc Mon Sep 17 00:00:00 2001
From: LemonBoy
Date: Sun, 28 Apr 2019 12:45:50 +0200
Subject: Fix generation of container initializers
The code creates temporary ConstExprValue with global_refs set to
nullptr and that's carried over to the final value. Doing so prevents
the deduplication mechanism to work correctly, causing all sorts of
runtime crashes.
Fixes #1636
Fixes #1608 (Even though it was already fixed by #1991)
---
src/ir.cpp | 11 ++++++-----
test/stage1/behavior/struct.zig | 22 ++++++++++++++++++++--
2 files changed, 26 insertions(+), 7 deletions(-)
(limited to 'src/ir.cpp')
diff --git a/src/ir.cpp b/src/ir.cpp
index a2bd72b197..91f931462e 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -9931,6 +9931,7 @@ static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, ZigType *t
static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs) {
ConstGlobalRefs *global_refs = dest->global_refs;
+ assert(!same_global_refs || src->global_refs != nullptr);
*dest = *src;
if (!same_global_refs) {
dest->global_refs = global_refs;
@@ -17468,6 +17469,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
ConstExprValue const_val = {};
const_val.special = ConstValSpecialStatic;
const_val.type = container_type;
+ // const_val.global_refs = allocate(1);
const_val.data.x_struct.fields = create_const_vals(actual_field_count);
for (size_t i = 0; i < instr_field_count; i += 1) {
IrInstructionContainerInitFieldsField *field = &fields[i];
@@ -17531,7 +17533,7 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
if (const_val.special == ConstValSpecialStatic) {
IrInstruction *result = ir_const(ira, instruction, nullptr);
ConstExprValue *out_val = &result->value;
- copy_const_val(out_val, &const_val, true);
+ copy_const_val(out_val, &const_val, false);
out_val->type = container_type;
for (size_t i = 0; i < instr_field_count; i += 1) {
@@ -17603,6 +17605,7 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
ConstExprValue const_val = {};
const_val.special = ConstValSpecialStatic;
const_val.type = fixed_size_array_type;
+ // const_val.global_refs = allocate(1);
const_val.data.x_array.data.s_none.elements = create_const_vals(elem_count);
bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope);
@@ -17639,8 +17642,6 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
if (const_val.special == ConstValSpecialStatic) {
IrInstruction *result = ir_const(ira, &instruction->base, nullptr);
ConstExprValue *out_val = &result->value;
- // Make sure to pass same_global_refs=false here in order not to
- // zero the global_refs field for `result` (#1608)
copy_const_val(out_val, &const_val, false);
result->value.type = fixed_size_array_type;
for (size_t i = 0; i < elem_count; i += 1) {
@@ -21319,7 +21320,7 @@ static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint3
}
IrInstruction *result = ir_const(ira, target, result_type);
- copy_const_val(&result->value, val, false);
+ copy_const_val(&result->value, val, true);
result->value.type = result_type;
return result;
}
@@ -21389,7 +21390,7 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_
}
IrInstruction *result = ir_const(ira, source_instr, dest_type);
- copy_const_val(&result->value, val, false);
+ copy_const_val(&result->value, val, true);
result->value.type = dest_type;
// Keep the bigger alignment, it can only help-
diff --git a/test/stage1/behavior/struct.zig b/test/stage1/behavior/struct.zig
index 62fb41ca28..114f06982b 100644
--- a/test/stage1/behavior/struct.zig
+++ b/test/stage1/behavior/struct.zig
@@ -2,8 +2,7 @@ const std = @import("std");
const expect = std.testing.expect;
const expectEqualSlices = std.testing.expectEqualSlices;
const builtin = @import("builtin");
-const maxInt = std.math.maxInt;
-
+const maxInt = std.math.maxInt;
const StructWithNoFields = struct {
fn add(a: i32, b: i32) i32 {
return a + b;
@@ -505,3 +504,22 @@ test "packed struct with u0 field access" {
var s = S{ .f0 = 0 };
comptime expect(s.f0 == 0);
}
+
+const S0 = struct{
+ bar: S1,
+
+ pub const S1 = struct{
+ value: u8,
+ };
+
+ fn init() @This() {
+ return S0{ .bar = S1{ .value = 123 } };
+ }
+};
+
+var g_foo: S0 = S0.init();
+
+test "access to global struct fields" {
+ g_foo.bar.value = 42;
+ expect(g_foo.bar.value == 42);
+}
--
cgit v1.2.3
From 50bbb34594eedf7a978c00edb525bcea472b554b Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Wed, 8 May 2019 16:06:34 -0400
Subject: C pointers support `null`
See #1967
---
src/codegen.cpp | 22 ++++-----
src/ir.cpp | 97 ++++++++++++++++++++++++++++++++-------
test/compile_errors.zig | 2 +-
test/stage1/behavior/pointers.zig | 28 +++++++++++
4 files changed, 121 insertions(+), 28 deletions(-)
(limited to 'src/ir.cpp')
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 396dfb1f88..712ee908cb 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -4023,19 +4023,19 @@ static LLVMValueRef ir_render_asm(CodeGen *g, IrExecutable *executable, IrInstru
}
static LLVMValueRef gen_non_null_bit(CodeGen *g, ZigType *maybe_type, LLVMValueRef maybe_handle) {
- assert(maybe_type->id == ZigTypeIdOptional);
+ assert(maybe_type->id == ZigTypeIdOptional ||
+ (maybe_type->id == ZigTypeIdPointer && maybe_type->data.pointer.allow_zero));
+
ZigType *child_type = maybe_type->data.maybe.child_type;
- if (!type_has_bits(child_type)) {
+ if (!type_has_bits(child_type))
return maybe_handle;
- } else {
- bool is_scalar = !handle_is_ptr(maybe_type);
- if (is_scalar) {
- return LLVMBuildICmp(g->builder, LLVMIntNE, maybe_handle, LLVMConstNull(get_llvm_type(g, maybe_type)), "");
- } else {
- LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, maybe_handle, maybe_null_index, "");
- return gen_load_untyped(g, maybe_field_ptr, 0, false, "");
- }
- }
+
+ bool is_scalar = !handle_is_ptr(maybe_type);
+ if (is_scalar)
+ return LLVMBuildICmp(g->builder, LLVMIntNE, maybe_handle, LLVMConstNull(get_llvm_type(g, maybe_type)), "");
+
+ LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, maybe_handle, maybe_null_index, "");
+ return gen_load_untyped(g, maybe_field_ptr, 0, false, "");
}
static LLVMValueRef ir_render_test_non_null(CodeGen *g, IrExecutable *executable,
diff --git a/src/ir.cpp b/src/ir.cpp
index 91f931462e..1b0fbd1f7f 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -10283,6 +10283,12 @@ static IrInstruction *ir_const_bool(IrAnalyze *ira, IrInstruction *source_instru
return result;
}
+static IrInstruction *ir_const_undef(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *ty) {
+ IrInstruction *result = ir_const(ira, source_instruction, ty);
+ result->value.special = ConstValSpecialUndef;
+ return result;
+}
+
static IrInstruction *ir_const_void(IrAnalyze *ira, IrInstruction *source_instruction) {
return ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_void);
}
@@ -10596,19 +10602,34 @@ static IrInstruction *ir_analyze_null_to_maybe(IrAnalyze *ira, IrInstruction *so
assert(instr_is_comptime(value));
ConstExprValue *val = ir_resolve_const(ira, value, UndefBad);
- assert(val);
+ assert(val != nullptr);
- IrInstructionConst *const_instruction = ir_create_instruction(&ira->new_irb, source_instr->scope, source_instr->source_node);
- const_instruction->base.value.special = ConstValSpecialStatic;
+ IrInstruction *result = ir_const(ira, source_instr, wanted_type);
+ result->value.special = ConstValSpecialStatic;
if (get_codegen_ptr_type(wanted_type) != nullptr) {
- const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialNull;
+ result->value.data.x_ptr.special = ConstPtrSpecialNull;
} else if (is_opt_err_set(wanted_type)) {
- const_instruction->base.value.data.x_err_set = nullptr;
+ result->value.data.x_err_set = nullptr;
} else {
- const_instruction->base.value.data.x_optional = nullptr;
+ result->value.data.x_optional = nullptr;
}
- const_instruction->base.value.type = wanted_type;
- return &const_instruction->base;
+ return result;
+}
+
+static IrInstruction *ir_analyze_null_to_c_pointer(IrAnalyze *ira, IrInstruction *source_instr,
+ IrInstruction *value, ZigType *wanted_type)
+{
+ assert(wanted_type->id == ZigTypeIdPointer);
+ assert(wanted_type->data.pointer.ptr_len == PtrLenC);
+ assert(instr_is_comptime(value));
+
+ ConstExprValue *val = ir_resolve_const(ira, value, UndefBad);
+ assert(val != nullptr);
+
+ IrInstruction *result = ir_const(ira, source_instr, wanted_type);
+ result->value.data.x_ptr.special = ConstPtrSpecialNull;
+ result->value.data.x_ptr.mut = ConstPtrMutComptimeConst;
+ return result;
}
static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *value,
@@ -11610,6 +11631,13 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
return ir_analyze_null_to_maybe(ira, source_instr, value, wanted_type);
}
+ // cast from null literal to C pointer
+ if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenC &&
+ actual_type->id == ZigTypeIdNull)
+ {
+ return ir_analyze_null_to_c_pointer(ira, source_instr, value, wanted_type);
+ }
+
// cast from [N]T to E![]const T
if (wanted_type->id == ZigTypeIdErrorUnion &&
is_slice(wanted_type->data.error_union.payload_type) &&
@@ -12227,14 +12255,12 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
IrBinOp op_id = bin_op_instruction->op_id;
bool is_equality_cmp = (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq);
- if (is_equality_cmp &&
+ if (is_equality_cmp && op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdNull) {
+ return ir_const_bool(ira, &bin_op_instruction->base, (op_id == IrBinOpCmpEq));
+ } else if (is_equality_cmp &&
((op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdOptional) ||
- (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdOptional) ||
- (op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdNull)))
+ (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdOptional)))
{
- if (op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdNull) {
- return ir_const_bool(ira, &bin_op_instruction->base, (op_id == IrBinOpCmpEq));
- }
IrInstruction *maybe_op;
if (op1->value.type->id == ZigTypeIdNull) {
maybe_op = op2;
@@ -12256,6 +12282,44 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
source_node, maybe_op);
is_non_null->value.type = ira->codegen->builtin_types.entry_bool;
+ if (op_id == IrBinOpCmpEq) {
+ IrInstruction *result = ir_build_bool_not(&ira->new_irb, bin_op_instruction->base.scope,
+ bin_op_instruction->base.source_node, is_non_null);
+ result->value.type = ira->codegen->builtin_types.entry_bool;
+ return result;
+ } else {
+ return is_non_null;
+ }
+ } else if (is_equality_cmp &&
+ ((op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdPointer &&
+ op2->value.type->data.pointer.ptr_len == PtrLenC) ||
+ (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdPointer &&
+ op1->value.type->data.pointer.ptr_len == PtrLenC)))
+ {
+ IrInstruction *c_ptr_op;
+ if (op1->value.type->id == ZigTypeIdNull) {
+ c_ptr_op = op2;
+ } else if (op2->value.type->id == ZigTypeIdNull) {
+ c_ptr_op = op1;
+ } else {
+ zig_unreachable();
+ }
+ if (instr_is_comptime(c_ptr_op)) {
+ ConstExprValue *c_ptr_val = ir_resolve_const(ira, c_ptr_op, UndefOk);
+ if (!c_ptr_val)
+ return ira->codegen->invalid_instruction;
+ if (c_ptr_val->special == ConstValSpecialUndef)
+ return ir_const_undef(ira, &bin_op_instruction->base, ira->codegen->builtin_types.entry_bool);
+ bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull ||
+ (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr &&
+ c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0);
+ bool bool_result = (op_id == IrBinOpCmpEq) ? is_null : !is_null;
+ return ir_const_bool(ira, &bin_op_instruction->base, bool_result);
+ }
+ IrInstruction *is_non_null = ir_build_test_nonnull(&ira->new_irb, bin_op_instruction->base.scope,
+ source_node, c_ptr_op);
+ is_non_null->value.type = ira->codegen->builtin_types.entry_bool;
+
if (op_id == IrBinOpCmpEq) {
IrInstruction *result = ir_build_bool_not(&ira->new_irb, bin_op_instruction->base.scope,
bin_op_instruction->base.source_node, is_non_null);
@@ -12265,8 +12329,9 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
return is_non_null;
}
} else if (op1->value.type->id == ZigTypeIdNull || op2->value.type->id == ZigTypeIdNull) {
- ir_add_error_node(ira, source_node, buf_sprintf("only optionals (not '%s') can compare to null",
- buf_ptr(&(op1->value.type->id == ZigTypeIdNull ? op2->value.type->name : op1->value.type->name))));
+ ZigType *non_null_type = (op1->value.type->id == ZigTypeIdNull) ? op2->value.type : op1->value.type;
+ ir_add_error_node(ira, source_node, buf_sprintf("comparison of '%s' with null",
+ buf_ptr(&non_null_type->name)));
return ira->codegen->invalid_instruction;
}
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index 60d1a9ac89..a367532ef5 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -863,7 +863,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
\\ _ = &x == null;
\\}
,
- "tmp.zig:3:12: error: only optionals (not '*i32') can compare to null",
+ "tmp.zig:3:12: error: comparison of '*i32' with null",
);
cases.add(
diff --git a/test/stage1/behavior/pointers.zig b/test/stage1/behavior/pointers.zig
index be47718358..8b1f7d0cb8 100644
--- a/test/stage1/behavior/pointers.zig
+++ b/test/stage1/behavior/pointers.zig
@@ -150,3 +150,31 @@ test "allowzero pointer and slice" {
expect(@typeInfo(@typeOf(ptr)).Pointer.is_allowzero);
expect(@typeInfo(@typeOf(slice)).Pointer.is_allowzero);
}
+
+test "assign null directly to C pointer and test null equality" {
+ var x: [*c]i32 = null;
+ expect(x == null);
+ expect(null == x);
+ expect(!(x != null));
+ expect(!(null != x));
+
+ const y: [*c]i32 = null;
+ expect(y == null);
+ expect(null == y);
+ expect(!(y != null));
+ expect(!(null != y));
+
+ var n: i32 = 1234;
+ var x1: [*c]i32 = &n;
+ expect(!(x1 == null));
+ expect(!(null == x1));
+ expect(x1 != null);
+ expect(null != x1);
+
+ const nc: i32 = 1234;
+ const y1: [*c]const i32 = &nc;
+ expect(!(y1 == null));
+ expect(!(null == y1));
+ expect(y1 != null);
+ expect(null != y1);
+}
--
cgit v1.2.3
From 0099583bd3eccbecbb827edbde46a40cf821fecf Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Wed, 8 May 2019 17:39:00 -0400
Subject: C pointers support .? operator
see #1967
---
src/all_types.hpp | 7 ++++++
src/codegen.cpp | 38 +++++++++++++++++++++++++++-
src/ir.cpp | 53 ++++++++++++++++++++++++++++++++++++---
src/ir_print.cpp | 9 +++++++
test/runtime_safety.zig | 20 +++++++++++++++
test/stage1/behavior/pointers.zig | 18 +++++++------
6 files changed, 132 insertions(+), 13 deletions(-)
(limited to 'src/ir.cpp')
diff --git a/src/all_types.hpp b/src/all_types.hpp
index 5a5c1cfda4..5cba3f2230 100644
--- a/src/all_types.hpp
+++ b/src/all_types.hpp
@@ -2293,6 +2293,7 @@ enum IrInstructionId {
IrInstructionIdVectorToArray,
IrInstructionIdArrayToVector,
IrInstructionIdAssertZero,
+ IrInstructionIdAssertNonNull,
};
struct IrInstruction {
@@ -3482,6 +3483,12 @@ struct IrInstructionAssertZero {
IrInstruction *target;
};
+struct IrInstructionAssertNonNull {
+ IrInstruction base;
+
+ IrInstruction *target;
+};
+
static const size_t slice_ptr_index = 0;
static const size_t slice_len_index = 1;
diff --git a/src/codegen.cpp b/src/codegen.cpp
index 712ee908cb..db7d96f4df 100644
--- a/src/codegen.cpp
+++ b/src/codegen.cpp
@@ -1008,10 +1008,19 @@ static void gen_panic(CodeGen *g, LLVMValueRef msg_arg, LLVMValueRef stack_trace
LLVMBuildUnreachable(g->builder);
}
+// TODO update most callsites to call gen_assertion instead of this
static void gen_safety_crash(CodeGen *g, PanicMsgId msg_id) {
gen_panic(g, get_panic_msg_ptr_val(g, msg_id), nullptr);
}
+static void gen_assertion(CodeGen *g, PanicMsgId msg_id, IrInstruction *source_instruction) {
+ if (ir_want_runtime_safety(g, source_instruction)) {
+ gen_safety_crash(g, msg_id);
+ } else {
+ LLVMBuildUnreachable(g->builder);
+ }
+}
+
static LLVMValueRef get_stacksave_fn_val(CodeGen *g) {
if (g->stacksave_fn_val)
return g->stacksave_fn_val;
@@ -4056,8 +4065,8 @@ static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, IrExecutable *exec
if (ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on) {
LLVMValueRef maybe_handle = get_handle_value(g, maybe_ptr, maybe_type, ptr_type);
LLVMValueRef non_null_bit = gen_non_null_bit(g, maybe_type, maybe_handle);
- LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapOptionalOk");
LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapOptionalFail");
+ LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapOptionalOk");
LLVMBuildCondBr(g->builder, non_null_bit, ok_block, fail_block);
LLVMPositionBuilderAtEnd(g->builder, fail_block);
@@ -5487,6 +5496,31 @@ static LLVMValueRef ir_render_assert_zero(CodeGen *g, IrExecutable *executable,
return nullptr;
}
+static LLVMValueRef ir_render_assert_non_null(CodeGen *g, IrExecutable *executable,
+ IrInstructionAssertNonNull *instruction)
+{
+ LLVMValueRef target = ir_llvm_value(g, instruction->target);
+ ZigType *target_type = instruction->target->value.type;
+
+ if (target_type->id == ZigTypeIdPointer) {
+ assert(target_type->data.pointer.ptr_len == PtrLenC);
+ LLVMValueRef non_null_bit = LLVMBuildICmp(g->builder, LLVMIntNE, target,
+ LLVMConstNull(get_llvm_type(g, target_type)), "");
+
+ LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "AssertNonNullFail");
+ LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "AssertNonNullOk");
+ LLVMBuildCondBr(g->builder, non_null_bit, ok_block, fail_block);
+
+ LLVMPositionBuilderAtEnd(g->builder, fail_block);
+ gen_assertion(g, PanicMsgIdUnwrapOptionalFail, &instruction->base);
+
+ LLVMPositionBuilderAtEnd(g->builder, ok_block);
+ } else {
+ zig_unreachable();
+ }
+ return nullptr;
+}
+
static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
AstNode *source_node = instruction->source_node;
Scope *scope = instruction->scope;
@@ -5741,6 +5775,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
return ir_render_vector_to_array(g, executable, (IrInstructionVectorToArray *)instruction);
case IrInstructionIdAssertZero:
return ir_render_assert_zero(g, executable, (IrInstructionAssertZero *)instruction);
+ case IrInstructionIdAssertNonNull:
+ return ir_render_assert_non_null(g, executable, (IrInstructionAssertNonNull *)instruction);
case IrInstructionIdResizeSlice:
return ir_render_resize_slice(g, executable, (IrInstructionResizeSlice *)instruction);
}
diff --git a/src/ir.cpp b/src/ir.cpp
index 1b0fbd1f7f..90e8f1ed8f 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -1003,6 +1003,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertZero *) {
return IrInstructionIdAssertZero;
}
+static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertNonNull *) {
+ return IrInstructionIdAssertNonNull;
+}
+
template
static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
T *special_instruction = allocate(1);
@@ -3037,6 +3041,19 @@ static IrInstruction *ir_build_assert_zero(IrAnalyze *ira, IrInstruction *source
return &instruction->base;
}
+static IrInstruction *ir_build_assert_non_null(IrAnalyze *ira, IrInstruction *source_instruction,
+ IrInstruction *target)
+{
+ IrInstructionAssertNonNull *instruction = ir_build_instruction(&ira->new_irb,
+ source_instruction->scope, source_instruction->source_node);
+ instruction->base.value.type = ira->codegen->builtin_types.entry_void;
+ instruction->target = target;
+
+ ir_ref_instruction(target, ira->new_irb.current_basic_block);
+
+ return &instruction->base;
+}
+
static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
results[ReturnKindUnconditional] = 0;
results[ReturnKindError] = 0;
@@ -16869,6 +16886,32 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr
if (type_is_invalid(type_entry))
return ira->codegen->invalid_instruction;
+ if (type_entry->id == ZigTypeIdPointer && type_entry->data.pointer.ptr_len == PtrLenC) {
+ if (instr_is_comptime(base_ptr)) {
+ ConstExprValue *val = ir_resolve_const(ira, base_ptr, UndefBad);
+ if (!val)
+ return ira->codegen->invalid_instruction;
+ if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) {
+ ConstExprValue *c_ptr_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node);
+ if (c_ptr_val == nullptr)
+ return ira->codegen->invalid_instruction;
+ bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull ||
+ (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr &&
+ c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0);
+ if (is_null) {
+ ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null"));
+ return ira->codegen->invalid_instruction;
+ }
+ return base_ptr;
+ }
+ }
+ if (!safety_check_on)
+ return base_ptr;
+ IrInstruction *c_ptr_val = ir_get_deref(ira, source_instr, base_ptr);
+ ir_build_assert_non_null(ira, source_instr, c_ptr_val);
+ return base_ptr;
+ }
+
if (type_entry->id != ZigTypeIdOptional) {
ir_add_error_node(ira, base_ptr->source_node,
buf_sprintf("expected optional type, found '%s'", buf_ptr(&type_entry->name)));
@@ -16883,11 +16926,11 @@ static IrInstruction *ir_analyze_unwrap_optional_payload(IrAnalyze *ira, IrInstr
ConstExprValue *val = ir_resolve_const(ira, base_ptr, UndefBad);
if (!val)
return ira->codegen->invalid_instruction;
- ConstExprValue *maybe_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node);
- if (maybe_val == nullptr)
- return ira->codegen->invalid_instruction;
-
if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) {
+ ConstExprValue *maybe_val = const_ptr_pointee(ira, ira->codegen, val, source_instr->source_node);
+ if (maybe_val == nullptr)
+ return ira->codegen->invalid_instruction;
+
if (optional_value_is_null(maybe_val)) {
ir_add_error(ira, source_instr, buf_sprintf("unable to unwrap null"));
return ira->codegen->invalid_instruction;
@@ -22942,6 +22985,7 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
case IrInstructionIdArrayToVector:
case IrInstructionIdVectorToArray:
case IrInstructionIdAssertZero:
+ case IrInstructionIdAssertNonNull:
case IrInstructionIdResizeSlice:
case IrInstructionIdLoadPtrGen:
case IrInstructionIdBitCastGen:
@@ -23346,6 +23390,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
case IrInstructionIdCmpxchgGen:
case IrInstructionIdCmpxchgSrc:
case IrInstructionIdAssertZero:
+ case IrInstructionIdAssertNonNull:
case IrInstructionIdResizeSlice:
case IrInstructionIdGlobalAsm:
return true;
diff --git a/src/ir_print.cpp b/src/ir_print.cpp
index dba0e4ee00..08f5cd01a4 100644
--- a/src/ir_print.cpp
+++ b/src/ir_print.cpp
@@ -1003,6 +1003,12 @@ static void ir_print_assert_zero(IrPrint *irp, IrInstructionAssertZero *instruct
fprintf(irp->f, ")");
}
+static void ir_print_assert_non_null(IrPrint *irp, IrInstructionAssertNonNull *instruction) {
+ fprintf(irp->f, "AssertNonNull(");
+ ir_print_other_instruction(irp, instruction->target);
+ fprintf(irp->f, ")");
+}
+
static void ir_print_resize_slice(IrPrint *irp, IrInstructionResizeSlice *instruction) {
fprintf(irp->f, "@resizeSlice(");
ir_print_other_instruction(irp, instruction->operand);
@@ -1880,6 +1886,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
case IrInstructionIdAssertZero:
ir_print_assert_zero(irp, (IrInstructionAssertZero *)instruction);
break;
+ case IrInstructionIdAssertNonNull:
+ ir_print_assert_non_null(irp, (IrInstructionAssertNonNull *)instruction);
+ break;
case IrInstructionIdResizeSlice:
ir_print_resize_slice(irp, (IrInstructionResizeSlice *)instruction);
break;
diff --git a/test/runtime_safety.zig b/test/runtime_safety.zig
index 78b45ac05f..b10accd213 100644
--- a/test/runtime_safety.zig
+++ b/test/runtime_safety.zig
@@ -1,6 +1,26 @@
const tests = @import("tests.zig");
pub fn addCases(cases: *tests.CompareOutputContext) void {
+ cases.addRuntimeSafety(".? operator on null pointer",
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
+ \\ @import("std").os.exit(126);
+ \\}
+ \\pub fn main() void {
+ \\ var ptr: ?*i32 = null;
+ \\ var b = ptr.?;
+ \\}
+ );
+
+ cases.addRuntimeSafety(".? operator on C pointer",
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
+ \\ @import("std").os.exit(126);
+ \\}
+ \\pub fn main() void {
+ \\ var ptr: [*c]i32 = null;
+ \\ var b = ptr.?;
+ \\}
+ );
+
cases.addRuntimeSafety("@ptrToInt address zero to non-optional pointer",
\\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
diff --git a/test/stage1/behavior/pointers.zig b/test/stage1/behavior/pointers.zig
index 8b1f7d0cb8..1a7616e757 100644
--- a/test/stage1/behavior/pointers.zig
+++ b/test/stage1/behavior/pointers.zig
@@ -159,10 +159,10 @@ test "assign null directly to C pointer and test null equality" {
expect(!(null != x));
const y: [*c]i32 = null;
- expect(y == null);
- expect(null == y);
- expect(!(y != null));
- expect(!(null != y));
+ comptime expect(y == null);
+ comptime expect(null == y);
+ comptime expect(!(y != null));
+ comptime expect(!(null != y));
var n: i32 = 1234;
var x1: [*c]i32 = &n;
@@ -170,11 +170,13 @@ test "assign null directly to C pointer and test null equality" {
expect(!(null == x1));
expect(x1 != null);
expect(null != x1);
+ expect(x1.?.* == 1234);
const nc: i32 = 1234;
const y1: [*c]const i32 = &nc;
- expect(!(y1 == null));
- expect(!(null == y1));
- expect(y1 != null);
- expect(null != y1);
+ comptime expect(!(y1 == null));
+ comptime expect(!(null == y1));
+ comptime expect(y1 != null);
+ comptime expect(null != y1);
+ comptime expect(y1.?.* == 1234);
}
--
cgit v1.2.3
From a4aee8b24d321aa4c7a791d20500e5847a08b587 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Wed, 8 May 2019 18:36:41 -0400
Subject: C pointers support if and orelse
See #1967
---
src/ir.cpp | 25 ++++++++++++++++++++++---
test/stage1/behavior/pointers.zig | 20 ++++++++++++++++++++
2 files changed, 42 insertions(+), 3 deletions(-)
(limited to 'src/ir.cpp')
diff --git a/src/ir.cpp b/src/ir.cpp
index 90e8f1ed8f..1cfdb4544d 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -16848,11 +16848,30 @@ static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira,
static IrInstruction *ir_analyze_test_non_null(IrAnalyze *ira, IrInstruction *source_inst, IrInstruction *value) {
ZigType *type_entry = value->value.type;
- if (type_entry->id == ZigTypeIdOptional) {
+ if (type_entry->id == ZigTypeIdPointer && type_entry->data.pointer.allow_zero) {
if (instr_is_comptime(value)) {
- ConstExprValue *maybe_val = ir_resolve_const(ira, value, UndefBad);
- if (!maybe_val)
+ ConstExprValue *c_ptr_val = ir_resolve_const(ira, value, UndefOk);
+ if (c_ptr_val == nullptr)
+ return ira->codegen->invalid_instruction;
+ if (c_ptr_val->special == ConstValSpecialUndef)
+ return ir_const_undef(ira, source_inst, ira->codegen->builtin_types.entry_bool);
+ bool is_null = c_ptr_val->data.x_ptr.special == ConstPtrSpecialNull ||
+ (c_ptr_val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr &&
+ c_ptr_val->data.x_ptr.data.hard_coded_addr.addr == 0);
+ return ir_const_bool(ira, source_inst, !is_null);
+ }
+
+ IrInstruction *result = ir_build_test_nonnull(&ira->new_irb,
+ source_inst->scope, source_inst->source_node, value);
+ result->value.type = ira->codegen->builtin_types.entry_bool;
+ return result;
+ } else if (type_entry->id == ZigTypeIdOptional) {
+ if (instr_is_comptime(value)) {
+ ConstExprValue *maybe_val = ir_resolve_const(ira, value, UndefOk);
+ if (maybe_val == nullptr)
return ira->codegen->invalid_instruction;
+ if (maybe_val->special == ConstValSpecialUndef)
+ return ir_const_undef(ira, source_inst, ira->codegen->builtin_types.entry_bool);
return ir_const_bool(ira, source_inst, !optional_value_is_null(maybe_val));
}
diff --git a/test/stage1/behavior/pointers.zig b/test/stage1/behavior/pointers.zig
index 1a7616e757..50b36fe583 100644
--- a/test/stage1/behavior/pointers.zig
+++ b/test/stage1/behavior/pointers.zig
@@ -157,12 +157,20 @@ test "assign null directly to C pointer and test null equality" {
expect(null == x);
expect(!(x != null));
expect(!(null != x));
+ if (x) |same_x| {
+ @panic("fail");
+ }
+ var otherx: i32 = undefined;
+ expect((x orelse &otherx) == &otherx);
const y: [*c]i32 = null;
comptime expect(y == null);
comptime expect(null == y);
comptime expect(!(y != null));
comptime expect(!(null != y));
+ if (y) |same_y| @panic("fail");
+ const othery: i32 = undefined;
+ comptime expect((y orelse &othery) == &othery);
var n: i32 = 1234;
var x1: [*c]i32 = &n;
@@ -171,6 +179,12 @@ test "assign null directly to C pointer and test null equality" {
expect(x1 != null);
expect(null != x1);
expect(x1.?.* == 1234);
+ if (x1) |same_x1| {
+ expect(same_x1.* == 1234);
+ } else {
+ @panic("fail");
+ }
+ expect((x1 orelse &otherx) == x1);
const nc: i32 = 1234;
const y1: [*c]const i32 = &nc;
@@ -179,4 +193,10 @@ test "assign null directly to C pointer and test null equality" {
comptime expect(y1 != null);
comptime expect(null != y1);
comptime expect(y1.?.* == 1234);
+ if (y1) |same_y1| {
+ expect(same_y1.* == 1234);
+ } else {
+ @compileError("fail");
+ }
+ comptime expect((y1 orelse &othery) == y1);
}
--
cgit v1.2.3
From c459edac18a53854dbfdebe50a370d169e715145 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 9 May 2019 13:18:13 -0400
Subject: compile error for attempt to cast enum literal to error
closes #2203
---
src/ir.cpp | 10 ++++++++--
test/compile_errors.zig | 11 +++++++++++
2 files changed, 19 insertions(+), 2 deletions(-)
(limited to 'src/ir.cpp')
diff --git a/src/ir.cpp b/src/ir.cpp
index 1cfdb4544d..9811225c3d 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -21213,11 +21213,17 @@ static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) {
IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i];
- IrInstruction *start_value = range->start->child;
+ IrInstruction *start_value_uncasted = range->start->child;
+ if (type_is_invalid(start_value_uncasted->value.type))
+ return ira->codegen->invalid_instruction;
+ IrInstruction *start_value = ir_implicit_cast(ira, start_value_uncasted, switch_type);
if (type_is_invalid(start_value->value.type))
return ira->codegen->invalid_instruction;
- IrInstruction *end_value = range->end->child;
+ IrInstruction *end_value_uncasted = range->end->child;
+ if (type_is_invalid(end_value_uncasted->value.type))
+ return ira->codegen->invalid_instruction;
+ IrInstruction *end_value = ir_implicit_cast(ira, end_value_uncasted, switch_type);
if (type_is_invalid(end_value->value.type))
return ira->codegen->invalid_instruction;
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index a367532ef5..40256f660a 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -2,6 +2,17 @@ const tests = @import("tests.zig");
const builtin = @import("builtin");
pub fn addCases(cases: *tests.CompileErrorContext) void {
+ cases.add(
+ "attempt to cast enum literal to error",
+ \\export fn entry() void {
+ \\ switch (error.Hi) {
+ \\ .Hi => {},
+ \\ }
+ \\}
+ ,
+ "tmp.zig:3:9: error: expected type 'error{Hi}', found '(enum literal)'",
+ );
+
cases.add(
"@sizeOf bad type",
\\export fn entry() void {
--
cgit v1.2.3
From 010963ce431db2648374368dfc886aa8482494a9 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Thu, 9 May 2019 14:52:06 -0400
Subject: stage1: make some asserts print source location
---
src/analyze.cpp | 13 +++++++++++++
src/analyze.hpp | 2 ++
src/ir.cpp | 56 +++++++++++++++++++++++++++++++-------------------------
3 files changed, 46 insertions(+), 25 deletions(-)
(limited to 'src/ir.cpp')
diff --git a/src/analyze.cpp b/src/analyze.cpp
index aa510003b8..c441676e77 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -7230,3 +7230,16 @@ ZigLLVMDIType *get_llvm_di_type(CodeGen *g, ZigType *type) {
assertNoError(type_resolve(g, type, ResolveStatusLLVMFull));
return type->llvm_di_type;
}
+
+void src_assert(bool ok, AstNode *source_node) {
+ if (ok) return;
+ if (source_node == nullptr) {
+ fprintf(stderr, "when analyzing (unknown source location): ");
+ } else {
+ fprintf(stderr, "when analyzing %s:%u:%u: ",
+ buf_ptr(source_node->owner->data.structure.root_struct->path),
+ (unsigned)source_node->line + 1, (unsigned)source_node->column + 1);
+ }
+ const char *msg = "assertion failed";
+ stage2_panic(msg, strlen(msg));
+}
diff --git a/src/analyze.hpp b/src/analyze.hpp
index cde9f2d321..d55733482f 100644
--- a/src/analyze.hpp
+++ b/src/analyze.hpp
@@ -249,4 +249,6 @@ ZigLLVMDIType *get_llvm_di_type(CodeGen *g, ZigType *type);
void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_path, bool translate_c);
+void src_assert(bool ok, AstNode *source_node);
+
#endif
diff --git a/src/ir.cpp b/src/ir.cpp
index 9811225c3d..d333708402 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -7933,6 +7933,11 @@ static ErrorMsg *ir_add_error(IrAnalyze *ira, IrInstruction *source_instruction,
return ir_add_error_node(ira, source_instruction->source_node, msg);
}
+static void ir_assert(bool ok, IrInstruction *source_instruction) {
+ if (ok) return;
+ src_assert(ok, source_instruction->source_node);
+}
+
// This function takes a comptime ptr and makes the child const value conform to the type
// described by the pointer.
static Error eval_comptime_ptr_reinterpret(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node,
@@ -13944,11 +13949,12 @@ IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_i
zig_unreachable();
}
-static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *call_instruction, ZigFn *fn_entry, ZigType *fn_type,
- IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count, IrInstruction *async_allocator_inst)
+static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *call_instruction, ZigFn *fn_entry,
+ ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count,
+ IrInstruction *async_allocator_inst)
{
Buf *realloc_field_name = buf_create_from_str(ASYNC_REALLOC_FIELD_NAME);
- assert(async_allocator_inst->value.type->id == ZigTypeIdPointer);
+ ir_assert(async_allocator_inst->value.type->id == ZigTypeIdPointer, &call_instruction->base);
ZigType *container_type = async_allocator_inst->value.type->data.pointer.child_type;
IrInstruction *field_ptr_inst = ir_analyze_container_field_ptr(ira, realloc_field_name, &call_instruction->base,
async_allocator_inst, container_type);
@@ -13956,7 +13962,7 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *c
return ira->codegen->invalid_instruction;
}
ZigType *ptr_to_realloc_fn_type = field_ptr_inst->value.type;
- assert(ptr_to_realloc_fn_type->id == ZigTypeIdPointer);
+ ir_assert(ptr_to_realloc_fn_type->id == ZigTypeIdPointer, &call_instruction->base);
ZigType *realloc_fn_type = ptr_to_realloc_fn_type->data.pointer.child_type;
if (realloc_fn_type->id != ZigTypeIdFn) {
@@ -21227,10 +21233,10 @@ static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira,
if (type_is_invalid(end_value->value.type))
return ira->codegen->invalid_instruction;
- assert(start_value->value.type->id == ZigTypeIdErrorSet);
+ ir_assert(start_value->value.type->id == ZigTypeIdErrorSet, &instruction->base);
uint32_t start_index = start_value->value.data.x_err_set->value;
- assert(end_value->value.type->id == ZigTypeIdErrorSet);
+ ir_assert(end_value->value.type->id == ZigTypeIdErrorSet, &instruction->base);
uint32_t end_index = end_value->value.data.x_err_set->value;
if (start_index != end_index) {
@@ -21755,7 +21761,7 @@ static Error buf_read_value_bytes_array(IrAnalyze *ira, CodeGen *codegen, AstNod
static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node, uint8_t *buf, ConstExprValue *val) {
Error err;
- assert(val->special == ConstValSpecialStatic);
+ src_assert(val->special == ConstValSpecialStatic, source_node);
switch (val->type->id) {
case ZigTypeIdInvalid:
case ZigTypeIdMetaType:
@@ -21805,7 +21811,7 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
zig_panic("TODO buf_read_value_bytes enum packed");
case ContainerLayoutExtern: {
ZigType *tag_int_type = val->type->data.enumeration.tag_int_type;
- assert(tag_int_type->id == ZigTypeIdInt);
+ src_assert(tag_int_type->id == ZigTypeIdInt, source_node);
bigint_read_twos_complement(&val->data.x_enum_tag, buf, tag_int_type->data.integral.bit_count,
codegen->is_big_endian, tag_int_type->data.integral.is_signed);
return ErrorNone;
@@ -21860,7 +21866,7 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
bigint_read_twos_complement(&big_int, buf + offset, big_int_byte_count * 8, is_big_endian, false);
while (src_i < src_field_count) {
TypeStructField *field = &val->type->data.structure.fields[src_i];
- assert(field->gen_index != SIZE_MAX);
+ src_assert(field->gen_index != SIZE_MAX, source_node);
if (field->gen_index != gen_i)
break;
ConstExprValue *field_val = &val->data.x_struct.fields[src_i];
@@ -21936,10 +21942,10 @@ static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_
Error err;
ZigType *src_type = value->value.type;
- assert(get_codegen_ptr_type(src_type) == nullptr);
- assert(type_can_bit_cast(src_type));
- assert(get_codegen_ptr_type(dest_type) == nullptr);
- assert(type_can_bit_cast(dest_type));
+ ir_assert(get_codegen_ptr_type(src_type) == nullptr, source_instr);
+ ir_assert(type_can_bit_cast(src_type), source_instr);
+ ir_assert(get_codegen_ptr_type(dest_type) == nullptr, source_instr);
+ ir_assert(type_can_bit_cast(dest_type), source_instr);
if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusSizeKnown)))
return ira->codegen->invalid_instruction;
@@ -22029,8 +22035,8 @@ static IrInstruction *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstruct
static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target,
ZigType *ptr_type)
{
- assert(get_src_ptr_type(ptr_type) != nullptr);
- assert(type_has_bits(ptr_type));
+ ir_assert(get_src_ptr_type(ptr_type) != nullptr, source_instr);
+ ir_assert(type_has_bits(ptr_type), source_instr);
IrInstruction *casted_int = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_usize);
if (type_is_invalid(casted_int->value.type))
@@ -22129,7 +22135,7 @@ static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira,
case TldIdFn: {
TldFn *tld_fn = (TldFn *)tld;
ZigFn *fn_entry = tld_fn->fn_entry;
- assert(fn_entry->type_entry);
+ ir_assert(fn_entry->type_entry, &instruction->base);
if (tld_fn->extern_lib_name != nullptr) {
add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, instruction->base.source_node);
@@ -22327,7 +22333,7 @@ static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstruct
ZigType *result_type = fn_type_id->param_info[arg_index].type;
if (result_type == nullptr) {
// Args are only unresolved if our function is generic.
- assert(fn_type->data.fn.is_generic);
+ ir_assert(fn_type->data.fn.is_generic, &instruction->base);
ir_add_error(ira, arg_index_inst,
buf_sprintf("@ArgType could not resolve the type of arg %" ZIG_PRI_u64 " because '%s' is generic",
@@ -22413,7 +22419,7 @@ static IrInstruction *ir_analyze_instruction_coro_begin(IrAnalyze *ira, IrInstru
return ira->codegen->invalid_instruction;
ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
- assert(fn_entry != nullptr);
+ ir_assert(fn_entry != nullptr, &instruction->base);
IrInstruction *result = ir_build_coro_begin(&ira->new_irb, instruction->base.scope, instruction->base.source_node,
coro_id, coro_mem_ptr);
result->value.type = get_promise_type(ira->codegen, fn_entry->type_entry->data.fn.fn_type_id.return_type);
@@ -22651,7 +22657,7 @@ static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstr
}
if (ordering == AtomicOrderRelease || ordering == AtomicOrderAcqRel) {
- assert(instruction->ordering != nullptr);
+ ir_assert(instruction->ordering != nullptr, &instruction->base);
ir_add_error(ira, instruction->ordering,
buf_sprintf("@atomicLoad atomic ordering must not be Release or AcqRel"));
return ira->codegen->invalid_instruction;
@@ -22659,7 +22665,7 @@ static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstr
if (instr_is_comptime(casted_ptr)) {
IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr);
- assert(result->value.type != nullptr);
+ ir_assert(result->value.type != nullptr, &instruction->base);
return result;
}
@@ -22689,7 +22695,7 @@ static IrInstruction *ir_analyze_instruction_await_bookkeeping(IrAnalyze *ira, I
return ira->codegen->invalid_instruction;
ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
- assert(fn_entry != nullptr);
+ ir_assert(fn_entry != nullptr, &instruction->base);
if (type_can_fail(promise_result_type)) {
fn_entry->calls_or_awaits_errorable_fn = true;
@@ -22705,9 +22711,9 @@ static IrInstruction *ir_analyze_instruction_merge_err_ret_traces(IrAnalyze *ira
if (type_is_invalid(coro_promise_ptr->value.type))
return ira->codegen->invalid_instruction;
- assert(coro_promise_ptr->value.type->id == ZigTypeIdPointer);
+ ir_assert(coro_promise_ptr->value.type->id == ZigTypeIdPointer, &instruction->base);
ZigType *promise_frame_type = coro_promise_ptr->value.type->data.pointer.child_type;
- assert(promise_frame_type->id == ZigTypeIdStruct);
+ ir_assert(promise_frame_type->id == ZigTypeIdStruct, &instruction->base);
ZigType *promise_result_type = promise_frame_type->data.structure.fields[1].type_entry;
if (!type_can_fail(promise_result_type)) {
@@ -22799,7 +22805,7 @@ static IrInstruction *ir_analyze_instruction_sqrt(IrAnalyze *ira, IrInstructionS
return result;
}
- assert(float_type->id == ZigTypeIdFloat);
+ ir_assert(float_type->id == ZigTypeIdFloat, &instruction->base);
if (float_type->data.floating.bit_count != 16 &&
float_type->data.floating.bit_count != 32 &&
float_type->data.floating.bit_count != 64) {
@@ -23290,7 +23296,7 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *old_instruction) {
IrInstruction *new_instruction = ir_analyze_instruction_nocast(ira, old_instruction);
- assert(new_instruction->value.type != nullptr);
+ ir_assert(new_instruction->value.type != nullptr, old_instruction);
old_instruction->child = new_instruction;
return new_instruction;
}
--
cgit v1.2.3
From 6b10f03b4a868cc02fc0535193ea0108c77ddd1f Mon Sep 17 00:00:00 2001
From: Jimmi HC
Date: Fri, 10 May 2019 16:09:58 +0200
Subject: Fixes and simplifications for stage 1 parser
---
src/ir.cpp | 7 ++---
src/parser.cpp | 74 +++++++++++++++++++------------------------------
test/compile_errors.zig | 9 ------
3 files changed, 31 insertions(+), 59 deletions(-)
(limited to 'src/ir.cpp')
diff --git a/src/ir.cpp b/src/ir.cpp
index d333708402..f764cbd983 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -5433,10 +5433,9 @@ static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *nod
add_node_error(irb->codegen, variable_declaration->section_expr,
buf_sprintf("cannot set section of local variable '%s'", buf_ptr(variable_declaration->symbol)));
}
- if (variable_declaration->threadlocal_tok != nullptr) {
- add_token_error(irb->codegen, node->owner, variable_declaration->threadlocal_tok,
- buf_sprintf("function-local variable '%s' cannot be threadlocal", buf_ptr(variable_declaration->symbol)));
- }
+
+ // Parser should ensure that this never happens
+ assert(variable_declaration->threadlocal_tok == nullptr);
// Temporarily set the name of the IrExecutable to the VariableDeclaration
// so that the struct or enum from the init expression inherits the name.
diff --git a/src/parser.cpp b/src/parser.cpp
index 9e72954b64..36ca3ed863 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -577,7 +577,7 @@ static AstNode *ast_parse_top_level_comptime(ParseContext *pc) {
// TopLevelDecl
// <- (KEYWORD_export / KEYWORD_extern STRINGLITERAL? / KEYWORD_inline)? FnProto (SEMICOLON / Block)
-// / (KEYWORD_export / KEYWORD_extern STRINGLITERAL?)? VarDecl
+// / (KEYWORD_export / KEYWORD_extern STRINGLITERAL?)? KEYWORD_threadlocal? VarDecl
// / KEYWORD_use Expr SEMICOLON
static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) {
Token *first = eat_token_if(pc, TokenIdKeywordExport);
@@ -632,13 +632,18 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod) {
ast_invalid_token_error(pc, peek_token(pc));
}
+ Token *thread_local_kw = eat_token_if(pc, TokenIdKeywordThreadLocal);
AstNode *var_decl = ast_parse_var_decl(pc);
if (var_decl != nullptr) {
assert(var_decl->type == NodeTypeVariableDeclaration);
var_decl->data.variable_declaration.visib_mod = visib_mod;
+ var_decl->data.variable_declaration.threadlocal_tok = thread_local_kw;
return var_decl;
}
+ if (thread_local_kw != nullptr)
+ put_back_token(pc);
+
AstNode *fn_proto = ast_parse_fn_proto(pc);
if (fn_proto != nullptr) {
AstNode *body = ast_parse_block(pc);
@@ -741,17 +746,12 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
// VarDecl <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? LinkSection? (EQUAL Expr)? SEMICOLON
static AstNode *ast_parse_var_decl(ParseContext *pc) {
- Token *thread_local_kw = eat_token_if(pc, TokenIdKeywordThreadLocal);
Token *mut_kw = eat_token_if(pc, TokenIdKeywordConst);
if (mut_kw == nullptr)
mut_kw = eat_token_if(pc, TokenIdKeywordVar);
- if (mut_kw == nullptr) {
- if (thread_local_kw == nullptr) {
- return nullptr;
- } else {
- ast_invalid_token_error(pc, peek_token(pc));
- }
- }
+ if (mut_kw == nullptr)
+ return nullptr;
+
Token *identifier = expect_token(pc, TokenIdSymbol);
AstNode *type_expr = nullptr;
if (eat_token_if(pc, TokenIdColon) != nullptr)
@@ -766,7 +766,6 @@ static AstNode *ast_parse_var_decl(ParseContext *pc) {
expect_token(pc, TokenIdSemicolon);
AstNode *res = ast_create_node(pc, NodeTypeVariableDeclaration, mut_kw);
- res->data.variable_declaration.threadlocal_tok = thread_local_kw;
res->data.variable_declaration.is_const = mut_kw->id == TokenIdKeywordConst;
res->data.variable_declaration.symbol = token_buf(identifier);
res->data.variable_declaration.type = type_expr;
@@ -952,17 +951,10 @@ static AstNode *ast_parse_labeled_statement(ParseContext *pc) {
// LoopStatement <- KEYWORD_inline? (ForStatement / WhileStatement)
static AstNode *ast_parse_loop_statement(ParseContext *pc) {
- Token *label = ast_parse_block_label(pc);
- Token *first = label;
-
Token *inline_token = eat_token_if(pc, TokenIdKeywordInline);
- if (first == nullptr)
- first = inline_token;
-
AstNode *for_statement = ast_parse_for_statement(pc);
if (for_statement != nullptr) {
assert(for_statement->type == NodeTypeForExpr);
- for_statement->data.for_expr.name = token_buf(label);
for_statement->data.for_expr.is_inline = inline_token != nullptr;
return for_statement;
}
@@ -970,12 +962,11 @@ static AstNode *ast_parse_loop_statement(ParseContext *pc) {
AstNode *while_statement = ast_parse_while_statement(pc);
if (while_statement != nullptr) {
assert(while_statement->type == NodeTypeWhileExpr);
- while_statement->data.while_expr.name = token_buf(label);
while_statement->data.while_expr.is_inline = inline_token != nullptr;
return while_statement;
}
- if (first != nullptr)
+ if (inline_token != nullptr)
ast_invalid_token_error(pc, peek_token(pc));
return nullptr;
}
@@ -1117,7 +1108,7 @@ static AstNode *ast_parse_bool_and_expr(ParseContext *pc) {
// CompareExpr <- BitwiseExpr (CompareOp BitwiseExpr)?
static AstNode *ast_parse_compare_expr(ParseContext *pc) {
- return ast_parse_bin_op_expr(pc, BinOpChainInf, ast_parse_compare_op, ast_parse_bitwise_expr);
+ return ast_parse_bin_op_expr(pc, BinOpChainOnce, ast_parse_compare_op, ast_parse_bitwise_expr);
}
// BitwiseExpr <- BitShiftExpr (BitwiseOp BitShiftExpr)*
@@ -1246,11 +1237,8 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc) {
}
AstNode *block = ast_parse_block(pc);
- if (block != nullptr) {
- assert(block->type == NodeTypeBlock);
- block->data.block.name = token_buf(label);
+ if (block != nullptr)
return block;
- }
AstNode *curly_suffix = ast_parse_curly_suffix_expr(pc);
if (curly_suffix != nullptr)
@@ -1672,32 +1660,26 @@ static AstNode *ast_parse_primary_type_expr(ParseContext *pc) {
// ContainerDecl <- (KEYWORD_extern / KEYWORD_packed)? ContainerDeclAuto
static AstNode *ast_parse_container_decl(ParseContext *pc) {
- Token *extern_token = eat_token_if(pc, TokenIdKeywordExtern);
- if (extern_token != nullptr) {
- AstNode *res = ast_parse_container_decl_auto(pc);
- if (res == nullptr) {
- put_back_token(pc);
- return nullptr;
- }
+ Token *layout_token = eat_token_if(pc, TokenIdKeywordExtern);
+ if (layout_token == nullptr)
+ layout_token = eat_token_if(pc, TokenIdKeywordPacked);
- assert(res->type == NodeTypeContainerDecl);
- res->line = extern_token->start_line;
- res->column = extern_token->start_column;
- res->data.container_decl.layout = ContainerLayoutExtern;
- return res;
+ AstNode *res = ast_parse_container_decl_auto(pc);
+ if (res == nullptr) {
+ if (layout_token != nullptr)
+ put_back_token(pc);
+ return nullptr;
}
- Token *packed_token = eat_token_if(pc, TokenIdKeywordPacked);
- if (packed_token != nullptr) {
- AstNode *res = ast_expect(pc, ast_parse_container_decl_auto);
- assert(res->type == NodeTypeContainerDecl);
- res->line = packed_token->start_line;
- res->column = packed_token->start_column;
- res->data.container_decl.layout = ContainerLayoutPacked;
- return res;
+ assert(res->type == NodeTypeContainerDecl);
+ if (layout_token != nullptr) {
+ res->line = layout_token->start_line;
+ res->column = layout_token->start_column;
+ res->data.container_decl.layout = layout_token->id == TokenIdKeywordExtern
+ ? ContainerLayoutExtern
+ : ContainerLayoutPacked;
}
-
- return ast_parse_container_decl_auto(pc);
+ return res;
}
// ErrorSetDecl <- KEYWORD_error LBRACE IdentifierList RBRACE
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index 40256f660a..63835e8c1b 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -587,15 +587,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
"tmp.zig:1:13: error: threadlocal variable cannot be constant",
);
- cases.add(
- "threadlocal qualifier on local variable",
- \\export fn entry() void {
- \\ threadlocal var x: i32 = 1234;
- \\}
- ,
- "tmp.zig:2:5: error: function-local variable 'x' cannot be threadlocal",
- );
-
cases.add(
"@bitCast same size but bit count mismatch",
\\export fn entry(byte: u8) void {
--
cgit v1.2.3
From d065f297ab6de5ca35636d169195ce5da6235786 Mon Sep 17 00:00:00 2001
From: Michael Dusan
Date: Fri, 10 May 2019 05:23:26 -0400
Subject: stage1: compile error for loop expr val ignored
closes #2460
---
src/ir.cpp | 4 +++-
test/compile_errors.zig | 17 +++++++++++++++++
2 files changed, 20 insertions(+), 1 deletion(-)
(limited to 'src/ir.cpp')
diff --git a/src/ir.cpp b/src/ir.cpp
index f764cbd983..d1d1c44043 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -5808,8 +5808,10 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
IrInstruction *body_result = ir_gen_node(irb, body_node, &loop_scope->base);
- if (!instr_is_unreachable(body_result))
+ if (!instr_is_unreachable(body_result)) {
+ ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.for_expr.body, body_result));
ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime));
+ }
ir_set_cursor_at_end_and_append_block(irb, continue_block);
IrInstruction *new_index_val = ir_build_bin_op(irb, child_scope, node, IrBinOpAdd, index_val, one, false);
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index 63835e8c1b..9edad2662a 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -5918,4 +5918,21 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
,
"tmp.zig:3:23: error: expected type '[]u32', found '*const u32'",
);
+
+ cases.add(
+ "for loop body expression ignored",
+ \\fn returns() usize {
+ \\ return 2;
+ \\}
+ \\export fn f1() void {
+ \\ for ("hello") |_| returns();
+ \\}
+ \\export fn f2() void {
+ \\ var x: anyerror!i32 = error.Bad;
+ \\ for ("hello") |_| returns() else unreachable;
+ \\}
+ ,
+ "tmp.zig:5:30: error: expression value is ignored",
+ "tmp.zig:9:30: error: expression value is ignored",
+ );
}
--
cgit v1.2.3
From fee0e6c8b9d676ef785aab52d25b19ed64e9adeb Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Date: Fri, 10 May 2019 16:39:50 -0400
Subject: fix hang for some compile errors
see #2467
---
src/ir.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
(limited to 'src/ir.cpp')
diff --git a/src/ir.cpp b/src/ir.cpp
index d1d1c44043..e89d30232e 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -10225,6 +10225,7 @@ static void ir_finish_bb(IrAnalyze *ira) {
ira->instruction_index += 1;
}
+ size_t my_old_bb_index = ira->old_bb_index;
ira->old_bb_index += 1;
bool need_repeat = true;
@@ -10235,7 +10236,7 @@ static void ir_finish_bb(IrAnalyze *ira) {
ira->old_bb_index += 1;
continue;
}
- if (old_bb->other->instruction_list.length != 0) {
+ if (old_bb->other->instruction_list.length != 0 || ira->old_bb_index == my_old_bb_index) {
ira->old_bb_index += 1;
continue;
}
--
cgit v1.2.3