Skip to content

Commit 7e11ef7

Browse files
committed
zig test no longer requires a separate test_runner.o file
See #298
1 parent 7b0542d commit 7e11ef7

File tree

10 files changed

+185
-132
lines changed

10 files changed

+185
-132
lines changed

doc/style.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ rules in written English are subject to naming conventions just like any other
2929
word. Even acronyms that are only 2 letters long are subject to these
3030
conventions.
3131

32+
These are general rules of thumb; if it makes sense to do something different,
33+
do what makes sense.
34+
3235
Examples:
3336

3437
```zig

src/all_types.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1095,6 +1095,7 @@ struct ImportTableEntry {
10951095
ScopeDecls *decls_scope;
10961096
AstNode *c_import_node;
10971097
bool any_imports_failed;
1098+
bool scanned;
10981099

10991100
ZigList<AstNode *> use_decls;
11001101
};
@@ -1398,6 +1399,7 @@ struct CodeGen {
13981399
PackageTableEntry *root_package;
13991400
PackageTableEntry *std_package;
14001401
PackageTableEntry *zigrt_package;
1402+
PackageTableEntry *test_runner_package;
14011403
Buf *root_out_name;
14021404
bool windows_subsystem_windows;
14031405
bool windows_subsystem_console;
@@ -1451,7 +1453,7 @@ struct CodeGen {
14511453
size_t clang_argv_len;
14521454
ZigList<const char *> lib_dirs;
14531455

1454-
uint32_t test_fn_count;
1456+
ZigList<FnTableEntry *> test_fns;
14551457
TypeTableEntry *test_fn_type;
14561458

14571459
bool each_lib_rpath;

src/analyze.cpp

Lines changed: 79 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1413,6 +1413,71 @@ static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {
14131413
zig_unreachable();
14141414
}
14151415

1416+
TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],
1417+
TypeTableEntry *field_types[], size_t field_count)
1418+
{
1419+
TypeTableEntry *struct_type = new_type_table_entry(TypeTableEntryIdStruct);
1420+
1421+
buf_init_from_str(&struct_type->name, type_name);
1422+
1423+
struct_type->data.structure.src_field_count = field_count;
1424+
struct_type->data.structure.gen_field_count = field_count;
1425+
struct_type->data.structure.zero_bits_known = true;
1426+
struct_type->data.structure.complete = true;
1427+
struct_type->data.structure.fields = allocate<TypeStructField>(field_count);
1428+
1429+
ZigLLVMDIType **di_element_types = allocate<ZigLLVMDIType*>(field_count);
1430+
LLVMTypeRef *element_types = allocate<LLVMTypeRef>(field_count);
1431+
for (size_t i = 0; i < field_count; i += 1) {
1432+
element_types[i] = field_types[i]->type_ref;
1433+
1434+
TypeStructField *field = &struct_type->data.structure.fields[i];
1435+
field->name = buf_create_from_str(field_names[i]);
1436+
field->type_entry = field_types[i];
1437+
field->src_index = i;
1438+
field->gen_index = i;
1439+
}
1440+
1441+
struct_type->type_ref = LLVMStructCreateNamed(LLVMGetGlobalContext(), type_name);
1442+
LLVMStructSetBody(struct_type->type_ref, element_types, field_count, false);
1443+
1444+
struct_type->di_type = ZigLLVMCreateReplaceableCompositeType(g->dbuilder,
1445+
ZigLLVMTag_DW_structure_type(), type_name,
1446+
ZigLLVMCompileUnitToScope(g->compile_unit), nullptr, 0);
1447+
1448+
for (size_t i = 0; i < field_count; i += 1) {
1449+
TypeStructField *type_struct_field = &struct_type->data.structure.fields[i];
1450+
TypeTableEntry *field_type = type_struct_field->type_entry;
1451+
uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, field_type->type_ref);
1452+
uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, field_type->type_ref);
1453+
uint64_t debug_offset_in_bits = 8*LLVMOffsetOfElement(g->target_data_ref, struct_type->type_ref, i);
1454+
di_element_types[i] = ZigLLVMCreateDebugMemberType(g->dbuilder,
1455+
ZigLLVMTypeToScope(struct_type->di_type), buf_ptr(type_struct_field->name),
1456+
nullptr, 0,
1457+
debug_size_in_bits,
1458+
debug_align_in_bits,
1459+
debug_offset_in_bits,
1460+
0, field_type->di_type);
1461+
1462+
assert(di_element_types[i]);
1463+
}
1464+
1465+
uint64_t debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, struct_type->type_ref);
1466+
uint64_t debug_align_in_bits = 8*LLVMABISizeOfType(g->target_data_ref, struct_type->type_ref);
1467+
ZigLLVMDIType *replacement_di_type = ZigLLVMCreateDebugStructType(g->dbuilder,
1468+
ZigLLVMCompileUnitToScope(g->compile_unit),
1469+
type_name, nullptr, 0,
1470+
debug_size_in_bits,
1471+
debug_align_in_bits,
1472+
0,
1473+
nullptr, di_element_types, field_count, 0, nullptr, "");
1474+
1475+
ZigLLVMReplaceTemporary(g->dbuilder, struct_type->di_type, replacement_di_type);
1476+
struct_type->di_type = replacement_di_type;
1477+
1478+
return struct_type;
1479+
}
1480+
14161481
static void resolve_struct_type(CodeGen *g, TypeTableEntry *struct_type) {
14171482
// if you change the logic of this function likely you must make a similar change in
14181483
// parseh.cpp
@@ -1823,7 +1888,7 @@ static void typecheck_panic_fn(CodeGen *g, FnTableEntry *panic_fn) {
18231888
}
18241889
}
18251890

1826-
static TypeTableEntry *get_test_fn_type(CodeGen *g) {
1891+
TypeTableEntry *get_test_fn_type(CodeGen *g) {
18271892
if (g->test_fn_type)
18281893
return g->test_fn_type;
18291894

@@ -1875,7 +1940,10 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
18751940
if (fn_def_node)
18761941
g->fn_defs.append(fn_table_entry);
18771942

1878-
if (g->have_pub_main && import == g->root_import && scope_is_root_decls(tld_fn->base.parent_scope)) {
1943+
if (g->have_pub_main && scope_is_root_decls(tld_fn->base.parent_scope) &&
1944+
((!g->is_test_build && import == g->root_import) ||
1945+
(g->is_test_build && import == g->test_runner_import)))
1946+
{
18791947
if (buf_eql_str(&fn_table_entry->symbol_name, "main")) {
18801948
g->main_fn = fn_table_entry;
18811949

@@ -1909,10 +1977,10 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
19091977
fn_table_entry->type_entry = get_test_fn_type(g);
19101978
fn_table_entry->body_node = source_node->data.test_decl.body;
19111979
fn_table_entry->is_test = true;
1912-
g->test_fn_count += 1;
19131980

19141981
g->fn_protos.append(fn_table_entry);
19151982
g->fn_defs.append(fn_table_entry);
1983+
g->test_fns.append(fn_table_entry);
19161984

19171985
} else {
19181986
zig_unreachable();
@@ -1926,7 +1994,7 @@ static void resolve_decl_comptime(CodeGen *g, TldCompTime *tld_comptime) {
19261994
}
19271995

19281996
static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
1929-
if (tld->visib_mod == VisibModExport || (tld->id == TldIdVar && g->is_test_build)) {
1997+
if (tld->visib_mod == VisibModExport) {
19301998
g->resolve_queue.append(tld);
19311999
}
19322000

@@ -2932,11 +3000,17 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a
29323000
return import_entry;
29333001
}
29343002

3003+
void scan_import(CodeGen *g, ImportTableEntry *import) {
3004+
if (!import->scanned) {
3005+
import->scanned = true;
3006+
scan_decls(g, import->decls_scope, import->root);
3007+
}
3008+
}
29353009

29363010
void semantic_analyze(CodeGen *g) {
29373011
for (; g->import_queue_index < g->import_queue.length; g->import_queue_index += 1) {
29383012
ImportTableEntry *import = g->import_queue.at(g->import_queue_index);
2939-
scan_decls(g, import->decls_scope, import->root);
3013+
scan_import(g, import);
29403014
}
29413015

29423016
for (; g->use_queue_index < g->use_queue.length; g->use_queue_index += 1) {

src/analyze.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ TypeTableEntry *get_smallest_unsigned_int_type(CodeGen *g, uint64_t x);
3333
TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type);
3434
TypeTableEntry *get_bound_fn_type(CodeGen *g, FnTableEntry *fn_entry);
3535
TypeTableEntry *get_opaque_type(CodeGen *g, Scope *scope, AstNode *source_node, const char *name);
36+
TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],
37+
TypeTableEntry *field_types[], size_t field_count);
38+
TypeTableEntry *get_test_fn_type(CodeGen *g);
3639
bool handle_is_ptr(TypeTableEntry *type_entry);
3740
void find_libc_include_path(CodeGen *g);
3841
void find_libc_lib_path(CodeGen *g);
@@ -60,6 +63,7 @@ ScopeDecls *get_container_scope(TypeTableEntry *type_entry);
6063
TypeEnumField *find_enum_type_field(TypeTableEntry *enum_type, Buf *name);
6164
bool is_container_ref(TypeTableEntry *type_entry);
6265
void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node);
66+
void scan_import(CodeGen *g, ImportTableEntry *import);
6367
void preview_use_decl(CodeGen *g, AstNode *node);
6468
void resolve_use_decl(CodeGen *g, AstNode *node);
6569
FnTableEntry *scope_fn_entry(Scope *scope);

0 commit comments

Comments
 (0)