mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 23:58:50 +00:00
Add @(rodata)
This commit is contained in:
@@ -1264,6 +1264,9 @@ gb_internal void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast
|
|||||||
if (ac.is_static) {
|
if (ac.is_static) {
|
||||||
error(e->token, "@(static) is not supported for global variables, nor required");
|
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);
|
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) {
|
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 = {};
|
Operand o = {};
|
||||||
check_expr_with_type_hint(ctx, &o, init_expr, e->type);
|
check_expr_with_type_hint(ctx, &o, init_expr, e->type);
|
||||||
check_init_variable(ctx, e, &o, str_lit("variable declaration"));
|
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");
|
check_rtti_type_disallowed(e->token, e->type, "A variable declaration is using a type, %s, which has been disallowed");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -501,6 +501,9 @@ gb_internal Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, O
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
case Addressing_Variable:
|
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;
|
break;
|
||||||
|
|
||||||
case Addressing_MapIndex: {
|
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 != "") {
|
if (ac.thread_local_model != "") {
|
||||||
String name = e->token.string;
|
String name = e->token.string;
|
||||||
if (name == "_") {
|
if (name == "_") {
|
||||||
|
|||||||
@@ -3628,6 +3628,12 @@ gb_internal DECL_ATTRIBUTE_PROC(var_decl_attribute) {
|
|||||||
}
|
}
|
||||||
ac->is_static = true;
|
ac->is_static = true;
|
||||||
return 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") {
|
} else if (name == "thread_local") {
|
||||||
ExactValue ev = check_decl_attribute_value(c, value);
|
ExactValue ev = check_decl_attribute_value(c, value);
|
||||||
if (ac->init_expr_list_count > 0) {
|
if (ac->init_expr_list_count > 0) {
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ struct AttributeContext {
|
|||||||
bool entry_point_only : 1;
|
bool entry_point_only : 1;
|
||||||
bool instrumentation_enter : 1;
|
bool instrumentation_enter : 1;
|
||||||
bool instrumentation_exit : 1;
|
bool instrumentation_exit : 1;
|
||||||
|
bool rodata : 1;
|
||||||
u32 optimization_mode; // ProcedureOptimizationMode
|
u32 optimization_mode; // ProcedureOptimizationMode
|
||||||
i64 foreign_import_priority_index;
|
i64 foreign_import_priority_index;
|
||||||
String extra_linker_flags;
|
String extra_linker_flags;
|
||||||
|
|||||||
@@ -230,6 +230,7 @@ struct Entity {
|
|||||||
bool is_foreign;
|
bool is_foreign;
|
||||||
bool is_export;
|
bool is_export;
|
||||||
bool is_global;
|
bool is_global;
|
||||||
|
bool is_rodata;
|
||||||
} Variable;
|
} Variable;
|
||||||
struct {
|
struct {
|
||||||
Type * type_parameter_specialization;
|
Type * type_parameter_specialization;
|
||||||
|
|||||||
+18
-2
@@ -1160,6 +1160,10 @@ gb_internal lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProc
|
|||||||
if (is_type_untyped_nil(init.type)) {
|
if (is_type_untyped_nil(init.type)) {
|
||||||
LLVMSetInitializer(var.var.value, LLVMConstNull(global_type));
|
LLVMSetInitializer(var.var.value, LLVMConstNull(global_type));
|
||||||
var.is_initialized = true;
|
var.is_initialized = true;
|
||||||
|
|
||||||
|
if (e->Variable.is_rodata) {
|
||||||
|
LLVMSetGlobalConstant(var.var.value, true);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
GB_PANIC("Invalid init value, got %s", expr_to_string(init_expr));
|
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);
|
LLVMSetInitializer(var.var.value, init.value);
|
||||||
var.is_initialized = true;
|
var.is_initialized = true;
|
||||||
|
|
||||||
|
if (e->Variable.is_rodata) {
|
||||||
|
LLVMSetGlobalConstant(var.var.value, true);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1206,8 +1214,9 @@ gb_internal lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProc
|
|||||||
|
|
||||||
var.is_initialized = true;
|
var.is_initialized = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
CheckerInfo *info = main_module->gen->info;
|
CheckerInfo *info = main_module->gen->info;
|
||||||
|
|
||||||
for (Entity *e : info->init_procedures) {
|
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);
|
lbValue init = lb_const_value(m, tav.type, v);
|
||||||
LLVMSetInitializer(g.value, init.value);
|
LLVMSetInitializer(g.value, init.value);
|
||||||
var.is_initialized = true;
|
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)) {
|
if (!var.is_initialized && is_type_untyped_nil(tav.type)) {
|
||||||
var.is_initialized = true;
|
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);
|
array_add(&global_variables, var);
|
||||||
|
|
||||||
lb_add_entity(m, e, g);
|
lb_add_entity(m, e, g);
|
||||||
|
|||||||
Reference in New Issue
Block a user