Add @(rodata)

This commit is contained in:
gingerBill
2024-06-06 15:16:34 +01:00
parent 971229fe66
commit 9ef43fc782
6 changed files with 38 additions and 2 deletions
+6
View File
@@ -1264,6 +1264,9 @@ gb_internal void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast
if (ac.is_static) {
error(e->token, "@(static) is not supported for global variables, nor required");
}
if (ac.rodata) {
e->Variable.is_rodata = true;
}
ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix, ac.link_suffix);
if (is_arch_wasm() && e->Variable.thread_local_model.len != 0) {
@@ -1350,6 +1353,9 @@ gb_internal void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast
Operand o = {};
check_expr_with_type_hint(ctx, &o, init_expr, e->type);
check_init_variable(ctx, e, &o, str_lit("variable declaration"));
if (e->Variable.is_rodata && o.mode != Addressing_Constant) {
error(o.expr, "Variables declared with @(rodata) must have constant initialization");
}
check_rtti_type_disallowed(e->token, e->type, "A variable declaration is using a type, %s, which has been disallowed");
}
+6
View File
@@ -501,6 +501,9 @@ gb_internal Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, O
return nullptr;
case Addressing_Variable:
if (e && e->kind == Entity_Variable && e->Variable.is_rodata) {
error(lhs->expr, "Assignment to variable '%.*s' marked as @(rodata) is not allowed", LIT(e->token.string));
}
break;
case Addressing_MapIndex: {
@@ -2055,6 +2058,9 @@ gb_internal void check_value_decl_stmt(CheckerContext *ctx, Ast *node, u32 mod_f
}
}
}
if (ac.rodata) {
error(e->token, "Only global variables can have @(rodata) applied");
}
if (ac.thread_local_model != "") {
String name = e->token.string;
if (name == "_") {
+6
View File
@@ -3628,6 +3628,12 @@ gb_internal DECL_ATTRIBUTE_PROC(var_decl_attribute) {
}
ac->is_static = true;
return true;
} else if (name == "rodata") {
if (value != nullptr) {
error(elem, "'rodata' does not have any parameters");
}
ac->rodata = true;
return true;
} else if (name == "thread_local") {
ExactValue ev = check_decl_attribute_value(c, value);
if (ac->init_expr_list_count > 0) {
+1
View File
@@ -133,6 +133,7 @@ struct AttributeContext {
bool entry_point_only : 1;
bool instrumentation_enter : 1;
bool instrumentation_exit : 1;
bool rodata : 1;
u32 optimization_mode; // ProcedureOptimizationMode
i64 foreign_import_priority_index;
String extra_linker_flags;
+1
View File
@@ -230,6 +230,7 @@ struct Entity {
bool is_foreign;
bool is_export;
bool is_global;
bool is_rodata;
} Variable;
struct {
Type * type_parameter_specialization;
+18 -2
View File
@@ -1160,6 +1160,10 @@ gb_internal lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProc
if (is_type_untyped_nil(init.type)) {
LLVMSetInitializer(var.var.value, LLVMConstNull(global_type));
var.is_initialized = true;
if (e->Variable.is_rodata) {
LLVMSetGlobalConstant(var.var.value, true);
}
continue;
}
GB_PANIC("Invalid init value, got %s", expr_to_string(init_expr));
@@ -1174,6 +1178,10 @@ gb_internal lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProc
}
LLVMSetInitializer(var.var.value, init.value);
var.is_initialized = true;
if (e->Variable.is_rodata) {
LLVMSetGlobalConstant(var.var.value, true);
}
continue;
}
} else {
@@ -1206,8 +1214,9 @@ gb_internal lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProc
var.is_initialized = true;
}
}
CheckerInfo *info = main_module->gen->info;
for (Entity *e : info->init_procedures) {
@@ -3210,14 +3219,21 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
lbValue init = lb_const_value(m, tav.type, v);
LLVMSetInitializer(g.value, init.value);
var.is_initialized = true;
if (e->kind == Entity_Variable && e->Variable.is_rodata) {
LLVMSetGlobalConstant(g.value, true);
}
}
}
}
if (!var.is_initialized && is_type_untyped_nil(tav.type)) {
var.is_initialized = true;
if (e->kind == Entity_Variable && e->Variable.is_rodata) {
LLVMSetGlobalConstant(g.value, true);
}
}
} else if (e->kind == Entity_Variable && e->Variable.is_rodata) {
LLVMSetGlobalConstant(g.value, true);
}
array_add(&global_variables, var);
lb_add_entity(m, e, g);