mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Fix zero value initialization in IR
This commit is contained in:
+4
-3
@@ -84,9 +84,10 @@ Type_Info_Union :: struct {
|
|||||||
tag_type: ^Type_Info,
|
tag_type: ^Type_Info,
|
||||||
};
|
};
|
||||||
Type_Info_Enum :: struct {
|
Type_Info_Enum :: struct {
|
||||||
base: ^Type_Info,
|
base: ^Type_Info,
|
||||||
names: []string,
|
names: []string,
|
||||||
values: []Type_Info_Enum_Value,
|
values: []Type_Info_Enum_Value,
|
||||||
|
is_export: bool,
|
||||||
};
|
};
|
||||||
Type_Info_Map :: struct {
|
Type_Info_Map :: struct {
|
||||||
key: ^Type_Info,
|
key: ^Type_Info,
|
||||||
|
|||||||
+31
-36
@@ -32,11 +32,12 @@ Fmt_Info :: struct {
|
|||||||
|
|
||||||
string_buffer_from_slice :: proc(backing: []byte) -> String_Buffer {
|
string_buffer_from_slice :: proc(backing: []byte) -> String_Buffer {
|
||||||
s := transmute(raw.Slice)backing;
|
s := transmute(raw.Slice)backing;
|
||||||
d: raw.Dynamic_Array;
|
d := raw.Dynamic_Array{
|
||||||
d.data = s.data;
|
data = s.data,
|
||||||
d.len = 0;
|
len = 0,
|
||||||
d.cap = s.len;
|
cap = s.len,
|
||||||
d.allocator = nil_allocator();
|
allocator = nil_allocator(),
|
||||||
|
};
|
||||||
return transmute(String_Buffer)d;
|
return transmute(String_Buffer)d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,6 +277,7 @@ write_type :: proc(buf: ^String_Buffer, ti: ^Type_Info) {
|
|||||||
case Type_Info_Enum:
|
case Type_Info_Enum:
|
||||||
write_string(buf, "enum ");
|
write_string(buf, "enum ");
|
||||||
write_type(buf, info.base);
|
write_type(buf, info.base);
|
||||||
|
if info.is_export do write_string(buf, " #export");
|
||||||
write_string(buf, " {");
|
write_string(buf, " {");
|
||||||
for name, i in info.names {
|
for name, i in info.names {
|
||||||
if i > 0 do write_string(buf, ", ");
|
if i > 0 do write_string(buf, ", ");
|
||||||
@@ -394,9 +396,7 @@ fmt_bad_verb :: proc(using fi: ^Fmt_Info, verb: rune) {
|
|||||||
fmt_bool :: proc(using fi: ^Fmt_Info, b: bool, verb: rune) {
|
fmt_bool :: proc(using fi: ^Fmt_Info, b: bool, verb: rune) {
|
||||||
switch verb {
|
switch verb {
|
||||||
case 't', 'v':
|
case 't', 'v':
|
||||||
s := "false";
|
write_string(buf, b ? "true" : "false");
|
||||||
if b do s = "true";
|
|
||||||
write_string(buf, s);
|
|
||||||
case:
|
case:
|
||||||
fmt_bad_verb(fi, verb);
|
fmt_bad_verb(fi, verb);
|
||||||
}
|
}
|
||||||
@@ -603,16 +603,14 @@ fmt_string :: proc(fi: ^Fmt_Info, s: string, verb: rune) {
|
|||||||
fmt_pointer :: proc(fi: ^Fmt_Info, p: rawptr, verb: rune) {
|
fmt_pointer :: proc(fi: ^Fmt_Info, p: rawptr, verb: rune) {
|
||||||
switch verb {
|
switch verb {
|
||||||
case 'p', 'v':
|
case 'p', 'v':
|
||||||
// Okay
|
u := u64(uintptr(p));
|
||||||
|
if !fi.hash || verb == 'v' {
|
||||||
|
write_string(fi.buf, "0x");
|
||||||
|
}
|
||||||
|
_fmt_int(fi, u, 16, false, 8*size_of(rawptr), __DIGITS_UPPER);
|
||||||
case:
|
case:
|
||||||
fmt_bad_verb(fi, verb);
|
fmt_bad_verb(fi, verb);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
u := u64(uintptr(p));
|
|
||||||
if !fi.hash || verb == 'v' {
|
|
||||||
write_string(fi.buf, "0x");
|
|
||||||
}
|
|
||||||
_fmt_int(fi, u, 16, false, 8*size_of(rawptr), __DIGITS_UPPER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum_value_to_string :: proc(v: any) -> (string, bool) {
|
enum_value_to_string :: proc(v: any) -> (string, bool) {
|
||||||
@@ -945,38 +943,35 @@ fmt_arg :: proc(fi: ^Fmt_Info, arg: any, verb: rune) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
base_arg := arg;
|
base_arg := arg;
|
||||||
base_arg.type_info = type_info_base(base_arg.type_info);
|
base_arg.type_info = type_info_base(base_arg.type_info);
|
||||||
switch a in base_arg {
|
switch a in base_arg {
|
||||||
case bool: fmt_bool(fi, bool(a), verb);
|
case bool: fmt_bool(fi, bool(a), verb);
|
||||||
case b8: fmt_bool(fi, bool(a), verb);
|
case b8: fmt_bool(fi, bool(a), verb);
|
||||||
case b16: fmt_bool(fi, bool(a), verb);
|
case b16: fmt_bool(fi, bool(a), verb);
|
||||||
case b32: fmt_bool(fi, bool(a), verb);
|
case b32: fmt_bool(fi, bool(a), verb);
|
||||||
case b64: fmt_bool(fi, bool(a), verb);
|
case b64: fmt_bool(fi, bool(a), verb);
|
||||||
|
|
||||||
case any: fmt_arg(fi, a, verb);
|
case any: fmt_arg(fi, a, verb);
|
||||||
case rune: fmt_rune(fi, a, verb);
|
case rune: fmt_rune(fi, a, verb);
|
||||||
|
|
||||||
case f32: fmt_float(fi, f64(a), 32, verb);
|
case f32: fmt_float(fi, f64(a), 32, verb);
|
||||||
case f64: fmt_float(fi, a, 64, verb);
|
case f64: fmt_float(fi, a, 64, verb);
|
||||||
|
|
||||||
case complex64: fmt_complex(fi, complex128(a), 64, verb);
|
case complex64: fmt_complex(fi, complex128(a), 64, verb);
|
||||||
case complex128: fmt_complex(fi, a, 128, verb);
|
case complex128: fmt_complex(fi, a, 128, verb);
|
||||||
|
|
||||||
case int: fmt_int(fi, u64(a), true, 8*size_of(int), verb);
|
case i8: fmt_int(fi, u64(a), true, 8, verb);
|
||||||
case i8: fmt_int(fi, u64(a), true, 8, verb);
|
case u8: fmt_int(fi, u64(a), false, 8, verb);
|
||||||
case i16: fmt_int(fi, u64(a), true, 16, verb);
|
case i16: fmt_int(fi, u64(a), true, 16, verb);
|
||||||
case i32: fmt_int(fi, u64(a), true, 32, verb);
|
|
||||||
case i64: fmt_int(fi, u64(a), true, 64, verb);
|
|
||||||
|
|
||||||
case uintptr: fmt_int(fi, u64(a), false, 8*size_of(uintptr), verb);
|
|
||||||
|
|
||||||
case uint: fmt_int(fi, u64(a), false, 8*size_of(uint), verb);
|
|
||||||
case u8: fmt_int(fi, u64(a), false, 8, verb);
|
|
||||||
case u16: fmt_int(fi, u64(a), false, 16, verb);
|
case u16: fmt_int(fi, u64(a), false, 16, verb);
|
||||||
|
case i32: fmt_int(fi, u64(a), true, 32, verb);
|
||||||
case u32: fmt_int(fi, u64(a), false, 32, verb);
|
case u32: fmt_int(fi, u64(a), false, 32, verb);
|
||||||
|
case i64: fmt_int(fi, u64(a), true, 64, verb);
|
||||||
case u64: fmt_int(fi, u64(a), false, 64, verb);
|
case u64: fmt_int(fi, u64(a), false, 64, verb);
|
||||||
|
case int: fmt_int(fi, u64(a), true, 8*size_of(int), verb);
|
||||||
|
case uint: fmt_int(fi, u64(a), false, 8*size_of(uint), verb);
|
||||||
|
case uintptr: fmt_int(fi, u64(a), false, 8*size_of(uintptr), verb);
|
||||||
|
|
||||||
case string: fmt_string(fi, a, verb);
|
case string: fmt_string(fi, a, verb);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -305,7 +305,7 @@ void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE(bill): Check to see if the expression it to be aliases
|
// NOTE(bill): Check to see if the expression it to be aliases
|
||||||
case Addressing_Builtin:
|
case Addressing_Builtin:
|
||||||
if (e->type != nullptr) {
|
if (e->type != nullptr) {
|
||||||
error(type_expr, "A constant alias of a built-in procedure may not have a type initializer");
|
error(type_expr, "A constant alias of a built-in procedure may not have a type initializer");
|
||||||
|
|||||||
+23
-69
@@ -94,7 +94,6 @@ bool check_has_break(AstNode *stmt, bool implicit) {
|
|||||||
|
|
||||||
// NOTE(bill): The last expression has to be a 'return' statement
|
// NOTE(bill): The last expression has to be a 'return' statement
|
||||||
// TODO(bill): This is a mild hack and should be probably handled properly
|
// TODO(bill): This is a mild hack and should be probably handled properly
|
||||||
// TODO(bill): Warn/err against code after 'return' that it won't be executed
|
|
||||||
bool check_is_terminating(AstNode *node) {
|
bool check_is_terminating(AstNode *node) {
|
||||||
switch (node->kind) {
|
switch (node->kind) {
|
||||||
case_ast_node(rs, ReturnStmt, node);
|
case_ast_node(rs, ReturnStmt, node);
|
||||||
@@ -344,22 +343,6 @@ Type *check_assignment_variable(Checker *c, Operand *lhs, Operand *rhs) {
|
|||||||
return rhs->type;
|
return rhs->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum SwitchKind {
|
|
||||||
Switch_Invalid,
|
|
||||||
Switch_Union,
|
|
||||||
Switch_Any,
|
|
||||||
};
|
|
||||||
|
|
||||||
SwitchKind check_valid_type_switch_type(Type *type) {
|
|
||||||
type = type_deref(type);
|
|
||||||
if (is_type_union(type)) {
|
|
||||||
return Switch_Union;
|
|
||||||
}
|
|
||||||
if (is_type_any(type)) {
|
|
||||||
return Switch_Any;
|
|
||||||
}
|
|
||||||
return Switch_Invalid;
|
|
||||||
}
|
|
||||||
|
|
||||||
void check_stmt_internal(Checker *c, AstNode *node, u32 flags);
|
void check_stmt_internal(Checker *c, AstNode *node, u32 flags);
|
||||||
void check_stmt(Checker *c, AstNode *node, u32 flags) {
|
void check_stmt(Checker *c, AstNode *node, u32 flags) {
|
||||||
@@ -771,12 +754,32 @@ void check_switch_stmt(Checker *c, AstNode *node, u32 mod_flags) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum SwitchKind {
|
||||||
|
Switch_Invalid,
|
||||||
|
Switch_Union,
|
||||||
|
Switch_Any,
|
||||||
|
};
|
||||||
|
|
||||||
|
SwitchKind check_valid_type_switch_type(Type *type) {
|
||||||
|
type = type_deref(type);
|
||||||
|
if (is_type_union(type)) {
|
||||||
|
return Switch_Union;
|
||||||
|
}
|
||||||
|
if (is_type_any(type)) {
|
||||||
|
return Switch_Any;
|
||||||
|
}
|
||||||
|
return Switch_Invalid;
|
||||||
|
}
|
||||||
|
|
||||||
void check_type_switch_stmt(Checker *c, AstNode *node, u32 mod_flags) {
|
void check_type_switch_stmt(Checker *c, AstNode *node, u32 mod_flags) {
|
||||||
ast_node(ss, TypeSwitchStmt, node);
|
ast_node(ss, TypeSwitchStmt, node);
|
||||||
Operand x = {};
|
Operand x = {};
|
||||||
|
|
||||||
mod_flags |= Stmt_BreakAllowed;
|
mod_flags |= Stmt_BreakAllowed;
|
||||||
check_open_scope(c, node);
|
check_open_scope(c, node);
|
||||||
|
defer (check_close_scope(c));
|
||||||
|
|
||||||
check_label(c, ss->label); // TODO(bill): What should the label's "scope" be?
|
check_label(c, ss->label); // TODO(bill): What should the label's "scope" be?
|
||||||
|
|
||||||
SwitchKind switch_kind = Switch_Invalid;
|
SwitchKind switch_kind = Switch_Invalid;
|
||||||
@@ -802,7 +805,7 @@ void check_type_switch_stmt(Checker *c, AstNode *node, u32 mod_flags) {
|
|||||||
check_expr(c, &x, rhs);
|
check_expr(c, &x, rhs);
|
||||||
check_assignment(c, &x, nullptr, str_lit("type switch expression"));
|
check_assignment(c, &x, nullptr, str_lit("type switch expression"));
|
||||||
switch_kind = check_valid_type_switch_type(x.type);
|
switch_kind = check_valid_type_switch_type(x.type);
|
||||||
if (check_valid_type_switch_type(x.type) == Switch_Invalid) {
|
if (switch_kind == Switch_Invalid) {
|
||||||
gbString str = type_to_string(x.type);
|
gbString str = type_to_string(x.type);
|
||||||
error(x.expr, "Invalid type for this type switch expression, got '%s'", str);
|
error(x.expr, "Invalid type for this type switch expression, got '%s'", str);
|
||||||
gb_string_free(str);
|
gb_string_free(str);
|
||||||
@@ -838,15 +841,14 @@ void check_type_switch_stmt(Checker *c, AstNode *node, u32 mod_flags) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (lhs->kind != AstNode_Ident) {
|
if (lhs->kind != AstNode_Ident) {
|
||||||
error(rhs, "Expected an identifier, got '%.*s'", LIT(ast_node_strings[rhs->kind]));
|
error(rhs, "Expected an identifier, got '%.*s'", LIT(ast_node_strings[rhs->kind]));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<bool> seen = {}; // Key: Type *
|
||||||
Map<bool> seen = {}; // Multimap, Key: Type *
|
|
||||||
map_init(&seen, heap_allocator());
|
map_init(&seen, heap_allocator());
|
||||||
|
defer (map_destroy(&seen));
|
||||||
|
|
||||||
for_array(i, bs->stmts) {
|
for_array(i, bs->stmts) {
|
||||||
AstNode *stmt = bs->stmts[i];
|
AstNode *stmt = bs->stmts[i];
|
||||||
@@ -933,9 +935,6 @@ void check_type_switch_stmt(Checker *c, AstNode *node, u32 mod_flags) {
|
|||||||
check_stmt_list(c, cc->stmts, mod_flags);
|
check_stmt_list(c, cc->stmts, mod_flags);
|
||||||
check_close_scope(c);
|
check_close_scope(c);
|
||||||
}
|
}
|
||||||
map_destroy(&seen);
|
|
||||||
|
|
||||||
check_close_scope(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||||
@@ -989,51 +988,6 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
|||||||
check_stmt(c, ts->stmt, flags);
|
check_stmt(c, ts->stmt, flags);
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
#if 0
|
|
||||||
case_ast_node(s, IncDecStmt, node);
|
|
||||||
TokenKind op = s->op.kind;
|
|
||||||
switch (op) {
|
|
||||||
case Token_Inc: op = Token_Add; break;
|
|
||||||
case Token_Dec: op = Token_Sub; break;
|
|
||||||
default:
|
|
||||||
error(node, "Invalid inc/dec operation");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Operand x = {};
|
|
||||||
check_expr(c, &x, s->expr);
|
|
||||||
if (x.mode == Addressing_Invalid) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!is_type_integer(x.type) && !is_type_float(x.type)) {
|
|
||||||
gbString e = expr_to_string(s->expr);
|
|
||||||
gbString t = type_to_string(x.type);
|
|
||||||
error(node, "%s%.*s used on non-numeric type %s", e, LIT(s->op.string), t);
|
|
||||||
gb_string_free(t);
|
|
||||||
gb_string_free(e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
AstNode *left = s->expr;
|
|
||||||
AstNode *right = gb_alloc_item(c->allocator, AstNode);
|
|
||||||
right->kind = AstNode_BasicLit;
|
|
||||||
right->BasicLit.pos = s->op.pos;
|
|
||||||
right->BasicLit.kind = Token_Integer;
|
|
||||||
right->BasicLit.string = str_lit("1");
|
|
||||||
|
|
||||||
AstNode *be = gb_alloc_item(c->allocator, AstNode);
|
|
||||||
be->kind = AstNode_BinaryExpr;
|
|
||||||
be->BinaryExpr.op = s->op;
|
|
||||||
be->BinaryExpr.op.kind = op;
|
|
||||||
be->BinaryExpr.left = left;
|
|
||||||
be->BinaryExpr.right = right;
|
|
||||||
check_binary_expr(c, &x, be);
|
|
||||||
if (x.mode == Addressing_Invalid) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
check_assignment_variable(c, &x, left);
|
|
||||||
case_end;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case_ast_node(as, AssignStmt, node);
|
case_ast_node(as, AssignStmt, node);
|
||||||
switch (as->op.kind) {
|
switch (as->op.kind) {
|
||||||
case Token_Eq: {
|
case Token_Eq: {
|
||||||
|
|||||||
+11
-5
@@ -2008,6 +2008,7 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
*type = t;
|
*type = t;
|
||||||
|
set_base_type(named_type, *type);
|
||||||
return true;
|
return true;
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
@@ -2038,21 +2039,22 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
|
|||||||
|
|
||||||
case_ast_node(pe, ParenExpr, e);
|
case_ast_node(pe, ParenExpr, e);
|
||||||
*type = check_type(c, pe->expr, named_type);
|
*type = check_type(c, pe->expr, named_type);
|
||||||
|
set_base_type(named_type, *type);
|
||||||
return true;
|
return true;
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
case_ast_node(ue, UnaryExpr, e);
|
case_ast_node(ue, UnaryExpr, e);
|
||||||
if (ue->op.kind == Token_Pointer) {
|
switch (ue->op.kind) {
|
||||||
|
case Token_Pointer:
|
||||||
*type = make_type_pointer(c->allocator, check_type(c, ue->expr));
|
*type = make_type_pointer(c->allocator, check_type(c, ue->expr));
|
||||||
|
set_base_type(named_type, *type);
|
||||||
return true;
|
return true;
|
||||||
} /* else if (ue->op.kind == Token_Maybe) {
|
}
|
||||||
*type = make_type_maybe(c->allocator, check_type(c, ue->expr));
|
|
||||||
return true;
|
|
||||||
} */
|
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
case_ast_node(pt, PointerType, e);
|
case_ast_node(pt, PointerType, e);
|
||||||
*type = make_type_pointer(c->allocator, check_type(c, pt->type));
|
*type = make_type_pointer(c->allocator, check_type(c, pt->type));
|
||||||
|
set_base_type(named_type, *type);
|
||||||
return true;
|
return true;
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
@@ -2074,12 +2076,14 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
|
|||||||
Type *elem = check_type(c, at->elem);
|
Type *elem = check_type(c, at->elem);
|
||||||
*type = make_type_slice(c->allocator, elem);
|
*type = make_type_slice(c->allocator, elem);
|
||||||
}
|
}
|
||||||
|
set_base_type(named_type, *type);
|
||||||
return true;
|
return true;
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
case_ast_node(dat, DynamicArrayType, e);
|
case_ast_node(dat, DynamicArrayType, e);
|
||||||
Type *elem = check_type(c, dat->elem);
|
Type *elem = check_type(c, dat->elem);
|
||||||
*type = make_type_dynamic_array(c->allocator, elem);
|
*type = make_type_dynamic_array(c->allocator, elem);
|
||||||
|
set_base_type(named_type, *type);
|
||||||
return true;
|
return true;
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
@@ -2143,6 +2147,7 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
|
|||||||
check_expr_or_type(c, &o, e);
|
check_expr_or_type(c, &o, e);
|
||||||
if (o.mode == Addressing_Type) {
|
if (o.mode == Addressing_Type) {
|
||||||
*type = o.type;
|
*type = o.type;
|
||||||
|
set_base_type(named_type, *type);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case_end;
|
case_end;
|
||||||
@@ -2152,6 +2157,7 @@ bool check_type_internal(Checker *c, AstNode *e, Type **type, Type *named_type)
|
|||||||
check_expr_or_type(c, &o, e);
|
check_expr_or_type(c, &o, e);
|
||||||
if (o.mode == Addressing_Type) {
|
if (o.mode == Addressing_Type) {
|
||||||
*type = o.type;
|
*type = o.type;
|
||||||
|
set_base_type(named_type, *type);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case_end;
|
case_end;
|
||||||
|
|||||||
+4
-4
@@ -782,7 +782,7 @@ void add_untyped(CheckerInfo *i, AstNode *expression, bool lhs, AddressingMode m
|
|||||||
if (mode == Addressing_Constant && type == t_invalid) {
|
if (mode == Addressing_Constant && type == t_invalid) {
|
||||||
compiler_error("add_untyped - invalid type: %s", type_to_string(type));
|
compiler_error("add_untyped - invalid type: %s", type_to_string(type));
|
||||||
}
|
}
|
||||||
map_set(&i->untyped, hash_node(expression), make_expr_info(lhs, mode, type, value));
|
map_set(&i->untyped, hash_node(expression), make_expr_info(mode, type, value, lhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
@@ -880,14 +880,14 @@ void add_entity_and_decl_info(Checker *c, AstNode *identifier, Entity *e, DeclIn
|
|||||||
GB_ASSERT(identifier->kind == AstNode_Ident);
|
GB_ASSERT(identifier->kind == AstNode_Ident);
|
||||||
GB_ASSERT(e != nullptr && d != nullptr);
|
GB_ASSERT(e != nullptr && d != nullptr);
|
||||||
GB_ASSERT(identifier->Ident.token.string == e->token.string);
|
GB_ASSERT(identifier->Ident.token.string == e->token.string);
|
||||||
if (e->scope != nullptr) add_entity(c, e->scope, identifier, e);
|
if (e->scope != nullptr) {
|
||||||
|
add_entity(c, e->scope, identifier, e);
|
||||||
|
}
|
||||||
add_entity_definition(&c->info, identifier, e);
|
add_entity_definition(&c->info, identifier, e);
|
||||||
GB_ASSERT(e->decl_info == nullptr);
|
GB_ASSERT(e->decl_info == nullptr);
|
||||||
e->decl_info = d;
|
e->decl_info = d;
|
||||||
array_add(&c->info.entities, e);
|
array_add(&c->info.entities, e);
|
||||||
e->order_in_src = c->info.entities.count;
|
e->order_in_src = c->info.entities.count;
|
||||||
// map_set(&c->info.entities, hash_entity(e), d);
|
|
||||||
// e->order_in_src = c->info.entities.entries.count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+7
-3
@@ -31,14 +31,18 @@ struct TypeAndValue {
|
|||||||
|
|
||||||
// ExprInfo stores information used for "untyped" expressions
|
// ExprInfo stores information used for "untyped" expressions
|
||||||
struct ExprInfo {
|
struct ExprInfo {
|
||||||
bool is_lhs; // Debug info
|
|
||||||
AddressingMode mode;
|
AddressingMode mode;
|
||||||
Type * type; // Type_Basic
|
Type * type; // Type_Basic
|
||||||
ExactValue value;
|
ExactValue value;
|
||||||
|
bool is_lhs; // Debug info
|
||||||
};
|
};
|
||||||
|
|
||||||
gb_inline ExprInfo make_expr_info(bool is_lhs, AddressingMode mode, Type *type, ExactValue value) {
|
gb_inline ExprInfo make_expr_info(AddressingMode mode, Type *type, ExactValue value, bool is_lhs) {
|
||||||
ExprInfo ei = {is_lhs, mode, type, value};
|
ExprInfo ei = {};
|
||||||
|
ei.is_lhs = is_lhs;
|
||||||
|
ei.mode = mode;
|
||||||
|
ei.type = type;
|
||||||
|
ei.value = value;
|
||||||
return ei;
|
return ei;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-13
@@ -1603,10 +1603,10 @@ void ir_emit_zero_init(irProcedure *p, irValue *address, AstNode *expr) {
|
|||||||
irValue **args = gb_alloc_array(a, irValue *, 2);
|
irValue **args = gb_alloc_array(a, irValue *, 2);
|
||||||
args[0] = ir_emit_conv(p, address, t_rawptr);
|
args[0] = ir_emit_conv(p, address, t_rawptr);
|
||||||
args[1] = ir_const_int(a, type_size_of(a, t));
|
args[1] = ir_const_int(a, type_size_of(a, t));
|
||||||
ir_emit(p, ir_instr_zero_init(p, address));
|
|
||||||
if (p->entity->token.string != "__mem_zero") {
|
if (p->entity->token.string != "__mem_zero") {
|
||||||
ir_emit_global_call(p, "__mem_zero", args, 2, expr);
|
ir_emit_global_call(p, "__mem_zero", args, 2, expr);
|
||||||
}
|
}
|
||||||
|
ir_emit(p, ir_instr_zero_init(p, address));
|
||||||
}
|
}
|
||||||
|
|
||||||
irValue *ir_emit_comment(irProcedure *p, String text) {
|
irValue *ir_emit_comment(irProcedure *p, String text) {
|
||||||
@@ -8033,6 +8033,9 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
|
|||||||
irValue *base = ir_type_info(proc, t->Enum.base_type);
|
irValue *base = ir_type_info(proc, t->Enum.base_type);
|
||||||
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), base);
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 0), base);
|
||||||
|
|
||||||
|
// is_export
|
||||||
|
ir_emit_store(proc, ir_emit_struct_ep(proc, tag, 3), ir_const_bool(a, t->Enum.is_export));
|
||||||
|
|
||||||
if (t->Enum.field_count > 0) {
|
if (t->Enum.field_count > 0) {
|
||||||
Entity **fields = t->Enum.fields;
|
Entity **fields = t->Enum.fields;
|
||||||
isize count = t->Enum.field_count;
|
isize count = t->Enum.field_count;
|
||||||
@@ -8342,22 +8345,17 @@ void ir_gen_tree(irGen *s) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decl->init_expr != nullptr) {
|
if (decl->init_expr != nullptr && !is_type_any(e->type)) {
|
||||||
if (is_type_any(e->type)) {
|
TypeAndValue tav = type_and_value_of_expr(info, decl->init_expr);
|
||||||
} else {
|
if (tav.mode != Addressing_Invalid) {
|
||||||
TypeAndValue tav = type_and_value_of_expr(info, decl->init_expr);
|
if (tav.value.kind != ExactValue_Invalid) {
|
||||||
if (tav.mode != Addressing_Invalid) {
|
ExactValue v = tav.value;
|
||||||
if (tav.value.kind != ExactValue_Invalid) {
|
g->Global.value = ir_add_module_constant(m, tav.type, v);
|
||||||
ExactValue v = tav.value;
|
|
||||||
g->Global.value = ir_add_module_constant(m, tav.type, v);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (g->Global.value == nullptr) {
|
array_add(&global_variables, var);
|
||||||
array_add(&global_variables, var);
|
|
||||||
// }
|
|
||||||
|
|
||||||
ir_module_add_value(m, e, g);
|
ir_module_add_value(m, e, g);
|
||||||
map_set(&m->members, hash_string(name), g);
|
map_set(&m->members, hash_string(name), g);
|
||||||
|
|||||||
Reference in New Issue
Block a user