mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Add @(link_suffix=<string>)
This commit is contained in:
+7
-6
@@ -724,15 +724,16 @@ gb_internal Entity *init_entity_foreign_library(CheckerContext *ctx, Entity *e)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_internal String handle_link_name(CheckerContext *ctx, Token token, String link_name, String link_prefix) {
|
gb_internal String handle_link_name(CheckerContext *ctx, Token token, String link_name, String link_prefix, String link_suffix) {
|
||||||
if (link_prefix.len > 0) {
|
if (link_prefix.len > 0) {
|
||||||
if (link_name.len > 0) {
|
if (link_name.len > 0) {
|
||||||
error(token, "'link_name' and 'link_prefix' cannot be used together");
|
error(token, "'link_name' and 'link_prefix' cannot be used together");
|
||||||
} else {
|
} else {
|
||||||
isize len = link_prefix.len + token.string.len;
|
isize len = link_prefix.len + token.string.len + link_suffix.len;
|
||||||
u8 *name = gb_alloc_array(permanent_allocator(), u8, len+1);
|
u8 *name = gb_alloc_array(permanent_allocator(), u8, len+1);
|
||||||
gb_memmove(name, &link_prefix[0], link_prefix.len);
|
gb_memmove(name, &link_prefix[0], link_prefix.len);
|
||||||
gb_memmove(name+link_prefix.len, &token.string[0], token.string.len);
|
gb_memmove(name+link_prefix.len, &token.string[0], token.string.len);
|
||||||
|
gb_memmove(name+link_prefix.len+token.string.len, link_suffix.text, link_suffix.len);
|
||||||
name[len] = 0;
|
name[len] = 0;
|
||||||
|
|
||||||
link_name = make_string(name, len);
|
link_name = make_string(name, len);
|
||||||
@@ -862,7 +863,7 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TypeProc *pt = &proc_type->Proc;
|
TypeProc *pt = &proc_type->Proc;
|
||||||
AttributeContext ac = make_attribute_context(e->Procedure.link_prefix);
|
AttributeContext ac = make_attribute_context(e->Procedure.link_prefix, e->Procedure.link_suffix);
|
||||||
|
|
||||||
if (d != nullptr) {
|
if (d != nullptr) {
|
||||||
check_decl_attributes(ctx, d->attributes, proc_decl_attribute, &ac);
|
check_decl_attributes(ctx, d->attributes, proc_decl_attribute, &ac);
|
||||||
@@ -1015,7 +1016,7 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
|
|||||||
|
|
||||||
e->deprecated_message = ac.deprecated_message;
|
e->deprecated_message = ac.deprecated_message;
|
||||||
e->warning_message = ac.warning_message;
|
e->warning_message = ac.warning_message;
|
||||||
ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix);
|
ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix,ac.link_suffix);
|
||||||
if (ac.has_disabled_proc) {
|
if (ac.has_disabled_proc) {
|
||||||
if (ac.disabled_proc) {
|
if (ac.disabled_proc) {
|
||||||
e->flags |= EntityFlag_Disabled;
|
e->flags |= EntityFlag_Disabled;
|
||||||
@@ -1223,7 +1224,7 @@ gb_internal void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast
|
|||||||
}
|
}
|
||||||
e->flags |= EntityFlag_Visited;
|
e->flags |= EntityFlag_Visited;
|
||||||
|
|
||||||
AttributeContext ac = make_attribute_context(e->Variable.link_prefix);
|
AttributeContext ac = make_attribute_context(e->Variable.link_prefix, e->Variable.link_suffix);
|
||||||
ac.init_expr_list_count = init_expr != nullptr ? 1 : 0;
|
ac.init_expr_list_count = init_expr != nullptr ? 1 : 0;
|
||||||
|
|
||||||
DeclInfo *decl = decl_info_of_entity(e);
|
DeclInfo *decl = decl_info_of_entity(e);
|
||||||
@@ -1244,7 +1245,7 @@ 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");
|
||||||
}
|
}
|
||||||
ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix);
|
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) {
|
||||||
e->Variable.thread_local_model.len = 0;
|
e->Variable.thread_local_model.len = 0;
|
||||||
|
|||||||
+2
-2
@@ -2020,7 +2020,7 @@ gb_internal void check_value_decl_stmt(CheckerContext *ctx, Ast *node, u32 mod_f
|
|||||||
|
|
||||||
|
|
||||||
// TODO NOTE(bill): This technically checks things multple times
|
// TODO NOTE(bill): This technically checks things multple times
|
||||||
AttributeContext ac = make_attribute_context(ctx->foreign_context.link_prefix);
|
AttributeContext ac = make_attribute_context(ctx->foreign_context.link_prefix, ctx->foreign_context.link_suffix);
|
||||||
check_decl_attributes(ctx, vd->attributes, var_decl_attribute, &ac);
|
check_decl_attributes(ctx, vd->attributes, var_decl_attribute, &ac);
|
||||||
|
|
||||||
for (isize i = 0; i < entity_count; i++) {
|
for (isize i = 0; i < entity_count; i++) {
|
||||||
@@ -2037,7 +2037,7 @@ gb_internal void check_value_decl_stmt(CheckerContext *ctx, Ast *node, u32 mod_f
|
|||||||
e->type = init_type;
|
e->type = init_type;
|
||||||
e->state = EntityState_Resolved;
|
e->state = EntityState_Resolved;
|
||||||
}
|
}
|
||||||
ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix);
|
ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix, ac.link_suffix);
|
||||||
|
|
||||||
if (ac.link_name.len > 0) {
|
if (ac.link_name.len > 0) {
|
||||||
e->Variable.link_name = ac.link_name;
|
e->Variable.link_name = ac.link_name;
|
||||||
|
|||||||
@@ -3127,6 +3127,18 @@ gb_internal DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) {
|
|||||||
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
} else if (name == "link_suffix") {
|
||||||
|
if (ev.kind == ExactValue_String) {
|
||||||
|
String link_suffix = ev.value_string;
|
||||||
|
if (!is_foreign_name_valid(link_suffix)) {
|
||||||
|
error(elem, "Invalid link suffix: '%.*s'", LIT(link_suffix));
|
||||||
|
} else {
|
||||||
|
c->foreign_context.link_suffix = link_suffix;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
} else if (name == "private") {
|
} else if (name == "private") {
|
||||||
EntityVisiblityKind kind = EntityVisiblity_PrivateToPackage;
|
EntityVisiblityKind kind = EntityVisiblity_PrivateToPackage;
|
||||||
if (ev.kind == ExactValue_Invalid) {
|
if (ev.kind == ExactValue_Invalid) {
|
||||||
@@ -3421,6 +3433,18 @@ gb_internal DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
|
|||||||
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
} else if (name == "link_suffix") {
|
||||||
|
ExactValue ev = check_decl_attribute_value(c, value);
|
||||||
|
|
||||||
|
if (ev.kind == ExactValue_String) {
|
||||||
|
ac->link_suffix = ev.value_string;
|
||||||
|
if (!is_foreign_name_valid(ac->link_suffix)) {
|
||||||
|
error(elem, "Invalid link suffix: %.*s", LIT(ac->link_suffix));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
} else if (name == "deprecated") {
|
} else if (name == "deprecated") {
|
||||||
ExactValue ev = check_decl_attribute_value(c, value);
|
ExactValue ev = check_decl_attribute_value(c, value);
|
||||||
|
|
||||||
@@ -3702,6 +3726,17 @@ gb_internal DECL_ATTRIBUTE_PROC(var_decl_attribute) {
|
|||||||
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
} else if (name == "link_suffix") {
|
||||||
|
ExactValue ev = check_decl_attribute_value(c, value);
|
||||||
|
if (ev.kind == ExactValue_String) {
|
||||||
|
ac->link_suffix = ev.value_string;
|
||||||
|
if (!is_foreign_name_valid(ac->link_suffix)) {
|
||||||
|
error(elem, "Invalid link suffix: %.*s", LIT(ac->link_suffix));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
error(elem, "Expected a string value for '%.*s'", LIT(name));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
} else if (name == "link_section") {
|
} else if (name == "link_section") {
|
||||||
ExactValue ev = check_decl_attribute_value(c, value);
|
ExactValue ev = check_decl_attribute_value(c, value);
|
||||||
if (ev.kind == ExactValue_String) {
|
if (ev.kind == ExactValue_String) {
|
||||||
@@ -3733,6 +3768,7 @@ gb_internal DECL_ATTRIBUTE_PROC(const_decl_attribute) {
|
|||||||
name == "linkage" ||
|
name == "linkage" ||
|
||||||
name == "link_name" ||
|
name == "link_name" ||
|
||||||
name == "link_prefix" ||
|
name == "link_prefix" ||
|
||||||
|
name == "link_suffix" ||
|
||||||
false) {
|
false) {
|
||||||
error(elem, "@(%.*s) is not supported for compile time constant value declarations", LIT(name));
|
error(elem, "@(%.*s) is not supported for compile time constant value declarations", LIT(name));
|
||||||
return true;
|
return true;
|
||||||
@@ -3775,8 +3811,10 @@ gb_internal void check_decl_attributes(CheckerContext *c, Array<Ast *> const &at
|
|||||||
if (attributes.count == 0) return;
|
if (attributes.count == 0) return;
|
||||||
|
|
||||||
String original_link_prefix = {};
|
String original_link_prefix = {};
|
||||||
|
String original_link_suffix = {};
|
||||||
if (ac) {
|
if (ac) {
|
||||||
original_link_prefix = ac->link_prefix;
|
original_link_prefix = ac->link_prefix;
|
||||||
|
original_link_suffix = ac->link_suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringSet set = {};
|
StringSet set = {};
|
||||||
@@ -3851,6 +3889,12 @@ gb_internal void check_decl_attributes(CheckerContext *c, Array<Ast *> const &at
|
|||||||
ac->link_prefix.len = 0;
|
ac->link_prefix.len = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ac->link_suffix.text == original_link_suffix.text) {
|
||||||
|
if (ac->link_name.len > 0) {
|
||||||
|
ac->link_suffix.text = nullptr;
|
||||||
|
ac->link_suffix.len = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4145,6 +4189,7 @@ gb_internal void check_collect_value_decl(CheckerContext *c, Ast *decl) {
|
|||||||
e->Variable.foreign_library_ident = fl;
|
e->Variable.foreign_library_ident = fl;
|
||||||
|
|
||||||
e->Variable.link_prefix = c->foreign_context.link_prefix;
|
e->Variable.link_prefix = c->foreign_context.link_prefix;
|
||||||
|
e->Variable.link_suffix = c->foreign_context.link_suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast *init_expr = value;
|
Ast *init_expr = value;
|
||||||
@@ -4219,6 +4264,7 @@ gb_internal void check_collect_value_decl(CheckerContext *c, Ast *decl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
e->Procedure.link_prefix = c->foreign_context.link_prefix;
|
e->Procedure.link_prefix = c->foreign_context.link_prefix;
|
||||||
|
e->Procedure.link_suffix = c->foreign_context.link_suffix;
|
||||||
|
|
||||||
GB_ASSERT(cc != ProcCC_Invalid);
|
GB_ASSERT(cc != ProcCC_Invalid);
|
||||||
pl->type->ProcType.calling_convention = cc;
|
pl->type->ProcType.calling_convention = cc;
|
||||||
|
|||||||
+4
-1
@@ -112,6 +112,7 @@ enum InstrumentationFlag : i32 {
|
|||||||
struct AttributeContext {
|
struct AttributeContext {
|
||||||
String link_name;
|
String link_name;
|
||||||
String link_prefix;
|
String link_prefix;
|
||||||
|
String link_suffix;
|
||||||
String link_section;
|
String link_section;
|
||||||
String linkage;
|
String linkage;
|
||||||
isize init_expr_list_count;
|
isize init_expr_list_count;
|
||||||
@@ -146,9 +147,10 @@ struct AttributeContext {
|
|||||||
String enable_target_feature; // will be enabled for the procedure only
|
String enable_target_feature; // will be enabled for the procedure only
|
||||||
};
|
};
|
||||||
|
|
||||||
gb_internal gb_inline AttributeContext make_attribute_context(String link_prefix) {
|
gb_internal gb_inline AttributeContext make_attribute_context(String link_prefix, String link_suffix) {
|
||||||
AttributeContext ac = {};
|
AttributeContext ac = {};
|
||||||
ac.link_prefix = link_prefix;
|
ac.link_prefix = link_prefix;
|
||||||
|
ac.link_suffix = link_suffix;
|
||||||
return ac;
|
return ac;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,6 +304,7 @@ struct ForeignContext {
|
|||||||
Ast * curr_library;
|
Ast * curr_library;
|
||||||
ProcCallingConvention default_cc;
|
ProcCallingConvention default_cc;
|
||||||
String link_prefix;
|
String link_prefix;
|
||||||
|
String link_suffix;
|
||||||
EntityVisiblityKind visibility_kind;
|
EntityVisiblityKind visibility_kind;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -223,6 +223,7 @@ struct Entity {
|
|||||||
Ast * foreign_library_ident;
|
Ast * foreign_library_ident;
|
||||||
String link_name;
|
String link_name;
|
||||||
String link_prefix;
|
String link_prefix;
|
||||||
|
String link_suffix;
|
||||||
String link_section;
|
String link_section;
|
||||||
CommentGroup *docs;
|
CommentGroup *docs;
|
||||||
CommentGroup *comment;
|
CommentGroup *comment;
|
||||||
@@ -243,6 +244,7 @@ struct Entity {
|
|||||||
Ast * foreign_library_ident;
|
Ast * foreign_library_ident;
|
||||||
String link_name;
|
String link_name;
|
||||||
String link_prefix;
|
String link_prefix;
|
||||||
|
String link_suffix;
|
||||||
DeferredProcedure deferred_procedure;
|
DeferredProcedure deferred_procedure;
|
||||||
|
|
||||||
struct GenProcsData *gen_procs;
|
struct GenProcsData *gen_procs;
|
||||||
|
|||||||
Reference in New Issue
Block a user