From 64bd884d94fc45600eaed9566585d455b875a87a Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 23 Feb 2019 14:42:44 +0000 Subject: Add "none" calling convention --- src/parser.hpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/parser.hpp') diff --git a/src/parser.hpp b/src/parser.hpp index fabb7ff8e..13dd1258c 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -166,6 +166,9 @@ enum ProcCallingConvention { // ProcCC_VectorCall, // ProcCC_ClrCall, + ProcCC_None, + + ProcCC_ForeignBlockDefault = -1, }; -- cgit v1.2.3 From a9ab90bd2488783c3523fa30315f9754937fd52e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 23 Feb 2019 22:17:27 +0000 Subject: Make `static` an attribute rather than a keyword prefix --- core/strings/builder.odin | 4 ++-- src/check_decl.cpp | 7 +++++- src/check_stmt.cpp | 17 ++++++++++----- src/checker.cpp | 20 +++++++---------- src/checker.hpp | 1 + src/ir.cpp | 11 +++++++++- src/parser.cpp | 55 +++++++++++++++++++++++------------------------ src/parser.hpp | 1 - src/tokenizer.cpp | 1 - 9 files changed, 66 insertions(+), 51 deletions(-) (limited to 'src/parser.hpp') diff --git a/core/strings/builder.odin b/core/strings/builder.odin index e86d748cc..547c456ba 100644 --- a/core/strings/builder.odin +++ b/core/strings/builder.odin @@ -61,8 +61,8 @@ write_bytes :: proc(b: ^Builder, x: []byte) { append(&b.buf, ..x); } -@(private) -static DIGITS_LOWER := "0123456789abcdefx"; +@(private, static) +DIGITS_LOWER := "0123456789abcdefx"; write_quoted_string :: proc(b: ^Builder, s: string, quote: byte = '"') { write_byte(b, quote); diff --git a/src/check_decl.cpp b/src/check_decl.cpp index e9d6d5860..c2796e1da 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -718,9 +718,14 @@ void check_var_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init_ex check_decl_attributes(ctx, decl->attributes, var_decl_attribute, &ac); } + e->Variable.thread_local_model = ac.thread_local_model; e->Variable.is_export = ac.is_export; + if (ac.is_static) { + e->flags |= EntityFlag_Static; + } else { + e->flags &= ~EntityFlag_Static; + } ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix); - e->Variable.thread_local_model = ac.thread_local_model; String context_name = str_lit("variable declaration"); diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 3262aea5d..c861cfdf3 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1665,8 +1665,6 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { if (!is_blank_ident(str)) { found = scope_lookup_current(ctx->scope, str); new_name_count += 1; - } else if (vd->is_static) { - error(name, "'static' is now allowed to be applied to '_'"); } if (found == nullptr) { entity = alloc_entity_variable(ctx->scope, token, nullptr, false); @@ -1678,9 +1676,6 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { entity->Variable.is_foreign = true; entity->Variable.foreign_library_ident = fl; } - if (vd->is_static) { - entity->flags |= EntityFlag_Static; - } } else { TokenPos pos = found->token.pos; error(token, @@ -1744,6 +1739,16 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { if (ac.link_name.len > 0) { e->Variable.link_name = ac.link_name; } + + e->flags &= ~EntityFlag_Static; + if (ac.is_static) { + String name = e->token.string; + if (name == "_") { + error(e->token, "The 'static' attribute is not allowed to be applied to '_'"); + } else { + e->flags |= EntityFlag_Static; + } + } } check_arity_match(ctx, vd); @@ -1751,6 +1756,7 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { for (isize i = 0; i < entity_count; i++) { Entity *e = entities[i]; + if (e->Variable.is_foreign) { if (vd->values.count > 0) { error(e->token, "A foreign variable declaration cannot have a default value"); @@ -1842,6 +1848,7 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { } } } + } else { // constant value declaration // NOTE(bill): Check `_` declarations diff --git a/src/checker.cpp b/src/checker.cpp index 9bbe64839..6389e3d30 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2070,6 +2070,14 @@ DECL_ATTRIBUTE_PROC(proc_decl_attribute) { DECL_ATTRIBUTE_PROC(var_decl_attribute) { ExactValue ev = check_decl_attribute_value(c, value); + if (name == "static") { + if (value != nullptr) { + error(elem, "'static' does not have any parameters"); + } + ac->is_static = true; + return true; + } + if (c->curr_proc_decl != nullptr) { error(elem, "Only a variable at file scope can have a '%.*s'", LIT(name)); return true; @@ -2425,10 +2433,6 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { e->flags |= EntityFlag_NotExported; } - if (vd->is_static) { - e->flags |= EntityFlag_Static; - } - if (vd->is_using) { vd->is_using = false; // NOTE(bill): This error will be only caught once error(name, "'using' is not allowed at the file scope"); @@ -2527,14 +2531,6 @@ void check_collect_value_decl(CheckerContext *c, Ast *decl) { e->flags |= EntityFlag_NotExported; } - if (vd->is_static) { - if (e->kind == Entity_Constant) { - e->flags |= EntityFlag_Static; - } else { - error(name, "'static' is not allowed on this constant value declaration"); - } - } - if (vd->is_using) { if (e->kind == Entity_TypeName && init->kind == Ast_EnumType) { d->is_using = true; diff --git a/src/checker.hpp b/src/checker.hpp index 759e343bf..4420d6bb4 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -306,6 +306,7 @@ struct DeferredProcedure { struct AttributeContext { bool is_export; + bool is_static; String link_name; String link_prefix; isize init_expr_list_count; diff --git a/src/ir.cpp b/src/ir.cpp index 4df6665f7..e92fa7f60 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -8166,7 +8166,16 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) { if (vd->is_mutable) { irModule *m = proc->module; - if (vd->is_static) { + bool is_static = false; + if (vd->names.count > 0) { + Entity *e = entity_of_ident(vd->names[0]); + if (e->flags & EntityFlag_Static) { + // NOTE(bill): If one of the entities is static, they all are + is_static = true; + } + } + + if (is_static) { for_array(i, vd->names) { irValue *value = nullptr; if (vd->values.count > 0) { diff --git a/src/parser.cpp b/src/parser.cpp index 9d42b3828..a5526fd73 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1208,7 +1208,6 @@ void fix_advance_to_next_stmt(AstFile *f) { case Token_defer: case Token_asm: case Token_using: - case Token_static: case Token_break: case Token_continue: @@ -3751,33 +3750,33 @@ Ast *parse_stmt(AstFile *f) { return s; } - case Token_static: { - CommentGroup *docs = f->lead_comment; - Token token = expect_token(f, Token_static); - - Ast *decl = nullptr; - Array list = parse_lhs_expr_list(f); - if (list.count == 0) { - syntax_error(token, "Illegal use of 'static' statement"); - expect_semicolon(f, nullptr); - return ast_bad_stmt(f, token, f->curr_token); - } - - expect_token_after(f, Token_Colon, "identifier list"); - decl = parse_value_decl(f, list, docs); - - if (decl != nullptr && decl->kind == Ast_ValueDecl) { - if (decl->ValueDecl.is_mutable) { - decl->ValueDecl.is_static = true; - } else { - error(token, "'static' may only be currently used with variable declaration"); - } - return decl; - } - - syntax_error(token, "Illegal use of 'static' statement"); - return ast_bad_stmt(f, token, f->curr_token); - } break; + // case Token_static: { + // CommentGroup *docs = f->lead_comment; + // Token token = expect_token(f, Token_static); + + // Ast *decl = nullptr; + // Array list = parse_lhs_expr_list(f); + // if (list.count == 0) { + // syntax_error(token, "Illegal use of 'static' statement"); + // expect_semicolon(f, nullptr); + // return ast_bad_stmt(f, token, f->curr_token); + // } + + // expect_token_after(f, Token_Colon, "identifier list"); + // decl = parse_value_decl(f, list, docs); + + // if (decl != nullptr && decl->kind == Ast_ValueDecl) { + // if (decl->ValueDecl.is_mutable) { + // decl->ValueDecl.is_static = true; + // } else { + // error(token, "'static' may only be currently used with variable declaration"); + // } + // return decl; + // } + + // syntax_error(token, "Illegal use of 'static' statement"); + // return ast_bad_stmt(f, token, f->curr_token); + // } break; case Token_using: { CommentGroup *docs = f->lead_comment; diff --git a/src/parser.hpp b/src/parser.hpp index 13dd1258c..d685aa1af 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -376,7 +376,6 @@ AST_KIND(_DeclBegin, "", bool) \ Array attributes; \ CommentGroup *docs; \ CommentGroup *comment; \ - bool is_static; \ bool is_using; \ bool is_mutable; \ }) \ diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 31afe3d2e..11fae7120 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -107,7 +107,6 @@ TOKEN_KIND(Token__KeywordBegin, ""), \ TOKEN_KIND(Token_bit_field, "bit_field"), \ TOKEN_KIND(Token_bit_set, "bit_set"), \ TOKEN_KIND(Token_map, "map"), \ - TOKEN_KIND(Token_static, "static"), \ TOKEN_KIND(Token_dynamic, "dynamic"), \ TOKEN_KIND(Token_auto_cast, "auto_cast"), \ TOKEN_KIND(Token_cast, "cast"), \ -- cgit v1.2.3 From ad3b6ab71854a638f2b769fc12e8776abfff48d6 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 6 Mar 2019 16:19:47 +0000 Subject: Implicit Selector Expressions: `.A` --- core/odin/ast/ast.odin | 4 ++++ core/odin/parser/parser.odin | 7 +++++++ src/check_expr.cpp | 49 ++++++++++++++++++++++++++++++++++++++++++-- src/ir.cpp | 7 +++++++ src/parser.cpp | 24 +++++++++++++++++++++- src/parser.hpp | 1 + 6 files changed, 89 insertions(+), 3 deletions(-) (limited to 'src/parser.hpp') diff --git a/core/odin/ast/ast.odin b/core/odin/ast/ast.odin index 8c43ee8e3..59d18a0c0 100644 --- a/core/odin/ast/ast.odin +++ b/core/odin/ast/ast.odin @@ -144,6 +144,10 @@ Selector_Expr :: struct { field: ^Ident, } +Implicit_Selector_Expr :: struct { + using node: Expr, + field: ^Ident, +} Index_Expr :: struct { using node: Expr, diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index c10a83e47..90de2ca30 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -2581,6 +2581,13 @@ parse_unary_expr :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr { ue.expr = expr; return ue; + case token.Period: + op := advance_token(p); + field := parse_ident(p); + ise := ast.new(ast.Implicit_Selector_Expr, op.pos, field.end); + ise.field = field; + return ise; + } return parse_atom_expr(p, parse_operand(p, lhs), lhs); } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index ea125a5eb..4c921f484 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -991,7 +991,6 @@ Entity *check_ident(CheckerContext *c, Operand *o, Ast *n, Type *named_type, Typ o->expr = n; String name = n->Ident.token.string; - Entity *e = scope_lookup(c->scope, name); if (e == nullptr) { if (is_blank_ident(name)) { @@ -6177,7 +6176,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type continue; } - check_expr(c, o, elem); + check_expr_with_type_hint(c, o, elem, et); if (is_constant) { is_constant = o->mode == Addressing_Constant; @@ -6408,6 +6407,47 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type case_end; + case_ast_node(ise, ImplicitSelectorExpr, node); + o->type = t_invalid; + o->expr = node; + o->mode = Addressing_Invalid; + + if (type_hint == nullptr) { + gbString str = expr_to_string(node); + error(node, "Cannot determine type for implicit selector expression '%s'", str); + gb_string_free(str); + return Expr_Expr; + } + o->type = type_hint; + if (!is_type_enum(type_hint)) { + gbString typ = type_to_string(type_hint); + gbString str = expr_to_string(node); + error(node, "Invalid type '%s' for implicit selector expression '%s'", typ, str); + gb_string_free(str); + gb_string_free(typ); + return Expr_Expr; + } + GB_ASSERT(ise->selector->kind == Ast_Ident); + String name = ise->selector->Ident.token.string; + + Type *enum_type = base_type(type_hint); + GB_ASSERT(enum_type->kind == Type_Enum); + Entity *e = scope_lookup_current(enum_type->Enum.scope, name); + if (e == nullptr) { + gbString typ = type_to_string(type_hint); + error(node, "Undeclared name %.*s for type '%s'", LIT(name), typ); + gb_string_free(typ); + return Expr_Expr; + } + GB_ASSERT(are_types_identical(base_type(e->type), base_type(type_hint))); + GB_ASSERT(e->kind == Entity_Constant); + o->value = e->Constant.value; + o->mode = Addressing_Constant; + o->type = e->type; + + return Expr_Expr; + case_end; + case_ast_node(ie, IndexExpr, node); check_expr(c, o, ie->expr); if (o->mode == Addressing_Invalid) { @@ -6832,6 +6872,11 @@ gbString write_expr_to_string(gbString str, Ast *node) { str = write_expr_to_string(str, se->selector); case_end; + case_ast_node(se, ImplicitSelectorExpr, node); + str = gb_string_append_rune(str, '.'); + str = write_expr_to_string(str, se->selector); + case_end; + case_ast_node(ta, TypeAssertion, node); str = write_expr_to_string(str, ta->expr); str = gb_string_appendc(str, ".("); diff --git a/src/ir.cpp b/src/ir.cpp index e3fe83c3b..0d5e3fc36 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -6268,6 +6268,13 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) { return ir_addr_load(proc, ir_build_addr(proc, expr)); case_end; + case_ast_node(ise, ImplicitSelectorExpr, expr); + TypeAndValue tav = type_and_value_of_expr(expr); + GB_ASSERT(tav.mode == Addressing_Constant); + + return ir_add_module_constant(proc->module, tv.type, tv.value); + case_end; + case_ast_node(te, TernaryExpr, expr); ir_emit_comment(proc, str_lit("TernaryExpr")); diff --git a/src/parser.cpp b/src/parser.cpp index a5526fd73..84c03587d 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -25,6 +25,11 @@ Token ast_token(Ast *node) { return ast_token(node->SelectorExpr.selector); } return node->SelectorExpr.token; + case Ast_ImplicitSelectorExpr: + if (node->ImplicitSelectorExpr.selector != nullptr) { + return ast_token(node->ImplicitSelectorExpr.selector); + } + return node->ImplicitSelectorExpr.token; case Ast_IndexExpr: return node->IndexExpr.open; case Ast_SliceExpr: return node->SliceExpr.open; case Ast_Ellipsis: return node->Ellipsis.token; @@ -165,6 +170,9 @@ Ast *clone_ast(Ast *node) { n->SelectorExpr.expr = clone_ast(n->SelectorExpr.expr); n->SelectorExpr.selector = clone_ast(n->SelectorExpr.selector); break; + case Ast_ImplicitSelectorExpr: + n->ImplicitSelectorExpr.selector = clone_ast(n->ImplicitSelectorExpr.selector); + break; case Ast_IndexExpr: n->IndexExpr.expr = clone_ast(n->IndexExpr.expr); n->IndexExpr.index = clone_ast(n->IndexExpr.index); @@ -504,11 +512,20 @@ Ast *ast_call_expr(AstFile *f, Ast *proc, Array args, Token open, Token c Ast *ast_selector_expr(AstFile *f, Token token, Ast *expr, Ast *selector) { Ast *result = alloc_ast_node(f, Ast_SelectorExpr); + result->SelectorExpr.token = token; result->SelectorExpr.expr = expr; result->SelectorExpr.selector = selector; return result; } +Ast *ast_implicit_selector_expr(AstFile *f, Token token, Ast *selector) { + Ast *result = alloc_ast_node(f, Ast_ImplicitSelectorExpr); + result->ImplicitSelectorExpr.token = token; + result->ImplicitSelectorExpr.selector = selector; + return result; +} + + Ast *ast_index_expr(AstFile *f, Ast *expr, Ast *index, Token open, Token close) { Ast *result = alloc_ast_node(f, Ast_IndexExpr); result->IndexExpr.expr = expr; @@ -1612,7 +1629,6 @@ Ast *parse_operand(AstFile *f, bool lhs) { case Token_offset_of: return parse_call_expr(f, ast_implicit(f, advance_token(f))); - case Token_String: return ast_basic_lit(f, advance_token(f)); @@ -2277,6 +2293,12 @@ Ast *parse_unary_expr(AstFile *f, bool lhs) { Ast *expr = parse_unary_expr(f, lhs); return ast_unary_expr(f, token, expr); } + + case Token_Period: { + Token token = expect_token(f, Token_Period); + Ast *ident = parse_ident(f); + return ast_implicit_selector_expr(f, token, ident); + } } return parse_atom_expr(f, parse_operand(f, lhs), lhs); diff --git a/src/parser.hpp b/src/parser.hpp index d685aa1af..816f3f534 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -245,6 +245,7 @@ AST_KIND(_ExprBegin, "", bool) \ AST_KIND(BinaryExpr, "binary expression", struct { Token op; Ast *left, *right; } ) \ AST_KIND(ParenExpr, "parentheses expression", struct { Ast *expr; Token open, close; }) \ AST_KIND(SelectorExpr, "selector expression", struct { Token token; Ast *expr, *selector; }) \ + AST_KIND(ImplicitSelectorExpr, "implicit selector expression", struct { Token token; Ast *selector; }) \ AST_KIND(IndexExpr, "index expression", struct { Ast *expr, *index; Token open, close; }) \ AST_KIND(DerefExpr, "dereference expression", struct { Token op; Ast *expr; }) \ AST_KIND(SliceExpr, "slice expression", struct { \ -- cgit v1.2.3 From bdab5e00da6dee80b7582135815f2183def935bb Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 11 Mar 2019 19:52:40 +0000 Subject: Minor code clean up --- core/odin/parser/parser.odin | 27 +++++++++++++++++++++++++-- core/runtime/core.odin | 30 ++++++++++++------------------ src/check_expr.cpp | 3 ++- src/check_type.cpp | 1 + src/parser.hpp | 1 - src/types.cpp | 1 + 6 files changed, 41 insertions(+), 22 deletions(-) (limited to 'src/parser.hpp') diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index 17a24c5f5..ccae59a7c 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -1077,9 +1077,9 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt { stmt := parse_stmt(p); switch name { case "bounds_check": - stmt.state_flags |= {ast.Node_State_Flag.Bounds_Check}; + stmt.state_flags |= {.Bounds_Check}; case "no_bounds_check": - stmt.state_flags |= {ast.Node_State_Flag.No_Bounds_Check}; + stmt.state_flags |= {.No_Bounds_Check}; } return stmt; case "complete": @@ -1723,6 +1723,29 @@ string_to_calling_convention :: proc(s: string) -> ast.Proc_Calling_Convention { return Invalid; } +parse_proc_tags :: proc(p: ^Parser) -> (tags: Proc_Tags) { + for p.curr_tok.kind == token.Hash { + tok := expect_token(p, token.Hash); + ident := expect_token(p, token.Ident); + + switch ident.text { + case "require_results": + tags |= {.Require_Results}; + case "bounds_check": + tags |= {.Bounds_Check}; + case "no_bounds_check": + tags |= {.No_Bounds_Check}; + case: + } + } + + if .Bounds_Check in tags && .No_Bounds_Check in tags { + p.err(p.curr_tok.pos, "#bounds_check and #no_bounds_check applied to the same procedure type"); + } + + return; +} + parse_proc_type :: proc(p: ^Parser, tok: token.Token) -> ^ast.Proc_Type { cc := ast.Proc_Calling_Convention.Invalid; if p.curr_tok.kind == token.String { diff --git a/core/runtime/core.odin b/core/runtime/core.odin index 38dd8f225..1ce7cfac5 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -251,8 +251,10 @@ Map_Entry_Header :: struct { Map_Header :: struct { m: ^mem.Raw_Map, is_key_string: bool, + entry_size: int, entry_align: int, + value_offset: uintptr, value_size: int, } @@ -833,29 +835,23 @@ __get_map_key :: proc "contextless" (key: $K) -> Map_Key { return map_key; } +_fnv64a :: proc(data: []byte, seed: u64 = 0xcbf29ce484222325) -> u64 { + h: u64 = seed; + for b in data { + h = (h ~ u64(b)) * 0x100000001b3; + } + return h; +} + default_hash :: proc(data: []byte) -> u64 { - fnv64a :: proc(data: []byte) -> u64 { - h: u64 = 0xcbf29ce484222325; - for b in data { - h = (h ~ u64(b)) * 0x100000001b3; - } - return h; - } - return fnv64a(data); + return _fnv64a(data); } default_hash_string :: proc(s: string) -> u64 do return default_hash(([]byte)(s)); source_code_location_hash :: proc(s: Source_Code_Location) -> u64 { - fnv64a :: proc(data: []byte, seed: u64 = 0xcbf29ce484222325) -> u64 { - h: u64 = seed; - for b in data { - h = (h ~ u64(b)) * 0x100000001b3; - } - return h; - } - hash := fnv64a(cast([]byte)s.file_path); + hash := _fnv64a(cast([]byte)s.file_path); hash = hash ~ (u64(s.line) * 0x100000001b3); hash = hash ~ (u64(s.column) * 0x100000001b3); return hash; @@ -863,7 +859,6 @@ source_code_location_hash :: proc(s: Source_Code_Location) -> u64 { - __slice_resize :: proc(array_: ^$T/[]$E, new_count: int, allocator: mem.Allocator, loc := #caller_location) -> bool { array := (^mem.Raw_Slice)(array_); @@ -942,7 +937,6 @@ __dynamic_map_get :: proc(h: Map_Header, key: Map_Key) -> rawptr { } __dynamic_map_set :: proc(h: Map_Header, key: Map_Key, value: rawptr, loc := #caller_location) #no_bounds_check { - index: int; assert(value != nil); diff --git a/src/check_expr.cpp b/src/check_expr.cpp index f533a1812..d0e18d89f 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -5439,7 +5439,8 @@ ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *call) { operand->mode = Addressing_NoValue; } else { GB_ASSERT(is_type_tuple(result_type)); - switch (result_type->Tuple.variables.count) { + isize count = result_type->Tuple.variables.count; + switch (count) { case 0: operand->mode = Addressing_NoValue; break; diff --git a/src/check_type.cpp b/src/check_type.cpp index 1c5d5ac85..451a388fb 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -2049,6 +2049,7 @@ bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node, type->Proc.is_polymorphic = pt->generic; type->Proc.specialization_count = specialization_count; type->Proc.diverging = pt->diverging; + type->Proc.tags = pt->tags; if (param_count > 0) { Entity *end = params->Tuple.variables[param_count-1]; diff --git a/src/parser.hpp b/src/parser.hpp index 816f3f534..e08648eca 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -151,7 +151,6 @@ enum ProcTag { ProcTag_bounds_check = 1<<0, ProcTag_no_bounds_check = 1<<1, ProcTag_require_results = 1<<4, - ProcTag_no_context = 1<<6, }; enum ProcCallingConvention { diff --git a/src/types.cpp b/src/types.cpp index c6886e984..5aa2ab6e1 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -198,6 +198,7 @@ struct TypeUnion { bool has_proc_default_values; \ bool has_named_results; \ bool diverging; /* no return */ \ + u64 tags; \ isize specialization_count; \ ProcCallingConvention calling_convention; \ }) \ -- cgit v1.2.3