Bug fixes, addition of hash map implementation. (#605)

* Simple hash map. Fix of bug preventing cast of typeid. Allow declarations in global "$checks". Fix to non-constant default args. Correctly duplicate macro contracts. Allow typeid to add methods. Fix printing of subarrays. Fix bug when printing a function with a module. Fix bug with initializer and creating local variables. Add the compile-only option to the help.
This commit is contained in:
Christoffer Lerno
2022-09-29 20:19:31 +02:00
committed by GitHub
parent e1b5b0b60c
commit 258a6ba97a
22 changed files with 1836 additions and 129 deletions

View File

@@ -157,3 +157,4 @@ macro uint ichar.hash(ichar c) = c;
macro uint long.hash(long i) = (uint)((i >> 32) ^ i);
macro uint ulong.hash(ulong i) = (uint)((i >> 32) ^ i);
macro uint bool.hash(bool b) = (uint)b;
macro uint typeid.hash(typeid t) = (uint)(((uptr)t >> 32) ^ (uptr)t);

View File

@@ -24,9 +24,9 @@ macro talloc($Type, usize elements)
/**
* @require (usize.max / elements > $Type.sizeof)
**/
macro make($Type, usize elements)
macro make($Type, usize elements, Allocator* allocator = mem::current_allocator())
{
$Type* ptr = calloc($Type.sizeof * elements);
$Type* ptr = allocator.calloc($Type.sizeof * elements)!!;
return ptr[:elements];
}

View File

@@ -182,4 +182,5 @@ fn usize ZString.len(ZString *str)
if (c & 0xC0 != 0x80) len++;
}
return len;
}
}

View File

@@ -114,6 +114,11 @@ macro bool is_comparable($Type)
$endif;
}
macro bool is_equatable($Type)
{
return $checks($Type a, a == a);
}
macro bool is_subarray_convertable($Type)
{
$switch ($Type.kind):
@@ -180,7 +185,7 @@ macro bool is_equatable_value(value)
$if ($defined(value.less) || $defined(value.compare_to) || $defined(value.equals)):
return true;
$else:
return is_comparable($typeof(value));
return is_equatable($typeof(value));
$endif;
}

View File

@@ -1,4 +1,5 @@
module std::io;
import std::map;
import libc;
const int PRINTF_NTOA_BUFFER_SIZE = 256;
@@ -13,6 +14,7 @@ fault PrintFault
INVALID_FORMAT_STRING,
MISSING_ARG,
}
bitstruct PrintFlags : uint
{
bool zeropad : 0;
@@ -36,15 +38,43 @@ struct PrintParam
}
define OutputFn = fn void!(char c, void* buffer, usize buffer_idx);
define PrintFunction = fn char[](void* value, Allocator *allocator);
private define PrintFunctionMap = std::map::HashMap<typeid, PrintFunction>;
private PrintFunctionMap print_functions;
/**
* @require $checks($Type {}.to_string()) "Expected a type with 'to_string' defined"
* @require $checks($Type a, Allocator b, a.to_string(&b)) "Expected 'to_string' to take an allocator as argument."
**/
macro void printf_register_to_string($Type)
{
printf_register($Type.typeid, (PrintFunction)&$Type.to_string);
}
fn void printf_register(typeid type, PrintFunction function)
{
if (!print_functions.table.len)
{
print_functions.init(512);
}
print_functions.set(type, function);
}
fn void! PrintParam.out(PrintParam* param, char c)
{
param.outfn(c, param.buffer, param.idx++)?;
}
private fn void! out_str(PrintParam* param, variant arg)
{
@pool()
{
if (try print_func = print_functions.get(arg.type))
{
return out_substr(param, print_func(arg.ptr, mem::temp_allocator()));
}
};
switch (arg.type.kind)
{
case TYPEID:

296
lib/std/map.c3 Normal file
View File

@@ -0,0 +1,296 @@
module std::map<Key, Value>;
import std::math;
const uint DEFAULT_INITIAL_CAPACITY = 16;
const uint MAXIMUM_CAPACITY = 1u << 31;
const float DEFAULT_LOAD_FACTOR = 0.75;
private struct Entry
{
uint hash;
Key key;
Value value;
Entry* next;
}
struct HashMap
{
Entry*[] table;
Allocator* allocator;
uint count; // Number of elements
uint threshold; // Resize limit
float load_factor;
}
/**
* @require capacity > 0
* @require load_factor > 0.0 && load_factor < 1.0
* @require map.table.len == 0
* @require capacity < MAXIMUM_CAPACITY
* @require allocator != null
**/
fn void HashMap.init(HashMap* map, uint capacity = DEFAULT_INITIAL_CAPACITY, float load_factor = DEFAULT_LOAD_FACTOR, Allocator* allocator = mem::current_allocator())
{
capacity = math::next_power_of_2(capacity);
map.allocator = allocator;
map.load_factor = load_factor;
map.threshold = (uint)(capacity * load_factor);
map.table = array::make(Entry*, capacity, allocator);
}
fn void HashMap.init_from_map(HashMap* map, HashMap* other_map, Allocator* allocator = mem::current_allocator())
{
map.init(other_map.table.len, other_map.load_factor, allocator);
map.put_all_for_create(other_map);
}
fn bool HashMap.is_empty(HashMap* map) @inline
{
return !map.count;
}
fn Value*! HashMap.get_ref(HashMap* map, Key key)
{
uint hash = rehash(key.hash());
for (Entry *e = map.table[index_for(hash, map.table.len)]; e != null; e = e.next)
{
if (e.hash == hash && equals(key, e.key)) return &e.value;
}
return SearchResult.MISSING!;
}
fn Value! HashMap.get(HashMap* map, Key key)
{
return *map.get_ref(key) @inline;
}
fn bool HashMap.has_key(HashMap* map, Key key)
{
return try(map.get_ref(key));
}
fn bool HashMap.set(HashMap* map, Key key, Value value)
{
uint hash = rehash(key.hash());
uint index = index_for(hash, map.table.len);
for (Entry *e = map.table[index]; e != null; e = e.next)
{
if (e.hash == hash && equals(key, e.key))
{
e.value = value;
return true;
}
}
map.add_entry(hash, key, value, index);
return false;
}
fn void! HashMap.remove(HashMap* map, Key key) @maydiscard
{
if (!map.remove_entry_for_key(key)) return SearchResult.MISSING!;
}
fn void HashMap.clear(HashMap* map)
{
if (!map.count) return;
foreach (Entry** &entry_ref : map.table)
{
Entry* entry = *entry_ref;
if (!entry) continue;
map.free(entry);
*entry_ref = null;
}
map.count = 0;
}
fn void HashMap.destroy(HashMap* map)
{
map.clear();
map.free(map.table.ptr);
map.table = Entry*[] {};
}
fn Key[] HashMap.key_tlist(HashMap* map)
{
return map.key_list(mem::temp_allocator());
}
fn Key[] HashMap.key_list(HashMap* map, Allocator* allocator = null)
{
if (!map.count) return Key[] {};
Key[] list = array::make(Key, map.count, allocator ?: map.allocator);
usize index = 0;
foreach (Entry* entry : map.table)
{
while (entry)
{
list[index++] = entry.key;
entry = entry.next;
}
}
return list;
}
fn Value[] HashMap.value_tlist(HashMap* map)
{
return map.value_list(mem::temp_allocator());
}
fn Value[] HashMap.value_list(HashMap* map, Allocator* allocator = null)
{
if (!map.count) return Value[] {};
Value[] list = array::make(Value, map.count, allocator ?: map.allocator);
usize index = 0;
foreach (Entry* entry : map.table)
{
while (entry)
{
list[index++] = entry.value;
entry = entry.next;
}
}
return list;
}
$if (types::is_equatable(Value)):
fn bool HashMap.has_value(HashMap* map, Value v)
{
if (!map.count) return false;
foreach (Entry* entry : map.table)
{
while (entry)
{
if (equals(v, entry.value)) return true;
entry = entry.next;
}
}
return false;
}
$endif;
// --- private methods
private fn void HashMap.add_entry(HashMap* map, uint hash, Key key, Value value, uint bucket_index)
{
Entry* entry = map.allocator.alloc(Entry.sizeof)!!;
*entry = { .hash = hash, .key = key, .value = value, .next = map.table[bucket_index] };
map.table[bucket_index] = entry;
if (map.count++ >= map.threshold)
{
map.resize(map.table.len * 2);
}
}
private fn void HashMap.resize(HashMap* map, uint new_capacity)
{
Entry*[] old_table = map.table;
uint old_capacity = old_table.len;
if (old_capacity == MAXIMUM_CAPACITY)
{
map.threshold = uint.max;
return;
}
Entry*[] new_table = array::make(Entry*, new_capacity, map.allocator);
map.transfer(new_table);
map.table = new_table;
map.free(old_table.ptr);
map.threshold = (uint)(new_capacity * map.load_factor);
}
private fn uint rehash(uint hash) @inline
{
hash ^= (hash >> 20) ^ (hash >> 12);
return hash ^ ((hash >> 7) ^ (hash >> 4));
}
private macro uint index_for(uint hash, uint capacity)
{
return hash & (capacity - 1);
}
private fn void HashMap.transfer(HashMap* map, Entry*[] new_table)
{
Entry*[] src = map.table;
uint new_capacity = new_table.len;
foreach (uint j, Entry *e : src)
{
if (!e) continue;
do
{
Entry* next = e.next;
uint i = index_for(e.hash, new_capacity);
e.next = new_table[i];
new_table[i] = e;
e = next;
}
while (e);
}
}
private fn void HashMap.put_all_for_create(HashMap* map, HashMap* other_map)
{
if (!other_map.count) return;
foreach (Entry *e : other_map.table)
{
if (!e) continue;
map.put_for_create(e.key, e.value);
}
}
private fn void HashMap.put_for_create(HashMap* map, Key key, Value value)
{
uint hash = rehash(key.hash());
uint i = index_for(hash, map.table.len);
for (Entry *e = map.table[i]; e != null; e = e.next)
{
if (e.hash == hash && equals(key, e.key))
{
e.value = value;
return;
}
}
map.create_entry(hash, key, value, i);
}
private fn void HashMap.free(HashMap* map, void* ptr)
{
map.free(ptr);
}
private fn bool HashMap.remove_entry_for_key(HashMap* map, Key key)
{
uint hash = rehash(key.hash());
uint i = index_for(hash, map.table.len);
Entry* prev = map.table[i];
Entry* e = prev;
while (e)
{
Entry *next = e.next;
if (e.hash == hash && equals(key, e.key))
{
map.count--;
if (prev == e)
{
map.table[i] = next;
}
else
{
prev.next = next;
}
map.free(e);
return true;
}
prev = e;
e = next;
}
return false;
}
private fn void HashMap.create_entry(HashMap* map, uint hash, Key key, Value value, int bucket_index)
{
Entry *e = map.table[bucket_index];
Entry* entry = map.allocator.alloc(Entry.sizeof)!!;
*entry = { .hash = hash, .key = key, .value = value, .next = map.table[bucket_index] };
map.table[bucket_index] = entry;
map.count++;
}

View File

@@ -70,6 +70,7 @@ static void usage(void)
OUTPUT(" bench [<target>] Benchmark a target.");
OUTPUT(" clean-run [<target>] Clean, then run the target.");
OUTPUT(" compile-run <file1> [<file2> ...] Compile files then immediately run the result.");
OUTPUT(" compile-only <file1> [<file2> ...] Compile files but do not perform linking.");
OUTPUT(" static-lib <file1> [<file2> ...] Compile files without a project into a static library.");
OUTPUT(" dynamic-lib <file1> [<file2> ...] Compile files without a project into a dynamic library.");
OUTPUT(" headers <file1> [<file2> ...] Analyse files and generate C headers for public methods.");

View File

@@ -1553,6 +1553,28 @@ typedef struct ParseContext_
Lexer lexer;
} ParseContext;
typedef enum
{
CALL_ENV_GLOBAL_INIT,
CALL_ENV_FUNCTION,
CALL_ENV_INITIALIZER,
CALL_ENV_FINALIZER,
CALL_ENV_CHECKS,
CALL_ENV_ATTR,
} CallEnvKind;
typedef struct
{
CallEnvKind kind : 8;
bool ensures : 1;
bool pure : 1;
union
{
Decl *attr_declaration;
Decl *current_function;
};
} CallEnv;
typedef struct SemaContext_
{
Module *core_module;
@@ -1560,12 +1582,7 @@ typedef struct SemaContext_
CompilationUnit *unit;
// Compiled in this unit.
CompilationUnit *compilation_unit;
Decl *current_function;
struct
{
bool current_function_pure : 1;
bool ensures : 1;
};
CallEnv call_env;
Decl *current_macro;
ScopeId scope_id;
Ast *break_target;
@@ -1751,6 +1768,7 @@ typedef struct CopyStruct_
CopyFixup fixups[MAX_FIXUPS];
CopyFixup *current_fixup;
bool single_static;
bool copy_in_use;
} CopyStruct;
@@ -1979,20 +1997,14 @@ UNUSED bool i128_get_bit(const Int128 *op, int bit);
#define MACRO_COPY_ASTID(x) x = astid_copy_deep(c, x)
Expr *expr_macro_copy(Expr *source_expr);
Decl **decl_copy_list(Decl **decl_list);
Ast *ast_macro_copy(Ast *source_ast);
Ast *ast_defer_copy(Ast *source_ast);
Decl *decl_macro_copy(Decl *source_decl);
Expr **copy_expr_list(CopyStruct *c, Expr **expr_list);
Expr *copy_expr(CopyStruct *c, Expr *source_expr);
Ast *ast_copy_deep(CopyStruct *c, Ast *source);
Ast **copy_ast_list(CopyStruct *c, Ast **to_copy);
Decl *copy_decl(CopyStruct *c, Decl *decl);
Decl **copy_decl_list(CopyStruct *c, Decl **decl_list);
TypeInfo *copy_type_info(CopyStruct *c, TypeInfo *source);
void copy_begin(void);
void copy_end(void);
Expr *copy_expr_single(Expr *source_expr);
Decl **copy_decl_list_single(Decl **decl_list);
Ast *copy_ast_single(Ast *source_ast);
Decl **copy_decl_list_macro(Decl **decl_list);
Ast *copy_ast_macro(Ast *source_ast);
Ast *copy_ast_defer(Ast *source_ast);
void init_asm(void);
AsmRegister *asm_reg_by_name(const char *name);

View File

@@ -11,6 +11,14 @@ INLINE void fixup_declid(CopyStruct *c, DeclId *declid_ref);
INLINE ConstInitializer **copy_const_initializer_list(CopyStruct *c, ConstInitializer **initializer_list);
INLINE ConstInitializer **copy_const_initializer_array(CopyStruct *c, ConstInitializer **initializer_list, unsigned len);
static Expr **copy_expr_list(CopyStruct *c, Expr **expr_list);
static Expr *copy_expr(CopyStruct *c, Expr *source_expr);
static Ast *ast_copy_deep(CopyStruct *c, Ast *source);
static Ast **copy_ast_list(CopyStruct *c, Ast **to_copy);
static Decl *copy_decl(CopyStruct *c, Decl *decl);
static Decl **copy_decl_list(CopyStruct *c, Decl **decl_list);
static TypeInfo *copy_type_info(CopyStruct *c, TypeInfo *source);
static inline void copy_reg_ref(CopyStruct *c, void *original, void *result)
{
c->current_fixup->new_ptr = result;
@@ -149,32 +157,35 @@ static DesignatorElement **macro_copy_designator_list(CopyStruct *c, DesignatorE
static CopyStruct copy_struct;
Ast *ast_macro_copy(Ast *source_ast)
Ast *copy_ast_single(Ast *source_ast)
{
copy_struct.current_fixup = copy_struct.fixups;
copy_struct.single_static = false;
copy_begin();
Ast *ast = ast_copy_deep(&copy_struct, source_ast);
copy_end();
return ast;
}
Ast *copy_ast_macro(Ast *source_ast)
{
assert(copy_struct.copy_in_use);
return ast_copy_deep(&copy_struct, source_ast);
}
Decl *decl_macro_copy(Decl *source_decl)
Ast *copy_ast_defer(Ast *source_ast)
{
copy_struct.current_fixup = copy_struct.fixups;
copy_struct.single_static = false;
return copy_decl(&copy_struct, source_decl);
}
Ast *ast_defer_copy(Ast *source_ast)
{
copy_struct.current_fixup = copy_struct.fixups;
copy_begin();
copy_struct.single_static = true;
return ast_copy_deep(&copy_struct, source_ast);
Ast *ast = copy_ast_macro(source_ast);
copy_end();
return ast;
}
Expr *expr_macro_copy(Expr *source_expr)
Expr *copy_expr_single(Expr *source_expr)
{
copy_struct.current_fixup = copy_struct.fixups;
copy_struct.single_static = false;
return copy_expr(&copy_struct, source_expr);
copy_begin();
Expr *expr = copy_expr(&copy_struct, source_expr);
copy_end();
return expr;
}
void copy_range(CopyStruct *c, Range *range)
@@ -640,14 +651,31 @@ Ast **copy_ast_list(CopyStruct *c, Ast **to_copy)
return result;
}
Decl **decl_copy_list(Decl **decl_list)
void copy_begin(void)
{
copy_struct.current_fixup = copy_struct.fixups;
Decl **result = NULL;
VECEACH(decl_list, i)
{
vec_add(result, copy_decl(&copy_struct, decl_list[i]));
}
assert(!copy_struct.copy_in_use);
copy_struct.copy_in_use = true;
copy_struct.single_static = false;
}
void copy_end(void)
{
assert(copy_struct.copy_in_use);
copy_struct.copy_in_use = false;
}
Decl **copy_decl_list_macro(Decl **decl_list)
{
assert(copy_struct.copy_in_use);
return copy_decl_list(&copy_struct, decl_list);
}
Decl **copy_decl_list_single(Decl **decl_list)
{
copy_begin();
Decl **result = copy_decl_list_macro(decl_list);
copy_end();
return result;
}

View File

@@ -321,24 +321,26 @@ LLVMTypeRef llvm_get_type(GenContext *c, Type *any_type)
assert(LLVMGetTypeContext(any_type->backend_type) == c->context && "Should have been purged");
return any_type->backend_type;
}
Type *type = type_flatten(any_type);
if (type != any_type)
{
return any_type->backend_type = llvm_get_type(c, type);
}
switch (any_type->type_kind)
{
case CT_TYPES:
UNREACHABLE
case TYPE_OPTIONAL:
case TYPE_FAILABLE_ANY:
case TYPE_TYPEDEF:
case TYPE_DISTINCT:
case TYPE_ENUM:
// If this is reachable, then we're not doing the proper lowering.
UNREACHABLE
case TYPE_TYPEID:
case TYPE_ANYERR:
case TYPE_FAULTTYPE:
return any_type->backend_type = llvm_get_type(c, type_iptr->canonical);
case TYPE_TYPEDEF:
return any_type->backend_type = llvm_get_type(c, any_type->canonical);
case TYPE_DISTINCT:
return any_type->backend_type = llvm_get_type(c, any_type->decl->distinct_decl.base_type);
case TYPE_ENUM:
return any_type->backend_type = llvm_get_type(c, any_type->decl->enums.type_info->type->canonical);
case TYPE_STRUCT:
case TYPE_UNION:
case TYPE_BITSTRUCT:

View File

@@ -1314,7 +1314,6 @@ static bool cast_inner(Expr *expr, Type *from_type, Type *to, Type *to_type)
UNREACHABLE
case TYPE_VOID:
UNREACHABLE
case TYPE_TYPEID:
case TYPE_DISTINCT:
case TYPE_FUNC:
case TYPE_TYPEDEF:
@@ -1353,6 +1352,7 @@ static bool cast_inner(Expr *expr, Type *from_type, Type *to, Type *to_type)
if (to == type_bool) return float_to_bool(expr, to_type);
if (type_is_float(to)) return float_to_float(expr, to, to_type);
break;
case TYPE_TYPEID:
case TYPE_POINTER:
if (type_is_integer(to)) return pointer_to_integer(expr, to_type);
if (to->type_kind == TYPE_BOOL) return pointer_to_bool(expr, to_type);

View File

@@ -1739,7 +1739,7 @@ static bool sema_analyse_attributes_inner(SemaContext *context, Decl *decl, Attr
}
// Handle the case where the current function is the declaration itself.
if (context->current_function == attr_decl)
if (context->call_env.kind == CALL_ENV_ATTR && context->call_env.attr_declaration == attr_decl)
{
SEMA_ERROR(attr_decl, "Recursive declaration of attribute '%s' it contains itself.", attr_decl->name);
return false;
@@ -1764,7 +1764,7 @@ static bool sema_analyse_attributes_inner(SemaContext *context, Decl *decl, Attr
// context.
SemaContext eval_context;
sema_context_init(&eval_context, attr_decl->unit);
eval_context.call_env = (CallEnv) { .kind = CALL_ENV_ATTR, .attr_declaration = decl };
// We copy the compilation unit.
eval_context.compilation_unit = context->unit;
@@ -2025,8 +2025,7 @@ static inline bool sema_analyse_xxlizer(SemaContext *context, Decl *decl)
{
if (!sema_analyse_attributes(context, decl, decl->attributes, decl->decl_kind == DECL_INITIALIZE ? ATTR_INITIALIZER : ATTR_FINALIZER)) return decl_poison(decl);
if (decl->xxlizer.priority == 0) decl->xxlizer.priority = MAX_PRIORITY;
context->current_function = NULL;
context->current_function_pure = false;
context->call_env = (CallEnv) { .kind = decl->decl_kind == DECL_INITIALIZE ? CALL_ENV_INITIALIZER : CALL_ENV_FINALIZER };
context->rtype = type_void;
context->active_scope = (DynamicScope) {
.scope_id = 0,
@@ -2042,7 +2041,6 @@ static inline bool sema_analyse_xxlizer(SemaContext *context, Decl *decl)
context->next_target = 0;
context->next_switch = 0;
context->break_target = 0;
context->ensures = false;
Ast *body = astptr(decl->xxlizer.init);
// Insert an implicit return
@@ -2353,7 +2351,7 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local)
}
else
{
if (!context->current_function)
if (context->call_env.kind == CALL_ENV_GLOBAL_INIT)
{
if (context->current_macro)
{
@@ -2399,7 +2397,7 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local)
decl->type = decl->var.type_info->type;
if (!sema_analyse_decl_type(context, decl->type, decl->var.type_info->span)) return false;
bool is_static = decl->var.is_static;
if (is_static && context->current_function_pure)
if (is_static && context->call_env.pure)
{
SEMA_ERROR(decl, "'@pure' functions may not have static variables.");
return false;
@@ -2407,7 +2405,7 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local)
if (is_static && !decl->has_extname)
{
scratch_buffer_clear();
scratch_buffer_append(context->current_function->name);
scratch_buffer_append(context->call_env.kind == CALL_ENV_FUNCTION ? context->call_env.current_function->name : ".global");
scratch_buffer_append_char('$');
scratch_buffer_append(decl->name);
decl->extname = scratch_buffer_copy();
@@ -2430,14 +2428,14 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local)
if (!decl->alignment) decl->alignment = type_alloca_alignment(decl->type);
}
Decl *function = context->current_function;
if (is_static) context->current_function = NULL;
CallEnvKind env_kind = context->call_env.kind;
if (is_static) context->call_env.kind = CALL_ENV_GLOBAL_INIT;
if (!sema_expr_analyse_assign_right_side(context, NULL, decl->type, init, false))
{
context->current_function = function;
context->call_env.kind = env_kind;
return decl_poison(decl);
}
context->current_function = function;
context->call_env.kind = env_kind;
if (infer_len)
{
@@ -2483,8 +2481,8 @@ bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local)
static CompilationUnit *unit_copy(Module *module, CompilationUnit *unit)
{
CompilationUnit *copy = unit_create(unit->file);
copy->imports = decl_copy_list(unit->imports);
copy->global_decls = decl_copy_list(unit->global_decls);
copy->imports = copy_decl_list_single(unit->imports);
copy->global_decls = copy_decl_list_single(unit->global_decls);
copy->module = module;
assert(!unit->functions && !unit->macro_methods && !unit->methods && !unit->enums && !unit->ct_ifs && !unit->types);
return copy;

View File

@@ -535,7 +535,7 @@ static inline bool sema_cast_ident_rvalue(SemaContext *context, Expr *expr)
UNREACHABLE
}
if (type_is_abi_aggregate(decl->type)) return true;
expr_replace(expr, expr_macro_copy(decl->var.init_expr));
expr_replace(expr, copy_expr_single(decl->var.init_expr));
return sema_analyse_expr(context, expr);
case VARDECL_PARAM_EXPR:
UNREACHABLE
@@ -548,7 +548,7 @@ static inline bool sema_cast_ident_rvalue(SemaContext *context, Expr *expr)
// Impossible to reach this, they are already unfolded
UNREACHABLE
case VARDECL_PARAM_REF:
expr_replace(expr, expr_macro_copy(decl->var.init_expr));
expr_replace(expr, copy_expr_single(decl->var.init_expr));
return sema_cast_rvalue(context, expr);
case VARDECL_PARAM:
case VARDECL_GLOBAL:
@@ -590,7 +590,7 @@ static inline bool sema_expr_analyse_ternary(SemaContext *context, Expr *expr)
}
if (expr_is_constant_eval(cond, true))
{
Expr *copy = expr_macro_copy(cond);
Expr *copy = copy_expr_single(cond);
cast(copy, type_bool);
assert(cond->expr_kind == EXPR_CONST);
path = cond->const_expr.b ? 1 : 0;
@@ -760,7 +760,7 @@ static inline bool sema_expr_analyse_identifier(SemaContext *context, Type *to,
case VARDECL_CONST:
if (!decl->type)
{
Expr *copy = expr_macro_copy(decl->var.init_expr);
Expr *copy = copy_expr_single(decl->var.init_expr);
if (!sema_analyse_expr(context, copy)) return false;
if (!expr_is_constant_eval(copy, false))
{
@@ -777,7 +777,7 @@ static inline bool sema_expr_analyse_identifier(SemaContext *context, Type *to,
}
break;
case VARDECL_GLOBAL:
if (context->current_function_pure)
if (context->call_env.pure)
{
SEMA_ERROR(expr, "'@pure' functions may not access globals.");
return false;
@@ -828,7 +828,7 @@ static inline bool sema_expr_analyse_hash_identifier(SemaContext *context, Expr
assert(decl->decl_kind == DECL_VAR);
expr_replace(expr, expr_macro_copy(decl->var.init_expr));
expr_replace(expr, copy_expr_single(decl->var.init_expr));
REMINDER("Remove analysis for hash");
if (!sema_analyse_expr_lvalue_fold_const(decl->var.hash_var.context, expr))
{
@@ -994,9 +994,8 @@ INLINE bool sema_call_expand_arguments(SemaContext *context, CalledDecl *callee,
return false;
}
// 8g. Set the parameter and update failability.
// 8g. Set the parameter
actual_args[index] = arg->designator_expr.value;
*failable |= IS_OPTIONAL(arg->designator_expr.value);
continue;
}
@@ -1060,7 +1059,7 @@ INLINE bool sema_call_expand_arguments(SemaContext *context, CalledDecl *callee,
Expr *init_expr = param->var.init_expr;
if (init_expr)
{
Expr *arg = actual_args[i] = expr_macro_copy(init_expr);
Expr *arg = actual_args[i] = copy_expr_single(init_expr);
if (arg->resolve_status != RESOLVE_DONE)
{
@@ -1294,6 +1293,7 @@ static inline bool sema_call_analyse_invocation(SemaContext *context, Expr *call
// &foo
if (!sema_analyse_expr_lvalue(context, arg)) return false;
if (!sema_expr_check_assign(context, arg)) return false;
*failable |= IS_OPTIONAL(arg);
if (!sema_call_check_inout_param_match(context, param, arg)) return false;
if (arg->type == type_untypedlist)
{
@@ -1388,7 +1388,7 @@ static inline bool sema_call_analyse_func_invocation(SemaContext *context, Type
.params = sig->params,
.signature = sig,
};
if (context->current_function_pure && !sig->attrs.is_pure && !expr->call_expr.attr_pure)
if (context->call_env.pure && !sig->attrs.is_pure && !expr->call_expr.attr_pure)
{
SEMA_ERROR(expr, "Only '@pure' functions may be called, you can override this with an attribute.");
return false;
@@ -1543,7 +1543,12 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s
{
assert(decl->decl_kind == DECL_MACRO);
Decl **params = decl_copy_list(decl->func_decl.signature.params);
copy_begin();
Decl **params = copy_decl_list_macro(decl->func_decl.signature.params);
Ast *body = copy_ast_macro(astptr(decl->func_decl.body));
AstId docs = decl->func_decl.docs;
if (docs) docs = astid(copy_ast_macro(astptr(docs)));
copy_end();
CalledDecl callee = {
.macro = true,
.name = decl->name,
@@ -1628,7 +1633,6 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s
if (!body_arg->alignment) body_arg->alignment = type_alloca_alignment(body_arg->type);
}
Ast *body = ast_macro_copy(astptr(decl->func_decl.body));
DynamicScope old_scope = context->active_scope;
context_change_scope_with_flags(context, SCOPE_NONE);
@@ -1638,7 +1642,7 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s
Type *rtype = NULL;
sema_context_init(&macro_context, decl->unit);
macro_context.compilation_unit = context->unit;
macro_context.current_function = context->current_function;
macro_context.call_env = context->call_env;
rtype = decl->func_decl.signature.rtype ? type_infoptr(decl->func_decl.signature.rtype)->type : NULL;
macro_context.expected_block_type = rtype;
bool may_failable = true;
@@ -1681,7 +1685,7 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s
AstId assert_first = 0;
AstId* next = &assert_first;
if (!sema_analyse_contracts(&macro_context, decl->func_decl.docs, &next)) return false;
if (!sema_analyse_contracts(&macro_context, docs, &next)) return false;
sema_append_contract_asserts(assert_first, body);
if (!sema_analyse_statement(&macro_context, body)) goto EXIT_FAIL;
@@ -1873,7 +1877,7 @@ static bool sema_call_analyse_body_expansion(SemaContext *macro_context, Expr *c
Decl *param = params[i];
if (!sema_add_local(context, param)) return SCOPE_POP_ERROR();
}
Ast *ast = ast_macro_copy(macro_context->yield_body);
Ast *ast = copy_ast_single(macro_context->yield_body);
call->body_expansion_expr.first_stmt = astid(ast);
if (!sema_analyse_statement(context, ast)) return SCOPE_POP_ERROR();
assert(ast->ast_kind == AST_COMPOUND_STMT);
@@ -3138,8 +3142,6 @@ CHECK_DEEPER:
if (flat_type->type_kind == TYPE_TYPEID)
{
if (sema_expr_rewrite_to_typeid_property(context, expr, parent, kw)) return true;
SEMA_ERROR(identifier, "'%s' is not a valid property for typeid.", kw);
return false;
}
// Hard coded ptr on subarrays and variant
@@ -3229,7 +3231,7 @@ CHECK_DEEPER:
if (member && decl_is_enum_kind(decl) && member->decl_kind == DECL_VAR && parent->expr_kind == EXPR_CONST)
{
assert(parent->const_expr.const_kind == CONST_ENUM);
Expr *copy_init = expr_macro_copy(current_parent->const_expr.enum_val->enum_constant.args[member->var.index]);
Expr *copy_init = copy_expr_single(current_parent->const_expr.enum_val->enum_constant.args[member->var.index]);
expr_replace(expr, copy_init);
return true;
}
@@ -5343,7 +5345,7 @@ static inline bool sema_expr_analyse_catch(SemaContext *context, Expr *expr)
static inline bool sema_expr_analyse_rethrow(SemaContext *context, Expr *expr)
{
if (!context->current_function)
if (context->call_env.kind != CALL_ENV_FUNCTION && context->call_env.kind != CALL_ENV_CHECKS)
{
SEMA_ERROR(expr, "Rethrow cannot be used outside of a function.");
return false;
@@ -5521,13 +5523,28 @@ static inline bool sema_expr_analyse_compiler_const(SemaContext *context, Expr *
}
if (string == kw_FUNC)
{
if (!context->current_function)
switch (context->call_env.kind)
{
expr_rewrite_to_string(expr, "<GLOBAL>");
return true;
case CALL_ENV_GLOBAL_INIT:
expr_rewrite_to_string(expr, "<GLOBAL>");
return true;
case CALL_ENV_CHECKS:
expr_rewrite_to_string(expr, "<CHECKS>");
return true;
case CALL_ENV_FUNCTION:
expr_rewrite_to_string(expr, context->call_env.current_function->name);
return true;
case CALL_ENV_INITIALIZER:
expr_rewrite_to_string(expr, "<static initializer>");
return true;
case CALL_ENV_FINALIZER:
expr_rewrite_to_string(expr, "<static finalizer>");
return true;
case CALL_ENV_ATTR:
expr_rewrite_to_string(expr, "<attribute>");
return true;
}
expr_rewrite_to_string(expr, context->current_function->name);
return true;
UNREACHABLE
}
if (string == kw_LINEREAL)
{
@@ -5969,6 +5986,8 @@ static inline Expr *sema_ct_checks_exprlist_compiles(SemaContext *context, Expr
Expr *failed = NULL;
bool suppress_error = global_context.suppress_errors;
global_context.suppress_errors = true;
CallEnvKind eval_kind = context->call_env.kind;
context->call_env.kind = CALL_ENV_CHECKS;
SCOPE_START_WITH_FLAGS(SCOPE_CHECKS);
FOREACH_BEGIN(Expr *expr, exprlist->expression_list)
if (!sema_analyse_expr(context, expr))
@@ -5978,6 +5997,7 @@ static inline Expr *sema_ct_checks_exprlist_compiles(SemaContext *context, Expr
}
FOREACH_END();
SCOPE_END;
context->call_env.kind = eval_kind;
global_context.suppress_errors = suppress_error;
return failed;
}
@@ -6137,14 +6157,14 @@ static inline bool sema_expr_analyse_ct_arg(SemaContext *context, Expr *expr)
{
// An expr argument, this means we copy and evaluate.
ASSIGN_EXPR_OR_RET(Expr *arg_expr, sema_expr_analyse_ct_arg_index(context, exprptr(expr->ct_arg_expr.arg)), false);
expr_replace(expr, expr_macro_copy(arg_expr));
expr_replace(expr, copy_expr_single(arg_expr));
return true;
}
case TOKEN_CT_VACONST:
{
// An expr argument, this means we copy and evaluate.
ASSIGN_EXPR_OR_RET(Expr *arg_expr, sema_expr_analyse_ct_arg_index(context, exprptr(expr->ct_arg_expr.arg)), false);
arg_expr = expr_macro_copy(arg_expr);
arg_expr = copy_expr_single(arg_expr);
if (!expr_is_constant_eval(arg_expr, CONSTANT_EVAL_CONSTANT_VALUE))
{
SEMA_ERROR(arg_expr, "This argument needs to be a compile time constant.");
@@ -6517,7 +6537,7 @@ bool sema_analyse_expr_rhs(SemaContext *context, Type *to, Expr *expr, bool allo
static inline bool sema_cast_ct_ident_rvalue(SemaContext *context, Expr *expr)
{
Decl *decl = expr->ct_ident_expr.decl;
Expr *copy = expr_macro_copy(decl->var.init_expr);
Expr *copy = copy_expr_single(decl->var.init_expr);
if (!sema_analyse_expr(context, copy)) return false;
expr_replace(expr, copy);
return true;

View File

@@ -39,9 +39,15 @@ static inline void sema_update_const_initializer_with_designator(
DesignatorElement **curr,
DesignatorElement **end,
Expr *value);
static inline ConstantEvalKind env_eval_type(SemaContext *context);
static inline ConstantEvalKind env_eval_type(SemaContext *context)
{
return context->call_env.kind == CALL_ENV_GLOBAL_INIT ? CONSTANT_EVAL_GLOBAL_INIT : CONSTANT_EVAL_LOCAL_INIT;
}
static inline void sema_not_enough_elements_error(Expr *initializer, int element)
{
if (element == 0)
@@ -162,7 +168,7 @@ static inline bool sema_expr_analyse_struct_plain_initializer(SemaContext *conte
// 6. There's the case of too few values as well. Mark the last field as wrong.
assert(elements_needed <= size);
initializer->resolve_status = RESOLVE_DONE;
if (expr_is_constant_eval(initializer, context->current_function ? CONSTANT_EVAL_LOCAL_INIT : CONSTANT_EVAL_GLOBAL_INIT))
if (expr_is_constant_eval(initializer, env_eval_type(context)))
{
bool is_union = type_flatten_distinct(initializer->type)->type_kind == TYPE_UNION;
assert(!is_union || vec_size(elements) == 1);
@@ -254,7 +260,7 @@ static inline bool sema_expr_analyse_array_plain_initializer(SemaContext *contex
}
initializer->resolve_status = RESOLVE_DONE;
if (expr_is_constant_eval(initializer, context->current_function ? CONSTANT_EVAL_LOCAL_INIT : CONSTANT_EVAL_GLOBAL_INIT))
if (expr_is_constant_eval(initializer, env_eval_type(context)))
{
ConstInitializer *const_init = CALLOCS(ConstInitializer);
const_init->kind = CONST_INIT_ARRAY_FULL;
@@ -326,7 +332,7 @@ static bool sema_expr_analyse_designated_initializer(SemaContext *context, Type
initializer->type = sema_type_lower_by_size(initializer->type, (ArraySize)(max_index + 1));
}
initializer->resolve_status = RESOLVE_DONE;
if (expr_is_constant_eval(initializer, context->current_function ? CONSTANT_EVAL_LOCAL_INIT : CONSTANT_EVAL_GLOBAL_INIT))
if (expr_is_constant_eval(initializer, env_eval_type(context)))
{
ConstInitializer *const_init = MALLOCS(ConstInitializer);
sema_create_const_initializer_from_designated_init(const_init, initializer);

View File

@@ -403,12 +403,12 @@ static inline bool sema_analyse_return_stmt(SemaContext *context, Ast *statement
// Process any ensures.
AstId cleanup = context_get_defers(context, context->active_scope.defer_last, 0);
if (context->ensures)
if (context->call_env.ensures)
{
AstId first = 0;
AstId *append_id = &first;
// Creating an assign statement
AstId doc_directive = context->current_function->func_decl.docs;
AstId doc_directive = context->call_env.current_function->func_decl.docs;
context->return_expr = return_expr;
while (doc_directive)
{
@@ -2268,7 +2268,7 @@ static inline bool sema_analyse_ct_foreach_stmt(SemaContext *context, Ast *state
AstId *current = &start;
for (unsigned i = 0; i < count; i++)
{
Ast *compound_stmt = ast_macro_copy(body);
Ast *compound_stmt = copy_ast_single(body);
if (expressions)
{
value->var.init_expr = expressions[i];
@@ -2442,8 +2442,8 @@ static inline bool sema_analyse_ct_for_stmt(SemaContext *context, Ast *statement
for (int i = 0; i < MAX_MACRO_ITERATIONS; i++)
{
// First evaluate the cond, which we note that we *must* have.
// we need to make a cop
Expr *copy = expr_macro_copy(exprptr(condition));
// we need to make a copy
Expr *copy = copy_expr_single(exprptr(condition));
if (!sema_analyse_cond_expr(context, copy)) return false;
if (!expr_is_const(copy))
{
@@ -2454,7 +2454,7 @@ static inline bool sema_analyse_ct_for_stmt(SemaContext *context, Ast *statement
if (!copy->const_expr.b) break;
// Otherwise we copy the body.
Ast *compound_stmt = ast_macro_copy(body);
Ast *compound_stmt = copy_ast_single(body);
// Analyse the body
if (!sema_analyse_compound_statement_no_scope(context, compound_stmt)) return false;
@@ -2465,7 +2465,7 @@ static inline bool sema_analyse_ct_for_stmt(SemaContext *context, Ast *statement
// Copy and evaluate all the expressions in "incr"
FOREACH_BEGIN(Expr *expr, incr_list)
if (!sema_analyse_ct_expr(context, expr_macro_copy(expr))) return false;
if (!sema_analyse_ct_expr(context, copy_expr_single(expr))) return false;
FOREACH_END();
}
// Analysis is done turn the generated statements into a compound statement for lowering.
@@ -2687,7 +2687,7 @@ bool sema_analyse_contracts(SemaContext *context, AstId doc, AstId **asserts)
break;
case DOC_DIRECTIVE_ENSURE:
if (!sema_analyse_ensure(context, directive)) return false;
context->ensures = true;
context->call_env.ensures = true;
break;
}
doc = directive->next;
@@ -2700,8 +2700,11 @@ bool sema_analyse_function_body(SemaContext *context, Decl *func)
if (!decl_ok(func)) return false;
Signature *signature = &func->func_decl.signature;
FunctionPrototype *prototype = func->type->function.prototype;
context->current_function = func;
context->current_function_pure = func->func_decl.signature.attrs.is_pure;
context->call_env = (CallEnv) {
.current_function = func,
.kind = CALL_ENV_FUNCTION,
.pure = func->func_decl.signature.attrs.is_pure
};
context->rtype = prototype->rtype;
context->active_scope = (DynamicScope) {
.scope_id = 0,
@@ -2717,7 +2720,6 @@ bool sema_analyse_function_body(SemaContext *context, Decl *func)
context->next_target = 0;
context->next_switch = 0;
context->break_target = 0;
context->ensures = false;
assert(func->func_decl.body);
Ast *body = astptr(func->func_decl.body);
SCOPE_START

View File

@@ -67,7 +67,7 @@ AstId context_get_defers(SemaContext *context, AstId defer_top, AstId defer_bott
while (defer_bottom != defer_top)
{
Ast *defer = astptr(defer_top);
Ast *defer_body = ast_defer_copy(astptr(defer->defer_stmt.body));
Ast *defer_body = copy_ast_defer(astptr(defer->defer_stmt.body));
*next = astid(defer_body);
next = &defer_body->next;
defer_top = defer->defer_stmt.prev_defer;
@@ -84,7 +84,7 @@ void context_pop_defers(SemaContext *context, AstId *next)
while (defer_current != defer_start)
{
Ast *defer = astptr(defer_current);
Ast *defer_body = ast_defer_copy(astptr(defer->defer_stmt.body));
Ast *defer_body = copy_ast_defer(astptr(defer->defer_stmt.body));
*next = astid(defer_body);
next = &defer_body->next;
defer_current = defer->defer_stmt.prev_defer;
@@ -169,24 +169,16 @@ static void register_generic_decls(CompilationUnit *unit, Decl **decls)
case DECL_DECLARRAY:
case DECL_INITIALIZE:
case DECL_FINALIZE:
case DECL_CT_IF:
case DECL_CT_SWITCH:
continue;
case DECL_ATTRIBUTE:
break;
case DECL_CT_CASE:
// register_generic_decls(module, decl->ct_case_decl.body);
continue;
case DECL_CT_ELIF:
// register_generic_decls(module, decl->ct_elif_decl.then);
continue;
case DECL_CT_ELSE:
// register_generic_decls(module, decl->ct_else_decl);
continue;
case DECL_CT_IF:
// register_generic_decls(module, decl->ct_if_decl.then);
continue;
case DECL_CT_SWITCH:
// register_generic_decls(module, decl->ct_switch_decl.cases);
continue;
case DECL_BODYPARAM:
UNREACHABLE
case DECL_MACRO:
case DECL_DEFINE:
case DECL_DISTINCT:
@@ -199,13 +191,11 @@ static void register_generic_decls(CompilationUnit *unit, Decl **decls)
case DECL_UNION:
case DECL_VAR:
case DECL_BITSTRUCT:
case DECL_BODYPARAM:
break;
}
htable_set(&unit->module->symbols, decl->name, decl);
if (decl->visibility == VISIBLE_PUBLIC) global_context_add_generic_decl(decl);
}
}
@@ -364,7 +354,7 @@ SemaContext *context_transform_for_eval(SemaContext *context, SemaContext *temp_
DEBUG_LOG("Changing compilation unit to %s", eval_unit->file->name);
sema_context_init(temp_context, eval_unit);
temp_context->compilation_unit = context->compilation_unit;
temp_context->current_function = context->current_function;
temp_context->call_env = context->call_env;
temp_context->current_macro = context->current_macro;
return temp_context;
}

View File

@@ -140,12 +140,15 @@ static void type_append_name_to_scratch(Type *type)
case TYPE_SUBARRAY:
type_append_name_to_scratch(type->array.base);
scratch_buffer_append("[]");
break;
case TYPE_FLEXIBLE_ARRAY:
type_append_name_to_scratch(type->array.base);
scratch_buffer_append("[*]");
break;
case TYPE_SCALED_VECTOR:
type_append_name_to_scratch(type->array.base);
scratch_buffer_append("[<>]");
break;
case TYPE_VOID:
case TYPE_BOOL:
case ALL_INTS:
@@ -527,7 +530,8 @@ void type_mangle_introspect_name_to_buffer(Type *type)
case TYPE_FUNC:
if (type->function.module)
{
scratch_buffer_append(type->function.module->extname);
Module *module = type->function.module;
scratch_buffer_append(module->extname ? module->extname : module->name->module);
scratch_buffer_append_char('$');
scratch_buffer_append(type->name);
}

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.3.60"
#define COMPILER_VERSION "0.3.61"

View File

@@ -0,0 +1,7 @@
module test;
static initialize
{
int a;
a = 1;
}

View File

@@ -0,0 +1,680 @@
// #target: macos-x64
module test;
import std::io;
import std::map;
struct Foo { int x; void* bar; }
define IntFooMap = std::map::HashMap<int, Foo>;
define IntDoubleMap = std::map::HashMap<int, double>;
fn char[] Foo.to_string(Foo* foo, Allocator* allocator = mem::current_allocator())
{
String s = string::new_with_capacity(128, allocator);
s.printf("{%s, %p}", foo.x, foo.bar);
return s.str();
}
static initialize
{
io::printf_register_to_string(Foo);
}
fn void main()
{
IntFooMap map;
map.init();
io::printfln("Map size: %d", map.count);
map.set(1, Foo { 1, null });
io::printfln("Map size: %d", map.count);
map.set(1, Foo { 2, null });
io::printfln("Map size: %d", map.count);
io::printfln("Val: %d", map.get(1).x);
io::printfln("Has 1: %s", map.has_key(1));
io::printfln("Has 2: %s", map.has_key(2));
map.set(7, Foo { 4, null });
io::printfln("Values: %s", map.value_list());
IntDoubleMap map2;
map2.init();
map2.set(4, 1.3);
io::printfln("Map find: %s", map2.has_value(1.3));
io::printfln("Map find: %s", map2.has_value(1.2));
map2.set(100, 3.4);
io::printfln("%s", map2.key_list());
io::printfln("%s", map2.value_list());
@pool()
{
IntDoubleMap map3;
map3.init(.allocator = mem::temp_allocator());
map3.set(5, 3.2);
map3.set(7, 5.2);
io::printfln("%s", map3.key_tlist());
};
}
/* #expect: test.ll
@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @.static_initialize.0, i8* null }]
define void @.static_initialize.0() {
entry:
call void @std_io_printf_register(i64 ptrtoint (%.introspect* @"ct$test_Foo" to i64), { i8*, i64 } (i8*, %Allocator*)* bitcast ({ i8*, i64 } (%Foo*, %Allocator*)* @test_Foo_to_string to { i8*, i64 } (i8*, %Allocator*)*))
ret void
}
define { i8*, i64 } @test_Foo_to_string(%Foo* %0, %Allocator* %1) #0 {
entry:
%s = alloca i8*, align 8
%retparam = alloca i64, align 8
%taddr = alloca %"char[]", align 8
%vararg = alloca %"variant[]", align 8
%varargslots = alloca [2 x %variant], align 16
%result = alloca %"char[]", align 8
%tempcoerce = alloca { i8*, i64 }, align 8
%2 = call i8* @std_core_string_new_with_capacity(i64 128, %Allocator* %1)
store i8* %2, i8** %s, align 8
store %"char[]" { i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.17, i32 0, i32 0), i64 8 }, %"char[]"* %taddr, align 8
%3 = bitcast %"char[]"* %taddr to { i8*, i64 }*
%4 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %3, i32 0, i32 0
%lo = load i8*, i8** %4, align 8
%5 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %3, i32 0, i32 1
%hi = load i64, i64* %5, align 8
%6 = getelementptr inbounds %Foo, %Foo* %0, i32 0, i32 0
%7 = bitcast i32* %6 to i8*
%8 = insertvalue %variant undef, i8* %7, 0
%9 = insertvalue %variant %8, i64 ptrtoint (%.introspect* @"ct$int" to i64), 1
%10 = getelementptr inbounds [2 x %variant], [2 x %variant]* %varargslots, i64 0, i64 0
store %variant %9, %variant* %10, align 16
%11 = getelementptr inbounds %Foo, %Foo* %0, i32 0, i32 1
%12 = bitcast i8** %11 to i8*
%13 = insertvalue %variant undef, i8* %12, 0
%14 = insertvalue %variant %13, i64 ptrtoint (%.introspect* @"ct$p$void" to i64), 1
%15 = getelementptr inbounds [2 x %variant], [2 x %variant]* %varargslots, i64 0, i64 1
store %variant %14, %variant* %15, align 16
%16 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg, i32 0, i32 1
store i64 2, i64* %16, align 8
%17 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg, i32 0, i32 0
%18 = bitcast [2 x %variant]* %varargslots to %variant*
store %variant* %18, %variant** %17, align 8
%19 = bitcast %"variant[]"* %vararg to { i8*, i64 }*
%20 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %19, i32 0, i32 0
%lo1 = load i8*, i8** %20, align 8
%21 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %19, i32 0, i32 1
%hi2 = load i64, i64* %21, align 8
%22 = call i64 @std_core_string_String_printf(i64* %retparam, i8** %s, i8* %lo, i64 %hi, i8* %lo1, i64 %hi2)
%not_err = icmp eq i64 %22, 0
br i1 %not_err, label %after_check, label %voiderr
after_check: ; preds = %entry
br label %voiderr
voiderr: ; preds = %after_check, %entry
%23 = load i8*, i8** %s, align 8
%24 = call { i8*, i64 } @std_core_string_String_str(i8* %23)
%25 = bitcast %"char[]"* %result to { i8*, i64 }*
store { i8*, i64 } %24, { i8*, i64 }* %25, align 8
%26 = bitcast { i8*, i64 }* %tempcoerce to i8*
%27 = bitcast %"char[]"* %result to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 8 %26, i8* align 8 %27, i32 16, i1 false)
%28 = load { i8*, i64 }, { i8*, i64 }* %tempcoerce, align 8
ret { i8*, i64 } %28
}
; Function Attrs: nounwind
define void @test_main() #0 {
entry:
%map = alloca %HashMap, align 8
%retparam = alloca i64, align 8
%taddr = alloca %"char[]", align 8
%vararg = alloca %"variant[]", align 8
%varargslots = alloca [1 x %variant], align 16
%literal = alloca %Foo, align 8
%retparam5 = alloca i64, align 8
%taddr6 = alloca %"char[]", align 8
%vararg9 = alloca %"variant[]", align 8
%varargslots10 = alloca [1 x %variant], align 16
%literal16 = alloca %Foo, align 8
%retparam19 = alloca i64, align 8
%taddr20 = alloca %"char[]", align 8
%vararg23 = alloca %"variant[]", align 8
%varargslots24 = alloca [1 x %variant], align 16
%retparam30 = alloca i64, align 8
%taddr31 = alloca %"char[]", align 8
%vararg34 = alloca %"variant[]", align 8
%varargslots35 = alloca [1 x %variant], align 16
%retparam36 = alloca %Foo, align 8
%retparam44 = alloca i64, align 8
%taddr45 = alloca %"char[]", align 8
%vararg48 = alloca %"variant[]", align 8
%varargslots49 = alloca [1 x %variant], align 16
%taddr50 = alloca i8, align 1
%retparam56 = alloca i64, align 8
%taddr57 = alloca %"char[]", align 8
%vararg60 = alloca %"variant[]", align 8
%varargslots61 = alloca [1 x %variant], align 16
%taddr62 = alloca i8, align 1
%literal68 = alloca %Foo, align 8
%retparam71 = alloca i64, align 8
%taddr72 = alloca %"char[]", align 8
%vararg75 = alloca %"variant[]", align 8
%varargslots76 = alloca [1 x %variant], align 16
%result = alloca %"Foo[]", align 8
%map2 = alloca %HashMap.0, align 8
%retparam82 = alloca i64, align 8
%taddr83 = alloca %"char[]", align 8
%vararg86 = alloca %"variant[]", align 8
%varargslots87 = alloca [1 x %variant], align 16
%taddr88 = alloca i8, align 1
%retparam94 = alloca i64, align 8
%taddr95 = alloca %"char[]", align 8
%vararg98 = alloca %"variant[]", align 8
%varargslots99 = alloca [1 x %variant], align 16
%taddr100 = alloca i8, align 1
%retparam106 = alloca i64, align 8
%taddr107 = alloca %"char[]", align 8
%vararg110 = alloca %"variant[]", align 8
%varargslots111 = alloca [1 x %variant], align 16
%result112 = alloca %"int[]", align 8
%retparam118 = alloca i64, align 8
%taddr119 = alloca %"char[]", align 8
%vararg122 = alloca %"variant[]", align 8
%varargslots123 = alloca [1 x %variant], align 16
%result124 = alloca %"double[]", align 8
%temp = alloca %TempAllocator*, align 8
%error_var = alloca i64, align 8
%retparam130 = alloca %TempAllocator*, align 8
%mark = alloca i64, align 8
%map3 = alloca %HashMap.0, align 8
%error_var135 = alloca i64, align 8
%retparam136 = alloca %TempAllocator*, align 8
%retparam143 = alloca i64, align 8
%taddr144 = alloca %"char[]", align 8
%vararg147 = alloca %"variant[]", align 8
%varargslots148 = alloca [1 x %variant], align 16
%result149 = alloca %"int[]", align 8
%0 = bitcast %HashMap* %map to i8*
call void @llvm.memset.p0i8.i64(i8* align 8 %0, i8 0, i64 40, i1 false)
%1 = load %Allocator*, %Allocator** @std_core_mem_thread_allocator, align 8
call void @"std_map$$int.test_Foo_HashMap_init"(%HashMap* %map, i32 16, float 7.500000e-01, %Allocator* %1)
store %"char[]" { i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i32 0, i32 0), i64 12 }, %"char[]"* %taddr, align 8
%2 = bitcast %"char[]"* %taddr to { i8*, i64 }*
%3 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %2, i32 0, i32 0
%lo = load i8*, i8** %3, align 8
%4 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %2, i32 0, i32 1
%hi = load i64, i64* %4, align 8
%5 = getelementptr inbounds %HashMap, %HashMap* %map, i32 0, i32 2
%6 = bitcast i32* %5 to i8*
%7 = insertvalue %variant undef, i8* %6, 0
%8 = insertvalue %variant %7, i64 ptrtoint (%.introspect* @"ct$uint" to i64), 1
%9 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots, i64 0, i64 0
store %variant %8, %variant* %9, align 16
%10 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg, i32 0, i32 1
store i64 1, i64* %10, align 8
%11 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg, i32 0, i32 0
%12 = bitcast [1 x %variant]* %varargslots to %variant*
store %variant* %12, %variant** %11, align 8
%13 = bitcast %"variant[]"* %vararg to { i8*, i64 }*
%14 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %13, i32 0, i32 0
%lo1 = load i8*, i8** %14, align 8
%15 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %13, i32 0, i32 1
%hi2 = load i64, i64* %15, align 8
%16 = call i64 @std_io_printfln(i64* %retparam, i8* %lo, i64 %hi, i8* %lo1, i64 %hi2)
%not_err = icmp eq i64 %16, 0
br i1 %not_err, label %after_check, label %voiderr
after_check: ; preds = %entry
br label %voiderr
voiderr: ; preds = %after_check, %entry
%17 = getelementptr inbounds %Foo, %Foo* %literal, i32 0, i32 0
store i32 1, i32* %17, align 8
%18 = getelementptr inbounds %Foo, %Foo* %literal, i32 0, i32 1
store i8* null, i8** %18, align 8
%19 = bitcast %Foo* %literal to { i64, i8* }*
%20 = getelementptr inbounds { i64, i8* }, { i64, i8* }* %19, i32 0, i32 0
%lo3 = load i64, i64* %20, align 8
%21 = getelementptr inbounds { i64, i8* }, { i64, i8* }* %19, i32 0, i32 1
%hi4 = load i8*, i8** %21, align 8
%22 = call i8 @"std_map$$int.test_Foo_HashMap_set"(%HashMap* %map, i32 1, i64 %lo3, i8* %hi4)
store %"char[]" { i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i32 0, i32 0), i64 12 }, %"char[]"* %taddr6, align 8
%23 = bitcast %"char[]"* %taddr6 to { i8*, i64 }*
%24 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %23, i32 0, i32 0
%lo7 = load i8*, i8** %24, align 8
%25 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %23, i32 0, i32 1
%hi8 = load i64, i64* %25, align 8
%26 = getelementptr inbounds %HashMap, %HashMap* %map, i32 0, i32 2
%27 = bitcast i32* %26 to i8*
%28 = insertvalue %variant undef, i8* %27, 0
%29 = insertvalue %variant %28, i64 ptrtoint (%.introspect* @"ct$uint" to i64), 1
%30 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots10, i64 0, i64 0
store %variant %29, %variant* %30, align 16
%31 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg9, i32 0, i32 1
store i64 1, i64* %31, align 8
%32 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg9, i32 0, i32 0
%33 = bitcast [1 x %variant]* %varargslots10 to %variant*
store %variant* %33, %variant** %32, align 8
%34 = bitcast %"variant[]"* %vararg9 to { i8*, i64 }*
%35 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %34, i32 0, i32 0
%lo11 = load i8*, i8** %35, align 8
%36 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %34, i32 0, i32 1
%hi12 = load i64, i64* %36, align 8
%37 = call i64 @std_io_printfln(i64* %retparam5, i8* %lo7, i64 %hi8, i8* %lo11, i64 %hi12)
%not_err13 = icmp eq i64 %37, 0
br i1 %not_err13, label %after_check14, label %voiderr15
after_check14: ; preds = %voiderr
br label %voiderr15
voiderr15: ; preds = %after_check14, %voiderr
%38 = getelementptr inbounds %Foo, %Foo* %literal16, i32 0, i32 0
store i32 2, i32* %38, align 8
%39 = getelementptr inbounds %Foo, %Foo* %literal16, i32 0, i32 1
store i8* null, i8** %39, align 8
%40 = bitcast %Foo* %literal16 to { i64, i8* }*
%41 = getelementptr inbounds { i64, i8* }, { i64, i8* }* %40, i32 0, i32 0
%lo17 = load i64, i64* %41, align 8
%42 = getelementptr inbounds { i64, i8* }, { i64, i8* }* %40, i32 0, i32 1
%hi18 = load i8*, i8** %42, align 8
%43 = call i8 @"std_map$$int.test_Foo_HashMap_set"(%HashMap* %map, i32 1, i64 %lo17, i8* %hi18)
store %"char[]" { i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.2, i32 0, i32 0), i64 12 }, %"char[]"* %taddr20, align 8
%44 = bitcast %"char[]"* %taddr20 to { i8*, i64 }*
%45 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %44, i32 0, i32 0
%lo21 = load i8*, i8** %45, align 8
%46 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %44, i32 0, i32 1
%hi22 = load i64, i64* %46, align 8
%47 = getelementptr inbounds %HashMap, %HashMap* %map, i32 0, i32 2
%48 = bitcast i32* %47 to i8*
%49 = insertvalue %variant undef, i8* %48, 0
%50 = insertvalue %variant %49, i64 ptrtoint (%.introspect* @"ct$uint" to i64), 1
%51 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots24, i64 0, i64 0
store %variant %50, %variant* %51, align 16
%52 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg23, i32 0, i32 1
store i64 1, i64* %52, align 8
%53 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg23, i32 0, i32 0
%54 = bitcast [1 x %variant]* %varargslots24 to %variant*
store %variant* %54, %variant** %53, align 8
%55 = bitcast %"variant[]"* %vararg23 to { i8*, i64 }*
%56 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %55, i32 0, i32 0
%lo25 = load i8*, i8** %56, align 8
%57 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %55, i32 0, i32 1
%hi26 = load i64, i64* %57, align 8
%58 = call i64 @std_io_printfln(i64* %retparam19, i8* %lo21, i64 %hi22, i8* %lo25, i64 %hi26)
%not_err27 = icmp eq i64 %58, 0
br i1 %not_err27, label %after_check28, label %voiderr29
after_check28: ; preds = %voiderr15
br label %voiderr29
voiderr29: ; preds = %after_check28, %voiderr15
store %"char[]" { i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.3, i32 0, i32 0), i64 7 }, %"char[]"* %taddr31, align 8
%59 = bitcast %"char[]"* %taddr31 to { i8*, i64 }*
%60 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %59, i32 0, i32 0
%lo32 = load i8*, i8** %60, align 8
%61 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %59, i32 0, i32 1
%hi33 = load i64, i64* %61, align 8
%62 = call i64 @"std_map$$int.test_Foo_HashMap_get"(%Foo* %retparam36, %HashMap* %map, i32 1)
%not_err37 = icmp eq i64 %62, 0
br i1 %not_err37, label %after_check38, label %voiderr43
after_check38: ; preds = %voiderr29
%63 = getelementptr inbounds %Foo, %Foo* %retparam36, i32 0, i32 0
%64 = bitcast i32* %63 to i8*
%65 = insertvalue %variant undef, i8* %64, 0
%66 = insertvalue %variant %65, i64 ptrtoint (%.introspect* @"ct$int" to i64), 1
%67 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots35, i64 0, i64 0
store %variant %66, %variant* %67, align 16
%68 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg34, i32 0, i32 1
store i64 1, i64* %68, align 8
%69 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg34, i32 0, i32 0
%70 = bitcast [1 x %variant]* %varargslots35 to %variant*
store %variant* %70, %variant** %69, align 8
%71 = bitcast %"variant[]"* %vararg34 to { i8*, i64 }*
%72 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %71, i32 0, i32 0
%lo39 = load i8*, i8** %72, align 8
%73 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %71, i32 0, i32 1
%hi40 = load i64, i64* %73, align 8
%74 = call i64 @std_io_printfln(i64* %retparam30, i8* %lo32, i64 %hi33, i8* %lo39, i64 %hi40)
%not_err41 = icmp eq i64 %74, 0
br i1 %not_err41, label %after_check42, label %voiderr43
after_check42: ; preds = %after_check38
br label %voiderr43
voiderr43: ; preds = %after_check42, %after_check38, %voiderr29
store %"char[]" { i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.4, i32 0, i32 0), i64 9 }, %"char[]"* %taddr45, align 8
%75 = bitcast %"char[]"* %taddr45 to { i8*, i64 }*
%76 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %75, i32 0, i32 0
%lo46 = load i8*, i8** %76, align 8
%77 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %75, i32 0, i32 1
%hi47 = load i64, i64* %77, align 8
%78 = call i8 @"std_map$$int.test_Foo_HashMap_has_key"(%HashMap* %map, i32 1)
store i8 %78, i8* %taddr50, align 1
%79 = insertvalue %variant undef, i8* %taddr50, 0
%80 = insertvalue %variant %79, i64 ptrtoint (%.introspect* @"ct$bool" to i64), 1
%81 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots49, i64 0, i64 0
store %variant %80, %variant* %81, align 16
%82 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg48, i32 0, i32 1
store i64 1, i64* %82, align 8
%83 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg48, i32 0, i32 0
%84 = bitcast [1 x %variant]* %varargslots49 to %variant*
store %variant* %84, %variant** %83, align 8
%85 = bitcast %"variant[]"* %vararg48 to { i8*, i64 }*
%86 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %85, i32 0, i32 0
%lo51 = load i8*, i8** %86, align 8
%87 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %85, i32 0, i32 1
%hi52 = load i64, i64* %87, align 8
%88 = call i64 @std_io_printfln(i64* %retparam44, i8* %lo46, i64 %hi47, i8* %lo51, i64 %hi52)
%not_err53 = icmp eq i64 %88, 0
br i1 %not_err53, label %after_check54, label %voiderr55
after_check54: ; preds = %voiderr43
br label %voiderr55
voiderr55: ; preds = %after_check54, %voiderr43
store %"char[]" { i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.5, i32 0, i32 0), i64 9 }, %"char[]"* %taddr57, align 8
%89 = bitcast %"char[]"* %taddr57 to { i8*, i64 }*
%90 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %89, i32 0, i32 0
%lo58 = load i8*, i8** %90, align 8
%91 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %89, i32 0, i32 1
%hi59 = load i64, i64* %91, align 8
%92 = call i8 @"std_map$$int.test_Foo_HashMap_has_key"(%HashMap* %map, i32 2)
store i8 %92, i8* %taddr62, align 1
%93 = insertvalue %variant undef, i8* %taddr62, 0
%94 = insertvalue %variant %93, i64 ptrtoint (%.introspect* @"ct$bool" to i64), 1
%95 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots61, i64 0, i64 0
store %variant %94, %variant* %95, align 16
%96 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg60, i32 0, i32 1
store i64 1, i64* %96, align 8
%97 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg60, i32 0, i32 0
%98 = bitcast [1 x %variant]* %varargslots61 to %variant*
store %variant* %98, %variant** %97, align 8
%99 = bitcast %"variant[]"* %vararg60 to { i8*, i64 }*
%100 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %99, i32 0, i32 0
%lo63 = load i8*, i8** %100, align 8
%101 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %99, i32 0, i32 1
%hi64 = load i64, i64* %101, align 8
%102 = call i64 @std_io_printfln(i64* %retparam56, i8* %lo58, i64 %hi59, i8* %lo63, i64 %hi64)
%not_err65 = icmp eq i64 %102, 0
br i1 %not_err65, label %after_check66, label %voiderr67
after_check66: ; preds = %voiderr55
br label %voiderr67
voiderr67: ; preds = %after_check66, %voiderr55
%103 = getelementptr inbounds %Foo, %Foo* %literal68, i32 0, i32 0
store i32 4, i32* %103, align 8
%104 = getelementptr inbounds %Foo, %Foo* %literal68, i32 0, i32 1
store i8* null, i8** %104, align 8
%105 = bitcast %Foo* %literal68 to { i64, i8* }*
%106 = getelementptr inbounds { i64, i8* }, { i64, i8* }* %105, i32 0, i32 0
%lo69 = load i64, i64* %106, align 8
%107 = getelementptr inbounds { i64, i8* }, { i64, i8* }* %105, i32 0, i32 1
%hi70 = load i8*, i8** %107, align 8
%108 = call i8 @"std_map$$int.test_Foo_HashMap_set"(%HashMap* %map, i32 7, i64 %lo69, i8* %hi70)
store %"char[]" { i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.6, i32 0, i32 0), i64 10 }, %"char[]"* %taddr72, align 8
%109 = bitcast %"char[]"* %taddr72 to { i8*, i64 }*
%110 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %109, i32 0, i32 0
%lo73 = load i8*, i8** %110, align 8
%111 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %109, i32 0, i32 1
%hi74 = load i64, i64* %111, align 8
%112 = call { i8*, i64 } @"std_map$$int.test_Foo_HashMap_value_list"(%HashMap* %map, %Allocator* null)
%113 = bitcast %"Foo[]"* %result to { i8*, i64 }*
store { i8*, i64 } %112, { i8*, i64 }* %113, align 8
%114 = bitcast %"Foo[]"* %result to i8*
%115 = insertvalue %variant undef, i8* %114, 0
%116 = insertvalue %variant %115, i64 ptrtoint (%.introspect* @"ct$sa$test_Foo" to i64), 1
%117 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots76, i64 0, i64 0
store %variant %116, %variant* %117, align 16
%118 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg75, i32 0, i32 1
store i64 1, i64* %118, align 8
%119 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg75, i32 0, i32 0
%120 = bitcast [1 x %variant]* %varargslots76 to %variant*
store %variant* %120, %variant** %119, align 8
%121 = bitcast %"variant[]"* %vararg75 to { i8*, i64 }*
%122 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %121, i32 0, i32 0
%lo77 = load i8*, i8** %122, align 8
%123 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %121, i32 0, i32 1
%hi78 = load i64, i64* %123, align 8
%124 = call i64 @std_io_printfln(i64* %retparam71, i8* %lo73, i64 %hi74, i8* %lo77, i64 %hi78)
%not_err79 = icmp eq i64 %124, 0
br i1 %not_err79, label %after_check80, label %voiderr81
after_check80: ; preds = %voiderr67
br label %voiderr81
voiderr81: ; preds = %after_check80, %voiderr67
%125 = bitcast %HashMap.0* %map2 to i8*
call void @llvm.memset.p0i8.i64(i8* align 8 %125, i8 0, i64 40, i1 false)
%126 = load %Allocator*, %Allocator** @std_core_mem_thread_allocator, align 8
call void @"std_map$$int.double_HashMap_init"(%HashMap.0* %map2, i32 16, float 7.500000e-01, %Allocator* %126)
%127 = call i8 @"std_map$$int.double_HashMap_set"(%HashMap.0* %map2, i32 4, double 1.300000e+00)
store %"char[]" { i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.7, i32 0, i32 0), i64 12 }, %"char[]"* %taddr83, align 8
%128 = bitcast %"char[]"* %taddr83 to { i8*, i64 }*
%129 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %128, i32 0, i32 0
%lo84 = load i8*, i8** %129, align 8
%130 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %128, i32 0, i32 1
%hi85 = load i64, i64* %130, align 8
%131 = call i8 @"std_map$$int.double_HashMap_has_value"(%HashMap.0* %map2, double 1.300000e+00)
store i8 %131, i8* %taddr88, align 1
%132 = insertvalue %variant undef, i8* %taddr88, 0
%133 = insertvalue %variant %132, i64 ptrtoint (%.introspect* @"ct$bool" to i64), 1
%134 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots87, i64 0, i64 0
store %variant %133, %variant* %134, align 16
%135 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg86, i32 0, i32 1
store i64 1, i64* %135, align 8
%136 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg86, i32 0, i32 0
%137 = bitcast [1 x %variant]* %varargslots87 to %variant*
store %variant* %137, %variant** %136, align 8
%138 = bitcast %"variant[]"* %vararg86 to { i8*, i64 }*
%139 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %138, i32 0, i32 0
%lo89 = load i8*, i8** %139, align 8
%140 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %138, i32 0, i32 1
%hi90 = load i64, i64* %140, align 8
%141 = call i64 @std_io_printfln(i64* %retparam82, i8* %lo84, i64 %hi85, i8* %lo89, i64 %hi90)
%not_err91 = icmp eq i64 %141, 0
br i1 %not_err91, label %after_check92, label %voiderr93
after_check92: ; preds = %voiderr81
br label %voiderr93
voiderr93: ; preds = %after_check92, %voiderr81
store %"char[]" { i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.8, i32 0, i32 0), i64 12 }, %"char[]"* %taddr95, align 8
%142 = bitcast %"char[]"* %taddr95 to { i8*, i64 }*
%143 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %142, i32 0, i32 0
%lo96 = load i8*, i8** %143, align 8
%144 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %142, i32 0, i32 1
%hi97 = load i64, i64* %144, align 8
%145 = call i8 @"std_map$$int.double_HashMap_has_value"(%HashMap.0* %map2, double 1.200000e+00)
store i8 %145, i8* %taddr100, align 1
%146 = insertvalue %variant undef, i8* %taddr100, 0
%147 = insertvalue %variant %146, i64 ptrtoint (%.introspect* @"ct$bool" to i64), 1
%148 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots99, i64 0, i64 0
store %variant %147, %variant* %148, align 16
%149 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg98, i32 0, i32 1
store i64 1, i64* %149, align 8
%150 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg98, i32 0, i32 0
%151 = bitcast [1 x %variant]* %varargslots99 to %variant*
store %variant* %151, %variant** %150, align 8
%152 = bitcast %"variant[]"* %vararg98 to { i8*, i64 }*
%153 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %152, i32 0, i32 0
%lo101 = load i8*, i8** %153, align 8
%154 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %152, i32 0, i32 1
%hi102 = load i64, i64* %154, align 8
%155 = call i64 @std_io_printfln(i64* %retparam94, i8* %lo96, i64 %hi97, i8* %lo101, i64 %hi102)
%not_err103 = icmp eq i64 %155, 0
br i1 %not_err103, label %after_check104, label %voiderr105
after_check104: ; preds = %voiderr93
br label %voiderr105
voiderr105: ; preds = %after_check104, %voiderr93
%156 = call i8 @"std_map$$int.double_HashMap_set"(%HashMap.0* %map2, i32 100, double 3.400000e+00)
store %"char[]" { i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.9, i32 0, i32 0), i64 2 }, %"char[]"* %taddr107, align 8
%157 = bitcast %"char[]"* %taddr107 to { i8*, i64 }*
%158 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %157, i32 0, i32 0
%lo108 = load i8*, i8** %158, align 8
%159 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %157, i32 0, i32 1
%hi109 = load i64, i64* %159, align 8
%160 = call { i8*, i64 } @"std_map$$int.double_HashMap_key_list"(%HashMap.0* %map2, %Allocator* null)
%161 = bitcast %"int[]"* %result112 to { i8*, i64 }*
store { i8*, i64 } %160, { i8*, i64 }* %161, align 8
%162 = bitcast %"int[]"* %result112 to i8*
%163 = insertvalue %variant undef, i8* %162, 0
%164 = insertvalue %variant %163, i64 ptrtoint (%.introspect* @"ct$sa$int" to i64), 1
%165 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots111, i64 0, i64 0
store %variant %164, %variant* %165, align 16
%166 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg110, i32 0, i32 1
store i64 1, i64* %166, align 8
%167 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg110, i32 0, i32 0
%168 = bitcast [1 x %variant]* %varargslots111 to %variant*
store %variant* %168, %variant** %167, align 8
%169 = bitcast %"variant[]"* %vararg110 to { i8*, i64 }*
%170 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %169, i32 0, i32 0
%lo113 = load i8*, i8** %170, align 8
%171 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %169, i32 0, i32 1
%hi114 = load i64, i64* %171, align 8
%172 = call i64 @std_io_printfln(i64* %retparam106, i8* %lo108, i64 %hi109, i8* %lo113, i64 %hi114)
%not_err115 = icmp eq i64 %172, 0
br i1 %not_err115, label %after_check116, label %voiderr117
after_check116: ; preds = %voiderr105
br label %voiderr117
voiderr117: ; preds = %after_check116, %voiderr105
store %"char[]" { i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.10, i32 0, i32 0), i64 2 }, %"char[]"* %taddr119, align 8
%173 = bitcast %"char[]"* %taddr119 to { i8*, i64 }*
%174 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %173, i32 0, i32 0
%lo120 = load i8*, i8** %174, align 8
%175 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %173, i32 0, i32 1
%hi121 = load i64, i64* %175, align 8
%176 = call { i8*, i64 } @"std_map$$int.double_HashMap_value_list"(%HashMap.0* %map2, %Allocator* null)
%177 = bitcast %"double[]"* %result124 to { i8*, i64 }*
store { i8*, i64 } %176, { i8*, i64 }* %177, align 8
%178 = bitcast %"double[]"* %result124 to i8*
%179 = insertvalue %variant undef, i8* %178, 0
%180 = insertvalue %variant %179, i64 ptrtoint (%.introspect* @"ct$sa$double" to i64), 1
%181 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots123, i64 0, i64 0
store %variant %180, %variant* %181, align 16
%182 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg122, i32 0, i32 1
store i64 1, i64* %182, align 8
%183 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg122, i32 0, i32 0
%184 = bitcast [1 x %variant]* %varargslots123 to %variant*
store %variant* %184, %variant** %183, align 8
%185 = bitcast %"variant[]"* %vararg122 to { i8*, i64 }*
%186 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %185, i32 0, i32 0
%lo125 = load i8*, i8** %186, align 8
%187 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %185, i32 0, i32 1
%hi126 = load i64, i64* %187, align 8
%188 = call i64 @std_io_printfln(i64* %retparam118, i8* %lo120, i64 %hi121, i8* %lo125, i64 %hi126)
%not_err127 = icmp eq i64 %188, 0
br i1 %not_err127, label %after_check128, label %voiderr129
after_check128: ; preds = %voiderr117
br label %voiderr129
voiderr129: ; preds = %after_check128, %voiderr117
%189 = load %TempAllocator*, %TempAllocator** @std_core_mem_thread_temp_allocator, align 8
%not = icmp eq %TempAllocator* %189, null
br i1 %not, label %if.then, label %if.exit
if.then: ; preds = %voiderr129
%190 = call i64 @std_core_mem_allocator_new_temp(%TempAllocator** %retparam130, i64 131072, %Allocator* @std_core_mem_allocator__SYSTEM_ALLOCATOR)
%not_err131 = icmp eq i64 %190, 0
br i1 %not_err131, label %after_check132, label %assign_optional
assign_optional: ; preds = %if.then
store i64 %190, i64* %error_var, align 8
br label %panic_block
after_check132: ; preds = %if.then
%191 = load %TempAllocator*, %TempAllocator** %retparam130, align 8
br label %noerr_block
panic_block: ; preds = %assign_optional
call void @std_core_builtin_panic(i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.zstr, i64 0, i64 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.zstr.11, i64 0, i64 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.zstr.12, i64 0, i64 0), i32 250)
unreachable
noerr_block: ; preds = %after_check132
store %TempAllocator* %191, %TempAllocator** @std_core_mem_thread_temp_allocator, align 8
br label %if.exit
if.exit: ; preds = %noerr_block, %voiderr129
%192 = load %TempAllocator*, %TempAllocator** @std_core_mem_thread_temp_allocator, align 8
store %TempAllocator* %192, %TempAllocator** %temp, align 8
%193 = load %TempAllocator*, %TempAllocator** %temp, align 8
%194 = getelementptr inbounds %TempAllocator, %TempAllocator* %193, i32 0, i32 3
%195 = load i64, i64* %194, align 8
store i64 %195, i64* %mark, align 8
%196 = bitcast %HashMap.0* %map3 to i8*
call void @llvm.memset.p0i8.i64(i8* align 8 %196, i8 0, i64 40, i1 false)
%197 = load %TempAllocator*, %TempAllocator** @std_core_mem_thread_temp_allocator, align 8
%not133 = icmp eq %TempAllocator* %197, null
br i1 %not133, label %if.then134, label %if.exit142
if.then134: ; preds = %if.exit
%198 = call i64 @std_core_mem_allocator_new_temp(%TempAllocator** %retparam136, i64 131072, %Allocator* @std_core_mem_allocator__SYSTEM_ALLOCATOR)
%not_err137 = icmp eq i64 %198, 0
br i1 %not_err137, label %after_check139, label %assign_optional138
assign_optional138: ; preds = %if.then134
store i64 %198, i64* %error_var135, align 8
br label %panic_block140
after_check139: ; preds = %if.then134
%199 = load %TempAllocator*, %TempAllocator** %retparam136, align 8
br label %noerr_block141
panic_block140: ; preds = %assign_optional138
call void @std_core_builtin_panic(i8* getelementptr inbounds ([28 x i8], [28 x i8]* @.zstr.13, i64 0, i64 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.zstr.14, i64 0, i64 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.zstr.15, i64 0, i64 0), i32 250)
unreachable
noerr_block141: ; preds = %after_check139
store %TempAllocator* %199, %TempAllocator** @std_core_mem_thread_temp_allocator, align 8
br label %if.exit142
if.exit142: ; preds = %noerr_block141, %if.exit
%200 = load %TempAllocator*, %TempAllocator** @std_core_mem_thread_temp_allocator, align 8
%ptrptr = bitcast %TempAllocator* %200 to %Allocator*
call void @"std_map$$int.double_HashMap_init"(%HashMap.0* %map3, i32 16, float 7.500000e-01, %Allocator* %ptrptr)
%201 = call i8 @"std_map$$int.double_HashMap_set"(%HashMap.0* %map3, i32 5, double 3.200000e+00)
%202 = call i8 @"std_map$$int.double_HashMap_set"(%HashMap.0* %map3, i32 7, double 5.200000e+00)
store %"char[]" { i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.16, i32 0, i32 0), i64 2 }, %"char[]"* %taddr144, align 8
%203 = bitcast %"char[]"* %taddr144 to { i8*, i64 }*
%204 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %203, i32 0, i32 0
%lo145 = load i8*, i8** %204, align 8
%205 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %203, i32 0, i32 1
%hi146 = load i64, i64* %205, align 8
%206 = call { i8*, i64 } @"std_map$$int.double_HashMap_key_tlist"(%HashMap.0* %map3)
%207 = bitcast %"int[]"* %result149 to { i8*, i64 }*
store { i8*, i64 } %206, { i8*, i64 }* %207, align 8
%208 = bitcast %"int[]"* %result149 to i8*
%209 = insertvalue %variant undef, i8* %208, 0
%210 = insertvalue %variant %209, i64 ptrtoint (%.introspect* @"ct$sa$int" to i64), 1
%211 = getelementptr inbounds [1 x %variant], [1 x %variant]* %varargslots148, i64 0, i64 0
store %variant %210, %variant* %211, align 16
%212 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg147, i32 0, i32 1
store i64 1, i64* %212, align 8
%213 = getelementptr inbounds %"variant[]", %"variant[]"* %vararg147, i32 0, i32 0
%214 = bitcast [1 x %variant]* %varargslots148 to %variant*
store %variant* %214, %variant** %213, align 8
%215 = bitcast %"variant[]"* %vararg147 to { i8*, i64 }*
%216 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %215, i32 0, i32 0
%lo150 = load i8*, i8** %216, align 8
%217 = getelementptr inbounds { i8*, i64 }, { i8*, i64 }* %215, i32 0, i32 1
%hi151 = load i64, i64* %217, align 8
%218 = call i64 @std_io_printfln(i64* %retparam143, i8* %lo145, i64 %hi146, i8* %lo150, i64 %hi151)
%not_err152 = icmp eq i64 %218, 0
br i1 %not_err152, label %after_check153, label %voiderr154
after_check153: ; preds = %if.exit142
br label %voiderr154
voiderr154: ; preds = %after_check153, %if.exit142
%219 = load %TempAllocator*, %TempAllocator** %temp, align 8
%220 = getelementptr inbounds %TempAllocator, %TempAllocator* %219, i32 0, i32 0
%221 = load i64, i64* %mark, align 8
call void @std_core_mem_allocator_Allocator_reset(%Allocator* %220, i64 %221)
ret void
}

View File

@@ -0,0 +1,7 @@
module test;
static initialize
{
int a;
a = 1;
}

View File

@@ -0,0 +1,617 @@
// #target: macos-x64
module test;
import std::io;
import std::map;
struct Foo { int x; void* bar; }
define IntFooMap = std::map::HashMap<int, Foo>;
define IntDoubleMap = std::map::HashMap<int, double>;
fn char[] Foo.to_string(Foo* foo, Allocator* allocator = mem::current_allocator())
{
String s = string::new_with_capacity(128, allocator);
s.printf("{%s, %p}", foo.x, foo.bar);
return s.str();
}
static initialize
{
io::printf_register_to_string(Foo);
}
fn void main()
{
IntFooMap map;
map.init();
io::printfln("Map size: %d", map.count);
map.set(1, Foo { 1, null });
io::printfln("Map size: %d", map.count);
map.set(1, Foo { 2, null });
io::printfln("Map size: %d", map.count);
io::printfln("Val: %d", map.get(1).x);
io::printfln("Has 1: %s", map.has_key(1));
io::printfln("Has 2: %s", map.has_key(2));
map.set(7, Foo { 4, null });
io::printfln("Values: %s", map.value_list());
IntDoubleMap map2;
map2.init();
map2.set(4, 1.3);
io::printfln("Map find: %s", map2.has_value(1.3));
io::printfln("Map find: %s", map2.has_value(1.2));
map2.set(100, 3.4);
io::printfln("%s", map2.key_list());
io::printfln("%s", map2.value_list());
@pool()
{
IntDoubleMap map3;
map3.init(.allocator = mem::temp_allocator());
map3.set(5, 3.2);
map3.set(7, 5.2);
io::printfln("%s", map3.key_tlist());
};
}
/* #expect: test.ll
@llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 65535, ptr @.static_initialize.0, ptr null }]
define void @.static_initialize.0() {
entry:
call void @std_io_printf_register(i64 ptrtoint (ptr @"ct$test_Foo" to i64), ptr @test_Foo_to_string)
ret void
}
define { ptr, i64 } @test_Foo_to_string(ptr %0, ptr %1) #0 {
entry:
%s = alloca ptr, align 8
%retparam = alloca i64, align 8
%taddr = alloca %"char[]", align 8
%vararg = alloca %"variant[]", align 8
%varargslots = alloca [2 x %variant], align 16
%result = alloca %"char[]", align 8
%tempcoerce = alloca { ptr, i64 }, align 8
%2 = call ptr @std_core_string_new_with_capacity(i64 128, ptr %1)
store ptr %2, ptr %s, align 8
store %"char[]" { ptr @.str.17, i64 8 }, ptr %taddr, align 8
%3 = getelementptr inbounds { ptr, i64 }, ptr %taddr, i32 0, i32 0
%lo = load ptr, ptr %3, align 8
%4 = getelementptr inbounds { ptr, i64 }, ptr %taddr, i32 0, i32 1
%hi = load i64, ptr %4, align 8
%5 = getelementptr inbounds %Foo, ptr %0, i32 0, i32 0
%6 = insertvalue %variant undef, ptr %5, 0
%7 = insertvalue %variant %6, i64 ptrtoint (ptr @"ct$int" to i64), 1
%8 = getelementptr inbounds [2 x %variant], ptr %varargslots, i64 0, i64 0
store %variant %7, ptr %8, align 16
%9 = getelementptr inbounds %Foo, ptr %0, i32 0, i32 1
%10 = insertvalue %variant undef, ptr %9, 0
%11 = insertvalue %variant %10, i64 ptrtoint (ptr @"ct$p$void" to i64), 1
%12 = getelementptr inbounds [2 x %variant], ptr %varargslots, i64 0, i64 1
store %variant %11, ptr %12, align 16
%13 = getelementptr inbounds %"variant[]", ptr %vararg, i32 0, i32 1
store i64 2, ptr %13, align 8
%14 = getelementptr inbounds %"variant[]", ptr %vararg, i32 0, i32 0
store ptr %varargslots, ptr %14, align 8
%15 = getelementptr inbounds { ptr, i64 }, ptr %vararg, i32 0, i32 0
%lo1 = load ptr, ptr %15, align 8
%16 = getelementptr inbounds { ptr, i64 }, ptr %vararg, i32 0, i32 1
%hi2 = load i64, ptr %16, align 8
%17 = call i64 @std_core_string_String_printf(ptr %retparam, ptr %s, ptr %lo, i64 %hi, ptr %lo1, i64 %hi2)
%not_err = icmp eq i64 %17, 0
br i1 %not_err, label %after_check, label %voiderr
after_check: ; preds = %entry
br label %voiderr
voiderr: ; preds = %after_check, %entry
%18 = load ptr, ptr %s, align 8
%19 = call { ptr, i64 } @std_core_string_String_str(ptr %18)
store { ptr, i64 } %19, ptr %result, align 8
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %tempcoerce, ptr align 8 %result, i32 16, i1 false)
%20 = load { ptr, i64 }, ptr %tempcoerce, align 8
ret { ptr, i64 } %20
}
; Function Attrs: nounwind
define void @test_main() #0 {
entry:
%map = alloca %HashMap, align 8
%retparam = alloca i64, align 8
%taddr = alloca %"char[]", align 8
%vararg = alloca %"variant[]", align 8
%varargslots = alloca [1 x %variant], align 16
%literal = alloca %Foo, align 8
%retparam5 = alloca i64, align 8
%taddr6 = alloca %"char[]", align 8
%vararg9 = alloca %"variant[]", align 8
%varargslots10 = alloca [1 x %variant], align 16
%literal16 = alloca %Foo, align 8
%retparam19 = alloca i64, align 8
%taddr20 = alloca %"char[]", align 8
%vararg23 = alloca %"variant[]", align 8
%varargslots24 = alloca [1 x %variant], align 16
%retparam30 = alloca i64, align 8
%taddr31 = alloca %"char[]", align 8
%vararg34 = alloca %"variant[]", align 8
%varargslots35 = alloca [1 x %variant], align 16
%retparam36 = alloca %Foo, align 8
%retparam44 = alloca i64, align 8
%taddr45 = alloca %"char[]", align 8
%vararg48 = alloca %"variant[]", align 8
%varargslots49 = alloca [1 x %variant], align 16
%taddr50 = alloca i8, align 1
%retparam56 = alloca i64, align 8
%taddr57 = alloca %"char[]", align 8
%vararg60 = alloca %"variant[]", align 8
%varargslots61 = alloca [1 x %variant], align 16
%taddr62 = alloca i8, align 1
%literal68 = alloca %Foo, align 8
%retparam71 = alloca i64, align 8
%taddr72 = alloca %"char[]", align 8
%vararg75 = alloca %"variant[]", align 8
%varargslots76 = alloca [1 x %variant], align 16
%result = alloca %"Foo[]", align 8
%map2 = alloca %HashMap.0, align 8
%retparam82 = alloca i64, align 8
%taddr83 = alloca %"char[]", align 8
%vararg86 = alloca %"variant[]", align 8
%varargslots87 = alloca [1 x %variant], align 16
%taddr88 = alloca i8, align 1
%retparam94 = alloca i64, align 8
%taddr95 = alloca %"char[]", align 8
%vararg98 = alloca %"variant[]", align 8
%varargslots99 = alloca [1 x %variant], align 16
%taddr100 = alloca i8, align 1
%retparam106 = alloca i64, align 8
%taddr107 = alloca %"char[]", align 8
%vararg110 = alloca %"variant[]", align 8
%varargslots111 = alloca [1 x %variant], align 16
%result112 = alloca %"int[]", align 8
%retparam118 = alloca i64, align 8
%taddr119 = alloca %"char[]", align 8
%vararg122 = alloca %"variant[]", align 8
%varargslots123 = alloca [1 x %variant], align 16
%result124 = alloca %"double[]", align 8
%temp = alloca ptr, align 8
%error_var = alloca i64, align 8
%retparam130 = alloca ptr, align 8
%mark = alloca i64, align 8
%map3 = alloca %HashMap.0, align 8
%error_var135 = alloca i64, align 8
%retparam136 = alloca ptr, align 8
%retparam143 = alloca i64, align 8
%taddr144 = alloca %"char[]", align 8
%vararg147 = alloca %"variant[]", align 8
%varargslots148 = alloca [1 x %variant], align 16
%result149 = alloca %"int[]", align 8
call void @llvm.memset.p0.i64(ptr align 8 %map, i8 0, i64 40, i1 false)
%0 = load ptr, ptr @std_core_mem_thread_allocator, align 8
call void @"std_map$$int.test_Foo_HashMap_init"(ptr %map, i32 16, float 7.500000e-01, ptr %0)
store %"char[]" { ptr @.str, i64 12 }, ptr %taddr, align 8
%1 = getelementptr inbounds { ptr, i64 }, ptr %taddr, i32 0, i32 0
%lo = load ptr, ptr %1, align 8
%2 = getelementptr inbounds { ptr, i64 }, ptr %taddr, i32 0, i32 1
%hi = load i64, ptr %2, align 8
%3 = getelementptr inbounds %HashMap, ptr %map, i32 0, i32 2
%4 = insertvalue %variant undef, ptr %3, 0
%5 = insertvalue %variant %4, i64 ptrtoint (ptr @"ct$uint" to i64), 1
%6 = getelementptr inbounds [1 x %variant], ptr %varargslots, i64 0, i64 0
store %variant %5, ptr %6, align 16
%7 = getelementptr inbounds %"variant[]", ptr %vararg, i32 0, i32 1
store i64 1, ptr %7, align 8
%8 = getelementptr inbounds %"variant[]", ptr %vararg, i32 0, i32 0
store ptr %varargslots, ptr %8, align 8
%9 = getelementptr inbounds { ptr, i64 }, ptr %vararg, i32 0, i32 0
%lo1 = load ptr, ptr %9, align 8
%10 = getelementptr inbounds { ptr, i64 }, ptr %vararg, i32 0, i32 1
%hi2 = load i64, ptr %10, align 8
%11 = call i64 @std_io_printfln(ptr %retparam, ptr %lo, i64 %hi, ptr %lo1, i64 %hi2)
%not_err = icmp eq i64 %11, 0
br i1 %not_err, label %after_check, label %voiderr
after_check: ; preds = %entry
br label %voiderr
voiderr: ; preds = %after_check, %entry
%12 = getelementptr inbounds %Foo, ptr %literal, i32 0, i32 0
store i32 1, ptr %12, align 8
%13 = getelementptr inbounds %Foo, ptr %literal, i32 0, i32 1
store ptr null, ptr %13, align 8
%14 = getelementptr inbounds { i64, ptr }, ptr %literal, i32 0, i32 0
%lo3 = load i64, ptr %14, align 8
%15 = getelementptr inbounds { i64, ptr }, ptr %literal, i32 0, i32 1
%hi4 = load ptr, ptr %15, align 8
%16 = call i8 @"std_map$$int.test_Foo_HashMap_set"(ptr %map, i32 1, i64 %lo3, ptr %hi4)
store %"char[]" { ptr @.str.1, i64 12 }, ptr %taddr6, align 8
%17 = getelementptr inbounds { ptr, i64 }, ptr %taddr6, i32 0, i32 0
%lo7 = load ptr, ptr %17, align 8
%18 = getelementptr inbounds { ptr, i64 }, ptr %taddr6, i32 0, i32 1
%hi8 = load i64, ptr %18, align 8
%19 = getelementptr inbounds %HashMap, ptr %map, i32 0, i32 2
%20 = insertvalue %variant undef, ptr %19, 0
%21 = insertvalue %variant %20, i64 ptrtoint (ptr @"ct$uint" to i64), 1
%22 = getelementptr inbounds [1 x %variant], ptr %varargslots10, i64 0, i64 0
store %variant %21, ptr %22, align 16
%23 = getelementptr inbounds %"variant[]", ptr %vararg9, i32 0, i32 1
store i64 1, ptr %23, align 8
%24 = getelementptr inbounds %"variant[]", ptr %vararg9, i32 0, i32 0
store ptr %varargslots10, ptr %24, align 8
%25 = getelementptr inbounds { ptr, i64 }, ptr %vararg9, i32 0, i32 0
%lo11 = load ptr, ptr %25, align 8
%26 = getelementptr inbounds { ptr, i64 }, ptr %vararg9, i32 0, i32 1
%hi12 = load i64, ptr %26, align 8
%27 = call i64 @std_io_printfln(ptr %retparam5, ptr %lo7, i64 %hi8, ptr %lo11, i64 %hi12)
%not_err13 = icmp eq i64 %27, 0
br i1 %not_err13, label %after_check14, label %voiderr15
after_check14: ; preds = %voiderr
br label %voiderr15
voiderr15: ; preds = %after_check14, %voiderr
%28 = getelementptr inbounds %Foo, ptr %literal16, i32 0, i32 0
store i32 2, ptr %28, align 8
%29 = getelementptr inbounds %Foo, ptr %literal16, i32 0, i32 1
store ptr null, ptr %29, align 8
%30 = getelementptr inbounds { i64, ptr }, ptr %literal16, i32 0, i32 0
%lo17 = load i64, ptr %30, align 8
%31 = getelementptr inbounds { i64, ptr }, ptr %literal16, i32 0, i32 1
%hi18 = load ptr, ptr %31, align 8
%32 = call i8 @"std_map$$int.test_Foo_HashMap_set"(ptr %map, i32 1, i64 %lo17, ptr %hi18)
store %"char[]" { ptr @.str.2, i64 12 }, ptr %taddr20, align 8
%33 = getelementptr inbounds { ptr, i64 }, ptr %taddr20, i32 0, i32 0
%lo21 = load ptr, ptr %33, align 8
%34 = getelementptr inbounds { ptr, i64 }, ptr %taddr20, i32 0, i32 1
%hi22 = load i64, ptr %34, align 8
%35 = getelementptr inbounds %HashMap, ptr %map, i32 0, i32 2
%36 = insertvalue %variant undef, ptr %35, 0
%37 = insertvalue %variant %36, i64 ptrtoint (ptr @"ct$uint" to i64), 1
%38 = getelementptr inbounds [1 x %variant], ptr %varargslots24, i64 0, i64 0
store %variant %37, ptr %38, align 16
%39 = getelementptr inbounds %"variant[]", ptr %vararg23, i32 0, i32 1
store i64 1, ptr %39, align 8
%40 = getelementptr inbounds %"variant[]", ptr %vararg23, i32 0, i32 0
store ptr %varargslots24, ptr %40, align 8
%41 = getelementptr inbounds { ptr, i64 }, ptr %vararg23, i32 0, i32 0
%lo25 = load ptr, ptr %41, align 8
%42 = getelementptr inbounds { ptr, i64 }, ptr %vararg23, i32 0, i32 1
%hi26 = load i64, ptr %42, align 8
%43 = call i64 @std_io_printfln(ptr %retparam19, ptr %lo21, i64 %hi22, ptr %lo25, i64 %hi26)
%not_err27 = icmp eq i64 %43, 0
br i1 %not_err27, label %after_check28, label %voiderr29
after_check28: ; preds = %voiderr15
br label %voiderr29
voiderr29: ; preds = %after_check28, %voiderr15
store %"char[]" { ptr @.str.3, i64 7 }, ptr %taddr31, align 8
%44 = getelementptr inbounds { ptr, i64 }, ptr %taddr31, i32 0, i32 0
%lo32 = load ptr, ptr %44, align 8
%45 = getelementptr inbounds { ptr, i64 }, ptr %taddr31, i32 0, i32 1
%hi33 = load i64, ptr %45, align 8
%46 = call i64 @"std_map$$int.test_Foo_HashMap_get"(ptr %retparam36, ptr %map, i32 1)
%not_err37 = icmp eq i64 %46, 0
br i1 %not_err37, label %after_check38, label %voiderr43
after_check38: ; preds = %voiderr29
%47 = getelementptr inbounds %Foo, ptr %retparam36, i32 0, i32 0
%48 = insertvalue %variant undef, ptr %47, 0
%49 = insertvalue %variant %48, i64 ptrtoint (ptr @"ct$int" to i64), 1
%50 = getelementptr inbounds [1 x %variant], ptr %varargslots35, i64 0, i64 0
store %variant %49, ptr %50, align 16
%51 = getelementptr inbounds %"variant[]", ptr %vararg34, i32 0, i32 1
store i64 1, ptr %51, align 8
%52 = getelementptr inbounds %"variant[]", ptr %vararg34, i32 0, i32 0
store ptr %varargslots35, ptr %52, align 8
%53 = getelementptr inbounds { ptr, i64 }, ptr %vararg34, i32 0, i32 0
%lo39 = load ptr, ptr %53, align 8
%54 = getelementptr inbounds { ptr, i64 }, ptr %vararg34, i32 0, i32 1
%hi40 = load i64, ptr %54, align 8
%55 = call i64 @std_io_printfln(ptr %retparam30, ptr %lo32, i64 %hi33, ptr %lo39, i64 %hi40)
%not_err41 = icmp eq i64 %55, 0
br i1 %not_err41, label %after_check42, label %voiderr43
after_check42: ; preds = %after_check38
br label %voiderr43
voiderr43: ; preds = %after_check42, %after_check38, %voiderr29
store %"char[]" { ptr @.str.4, i64 9 }, ptr %taddr45, align 8
%56 = getelementptr inbounds { ptr, i64 }, ptr %taddr45, i32 0, i32 0
%lo46 = load ptr, ptr %56, align 8
%57 = getelementptr inbounds { ptr, i64 }, ptr %taddr45, i32 0, i32 1
%hi47 = load i64, ptr %57, align 8
%58 = call i8 @"std_map$$int.test_Foo_HashMap_has_key"(ptr %map, i32 1)
store i8 %58, ptr %taddr50, align 1
%59 = insertvalue %variant undef, ptr %taddr50, 0
%60 = insertvalue %variant %59, i64 ptrtoint (ptr @"ct$bool" to i64), 1
%61 = getelementptr inbounds [1 x %variant], ptr %varargslots49, i64 0, i64 0
store %variant %60, ptr %61, align 16
%62 = getelementptr inbounds %"variant[]", ptr %vararg48, i32 0, i32 1
store i64 1, ptr %62, align 8
%63 = getelementptr inbounds %"variant[]", ptr %vararg48, i32 0, i32 0
store ptr %varargslots49, ptr %63, align 8
%64 = getelementptr inbounds { ptr, i64 }, ptr %vararg48, i32 0, i32 0
%lo51 = load ptr, ptr %64, align 8
%65 = getelementptr inbounds { ptr, i64 }, ptr %vararg48, i32 0, i32 1
%hi52 = load i64, ptr %65, align 8
%66 = call i64 @std_io_printfln(ptr %retparam44, ptr %lo46, i64 %hi47, ptr %lo51, i64 %hi52)
%not_err53 = icmp eq i64 %66, 0
br i1 %not_err53, label %after_check54, label %voiderr55
after_check54: ; preds = %voiderr43
br label %voiderr55
voiderr55: ; preds = %after_check54, %voiderr43
store %"char[]" { ptr @.str.5, i64 9 }, ptr %taddr57, align 8
%67 = getelementptr inbounds { ptr, i64 }, ptr %taddr57, i32 0, i32 0
%lo58 = load ptr, ptr %67, align 8
%68 = getelementptr inbounds { ptr, i64 }, ptr %taddr57, i32 0, i32 1
%hi59 = load i64, ptr %68, align 8
%69 = call i8 @"std_map$$int.test_Foo_HashMap_has_key"(ptr %map, i32 2)
store i8 %69, ptr %taddr62, align 1
%70 = insertvalue %variant undef, ptr %taddr62, 0
%71 = insertvalue %variant %70, i64 ptrtoint (ptr @"ct$bool" to i64), 1
%72 = getelementptr inbounds [1 x %variant], ptr %varargslots61, i64 0, i64 0
store %variant %71, ptr %72, align 16
%73 = getelementptr inbounds %"variant[]", ptr %vararg60, i32 0, i32 1
store i64 1, ptr %73, align 8
%74 = getelementptr inbounds %"variant[]", ptr %vararg60, i32 0, i32 0
store ptr %varargslots61, ptr %74, align 8
%75 = getelementptr inbounds { ptr, i64 }, ptr %vararg60, i32 0, i32 0
%lo63 = load ptr, ptr %75, align 8
%76 = getelementptr inbounds { ptr, i64 }, ptr %vararg60, i32 0, i32 1
%hi64 = load i64, ptr %76, align 8
%77 = call i64 @std_io_printfln(ptr %retparam56, ptr %lo58, i64 %hi59, ptr %lo63, i64 %hi64)
%not_err65 = icmp eq i64 %77, 0
br i1 %not_err65, label %after_check66, label %voiderr67
after_check66: ; preds = %voiderr55
br label %voiderr67
voiderr67: ; preds = %after_check66, %voiderr55
%78 = getelementptr inbounds %Foo, ptr %literal68, i32 0, i32 0
store i32 4, ptr %78, align 8
%79 = getelementptr inbounds %Foo, ptr %literal68, i32 0, i32 1
store ptr null, ptr %79, align 8
%80 = getelementptr inbounds { i64, ptr }, ptr %literal68, i32 0, i32 0
%lo69 = load i64, ptr %80, align 8
%81 = getelementptr inbounds { i64, ptr }, ptr %literal68, i32 0, i32 1
%hi70 = load ptr, ptr %81, align 8
%82 = call i8 @"std_map$$int.test_Foo_HashMap_set"(ptr %map, i32 7, i64 %lo69, ptr %hi70)
store %"char[]" { ptr @.str.6, i64 10 }, ptr %taddr72, align 8
%83 = getelementptr inbounds { ptr, i64 }, ptr %taddr72, i32 0, i32 0
%lo73 = load ptr, ptr %83, align 8
%84 = getelementptr inbounds { ptr, i64 }, ptr %taddr72, i32 0, i32 1
%hi74 = load i64, ptr %84, align 8
%85 = call { ptr, i64 } @"std_map$$int.test_Foo_HashMap_value_list"(ptr %map, ptr null)
store { ptr, i64 } %85, ptr %result, align 8
%86 = insertvalue %variant undef, ptr %result, 0
%87 = insertvalue %variant %86, i64 ptrtoint (ptr @"ct$sa$test_Foo" to i64), 1
%88 = getelementptr inbounds [1 x %variant], ptr %varargslots76, i64 0, i64 0
store %variant %87, ptr %88, align 16
%89 = getelementptr inbounds %"variant[]", ptr %vararg75, i32 0, i32 1
store i64 1, ptr %89, align 8
%90 = getelementptr inbounds %"variant[]", ptr %vararg75, i32 0, i32 0
store ptr %varargslots76, ptr %90, align 8
%91 = getelementptr inbounds { ptr, i64 }, ptr %vararg75, i32 0, i32 0
%lo77 = load ptr, ptr %91, align 8
%92 = getelementptr inbounds { ptr, i64 }, ptr %vararg75, i32 0, i32 1
%hi78 = load i64, ptr %92, align 8
%93 = call i64 @std_io_printfln(ptr %retparam71, ptr %lo73, i64 %hi74, ptr %lo77, i64 %hi78)
%not_err79 = icmp eq i64 %93, 0
br i1 %not_err79, label %after_check80, label %voiderr81
after_check80: ; preds = %voiderr67
br label %voiderr81
voiderr81: ; preds = %after_check80, %voiderr67
call void @llvm.memset.p0.i64(ptr align 8 %map2, i8 0, i64 40, i1 false)
%94 = load ptr, ptr @std_core_mem_thread_allocator, align 8
call void @"std_map$$int.double_HashMap_init"(ptr %map2, i32 16, float 7.500000e-01, ptr %94)
%95 = call i8 @"std_map$$int.double_HashMap_set"(ptr %map2, i32 4, double 1.300000e+00)
store %"char[]" { ptr @.str.7, i64 12 }, ptr %taddr83, align 8
%96 = getelementptr inbounds { ptr, i64 }, ptr %taddr83, i32 0, i32 0
%lo84 = load ptr, ptr %96, align 8
%97 = getelementptr inbounds { ptr, i64 }, ptr %taddr83, i32 0, i32 1
%hi85 = load i64, ptr %97, align 8
%98 = call i8 @"std_map$$int.double_HashMap_has_value"(ptr %map2, double 1.300000e+00)
store i8 %98, ptr %taddr88, align 1
%99 = insertvalue %variant undef, ptr %taddr88, 0
%100 = insertvalue %variant %99, i64 ptrtoint (ptr @"ct$bool" to i64), 1
%101 = getelementptr inbounds [1 x %variant], ptr %varargslots87, i64 0, i64 0
store %variant %100, ptr %101, align 16
%102 = getelementptr inbounds %"variant[]", ptr %vararg86, i32 0, i32 1
store i64 1, ptr %102, align 8
%103 = getelementptr inbounds %"variant[]", ptr %vararg86, i32 0, i32 0
store ptr %varargslots87, ptr %103, align 8
%104 = getelementptr inbounds { ptr, i64 }, ptr %vararg86, i32 0, i32 0
%lo89 = load ptr, ptr %104, align 8
%105 = getelementptr inbounds { ptr, i64 }, ptr %vararg86, i32 0, i32 1
%hi90 = load i64, ptr %105, align 8
%106 = call i64 @std_io_printfln(ptr %retparam82, ptr %lo84, i64 %hi85, ptr %lo89, i64 %hi90)
%not_err91 = icmp eq i64 %106, 0
br i1 %not_err91, label %after_check92, label %voiderr93
after_check92: ; preds = %voiderr81
br label %voiderr93
voiderr93: ; preds = %after_check92, %voiderr81
store %"char[]" { ptr @.str.8, i64 12 }, ptr %taddr95, align 8
%107 = getelementptr inbounds { ptr, i64 }, ptr %taddr95, i32 0, i32 0
%lo96 = load ptr, ptr %107, align 8
%108 = getelementptr inbounds { ptr, i64 }, ptr %taddr95, i32 0, i32 1
%hi97 = load i64, ptr %108, align 8
%109 = call i8 @"std_map$$int.double_HashMap_has_value"(ptr %map2, double 1.200000e+00)
store i8 %109, ptr %taddr100, align 1
%110 = insertvalue %variant undef, ptr %taddr100, 0
%111 = insertvalue %variant %110, i64 ptrtoint (ptr @"ct$bool" to i64), 1
%112 = getelementptr inbounds [1 x %variant], ptr %varargslots99, i64 0, i64 0
store %variant %111, ptr %112, align 16
%113 = getelementptr inbounds %"variant[]", ptr %vararg98, i32 0, i32 1
store i64 1, ptr %113, align 8
%114 = getelementptr inbounds %"variant[]", ptr %vararg98, i32 0, i32 0
store ptr %varargslots99, ptr %114, align 8
%115 = getelementptr inbounds { ptr, i64 }, ptr %vararg98, i32 0, i32 0
%lo101 = load ptr, ptr %115, align 8
%116 = getelementptr inbounds { ptr, i64 }, ptr %vararg98, i32 0, i32 1
%hi102 = load i64, ptr %116, align 8
%117 = call i64 @std_io_printfln(ptr %retparam94, ptr %lo96, i64 %hi97, ptr %lo101, i64 %hi102)
%not_err103 = icmp eq i64 %117, 0
br i1 %not_err103, label %after_check104, label %voiderr105
after_check104: ; preds = %voiderr93
br label %voiderr105
voiderr105: ; preds = %after_check104, %voiderr93
%118 = call i8 @"std_map$$int.double_HashMap_set"(ptr %map2, i32 100, double 3.400000e+00)
store %"char[]" { ptr @.str.9, i64 2 }, ptr %taddr107, align 8
%119 = getelementptr inbounds { ptr, i64 }, ptr %taddr107, i32 0, i32 0
%lo108 = load ptr, ptr %119, align 8
%120 = getelementptr inbounds { ptr, i64 }, ptr %taddr107, i32 0, i32 1
%hi109 = load i64, ptr %120, align 8
%121 = call { ptr, i64 } @"std_map$$int.double_HashMap_key_list"(ptr %map2, ptr null)
store { ptr, i64 } %121, ptr %result112, align 8
%122 = insertvalue %variant undef, ptr %result112, 0
%123 = insertvalue %variant %122, i64 ptrtoint (ptr @"ct$sa$int" to i64), 1
%124 = getelementptr inbounds [1 x %variant], ptr %varargslots111, i64 0, i64 0
store %variant %123, ptr %124, align 16
%125 = getelementptr inbounds %"variant[]", ptr %vararg110, i32 0, i32 1
store i64 1, ptr %125, align 8
%126 = getelementptr inbounds %"variant[]", ptr %vararg110, i32 0, i32 0
store ptr %varargslots111, ptr %126, align 8
%127 = getelementptr inbounds { ptr, i64 }, ptr %vararg110, i32 0, i32 0
%lo113 = load ptr, ptr %127, align 8
%128 = getelementptr inbounds { ptr, i64 }, ptr %vararg110, i32 0, i32 1
%hi114 = load i64, ptr %128, align 8
%129 = call i64 @std_io_printfln(ptr %retparam106, ptr %lo108, i64 %hi109, ptr %lo113, i64 %hi114)
%not_err115 = icmp eq i64 %129, 0
br i1 %not_err115, label %after_check116, label %voiderr117
after_check116: ; preds = %voiderr105
br label %voiderr117
voiderr117: ; preds = %after_check116, %voiderr105
store %"char[]" { ptr @.str.10, i64 2 }, ptr %taddr119, align 8
%130 = getelementptr inbounds { ptr, i64 }, ptr %taddr119, i32 0, i32 0
%lo120 = load ptr, ptr %130, align 8
%131 = getelementptr inbounds { ptr, i64 }, ptr %taddr119, i32 0, i32 1
%hi121 = load i64, ptr %131, align 8
%132 = call { ptr, i64 } @"std_map$$int.double_HashMap_value_list"(ptr %map2, ptr null)
store { ptr, i64 } %132, ptr %result124, align 8
%133 = insertvalue %variant undef, ptr %result124, 0
%134 = insertvalue %variant %133, i64 ptrtoint (ptr @"ct$sa$double" to i64), 1
%135 = getelementptr inbounds [1 x %variant], ptr %varargslots123, i64 0, i64 0
store %variant %134, ptr %135, align 16
%136 = getelementptr inbounds %"variant[]", ptr %vararg122, i32 0, i32 1
store i64 1, ptr %136, align 8
%137 = getelementptr inbounds %"variant[]", ptr %vararg122, i32 0, i32 0
store ptr %varargslots123, ptr %137, align 8
%138 = getelementptr inbounds { ptr, i64 }, ptr %vararg122, i32 0, i32 0
%lo125 = load ptr, ptr %138, align 8
%139 = getelementptr inbounds { ptr, i64 }, ptr %vararg122, i32 0, i32 1
%hi126 = load i64, ptr %139, align 8
%140 = call i64 @std_io_printfln(ptr %retparam118, ptr %lo120, i64 %hi121, ptr %lo125, i64 %hi126)
%not_err127 = icmp eq i64 %140, 0
br i1 %not_err127, label %after_check128, label %voiderr129
after_check128: ; preds = %voiderr117
br label %voiderr129
voiderr129: ; preds = %after_check128, %voiderr117
%141 = load ptr, ptr @std_core_mem_thread_temp_allocator, align 8
%not = icmp eq ptr %141, null
br i1 %not, label %if.then, label %if.exit
if.then: ; preds = %voiderr129
%142 = call i64 @std_core_mem_allocator_new_temp(ptr %retparam130, i64 131072, ptr @std_core_mem_allocator__SYSTEM_ALLOCATOR)
%not_err131 = icmp eq i64 %142, 0
br i1 %not_err131, label %after_check132, label %assign_optional
assign_optional: ; preds = %if.then
store i64 %142, ptr %error_var, align 8
br label %panic_block
after_check132: ; preds = %if.then
%143 = load ptr, ptr %retparam130, align 8
br label %noerr_block
panic_block: ; preds = %assign_optional
call void @std_core_builtin_panic(ptr @.zstr, ptr @.zstr.11, ptr @.zstr.12, i32 250)
unreachable
noerr_block: ; preds = %after_check132
store ptr %143, ptr @std_core_mem_thread_temp_allocator, align 8
br label %if.exit
if.exit: ; preds = %noerr_block, %voiderr129
%144 = load ptr, ptr @std_core_mem_thread_temp_allocator, align 8
store ptr %144, ptr %temp, align 8
%145 = load ptr, ptr %temp, align 8
%146 = getelementptr inbounds %TempAllocator, ptr %145, i32 0, i32 3
%147 = load i64, ptr %146, align 8
store i64 %147, ptr %mark, align 8
call void @llvm.memset.p0.i64(ptr align 8 %map3, i8 0, i64 40, i1 false)
%148 = load ptr, ptr @std_core_mem_thread_temp_allocator, align 8
%not133 = icmp eq ptr %148, null
br i1 %not133, label %if.then134, label %if.exit142
if.then134: ; preds = %if.exit
%149 = call i64 @std_core_mem_allocator_new_temp(ptr %retparam136, i64 131072, ptr @std_core_mem_allocator__SYSTEM_ALLOCATOR)
%not_err137 = icmp eq i64 %149, 0
br i1 %not_err137, label %after_check139, label %assign_optional138
assign_optional138: ; preds = %if.then134
store i64 %149, ptr %error_var135, align 8
br label %panic_block140
after_check139: ; preds = %if.then134
%150 = load ptr, ptr %retparam136, align 8
br label %noerr_block141
panic_block140: ; preds = %assign_optional138
call void @std_core_builtin_panic(ptr @.zstr.13, ptr @.zstr.14, ptr @.zstr.15, i32 250)
unreachable
noerr_block141: ; preds = %after_check139
store ptr %150, ptr @std_core_mem_thread_temp_allocator, align 8
br label %if.exit142
if.exit142: ; preds = %noerr_block141, %if.exit
%151 = load ptr, ptr @std_core_mem_thread_temp_allocator, align 8
call void @"std_map$$int.double_HashMap_init"(ptr %map3, i32 16, float 7.500000e-01, ptr %151)
%152 = call i8 @"std_map$$int.double_HashMap_set"(ptr %map3, i32 5, double 3.200000e+00)
%153 = call i8 @"std_map$$int.double_HashMap_set"(ptr %map3, i32 7, double 5.200000e+00)
store %"char[]" { ptr @.str.16, i64 2 }, ptr %taddr144, align 8
%154 = getelementptr inbounds { ptr, i64 }, ptr %taddr144, i32 0, i32 0
%lo145 = load ptr, ptr %154, align 8
%155 = getelementptr inbounds { ptr, i64 }, ptr %taddr144, i32 0, i32 1
%hi146 = load i64, ptr %155, align 8
%156 = call { ptr, i64 } @"std_map$$int.double_HashMap_key_tlist"(ptr %map3)
store { ptr, i64 } %156, ptr %result149, align 8
%157 = insertvalue %variant undef, ptr %result149, 0
%158 = insertvalue %variant %157, i64 ptrtoint (ptr @"ct$sa$int" to i64), 1
%159 = getelementptr inbounds [1 x %variant], ptr %varargslots148, i64 0, i64 0
store %variant %158, ptr %159, align 16
%160 = getelementptr inbounds %"variant[]", ptr %vararg147, i32 0, i32 1
store i64 1, ptr %160, align 8
%161 = getelementptr inbounds %"variant[]", ptr %vararg147, i32 0, i32 0
store ptr %varargslots148, ptr %161, align 8
%162 = getelementptr inbounds { ptr, i64 }, ptr %vararg147, i32 0, i32 0
%lo150 = load ptr, ptr %162, align 8
%163 = getelementptr inbounds { ptr, i64 }, ptr %vararg147, i32 0, i32 1
%hi151 = load i64, ptr %163, align 8
%164 = call i64 @std_io_printfln(ptr %retparam143, ptr %lo145, i64 %hi146, ptr %lo150, i64 %hi151)
%not_err152 = icmp eq i64 %164, 0
br i1 %not_err152, label %after_check153, label %voiderr154
after_check153: ; preds = %if.exit142
br label %voiderr154
voiderr154: ; preds = %after_check153, %if.exit142
%165 = load ptr, ptr %temp, align 8
%166 = getelementptr inbounds %TempAllocator, ptr %165, i32 0, i32 0
%167 = load i64, ptr %mark, align 8
call void @std_core_mem_allocator_Allocator_reset(ptr %166, i64 %167)
ret void
}