From c95466622a0069161f5e7ff8bdb1ce91db5cb232 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sun, 24 Aug 2025 16:54:48 +0200 Subject: [PATCH] Allow exporting global external variables --- gcc/elna-builtins.cc | 61 ++++++++++++++---------------- gcc/elna-diagnostic.cc | 10 +++++ gcc/elna-generic.cc | 14 +------ gcc/elna1.cc | 11 +++--- include/elna/boot/dependency.h | 2 +- include/elna/gcc/elna-diagnostic.h | 9 +++++ include/elna/gcc/elna-generic.h | 1 - 7 files changed, 56 insertions(+), 52 deletions(-) diff --git a/gcc/elna-builtins.cc b/gcc/elna-builtins.cc index a121bdc..61a24c4 100644 --- a/gcc/elna-builtins.cc +++ b/gcc/elna-builtins.cc @@ -57,8 +57,6 @@ namespace elna::gcc tree identifier = get_identifier(name); tree type_declaration = build_decl(UNKNOWN_LOCATION, TYPE_DECL, identifier, type); - TREE_PUBLIC(type_declaration) = 1; - symbol_table->enter(name, type_declaration); return type_declaration; @@ -82,24 +80,6 @@ namespace elna::gcc return symbol_table; } - tree build_type_declaration(const std::string& identifier, tree type) - { - tree definition_tree = build_decl(UNKNOWN_LOCATION, TYPE_DECL, - get_identifier(identifier.c_str()), type); - - TREE_PUBLIC(definition_tree) = 1; - if (is_unique_type(type)) - { - TYPE_NAME(type) = DECL_NAME(definition_tree); - TYPE_STUB_DECL(type) = definition_tree; - } - else - { - TYPE_NAME(type) = definition_tree; - } - return definition_tree; - } - tree build_composite_type(const std::vector& fields, tree composite_type_node, std::shared_ptr symbols) { @@ -178,7 +158,7 @@ namespace elna::gcc } else if (auto reference = type.get()) { - return handle_symbol(reference->name, reference, symbols); + return TREE_TYPE(handle_symbol(reference->name, reference, symbols)); } return error_mark_node; } @@ -190,13 +170,21 @@ namespace elna::gcc if (looked_up == NULL_TREE) { - looked_up = get_inner_alias(reference->reference, symbols); + tree type_tree = get_inner_alias(reference->reference, symbols); + looked_up = build_decl(UNKNOWN_LOCATION, TYPE_DECL, + get_identifier(symbol_name.c_str()), type_tree); - symbols->enter(symbol_name, build_type_declaration(symbol_name, looked_up)); - } - else - { - looked_up = TREE_TYPE(looked_up); + TREE_PUBLIC(looked_up) = 1; + if (is_unique_type(type_tree)) + { + TYPE_NAME(type_tree) = DECL_NAME(looked_up); + TYPE_STUB_DECL(type_tree) = looked_up; + } + else + { + TYPE_NAME(type_tree) = looked_up; + } + symbols->enter(symbol_name, looked_up); } return looked_up; } @@ -236,6 +224,7 @@ namespace elna::gcc DECL_ARGUMENTS(fndecl) = argument_chain; TREE_ADDRESSABLE(fndecl) = 1; DECL_EXTERNAL(fndecl) = info.is_extern(); + TREE_PUBLIC(fndecl) = info.exported; } tree declare_variable(const std::string& name, const boot::variable_info& info, @@ -246,23 +235,31 @@ namespace elna::gcc TREE_ADDRESSABLE(declaration_tree) = 1; DECL_EXTERNAL(declaration_tree) = info.is_extern; + TREE_PUBLIC(declaration_tree) = info.exported; symbols->enter(name, declaration_tree); return declaration_tree; } + void declare_type(const std::string& name, const boot::type_info& info, std::shared_ptr symbols) + { + // The top level symbol table has basic (builtin) types in it which are not aliases. + if (auto alias_type = info.symbol.get()) + { + tree type_declaration = handle_symbol(name, alias_type, symbols); + + TREE_PUBLIC(type_declaration) = info.exported; + } + } + void rewrite_symbol_table(std::shared_ptr info_table, std::shared_ptr symbols) { for (auto& [symbol_name, symbol_info] : *info_table) { if (auto type_info = symbol_info->is_type()) { - // The top level symbol table has basic (builtin) types in it which are not aliases. - if (auto alias_type = type_info->symbol.get()) - { - handle_symbol(symbol_name, alias_type, symbols); - } + declare_type(symbol_name, *type_info, symbols); } else if (auto variable_info = symbol_info->is_variable()) { diff --git a/gcc/elna-diagnostic.cc b/gcc/elna-diagnostic.cc index 5455ce7..3e6e4c3 100644 --- a/gcc/elna-diagnostic.cc +++ b/gcc/elna-diagnostic.cc @@ -21,6 +21,16 @@ along with GCC; see the file COPYING3. If not see namespace elna::gcc { + linemap_guard::linemap_guard(const char *filename) + { + linemap_add(line_table, LC_ENTER, 0, filename, 1); + } + + linemap_guard::~linemap_guard() + { + linemap_add(line_table, LC_LEAVE, 0, NULL, 0); + } + location_t get_location(const boot::position *position) { linemap_line_start(line_table, position->line, 0); diff --git a/gcc/elna-generic.cc b/gcc/elna-generic.cc index 72f67eb..0f0e2ef 100644 --- a/gcc/elna-generic.cc +++ b/gcc/elna-generic.cc @@ -295,10 +295,6 @@ namespace elna::gcc { constant->accept(this); } - for (boot::type_declaration *const type : unit->types) - { - type->accept(this); - } for (boot::variable_declaration *const variable : unit->variables) { variable->accept(this); @@ -312,13 +308,11 @@ namespace elna::gcc void generic_visitor::visit(boot::procedure_declaration *definition) { tree fndecl = this->symbols->lookup(definition->identifier.name); - TREE_PUBLIC(fndecl) = definition->identifier.exported; if (!definition->body.has_value()) { return; } - push_struct_function(fndecl, false); DECL_STRUCT_FUNCTION(fndecl)->language = ggc_cleared_alloc(); @@ -738,11 +732,6 @@ namespace elna::gcc this->current_expression = NULL_TREE; } - void generic_visitor::visit(boot::type_declaration *declaration) - { - TREE_PUBLIC(this->symbols->lookup(declaration->identifier.name)) = declaration->identifier.exported; - } - void generic_visitor::visit(boot::variable_declaration *declaration) { for (const auto& variable_identifier : declaration->identifiers) @@ -775,12 +764,11 @@ namespace elna::gcc { DECL_INITIAL(declaration_tree) = elna_pointer_nil_node; } - TREE_PUBLIC(declaration_tree) = variable_identifier.exported; this->current_expression = NULL_TREE; if (lang_hooks.decls.global_bindings_p()) { - TREE_STATIC(declaration_tree) = 1; + TREE_STATIC(declaration_tree) = !variable_identifier.exported && !declaration->is_extern; varpool_node::get_create(declaration_tree); varpool_node::finalize_decl(declaration_tree); } diff --git a/gcc/elna1.cc b/gcc/elna1.cc index cb643c3..0333f70 100644 --- a/gcc/elna1.cc +++ b/gcc/elna1.cc @@ -72,12 +72,13 @@ static elna::boot::dependency elna_parse_file(dependency_state& state, const cha { fatal_error(UNKNOWN_LOCATION, "Cannot open filename %s: %m", filename); } - linemap_add(line_table, LC_ENTER, 0, filename, 1); + elna::gcc::linemap_guard{ filename }; elna::boot::dependency outcome = elna::boot::read_source(entry_point, filename); if (outcome.has_errors()) { elna::gcc::report_errors(outcome.errors()); + return outcome; } elna::boot::symbol_bag outcome_bag = elna::boot::symbol_bag{ std::move(outcome.unresolved), state.globals }; @@ -94,15 +95,15 @@ static elna::boot::dependency elna_parse_file(dependency_state& state, const cha } outcome_bag.add_import(cached_import->second); } - elna::boot::error_list semantic_errors = analyze_semantics(filename, outcome.tree, outcome_bag); + outcome.errors() = analyze_semantics(filename, outcome.tree, outcome_bag); - if (!semantic_errors.empty()) + if (outcome.has_errors()) { - elna::gcc::report_errors(semantic_errors); + elna::gcc::report_errors(outcome.errors()); + return outcome; } state.cache.insert({ filename, outcome_bag }); elna::gcc::rewrite_symbol_table(outcome_bag.leave(), state.custom); - linemap_add(line_table, LC_LEAVE, 0, NULL, 0); return outcome; } diff --git a/include/elna/boot/dependency.h b/include/elna/boot/dependency.h index 98d65c5..c8f2e5b 100644 --- a/include/elna/boot/dependency.h +++ b/include/elna/boot/dependency.h @@ -31,7 +31,7 @@ namespace elna::boot public: std::unique_ptr tree; - std::unordered_map> unresolved; + forward_table unresolved; explicit dependency(const char *path); }; diff --git a/include/elna/gcc/elna-diagnostic.h b/include/elna/gcc/elna-diagnostic.h index 2f37ee9..1eef65d 100644 --- a/include/elna/gcc/elna-diagnostic.h +++ b/include/elna/gcc/elna-diagnostic.h @@ -31,6 +31,15 @@ along with GCC; see the file COPYING3. If not see namespace elna::gcc { + struct linemap_guard + { + explicit linemap_guard(const char *filename); + linemap_guard(const linemap_guard&) = delete; + linemap_guard(linemap_guard&&) = delete; + + ~linemap_guard(); + }; + location_t get_location(const boot::position *position); std::string print_type(tree type); void report_errors(const std::deque>& errors); diff --git a/include/elna/gcc/elna-generic.h b/include/elna/gcc/elna-generic.h index ad74bc2..e8ab874 100644 --- a/include/elna/gcc/elna-generic.h +++ b/include/elna/gcc/elna-generic.h @@ -80,7 +80,6 @@ namespace elna::gcc void visit(boot::binary_expression *expression) override; void visit(boot::unary_expression *expression) override; void visit(boot::constant_declaration *definition) override; - void visit(boot::type_declaration *declaration) override; void visit(boot::variable_declaration *declaration) override; void visit(boot::variable_expression *expression) override; void visit(boot::array_access_expression *expression) override;