mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Fix exact value bug when updating expressions
This commit is contained in:
@@ -1,6 +1,13 @@
|
|||||||
#import "fmt.odin"
|
#import "fmt.odin"
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
|
Thing :: struct {
|
||||||
|
f: f32
|
||||||
|
a: any
|
||||||
|
}
|
||||||
|
t := Thing{1, "Hello"}
|
||||||
|
|
||||||
|
|
||||||
|
fmt.printf("Here % %\n", 123, 2.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-8
@@ -74,11 +74,12 @@ type_info_base :: proc(info: ^Type_Info) -> ^Type_Info {
|
|||||||
if info == nil {
|
if info == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
match type i : info {
|
base := info
|
||||||
|
match type i : base {
|
||||||
case Type_Info.Named:
|
case Type_Info.Named:
|
||||||
info = i.base
|
base = i.base
|
||||||
}
|
}
|
||||||
return info
|
return base
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -259,10 +260,10 @@ __string_eq :: proc(a, b: string) -> bool {
|
|||||||
if a.count != b.count {
|
if a.count != b.count {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if ^a[0] == ^b[0] {
|
if a.data == b.data {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return mem.compare(^a[0], ^b[0], a.count) == 0
|
return mem.compare(a.data, b.data, a.count) == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
__string_cmp :: proc(a, b : string) -> int {
|
__string_cmp :: proc(a, b : string) -> int {
|
||||||
@@ -312,9 +313,7 @@ __substring_expr_error :: proc(file: string, line, column: int,
|
|||||||
}
|
}
|
||||||
|
|
||||||
__enum_to_string :: proc(info: ^Type_Info, value: i64) -> string {
|
__enum_to_string :: proc(info: ^Type_Info, value: i64) -> string {
|
||||||
info = type_info_base(info)
|
match type ti : type_info_base(info) {
|
||||||
|
|
||||||
match type ti : info {
|
|
||||||
case Type_Info.Enum:
|
case Type_Info.Enum:
|
||||||
// TODO(bill): Search faster than linearly
|
// TODO(bill): Search faster than linearly
|
||||||
for i := 0; i < ti.values.count; i++ {
|
for i := 0; i < ti.values.count; i++ {
|
||||||
|
|||||||
+7
-5
@@ -90,7 +90,8 @@ print_pointer_to_buffer :: proc(buffer: ^[]byte, p: rawptr) #inline {
|
|||||||
|
|
||||||
print_f32_to_buffer :: proc(buffer: ^[]byte, f: f32) #inline { print__f64(buffer, f as f64, 7) }
|
print_f32_to_buffer :: proc(buffer: ^[]byte, f: f32) #inline { print__f64(buffer, f as f64, 7) }
|
||||||
print_f64_to_buffer :: proc(buffer: ^[]byte, f: f64) #inline { print__f64(buffer, f, 10) }
|
print_f64_to_buffer :: proc(buffer: ^[]byte, f: f64) #inline { print__f64(buffer, f, 10) }
|
||||||
print_u64_to_buffer :: proc(buffer: ^[]byte, i: u64) {
|
print_u64_to_buffer :: proc(buffer: ^[]byte, value: u64) {
|
||||||
|
i := value
|
||||||
buf: [22]byte
|
buf: [22]byte
|
||||||
len := 0
|
len := 0
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
@@ -105,7 +106,8 @@ print_u64_to_buffer :: proc(buffer: ^[]byte, i: u64) {
|
|||||||
byte_reverse(buf[:len])
|
byte_reverse(buf[:len])
|
||||||
print_string_to_buffer(buffer, buf[:len] as string)
|
print_string_to_buffer(buffer, buf[:len] as string)
|
||||||
}
|
}
|
||||||
print_i64_to_buffer :: proc(buffer: ^[]byte, i: i64) {
|
print_i64_to_buffer :: proc(buffer: ^[]byte, value: i64) {
|
||||||
|
i := value
|
||||||
neg := i < 0
|
neg := i < 0
|
||||||
if neg {
|
if neg {
|
||||||
i = -i
|
i = -i
|
||||||
@@ -114,7 +116,8 @@ print_i64_to_buffer :: proc(buffer: ^[]byte, i: i64) {
|
|||||||
print_u64_to_buffer(buffer, i as u64)
|
print_u64_to_buffer(buffer, i as u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
print__f64 :: proc(buffer: ^[]byte, f: f64, decimal_places: int) {
|
print__f64 :: proc(buffer: ^[]byte, value: f64, decimal_places: int) {
|
||||||
|
f := value
|
||||||
if f == 0 {
|
if f == 0 {
|
||||||
print_rune_to_buffer(buffer, #rune "0")
|
print_rune_to_buffer(buffer, #rune "0")
|
||||||
return
|
return
|
||||||
@@ -555,12 +558,11 @@ bprintf :: proc(buf: ^[]byte, fmt: string, args: ..any) {
|
|||||||
bprint :: proc(buf: ^[]byte, args: ..any) {
|
bprint :: proc(buf: ^[]byte, args: ..any) {
|
||||||
is_type_string :: proc(info: ^Type_Info) -> bool {
|
is_type_string :: proc(info: ^Type_Info) -> bool {
|
||||||
using Type_Info
|
using Type_Info
|
||||||
info = type_info_base(info)
|
|
||||||
if info == nil {
|
if info == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
match type i : info {
|
match type i : type_info_base(info) {
|
||||||
case String:
|
case String:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -39,7 +39,8 @@ accept_sizes := [256]byte{
|
|||||||
0x34, 0x04, 0x04, 0x04, 0x44, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0xf0-0xff
|
0x34, 0x04, 0x04, 0x04, 0x44, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0xf0-0xff
|
||||||
}
|
}
|
||||||
|
|
||||||
encode_rune :: proc(r: rune) -> ([4]byte, int) {
|
encode_rune :: proc(r_: rune) -> ([4]byte, int) {
|
||||||
|
r := r_
|
||||||
buf: [4]byte
|
buf: [4]byte
|
||||||
i := r as u32
|
i := r as u32
|
||||||
mask: byte : 0x3f
|
mask: byte : 0x3f
|
||||||
|
|||||||
@@ -645,7 +645,6 @@ void add_untyped(CheckerInfo *i, AstNode *expression, b32 lhs, AddressingMode mo
|
|||||||
map_set(&i->untyped, hash_pointer(expression), make_expression_info(lhs, mode, basic_type, value));
|
map_set(&i->untyped, hash_pointer(expression), make_expression_info(lhs, mode, basic_type, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void add_type_and_value(CheckerInfo *i, AstNode *expression, AddressingMode mode, Type *type, ExactValue value) {
|
void add_type_and_value(CheckerInfo *i, AstNode *expression, AddressingMode mode, Type *type, ExactValue value) {
|
||||||
GB_ASSERT(expression != NULL);
|
GB_ASSERT(expression != NULL);
|
||||||
if (mode == Addressing_Invalid)
|
if (mode == Addressing_Invalid)
|
||||||
@@ -1306,7 +1305,7 @@ void check_parsed_files(Checker *c) {
|
|||||||
ExpressionInfo *info = &entry->value;
|
ExpressionInfo *info = &entry->value;
|
||||||
if (info != NULL && expr != NULL) {
|
if (info != NULL && expr != NULL) {
|
||||||
if (is_type_typed(info->type)) {
|
if (is_type_typed(info->type)) {
|
||||||
compiler_error("%s (type %s) is typed!", expr_to_string(expr), info->type);
|
compiler_error("%s (type %s) is typed!", expr_to_string(expr), type_to_string(info->type));
|
||||||
}
|
}
|
||||||
add_type_and_value(&c->info, expr, info->mode, info->type, info->value);
|
add_type_and_value(&c->info, expr, info->mode, info->type, info->value);
|
||||||
}
|
}
|
||||||
|
|||||||
+36
-18
@@ -933,7 +933,11 @@ void check_identifier(Checker *c, Operand *o, AstNode *n, Type *named_type, Cycl
|
|||||||
o->type = t_invalid;
|
o->type = t_invalid;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
o->mode = Addressing_Variable;
|
// if (e->Variable.param) {
|
||||||
|
// o->mode = Addressing_Value;
|
||||||
|
// } else {
|
||||||
|
o->mode = Addressing_Variable;
|
||||||
|
// }
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Entity_TypeName: {
|
case Entity_TypeName: {
|
||||||
@@ -2239,7 +2243,6 @@ void convert_to_typed(Checker *c, Operand *operand, Type *target_type, i32 level
|
|||||||
|
|
||||||
|
|
||||||
operand->type = target_type;
|
operand->type = target_type;
|
||||||
update_expr_type(c, operand->expr, target_type, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
b32 check_index_value(Checker *c, AstNode *index_value, i64 max_count, i64 *value) {
|
b32 check_index_value(Checker *c, AstNode *index_value, i64 max_count, i64 *value) {
|
||||||
@@ -3265,7 +3268,6 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode
|
|||||||
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
|
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
|
||||||
defer (gb_temp_arena_memory_end(tmp));
|
defer (gb_temp_arena_memory_end(tmp));
|
||||||
|
|
||||||
isize operand_count = 0;
|
|
||||||
Array<Operand> operands;
|
Array<Operand> operands;
|
||||||
array_init(&operands, c->tmp_allocator, 2*param_count);
|
array_init(&operands, c->tmp_allocator, 2*param_count);
|
||||||
|
|
||||||
@@ -3289,11 +3291,10 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
operand_count = operands.count;
|
|
||||||
i32 error_code = 0;
|
i32 error_code = 0;
|
||||||
if (operand_count < param_count) {
|
if (operands.count < param_count) {
|
||||||
error_code = -1;
|
error_code = -1;
|
||||||
} else if (!variadic && operand_count > param_count) {
|
} else if (!variadic && operands.count > param_count) {
|
||||||
error_code = +1;
|
error_code = +1;
|
||||||
}
|
}
|
||||||
if (error_code != 0) {
|
if (error_code != 0) {
|
||||||
@@ -3303,16 +3304,22 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode
|
|||||||
}
|
}
|
||||||
|
|
||||||
gbString proc_str = expr_to_string(ce->proc);
|
gbString proc_str = expr_to_string(ce->proc);
|
||||||
|
defer (gb_string_free(proc_str));
|
||||||
error(ast_node_token(call), err_fmt, proc_str, param_count);
|
error(ast_node_token(call), err_fmt, proc_str, param_count);
|
||||||
gb_string_free(proc_str);
|
|
||||||
operand->mode = Addressing_Invalid;
|
operand->mode = Addressing_Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
GB_ASSERT(proc_type->Proc.params != NULL);
|
GB_ASSERT(proc_type->Proc.params != NULL);
|
||||||
Entity **sig_params = proc_type->Proc.params->Tuple.variables;
|
Entity **sig_params = proc_type->Proc.params->Tuple.variables;
|
||||||
for (isize i = 0; i < param_count; i++) {
|
isize operand_index = 0;
|
||||||
Type *arg_type = sig_params[i]->type;
|
for (; operand_index < param_count; operand_index++) {
|
||||||
check_assignment(c, &operands[i], arg_type, make_string("argument"), true);
|
Type *arg_type = sig_params[operand_index]->type;
|
||||||
|
Operand o = operands[operand_index];
|
||||||
|
if (variadic) {
|
||||||
|
|
||||||
|
o = operands[operand_index];
|
||||||
|
}
|
||||||
|
check_assignment(c, &o, arg_type, make_string("argument"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (variadic) {
|
if (variadic) {
|
||||||
@@ -3320,18 +3327,18 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode
|
|||||||
Type *slice = sig_params[param_count]->type;
|
Type *slice = sig_params[param_count]->type;
|
||||||
Type *elem = base_type(slice)->Slice.elem;
|
Type *elem = base_type(slice)->Slice.elem;
|
||||||
Type *t = elem;
|
Type *t = elem;
|
||||||
for (isize i = param_count; i < operand_count; i++) {
|
for (; operand_index < operands.count; operand_index++) {
|
||||||
Operand *o = &operands[i];
|
Operand o = operands[operand_index];
|
||||||
if (vari_expand) {
|
if (vari_expand) {
|
||||||
variadic_expand = true;
|
variadic_expand = true;
|
||||||
t = slice;
|
t = slice;
|
||||||
if (i != param_count) {
|
if (operand_index != param_count) {
|
||||||
error(ast_node_token(o->expr),
|
error(ast_node_token(o.expr),
|
||||||
"`..` in a variadic procedure can only have one variadic argument at the end");
|
"`..` in a variadic procedure can only have one variadic argument at the end");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
check_assignment(c, o, t, make_string("argument"), true);
|
check_assignment(c, &o, t, make_string("argument"), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3574,10 +3581,14 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
|
|||||||
fields_visited[sel.index[0]] = true;
|
fields_visited[sel.index[0]] = true;
|
||||||
check_expr(c, o, fv->value);
|
check_expr(c, o, fv->value);
|
||||||
|
|
||||||
|
if (base_type(field->type) == t_any) {
|
||||||
|
is_constant = false;
|
||||||
|
}
|
||||||
if (is_constant) {
|
if (is_constant) {
|
||||||
is_constant = o->mode == Addressing_Constant;
|
is_constant = o->mode == Addressing_Constant;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
check_assignment(c, o, field->type, make_string("structure literal"));
|
check_assignment(c, o, field->type, make_string("structure literal"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -3596,6 +3607,9 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (base_type(field->type) == t_any) {
|
||||||
|
is_constant = false;
|
||||||
|
}
|
||||||
if (is_constant) {
|
if (is_constant) {
|
||||||
is_constant = o->mode == Addressing_Constant;
|
is_constant = o->mode == Addressing_Constant;
|
||||||
}
|
}
|
||||||
@@ -3632,15 +3646,18 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
|
|||||||
isize index = 0;
|
isize index = 0;
|
||||||
isize elem_count = cl->elems.count;
|
isize elem_count = cl->elems.count;
|
||||||
|
|
||||||
|
if (base_type(elem_type) == t_any) {
|
||||||
|
is_constant = false;
|
||||||
|
}
|
||||||
|
|
||||||
for (; index < elem_count; index++) {
|
for (; index < elem_count; index++) {
|
||||||
AstNode *e = cl->elems[index];
|
AstNode *e = cl->elems[index];
|
||||||
if (e->kind == AstNode_FieldValue) {
|
if (e->kind == AstNode_FieldValue) {
|
||||||
error(ast_node_token(e),
|
error(ast_node_token(e),
|
||||||
"`field = value` is only allowed in structure literals");
|
"`field = value` is only allowed in struct literals");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (t->kind == Type_Array &&
|
if (t->kind == Type_Array &&
|
||||||
t->Array.count >= 0 &&
|
t->Array.count >= 0 &&
|
||||||
index >= t->Array.count) {
|
index >= t->Array.count) {
|
||||||
@@ -3660,8 +3677,9 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
|
|||||||
is_constant = operand.mode == Addressing_Constant;
|
is_constant = operand.mode == Addressing_Constant;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (max < index)
|
if (max < index) {
|
||||||
max = index;
|
max = index;
|
||||||
|
}
|
||||||
|
|
||||||
if (t->kind == Type_Vector) {
|
if (t->kind == Type_Vector) {
|
||||||
if (t->Vector.count > 1 && gb_is_between(index, 2, t->Vector.count-1)) {
|
if (t->Vector.count > 1 && gb_is_between(index, 2, t->Vector.count-1)) {
|
||||||
|
|||||||
@@ -145,12 +145,10 @@ void ssa_print_type(ssaFileBuffer *f, ssaModule *m, Type *t) {
|
|||||||
case Basic_i16: ssa_fprintf(f, "i16"); break;
|
case Basic_i16: ssa_fprintf(f, "i16"); break;
|
||||||
case Basic_i32: ssa_fprintf(f, "i32"); break;
|
case Basic_i32: ssa_fprintf(f, "i32"); break;
|
||||||
case Basic_i64: ssa_fprintf(f, "i64"); break;
|
case Basic_i64: ssa_fprintf(f, "i64"); break;
|
||||||
// case Basic_i128: ssa_fprintf(f, "i128"); break;
|
|
||||||
case Basic_u8: ssa_fprintf(f, "i8"); break;
|
case Basic_u8: ssa_fprintf(f, "i8"); break;
|
||||||
case Basic_u16: ssa_fprintf(f, "i16"); break;
|
case Basic_u16: ssa_fprintf(f, "i16"); break;
|
||||||
case Basic_u32: ssa_fprintf(f, "i32"); break;
|
case Basic_u32: ssa_fprintf(f, "i32"); break;
|
||||||
case Basic_u64: ssa_fprintf(f, "i64"); break;
|
case Basic_u64: ssa_fprintf(f, "i64"); break;
|
||||||
// case Basic_u128: ssa_fprintf(f, "i128"); break;
|
|
||||||
case Basic_f32: ssa_fprintf(f, "float"); break;
|
case Basic_f32: ssa_fprintf(f, "float"); break;
|
||||||
case Basic_f64: ssa_fprintf(f, "double"); break;
|
case Basic_f64: ssa_fprintf(f, "double"); break;
|
||||||
case Basic_rawptr: ssa_fprintf(f, "%%..rawptr"); break;
|
case Basic_rawptr: ssa_fprintf(f, "%%..rawptr"); break;
|
||||||
@@ -176,12 +174,11 @@ void ssa_print_type(ssaFileBuffer *f, ssaModule *m, Type *t) {
|
|||||||
ssa_print_type(f, m, t->Array.elem);
|
ssa_print_type(f, m, t->Array.elem);
|
||||||
ssa_fprintf(f, "]");
|
ssa_fprintf(f, "]");
|
||||||
break;
|
break;
|
||||||
case Type_Vector: {
|
case Type_Vector:
|
||||||
// TODO(bill): actually do correctly
|
|
||||||
ssa_fprintf(f, "<%lld x ", t->Vector.count);
|
ssa_fprintf(f, "<%lld x ", t->Vector.count);
|
||||||
ssa_print_type(f, m, t->Vector.elem);
|
ssa_print_type(f, m, t->Vector.elem);
|
||||||
ssa_fprintf(f, ">");
|
ssa_fprintf(f, ">");
|
||||||
} break;
|
break;
|
||||||
case Type_Slice:
|
case Type_Slice:
|
||||||
ssa_fprintf(f, "{");
|
ssa_fprintf(f, "{");
|
||||||
ssa_print_type(f, m, t->Slice.elem);
|
ssa_print_type(f, m, t->Slice.elem);
|
||||||
@@ -278,7 +275,7 @@ void ssa_print_compound_element(ssaFileBuffer *f, ssaModule *m, ExactValue v, Ty
|
|||||||
ssa_fprintf(f, " ");
|
ssa_fprintf(f, " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v.kind == ExactValue_Invalid) {
|
if (v.kind == ExactValue_Invalid || base_type(elem_type) == t_any) {
|
||||||
ssa_fprintf(f, "zeroinitializer");
|
ssa_fprintf(f, "zeroinitializer");
|
||||||
} else if (v.kind == ExactValue_String) {
|
} else if (v.kind == ExactValue_String) {
|
||||||
// HACK NOTE(bill): This is a hack but it works because strings are created at the very end
|
// HACK NOTE(bill): This is a hack but it works because strings are created at the very end
|
||||||
|
|||||||
+23
-12
@@ -1418,6 +1418,7 @@ void ssa_end_procedure_body(ssaProcedure *proc) {
|
|||||||
proc->curr_block = proc->decl_block;
|
proc->curr_block = proc->decl_block;
|
||||||
ssa_emit_jump(proc, proc->entry_block);
|
ssa_emit_jump(proc, proc->entry_block);
|
||||||
|
|
||||||
|
#if 0
|
||||||
ssa_optimize_blocks(proc);
|
ssa_optimize_blocks(proc);
|
||||||
ssa_build_referrers(proc);
|
ssa_build_referrers(proc);
|
||||||
ssa_build_dom_tree(proc);
|
ssa_build_dom_tree(proc);
|
||||||
@@ -1428,7 +1429,7 @@ void ssa_end_procedure_body(ssaProcedure *proc) {
|
|||||||
// [ ] Local stored once? Replace loads with dominating store
|
// [ ] Local stored once? Replace loads with dominating store
|
||||||
// [ ] Convert to phi nodes
|
// [ ] Convert to phi nodes
|
||||||
ssa_opt_mem2reg(proc);
|
ssa_opt_mem2reg(proc);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Number registers
|
// Number registers
|
||||||
i32 reg_index = 0;
|
i32 reg_index = 0;
|
||||||
@@ -1923,6 +1924,7 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t, b32 is_arg
|
|||||||
ev = exact_value_to_float(ev);
|
ev = exact_value_to_float(ev);
|
||||||
} else if (is_type_string(dst)) {
|
} else if (is_type_string(dst)) {
|
||||||
// Handled elsewhere
|
// Handled elsewhere
|
||||||
|
GB_ASSERT(ev.kind == ExactValue_String);
|
||||||
} else if (is_type_integer(dst)) {
|
} else if (is_type_integer(dst)) {
|
||||||
ev = exact_value_to_integer(ev);
|
ev = exact_value_to_integer(ev);
|
||||||
} else if (is_type_pointer(dst)) {
|
} else if (is_type_pointer(dst)) {
|
||||||
@@ -2479,7 +2481,10 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
|||||||
case Type_Slice: et = bt->Slice.elem; break;
|
case Type_Slice: et = bt->Slice.elem; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto is_elem_const = [](ssaModule *m, AstNode *elem) -> b32 {
|
auto is_elem_const = [](ssaModule *m, AstNode *elem, Type *elem_type) -> b32 {
|
||||||
|
if (base_type(elem_type) == t_any) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (elem->kind == AstNode_FieldValue) {
|
if (elem->kind == AstNode_FieldValue) {
|
||||||
elem = elem->FieldValue.value;
|
elem = elem->FieldValue.value;
|
||||||
}
|
}
|
||||||
@@ -2495,7 +2500,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
|||||||
ssaValue *result = ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr));
|
ssaValue *result = ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr));
|
||||||
for_array(index, cl->elems) {
|
for_array(index, cl->elems) {
|
||||||
AstNode *elem = cl->elems[index];
|
AstNode *elem = cl->elems[index];
|
||||||
if (is_elem_const(proc->module, elem)) {
|
if (is_elem_const(proc->module, elem, et)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ssaValue *field_elem = ssa_build_expr(proc, elem);
|
ssaValue *field_elem = ssa_build_expr(proc, elem);
|
||||||
@@ -2526,9 +2531,6 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
|||||||
ssa_emit_store(proc, v, ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr)));
|
ssa_emit_store(proc, v, ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr)));
|
||||||
for_array(field_index, cl->elems) {
|
for_array(field_index, cl->elems) {
|
||||||
AstNode *elem = cl->elems[field_index];
|
AstNode *elem = cl->elems[field_index];
|
||||||
if (is_elem_const(proc->module, elem)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssaValue *field_expr = NULL;
|
ssaValue *field_expr = NULL;
|
||||||
Entity *field = NULL;
|
Entity *field = NULL;
|
||||||
@@ -2538,17 +2540,23 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
|||||||
ast_node(fv, FieldValue, elem);
|
ast_node(fv, FieldValue, elem);
|
||||||
Selection sel = lookup_field(proc->module->allocator, bt, fv->field->Ident.string, false);
|
Selection sel = lookup_field(proc->module->allocator, bt, fv->field->Ident.string, false);
|
||||||
index = sel.index[0];
|
index = sel.index[0];
|
||||||
field_expr = ssa_build_expr(proc, fv->value);
|
elem = fv->value;
|
||||||
} else {
|
} else {
|
||||||
TypeAndValue *tav = type_and_value_of_expression(proc->module->info, elem);
|
TypeAndValue *tav = type_and_value_of_expression(proc->module->info, elem);
|
||||||
Selection sel = lookup_field(proc->module->allocator, bt, st->fields_in_src_order[field_index]->token.string, false);
|
Selection sel = lookup_field(proc->module->allocator, bt, st->fields_in_src_order[field_index]->token.string, false);
|
||||||
index = sel.index[0];
|
index = sel.index[0];
|
||||||
field_expr = ssa_build_expr(proc, elem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
field = st->fields[index];
|
||||||
|
if (is_elem_const(proc->module, elem, field->type)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
field_expr = ssa_build_expr(proc, elem);
|
||||||
|
|
||||||
GB_ASSERT(ssa_type(field_expr)->kind != Type_Tuple);
|
GB_ASSERT(ssa_type(field_expr)->kind != Type_Tuple);
|
||||||
|
|
||||||
field = st->fields[index];
|
|
||||||
|
|
||||||
Type *ft = field->type;
|
Type *ft = field->type;
|
||||||
ssaValue *fv = ssa_emit_conv(proc, field_expr, ft);
|
ssaValue *fv = ssa_emit_conv(proc, field_expr, ft);
|
||||||
@@ -2562,7 +2570,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
|||||||
ssa_emit_store(proc, v, ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr)));
|
ssa_emit_store(proc, v, ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr)));
|
||||||
for_array(i, cl->elems) {
|
for_array(i, cl->elems) {
|
||||||
AstNode *elem = cl->elems[i];
|
AstNode *elem = cl->elems[i];
|
||||||
if (is_elem_const(proc->module, elem)) {
|
if (is_elem_const(proc->module, elem, et)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ssaValue *field_expr = ssa_build_expr(proc, elem);
|
ssaValue *field_expr = ssa_build_expr(proc, elem);
|
||||||
@@ -2587,7 +2595,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
|||||||
|
|
||||||
for_array(i, cl->elems) {
|
for_array(i, cl->elems) {
|
||||||
AstNode *elem = cl->elems[i];
|
AstNode *elem = cl->elems[i];
|
||||||
if (is_elem_const(proc->module,elem)) {
|
if (is_elem_const(proc->module, elem, et)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3034,12 +3042,15 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
|||||||
ssa_emit_store(proc, ssa_emit_struct_gep(proc, slice, v_two32, t_int), len);
|
ssa_emit_store(proc, ssa_emit_struct_gep(proc, slice, v_two32, t_int), len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (args[0]->kind == ssaValue_Constant) {
|
||||||
|
auto *c = &args[0]->Constant;
|
||||||
|
gb_printf_err("%s %d\n", type_to_string(c->type), c->value.kind);
|
||||||
|
}
|
||||||
|
|
||||||
arg_count = type->param_count;
|
arg_count = type->param_count;
|
||||||
args[arg_count-1] = ssa_emit_load(proc, slice);
|
args[arg_count-1] = ssa_emit_load(proc, slice);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return ssa_emit_call(proc, value, args, arg_count);
|
return ssa_emit_call(proc, value, args, arg_count);
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user