remove var args from the language

closes #208
master
Andrew Kelley 2019-12-09 14:55:51 -05:00
parent f205d23e65
commit a3f6a58c77
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
21 changed files with 2049 additions and 2820 deletions

View File

@ -5862,7 +5862,7 @@ pub fn main() void {
{#code_begin|syntax#}
/// Calls print and then flushes the buffer.
pub fn printf(self: *OutStream, comptime format: []const u8, args: ...) anyerror!void {
pub fn printf(self: *OutStream, comptime format: []const u8, args: var) anyerror!void {
const State = enum {
Start,
OpenBrace,
@ -8277,7 +8277,6 @@ test "integer truncation" {
<li>{#link|union#}</li>
<li>{#link|Functions#}</li>
<li>BoundFn</li>
<li>ArgTuple</li>
<li>{#link|struct#}</li>
</ul>
{#header_close#}
@ -8310,7 +8309,6 @@ pub const TypeId = enum {
Fn,
Block,
BoundFn,
ArgTuple,
Opaque,
};
{#code_end#}
@ -8343,7 +8341,6 @@ pub const TypeInfo = union(TypeId) {
Union: Union,
Fn: Fn,
BoundFn: Fn,
ArgTuple: void,
Opaque: void,
Promise: Promise,
Vector: Vector,

View File

@ -116,7 +116,6 @@ pub const TypeInfo = union(enum) {
Union: Union,
Fn: Fn,
BoundFn: Fn,
ArgTuple: void,
Opaque: void,
Frame: void,
AnyFrame: AnyFrame,

View File

@ -94,9 +94,7 @@ pub fn format(
args: var,
) Errors!void {
const ArgSetType = @IntType(false, 32);
const args_fields = std.meta.fields(@typeOf(args));
const args_len = args_fields.len;
if (args_len > ArgSetType.bit_count) {
if (args.len > ArgSetType.bit_count) {
@compileError("32 arguments max are supported per format call");
}
@ -160,14 +158,14 @@ pub fn format(
maybe_pos_arg.? += c - '0';
specifier_start = i + 1;
if (maybe_pos_arg.? >= args_len) {
if (maybe_pos_arg.? >= args.len) {
@compileError("Positional value refers to non-existent argument");
}
},
'}' => {
const arg_to_print = comptime nextArg(&used_pos_args, maybe_pos_arg, &next_arg);
if (arg_to_print >= args_len) {
if (arg_to_print >= args.len) {
@compileError("Too few arguments");
}
@ -304,7 +302,7 @@ pub fn format(
used_pos_args |= 1 << i;
}
if (@popCount(ArgSetType, used_pos_args) != args_len) {
if (@popCount(ArgSetType, used_pos_args) != args.len) {
@compileError("Unused arguments");
}
if (state != State.Start) {

View File

@ -79,7 +79,6 @@ pub fn hash(hasher: var, key: var, comptime strat: HashStrategy) void {
.NoReturn,
.Opaque,
.Undefined,
.ArgTuple,
.Void,
.Null,
.BoundFn,

View File

@ -1194,7 +1194,7 @@
// This is just for debugging purposes, not needed to function
var assertList = ["Type","Void","Bool","NoReturn","Int","Float","Pointer","Array","Struct",
"ComptimeFloat","ComptimeInt","Undefined","Null","Optional","ErrorUnion","ErrorSet","Enum",
"Union","Fn","BoundFn","ArgTuple","Opaque","Frame","AnyFrame","Vector","EnumLiteral"];
"Union","Fn","BoundFn","Opaque","Frame","AnyFrame","Vector","EnumLiteral"];
for (var i = 0; i < assertList.length; i += 1) {
if (map[assertList[i]] == null) throw new Error("No type kind '" + assertList[i] + "' found");
}

View File

@ -33,7 +33,6 @@ pub fn expectEqual(expected: var, actual: @typeOf(expected)) void {
switch (@typeInfo(@typeOf(actual))) {
.NoReturn,
.BoundFn,
.ArgTuple,
.Opaque,
.Frame,
.AnyFrame,

View File

@ -41,7 +41,6 @@ pub const Type = struct {
.Enum => @fieldParentPtr(Enum, "base", base).destroy(comp),
.Union => @fieldParentPtr(Union, "base", base).destroy(comp),
.BoundFn => @fieldParentPtr(BoundFn, "base", base).destroy(comp),
.ArgTuple => @fieldParentPtr(ArgTuple, "base", base).destroy(comp),
.Opaque => @fieldParentPtr(Opaque, "base", base).destroy(comp),
.Frame => @fieldParentPtr(Frame, "base", base).destroy(comp),
.AnyFrame => @fieldParentPtr(AnyFrame, "base", base).destroy(comp),
@ -76,7 +75,6 @@ pub const Type = struct {
.Enum => return @fieldParentPtr(Enum, "base", base).getLlvmType(allocator, llvm_context),
.Union => return @fieldParentPtr(Union, "base", base).getLlvmType(allocator, llvm_context),
.BoundFn => return @fieldParentPtr(BoundFn, "base", base).getLlvmType(allocator, llvm_context),
.ArgTuple => unreachable,
.Opaque => return @fieldParentPtr(Opaque, "base", base).getLlvmType(allocator, llvm_context),
.Frame => return @fieldParentPtr(Frame, "base", base).getLlvmType(allocator, llvm_context),
.AnyFrame => return @fieldParentPtr(AnyFrame, "base", base).getLlvmType(allocator, llvm_context),
@ -93,7 +91,6 @@ pub const Type = struct {
.Undefined,
.Null,
.BoundFn,
.ArgTuple,
.Opaque,
=> unreachable,
@ -128,7 +125,6 @@ pub const Type = struct {
.Undefined,
.Null,
.BoundFn,
.ArgTuple,
.Opaque,
=> unreachable,
@ -1004,14 +1000,6 @@ pub const Type = struct {
}
};
pub const ArgTuple = struct {
base: Type,
pub fn destroy(self: *ArgTuple, comp: *Compilation) void {
comp.gpa().destroy(self);
}
};
pub const Opaque = struct {
base: Type,

View File

@ -1471,7 +1471,6 @@ enum ZigTypeId {
ZigTypeIdUnion,
ZigTypeIdFn,
ZigTypeIdBoundFn,
ZigTypeIdArgTuple,
ZigTypeIdOpaque,
ZigTypeIdFnFrame,
ZigTypeIdAnyFrame,
@ -2039,7 +2038,6 @@ struct CodeGen {
ZigType *entry_null;
ZigType *entry_var;
ZigType *entry_global_error_set;
ZigType *entry_arg_tuple;
ZigType *entry_enum_literal;
ZigType *entry_any_frame;
} builtin_types;

View File

@ -323,7 +323,6 @@ AstNode *type_decl_node(ZigType *type_entry) {
case ZigTypeIdErrorSet:
case ZigTypeIdFn:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdVector:
case ZigTypeIdAnyFrame:
return nullptr;
@ -392,7 +391,6 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {
case ZigTypeIdErrorSet:
case ZigTypeIdFn:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdVector:
case ZigTypeIdAnyFrame:
return true;
@ -1558,7 +1556,6 @@ static Error emit_error_unless_type_allowed_in_packed_container(CodeGen *g, ZigT
case ZigTypeIdErrorUnion:
case ZigTypeIdErrorSet:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
case ZigTypeIdFnFrame:
case ZigTypeIdAnyFrame:
@ -1661,7 +1658,6 @@ Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result) {
case ZigTypeIdErrorUnion:
case ZigTypeIdErrorSet:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdVoid:
case ZigTypeIdFnFrame:
case ZigTypeIdAnyFrame:
@ -1786,12 +1782,9 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
if (fn_type_id.cc == CallingConventionC) {
fn_type_id.param_count = fn_type_id.next_param_index;
continue;
} else if (calling_convention_allows_zig_types(fn_type_id.cc)) {
return get_generic_fn_type(g, &fn_type_id);
} else {
add_node_error(g, param_node,
buf_sprintf("var args not allowed in function with calling convention '%s'",
calling_convention_name(fn_type_id.cc)));
buf_sprintf("var args only allowed in functions with C calling convention"));
return g->builtin_types.entry_invalid;
}
} else if (param_node->data.param_decl.var_token != nullptr) {
@ -1838,7 +1831,6 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
case ZigTypeIdUnreachable:
case ZigTypeIdUndefined:
case ZigTypeIdNull:
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
add_node_error(g, param_node->data.param_decl.type,
buf_sprintf("parameter of type '%s' not allowed", buf_ptr(&type_entry->name)));
@ -1913,7 +1905,6 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
case ZigTypeIdUndefined:
case ZigTypeIdNull:
case ZigTypeIdArgTuple:
add_node_error(g, fn_proto->return_type,
buf_sprintf("return type '%s' not allowed", buf_ptr(&specified_return_type->name)));
return g->builtin_types.entry_invalid;
@ -1963,7 +1954,6 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc
case ZigTypeIdInvalid:
case ZigTypeIdUndefined:
case ZigTypeIdNull:
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
zig_unreachable();
@ -3720,7 +3710,6 @@ ZigType *validate_var_type(CodeGen *g, AstNode *source_node, ZigType *type_entry
case ZigTypeIdUnreachable:
case ZigTypeIdUndefined:
case ZigTypeIdNull:
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
add_node_error(g, source_node, buf_sprintf("variable of type '%s' not allowed",
buf_ptr(&type_entry->name)));
@ -4275,7 +4264,6 @@ bool is_container(ZigType *type_entry) {
case ZigTypeIdErrorSet:
case ZigTypeIdFn:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
case ZigTypeIdVector:
case ZigTypeIdFnFrame:
@ -4982,7 +4970,6 @@ bool handle_is_ptr(ZigType *type_entry) {
case ZigTypeIdUndefined:
case ZigTypeIdNull:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
zig_unreachable();
case ZigTypeIdUnreachable:
@ -5201,9 +5188,6 @@ static uint32_t hash_const_val(ZigValue *const_val) {
memcpy(&ints[0], &f128, 16);
return ints[0] ^ ints[1] ^ ints[2] ^ ints[3] ^ 0xed8b3dfb;
}
case ZigTypeIdArgTuple:
return (uint32_t)const_val->data.x_arg_tuple.start_index * (uint32_t)281907309 +
(uint32_t)const_val->data.x_arg_tuple.end_index * (uint32_t)2290442768;
case ZigTypeIdFn:
assert(const_val->data.x_ptr.mut == ConstPtrMutComptimeConst);
assert(const_val->data.x_ptr.special == ConstPtrSpecialFunction);
@ -5357,9 +5341,6 @@ static bool can_mutate_comptime_var_state(ZigValue *value) {
case ZigTypeIdUnion:
return can_mutate_comptime_var_state(value->data.x_union.payload);
case ZigTypeIdArgTuple:
zig_panic("TODO var args at comptime is currently not supported");
}
zig_unreachable();
}
@ -5400,9 +5381,6 @@ static bool return_type_is_cacheable(ZigType *return_type) {
case ZigTypeIdErrorUnion:
return return_type_is_cacheable(return_type->data.error_union.payload_type);
case ZigTypeIdArgTuple:
zig_panic("TODO var args at comptime is currently not supported");
}
zig_unreachable();
}
@ -5540,7 +5518,6 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
case ZigTypeIdEnumLiteral:
case ZigTypeIdMetaType:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdOptional:
case ZigTypeIdFn:
case ZigTypeIdBool:
@ -5626,7 +5603,6 @@ ReqCompTime type_requires_comptime(CodeGen *g, ZigType *ty) {
case ZigTypeIdNull:
case ZigTypeIdMetaType:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
return ReqCompTimeYes;
case ZigTypeIdArray:
return type_requires_comptime(g, ty->data.array.child_type);
@ -5918,20 +5894,6 @@ ZigValue *create_const_ptr_hard_coded_addr(CodeGen *g, ZigType *pointee_type,
return const_val;
}
void init_const_arg_tuple(CodeGen *g, ZigValue *const_val, size_t arg_index_start, size_t arg_index_end) {
const_val->special = ConstValSpecialStatic;
const_val->type = g->builtin_types.entry_arg_tuple;
const_val->data.x_arg_tuple.start_index = arg_index_start;
const_val->data.x_arg_tuple.end_index = arg_index_end;
}
ZigValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end) {
ZigValue *const_val = create_const_vals(1);
init_const_arg_tuple(g, const_val, arg_index_start, arg_index_end);
return const_val;
}
ZigValue *create_const_vals(size_t count) {
return allocate<ZigValue>(count, "ZigValue");
}
@ -6679,9 +6641,6 @@ bool const_values_equal(CodeGen *g, ZigValue *a, ZigValue *b) {
}
case ZigTypeIdErrorUnion:
zig_panic("TODO");
case ZigTypeIdArgTuple:
return a->data.x_arg_tuple.start_index == b->data.x_arg_tuple.start_index &&
a->data.x_arg_tuple.end_index == b->data.x_arg_tuple.end_index;
case ZigTypeIdBoundFn:
case ZigTypeIdInvalid:
case ZigTypeIdUnreachable:
@ -7008,11 +6967,6 @@ void render_const_value(CodeGen *g, Buf *buf, ZigValue *const_val) {
}
case ZigTypeIdErrorSet:
return render_const_val_err_set(g, buf, const_val, type_entry);
case ZigTypeIdArgTuple:
{
buf_appendf(buf, "(args value)");
return;
}
case ZigTypeIdFnFrame:
buf_appendf(buf, "(TODO: async function frame value)");
return;
@ -7075,7 +7029,6 @@ uint32_t type_id_hash(TypeId x) {
case ZigTypeIdUnion:
case ZigTypeIdFn:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdFnFrame:
case ZigTypeIdAnyFrame:
zig_unreachable();
@ -7127,7 +7080,6 @@ bool type_id_eql(TypeId a, TypeId b) {
case ZigTypeIdUnion:
case ZigTypeIdFn:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
case ZigTypeIdFnFrame:
case ZigTypeIdAnyFrame:
@ -7350,7 +7302,6 @@ static const ZigTypeId all_type_ids[] = {
ZigTypeIdUnion,
ZigTypeIdFn,
ZigTypeIdBoundFn,
ZigTypeIdArgTuple,
ZigTypeIdOpaque,
ZigTypeIdFnFrame,
ZigTypeIdAnyFrame,
@ -7413,18 +7364,16 @@ size_t type_id_index(ZigType *entry) {
return 18;
case ZigTypeIdBoundFn:
return 19;
case ZigTypeIdArgTuple:
return 20;
case ZigTypeIdOpaque:
return 21;
return 20;
case ZigTypeIdFnFrame:
return 22;
return 21;
case ZigTypeIdAnyFrame:
return 23;
return 22;
case ZigTypeIdVector:
return 24;
return 23;
case ZigTypeIdEnumLiteral:
return 25;
return 24;
}
zig_unreachable();
}
@ -7475,8 +7424,6 @@ const char *type_id_name(ZigTypeId id) {
return "Fn";
case ZigTypeIdBoundFn:
return "BoundFn";
case ZigTypeIdArgTuple:
return "ArgTuple";
case ZigTypeIdOpaque:
return "Opaque";
case ZigTypeIdVector:
@ -9064,7 +9011,6 @@ static void resolve_llvm_types(CodeGen *g, ZigType *type, ResolveStatus wanted_r
case ZigTypeIdUndefined:
case ZigTypeIdNull:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
zig_unreachable();
case ZigTypeIdFloat:
case ZigTypeIdOpaque:

View File

@ -171,9 +171,6 @@ void init_const_slice(CodeGen *g, ZigValue *const_val, ZigValue *array_val,
size_t start, size_t len, bool is_const);
ZigValue *create_const_slice(CodeGen *g, ZigValue *array_val, size_t start, size_t len, bool is_const);
void init_const_arg_tuple(CodeGen *g, ZigValue *const_val, size_t arg_index_start, size_t arg_index_end);
ZigValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end);
void init_const_null(ZigValue *const_val, ZigType *type);
ZigValue *create_const_null(ZigType *type);

View File

@ -6539,7 +6539,6 @@ static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, Zig
case ZigTypeIdErrorUnion:
case ZigTypeIdErrorSet:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdVoid:
case ZigTypeIdOpaque:
zig_unreachable();
@ -7182,7 +7181,6 @@ check: switch (const_val->special) {
case ZigTypeIdUndefined:
case ZigTypeIdNull:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
zig_unreachable();
case ZigTypeIdFnFrame:
@ -7887,11 +7885,6 @@ static void define_builtin_types(CodeGen *g) {
buf_init_from_str(&entry->name, "(var)");
g->builtin_types.entry_var = entry;
}
{
ZigType *entry = new_type_table_entry(ZigTypeIdArgTuple);
buf_init_from_str(&entry->name, "(args)");
g->builtin_types.entry_arg_tuple = entry;
}
for (size_t i = 0; i < array_length(c_int_type_infos); i += 1) {
const CIntTypeInfo *info = &c_int_type_infos[i];
@ -9532,7 +9525,6 @@ static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, ZigType *type_e
case ZigTypeIdUndefined:
case ZigTypeIdNull:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdErrorUnion:
case ZigTypeIdErrorSet:
case ZigTypeIdFnFrame:
@ -9721,7 +9713,6 @@ static void get_c_type(CodeGen *g, GenH *gen_h, ZigType *type_entry, Buf *out_bu
case ZigTypeIdEnumLiteral:
case ZigTypeIdUndefined:
case ZigTypeIdNull:
case ZigTypeIdArgTuple:
case ZigTypeIdFnFrame:
case ZigTypeIdAnyFrame:
zig_unreachable();
@ -9781,7 +9772,6 @@ static void gen_h_file_types(CodeGen* g, GenH* gen_h, Buf* out_buf) {
case ZigTypeIdErrorUnion:
case ZigTypeIdErrorSet:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdOptional:
case ZigTypeIdFn:
case ZigTypeIdVector:

View File

@ -780,7 +780,6 @@ static bool types_have_same_zig_comptime_repr(CodeGen *codegen, ZigType *expecte
case ZigTypeIdErrorUnion:
case ZigTypeIdEnum:
case ZigTypeIdUnion:
case ZigTypeIdArgTuple:
case ZigTypeIdVector:
case ZigTypeIdFnFrame:
return false;
@ -14791,7 +14790,6 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *
case ZigTypeIdFn:
case ZigTypeIdOpaque:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdEnum:
case ZigTypeIdEnumLiteral:
case ZigTypeIdAnyFrame:
@ -16437,7 +16435,6 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
case ZigTypeIdErrorUnion:
case ZigTypeIdErrorSet:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
case ZigTypeIdFnFrame:
case ZigTypeIdAnyFrame:
@ -16462,7 +16459,6 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
case ZigTypeIdVector:
zig_panic("TODO export const value of type %s", buf_ptr(&target->value->type->name));
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
case ZigTypeIdEnumLiteral:
case ZigTypeIdFnFrame:
@ -16609,7 +16605,6 @@ static bool type_can_bit_cast(ZigType *t) {
case ZigTypeIdMetaType:
case ZigTypeIdOpaque:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdUnreachable:
case ZigTypeIdComptimeFloat:
case ZigTypeIdComptimeInt:
@ -17416,23 +17411,6 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
return true;
}
static ZigVar *get_fn_var_by_index(ZigFn *fn_entry, size_t index) {
FnTypeParamInfo *src_param_info = &fn_entry->type_entry->data.fn.fn_type_id.param_info[index];
if (!type_has_bits(src_param_info->type))
return nullptr;
size_t next_var_i = 0;
for (size_t param_i = 0; param_i < index; param_i += 1) {
FnTypeParamInfo *src_param_info = &fn_entry->type_entry->data.fn.fn_type_id.param_info[param_i];
if (!type_has_bits(src_param_info->type)) {
continue;
}
next_var_i += 1;
}
return fn_entry->variable_list.at(next_var_i);
}
static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, ZigVar *var) {
while (var->next_var != nullptr) {
var = var->next_var;
@ -17690,16 +17668,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i
var_args_1_or_0 = fn_type_id->is_var_args ? 1 : 0;
}
size_t src_param_count = fn_type_id->param_count - var_args_1_or_0;
size_t call_param_count = args_len + first_arg_1_or_0;
for (size_t i = 0; i < args_len; i += 1) {
ZigValue *arg_tuple_value = args_ptr[i]->value;
if (arg_tuple_value->type->id == ZigTypeIdArgTuple) {
call_param_count -= 1;
call_param_count += arg_tuple_value->data.x_arg_tuple.end_index -
arg_tuple_value->data.x_arg_tuple.start_index;
}
}
AstNode *source_node = source_instr->source_node;
AstNode *fn_proto_node = fn_entry ? fn_entry->proto_node : nullptr;;
@ -17854,16 +17823,7 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i
return ira->codegen->invalid_instruction;
}
// Count the arguments of the function type id we are creating
size_t new_fn_arg_count = first_arg_1_or_0;
for (size_t call_i = 0; call_i < args_len; call_i += 1) {
IrInstruction *arg = args_ptr[call_i];
if (arg->value->type->id == ZigTypeIdArgTuple) {
new_fn_arg_count += arg->value->data.x_arg_tuple.end_index - arg->value->data.x_arg_tuple.start_index;
} else {
new_fn_arg_count += 1;
}
}
size_t new_fn_arg_count = first_arg_1_or_0 + args_len;
IrInstruction **casted_args = allocate<IrInstruction *>(new_fn_arg_count);
@ -17914,76 +17874,19 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i
}
}
bool found_first_var_arg = false;
size_t first_var_arg;
ZigFn *parent_fn_entry = exec_fn_entry(ira->new_irb.exec);
assert(parent_fn_entry);
for (size_t call_i = 0; call_i < args_len; call_i += 1) {
IrInstruction *arg = args_ptr[call_i];
if (arg->value->type->id == ZigTypeIdArgTuple) {
for (size_t arg_tuple_i = arg->value->data.x_arg_tuple.start_index;
arg_tuple_i < arg->value->data.x_arg_tuple.end_index; arg_tuple_i += 1)
{
AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i);
assert(param_decl_node->type == NodeTypeParamDecl);
bool is_var_args = param_decl_node->data.param_decl.is_var_args;
if (is_var_args && !found_first_var_arg) {
first_var_arg = inst_fn_type_id.param_count;
found_first_var_arg = true;
}
ZigVar *arg_var = get_fn_var_by_index(parent_fn_entry, arg_tuple_i);
if (arg_var == nullptr) {
ir_add_error(ira, arg,
buf_sprintf("compiler bug: var args can't handle void. https://github.com/ziglang/zig/issues/557"));
return ira->codegen->invalid_instruction;
}
IrInstruction *arg_var_ptr_inst = ir_get_var_ptr(ira, arg, arg_var);
if (type_is_invalid(arg_var_ptr_inst->value->type))
return ira->codegen->invalid_instruction;
IrInstruction *arg_tuple_arg = ir_get_deref(ira, arg, arg_var_ptr_inst, nullptr);
if (type_is_invalid(arg_tuple_arg->value->type))
return ira->codegen->invalid_instruction;
if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg_tuple_arg, &impl_fn->child_scope,
&next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn))
{
return ira->codegen->invalid_instruction;
}
}
} else {
AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i);
assert(param_decl_node->type == NodeTypeParamDecl);
bool is_var_args = param_decl_node->data.param_decl.is_var_args;
if (is_var_args && !found_first_var_arg) {
first_var_arg = inst_fn_type_id.param_count;
found_first_var_arg = true;
}
if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg, &impl_fn->child_scope,
&next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn))
{
return ira->codegen->invalid_instruction;
}
}
}
if (fn_proto_node->data.fn_proto.is_var_args) {
AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i);
Buf *param_name = param_decl_node->data.param_decl.name;
assert(param_decl_node->type == NodeTypeParamDecl);
if (!found_first_var_arg) {
first_var_arg = inst_fn_type_id.param_count;
if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg, &impl_fn->child_scope,
&next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn))
{
return ira->codegen->invalid_instruction;
}
ZigValue *var_args_val = create_const_arg_tuple(ira->codegen,
first_var_arg, inst_fn_type_id.param_count);
ZigVar *var = add_variable(ira->codegen, param_decl_node,
impl_fn->child_scope, param_name, true, var_args_val, nullptr, var_args_val->type);
impl_fn->child_scope = var->child_scope;
}
if (fn_proto_node->data.fn_proto.align_expr != nullptr) {
@ -18153,55 +18056,20 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstruction *source_i
if (type_is_invalid(old_arg->value->type))
return ira->codegen->invalid_instruction;
if (old_arg->value->type->id == ZigTypeIdArgTuple) {
for (size_t arg_tuple_i = old_arg->value->data.x_arg_tuple.start_index;
arg_tuple_i < old_arg->value->data.x_arg_tuple.end_index; arg_tuple_i += 1)
{
ZigVar *arg_var = get_fn_var_by_index(parent_fn_entry, arg_tuple_i);
if (arg_var == nullptr) {
ir_add_error(ira, old_arg,
buf_sprintf("compiler bug: var args can't handle void. https://github.com/ziglang/zig/issues/557"));
return ira->codegen->invalid_instruction;
}
IrInstruction *arg_var_ptr_inst = ir_get_var_ptr(ira, old_arg, arg_var);
if (type_is_invalid(arg_var_ptr_inst->value->type))
return ira->codegen->invalid_instruction;
IrInstruction *arg_tuple_arg = ir_get_deref(ira, old_arg, arg_var_ptr_inst, nullptr);
if (type_is_invalid(arg_tuple_arg->value->type))
return ira->codegen->invalid_instruction;
IrInstruction *casted_arg;
if (next_arg_index < src_param_count) {
ZigType *param_type = fn_type_id->param_info[next_arg_index].type;
if (type_is_invalid(param_type))
return ira->codegen->invalid_instruction;
casted_arg = ir_implicit_cast(ira, arg_tuple_arg, param_type);
if (type_is_invalid(casted_arg->value->type))
return ira->codegen->invalid_instruction;
} else {
casted_arg = arg_tuple_arg;
}
casted_args[next_arg_index] = casted_arg;
next_arg_index += 1;
}
IrInstruction *casted_arg;
if (next_arg_index < src_param_count) {
ZigType *param_type = fn_type_id->param_info[next_arg_index].type;
if (type_is_invalid(param_type))
return ira->codegen->invalid_instruction;
casted_arg = ir_implicit_cast(ira, old_arg, param_type);
if (type_is_invalid(casted_arg->value->type))
return ira->codegen->invalid_instruction;
} else {
IrInstruction *casted_arg;
if (next_arg_index < src_param_count) {
ZigType *param_type = fn_type_id->param_info[next_arg_index].type;
if (type_is_invalid(param_type))
return ira->codegen->invalid_instruction;
casted_arg = ir_implicit_cast(ira, old_arg, param_type);
if (type_is_invalid(casted_arg->value->type))
return ira->codegen->invalid_instruction;
} else {
casted_arg = old_arg;
}
casted_args[next_arg_index] = casted_arg;
next_arg_index += 1;
casted_arg = old_arg;
}
casted_args[next_arg_index] = casted_arg;
next_arg_index += 1;
}
assert(next_arg_index == call_param_count);
@ -19186,37 +19054,6 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
} else if (is_slice(array_type)) {
return_type = adjust_ptr_len(ira->codegen, array_type->data.structure.fields[slice_ptr_index]->type_entry,
elem_ptr_instruction->ptr_len);
} else if (array_type->id == ZigTypeIdArgTuple) {
ZigValue *ptr_val = ir_resolve_const(ira, array_ptr, UndefBad);
if (!ptr_val)
return ira->codegen->invalid_instruction;
ZigValue *args_val = const_ptr_pointee(ira, ira->codegen, ptr_val, elem_ptr_instruction->base.source_node);
if (args_val == nullptr)
return ira->codegen->invalid_instruction;
size_t start = args_val->data.x_arg_tuple.start_index;
size_t end = args_val->data.x_arg_tuple.end_index;
uint64_t elem_index_val;
if (!ir_resolve_usize(ira, elem_index, &elem_index_val))
return ira->codegen->invalid_instruction;
size_t index = elem_index_val;
size_t len = end - start;
if (index >= len) {
ir_add_error(ira, &elem_ptr_instruction->base,
buf_sprintf("index %" ZIG_PRI_usize " outside argument list of size %" ZIG_PRI_usize "", index, len));
return ira->codegen->invalid_instruction;
}
size_t abs_index = start + index;
ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec);
assert(fn_entry);
ZigVar *var = get_fn_var_by_index(fn_entry, abs_index);
bool is_const = true;
bool is_volatile = false;
if (var) {
return ir_get_var_ptr(ira, &elem_ptr_instruction->base, var);
} else {
return ir_get_const_ptr(ira, &elem_ptr_instruction->base, ira->codegen->intern.for_void(),
ira->codegen->builtin_types.entry_void, ConstPtrMutComptimeConst, is_const, is_volatile, 0);
}
} else if (array_type->id == ZigTypeIdVector) {
// This depends on whether the element index is comptime, so it is computed later.
return_type = nullptr;
@ -20025,6 +19862,10 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc
if (type_is_invalid(container_type)) {
return ira->codegen->invalid_instruction;
} else if (is_tuple(container_type) && !field_ptr_instruction->initializing && buf_eql_str(field_name, "len")) {
IrInstruction *len_inst = ir_const_unsigned(ira, &field_ptr_instruction->base,
container_type->data.structure.src_field_count);
return ir_get_ref(ira, &field_ptr_instruction->base, len_inst, true, false);
} else if (is_slice(container_type) || is_container_ref(container_type)) {
assert(container_ptr->value->type->id == ZigTypeIdPointer);
if (container_type->id == ZigTypeIdPointer) {
@ -20045,32 +19886,6 @@ static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstruc
init_const_usize(ira->codegen, len_val, container_type->data.array.len);
}
ZigType *usize = ira->codegen->builtin_types.entry_usize;
bool ptr_is_const = true;
bool ptr_is_volatile = false;
return ir_get_const_ptr(ira, &field_ptr_instruction->base, len_val,
usize, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0);
} else {
ir_add_error_node(ira, source_node,
buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name),
buf_ptr(&container_type->name)));
return ira->codegen->invalid_instruction;
}
} else if (container_type->id == ZigTypeIdArgTuple) {
ZigValue *container_ptr_val = ir_resolve_const(ira, container_ptr, UndefBad);
if (!container_ptr_val)
return ira->codegen->invalid_instruction;
assert(container_ptr->value->type->id == ZigTypeIdPointer);
ZigValue *child_val = const_ptr_pointee(ira, ira->codegen, container_ptr_val, source_node);
if (child_val == nullptr)
return ira->codegen->invalid_instruction;
if (buf_eql_str(field_name, "len")) {
ZigValue *len_val = create_const_vals(1);
size_t len = child_val->data.x_arg_tuple.end_index - child_val->data.x_arg_tuple.start_index;
init_const_usize(ira->codegen, len_val, len);
ZigType *usize = ira->codegen->builtin_types.entry_usize;
bool ptr_is_const = true;
bool ptr_is_volatile = false;
@ -21258,7 +21073,6 @@ static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira,
case ZigTypeIdNull:
case ZigTypeIdOptional:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
case ZigTypeIdVector:
case ZigTypeIdFnFrame:
@ -22580,7 +22394,6 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInstruction *source_instr
case ZigTypeIdEnumLiteral:
case ZigTypeIdUndefined:
case ZigTypeIdNull:
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
result = ira->codegen->intern.for_void();
break;
@ -23357,7 +23170,6 @@ static ZigType *type_info_to_type(IrAnalyze *ira, IrInstruction *instruction, Zi
case ZigTypeIdUnion:
case ZigTypeIdFn:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdStruct:
ir_add_error(ira, instruction, buf_sprintf(
"@Type not availble for 'TypeInfo.%s'", type_id_name(tagTypeId)));
@ -26452,7 +26264,6 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ZigValue *val)
case ZigTypeIdMetaType:
case ZigTypeIdOpaque:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdUnreachable:
case ZigTypeIdComptimeFloat:
case ZigTypeIdComptimeInt:
@ -26609,7 +26420,6 @@ static Error buf_read_value_bytes(IrAnalyze *ira, CodeGen *codegen, AstNode *sou
case ZigTypeIdMetaType:
case ZigTypeIdOpaque:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdUnreachable:
case ZigTypeIdComptimeFloat:
case ZigTypeIdComptimeInt:
@ -28838,7 +28648,6 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
case ZigTypeIdUndefined:
case ZigTypeIdNull:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdVoid:
case ZigTypeIdOpaque:
ir_add_error(ira, lazy_align_of->target_type,
@ -28890,7 +28699,6 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
case ZigTypeIdUndefined:
case ZigTypeIdNull:
case ZigTypeIdBoundFn:
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
ir_add_error(ira, lazy_size_of->target_type,
buf_sprintf("no size available for type '%s'",
@ -28969,7 +28777,6 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
case ZigTypeIdUnreachable:
case ZigTypeIdUndefined:
case ZigTypeIdNull:
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
ir_add_error(ira, lazy_slice_type->elem_type,
buf_sprintf("slice of type '%s' not allowed", buf_ptr(&elem_type->name)));
@ -29102,7 +28909,6 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
case ZigTypeIdUnreachable:
case ZigTypeIdUndefined:
case ZigTypeIdNull:
case ZigTypeIdArgTuple:
case ZigTypeIdOpaque:
ir_add_error(ira, lazy_array_type->elem_type,
buf_sprintf("array of type '%s' not allowed",

View File

@ -802,12 +802,6 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc) {
res->data.fn_proto.auto_err_set = exmark != nullptr;
res->data.fn_proto.return_type = return_type;
// It seems that the Zig compiler expects varargs to be the
// last parameter in the decl list. This is not encoded in
// the grammar, which allows varargs anywhere in the decl.
// Since varargs is gonna be removed at some point, I'm not
// gonna encode this "varargs is always last" rule in the
// grammar, and just enforce it here, until varargs is removed.
for (size_t i = 0; i < params.length; i++) {
AstNode *param_decl = params.at(i);
assert(param_decl->type == NodeTypeParamDecl);

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
cases.add("declare enum",
\\const Foo = extern enum { A, B, C };
\\export fn entry(foo: Foo) void { }
,
, &[_][]const u8{
\\enum Foo {
\\ A = 0,
\\ B = 1,
@ -12,7 +12,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
\\};
,
\\void entry(enum Foo foo);
);
});
cases.add("declare struct",
\\const Foo = extern struct {
@ -24,7 +24,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
\\ F: u64,
\\};
\\export fn entry(foo: Foo) void { }
,
, &[_][]const u8{
\\struct Foo {
\\ int32_t A;
\\ float B;
@ -36,7 +36,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
,
\\void entry(struct Foo foo);
\\
);
});
cases.add("declare union",
\\const Big = extern struct {
@ -53,7 +53,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
\\ D: Big,
\\};
\\export fn entry(foo: Foo) void {}
,
, &[_][]const u8{
\\struct Big {
\\ uint64_t A;
\\ uint64_t B;
@ -71,17 +71,17 @@ pub fn addCases(cases: *tests.GenHContext) void {
,
\\void entry(union Foo foo);
\\
);
});
cases.add("declare opaque type",
\\const Foo = @OpaqueType();
\\
\\export fn entry(foo: ?*Foo) void { }
,
, &[_][]const u8{
\\struct Foo;
,
\\void entry(struct Foo * foo);
);
});
cases.add("array field-type",
\\const Foo = extern struct {
@ -89,7 +89,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
\\ B: [4]*u32,
\\};
\\export fn entry(foo: Foo, bar: [3]u8) void { }
,
, &[_][]const u8{
\\struct Foo {
\\ int32_t A[2];
\\ uint32_t * B[4];
@ -97,7 +97,7 @@ pub fn addCases(cases: *tests.GenHContext) void {
,
\\void entry(struct Foo foo, uint8_t bar[]);
\\
);
});
cases.add("ptr to zig struct",
\\const S = struct {
@ -107,12 +107,12 @@ pub fn addCases(cases: *tests.GenHContext) void {
\\export fn a(s: *S) u8 {
\\ return s.a;
\\}
,
, &[_][]const u8{
\\struct S;
,
\\uint8_t a(struct S * s);
\\
);
});
cases.add("ptr to zig union",
\\const U = union(enum) {
@ -123,12 +123,12 @@ pub fn addCases(cases: *tests.GenHContext) void {
\\export fn a(s: *U) u8 {
\\ return s.A;
\\}
,
, &[_][]const u8{
\\union U;
,
\\uint8_t a(union U * s);
\\
);
});
cases.add("ptr to zig enum",
\\const E = enum(u8) {
@ -139,10 +139,10 @@ pub fn addCases(cases: *tests.GenHContext) void {
\\export fn a(s: *E) u8 {
\\ return @enumToInt(s.*);
\\}
,
, &[_][]const u8{
\\enum E;
,
\\uint8_t a(enum E * s);
\\
);
});
}

View File

@ -670,10 +670,10 @@ fn loopNTimes(comptime n: usize) void {
}
test "variable inside inline loop that has different types on different iterations" {
testVarInsideInlineLoop(true, @as(u32, 42));
testVarInsideInlineLoop(.{true, @as(u32, 42)});
}
fn testVarInsideInlineLoop(args: ...) void {
fn testVarInsideInlineLoop(args: var) void {
comptime var i = 0;
inline while (i < args.len) : (i += 1) {
const x = args[i];

View File

@ -15,7 +15,6 @@ test "reflection: function return type, var args, and param types" {
comptime {
expect(@typeOf(dummy).ReturnType == i32);
expect(!@typeOf(dummy).is_var_args);
expect(@typeOf(dummy_varargs).is_var_args);
expect(@typeOf(dummy).arg_count == 3);
expect(@ArgType(@typeOf(dummy), 0) == bool);
expect(@ArgType(@typeOf(dummy), 1) == i32);
@ -26,7 +25,6 @@ test "reflection: function return type, var args, and param types" {
fn dummy(a: bool, b: i32, c: f32) i32 {
return 1234;
}
fn dummy_varargs(args: ...) void {}
test "reflection: struct member types and names" {
comptime {

View File

@ -198,7 +198,7 @@ fn testUnion() void {
expect(@as(TypeId, typeinfo_info) == TypeId.Union);
expect(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
expect(typeinfo_info.Union.tag_type.? == TypeId);
expect(typeinfo_info.Union.fields.len == 26);
expect(typeinfo_info.Union.fields.len == 25);
expect(typeinfo_info.Union.fields[4].enum_field != null);
expect(typeinfo_info.Union.fields[4].enum_field.?.value == 4);
expect(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));

View File

@ -1,6 +1,6 @@
const expect = @import("std").testing.expect;
fn add(args: ...) i32 {
fn add(args: var) i32 {
var sum = @as(i32, 0);
{
comptime var i: usize = 0;
@ -12,43 +12,42 @@ fn add(args: ...) i32 {
}
test "add arbitrary args" {
expect(add(@as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4)) == 10);
expect(add(@as(i32, 1234)) == 1234);
expect(add() == 0);
expect(add(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10);
expect(add(.{@as(i32, 1234)}) == 1234);
expect(add(.{}) == 0);
}
fn readFirstVarArg(args: ...) void {
fn readFirstVarArg(args: var) void {
const value = args[0];
}
test "send void arg to var args" {
readFirstVarArg({});
readFirstVarArg(.{{}});
}
test "pass args directly" {
expect(addSomeStuff(@as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4)) == 10);
expect(addSomeStuff(@as(i32, 1234)) == 1234);
expect(addSomeStuff() == 0);
expect(addSomeStuff(.{ @as(i32, 1), @as(i32, 2), @as(i32, 3), @as(i32, 4) }) == 10);
expect(addSomeStuff(.{@as(i32, 1234)}) == 1234);
expect(addSomeStuff(.{}) == 0);
}
fn addSomeStuff(args: ...) i32 {
fn addSomeStuff(args: var) i32 {
return add(args);
}
test "runtime parameter before var args" {
expect(extraFn(10) == 0);
expect(extraFn(10, false) == 1);
expect(extraFn(10, false, true) == 2);
expect(extraFn(10, .{}) == 0);
expect(extraFn(10, .{false}) == 1);
expect(extraFn(10, .{ false, true }) == 2);
// TODO issue #313
//comptime {
// expect(extraFn(10) == 0);
// expect(extraFn(10, false) == 1);
// expect(extraFn(10, false, true) == 2);
//}
comptime {
expect(extraFn(10, .{}) == 0);
expect(extraFn(10, .{false}) == 1);
expect(extraFn(10, .{ false, true }) == 2);
}
}
fn extraFn(extra: u32, args: ...) usize {
fn extraFn(extra: u32, args: var) usize {
if (args.len >= 1) {
expect(args[0] == false);
}
@ -58,27 +57,27 @@ fn extraFn(extra: u32, args: ...) usize {
return args.len;
}
const foos = [_]fn (...) bool{
const foos = [_]fn (var) bool{
foo1,
foo2,
};
fn foo1(args: ...) bool {
fn foo1(args: var) bool {
return true;
}
fn foo2(args: ...) bool {
fn foo2(args: var) bool {
return false;
}
test "array of var args functions" {
expect(foos[0]());
expect(!foos[1]());
expect(foos[0](.{}));
expect(!foos[1](.{}));
}
test "pass zero length array to var args param" {
doNothingWithFirstArg("");
doNothingWithFirstArg(.{""});
}
fn doNothingWithFirstArg(args: ...) void {
fn doNothingWithFirstArg(args: var) void {
const a = args[0];
}

View File

@ -1253,7 +1253,12 @@ pub const CompileErrorContext = struct {
}
};
pub fn create(self: *CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) *TestCase {
pub fn create(
self: *CompileErrorContext,
name: []const u8,
source: []const u8,
expected_lines: []const []const u8,
) *TestCase {
const tc = self.b.allocator.create(TestCase) catch unreachable;
tc.* = TestCase{
.name = name,
@ -1266,31 +1271,46 @@ pub const CompileErrorContext = struct {
};
tc.addSourceFile("tmp.zig", source);
comptime var arg_i = 0;
inline while (arg_i < expected_lines.len) : (arg_i += 1) {
var arg_i: usize = 0;
while (arg_i < expected_lines.len) : (arg_i += 1) {
tc.addExpectedError(expected_lines[arg_i]);
}
return tc;
}
pub fn addC(self: *CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) void {
pub fn addC(self: *CompileErrorContext, name: []const u8, source: []const u8, expected_lines: []const []const u8) void {
var tc = self.create(name, source, expected_lines);
tc.link_libc = true;
self.addCase(tc);
}
pub fn addExe(self: *CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) void {
pub fn addExe(
self: *CompileErrorContext,
name: []const u8,
source: []const u8,
expected_lines: []const []const u8,
) void {
var tc = self.create(name, source, expected_lines);
tc.is_exe = true;
self.addCase(tc);
}
pub fn add(self: *CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) void {
pub fn add(
self: *CompileErrorContext,
name: []const u8,
source: []const u8,
expected_lines: []const []const u8,
) void {
const tc = self.create(name, source, expected_lines);
self.addCase(tc);
}
pub fn addTest(self: *CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) void {
pub fn addTest(
self: *CompileErrorContext,
name: []const u8,
source: []const u8,
expected_lines: []const []const u8,
) void {
const tc = self.create(name, source, expected_lines);
tc.is_test = true;
self.addCase(tc);
@ -1549,7 +1569,14 @@ pub const TranslateCContext = struct {
warn("\n", .{});
}
pub fn create(self: *TranslateCContext, allow_warnings: bool, filename: []const u8, name: []const u8, source: []const u8, expected_lines: ...) *TestCase {
pub fn create(
self: *TranslateCContext,
allow_warnings: bool,
filename: []const u8,
name: []const u8,
source: []const u8,
expected_lines: []const []const u8,
) *TestCase {
const tc = self.b.allocator.create(TestCase) catch unreachable;
tc.* = TestCase{
.name = name,
@ -1560,24 +1587,39 @@ pub const TranslateCContext = struct {
};
tc.addSourceFile(filename, source);
comptime var arg_i = 0;
inline while (arg_i < expected_lines.len) : (arg_i += 1) {
var arg_i: usize = 0;
while (arg_i < expected_lines.len) : (arg_i += 1) {
tc.addExpectedLine(expected_lines[arg_i]);
}
return tc;
}
pub fn add(self: *TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
pub fn add(
self: *TranslateCContext,
name: []const u8,
source: []const u8,
expected_lines: []const []const u8,
) void {
const tc = self.create(false, "source.h", name, source, expected_lines);
self.addCase(tc);
}
pub fn addC(self: *TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
pub fn addC(
self: *TranslateCContext,
name: []const u8,
source: []const u8,
expected_lines: []const []const u8,
) void {
const tc = self.create(false, "source.c", name, source, expected_lines);
self.addCase(tc);
}
pub fn add_both(self: *TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
pub fn add_both(
self: *TranslateCContext,
name: []const u8,
source: []const u8,
expected_lines: []const []const u8,
) void {
for ([_]bool{ false, true }) |stage2| {
const tc = self.create(false, "source.h", name, source, expected_lines);
tc.stage2 = stage2;
@ -1585,7 +1627,12 @@ pub const TranslateCContext = struct {
}
}
pub fn addC_both(self: *TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
pub fn addC_both(
self: *TranslateCContext,
name: []const u8,
source: []const u8,
expected_lines: []const []const u8,
) void {
for ([_]bool{ false, true }) |stage2| {
const tc = self.create(false, "source.c", name, source, expected_lines);
tc.stage2 = stage2;
@ -1593,19 +1640,34 @@ pub const TranslateCContext = struct {
}
}
pub fn add_2(self: *TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
pub fn add_2(
self: *TranslateCContext,
name: []const u8,
source: []const u8,
expected_lines: []const []const u8,
) void {
const tc = self.create(false, "source.h", name, source, expected_lines);
tc.stage2 = true;
self.addCase(tc);
}
pub fn addC_2(self: *TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
pub fn addC_2(
self: *TranslateCContext,
name: []const u8,
source: []const u8,
expected_lines: []const []const u8,
) void {
const tc = self.create(false, "source.c", name, source, expected_lines);
tc.stage2 = true;
self.addCase(tc);
}
pub fn addAllowWarnings(self: *TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
pub fn addAllowWarnings(
self: *TranslateCContext,
name: []const u8,
source: []const u8,
expected_lines: []const []const u8,
) void {
const tc = self.create(true, "source.h", name, source, expected_lines);
self.addCase(tc);
}
@ -1723,7 +1785,13 @@ pub const GenHContext = struct {
warn("\n", .{});
}
pub fn create(self: *GenHContext, filename: []const u8, name: []const u8, source: []const u8, expected_lines: ...) *TestCase {
pub fn create(
self: *GenHContext,
filename: []const u8,
name: []const u8,
source: []const u8,
expected_lines: []const []const u8,
) *TestCase {
const tc = self.b.allocator.create(TestCase) catch unreachable;
tc.* = TestCase{
.name = name,
@ -1732,14 +1800,14 @@ pub const GenHContext = struct {
};
tc.addSourceFile(filename, source);
comptime var arg_i = 0;
inline while (arg_i < expected_lines.len) : (arg_i += 1) {
var arg_i: usize = 0;
while (arg_i < expected_lines.len) : (arg_i += 1) {
tc.addExpectedLine(expected_lines[arg_i]);
}
return tc;
}
pub fn add(self: *GenHContext, name: []const u8, source: []const u8, expected_lines: ...) void {
pub fn add(self: *GenHContext, name: []const u8, source: []const u8, expected_lines: []const []const u8) void {
const tc = self.create("test.zig", name, source, expected_lines);
self.addCase(tc);
}

File diff suppressed because it is too large Load Diff