aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/gcc/elna-builtins.cc14
-rw-r--r--gcc/gcc/elna-generic.cc9
2 files changed, 23 insertions, 0 deletions
diff --git a/gcc/gcc/elna-builtins.cc b/gcc/gcc/elna-builtins.cc
index 637e37a..7d2f8f0 100644
--- a/gcc/gcc/elna-builtins.cc
+++ b/gcc/gcc/elna-builtins.cc
@@ -255,6 +255,20 @@ namespace elna::gcc
{
return TREE_TYPE(handle_symbol(reference->name, reference, symbols));
}
+ else if (type.get<boot::parameter_type>() != nullptr)
+ {
+ return elna_pointer_type_node;
+ }
+ else if (auto reference = type.get<boot::instantiated_type>())
+ {
+ // Erasure is argument blind, so every instantiation of one generic
+ // shares the tree the generic's own name is bound to.
+ return get_inner_alias(reference->generic, symbols, placeholder);
+ }
+ else if (auto reference = type.get<boot::generic_type>())
+ {
+ return get_inner_alias(reference->referent, symbols, placeholder);
+ }
return error_mark_node;
}
diff --git a/gcc/gcc/elna-generic.cc b/gcc/gcc/elna-generic.cc
index 45d8311..b67e91c 100644
--- a/gcc/gcc/elna-generic.cc
+++ b/gcc/gcc/elna-generic.cc
@@ -875,7 +875,16 @@ namespace elna::gcc
{
expression->base().accept(this);
const location_t expression_location = get_location(&expression->position());
+ tree pointee = get_inner_alias(expression->type_decoration, this->symbols);
+ // A field read out of an erased generic record is typed by the erasure,
+ // so the pointer is converted before it is dereferenced, which keeps
+ // the result an lvalue.
+ if (TREE_TYPE(TREE_TYPE(this->current_expression)) != pointee)
+ {
+ this->current_expression = fold_convert_loc(expression_location,
+ build_pointer_type(pointee), this->current_expression);
+ }
this->current_expression = build_simple_mem_ref_loc(expression_location,
this->current_expression);
}