aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2026-07-17 13:49:20 +0200
committerEugen Wissner <belka@caraus.de>2026-07-17 13:49:20 +0200
commit44a0c221d51c9aa036b47b218a6caea4424f5996 (patch)
tree0a83ceb4b938b893f393f647e355546d24b65dd4 /include
parenta0e1740227535adc3151c02eb102c4f96b4f9731 (diff)
downloadelna-44a0c221d51c9aa036b47b218a6caea4424f5996.tar.gz
Handle const Pointer as const pointer to const data
Diffstat (limited to 'include')
-rw-r--r--include/elna/boot/name_analysis.h153
-rw-r--r--include/elna/boot/type_check.h (renamed from include/elna/boot/semantic.h)165
-rw-r--r--include/elna/gcc/elna-generic.h1
3 files changed, 186 insertions, 133 deletions
diff --git a/include/elna/boot/name_analysis.h b/include/elna/boot/name_analysis.h
new file mode 100644
index 0000000..4498d0c
--- /dev/null
+++ b/include/elna/boot/name_analysis.h
@@ -0,0 +1,153 @@
+/* Name analysis.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#pragma once
+
+#include <string>
+#include <memory>
+#include <map>
+
+#include "elna/boot/ast.h"
+#include "elna/boot/result.h"
+#include "elna/boot/symbol.h"
+#include "elna/boot/type_check.h"
+
+namespace elna::boot
+{
+ /**
+ * Error declaring a symbol.
+ */
+ class declaration_error : public error
+ {
+ public:
+ enum class kind
+ {
+ undeclared,
+ local_export
+ };
+
+ private:
+ std::string identifier;
+ kind error_kind;
+
+ public:
+
+ declaration_error(const kind error_kind,
+ const boot::identifier& identifier);
+
+ std::string what() const override;
+ };
+
+ /**
+ * Attempted to redefine a name that is already in use in the
+ * current scope.
+ */
+ class redefinition_error : public error
+ {
+ std::string identifier;
+ std::optional<source_position> original;
+
+ public:
+ redefinition_error(const boot::identifier& identifier,
+ std::optional<source_position> original);
+
+ std::string what() const override;
+
+ std::optional<std::pair<std::string, source_position>> note() const override;
+ };
+
+ /**
+ * Origin of a field in a composite type.
+ */
+ struct field_origin
+ {
+ std::optional<source_position> declaration;
+ type base_type;
+ };
+
+ /**
+ * Performs name analysis.
+ */
+ class name_analysis_visitor final : public walking_visitor, public error_container
+ {
+ type current_type;
+
+ symbol_bag bag;
+
+ std::pair<procedure_type, std::vector<std::string>> build_procedure(
+ procedure_type_expression& expression);
+ std::vector<type_field> build_composite_type(const std::vector<field_declaration>& fields,
+ std::map<std::string, field_origin>& known_names,
+ type aggregate);
+ std::shared_ptr<variable_info> register_variable(const std::string& name,
+ const bool is_extern, const source_position position);
+
+ type lookup_primitive_type(const std::string& name);
+ type lookup_field(const type& composite_type, const std::string& field_name);
+
+ public:
+ name_analysis_visitor(symbol_bag bag);
+
+ void visit(array_type_expression *expression) override;
+ void visit(pointer_type_expression *expression) override;
+ void visit(constant_type_expression *expression) override;
+ void visit(type_declaration *declaration) override;
+ void visit(record_type_expression *expression) override;
+ void visit(record_constructor_expression *expression) override;
+ void visit(array_constructor_expression *expression) override;
+ void visit(procedure_type_expression *expression) override;
+ void visit(enumeration_type_expression *expression) override;
+
+ void visit(variable_declaration *declaration) override;
+ void visit(procedure_declaration *declaration) override;
+
+ void visit(procedure_call *call) override;
+ void visit(unit *unit) override;
+ void visit(cast_expression *expression) override;
+ void visit(traits_expression *trait) override;
+ void visit(binary_expression *expression) override;
+ void visit(unary_expression *expression) override;
+ void visit(named_expression *expression) override;
+ void visit(array_access_expression *expression) override;
+ void visit(field_access_expression *expression) override;
+ void visit(dereference_expression *expression) override;
+ void visit(literal<std::int32_t> *literal) override;
+ void visit(literal<std::uint32_t> *literal) override;
+ void visit(literal<double> *literal) override;
+ void visit(literal<bool> *literal) override;
+ void visit(literal<unsigned char> *literal) override;
+ void visit(literal<std::nullptr_t> *literal) override;
+ void visit(literal<std::string> *literal) override;
+ };
+
+ /**
+ * Collects global declarations without resolving any symbols.
+ */
+ class declaration_visitor final : public empty_visitor, public error_container
+ {
+ public:
+ forward_table unresolved;
+
+ explicit declaration_visitor();
+
+ void visit(import_declaration *) override;
+ void visit(unit *unit) override;
+ void visit(type_declaration *declaration) override;
+ void visit(procedure_declaration *declaration) override;
+ void visit(variable_declaration *declaration) override;
+ };
+}
diff --git a/include/elna/boot/semantic.h b/include/elna/boot/type_check.h
index 3d2de10..b250f48 100644
--- a/include/elna/boot/semantic.h
+++ b/include/elna/boot/type_check.h
@@ -1,4 +1,4 @@
-/* Name analysis.
+/* Type analysis.
Copyright (C) 2025 Free Software Foundation, Inc.
GCC is free software; you can redistribute it and/or modify
@@ -19,7 +19,7 @@ along with GCC; see the file COPYING3. If not see
#include <string>
#include <memory>
-#include <map>
+#include <vector>
#include "elna/boot/ast.h"
#include "elna/boot/result.h"
@@ -28,48 +28,6 @@ along with GCC; see the file COPYING3. If not see
namespace elna::boot
{
/**
- * Error declaring a symbol.
- */
- class declaration_error : public error
- {
- public:
- enum class kind
- {
- undeclared,
- local_export
- };
-
- private:
- std::string identifier;
- kind error_kind;
-
- public:
-
- declaration_error(const kind error_kind,
- const boot::identifier& identifier);
-
- std::string what() const override;
- };
-
- /**
- * Attempted to redefine a name that is already in use in the
- * current scope.
- */
- class redefinition_error : public error
- {
- std::string identifier;
- std::optional<source_position> original;
-
- public:
- redefinition_error(const boot::identifier& identifier,
- std::optional<source_position> original);
-
- std::string what() const override;
-
- std::optional<std::pair<std::string, source_position>> note() const override;
- };
-
- /**
* Expected type does not match the actual type of an expression.
*/
class type_mismatch_error : public error
@@ -205,7 +163,37 @@ namespace elna::boot
};
/**
- * Checks types.
+ * Chain of responsibility for type compatibility checks.
+ *
+ * Populate \c ctx with pre-resolved types, then call \c run().
+ * Each handler inspects the context and returns a verdict —
+ * the first non-\c pass verdict wins.
+ */
+ struct assign_check
+ {
+ enum class verdict { pass, accept, reject };
+
+ struct context
+ {
+ type aliased_assignee;
+ type aliased_assignment;
+ type resolved_assignee;
+ type resolved_assignment;
+ };
+ context ctx;
+
+ verdict guard_const_laundering();
+ verdict check_exact_match();
+ verdict check_pointer_hatch();
+ verdict check_pointer_conversion();
+
+ bool run();
+ };
+
+ /**
+ * Checks types: assignment compatibility, const-correctness,
+ * procedure argument counts, record field validity,
+ * and type declaration well-formedness.
*/
class type_analysis_visitor final : public walking_visitor, public error_container
{
@@ -217,12 +205,6 @@ namespace elna::boot
* of type assignee.
*/
static bool is_assignable_from(const type& assignee, const type& assignment);
- /*
- * Checks whether derived has base in its parent chain.
- * base should not be null, derived can be null.
- */
- static bool is_base_of(const std::shared_ptr<record_type>& base,
- const std::shared_ptr<record_type>& derived);
static bool check_unresolved_symbol(std::shared_ptr<alias_type> alias,
std::vector<std::string>& path);
@@ -240,85 +222,4 @@ namespace elna::boot
void visit(record_constructor_expression *expression) override;
void visit(array_constructor_expression *expression) override;
};
-
- /**
- * Origin of a field in a composite type.
- */
- struct field_origin
- {
- std::optional<source_position> declaration;
- type base_type;
- };
-
- /**
- * Performs name analysis.
- */
- class name_analysis_visitor final : public walking_visitor, public error_container
- {
- type current_type;
-
- symbol_bag bag;
-
- std::pair<procedure_type, std::vector<std::string>> build_procedure(
- procedure_type_expression& expression);
- std::vector<type_field> build_composite_type(const std::vector<field_declaration>& fields,
- std::map<std::string, field_origin>& known_names,
- type aggregate);
- std::shared_ptr<variable_info> register_variable(const std::string& name,
- const bool is_extern, const source_position position);
-
- type lookup_primitive_type(const std::string& name);
- type lookup_field(const type& composite_type, const std::string& field_name);
-
- public:
- name_analysis_visitor(symbol_bag bag);
-
- void visit(array_type_expression *expression) override;
- void visit(pointer_type_expression *expression) override;
- void visit(constant_type_expression *expression) override;
- void visit(type_declaration *declaration) override;
- void visit(record_type_expression *expression) override;
- void visit(record_constructor_expression *expression) override;
- void visit(array_constructor_expression *expression) override;
- void visit(procedure_type_expression *expression) override;
- void visit(enumeration_type_expression *expression) override;
-
- void visit(variable_declaration *declaration) override;
- void visit(procedure_declaration *declaration) override;
-
- void visit(procedure_call *call) override;
- void visit(unit *unit) override;
- void visit(cast_expression *expression) override;
- void visit(traits_expression *trait) override;
- void visit(binary_expression *expression) override;
- void visit(unary_expression *expression) override;
- void visit(named_expression *expression) override;
- void visit(array_access_expression *expression) override;
- void visit(field_access_expression *expression) override;
- void visit(dereference_expression *expression) override;
- void visit(literal<std::int32_t> *literal) override;
- void visit(literal<std::uint32_t> *literal) override;
- void visit(literal<double> *literal) override;
- void visit(literal<bool> *literal) override;
- void visit(literal<unsigned char> *literal) override;
- void visit(literal<std::nullptr_t> *literal) override;
- void visit(literal<std::string> *literal) override;
- };
-
- /**
- * Collects global declarations without resolving any symbols.
- */
- class declaration_visitor final : public empty_visitor, public error_container
- {
- public:
- forward_table unresolved;
-
- explicit declaration_visitor();
-
- void visit(import_declaration *) override;
- void visit(unit *unit) override;
- void visit(type_declaration *declaration) override;
- void visit(procedure_declaration *declaration) override;
- void visit(variable_declaration *declaration) override;
- };
}
diff --git a/include/elna/gcc/elna-generic.h b/include/elna/gcc/elna-generic.h
index a1689be..dd5c9ef 100644
--- a/include/elna/gcc/elna-generic.h
+++ b/include/elna/gcc/elna-generic.h
@@ -20,7 +20,6 @@ along with GCC; see the file COPYING3. If not see
#include <string>
#include "elna/boot/ast.h"
#include "elna/boot/symbol.h"
-#include "elna/boot/semantic.h"
#include "elna/gcc/elna-tree.h"
#include "config.h"