@@ -1413,6 +1413,71 @@ static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {
1413
1413
zig_unreachable ();
1414
1414
}
1415
1415
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
+
1416
1481
static void resolve_struct_type (CodeGen *g, TypeTableEntry *struct_type) {
1417
1482
// if you change the logic of this function likely you must make a similar change in
1418
1483
// parseh.cpp
@@ -1823,7 +1888,7 @@ static void typecheck_panic_fn(CodeGen *g, FnTableEntry *panic_fn) {
1823
1888
}
1824
1889
}
1825
1890
1826
- static TypeTableEntry *get_test_fn_type (CodeGen *g) {
1891
+ TypeTableEntry *get_test_fn_type (CodeGen *g) {
1827
1892
if (g->test_fn_type )
1828
1893
return g->test_fn_type ;
1829
1894
@@ -1875,7 +1940,10 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
1875
1940
if (fn_def_node)
1876
1941
g->fn_defs .append (fn_table_entry);
1877
1942
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
+ {
1879
1947
if (buf_eql_str (&fn_table_entry->symbol_name , " main" )) {
1880
1948
g->main_fn = fn_table_entry;
1881
1949
@@ -1909,10 +1977,10 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
1909
1977
fn_table_entry->type_entry = get_test_fn_type (g);
1910
1978
fn_table_entry->body_node = source_node->data .test_decl .body ;
1911
1979
fn_table_entry->is_test = true ;
1912
- g->test_fn_count += 1 ;
1913
1980
1914
1981
g->fn_protos .append (fn_table_entry);
1915
1982
g->fn_defs .append (fn_table_entry);
1983
+ g->test_fns .append (fn_table_entry);
1916
1984
1917
1985
} else {
1918
1986
zig_unreachable ();
@@ -1926,7 +1994,7 @@ static void resolve_decl_comptime(CodeGen *g, TldCompTime *tld_comptime) {
1926
1994
}
1927
1995
1928
1996
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) {
1930
1998
g->resolve_queue .append (tld);
1931
1999
}
1932
2000
@@ -2932,11 +3000,17 @@ ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *a
2932
3000
return import_entry;
2933
3001
}
2934
3002
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
+ }
2935
3009
2936
3010
void semantic_analyze (CodeGen *g) {
2937
3011
for (; g->import_queue_index < g->import_queue .length ; g->import_queue_index += 1 ) {
2938
3012
ImportTableEntry *import = g->import_queue .at (g->import_queue_index );
2939
- scan_decls (g, import-> decls_scope , import-> root );
3013
+ scan_import (g, import);
2940
3014
}
2941
3015
2942
3016
for (; g->use_queue_index < g->use_queue .length ; g->use_queue_index += 1 ) {
0 commit comments