diff --git a/core/_preload.odin b/core/_preload.odin index 43eb598d2..cd6cb3b55 100644 --- a/core/_preload.odin +++ b/core/_preload.odin @@ -721,18 +721,16 @@ __mem_copy_non_overlapping :: proc(dst, src: rawptr, len: int) -> rawptr #cc_con 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" ---; } 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); return dst; } __mem_compare :: proc(a, b: ^u8, n: int) -> int #cc_contextless { - for i in 0..n { - switch { - case (a+i)^ < (b+i)^: return -1; - case (a+i)^ > (b+i)^: return +1; - } + for i in 0..n do switch { + case (a+i)^ < (b+i)^: return -1; + case (a+i)^ > (b+i)^: return +1; } return 0; } diff --git a/core/c.odin b/core/c.odin index 300817814..fbfb35a74 100644 --- a/core/c.odin +++ b/core/c.odin @@ -13,17 +13,13 @@ c_ushort :: i16; c_int :: i32; c_uint :: u32; -when ODIN_OS == "windows" { - c_long :: i32; -} else when size_of(int) == 4 { +when ODIN_OS == "windows" || size_of(int) == 4 { c_long :: i32; } else { c_long :: i64; } -when ODIN_OS == "windows" { - c_ulong :: u32; -} else when size_of(uint) == 4 { +when ODIN_OS == "windows" || size_of(uint) == 4 { c_ulong :: u32; } else { c_ulong :: u64; diff --git a/src/check_expr.cpp b/src/check_expr.cpp index c5dc436b2..dd172634b 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -1035,7 +1035,12 @@ Array check_struct_fields(Checker *c, AstNode *node, Array if (is_operand_nil(o)) { default_is_nil = true; } 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 { value = o.value; } @@ -1329,10 +1334,10 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node, Arraypolymorphic_params != nullptr) { ast_node(field_list, FieldList, st->polymorphic_params); @@ -1481,12 +1486,12 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node, ArrayStruct.scope = c->context.scope; - struct_type->Struct.is_packed = st->is_packed; - struct_type->Struct.is_ordered = st->is_ordered; - struct_type->Struct.polymorphic_params = polymorphic_params; - struct_type->Struct.is_polymorphic = is_polymorphic; - struct_type->Struct.is_poly_specialized = is_poly_specialized; + struct_type->Struct.scope = c->context.scope; + struct_type->Struct.is_packed = st->is_packed; + struct_type->Struct.is_ordered = st->is_ordered; + struct_type->Struct.polymorphic_params = polymorphic_params; + struct_type->Struct.is_polymorphic = is_polymorphic; + struct_type->Struct.is_poly_specialized = is_poly_specialized; Array fields = {}; @@ -1497,6 +1502,16 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node, ArrayStruct.fields = 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) { type_set_offsets(c->allocator, struct_type); diff --git a/src/exact_value.cpp b/src/exact_value.cpp index 4f9f1e40f..ac70b42f4 100644 --- a/src/exact_value.cpp +++ b/src/exact_value.cpp @@ -22,6 +22,7 @@ enum ExactValueKind { ExactValue_Complex, ExactValue_Pointer, ExactValue_Compound, // TODO(bill): Is this good enough? + ExactValue_Procedure, // TODO(bill): Is this good enough? ExactValue_Type, ExactValue_Count, @@ -37,6 +38,7 @@ struct ExactValue { i64 value_pointer; Complex128 value_complex; AstNode * value_compound; + AstNode * value_procedure; Type * value_type; }; }; @@ -109,6 +111,12 @@ ExactValue exact_value_type(Type *type) { 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) { return exact_value_u128(u128_from_string(string)); diff --git a/src/ir.cpp b/src/ir.cpp index 673cb5a54..0fe5f544e 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -20,10 +20,12 @@ struct irModule { // String triple; PtrSet min_dep_set; - Map values; // Key: Entity * - Map members; // Key: String - Map entity_names; // Key: Entity * of the typename - Map debug_info; // Key: Unique pointer + Map values; // Key: Entity * + Map members; // Key: String + Map entity_names; // Key: Entity * of the typename + Map debug_info; // Key: Unique pointer + Map anonymous_proc_lits; // Key: AstNode * + i32 global_string_index; i32 global_array_index; // For ConstantSlice 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) { if (e->type == nullptr) return; @@ -3759,13 +3793,29 @@ void ir_gen_global_type_name(irModule *m, Entity *e, String name) { } #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) { - 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->Struct.has_proc_default_values) { + for_array(i, bt->Struct.fields) { + Entity *f = bt->Struct.fields[i]; + if (f->kind == Entity_Variable) { + if (f->Variable.default_value.kind == ExactValue_Procedure) { + 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; } - irValue *ir_build_expr(irProcedure *proc, AstNode *expr) { expr = unparen_expr(expr); @@ -4832,24 +4881,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) { case_end; case_ast_node(pl, ProcLit, expr); - // NOTE(bill): Generate a new name - // 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; + return ir_gen_anonymous_proc_lit(proc->module, proc->name, expr, proc); case_end; @@ -7424,6 +7456,7 @@ void ir_init_module(irModule *m, Checker *c) { map_init(&m->members, heap_allocator()); map_init(&m->debug_info, 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_to_generate, 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->members); map_destroy(&m->entity_names); + map_destroy(&m->anonymous_proc_lits); map_destroy(&m->debug_info); map_destroy(&m->const_strings); array_free(&m->procs); @@ -8535,7 +8569,9 @@ void ir_gen_tree(irGen *s) { 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 diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 70a1defb5..8b728acdf 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -341,7 +341,8 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) { } return; } - } break; + break; + } 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)); // GB_ASSERT_MSG(found != nullptr, "%.*s %p", LIT(t->Named.name), t->Named.type_name); } - } break; + break; + } default: ir_print_type(f, m, base_type(t)); break; @@ -389,13 +391,15 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t) { generate_map_internal_types(m->allocator, t); GB_ASSERT(t->Map.generated_struct_type != nullptr); ir_print_type(f, m, t->Map.generated_struct_type); - } break; + break; + } case Type_BitField: { i64 align = type_align_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); - } 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_fprintf(f, " %lld}", cast(i64)str.len); } - } break; + break; + } case ExactValue_Integer: { if (is_type_pointer(type)) { 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 { ir_write_i128(f, value.value_integer); } - } break; + break; + } case ExactValue_Float: { GB_ASSERT_MSG(is_type_float(type), "%s", type_to_string(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); break; } - } break; + break; + } case ExactValue_Complex: { 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_print_exact_value(f, m, exact_value_float(value.value_complex.imag), ft); ir_write_byte(f, '}'); - } break; + break; + } case ExactValue_Pointer: 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"); } - } 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: { 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); - } 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_fprintf(f, " %lld}", cs->count); } - } break; + break; + } case irValue_Nil: 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; } ir_print_encoded_global(f, ir_get_global_name(m, value), in_global_scope); - } break; + break; + } case irValue_Param: ir_print_encoded_local(f, value->Param.entity->token.string); break; @@ -864,13 +887,15 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { default: { GB_PANIC(" %d\n", instr->kind); ir_fprintf(f, "; %d\n", instr->kind); - } break; + break; + } case irInstr_StartupRuntime: { ir_write_string(f, "call void "); ir_print_encoded_global(f, str_lit(IR_STARTUP_RUNTIME_PROC_NAME), false); ir_write_string(f, "()\n"); - } break; + break; + } case irInstr_Comment: 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_print_type(f, m, type); ir_fprintf(f, ", align %lld\n", align); - } break; + break; + } case irInstr_ZeroInit: { 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_print_type(f, m, type); ir_fprintf(f, "* %%%d\n", instr->ZeroInit.address->index); - } break; + break; + } case irInstr_Store: { 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_print_value(f, m, instr->Store.address, type); ir_write_byte(f, '\n'); - } break; + break; + } case irInstr_Load: { Type *type = instr->Load.type; @@ -922,7 +950,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { ir_write_string(f, "* "); ir_print_value(f, m, instr->Load.address, type); ir_fprintf(f, ", align %lld\n", type_align_of(m->allocator, type)); - } break; + break; + } case irInstr_ArrayElementPtr: { 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_print_value(f, m, index, t); ir_write_byte(f, '\n'); - } break; + break; + } case irInstr_StructElementPtr: { 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_fprintf(f, " %d", index); ir_write_byte(f, '\n'); - } break; + break; + } case irInstr_PtrOffset: { 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_print_value(f, m, offset, t); ir_write_byte(f, '\n'); - } break; + break; + } case irInstr_Phi: { 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_byte(f, '\n'); - } break; + break; + } case irInstr_StructExtractValue: { 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_print_value(f, m, instr->StructExtractValue.address, et); ir_fprintf(f, ", %d\n", index); - } break; + break; + } case irInstr_UnionTagPtr: { Type *et = ir_type(instr->UnionTagPtr.address); @@ -1062,7 +1096,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { #endif ir_write_string(f, " ; UnionTagPtr"); ir_write_byte(f, '\n'); - } break; + break; + } case irInstr_UnionTagValue: { Type *et = ir_type(instr->UnionTagValue.address); @@ -1081,13 +1116,15 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { #endif ir_write_string(f, " ; UnionTagValue"); ir_write_byte(f, '\n'); - } break; + break; + } case irInstr_Jump: {; ir_write_string(f, "br label %"); ir_print_block_name(f, instr->Jump.block); ir_write_byte(f, '\n'); - } break; + break; + } case irInstr_If: {; 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.false_block); ir_write_byte(f, '\n'); - } break; + break; + } case irInstr_Return: { irInstrReturn *ret = &instr->Return; @@ -1114,7 +1152,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { ir_write_byte(f, '\n'); - } break; + break; + } case irInstr_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_write_byte(f, '\n'); - } break; + break; + } case irInstr_Unreachable: { ir_fprintf(f, "unreachable\n"); - } break; + break; + } case irInstr_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_print_value(f, m, uo->expr, type); ir_write_byte(f, '\n'); - } break; + break; + } case irInstr_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_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_print_value(f, m, bo->right, type); ir_write_byte(f, '\n'); - } break; + break; + } case irInstr_Call: { irInstrCall *call = &instr->Call; @@ -1421,7 +1465,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { } ir_write_string(f, ")\n"); - } break; + break; + } case irInstr_Select: { 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_print_value(f, m, instr->Select.false_value, ir_type(instr->Select.false_value)); ir_write_byte(f, '\n'); - } break; + break; + } // case irInstr_VectorExtractElement: { // 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_print_value(f, m, instr->VectorExtractElement.index, it); // ir_write_byte(f, '\n'); - // } break; + // break; + // } // case irInstr_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_write_byte(f, '\n'); - // } break; + // break; + // } // case irInstr_VectorShuffle: { // irInstrVectorShuffle *sv = &instr->VectorShuffle; @@ -1498,7 +1546,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { // } // ir_fprintf(f, ">"); // ir_write_byte(f, '\n'); - // } break; + // break; + // } #if 0 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_fprintf(f, ")\n"); - } break; + break; + } case irInstr_SliceBoundsCheck: { irInstrSliceBoundsCheck *bc = &instr->SliceBoundsCheck; @@ -1571,7 +1621,8 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { } ir_fprintf(f, ")\n"); - } break; + break; + } #endif 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_write_byte(f, '\n'); - } break; + break; + } } } @@ -1925,7 +1977,8 @@ void print_llvm_ir(irGen *ir) { ")", file->id); - } break; + break; + } case irDebugInfo_File: ir_fprintf(f, "!DIFile(filename: \""); ir_print_escape_string(f, di->File.filename, false); diff --git a/src/types.cpp b/src/types.cpp index 3aeb4f3e4..7cc85f40d 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -82,6 +82,7 @@ struct TypeStruct { bool is_raw_union; bool is_polymorphic; bool is_poly_specialized; + bool has_proc_default_values; Type * polymorphic_params; // Type_Tuple Type * polymorphic_parent;