From 74e75e41fe12f19e5365a3152ffafa1a29376240 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sat, 19 Sep 2026 23:52:00 +0200 Subject: Reject exporting symbols with the same name from 2 modules --- include/elna/boot/dependency.h | 19 ++++++++++++++++--- include/elna/boot/symbol.h | 30 +++++++++++++++++++++++------- 2 files changed, 39 insertions(+), 10 deletions(-) (limited to 'include') diff --git a/include/elna/boot/dependency.h b/include/elna/boot/dependency.h index 195d37a..a87503e 100644 --- a/include/elna/boot/dependency.h +++ b/include/elna/boot/dependency.h @@ -148,6 +148,16 @@ namespace elna::boot */ std::filesystem::path build_path(const std::vector& segments); + /** + * Symbols brought in by one import declaration, paired with the position + * of the declaration that requested them. + */ + struct module_import + { + source_position position; + std::shared_ptr symbols; + }; + /** * Analyzes a module semantically: collects type declarations, resolves * names, checks types and validates the module. @@ -165,7 +175,7 @@ namespace elna::boot * \return Module scope and diagnostics. */ analysis_result analyze_semantics(std::unique_ptr& tree, - const std::vector>& imports, + const std::vector& imports, const std::shared_ptr& globals, const target_info& target, const std::filesystem::path& module_path); @@ -257,7 +267,7 @@ namespace elna::boot return result; } auto& tree = std::get>(parsed); - std::vector> imports; + std::vector imports; diagnostic_list circular; if (imported && tree->entry_point.has_value()) @@ -289,7 +299,10 @@ namespace elna::boot { result.append(std::move(diagnostics.module), std::move(diagnostics.errors())); } - imports.push_back(this->cache.find(module_path)->second.exported_symbols()); + imports.push_back({ + .position = sub_tree->position(), + .symbols = this->cache.find(module_path)->second.exported_symbols() + }); } result.append(key, std::move(circular)); analysis_result analysis = analyze_semantics(tree, imports, this->globals, target, key); diff --git a/include/elna/boot/symbol.h b/include/elna/boot/symbol.h index 5bbe2c6..a5f7ca8 100644 --- a/include/elna/boot/symbol.h +++ b/include/elna/boot/symbol.h @@ -19,7 +19,7 @@ along with GCC; see the file COPYING3. If not see #include #include -#include +#include #include #include #include @@ -300,11 +300,13 @@ namespace elna::boot std::is_convertible_v || std::is_assignable_v, T >; - using iterator = std::unordered_map::iterator; - using const_iterator = std::unordered_map::const_iterator; + using iterator = std::map::iterator; + using const_iterator = std::map::const_iterator; private: - std::unordered_map entries; + // Ordered, so that a pass iterating the table reports in a stable + // order without sorting first. + std::map entries; std::shared_ptr outer_scope; public: @@ -527,6 +529,16 @@ namespace elna::boot std::shared_ptr builtin_symbol_table(const target_info& target); + /** + * A name exported by more than one imported module. + */ + struct import_collision + { + std::string name; + /// The symbol imported first, which keeps the name. + std::shared_ptr original; + }; + /** * Symbol bag contains: * @@ -537,7 +549,7 @@ namespace elna::boot class symbol_bag { std::shared_ptr symbols; - std::forward_list> imports; + std::vector> imports; forward_table unresolved; std::shared_ptr lookup_import(const std::string& name) const; @@ -619,11 +631,15 @@ namespace elna::boot bool forward_declare(const std::string& symbol_name, std::shared_ptr forward_declaration); /** - * Add imported symbols to the scope. + * Add imported symbols to the scope. The symbols are appended, so an + * earlier import keeps its names. * * \param symbols Exported symbol table of another module. + * + * \return Names an earlier import already brought into the scope, + * sorted by name. */ - void add_import(const std::shared_ptr& symbols); + std::vector add_import(const std::shared_ptr& symbols); /** * Tells whether the current scope is the module global scope. -- cgit v1.2.3