aboutsummaryrefslogtreecommitdiff
path: root/gcc/gcc/elna-tree.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/gcc/elna-tree.cc')
-rw-r--r--gcc/gcc/elna-tree.cc39
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)
{