|
@@ -724,9 +724,10 @@ gb_internal Entity *init_entity_foreign_library(CheckerContext *ctx, Entity *e)
|
|
|
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) {
|
|
|
+ String original_link_name = link_name;
|
|
|
if (link_prefix.len > 0) {
|
|
|
- if (link_name.len > 0) {
|
|
|
+ if (original_link_name.len > 0) {
|
|
|
error(token, "'link_name' and 'link_prefix' cannot be used together");
|
|
|
} else {
|
|
|
isize len = link_prefix.len + token.string.len;
|
|
@@ -738,6 +739,24 @@ gb_internal String handle_link_name(CheckerContext *ctx, Token token, String lin
|
|
|
link_name = make_string(name, len);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ if (link_suffix.len > 0) {
|
|
|
+ if (original_link_name.len > 0) {
|
|
|
+ error(token, "'link_name' and 'link_suffix' cannot be used together");
|
|
|
+ } else {
|
|
|
+ String new_name = token.string;
|
|
|
+ if (link_name != original_link_name) {
|
|
|
+ new_name = link_name;
|
|
|
+ }
|
|
|
+
|
|
|
+ isize len = new_name.len + link_suffix.len;
|
|
|
+ u8 *name = gb_alloc_array(permanent_allocator(), u8, len+1);
|
|
|
+ gb_memmove(name, &new_name[0], new_name.len);
|
|
|
+ gb_memmove(name+new_name.len, &link_suffix[0], link_suffix.len);
|
|
|
+ name[len] = 0;
|
|
|
+ link_name = make_string(name, len);
|
|
|
+ }
|
|
|
+ }
|
|
|
return link_name;
|
|
|
}
|
|
|
|
|
@@ -862,7 +881,7 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
|
|
|
}
|
|
|
|
|
|
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) {
|
|
|
check_decl_attributes(ctx, d->attributes, proc_decl_attribute, &ac);
|
|
@@ -995,7 +1014,7 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
|
|
|
|
|
|
e->deprecated_message = ac.deprecated_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.disabled_proc) {
|
|
|
e->flags |= EntityFlag_Disabled;
|
|
@@ -1203,7 +1222,7 @@ gb_internal void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast
|
|
|
}
|
|
|
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;
|
|
|
|
|
|
DeclInfo *decl = decl_info_of_entity(e);
|
|
@@ -1224,7 +1243,7 @@ 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");
|
|
|
}
|
|
|
- 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) {
|
|
|
e->Variable.thread_local_model.len = 0;
|