diff options
Diffstat (limited to 'gcc/gcc/elna-tree.cc')
| -rw-r--r-- | gcc/gcc/elna-tree.cc | 39 |
1 files changed, 22 insertions, 17 deletions
diff --git a/gcc/gcc/elna-tree.cc b/gcc/gcc/elna-tree.cc index cddb407..7aa4012 100644 --- a/gcc/gcc/elna-tree.cc +++ b/gcc/gcc/elna-tree.cc @@ -97,6 +97,14 @@ namespace elna::gcc return field_declaration; } + // The generic Pointer has no pointee size; it advances byte by byte. + static tree pointer_stride(tree pointer_type, tree offset_type) + { + return pointer_type == elna_pointer_type_node + ? size_one_node + : fold_convert(offset_type, size_in_bytes(TREE_TYPE(pointer_type))); + } + tree do_pointer_arithmetic(boot::binary_operator binary_operator, tree left, tree right, location_t operation_location) { @@ -124,9 +132,7 @@ namespace elna::gcc { return error_mark_node; } - tree size_exp = pointer_type == elna_pointer_type_node - ? size_one_node - : fold_convert(TREE_TYPE(offset), size_in_bytes(TREE_TYPE(TREE_TYPE(pointer)))); + tree size_exp = pointer_stride(pointer_type, TREE_TYPE(offset)); offset = fold_build2(MULT_EXPR, TREE_TYPE(offset), offset, size_exp); offset = fold_convert(size_type_node, offset); @@ -139,7 +145,7 @@ namespace elna::gcc { tree pointer_type = left_type; tree offset_type = right_type; - tree size_exp = fold_convert(offset_type, size_in_bytes(TREE_TYPE(pointer_type))); + tree size_exp = pointer_stride(pointer_type, offset_type); tree convert_expression = fold_build2(MULT_EXPR, offset_type, right, size_exp); convert_expression = fold_convert(size_type_node, convert_expression); @@ -156,13 +162,11 @@ namespace elna::gcc gcc_unreachable(); } - tree find_field_by_name(location_t, tree type, const std::string& field_name) + tree find_field_by_name(tree type, const std::string& field_name) { - // NOLINTNEXTLINE(readability-simplify-boolean-expr) - if (type == error_mark_node || !RECORD_OR_UNION_TYPE_P(type)) - { - return error_mark_node; - } + // Name analysis rejects a field the record does not have. + gcc_assert(RECORD_OR_UNION_TYPE_P(type)); + for (tree field = TYPE_FIELDS(type); field != NULL_TREE; field = TREE_CHAIN(field)) { if (field_name == IDENTIFIER_POINTER(DECL_NAME(field))) @@ -170,7 +174,7 @@ namespace elna::gcc return field; } } - return error_mark_node; + gcc_unreachable(); } tree build_static_array_type(tree type, const std::uint64_t size) @@ -233,8 +237,13 @@ namespace elna::gcc tree extract_constant(tree expression) { const int code = TREE_CODE(expression); + // A mutable variable can have a constant initializer too, so readonly is + // what marks one whose value is known at compile time. + const bool constant_variable = code == VAR_DECL && TREE_READONLY(expression) + && DECL_INITIAL(expression) != NULL_TREE + && TREE_CONSTANT(DECL_INITIAL(expression)); - if (code == CONST_DECL) + if (code == CONST_DECL || constant_variable) { return DECL_INITIAL(expression); } @@ -333,11 +342,7 @@ namespace elna::gcc for (const auto& [field_name, field_value] : fields) { - tree field_decl = find_field_by_name(UNKNOWN_LOCATION, type, field_name); - if (field_decl == error_mark_node) - { - return NULL_TREE; - } + tree field_decl = find_field_by_name(type, field_name); tree value_tree = constant_to_tree(field_value, symbols, TREE_TYPE(field_decl)); if (value_tree == NULL_TREE) { |
