diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 04308d40b..c0e336149 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1669,8 +1669,8 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { CheckerContext prev_context = c->context; if (ok) { - c->context.curr_foreign_library = foreign_library; - c->context.default_foreign_cc = ProcCC_CDecl; + c->context.foreign_context.curr_library = foreign_library; + c->context.foreign_context.default_cc = ProcCC_CDecl; } check_foreign_block_decl_attributes(c, fb); @@ -1763,7 +1763,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { entity = make_entity_variable(c->allocator, c->context.scope, token, nullptr, false); entity->identifier = name; - AstNode *fl = c->context.curr_foreign_library; + AstNode *fl = c->context.foreign_context.curr_library; if (fl != nullptr) { GB_ASSERT(fl->kind == AstNode_Ident); entity->Variable.is_foreign = true; @@ -1850,7 +1850,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { add_entity(c, c->context.scope, e->identifier, e); } - if ((vd->flags & VarDeclFlag_using) != 0) { + if (vd->is_using != 0) { Token token = ast_node_token(node); if (vd->type != nullptr && entity_count > 1) { error(token, "`using` can only be applied to one variable of the same type"); diff --git a/src/check_type.cpp b/src/check_type.cpp index b2536e685..2d881fbe0 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -82,7 +82,7 @@ void check_struct_field_decl(Checker *c, AstNode *decl, Array *fields, if (!vd->is_mutable) return; - bool is_using = (vd->flags&VarDeclFlag_using) != 0; + bool is_using = vd->is_using; if (is_using && vd->names.count > 1) { error(vd->names[0], "Cannot apply `using` to more than one of the same type"); @@ -1891,8 +1891,8 @@ bool check_procedure_type(Checker *c, Type *type, AstNode *proc_type_node, Array ProcCallingConvention cc = pt->calling_convention; if (cc == ProcCC_ForeignBlockDefault) { cc = ProcCC_CDecl; - if (c->context.default_foreign_cc > 0) { - cc = c->context.default_foreign_cc; + if (c->context.foreign_context.default_cc > 0) { + cc = c->context.foreign_context.default_cc; } } GB_ASSERT(cc > 0); diff --git a/src/checker.cpp b/src/checker.cpp index 5e77dc90f..ffca55ce9 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -411,7 +411,12 @@ GB_COMPARE_PROC(ast_node_cmp) { return token_pos_cmp(i.pos, j.pos); } - +struct ForeignContext { + AstNode * curr_library; + ProcCallingConvention default_cc; + String link_prefix; + bool in_export; +}; struct CheckerContext { Scope * file_scope; @@ -422,11 +427,8 @@ struct CheckerContext { String proc_name; Type * type_hint; DeclInfo * curr_proc_decl; - AstNode * curr_foreign_library; - ProcCallingConvention default_foreign_cc; - String foreign_link_prefix; + ForeignContext foreign_context; - bool in_foreign_export; bool collect_delayed_decls; bool allow_polymorphic_types; bool no_polymorphic_errors; @@ -1916,7 +1918,7 @@ void check_foreign_block_decl_attributes(Checker *c, AstNodeForeignBlockDecl *fb if (cc == ProcCC_Invalid) { error(elem, "Unknown procedure calling convention: `%.*s`\n", LIT(ev.value_string)); } else { - c->context.default_foreign_cc = cc; + c->context.foreign_context.default_cc = cc; } } else { error(elem, "Expected a string value for `%.*s`", LIT(name)); @@ -1927,7 +1929,7 @@ void check_foreign_block_decl_attributes(Checker *c, AstNodeForeignBlockDecl *fb if (!is_foreign_name_valid(link_prefix)) { error(elem, "Invalid link prefix: `%.*s`\n", LIT(link_prefix)); } else { - c->context.foreign_link_prefix = link_prefix; + c->context.foreign_context.link_prefix = link_prefix; } } else { error(elem, "Expected a string value for `%.*s`", LIT(name)); @@ -2053,20 +2055,20 @@ void check_collect_value_decl(Checker *c, AstNode *decl) { Entity *e = make_entity_variable(c->allocator, c->context.scope, name->Ident.token, nullptr, false); e->identifier = name; - if (vd->flags & VarDeclFlag_using) { - vd->flags &= ~VarDeclFlag_using; // NOTE(bill): This error will be only caught once + 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"); } - AstNode *fl = c->context.curr_foreign_library; + AstNode *fl = c->context.foreign_context.curr_library; if (fl != nullptr) { GB_ASSERT(fl->kind == AstNode_Ident); e->Variable.is_foreign = true; e->Variable.foreign_library_ident = fl; - e->Variable.link_prefix = c->context.foreign_link_prefix; + e->Variable.link_prefix = c->context.foreign_context.link_prefix; - } else if (c->context.in_foreign_export) { + } else if (c->context.foreign_context.in_export) { e->Variable.is_export = true; } @@ -2105,7 +2107,7 @@ void check_collect_value_decl(Checker *c, AstNode *decl) { Token token = name->Ident.token; - AstNode *fl = c->context.curr_foreign_library; + AstNode *fl = c->context.foreign_context.curr_library; DeclInfo *d = make_declaration_info(c->allocator, c->context.scope, c->context.decl); Entity *e = nullptr; @@ -2135,16 +2137,16 @@ void check_collect_value_decl(Checker *c, AstNode *decl) { auto cc = pl->type->ProcType.calling_convention; if (cc == ProcCC_ForeignBlockDefault) { cc = ProcCC_CDecl; - if (c->context.default_foreign_cc > 0) { - cc = c->context.default_foreign_cc; + if (c->context.foreign_context.default_cc > 0) { + cc = c->context.foreign_context.default_cc; } } - e->Procedure.link_prefix = c->context.foreign_link_prefix; + e->Procedure.link_prefix = c->context.foreign_context.link_prefix; GB_ASSERT(cc != ProcCC_Invalid); pl->type->ProcType.calling_convention = cc; - } else if (c->context.in_foreign_export) { + } else if (c->context.foreign_context.in_export) { e->Procedure.is_export = true; } d->proc_lit = init; @@ -2157,7 +2159,7 @@ void check_collect_value_decl(Checker *c, AstNode *decl) { e->identifier = name; if (e->kind != Entity_Procedure) { - if (fl != nullptr || c->context.in_foreign_export) { + if (fl != nullptr || c->context.foreign_context.in_export) { AstNodeKind kind = init->kind; error(name, "Only procedures and variables are allowed to be in a foreign block, got %.*s", LIT(ast_node_strings[kind])); if (kind == AstNode_ProcType) { @@ -2182,15 +2184,14 @@ void check_add_foreign_block_decl(Checker *c, AstNode *decl) { AstNode *foreign_library = fb->foreign_library; - CheckerContext prev_context = c->context; if (foreign_library->kind == AstNode_Ident) { - c->context.curr_foreign_library = foreign_library; + c->context.foreign_context.curr_library = foreign_library; } else if (foreign_library->kind == AstNode_Implicit && foreign_library->Implicit.kind == Token_export) { - c->context.in_foreign_export = true; + c->context.foreign_context.in_export = true; } else { error(foreign_library, "Foreign block name must be an identifier or `export`"); - c->context.curr_foreign_library = nullptr; + c->context.foreign_context.curr_library = nullptr; } check_foreign_block_decl_attributes(c, fb); diff --git a/src/parser.cpp b/src/parser.cpp index 72c689674..dc148f1b5 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -115,10 +115,6 @@ enum ProcCallingConvention { ProcCC_ForeignBlockDefault = -1, }; -enum VarDeclFlag { - VarDeclFlag_using = 1<<0, -}; - enum StmtStateFlag { StmtStateFlag_bounds_check = 1<<0, StmtStateFlag_no_bounds_check = 1<<1, @@ -347,7 +343,7 @@ AST_NODE_KIND(_DeclBegin, "", i32) \ Array names; \ AstNode * type; \ Array values; \ - u64 flags; \ + bool is_using; \ bool is_mutable; \ bool been_handled; \ Array attributes; \ @@ -3517,39 +3513,6 @@ AstNode *parse_struct_field_list(AstFile *f, isize *name_count_) { AstNode *params = parse_field_list(f, &total_name_count, FieldFlag_Struct, Token_CloseBrace, true, false); if (name_count_) *name_count_ = total_name_count; return params; - -#if 0 - while (f->curr_token.kind != Token_CloseBrace && - f->curr_token.kind != Token_EOF) { - AstNode *decl = parse_stmt(f); - switch (decl->kind) { - case AstNode_EmptyStmt: - case AstNode_BadStmt: - case AstNode_BadDecl: - break; - - case_ast_node(vd, ValueDecl, decl); - if (vd->flags&VarDeclFlag_thread_local) { - vd->flags &= ~VarDeclFlag_thread_local; - syntax_error(decl, "Field values cannot be #thread_local"); - } - array_add(&decls, decl); - total_name_count += vd->names.count; - case_end; - - case AstNode_WhenStmt: - array_add(&decls, decl); - break; - - default: - syntax_error(decl, "Expected a value declaration, got %.*s", LIT(ast_node_strings[decl->kind])); - break; - } - } - - if (name_count_) *name_count_ = total_name_count; - return ast_field_list(f, start_token, decls); -#endif } AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, TokenKind follow, bool allow_default_parameters, bool allow_type_token) { @@ -4549,7 +4512,7 @@ AstNode *parse_stmt(AstFile *f) { syntax_error(token, "`using` may only be applied to variable declarations"); return decl; } - decl->ValueDecl.flags |= VarDeclFlag_using; + decl->ValueDecl.is_using = true; return decl; }