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.is_export = ac.is_export; - ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix); 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); 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); + // 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); - } + // 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); + // 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; - } + // 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; + // 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"), \