test runner prints test names

This commit is contained in:
Andrew Kelley 2016-02-03 18:38:09 -07:00
parent 11a0644365
commit 39223c1847
2 changed files with 51 additions and 40 deletions

View File

@ -2704,6 +2704,32 @@ static bool skip_fn_codegen(CodeGen *g, FnTableEntry *fn_entry) {
return fn_entry->ref_count == 0; return fn_entry->ref_count == 0;
} }
static LLVMValueRef gen_test_fn_val(CodeGen *g, FnTableEntry *fn_entry) {
// Must match TestFn struct from test_runner.zig
Buf *fn_name = &fn_entry->symbol_name;
LLVMValueRef str_init = LLVMConstString(buf_ptr(fn_name), buf_len(fn_name), true);
LLVMValueRef str_global_val = LLVMAddGlobal(g->module, LLVMTypeOf(str_init), "");
LLVMSetInitializer(str_global_val, str_init);
LLVMSetLinkage(str_global_val, LLVMPrivateLinkage);
LLVMSetGlobalConstant(str_global_val, true);
LLVMSetUnnamedAddr(str_global_val, true);
LLVMValueRef len_val = LLVMConstInt(g->builtin_types.entry_isize->type_ref, buf_len(fn_name), false);
LLVMTypeRef ptr_type = LLVMPointerType(g->builtin_types.entry_u8->type_ref, 0);
LLVMValueRef name_fields[] = {
LLVMConstBitCast(str_global_val, ptr_type),
len_val,
};
LLVMValueRef name_val = LLVMConstStruct(name_fields, 2, false);
LLVMValueRef fields[] = {
name_val,
fn_entry->fn_value,
};
return LLVMConstStruct(fields, 2, false);
}
static void do_code_gen(CodeGen *g) { static void do_code_gen(CodeGen *g) {
assert(!g->errors.length); assert(!g->errors.length);
@ -2817,7 +2843,7 @@ static void do_code_gen(CodeGen *g) {
} }
if (fn_table_entry->is_test) { if (fn_table_entry->is_test) {
test_fn_vals[next_test_index] = fn_table_entry->fn_value; test_fn_vals[next_test_index] = gen_test_fn_val(g, fn_table_entry);
next_test_index += 1; next_test_index += 1;
} }
} }
@ -2827,27 +2853,28 @@ static void do_code_gen(CodeGen *g) {
assert(g->test_fn_count > 0); assert(g->test_fn_count > 0);
assert(next_test_index == g->test_fn_count); assert(next_test_index == g->test_fn_count);
{ LLVMValueRef test_fn_array_init = LLVMConstArray(LLVMTypeOf(test_fn_vals[0]),
LLVMValueRef test_fn_array_val = LLVMConstArray(LLVMTypeOf(test_fn_vals[0]), test_fn_vals, g->test_fn_count);
test_fn_vals, g->test_fn_count); LLVMValueRef test_fn_array_val = LLVMAddGlobal(g->module,
LLVMValueRef global_value = LLVMAddGlobal(g->module, LLVMTypeOf(test_fn_array_init), "");
LLVMTypeOf(test_fn_array_val), "zig_test_fn_list"); LLVMSetInitializer(test_fn_array_val, test_fn_array_init);
LLVMSetInitializer(global_value, test_fn_array_val); LLVMSetLinkage(test_fn_array_val, LLVMInternalLinkage);
LLVMSetLinkage(global_value, LLVMExternalLinkage); LLVMSetGlobalConstant(test_fn_array_val, true);
LLVMSetGlobalConstant(global_value, true); LLVMSetUnnamedAddr(test_fn_array_val, true);
LLVMSetUnnamedAddr(global_value, true);
}
{ LLVMValueRef len_val = LLVMConstInt(g->builtin_types.entry_isize->type_ref, g->test_fn_count, false);
LLVMValueRef test_fn_count_val = LLVMConstInt(g->builtin_types.entry_isize->type_ref, LLVMTypeRef ptr_type = LLVMPointerType(LLVMTypeOf(test_fn_vals[0]), 0);
g->test_fn_count, false); LLVMValueRef fields[] = {
LLVMValueRef global_value = LLVMAddGlobal(g->module, LLVMConstBitCast(test_fn_array_val, ptr_type),
LLVMTypeOf(test_fn_count_val), "zig_test_fn_count"); len_val,
LLVMSetInitializer(global_value, test_fn_count_val); };
LLVMSetLinkage(global_value, LLVMExternalLinkage); LLVMValueRef test_fn_slice_init = LLVMConstStruct(fields, 2, false);
LLVMSetGlobalConstant(global_value, true); LLVMValueRef test_fn_slice_val = LLVMAddGlobal(g->module,
LLVMSetUnnamedAddr(global_value, true); LLVMTypeOf(test_fn_slice_init), "zig_test_fn_list");
} LLVMSetInitializer(test_fn_slice_val, test_fn_slice_init);
LLVMSetLinkage(test_fn_slice_val, LLVMExternalLinkage);
LLVMSetGlobalConstant(test_fn_slice_val, true);
LLVMSetUnnamedAddr(test_fn_slice_val, true);
} }
// Generate function definitions. // Generate function definitions.

View File

@ -1,45 +1,29 @@
import "std.zig"; import "std.zig";
/*
struct TestFn { struct TestFn {
name: []u8, name: []u8,
func: extern fn(), func: extern fn(),
} }
extern var test_fn_list: []TestFn; extern var zig_test_fn_list: []TestFn;
*/
extern var zig_test_fn_count: isize;
// TODO make this a slice of structs
extern var zig_test_fn_list: [99999999]extern fn();
pub fn main(args: [][]u8) -> %void { pub fn main(args: [][]u8) -> %void {
var i : isize = 0; for (test_fn, zig_test_fn_list, i) {
while (i < zig_test_fn_count) {
%%stderr.print_str("Test "); %%stderr.print_str("Test ");
// TODO get rid of the isize // TODO get rid of the isize
%%stderr.print_i64(i + isize(1)); %%stderr.print_i64(i + isize(1));
%%stderr.print_str("/"); %%stderr.print_str("/");
%%stderr.print_i64(zig_test_fn_count); %%stderr.print_i64(zig_test_fn_list.len);
%%stderr.print_str(" "); %%stderr.print_str(" ");
/*
%%stderr.print_str(test_fn.name); %%stderr.print_str(test_fn.name);
*/
%%stderr.print_str("..."); %%stderr.print_str("...");
/*
// TODO support calling function pointers as fields directly // TODO support calling function pointers as fields directly
const fn_ptr = test_fn.func; const fn_ptr = test_fn.func;
fn_ptr(); fn_ptr();
*/
const test_fn = zig_test_fn_list[i];
test_fn();
%%stderr.print_str("OK\n"); %%stderr.print_str("OK\n");
%%stderr.flush(); %%stderr.flush();
i += 1;
} }
} }