aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-07-25 23:33:22 +0200
committerEugen Wissner <belka@caraus.de>2026-07-26 02:45:19 +0200
commitdea1c177cd3592cc24fd15ad446a676da2e4da28 (patch)
treeca29eefe25858ca49d376614ecf6ddda9e144299 /include
parent4f89a02e03b056d0c55108a8c9194126ef4ee811 (diff)
downloadelna-dea1c177cd3592cc24fd15ad446a676da2e4da28.tar.gz
Support #offset trait at compile time
Diffstat (limited to 'include')
-rw-r--r--include/elna/boot/evaluator.h61
-rw-r--r--include/elna/boot/result.h3
-rw-r--r--include/elna/gcc/elna-builtins.h14
-rw-r--r--include/elna/gcc/elna-diagnostic.h2
-rw-r--r--include/elna/gcc/elna-generic.h14
-rw-r--r--include/elna/gcc/elna-tree.h9
6 files changed, 67 insertions, 36 deletions
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
@@ -30,22 +30,35 @@ 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<std::size_t> 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<template<typename, typename> typename C, template<typename> 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<type_properties> 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<record_properties> layout_record(const std::shared_ptr<record_type>& 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 <variant>
#include <vector>
#include <unordered_map>
-#include <ranges>
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<symbol_table> builtin_symbol_table();
- void rewrite_symbol_table(std::shared_ptr<boot::symbol_table> info_table, std::shared_ptr<symbol_table> symbols);
- tree handle_symbol(const std::string& symbol_name, std::shared_ptr<boot::alias_type> reference,
- std::shared_ptr<symbol_table> symbols);
- tree get_inner_alias(const boot::type& type, std::shared_ptr<symbol_table> symbols);
+ void rewrite_symbol_table(const std::shared_ptr<boot::symbol_table>& info_table,
+ const std::shared_ptr<symbol_table>& symbols);
+ tree handle_symbol(const std::string& symbol_name,
+ const std::shared_ptr<boot::alias_type>& reference,
+ const std::shared_ptr<symbol_table>& symbols);
+ tree get_inner_alias(const boot::type& type, const std::shared_ptr<symbol_table>& symbols);
void declare_procedure(const std::string& name, const boot::procedure_info& info,
- std::shared_ptr<symbol_table> symbols);
+ const std::shared_ptr<symbol_table>& symbols);
tree declare_variable(const std::string& name, const boot::variable_info& info,
- std::shared_ptr<symbol_table> symbols);
+ const std::shared_ptr<symbol_table>& 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<std::string, boot::expression *> evaluated_initializers;
std::unique_ptr<boot::evaluator> 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<tree, tree> 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<boot::expression *>& arguments);
- bool expect_trait_type_only(boot::traits_expression *trait);
void visit_statements(const std::vector<boot::statement *>& 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<tree, tree> build_loop_head(tree control_variable_declaration, tree limit,
- tree_code comparison, location_t check_location);
public:
- generic_visitor(std::shared_ptr<symbol_table> symbol_table,
+ generic_visitor(const std::shared_ptr<symbol_table>& 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 <forward_list>
-
#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<std::string>& members);
+ const elna::boot::target_info& get_host_target();
+
tree extract_constant(tree expression);
template<typename... Args>