From c440296ae8b0f171fc0f7df311831954c9992162 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 24 May 2021 15:41:22 +0100 Subject: [PATCH] Add `@(link_section=)` for global variables --- src/check_decl.cpp | 3 +++ src/checker.cpp | 10 ++++++++++ src/checker.hpp | 1 + src/entity.cpp | 1 + src/llvm_backend.cpp | 3 +++ 5 files changed, 18 insertions(+) diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 0aef40546..323de6d43 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -934,6 +934,9 @@ void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast *type_expr, if (ac.link_name.len > 0) { e->Variable.link_name = ac.link_name; } + if (ac.link_section.len > 0) { + e->Variable.link_section = ac.link_section; + } if (e->Variable.is_foreign || e->Variable.is_export) { String name = e->token.string; diff --git a/src/checker.cpp b/src/checker.cpp index 21ca4c398..8f426f116 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -2650,6 +2650,16 @@ DECL_ATTRIBUTE_PROC(var_decl_attribute) { error(elem, "Expected a string value for '%.*s'", LIT(name)); } return true; + } else if (name == "link_section") { + if (ev.kind == ExactValue_String) { + ac->link_section = ev.value_string; + if (!is_foreign_name_valid(ac->link_section)) { + error(elem, "Invalid link section: %.*s", LIT(ac->link_section)); + } + } else { + error(elem, "Expected a string value for '%.*s'", LIT(name)); + } + return true; } return false; } diff --git a/src/checker.hpp b/src/checker.hpp index 38628ed51..f0f116a02 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -109,6 +109,7 @@ struct AttributeContext { bool set_cold; String link_name; String link_prefix; + String link_section; isize init_expr_list_count; String thread_local_model; String deprecated_message; diff --git a/src/entity.cpp b/src/entity.cpp index 460f4ec6d..173a3fcd0 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -158,6 +158,7 @@ struct Entity { Ast * foreign_library_ident; String link_name; String link_prefix; + String link_section; bool is_foreign; bool is_export; } Variable; diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index c009e846a..a0294aee0 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -14880,6 +14880,9 @@ void lb_generate_code(lbGenerator *gen) { LLVMSetLinkage(g.value, LLVMInternalLinkage); } } + if (e->Variable.link_section.len > 0) { + LLVMSetSection(g.value, alloc_cstring(permanent_allocator(), e->Variable.link_section)); + } lbGlobalVariable var = {}; var.var = g;