Refactoring -> ensure built in aliases have a valid unit.

This commit is contained in:
Christoffer Lerno
2024-08-05 21:43:55 +02:00
parent 8aa3461bf6
commit 14358417c8
15 changed files with 92 additions and 84 deletions

View File

@@ -1,6 +1,7 @@
module std::core::string;
import std::ascii;
distinct String @if(!$defined(String)) = inline char[];
distinct ZString = inline char*;
distinct WString = inline Char16*;
def Char32 = uint;

View File

@@ -1068,6 +1068,16 @@ void compile()
global_context.main = NULL;
global_context.string_type = NULL;
asm_target.initialized = false;
// Create the core module if needed.
Path *core_path = MALLOCS(Path);
core_path->module = kw_std__core;
core_path->span = INVALID_SPAN;
core_path->len = strlen(kw_std__core);
global_context.core_module = compiler_find_or_create_module(core_path, NULL);
CompilationUnit *unit = CALLOCS(CompilationUnit);
unit->file = source_file_generate("core_internal.c3");
unit->module = global_context.core_module;
global_context.core_unit = unit;
target_setup(&active_target);
resolve_libraries(&active_target);
global_context.sources = active_target.sources;

View File

@@ -1732,7 +1732,6 @@ typedef struct InliningSpan_
struct SemaContext_
{
Module *core_module;
// Evaluated in this.
CompilationUnit *unit;
// Compiled in this unit.
@@ -1778,6 +1777,7 @@ typedef struct
{
HTable modules;
Module *core_module;
CompilationUnit *core_unit;
Module **module_list;
Module **generic_module_list;
Type **type;
@@ -2250,7 +2250,6 @@ static inline Decl *decl_raw(Decl *decl);
static inline DeclKind decl_from_token(TokenType type);
static inline bool decl_is_var_local(Decl *decl);
bool decl_is_ct_var(Decl *decl);
INLINE Module* decl_module(Decl *decl);
Decl *decl_find_enum_constant(Decl *decl, const char *name);
bool decl_needs_prefix(Decl *decl);
AlignSize decl_find_member_offset(Decl *decl, Decl *member);
@@ -2420,6 +2419,7 @@ bool sema_type_error_on_binop(SemaContext *context, Expr *expr);
File *source_file_by_id(FileId file);
File *source_file_load(const char *filename, bool *already_loaded, const char **error);
File *source_file_generate(const char *filename);
File *source_file_text_load(const char *filename, const char *content);
File *compile_and_invoke(const char *file, const char *args);
@@ -3077,7 +3077,7 @@ static inline Type *type_flatten_no_export(Type *type)
switch (type->type_kind)
{
case TYPE_TYPEDEF:
if (!type->decl || type->decl->is_export) return type;
if (type->decl->is_export) return type;
type = type->canonical;
break;
case TYPE_DISTINCT:
@@ -3782,10 +3782,6 @@ INLINE bool decl_var_kind_is_ct(VarDeclKind kind)
return kind >= VARDECL_FIRST_CT && kind <= VARDECL_LAST_CT;
}
INLINE Module *decl_module(Decl *decl)
{
return decl->unit ? decl->unit->module : global_context.core_module;
}
static inline bool decl_is_var_local(Decl *decl)
{

View File

@@ -110,7 +110,7 @@ void unit_register_external_symbol(SemaContext *context, Decl *decl)
{
if (decl->is_external_visible) return;
Module *active_module = context->current_macro ? context->original_module : context->compilation_unit->module;
if (decl_module(decl) == active_module) return;
if (decl->unit->module == active_module) return;
decl->is_external_visible = true;
}

View File

@@ -187,15 +187,10 @@ static void header_print_type(HeaderContext *c, Type *type)
header_print_type(c, type->decl->distinct->type);
return;
case TYPE_TYPEDEF:
if (!type->decl)
{
if (type == type_usz) { PRINTF("size_t"); return; }
if (type == type_isz) { PRINTF("ptrdiff_t"); return; }
if (type == type_iptr) { PRINTF("intptr_t"); return; }
if (type == type_uptr) { PRINTF("uintptr_t"); return; }
header_print_type(c, type->canonical);
return;
}
if (type == type_usz) { PRINTF("size_t"); return; }
if (type == type_isz) { PRINTF("ptrdiff_t"); return; }
if (type == type_iptr) { PRINTF("intptr_t"); return; }
if (type == type_uptr) { PRINTF("uintptr_t"); return; }
if (type->decl->is_export)
{
PRINTF("%s", decl_get_extname(type->decl));
@@ -534,11 +529,6 @@ RETRY:
}
case TYPE_TYPEDEF:
{
if (!type->decl)
{
type = type->canonical;
goto RETRY;
}
if (!header_try_gen_both(c, type)) return;
Type *underlying_type = type->canonical;
header_gen_maybe_generate_type(c, underlying_type, is_pointer);

View File

@@ -1031,7 +1031,7 @@ void llvm_add_global_decl(GenContext *c, Decl *decl)
{
assert(decl->var.kind == VARDECL_GLOBAL || decl->var.kind == VARDECL_CONST);
bool same_module = decl_module(decl) == c->code_module;
bool same_module = decl->unit->module == c->code_module;
LLVMTypeRef type = llvm_get_type(c, decl->type);
if (same_module)
{
@@ -1165,7 +1165,7 @@ void llvm_append_function_attributes(GenContext *c, Decl *decl)
}
if (decl->is_export && arch_is_wasm(platform_target.arch))
{
if (c->code_module == decl_module(decl))
if (c->code_module == decl->unit->module)
{
scratch_buffer_set_extern_decl_name(decl, true);
llvm_attribute_add_string(c, function, "wasm-export-name", scratch_buffer_to_string(), -1);
@@ -1236,7 +1236,7 @@ LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl)
}
if (decl_is_local(decl))
{
assert(decl_module(decl) == c->code_module);
assert(decl->unit->module == c->code_module);
llvm_set_internal_linkage(backend_ref);
}
return backend_ref;

View File

@@ -482,10 +482,10 @@ static LLVMMetadataRef llvm_debug_typedef_type(GenContext *c, Type *type)
Decl *decl = type->decl;
// Is this a primitive typedef? If so, we create it without reference.
if (!decl)
if (decl->unit == global_context.core_unit)
{
return LLVMDIBuilderCreateTypedef(c->debug.builder,
llvm_get_debug_type(c, type->canonical),
llvm_get_debug_type(c, type_lowering(type)),
type->name, strlen(type->name),
NULL, 0, NULL, 0);
}

View File

@@ -489,7 +489,7 @@ static LLVMValueRef llvm_get_introspection_for_builtin_type(GenContext *c, Type
static LLVMValueRef llvm_get_introspection_for_enum(GenContext *c, Type *type)
{
Decl *decl = type->decl;
bool is_external = decl_module(decl) != c->code_module;
bool is_external = decl->unit->module != c->code_module;
bool is_dynamic = decl->is_dynamic;
Decl **enum_vals = decl->enums.values;

View File

@@ -1987,7 +1987,7 @@ static inline bool unit_add_method(SemaContext *context, Type *parent_type, Decl
vec_add(parent->methods, method);
break;
case VISIBLE_PRIVATE:
if (decl_module(parent) == unit->module && parent->visibility >= VISIBLE_PRIVATE)
if (parent->unit->module == unit->module && parent->visibility >= VISIBLE_PRIVATE)
{
vec_add(parent->methods, method);
break;
@@ -4114,7 +4114,7 @@ Decl *sema_analyse_parameterized_identifier(SemaContext *c, Path *decl_path, con
if (!unit_resolve_parameterized_symbol(c, &name_resolve)) return poisoned_decl;
Decl *alias = name_resolve.found;
assert(alias);
Module *module = decl_module(alias);
Module *module = alias->unit->module;
unsigned parameter_count = vec_size(module->parameters);
assert(parameter_count > 0);
if (parameter_count != vec_size(params))
@@ -4237,8 +4237,6 @@ RETRY:
case TYPE_MEMBER:
return true;
case TYPE_FUNC_RAW:
if (!type->decl) return true;
FALLTHROUGH;
case TYPE_ENUM:
case TYPE_STRUCT:
case TYPE_UNION:

View File

@@ -1004,7 +1004,7 @@ static inline bool sema_expr_analyse_identifier(SemaContext *context, Type *to,
if (decl_needs_prefix(decl))
{
if (!sema_analyse_decl(context, decl)) return false;
if (decl_module(decl) != context->unit->module && !expr->identifier_expr.path)
if (decl->unit->module != context->unit->module && !expr->identifier_expr.path)
{
const char *message;
switch (decl->decl_kind)
@@ -1410,7 +1410,7 @@ INLINE bool sema_call_expand_arguments(SemaContext *context, CalledDecl *callee,
bool success;
SCOPE_START
new_context->original_inline_line = context->original_inline_line ? context->original_inline_line : call->span.row;
new_context->original_module = context->original_module ? context->original_module : context->core_module;
new_context->original_module = context->original_module;
success = sema_analyse_expr_rhs(new_context, param->type, arg, true, no_match_ref, false);
SCOPE_END;
sema_context_destroy(&default_context);
@@ -3333,7 +3333,7 @@ static inline bool sema_expr_analyse_type_access(SemaContext *context, Expr *exp
{
RETURN_SEMA_ERROR(expr, "'%s' is an ambiguous name and so cannot be resolved, "
"it may refer to method defined in '%s' or one in '%s'",
name, decl_module(member)->name->module, decl_module(ambiguous)->name->module);
name, member->unit->module->name->module, ambiguous->unit->module->name->module);
}
}
if (!member)
@@ -4537,7 +4537,7 @@ CHECK_DEEPER:
{
RETURN_SEMA_ERROR(expr, "'%s' is an ambiguous name and so cannot be resolved, "
"it may refer to method defined in '%s' or one in '%s'",
kw, decl_module(method)->name->module, decl_module(ambiguous)->name->module);
kw, method->unit->module->name->module, ambiguous->unit->module->name->module);
}
if (!method)
{
@@ -4580,9 +4580,8 @@ CHECK_DEEPER:
}
if (ambiguous)
{
SEMA_ERROR(expr, "'%s' is an ambiguous name and so cannot be resolved, it may refer to method defined in '%s' or one in '%s'",
kw, decl_module(member)->name->module, decl_module(ambiguous)->name->module);
return false;
RETURN_SEMA_ERROR(expr, "'%s' is an ambiguous name and so cannot be resolved, it may refer to method defined in '%s' or one in '%s'",
kw, member->unit->module->name->module, ambiguous->unit->module->name->module);
}
}
@@ -7988,7 +7987,7 @@ static inline bool sema_expr_analyse_decl_element(SemaContext *context, Designat
if (ambiguous)
{
sema_error_at(context, loc, "'%s' is an ambiguous name and so cannot be resolved, it may refer to method defined in '%s' or one in '%s'",
kw, decl_module(member)->name->module, decl_module(ambiguous)->name->module);
kw, member->unit->module->name->module, ambiguous->unit->module->name->module);
return false;
}
if (is_missing)
@@ -8170,7 +8169,7 @@ RETURN_CT:
return true;
}
scratch_buffer_clear();
scratch_buffer_append(decl_module(decl)->name->module);
scratch_buffer_append(decl->unit->module->name->module);
scratch_buffer_append("::");
scratch_buffer_append(decl->name);
expr_rewrite_to_string(expr, scratch_buffer_copy());

View File

@@ -341,7 +341,7 @@ static bool sema_find_decl_in_global(SemaContext *context, DeclTable *table, Mod
// There might just be a single match.
if (decls->decl_kind != DECL_DECLARRAY)
{
if (path && !matches_subpath(decl_module(decls)->name, path)) return true;
if (path && !matches_subpath(decls->unit->module->name, path)) return true;
if (!decl_is_visible(context->unit, decls))
{
name_resolve->maybe_decl = decls;
@@ -359,7 +359,7 @@ static bool sema_find_decl_in_global(SemaContext *context, DeclTable *table, Mod
Decl *decl = NULL;
FOREACH(Decl *, candidate, decls->decl_list)
{
if (path && !matches_subpath(decl_module(candidate)->name, path)) continue;
if (path && !matches_subpath(candidate->unit->module->name, path)) continue;
if (!decl_is_visible(context->unit, candidate))
{
maybe_decl = candidate;
@@ -580,7 +580,7 @@ static void sema_report_error_on_decl(SemaContext *context, NameResolve *name_re
if (!found && name_resolve->maybe_decl)
{
const char *maybe_name = decl_to_name(name_resolve->maybe_decl);
const char *module_name = decl_module(name_resolve->maybe_decl)->name->module;
const char *module_name = name_resolve->maybe_decl->unit->module->name->module;
if (path_name)
{
sema_error_at(context, span, "Did you mean the %s '%s::%s' in module %s? If so please add 'import %s'.",
@@ -598,8 +598,8 @@ static void sema_report_error_on_decl(SemaContext *context, NameResolve *name_re
{
assert(found);
const char *symbol_type = decl_to_name(found);
const char *found_path = decl_module(found)->name->module;
const char *other_path = decl_module(name_resolve->ambiguous_other_decl)->name->module;
const char *found_path = found->unit->module->name->module;
const char *other_path = name_resolve->ambiguous_other_decl->unit->module->name->module;
if (path_name)
{
sema_error_at(context, span,
@@ -1028,7 +1028,7 @@ BoolErr sema_symbol_is_defined_in_scope(SemaContext *c, const char *symbol)
Decl *found = resolve.found;
if (!found) return BOOL_FALSE;
// Defined in the same module => defined
if (decl_module(found) == c->unit->module) return BOOL_TRUE;
if (found->unit->module == c->unit->module) return BOOL_TRUE;
// Not a variable or function => defined
if (found->decl_kind != DECL_VAR && found->decl_kind != DECL_FUNC) return BOOL_TRUE;
// Otherwise defined only if autoimport.
@@ -1114,8 +1114,7 @@ bool sema_add_local(SemaContext *context, Decl *decl)
if (is_var && decl->var.shadow) goto ADD_VAR;
Decl *other = sema_find_local(context, decl->name);
assert(!other || decl_module(other));
if (other && (decl_module(other) == current_unit->module || other->is_autoimport))
if (other && (other->unit->module == current_unit->module || other->is_autoimport))
{
sema_shadow_error(context, decl, other);
decl_poison(decl);

View File

@@ -414,12 +414,6 @@ void sema_analysis_run(void)
error_exit("No modules to compile.");
}
// Create the core module if needed.
Path *core_path = MALLOCS(Path);
core_path->module = kw_std__core;
core_path->span = INVALID_SPAN;
core_path->len = strlen(kw_std__core);
global_context.core_module = compiler_find_or_create_module(core_path, NULL);
// We parse the generic modules, just by storing the decls.
FOREACH(Module *, module, global_context.generic_module_list)

View File

@@ -36,6 +36,17 @@ File *source_file_text_load(const char *filename, const char *content)
}
File *source_file_generate(const char *filename)
{
File *file = CALLOCS(File);
file->file_id = vec_size(global_context.loaded_sources);
file->full_path = "<generated>";
file->contents = "";
file->content_len = 0;
vec_add(global_context.loaded_sources, file);
return file;
}
File *source_file_load(const char *filename, bool *already_loaded, const char **error)
{
if (already_loaded) *already_loaded = false;

View File

@@ -226,10 +226,11 @@ const char *type_to_error_string(Type *type)
case TYPE_INTERFACE:
{
Decl *decl = type->decl;
if (!decl || !decl_module(decl)->generic_suffix) return type->name;
const char *suffix = decl->unit->module->generic_suffix;
if (!suffix) return type->name;
scratch_buffer_clear();
scratch_buffer_append(decl->name);
scratch_buffer_append(decl_module(decl)->generic_suffix);
scratch_buffer_append(suffix);
return scratch_buffer_copy();
}
case TYPE_FUNC_PTR:
@@ -582,7 +583,7 @@ void type_mangle_introspect_name_to_buffer(Type *type)
type = type->function.prototype->raw_type;
if (type->function.decl)
{
scratch_buffer_append_module(decl_module(type->function.decl), true);
scratch_buffer_append_module(type->function.decl->unit->module, true);
scratch_buffer_append("$");
scratch_buffer_append(type->name);
}
@@ -1046,7 +1047,7 @@ bool type_is_user_defined(Type *type)
case TYPE_BITSTRUCT:
case TYPE_TYPEDEF:
case TYPE_INTERFACE:
return type->decl != NULL;
return true;
default:
return false;
}
@@ -1165,7 +1166,7 @@ bool type_is_valid_for_array(Type *type)
switch (type->type_kind)
{
case TYPE_DISTINCT:
assert(!type->decl || type->decl->resolve_status == RESOLVE_DONE);
assert(type->decl->resolve_status == RESOLVE_DONE);
type = type->decl->distinct->type;
goto RETRY;
case TYPE_ANY:
@@ -1188,7 +1189,7 @@ bool type_is_valid_for_array(Type *type)
case TYPE_VECTOR:
return true;
case TYPE_TYPEDEF:
assert(!type->decl || type->decl->resolve_status == RESOLVE_DONE);
assert(type->decl->resolve_status == RESOLVE_DONE);
type = type->canonical;
goto RETRY;
case TYPE_FLEXIBLE_ARRAY:
@@ -1260,11 +1261,18 @@ static void type_init(const char *name, Type *location, TypeKind kind, unsigned
static void type_create_alias(const char *name, Type *location, Type *canonical)
{
Decl *decl = decl_new(DECL_TYPEDEF, name, INVALID_SPAN);
decl->resolve_status = RESOLVE_DONE;
decl->typedef_decl.type_info = type_info_new_base(canonical, INVALID_SPAN);
decl->unit = global_context.core_unit;
decl->is_export = true;
*location = (Type) {
.decl = decl,
.type_kind = TYPE_TYPEDEF,
.name = name,
.canonical = canonical
};
decl->type = location;
global_context_add_type(location);
}
@@ -1338,6 +1346,7 @@ void type_setup(PlatformTarget *target)
type_chars = type_get_slice(type_char);
type_wildcard_optional = type_get_optional(type_wildcard);
Decl *string_decl = decl_new_with_type(symtab_preset("String", TOKEN_TYPE_IDENT), INVALID_SPAN, DECL_DISTINCT);
string_decl->unit = global_context.core_unit;
string_decl->extname = string_decl->name;
string_decl->is_substruct = true;
string_decl->distinct = type_info_new_base(type_chars, INVALID_SPAN);
@@ -2097,7 +2106,7 @@ Module *type_base_module(Type *type)
type = type->pointer;
FALLTHROUGH;
case TYPE_FUNC_RAW:
return type->function.decl ? decl_module(type->function.decl) : NULL;
return type->function.decl ? type->function.decl->unit->module : NULL;
case TYPE_ENUM:
case TYPE_STRUCT:
case TYPE_UNION:

View File

@@ -139,8 +139,8 @@ entry:
%a = alloca i32, align 4
%a.f = alloca i64, align 8
store i32 %0, ptr %x, align 4
!21
!23
!20
!22
%1 = load i32, ptr %x, align 4, !dbg !24
store i32 %1, ptr %a, align 4, !dbg !24
store i64 0, ptr %a.f, align 8, !dbg !24
@@ -165,8 +165,8 @@ entry:
store ptr %0, ptr %args, align 8
%ptradd = getelementptr inbounds i8, ptr %args, i64 8
store i64 %1, ptr %ptradd, align 8
!47
!53
!46
!48
%2 = call { i32, ptr } @attach.to_scope()
store { i32, ptr } %2, ptr %result, align 8
%lo = load i32, ptr %result, align 8, !dbg !55
@@ -191,13 +191,13 @@ entry:
store i32 %0, ptr %attach, align 8
%ptradd = getelementptr inbounds i8, ptr %attach, i64 8
store ptr %1, ptr %ptradd, align 8
!67
!66
store i64 %2, ptr %flags, align 8
!69
!68
store ptr %3, ptr %name, align 8
%ptradd1 = getelementptr inbounds i8, ptr %name, i64 8
store i64 %4, ptr %ptradd1, align 8
!71
!70
%5 = call ptr @std.core.mem.calloc(i64 8)
ret ptr %5, !dbg !72
}
@@ -219,14 +219,14 @@ entry:
%error_var5 = alloca i64, align 8
%error_var11 = alloca i64, align 8
store <4 x float> %0, ptr %color, align 16
!85
!84
%1 = load <4 x float>, ptr %color, align 16
store <4 x float> %1, ptr %x, align 16
%2 = call ptr @std.io.stdout(), !dbg !86
store ptr %2, ptr %out, align 8
%3 = load <4 x float>, ptr %x, align 16
store <4 x float> %3, ptr %x1, align 16
!92
!90
%4 = load ptr, ptr %out, align 8
store ptr %4, ptr %out2, align 8
%5 = load <4 x float>, ptr %x1, align 16
@@ -299,17 +299,17 @@ entry:
%scratch1 = alloca ptr, align 8
%asdf = alloca ptr, align 8
store %"Arena*[]" zeroinitializer, ptr %conflicts, align 8
!117
!107
%lo = load ptr, ptr %conflicts, align 8, !dbg !119
%ptradd = getelementptr inbounds i8, ptr %conflicts, i64 8, !dbg !119
%hi = load i64, ptr %ptradd, align 8, !dbg !119
%0 = call { ptr, i64 } @arena_scratch_begin(ptr %lo, i64 %hi), !dbg !120
store { ptr, i64 } %0, ptr %result, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %scratch, ptr align 8 %result, i32 16, i1 false)
!122
!121
%1 = load ptr, ptr %scratch, align 8, !dbg !123
store ptr %1, ptr %scratch1, align 8, !dbg !123
!127
!125
store ptr null, ptr %asdf, align 8, !dbg !127
%2 = load ptr, ptr %asdf, align 8, !dbg !128
%lo2 = load ptr, ptr %scratch, align 8, !dbg !129
@@ -352,19 +352,19 @@ entry:
%len18 = alloca i64, align 8
store ptr null, ptr %.cachedtype, align 8
store i32 %0, ptr %.anon, align 4
!137
!136
store ptr %1, ptr %.anon1, align 8
!137
!138
%2 = load i32, ptr %.anon, align 4
store i32 %2, ptr %argc, align 4
%3 = load ptr, ptr %.anon1, align 8
store ptr %3, ptr %argv, align 8
!142
!139
%4 = load i32, ptr %argc, align 4
store i32 %4, ptr %argc2, align 4
%5 = load ptr, ptr %argv, align 8
store ptr %5, ptr %argv3, align 8
!145
!143
%6 = load i32, ptr %argc2, align 4, !dbg !147
%sext = sext i32 %6 to i64, !dbg !147
store i64 %sext, ptr %elements, align 8
@@ -444,7 +444,7 @@ panic_block: ; preds = %assign_optional
unreachable, !dbg !151
noerr_block: ; preds = %expr_block.exit
store %"char[][]" %28, ptr %list5, align 8, !dbg !151
!167
!165
store i32 0, ptr %i, align 4, !dbg !168
br label %loop.cond, !dbg !168
loop.cond: ; preds = %loop.exit, %noerr_block
@@ -453,14 +453,14 @@ loop.cond: ; preds = %loop.exit, %noerr_b
%lt = icmp slt i32 %32, %33, !dbg !169
br i1 %lt, label %loop.body, label %loop.exit26, !dbg !169
loop.body: ; preds = %loop.cond
!173
!171
%34 = load ptr, ptr %argv3, align 8, !dbg !174
%35 = load i32, ptr %i, align 4, !dbg !175
%sext14 = sext i32 %35 to i64, !dbg !175
%ptroffset = getelementptr inbounds [8 x i8], ptr %34, i64 %sext14, !dbg !175
%36 = load ptr, ptr %ptroffset, align 8, !dbg !175
store ptr %36, ptr %arg, align 8, !dbg !175
!177
call void @llvm.dbg.declare(metadata ptr %len, metadata !176, metadata !DIExpression()), !dbg !177
store i64 0, ptr %len, align 8, !dbg !178
%37 = load ptr, ptr %list5, align 8, !dbg !179
%38 = load i32, ptr %i, align 4, !dbg !180
@@ -469,7 +469,7 @@ loop.body: ; preds = %loop.cond
%39 = load ptr, ptr %arg, align 8, !dbg !181
%40 = load ptr, ptr %arg, align 8
store ptr %40, ptr %ptr, align 8
!184
call void @llvm.dbg.declare(metadata ptr %len18, metadata !182, metadata !DIExpression()), !dbg !184
store i64 0, ptr %len18, align 8, !dbg !186
br label %loop.cond19, !dbg !187
loop.cond19: ; preds = %loop.body21, %loop.body
@@ -503,7 +503,7 @@ loop.exit26: ; preds = %loop.cond
%49 = call i32 @test.main(ptr %lo, i64 %hi), !dbg !196
store i32 %49, ptr %blockret, align 4, !dbg !196
%50 = load ptr, ptr %list, align 8, !dbg !197
call void @std.core.mem.free(ptr %50)
call void @std.core.mem.free(ptr %50) #4, !dbg !199
br label %expr_block.exit28, !dbg !199
expr_block.exit28: ; preds = %loop.exit26
%51 = load i32, ptr %blockret, align 4, !dbg !199
@@ -580,7 +580,7 @@ no_match: ; preds = %compare
!34 = !{!35, !45}
!35 = !DIDerivedType(tag: DW_TAG_member, name: "ptr", scope: !33, baseType: !36, size: 64, align: 64)
!36 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "String*", baseType: !37, size: 64, align: 64, dwarfAddressSpace: 0)
!37 = !DIDerivedType(tag: DW_TAG_typedef, name: "String", scope: !5, file: !5, line: 1, baseType: !38, align: 8)
!37 = !DIDerivedType(tag: DW_TAG_typedef, name: "String", baseType: !38)
!38 = !DICompositeType(tag: DW_TAG_structure_type, name: "char[]", size: 128, align: 64, elements: !39, identifier: "char[]")
!39 = !{!40, !43}
!40 = !DIDerivedType(tag: DW_TAG_member, name: "ptr", scope: !38, baseType: !41, size: 64, align: 64)
@@ -598,6 +598,7 @@ no_match: ; preds = %compare
!52 = !DIDerivedType(tag: DW_TAG_member, name: "asdf", scope: !50, file: !5, line: 28, baseType: !12, size: 64, align: 64)
!53 = !DILocation(line: 18, column: 8, scope: !30)
!54 = !DILocation(line: 18, column: 34, scope: !30)
!55 = !DILocation
!56 = distinct !DISubprogram(name: "[DEFAULT INIT]", linkageName: "[DEFAULT INIT]", scope: !5, file: !5, line: 33, scopeLine: 33, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition
!57 = !DILocation(line: 18, column: 15, scope: !30)
!58 = !DILocation(line: 21, column: 8, scope: !30)