Allow exporting global external variables
This commit is contained in:
		@@ -57,8 +57,6 @@ namespace elna::gcc
 | 
				
			|||||||
        tree identifier = get_identifier(name);
 | 
					        tree identifier = get_identifier(name);
 | 
				
			||||||
        tree type_declaration = build_decl(UNKNOWN_LOCATION, TYPE_DECL, identifier, type);
 | 
					        tree type_declaration = build_decl(UNKNOWN_LOCATION, TYPE_DECL, identifier, type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        TREE_PUBLIC(type_declaration) = 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        symbol_table->enter(name, type_declaration);
 | 
					        symbol_table->enter(name, type_declaration);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return type_declaration;
 | 
					        return type_declaration;
 | 
				
			||||||
@@ -82,24 +80,6 @@ namespace elna::gcc
 | 
				
			|||||||
        return symbol_table;
 | 
					        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<boot::type_field>& fields, tree composite_type_node,
 | 
					    tree build_composite_type(const std::vector<boot::type_field>& fields, tree composite_type_node,
 | 
				
			||||||
            std::shared_ptr<symbol_table> symbols)
 | 
					            std::shared_ptr<symbol_table> symbols)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -178,7 +158,7 @@ namespace elna::gcc
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (auto reference = type.get<boot::alias_type>())
 | 
					        else if (auto reference = type.get<boot::alias_type>())
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return handle_symbol(reference->name, reference, symbols);
 | 
					            return TREE_TYPE(handle_symbol(reference->name, reference, symbols));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return error_mark_node;
 | 
					        return error_mark_node;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -190,13 +170,21 @@ namespace elna::gcc
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (looked_up == NULL_TREE)
 | 
					        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));
 | 
					            TREE_PUBLIC(looked_up) = 1;
 | 
				
			||||||
        }
 | 
					            if (is_unique_type(type_tree))
 | 
				
			||||||
        else
 | 
					            {
 | 
				
			||||||
        {
 | 
					                TYPE_NAME(type_tree) = DECL_NAME(looked_up);
 | 
				
			||||||
            looked_up = TREE_TYPE(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;
 | 
					        return looked_up;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -236,6 +224,7 @@ namespace elna::gcc
 | 
				
			|||||||
        DECL_ARGUMENTS(fndecl) = argument_chain;
 | 
					        DECL_ARGUMENTS(fndecl) = argument_chain;
 | 
				
			||||||
        TREE_ADDRESSABLE(fndecl) = 1;
 | 
					        TREE_ADDRESSABLE(fndecl) = 1;
 | 
				
			||||||
        DECL_EXTERNAL(fndecl) = info.is_extern();
 | 
					        DECL_EXTERNAL(fndecl) = info.is_extern();
 | 
				
			||||||
 | 
					        TREE_PUBLIC(fndecl) = info.exported;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    tree declare_variable(const std::string& name, const boot::variable_info& info,
 | 
					    tree declare_variable(const std::string& name, const boot::variable_info& info,
 | 
				
			||||||
@@ -246,23 +235,31 @@ namespace elna::gcc
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        TREE_ADDRESSABLE(declaration_tree) = 1;
 | 
					        TREE_ADDRESSABLE(declaration_tree) = 1;
 | 
				
			||||||
        DECL_EXTERNAL(declaration_tree) = info.is_extern;
 | 
					        DECL_EXTERNAL(declaration_tree) = info.is_extern;
 | 
				
			||||||
 | 
					        TREE_PUBLIC(declaration_tree) = info.exported;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        symbols->enter(name, declaration_tree);
 | 
					        symbols->enter(name, declaration_tree);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return declaration_tree;
 | 
					        return declaration_tree;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void declare_type(const std::string& name, const boot::type_info& info, std::shared_ptr<symbol_table> symbols)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // The top level symbol table has basic (builtin) types in it which are not aliases.
 | 
				
			||||||
 | 
					        if (auto alias_type = info.symbol.get<boot::alias_type>())
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            tree type_declaration = handle_symbol(name, alias_type, symbols);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            TREE_PUBLIC(type_declaration) = info.exported;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void rewrite_symbol_table(std::shared_ptr<boot::symbol_table> info_table, std::shared_ptr<symbol_table> symbols)
 | 
					    void rewrite_symbol_table(std::shared_ptr<boot::symbol_table> info_table, std::shared_ptr<symbol_table> symbols)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        for (auto& [symbol_name, symbol_info] : *info_table)
 | 
					        for (auto& [symbol_name, symbol_info] : *info_table)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            if (auto type_info = symbol_info->is_type())
 | 
					            if (auto type_info = symbol_info->is_type())
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // The top level symbol table has basic (builtin) types in it which are not aliases.
 | 
					                declare_type(symbol_name, *type_info, symbols);
 | 
				
			||||||
                if (auto alias_type = type_info->symbol.get<boot::alias_type>())
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    handle_symbol(symbol_name, alias_type, symbols);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else if (auto variable_info = symbol_info->is_variable())
 | 
					            else if (auto variable_info = symbol_info->is_variable())
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,6 +21,16 @@ along with GCC; see the file COPYING3.  If not see
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace elna::gcc
 | 
					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)
 | 
					    location_t get_location(const boot::position *position)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        linemap_line_start(line_table, position->line, 0);
 | 
					        linemap_line_start(line_table, position->line, 0);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -295,10 +295,6 @@ namespace elna::gcc
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            constant->accept(this);
 | 
					            constant->accept(this);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        for (boot::type_declaration *const type : unit->types)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            type->accept(this);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        for (boot::variable_declaration *const variable : unit->variables)
 | 
					        for (boot::variable_declaration *const variable : unit->variables)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            variable->accept(this);
 | 
					            variable->accept(this);
 | 
				
			||||||
@@ -312,13 +308,11 @@ namespace elna::gcc
 | 
				
			|||||||
    void generic_visitor::visit(boot::procedure_declaration *definition)
 | 
					    void generic_visitor::visit(boot::procedure_declaration *definition)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        tree fndecl = this->symbols->lookup(definition->identifier.name);
 | 
					        tree fndecl = this->symbols->lookup(definition->identifier.name);
 | 
				
			||||||
        TREE_PUBLIC(fndecl) = definition->identifier.exported;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!definition->body.has_value())
 | 
					        if (!definition->body.has_value())
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        push_struct_function(fndecl, false);
 | 
					        push_struct_function(fndecl, false);
 | 
				
			||||||
        DECL_STRUCT_FUNCTION(fndecl)->language = ggc_cleared_alloc<language_function>();
 | 
					        DECL_STRUCT_FUNCTION(fndecl)->language = ggc_cleared_alloc<language_function>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -738,11 +732,6 @@ namespace elna::gcc
 | 
				
			|||||||
        this->current_expression = NULL_TREE;
 | 
					        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)
 | 
					    void generic_visitor::visit(boot::variable_declaration *declaration)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        for (const auto& variable_identifier : declaration->identifiers)
 | 
					        for (const auto& variable_identifier : declaration->identifiers)
 | 
				
			||||||
@@ -775,12 +764,11 @@ namespace elna::gcc
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                DECL_INITIAL(declaration_tree) = elna_pointer_nil_node;
 | 
					                DECL_INITIAL(declaration_tree) = elna_pointer_nil_node;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            TREE_PUBLIC(declaration_tree) = variable_identifier.exported;
 | 
					 | 
				
			||||||
            this->current_expression = NULL_TREE;
 | 
					            this->current_expression = NULL_TREE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (lang_hooks.decls.global_bindings_p())
 | 
					            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::get_create(declaration_tree);
 | 
				
			||||||
                varpool_node::finalize_decl(declaration_tree);
 | 
					                varpool_node::finalize_decl(declaration_tree);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								gcc/elna1.cc
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								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);
 | 
					        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);
 | 
					    elna::boot::dependency outcome = elna::boot::read_source(entry_point, filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (outcome.has_errors())
 | 
					    if (outcome.has_errors())
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        elna::gcc::report_errors(outcome.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 };
 | 
					    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);
 | 
					        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 });
 | 
					    state.cache.insert({ filename, outcome_bag });
 | 
				
			||||||
    elna::gcc::rewrite_symbol_table(outcome_bag.leave(), state.custom);
 | 
					    elna::gcc::rewrite_symbol_table(outcome_bag.leave(), state.custom);
 | 
				
			||||||
    linemap_add(line_table, LC_LEAVE, 0, NULL, 0);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return outcome;
 | 
					    return outcome;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,7 +31,7 @@ namespace elna::boot
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        std::unique_ptr<unit> tree;
 | 
					        std::unique_ptr<unit> tree;
 | 
				
			||||||
        std::unordered_map<std::string, std::shared_ptr<alias_type>> unresolved;
 | 
					        forward_table unresolved;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        explicit dependency(const char *path);
 | 
					        explicit dependency(const char *path);
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,6 +31,15 @@ along with GCC; see the file COPYING3.  If not see
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace elna::gcc
 | 
					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);
 | 
					    location_t get_location(const boot::position *position);
 | 
				
			||||||
    std::string print_type(tree type);
 | 
					    std::string print_type(tree type);
 | 
				
			||||||
    void report_errors(const std::deque<std::unique_ptr<boot::error>>& errors);
 | 
					    void report_errors(const std::deque<std::unique_ptr<boot::error>>& errors);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -80,7 +80,6 @@ namespace elna::gcc
 | 
				
			|||||||
        void visit(boot::binary_expression *expression) override;
 | 
					        void visit(boot::binary_expression *expression) override;
 | 
				
			||||||
        void visit(boot::unary_expression *expression) override;
 | 
					        void visit(boot::unary_expression *expression) override;
 | 
				
			||||||
        void visit(boot::constant_declaration *definition) 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_declaration *declaration) override;
 | 
				
			||||||
        void visit(boot::variable_expression *expression) override;
 | 
					        void visit(boot::variable_expression *expression) override;
 | 
				
			||||||
        void visit(boot::array_access_expression *expression) override;
 | 
					        void visit(boot::array_access_expression *expression) override;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user