diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/elna/boot/type_check.h | 26 | ||||
| -rw-r--r-- | include/elna/gcc/elna-generic.h | 4 |
2 files changed, 27 insertions, 3 deletions
diff --git a/include/elna/boot/type_check.h b/include/elna/boot/type_check.h index 5faec43..582b887 100644 --- a/include/elna/boot/type_check.h +++ b/include/elna/boot/type_check.h @@ -181,6 +181,10 @@ namespace elna::boot { type actual; }; + struct argument_not_scalar + { + type actual; + }; struct constant_argument { type actual; @@ -196,8 +200,8 @@ namespace elna::boot }; using payload_type = std::variant<not_generic, unused_parameter, - argument_not_pointer, constant_argument, uninferrable_parameter, - shape_mismatch>; + argument_not_pointer, argument_not_scalar, constant_argument, + uninferrable_parameter, shape_mismatch>; generic_error(const source_position position, const std::string& generic_name, payload_type payload); @@ -210,6 +214,21 @@ namespace elna::boot }; /** + * What a generic declaration accepts as a type argument. + * + * An erased generic takes a pointer, because that is what its single + * compiled body knows how to move. A builtin has no body to erase, so it + * takes whatever it can load or store, and only a reading one tolerates a + * constant. + */ + enum class argument_rule + { + pointer, + scalar, + mutable_scalar + }; + + /** * Chain of responsibility for type compatibility checks. * * Populate \c ctx with pre-resolved types, then call \c run(). @@ -265,7 +284,8 @@ namespace elna::boot static bool is_equality_compatible(const type& left, const type& right); void visit_and_validate_condition(expression& condition); - void check_arguments(const named_expression& reference, const std::vector<type>& arguments); + void check_arguments(const named_expression& reference, const std::vector<type>& arguments, + const argument_rule rule); void check_parameters_used(const source_position position, const std::string& name, const std::vector<type>& parameters, const type& heading); type infer_call(procedure_call& call, const named_expression& reference, diff --git a/include/elna/gcc/elna-generic.h b/include/elna/gcc/elna-generic.h index fbd68d8..dde883a 100644 --- a/include/elna/gcc/elna-generic.h +++ b/include/elna/gcc/elna-generic.h @@ -61,6 +61,10 @@ namespace elna::gcc const std::vector<boot::type>& argument_types); bool build_builtin_procedures(boot::procedure_call *call); void build_assert_builtin(location_t call_location, const std::vector<boot::expression *>& arguments); + tree build_volatile_reference(location_t location, boot::expression& pointer, + const boot::type& accessed); + void build_volatile_load_builtin(location_t call_location, boot::procedure_call *call); + void build_volatile_store_builtin(location_t call_location, boot::procedure_call *call); void visit_statements(const std::vector<boot::statement *>& statements); void assert_constant(); |
