mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 23:28:48 +00:00
Procedure literals for default values in structs
This commit is contained in:
+4
-6
@@ -721,18 +721,16 @@ __mem_copy_non_overlapping :: proc(dst, src: rawptr, len: int) -> rawptr #cc_con
|
|||||||
when size_of(rawptr) == 8 {
|
when size_of(rawptr) == 8 {
|
||||||
foreign __llvm_core llvm_memcpy :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #link_name "llvm.memcpy.p0i8.p0i8.i64" ---;
|
foreign __llvm_core llvm_memcpy :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #link_name "llvm.memcpy.p0i8.p0i8.i64" ---;
|
||||||
} else {
|
} else {
|
||||||
foreign __llvm_core llvm_memcpy :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #link_name "llvm.memcpy.p0i8.p0i8.i32";
|
foreign __llvm_core llvm_memcpy :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #link_name "llvm.memcpy.p0i8.p0i8.i32" ---;
|
||||||
}
|
}
|
||||||
llvm_memcpy(dst, src, len, 1, false);
|
llvm_memcpy(dst, src, len, 1, false);
|
||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
__mem_compare :: proc(a, b: ^u8, n: int) -> int #cc_contextless {
|
__mem_compare :: proc(a, b: ^u8, n: int) -> int #cc_contextless {
|
||||||
for i in 0..n {
|
for i in 0..n do switch {
|
||||||
switch {
|
case (a+i)^ < (b+i)^: return -1;
|
||||||
case (a+i)^ < (b+i)^: return -1;
|
case (a+i)^ > (b+i)^: return +1;
|
||||||
case (a+i)^ > (b+i)^: return +1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-6
@@ -13,17 +13,13 @@ c_ushort :: i16;
|
|||||||
c_int :: i32;
|
c_int :: i32;
|
||||||
c_uint :: u32;
|
c_uint :: u32;
|
||||||
|
|
||||||
when ODIN_OS == "windows" {
|
when ODIN_OS == "windows" || size_of(int) == 4 {
|
||||||
c_long :: i32;
|
|
||||||
} else when size_of(int) == 4 {
|
|
||||||
c_long :: i32;
|
c_long :: i32;
|
||||||
} else {
|
} else {
|
||||||
c_long :: i64;
|
c_long :: i64;
|
||||||
}
|
}
|
||||||
|
|
||||||
when ODIN_OS == "windows" {
|
when ODIN_OS == "windows" || size_of(uint) == 4 {
|
||||||
c_ulong :: u32;
|
|
||||||
} else when size_of(uint) == 4 {
|
|
||||||
c_ulong :: u32;
|
c_ulong :: u32;
|
||||||
} else {
|
} else {
|
||||||
c_ulong :: u64;
|
c_ulong :: u64;
|
||||||
|
|||||||
+26
-11
@@ -1035,7 +1035,12 @@ Array<Entity *> check_struct_fields(Checker *c, AstNode *node, Array<AstNode *>
|
|||||||
if (is_operand_nil(o)) {
|
if (is_operand_nil(o)) {
|
||||||
default_is_nil = true;
|
default_is_nil = true;
|
||||||
} else if (o.mode != Addressing_Constant) {
|
} else if (o.mode != Addressing_Constant) {
|
||||||
error(default_value, "Default parameter must be a constant");
|
if (default_value->kind == AstNode_ProcLit) {
|
||||||
|
value = exact_value_procedure(default_value);
|
||||||
|
// error(default_value, "A procedure literal as a default param is not yet supported");
|
||||||
|
} else {
|
||||||
|
error(default_value, "Default parameter must be a constant");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
value = o.value;
|
value = o.value;
|
||||||
}
|
}
|
||||||
@@ -1329,10 +1334,10 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node, Array<Opera
|
|||||||
context = str_lit("struct #raw_union");
|
context = str_lit("struct #raw_union");
|
||||||
}
|
}
|
||||||
|
|
||||||
Type *polymorphic_params = nullptr;
|
Type *polymorphic_params = nullptr;
|
||||||
bool is_polymorphic = false;
|
bool is_polymorphic = false;
|
||||||
bool can_check_fields = true;
|
bool can_check_fields = true;
|
||||||
bool is_poly_specialized = false;
|
bool is_poly_specialized = false;
|
||||||
|
|
||||||
if (st->polymorphic_params != nullptr) {
|
if (st->polymorphic_params != nullptr) {
|
||||||
ast_node(field_list, FieldList, st->polymorphic_params);
|
ast_node(field_list, FieldList, st->polymorphic_params);
|
||||||
@@ -1481,12 +1486,12 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node, Array<Opera
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct_type->Struct.scope = c->context.scope;
|
struct_type->Struct.scope = c->context.scope;
|
||||||
struct_type->Struct.is_packed = st->is_packed;
|
struct_type->Struct.is_packed = st->is_packed;
|
||||||
struct_type->Struct.is_ordered = st->is_ordered;
|
struct_type->Struct.is_ordered = st->is_ordered;
|
||||||
struct_type->Struct.polymorphic_params = polymorphic_params;
|
struct_type->Struct.polymorphic_params = polymorphic_params;
|
||||||
struct_type->Struct.is_polymorphic = is_polymorphic;
|
struct_type->Struct.is_polymorphic = is_polymorphic;
|
||||||
struct_type->Struct.is_poly_specialized = is_poly_specialized;
|
struct_type->Struct.is_poly_specialized = is_poly_specialized;
|
||||||
|
|
||||||
Array<Entity *> fields = {};
|
Array<Entity *> fields = {};
|
||||||
|
|
||||||
@@ -1497,6 +1502,16 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node, Array<Opera
|
|||||||
struct_type->Struct.fields = fields;
|
struct_type->Struct.fields = fields;
|
||||||
struct_type->Struct.fields_in_src_order = fields;
|
struct_type->Struct.fields_in_src_order = fields;
|
||||||
|
|
||||||
|
for_array(i, fields) {
|
||||||
|
Entity *f = fields[i];
|
||||||
|
if (f->kind == Entity_Variable) {
|
||||||
|
if (f->Variable.default_value.kind == ExactValue_Procedure) {
|
||||||
|
struct_type->Struct.has_proc_default_values = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!struct_type->Struct.is_raw_union) {
|
if (!struct_type->Struct.is_raw_union) {
|
||||||
type_set_offsets(c->allocator, struct_type);
|
type_set_offsets(c->allocator, struct_type);
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ enum ExactValueKind {
|
|||||||
ExactValue_Complex,
|
ExactValue_Complex,
|
||||||
ExactValue_Pointer,
|
ExactValue_Pointer,
|
||||||
ExactValue_Compound, // TODO(bill): Is this good enough?
|
ExactValue_Compound, // TODO(bill): Is this good enough?
|
||||||
|
ExactValue_Procedure, // TODO(bill): Is this good enough?
|
||||||
ExactValue_Type,
|
ExactValue_Type,
|
||||||
|
|
||||||
ExactValue_Count,
|
ExactValue_Count,
|
||||||
@@ -37,6 +38,7 @@ struct ExactValue {
|
|||||||
i64 value_pointer;
|
i64 value_pointer;
|
||||||
Complex128 value_complex;
|
Complex128 value_complex;
|
||||||
AstNode * value_compound;
|
AstNode * value_compound;
|
||||||
|
AstNode * value_procedure;
|
||||||
Type * value_type;
|
Type * value_type;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -109,6 +111,12 @@ ExactValue exact_value_type(Type *type) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExactValue exact_value_procedure(AstNode *node) {
|
||||||
|
ExactValue result = {ExactValue_Procedure};
|
||||||
|
result.value_procedure = node;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ExactValue exact_value_integer_from_string(String string) {
|
ExactValue exact_value_integer_from_string(String string) {
|
||||||
return exact_value_u128(u128_from_string(string));
|
return exact_value_u128(u128_from_string(string));
|
||||||
|
|||||||
+66
-30
@@ -20,10 +20,12 @@ struct irModule {
|
|||||||
// String triple;
|
// String triple;
|
||||||
|
|
||||||
PtrSet<Entity *> min_dep_set;
|
PtrSet<Entity *> min_dep_set;
|
||||||
Map<irValue *> values; // Key: Entity *
|
Map<irValue *> values; // Key: Entity *
|
||||||
Map<irValue *> members; // Key: String
|
Map<irValue *> members; // Key: String
|
||||||
Map<String> entity_names; // Key: Entity * of the typename
|
Map<String> entity_names; // Key: Entity * of the typename
|
||||||
Map<irDebugInfo *> debug_info; // Key: Unique pointer
|
Map<irDebugInfo *> debug_info; // Key: Unique pointer
|
||||||
|
Map<irValue *> anonymous_proc_lits; // Key: AstNode *
|
||||||
|
|
||||||
i32 global_string_index;
|
i32 global_string_index;
|
||||||
i32 global_array_index; // For ConstantSlice
|
i32 global_array_index; // For ConstantSlice
|
||||||
i32 global_generated_index;
|
i32 global_generated_index;
|
||||||
@@ -3720,6 +3722,38 @@ void ir_pop_target_list(irProcedure *proc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
irValue *ir_gen_anonymous_proc_lit(irModule *m, String prefix_name, AstNode *expr, irProcedure *proc = nullptr) {
|
||||||
|
ast_node(pl, ProcLit, expr);
|
||||||
|
|
||||||
|
// NOTE(bill): Generate a new name
|
||||||
|
// parent$count
|
||||||
|
isize name_len = prefix_name.len + 1 + 8 + 1;
|
||||||
|
u8 *name_text = gb_alloc_array(m->allocator, u8, name_len);
|
||||||
|
i32 name_id = cast(i32)m->anonymous_proc_lits.entries.count;
|
||||||
|
|
||||||
|
name_len = gb_snprintf(cast(char *)name_text, name_len, "%.*s$anon-%d", LIT(prefix_name), name_id);
|
||||||
|
String name = make_string(name_text, name_len-1);
|
||||||
|
|
||||||
|
Type *type = type_of_expr(m->info, expr);
|
||||||
|
irValue *value = ir_value_procedure(m->allocator,
|
||||||
|
m, nullptr, type, pl->type, pl->body, name);
|
||||||
|
|
||||||
|
value->Proc.tags = pl->tags;
|
||||||
|
value->Proc.parent = proc;
|
||||||
|
|
||||||
|
array_add(&m->procs_to_generate, value);
|
||||||
|
if (proc != nullptr) {
|
||||||
|
array_add(&proc->children, &value->Proc);
|
||||||
|
} else {
|
||||||
|
map_set(&m->members, hash_string(name), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
map_set(&m->anonymous_proc_lits, hash_pointer(expr), value);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
void ir_gen_global_type_name(irModule *m, Entity *e, String name) {
|
void ir_gen_global_type_name(irModule *m, Entity *e, String name) {
|
||||||
if (e->type == nullptr) return;
|
if (e->type == nullptr) return;
|
||||||
|
|
||||||
@@ -3759,13 +3793,29 @@ void ir_gen_global_type_name(irModule *m, Entity *e, String name) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// if (bt->kind == Type_Struct) {
|
||||||
|
// Scope *s = bt->Struct.scope;
|
||||||
|
// if (s != nullptr) {
|
||||||
|
// for_array(i, s->elements.entries) {
|
||||||
|
// Entity *e = s->elements.entries[i].value;
|
||||||
|
// if (e->kind == Entity_TypeName) {
|
||||||
|
// ir_mangle_add_sub_type_name(m, e, name);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
if (bt->kind == Type_Struct) {
|
if (bt->kind == Type_Struct) {
|
||||||
Scope *s = bt->Struct.scope;
|
if (bt->Struct.has_proc_default_values) {
|
||||||
if (s != nullptr) {
|
for_array(i, bt->Struct.fields) {
|
||||||
for_array(i, s->elements.entries) {
|
Entity *f = bt->Struct.fields[i];
|
||||||
Entity *e = s->elements.entries[i].value;
|
if (f->kind == Entity_Variable) {
|
||||||
if (e->kind == Entity_TypeName) {
|
if (f->Variable.default_value.kind == ExactValue_Procedure) {
|
||||||
ir_mangle_add_sub_type_name(m, e, name);
|
AstNode *expr = f->Variable.default_value.value_procedure;
|
||||||
|
GB_ASSERT(expr != nullptr);
|
||||||
|
GB_ASSERT(expr->kind == AstNode_ProcLit);
|
||||||
|
ir_gen_anonymous_proc_lit(m, e->token.string, expr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4563,7 +4613,6 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
||||||
expr = unparen_expr(expr);
|
expr = unparen_expr(expr);
|
||||||
|
|
||||||
@@ -4832,24 +4881,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
|
|||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
case_ast_node(pl, ProcLit, expr);
|
case_ast_node(pl, ProcLit, expr);
|
||||||
// NOTE(bill): Generate a new name
|
return ir_gen_anonymous_proc_lit(proc->module, proc->name, expr, proc);
|
||||||
// parent$count
|
|
||||||
isize name_len = proc->name.len + 1 + 8 + 1;
|
|
||||||
u8 *name_text = gb_alloc_array(proc->module->allocator, u8, name_len);
|
|
||||||
name_len = gb_snprintf(cast(char *)name_text, name_len, "%.*s$%d", LIT(proc->name), cast(i32)proc->children.count);
|
|
||||||
String name = make_string(name_text, name_len-1);
|
|
||||||
|
|
||||||
Type *type = type_of_expr(proc->module->info, expr);
|
|
||||||
irValue *value = ir_value_procedure(proc->module->allocator,
|
|
||||||
proc->module, nullptr, type, pl->type, pl->body, name);
|
|
||||||
|
|
||||||
value->Proc.tags = pl->tags;
|
|
||||||
value->Proc.parent = proc;
|
|
||||||
|
|
||||||
array_add(&proc->children, &value->Proc);
|
|
||||||
array_add(&proc->module->procs_to_generate, value);
|
|
||||||
|
|
||||||
return value;
|
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
|
|
||||||
@@ -7424,6 +7456,7 @@ void ir_init_module(irModule *m, Checker *c) {
|
|||||||
map_init(&m->members, heap_allocator());
|
map_init(&m->members, heap_allocator());
|
||||||
map_init(&m->debug_info, heap_allocator());
|
map_init(&m->debug_info, heap_allocator());
|
||||||
map_init(&m->entity_names, heap_allocator());
|
map_init(&m->entity_names, heap_allocator());
|
||||||
|
map_init(&m->anonymous_proc_lits, heap_allocator());
|
||||||
array_init(&m->procs, heap_allocator());
|
array_init(&m->procs, heap_allocator());
|
||||||
array_init(&m->procs_to_generate, heap_allocator());
|
array_init(&m->procs_to_generate, heap_allocator());
|
||||||
array_init(&m->foreign_library_paths, heap_allocator());
|
array_init(&m->foreign_library_paths, heap_allocator());
|
||||||
@@ -7532,6 +7565,7 @@ void ir_destroy_module(irModule *m) {
|
|||||||
map_destroy(&m->values);
|
map_destroy(&m->values);
|
||||||
map_destroy(&m->members);
|
map_destroy(&m->members);
|
||||||
map_destroy(&m->entity_names);
|
map_destroy(&m->entity_names);
|
||||||
|
map_destroy(&m->anonymous_proc_lits);
|
||||||
map_destroy(&m->debug_info);
|
map_destroy(&m->debug_info);
|
||||||
map_destroy(&m->const_strings);
|
map_destroy(&m->const_strings);
|
||||||
array_free(&m->procs);
|
array_free(&m->procs);
|
||||||
@@ -8535,7 +8569,9 @@ void ir_gen_tree(irGen *s) {
|
|||||||
|
|
||||||
|
|
||||||
for_array(i, m->procs_to_generate) {
|
for_array(i, m->procs_to_generate) {
|
||||||
ir_build_proc(m->procs_to_generate[i], m->procs_to_generate[i]->Proc.parent);
|
irValue *p = m->procs_to_generate[i];
|
||||||
|
gb_printf_err("%.*s\n", LIT(p->Proc.name));
|
||||||
|
ir_build_proc(p, p->Proc.parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Number debug info
|
// Number debug info
|
||||||
|
|||||||
+95
-42
@@ -341,7 +341,8 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
case Type_Named:
|
case Type_Named:
|
||||||
@@ -357,7 +358,8 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
|
|||||||
ir_print_type(f, m, base_type(t));
|
ir_print_type(f, m, base_type(t));
|
||||||
// GB_ASSERT_MSG(found != nullptr, "%.*s %p", LIT(t->Named.name), t->Named.type_name);
|
// GB_ASSERT_MSG(found != nullptr, "%.*s %p", LIT(t->Named.name), t->Named.type_name);
|
||||||
}
|
}
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
ir_print_type(f, m, base_type(t));
|
ir_print_type(f, m, base_type(t));
|
||||||
break;
|
break;
|
||||||
@@ -389,13 +391,15 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) {
|
|||||||
generate_map_internal_types(m->allocator, t);
|
generate_map_internal_types(m->allocator, t);
|
||||||
GB_ASSERT(t->Map.generated_struct_type != nullptr);
|
GB_ASSERT(t->Map.generated_struct_type != nullptr);
|
||||||
ir_print_type(f, m, t->Map.generated_struct_type);
|
ir_print_type(f, m, t->Map.generated_struct_type);
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case Type_BitField: {
|
case Type_BitField: {
|
||||||
i64 align = type_align_of(heap_allocator(), t);
|
i64 align = type_align_of(heap_allocator(), t);
|
||||||
i64 size = type_size_of(heap_allocator(), t);
|
i64 size = type_size_of(heap_allocator(), t);
|
||||||
ir_fprintf(f, "{[0 x <%lld x i8>], [%lld x i8]}", align, size);
|
ir_fprintf(f, "{[0 x <%lld x i8>], [%lld x i8]}", align, size);
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -455,7 +459,8 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
|
|||||||
ir_print_type(f, m, t_int);
|
ir_print_type(f, m, t_int);
|
||||||
ir_fprintf(f, " %lld}", cast(i64)str.len);
|
ir_fprintf(f, " %lld}", cast(i64)str.len);
|
||||||
}
|
}
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
case ExactValue_Integer: {
|
case ExactValue_Integer: {
|
||||||
if (is_type_pointer(type)) {
|
if (is_type_pointer(type)) {
|
||||||
if (i128_eq(value.value_integer, I128_ZERO)) {
|
if (i128_eq(value.value_integer, I128_ZERO)) {
|
||||||
@@ -472,7 +477,8 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
|
|||||||
} else {
|
} else {
|
||||||
ir_write_i128(f, value.value_integer);
|
ir_write_i128(f, value.value_integer);
|
||||||
}
|
}
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
case ExactValue_Float: {
|
case ExactValue_Float: {
|
||||||
GB_ASSERT_MSG(is_type_float(type), "%s", type_to_string(type));
|
GB_ASSERT_MSG(is_type_float(type), "%s", type_to_string(type));
|
||||||
type = core_type(type);
|
type = core_type(type);
|
||||||
@@ -501,7 +507,8 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
|
|||||||
ir_fprintf(f, "0x%016llx", u);
|
ir_fprintf(f, "0x%016llx", u);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ExactValue_Complex: {
|
case ExactValue_Complex: {
|
||||||
type = core_type(type);
|
type = core_type(type);
|
||||||
@@ -514,7 +521,8 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
|
|||||||
ir_write_string(f, str_lit(", ")); ir_print_type(f, m, ft); ir_write_byte(f, ' ');
|
ir_write_string(f, str_lit(", ")); ir_print_type(f, m, ft); ir_write_byte(f, ' ');
|
||||||
ir_print_exact_value(f, m, exact_value_float(value.value_complex.imag), ft);
|
ir_print_exact_value(f, m, exact_value_float(value.value_complex.imag), ft);
|
||||||
ir_write_byte(f, '}');
|
ir_write_byte(f, '}');
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ExactValue_Pointer:
|
case ExactValue_Pointer:
|
||||||
if (value.value_pointer == 0) {
|
if (value.value_pointer == 0) {
|
||||||
@@ -689,7 +697,19 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
|
|||||||
ir_write_string(f, "zeroinitializer");
|
ir_write_string(f, "zeroinitializer");
|
||||||
}
|
}
|
||||||
|
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ExactValue_Procedure: {
|
||||||
|
AstNode *expr = value.value_procedure;
|
||||||
|
GB_ASSERT(expr != nullptr);
|
||||||
|
GB_ASSERT(expr->kind == AstNode_ProcLit);
|
||||||
|
irValue **found = map_get(&m->anonymous_proc_lits, hash_pointer(expr));
|
||||||
|
GB_ASSERT(found != nullptr);
|
||||||
|
irValue *val = *found;
|
||||||
|
ir_print_value(f, m, val, type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
bool has_defaults = ir_type_has_default_values(type);
|
bool has_defaults = ir_type_has_default_values(type);
|
||||||
@@ -745,7 +765,8 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type *
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// GB_PANIC("Invalid ExactValue: %d", value.kind);
|
// GB_PANIC("Invalid ExactValue: %d", value.kind);
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -808,7 +829,8 @@ void ir_print_value(irFileBuffer *f, irModule *m, irValue *value, Type *type_hin
|
|||||||
ir_print_type(f, m, t_int);
|
ir_print_type(f, m, t_int);
|
||||||
ir_fprintf(f, " %lld}", cs->count);
|
ir_fprintf(f, " %lld}", cs->count);
|
||||||
}
|
}
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case irValue_Nil:
|
case irValue_Nil:
|
||||||
ir_write_string(f, "zeroinitializer");
|
ir_write_string(f, "zeroinitializer");
|
||||||
@@ -830,7 +852,8 @@ void ir_print_value(irFileBuffer *f, irModule *m, irValue *value, Type *type_hin
|
|||||||
in_global_scope = scope->is_global || scope->is_init;
|
in_global_scope = scope->is_global || scope->is_init;
|
||||||
}
|
}
|
||||||
ir_print_encoded_global(f, ir_get_global_name(m, value), in_global_scope);
|
ir_print_encoded_global(f, ir_get_global_name(m, value), in_global_scope);
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
case irValue_Param:
|
case irValue_Param:
|
||||||
ir_print_encoded_local(f, value->Param.entity->token.string);
|
ir_print_encoded_local(f, value->Param.entity->token.string);
|
||||||
break;
|
break;
|
||||||
@@ -864,13 +887,15 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
default: {
|
default: {
|
||||||
GB_PANIC("<unknown instr> %d\n", instr->kind);
|
GB_PANIC("<unknown instr> %d\n", instr->kind);
|
||||||
ir_fprintf(f, "; <unknown instr> %d\n", instr->kind);
|
ir_fprintf(f, "; <unknown instr> %d\n", instr->kind);
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case irInstr_StartupRuntime: {
|
case irInstr_StartupRuntime: {
|
||||||
ir_write_string(f, "call void ");
|
ir_write_string(f, "call void ");
|
||||||
ir_print_encoded_global(f, str_lit(IR_STARTUP_RUNTIME_PROC_NAME), false);
|
ir_print_encoded_global(f, str_lit(IR_STARTUP_RUNTIME_PROC_NAME), false);
|
||||||
ir_write_string(f, "()\n");
|
ir_write_string(f, "()\n");
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case irInstr_Comment:
|
case irInstr_Comment:
|
||||||
ir_write_string(f, "; ");
|
ir_write_string(f, "; ");
|
||||||
@@ -887,7 +912,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
ir_fprintf(f, "%%%d = alloca ", value->index);
|
ir_fprintf(f, "%%%d = alloca ", value->index);
|
||||||
ir_print_type(f, m, type);
|
ir_print_type(f, m, type);
|
||||||
ir_fprintf(f, ", align %lld\n", align);
|
ir_fprintf(f, ", align %lld\n", align);
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case irInstr_ZeroInit: {
|
case irInstr_ZeroInit: {
|
||||||
Type *type = type_deref(ir_type(instr->ZeroInit.address));
|
Type *type = type_deref(ir_type(instr->ZeroInit.address));
|
||||||
@@ -898,7 +924,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
ir_write_string(f, str_lit(", "));
|
ir_write_string(f, str_lit(", "));
|
||||||
ir_print_type(f, m, type);
|
ir_print_type(f, m, type);
|
||||||
ir_fprintf(f, "* %%%d\n", instr->ZeroInit.address->index);
|
ir_fprintf(f, "* %%%d\n", instr->ZeroInit.address->index);
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case irInstr_Store: {
|
case irInstr_Store: {
|
||||||
Type *type = type_deref(ir_type(instr->Store.address));
|
Type *type = type_deref(ir_type(instr->Store.address));
|
||||||
@@ -911,7 +938,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
ir_write_string(f, "* ");
|
ir_write_string(f, "* ");
|
||||||
ir_print_value(f, m, instr->Store.address, type);
|
ir_print_value(f, m, instr->Store.address, type);
|
||||||
ir_write_byte(f, '\n');
|
ir_write_byte(f, '\n');
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case irInstr_Load: {
|
case irInstr_Load: {
|
||||||
Type *type = instr->Load.type;
|
Type *type = instr->Load.type;
|
||||||
@@ -922,7 +950,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
ir_write_string(f, "* ");
|
ir_write_string(f, "* ");
|
||||||
ir_print_value(f, m, instr->Load.address, type);
|
ir_print_value(f, m, instr->Load.address, type);
|
||||||
ir_fprintf(f, ", align %lld\n", type_align_of(m->allocator, type));
|
ir_fprintf(f, ", align %lld\n", type_align_of(m->allocator, type));
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case irInstr_ArrayElementPtr: {
|
case irInstr_ArrayElementPtr: {
|
||||||
Type *et = ir_type(instr->ArrayElementPtr.address);
|
Type *et = ir_type(instr->ArrayElementPtr.address);
|
||||||
@@ -947,7 +976,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
ir_write_byte(f, ' ');
|
ir_write_byte(f, ' ');
|
||||||
ir_print_value(f, m, index, t);
|
ir_print_value(f, m, index, t);
|
||||||
ir_write_byte(f, '\n');
|
ir_write_byte(f, '\n');
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case irInstr_StructElementPtr: {
|
case irInstr_StructElementPtr: {
|
||||||
Type *et = ir_type(instr->StructElementPtr.address);
|
Type *et = ir_type(instr->StructElementPtr.address);
|
||||||
@@ -973,7 +1003,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
ir_print_type(f, m, t_i32);
|
ir_print_type(f, m, t_i32);
|
||||||
ir_fprintf(f, " %d", index);
|
ir_fprintf(f, " %d", index);
|
||||||
ir_write_byte(f, '\n');
|
ir_write_byte(f, '\n');
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case irInstr_PtrOffset: {
|
case irInstr_PtrOffset: {
|
||||||
Type *pt = ir_type(instr->PtrOffset.address);
|
Type *pt = ir_type(instr->PtrOffset.address);
|
||||||
@@ -991,7 +1022,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
ir_write_byte(f, ' ');
|
ir_write_byte(f, ' ');
|
||||||
ir_print_value(f, m, offset, t);
|
ir_print_value(f, m, offset, t);
|
||||||
ir_write_byte(f, '\n');
|
ir_write_byte(f, '\n');
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case irInstr_Phi: {
|
case irInstr_Phi: {
|
||||||
ir_fprintf(f, "%%%d = phi ", value->index);
|
ir_fprintf(f, "%%%d = phi ", value->index);
|
||||||
@@ -1018,7 +1050,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
ir_write_string(f, " ]");
|
ir_write_string(f, " ]");
|
||||||
}
|
}
|
||||||
ir_write_byte(f, '\n');
|
ir_write_byte(f, '\n');
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case irInstr_StructExtractValue: {
|
case irInstr_StructExtractValue: {
|
||||||
Type *et = ir_type(instr->StructExtractValue.address);
|
Type *et = ir_type(instr->StructExtractValue.address);
|
||||||
@@ -1038,7 +1071,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
ir_write_byte(f, ' ');
|
ir_write_byte(f, ' ');
|
||||||
ir_print_value(f, m, instr->StructExtractValue.address, et);
|
ir_print_value(f, m, instr->StructExtractValue.address, et);
|
||||||
ir_fprintf(f, ", %d\n", index);
|
ir_fprintf(f, ", %d\n", index);
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case irInstr_UnionTagPtr: {
|
case irInstr_UnionTagPtr: {
|
||||||
Type *et = ir_type(instr->UnionTagPtr.address);
|
Type *et = ir_type(instr->UnionTagPtr.address);
|
||||||
@@ -1062,7 +1096,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
#endif
|
#endif
|
||||||
ir_write_string(f, " ; UnionTagPtr");
|
ir_write_string(f, " ; UnionTagPtr");
|
||||||
ir_write_byte(f, '\n');
|
ir_write_byte(f, '\n');
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case irInstr_UnionTagValue: {
|
case irInstr_UnionTagValue: {
|
||||||
Type *et = ir_type(instr->UnionTagValue.address);
|
Type *et = ir_type(instr->UnionTagValue.address);
|
||||||
@@ -1081,13 +1116,15 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
#endif
|
#endif
|
||||||
ir_write_string(f, " ; UnionTagValue");
|
ir_write_string(f, " ; UnionTagValue");
|
||||||
ir_write_byte(f, '\n');
|
ir_write_byte(f, '\n');
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case irInstr_Jump: {;
|
case irInstr_Jump: {;
|
||||||
ir_write_string(f, "br label %");
|
ir_write_string(f, "br label %");
|
||||||
ir_print_block_name(f, instr->Jump.block);
|
ir_print_block_name(f, instr->Jump.block);
|
||||||
ir_write_byte(f, '\n');
|
ir_write_byte(f, '\n');
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case irInstr_If: {;
|
case irInstr_If: {;
|
||||||
ir_write_string(f, "br ");
|
ir_write_string(f, "br ");
|
||||||
@@ -1098,7 +1135,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
ir_write_string(f, "label %"); ir_print_block_name(f, instr->If.true_block);
|
ir_write_string(f, "label %"); ir_print_block_name(f, instr->If.true_block);
|
||||||
ir_write_string(f, ", label %"); ir_print_block_name(f, instr->If.false_block);
|
ir_write_string(f, ", label %"); ir_print_block_name(f, instr->If.false_block);
|
||||||
ir_write_byte(f, '\n');
|
ir_write_byte(f, '\n');
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case irInstr_Return: {
|
case irInstr_Return: {
|
||||||
irInstrReturn *ret = &instr->Return;
|
irInstrReturn *ret = &instr->Return;
|
||||||
@@ -1114,7 +1152,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
|
|
||||||
ir_write_byte(f, '\n');
|
ir_write_byte(f, '\n');
|
||||||
|
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case irInstr_Conv: {
|
case irInstr_Conv: {
|
||||||
irInstrConv *c = &instr->Conv;
|
irInstrConv *c = &instr->Conv;
|
||||||
@@ -1126,11 +1165,13 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
ir_print_type(f, m, c->to);
|
ir_print_type(f, m, c->to);
|
||||||
ir_write_byte(f, '\n');
|
ir_write_byte(f, '\n');
|
||||||
|
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case irInstr_Unreachable: {
|
case irInstr_Unreachable: {
|
||||||
ir_fprintf(f, "unreachable\n");
|
ir_fprintf(f, "unreachable\n");
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case irInstr_UnaryOp: {
|
case irInstr_UnaryOp: {
|
||||||
irInstrUnaryOp *uo = &value->Instr.UnaryOp;
|
irInstrUnaryOp *uo = &value->Instr.UnaryOp;
|
||||||
@@ -1179,7 +1220,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
ir_write_string(f, str_lit(", "));
|
ir_write_string(f, str_lit(", "));
|
||||||
ir_print_value(f, m, uo->expr, type);
|
ir_print_value(f, m, uo->expr, type);
|
||||||
ir_write_byte(f, '\n');
|
ir_write_byte(f, '\n');
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case irInstr_BinaryOp: {
|
case irInstr_BinaryOp: {
|
||||||
irInstrBinaryOp *bo = &value->Instr.BinaryOp;
|
irInstrBinaryOp *bo = &value->Instr.BinaryOp;
|
||||||
@@ -1311,7 +1353,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
case Token_Quo: ir_write_string(f, "div"); break;
|
case Token_Quo: ir_write_string(f, "div"); break;
|
||||||
case Token_Mod: ir_write_string(f, "rem"); break;
|
case Token_Mod: ir_write_string(f, "rem"); break;
|
||||||
}
|
}
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1322,7 +1365,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
ir_write_string(f, str_lit(", "));
|
ir_write_string(f, str_lit(", "));
|
||||||
ir_print_value(f, m, bo->right, type);
|
ir_print_value(f, m, bo->right, type);
|
||||||
ir_write_byte(f, '\n');
|
ir_write_byte(f, '\n');
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case irInstr_Call: {
|
case irInstr_Call: {
|
||||||
irInstrCall *call = &instr->Call;
|
irInstrCall *call = &instr->Call;
|
||||||
@@ -1421,7 +1465,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
}
|
}
|
||||||
ir_write_string(f, ")\n");
|
ir_write_string(f, ")\n");
|
||||||
|
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case irInstr_Select: {
|
case irInstr_Select: {
|
||||||
ir_fprintf(f, "%%%d = select i1 ", value->index);
|
ir_fprintf(f, "%%%d = select i1 ", value->index);
|
||||||
@@ -1435,7 +1480,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
ir_write_byte(f, ' ');
|
ir_write_byte(f, ' ');
|
||||||
ir_print_value(f, m, instr->Select.false_value, ir_type(instr->Select.false_value));
|
ir_print_value(f, m, instr->Select.false_value, ir_type(instr->Select.false_value));
|
||||||
ir_write_byte(f, '\n');
|
ir_write_byte(f, '\n');
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// case irInstr_VectorExtractElement: {
|
// case irInstr_VectorExtractElement: {
|
||||||
// Type *vt = ir_type(instr->VectorExtractElement.vector);
|
// Type *vt = ir_type(instr->VectorExtractElement.vector);
|
||||||
@@ -1450,7 +1496,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
// ir_write_byte(f, ' ');
|
// ir_write_byte(f, ' ');
|
||||||
// ir_print_value(f, m, instr->VectorExtractElement.index, it);
|
// ir_print_value(f, m, instr->VectorExtractElement.index, it);
|
||||||
// ir_write_byte(f, '\n');
|
// ir_write_byte(f, '\n');
|
||||||
// } break;
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
// case irInstr_VectorInsertElement: {
|
// case irInstr_VectorInsertElement: {
|
||||||
// irInstrVectorInsertElement *ie = &instr->VectorInsertElement;
|
// irInstrVectorInsertElement *ie = &instr->VectorInsertElement;
|
||||||
@@ -1472,7 +1519,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
// ir_print_value(f, m, ie->index, ir_type(ie->index));
|
// ir_print_value(f, m, ie->index, ir_type(ie->index));
|
||||||
|
|
||||||
// ir_write_byte(f, '\n');
|
// ir_write_byte(f, '\n');
|
||||||
// } break;
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
// case irInstr_VectorShuffle: {
|
// case irInstr_VectorShuffle: {
|
||||||
// irInstrVectorShuffle *sv = &instr->VectorShuffle;
|
// irInstrVectorShuffle *sv = &instr->VectorShuffle;
|
||||||
@@ -1498,7 +1546,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
// }
|
// }
|
||||||
// ir_fprintf(f, ">");
|
// ir_fprintf(f, ">");
|
||||||
// ir_write_byte(f, '\n');
|
// ir_write_byte(f, '\n');
|
||||||
// } break;
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
case irInstr_BoundsCheck: {
|
case irInstr_BoundsCheck: {
|
||||||
@@ -1529,7 +1578,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
ir_print_value(f, m, bc->len, t_int);
|
ir_print_value(f, m, bc->len, t_int);
|
||||||
|
|
||||||
ir_fprintf(f, ")\n");
|
ir_fprintf(f, ")\n");
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case irInstr_SliceBoundsCheck: {
|
case irInstr_SliceBoundsCheck: {
|
||||||
irInstrSliceBoundsCheck *bc = &instr->SliceBoundsCheck;
|
irInstrSliceBoundsCheck *bc = &instr->SliceBoundsCheck;
|
||||||
@@ -1571,7 +1621,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ir_fprintf(f, ")\n");
|
ir_fprintf(f, ")\n");
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case irInstr_DebugDeclare: {
|
case irInstr_DebugDeclare: {
|
||||||
@@ -1596,7 +1647,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
|
|||||||
ir_fprintf(f, ", !dbg !DILocation(line: %td, column: %td, scope: !%d)", pos.line, pos.column, di->id);
|
ir_fprintf(f, ", !dbg !DILocation(line: %td, column: %td, scope: !%d)", pos.line, pos.column, di->id);
|
||||||
|
|
||||||
ir_write_byte(f, '\n');
|
ir_write_byte(f, '\n');
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1925,7 +1977,8 @@ void print_llvm_ir(irGen *ir) {
|
|||||||
")",
|
")",
|
||||||
file->id);
|
file->id);
|
||||||
|
|
||||||
} break;
|
break;
|
||||||
|
}
|
||||||
case irDebugInfo_File:
|
case irDebugInfo_File:
|
||||||
ir_fprintf(f, "!DIFile(filename: \"");
|
ir_fprintf(f, "!DIFile(filename: \"");
|
||||||
ir_print_escape_string(f, di->File.filename, false);
|
ir_print_escape_string(f, di->File.filename, false);
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ struct TypeStruct {
|
|||||||
bool is_raw_union;
|
bool is_raw_union;
|
||||||
bool is_polymorphic;
|
bool is_polymorphic;
|
||||||
bool is_poly_specialized;
|
bool is_poly_specialized;
|
||||||
|
bool has_proc_default_values;
|
||||||
Type * polymorphic_params; // Type_Tuple
|
Type * polymorphic_params; // Type_Tuple
|
||||||
Type * polymorphic_parent;
|
Type * polymorphic_parent;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user