From dea1c177cd3592cc24fd15ad446a676da2e4da28 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sat, 25 Jul 2026 23:33:22 +0200 Subject: Support #offset trait at compile time --- include/elna/boot/evaluator.h | 61 ++++++++++++++++++++++++++++---------- include/elna/boot/result.h | 3 +- include/elna/gcc/elna-builtins.h | 14 +++++---- include/elna/gcc/elna-diagnostic.h | 2 +- include/elna/gcc/elna-generic.h | 14 ++++----- include/elna/gcc/elna-tree.h | 9 +++--- 6 files changed, 67 insertions(+), 36 deletions(-) (limited to 'include') diff --git a/include/elna/boot/evaluator.h b/include/elna/boot/evaluator.h index 015a2c7..2d832bf 100644 --- a/include/elna/boot/evaluator.h +++ b/include/elna/boot/evaluator.h @@ -29,23 +29,36 @@ along with GCC; see the file COPYING3. If not see namespace elna::boot { + /** + * Size and alignment of a single type on the target machine. + */ + struct type_properties + { + std::size_t size{0}; + std::size_t alignment{0}; + }; + + /** + * Size, alignment and offset of each field of a record. + */ + struct record_properties + { + ordered_map offset_map; + std::size_t size; + std::size_t alignment; + }; + /** * Target machine information, populated by the compiler backend glue layer. */ struct target_info { - std::size_t int_size{0}; - std::size_t int_alignment{0}; - std::size_t word_size{0}; - std::size_t word_alignment{0}; - std::size_t pointer_size{0}; - std::size_t pointer_alignment{0}; - std::size_t char_size{0}; - std::size_t char_alignment{0}; - std::size_t float_size{0}; - std::size_t float_alignment{0}; - std::size_t bool_size{0}; - std::size_t bool_alignment{0}; + type_properties int_properties; + type_properties word_properties; + type_properties pointer_properties; + type_properties char_properties; + type_properties float_properties; + type_properties bool_properties; }; template typename C, template typename Alloc = std::allocator> @@ -85,27 +98,43 @@ namespace elna::boot { } - constant_value& operator*() + Container& operator*() { return *this->container; } - constant_value& operator*() const + const Container& operator*() const { return *this->container; } - constant_value *operator->() + Container *operator->() { return this->container.get(); } - constant_value *operator->() const + const Container *operator->() const { return this->container.get(); } }; + std::optional get_type_properties(const type& subject, const target_info& target); + + /** + * Computes the layout of a record type at compile time. + * + * Walks fields in layout order (base chain, root to leaf), aligning + * each field to its natural alignment. Uses \p target for size and + * alignment values so that the computation is backend-independent. + * + * \param subject The record type to lay out. + * \param target Target type information (sizes, alignments). + * \return Record layout, or std::nullopt if any field cannot be layed out. + */ + std::optional layout_record(const std::shared_ptr& subject, + const target_info& target); + /** * Called on-demand. */ diff --git a/include/elna/boot/result.h b/include/elna/boot/result.h index 1f22baf..0719151 100644 --- a/include/elna/boot/result.h +++ b/include/elna/boot/result.h @@ -26,7 +26,6 @@ along with GCC; see the file COPYING3. If not see #include #include #include -#include namespace elna::boot { @@ -217,7 +216,7 @@ namespace elna::boot } else { - return this->payload.at(search_result->second); + return this->payload.begin() + search_result->second; } } diff --git a/include/elna/gcc/elna-builtins.h b/include/elna/gcc/elna-builtins.h index 0cdf519..846a8db 100644 --- a/include/elna/gcc/elna-builtins.h +++ b/include/elna/gcc/elna-builtins.h @@ -30,12 +30,14 @@ namespace elna::gcc void init_ttree(); std::shared_ptr builtin_symbol_table(); - void rewrite_symbol_table(std::shared_ptr info_table, std::shared_ptr symbols); - tree handle_symbol(const std::string& symbol_name, std::shared_ptr reference, - std::shared_ptr symbols); - tree get_inner_alias(const boot::type& type, std::shared_ptr symbols); + void rewrite_symbol_table(const std::shared_ptr& info_table, + const std::shared_ptr& symbols); + tree handle_symbol(const std::string& symbol_name, + const std::shared_ptr& reference, + const std::shared_ptr& symbols); + tree get_inner_alias(const boot::type& type, const std::shared_ptr& symbols); void declare_procedure(const std::string& name, const boot::procedure_info& info, - std::shared_ptr symbols); + const std::shared_ptr& symbols); tree declare_variable(const std::string& name, const boot::variable_info& info, - std::shared_ptr symbols); + const std::shared_ptr& symbols); } diff --git a/include/elna/gcc/elna-diagnostic.h b/include/elna/gcc/elna-diagnostic.h index 31e180e..2cb30f5 100644 --- a/include/elna/gcc/elna-diagnostic.h +++ b/include/elna/gcc/elna-diagnostic.h @@ -33,7 +33,7 @@ namespace elna::gcc struct linemap_guard { explicit linemap_guard(const char *filename); - explicit linemap_guard(const std::filesystem::path filename); + explicit linemap_guard(const std::filesystem::path& filename); linemap_guard(const linemap_guard&) = delete; linemap_guard(linemap_guard&&) = delete; diff --git a/include/elna/gcc/elna-generic.h b/include/elna/gcc/elna-generic.h index 727c646..27fdb43 100644 --- a/include/elna/gcc/elna-generic.h +++ b/include/elna/gcc/elna-generic.h @@ -42,6 +42,12 @@ namespace elna::gcc std::map evaluated_initializers; std::unique_ptr const_evaluator; + static tree build_equality(boot::binary_expression *expression, tree left, tree right); + static tree build_equality_comparison(location_t loc, tree left, tree right, + const boot::type& left_type, tree_code equality_code); + static std::pair build_loop_head(tree control_variable_declaration, + tree limit, tree_code comparison, location_t check_location); + void enter_scope(); tree leave_scope(); @@ -51,9 +57,6 @@ namespace elna::gcc tree make_if_branch(boot::conditional_statements& branch, tree next, tree goto_append = NULL_TREE); - tree build_equality(boot::binary_expression *expression, tree left, tree right); - tree build_equality_comparison(location_t loc, tree left, tree right, - const boot::type& left_type, tree_code equality_code); void build_case_integral(boot::case_statement *statement, tree condition_expression); void build_case_general(boot::case_statement *statement, tree condition_expression); void build_procedure_call(location_t call_location, @@ -61,16 +64,13 @@ namespace elna::gcc bool build_builtin_procedures(boot::procedure_call *call); void build_assert_builtin(location_t call_location, const std::vector& arguments); - bool expect_trait_type_only(boot::traits_expression *trait); void visit_statements(const std::vector& statements); bool assert_constant(location_t expression_location); tree declare_local_variable(const boot::identifier& name, const boot::variable_info& info, tree initial_value); - std::pair build_loop_head(tree control_variable_declaration, tree limit, - tree_code comparison, location_t check_location); public: - generic_visitor(std::shared_ptr symbol_table, + generic_visitor(const std::shared_ptr& symbol_table, elna::boot::symbol_bag bag, const elna::boot::target_info& target); void visit(boot::procedure_declaration *declaration) override; diff --git a/include/elna/gcc/elna-tree.h b/include/elna/gcc/elna-tree.h index ac97e41..a989656 100644 --- a/include/elna/gcc/elna-tree.h +++ b/include/elna/gcc/elna-tree.h @@ -17,8 +17,6 @@ along with GCC; see the file COPYING3. If not see #pragma once -#include - #include "config.h" #include "system.h" #include "coretypes.h" @@ -28,6 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "fold-const.h" #include "elna/boot/ast.h" +#include "elna/boot/evaluator.h" #include "elna/boot/symbol.h" #include "elna/gcc/elna1.h" @@ -60,12 +59,14 @@ namespace elna::gcc tree chain_defer(); tree do_pointer_arithmetic(boot::binary_operator binary_operator, - tree left, tree right, location_t expression_location); - tree build_field(location_t location, tree record_type, const std::string name, tree type); + tree left, tree right, location_t operation_location); + tree build_field(location_t location, tree record_type, const std::string& name, tree type); tree find_field_by_name(location_t expression_location, tree type, const std::string& field_name); tree build_static_array_type(tree type, const std::uint64_t size); tree build_enumeration_type(const std::vector& members); + const elna::boot::target_info& get_host_target(); + tree extract_constant(tree expression); template -- cgit v1.2.3