Index strings

This commit is contained in:
2025-02-12 20:47:47 +01:00
parent f991686330
commit 137802914e
10 changed files with 85 additions and 56 deletions

View File

@ -41,14 +41,13 @@ namespace gcc
elna_string_type_node = make_node(RECORD_TYPE);
tree string_ptr_type = build_pointer_type_for_mode(elna_char_type_node, VOIDmode, true);
tree record_chain = NULL_TREE;
record_chain = chainon(record_chain,
build_field(UNKNOWN_LOCATION, elna_string_type_node, "length", elna_word_type_node));
record_chain = chainon(record_chain,
build_field(UNKNOWN_LOCATION, elna_string_type_node, "ptr", string_ptr_type));
elna_string_length_field_node = build_field(UNKNOWN_LOCATION,
elna_string_type_node, "length", elna_word_type_node);
elna_string_ptr_field_node = build_field(UNKNOWN_LOCATION,
elna_string_type_node, "ptr", string_ptr_type);
TYPE_FIELDS(elna_string_type_node) = record_chain;
TYPE_FIELDS(elna_string_type_node) = chainon(elna_string_ptr_field_node, elna_string_length_field_node);
layout_type(elna_string_type_node);
}
}

View File

@ -58,11 +58,15 @@ namespace gcc
{
return "Char";
}
else if (type == elna_string_type_node)
{
return "String";
}
else if (is_pointer_type(type))
{
return std::string("\"pointer to " + print_type(TREE_TYPE(type)) + "\"");
}
else if (TREE_CODE(type) == ARRAY_TYPE)
else if (is_array_type(type))
{
return "array";
}

View File

@ -347,14 +347,14 @@ namespace gcc
TREE_READONLY(string_literal) = 1;
TREE_STATIC(string_literal) = 1;
string_type = TREE_TYPE(TREE_CHAIN(TYPE_FIELDS(elna_string_type_node)));
string_type = TREE_TYPE(elna_string_ptr_field_node);
string_literal = build4(ARRAY_REF, elna_char_type_node,
string_literal, integer_zero_node, NULL_TREE, NULL_TREE);
string_literal = build1(ADDR_EXPR, string_type, string_literal);
vec<constructor_elt, va_gc> *elms = NULL;
CONSTRUCTOR_APPEND_ELT(elms, TYPE_FIELDS(elna_string_type_node), index_constant);
CONSTRUCTOR_APPEND_ELT(elms, TREE_CHAIN(TYPE_FIELDS(elna_string_type_node)), string_literal);
CONSTRUCTOR_APPEND_ELT(elms, elna_string_ptr_field_node, string_literal);
CONSTRUCTOR_APPEND_ELT(elms, elna_string_length_field_node, index_constant);
this->current_expression = build_constructor(elna_string_type_node, elms);
}
@ -401,14 +401,15 @@ namespace gcc
}
if (TREE_TYPE(left) == elna_string_type_node)
{
tree length_field = TYPE_FIELDS(elna_string_type_node);
tree ptr_field = TREE_CHAIN(length_field);
tree lhs_length = build3(COMPONENT_REF, TREE_TYPE(elna_string_length_field_node),
left, elna_string_length_field_node, NULL_TREE);
tree lhs_ptr = build3(COMPONENT_REF, TREE_TYPE(elna_string_ptr_field_node),
left, elna_string_ptr_field_node, NULL_TREE);
tree lhs_length = build3(COMPONENT_REF, TREE_TYPE(length_field), left, length_field, NULL_TREE);
tree lhs_ptr = build3(COMPONENT_REF, TREE_TYPE(ptr_field), left, ptr_field, NULL_TREE);
tree rhs_length = build3(COMPONENT_REF, TREE_TYPE(length_field), right, length_field, NULL_TREE);
tree rhs_ptr = build3(COMPONENT_REF, TREE_TYPE(ptr_field), right, ptr_field, NULL_TREE);
tree rhs_length = build3(COMPONENT_REF, TREE_TYPE(elna_string_length_field_node),
right, elna_string_length_field_node, NULL_TREE);
tree rhs_ptr = build3(COMPONENT_REF, TREE_TYPE(elna_string_ptr_field_node),
right, elna_string_ptr_field_node, NULL_TREE);
tree length_equality = build2(equality_code, elna_bool_type_node, lhs_length, rhs_length);
tree *memcmp = elna_global_decls->get("__builtin_memcmp");
@ -734,12 +735,33 @@ namespace gcc
tree designator = this->current_expression;
expression->index().accept(this);
tree index = this->current_expression;
tree offset = build2(MINUS_EXPR, elna_word_type_node, this->current_expression, size_one_node);
tree element_type = TREE_TYPE(TREE_TYPE(designator));
location_t location = get_location(&expression->position());
this->current_expression = build4_loc(get_location(&expression->position()),
ARRAY_REF, element_type, designator, index, NULL_TREE, NULL_TREE);
if (is_array_type(TREE_TYPE(designator)))
{
tree element_type = TREE_TYPE(TREE_TYPE(designator));
this->current_expression = build4_loc(location,
ARRAY_REF, element_type, designator, offset, NULL_TREE, NULL_TREE);
}
else if (TREE_TYPE(designator) == elna_string_type_node)
{
tree string_ptr = build3_loc(location, COMPONENT_REF, TREE_TYPE(elna_string_ptr_field_node),
designator, elna_string_ptr_field_node, NULL_TREE);
tree target_pointer = do_pointer_arithmetic(boot::binary_operator::sum, string_ptr, offset);
this->current_expression = build1_loc(location, INDIRECT_REF,
elna_char_type_node, target_pointer);
}
else
{
error_at(location, "indexing is not allowed on type '%s'",
print_type(TREE_TYPE(designator)).c_str());
this->current_expression = error_mark_node;
}
}
void generic_visitor::visit(boot::field_access_expression *expression)

View File

@ -15,18 +15,16 @@ 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/>. */
void
lang_specific_driver (struct cl_decoded_option ** /* in_decoded_options */,
unsigned int * /* in_decoded_options_count */,
int * /*in_added_libraries */)
void lang_specific_driver(struct cl_decoded_option ** /* in_decoded_options */,
unsigned int * /* in_decoded_options_count */,
int * /*in_added_libraries */)
{
}
/* Called before linking. Returns 0 on success and -1 on failure. */
int
lang_specific_pre_link (void)
int lang_specific_pre_link (void)
{
return 0;
return 0;
}
/* Number of extra output files that lang_specific_pre_link may generate. */

View File

@ -45,6 +45,12 @@ namespace gcc
return is_integral_type(type) || type == elna_float_type_node;
}
bool is_array_type(tree type)
{
gcc_assert(TYPE_P(type));
return TREE_CODE(type) == ARRAY_TYPE;
}
bool are_compatible_pointers(tree lhs, tree rhs)
{
tree lhs_type = TREE_TYPE(lhs);
@ -149,7 +155,7 @@ namespace gcc
return fold_build2(POINTER_DIFF_EXPR, ssizetype, left, right);
}
}
return error_mark_node;
gcc_unreachable();
}
tree build_binary_operation(bool condition, boot::binary_expression *expression,

View File

@ -41,10 +41,10 @@ hash_map<nofree_string_hash, tree> *elna_global_decls = nullptr;
/* The resulting tree type. */
union GTY ((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), "
"TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN "
"(&%h.generic)) : NULL"))) lang_tree_node
union GTY ((desc("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
chain_next("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), "
"TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN "
"(&%h.generic)) : NULL"))) lang_tree_node
{
union tree_node GTY ((tag ("0"), desc ("tree_node_structure (&%h)"))) generic;
};