/* Language-dependent hooks for Elna. Copyright (C) 2025 Free Software Foundation, Inc. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see . */ #include "config.h" #include "system.h" #include "coretypes.h" #include "target.h" #include "function.h" #include "tree.h" #include "elna/gcc/elna1.h" #include "diagnostic.h" #include "opts.h" #include "debug.h" #include "langhooks.h" #include "langhooks-def.h" #include #include "elna/boot/driver.h" #include "elna/gcc/elna-tree.h" #include "elna/gcc/elna-generic.h" #include "elna/gcc/elna-diagnostic.h" #include "elna/gcc/elna-builtins.h" #include "parser.hh" tree elna_global_trees[ELNA_TI_MAX]; hash_map *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 tree_node GTY ((tag ("0"), desc ("tree_node_structure (&%h)"))) generic; }; /* Language hooks. */ static bool elna_langhook_init(void) { build_common_tree_nodes(false); elna::gcc::init_ttree(); elna_global_decls = hash_map::create_ggc(default_hash_map_size); build_common_builtin_nodes(); return true; } static void elna_parse_file(const char *filename) { std::ifstream file{ filename, std::ios::in }; if (!file) { fatal_error(UNKNOWN_LOCATION, "cannot open filename %s: %m", filename); } elna::boot::driver driver{ filename }; elna::boot::lexer lexer(file); yy::parser parser(lexer, driver); linemap_add(line_table, LC_ENTER, 0, filename, 1); if (parser()) { for (const auto& error : driver.errors()) { auto gcc_location = elna::gcc::get_location(&error->position); error_at(gcc_location, error->what().c_str()); } } else { elna::gcc::generic_visitor generic_visitor{ std::make_shared>() }; generic_visitor.visit(driver.tree.get()); } linemap_add(line_table, LC_LEAVE, 0, NULL, 0); } static void elna_langhook_parse_file(void) { for (unsigned int i = 0; i < num_in_fnames; i++) { elna_parse_file(in_fnames[i]); } } static tree elna_langhook_type_for_mode(enum machine_mode mode, int unsignedp) { if (mode == TYPE_MODE(float_type_node)) { return float_type_node; } else if (mode == TYPE_MODE(double_type_node)) { return double_type_node; } if (mode == TYPE_MODE(intQI_type_node)) { return unsignedp ? unsigned_intQI_type_node : intQI_type_node; } else if (mode == TYPE_MODE(intHI_type_node)) { return unsignedp ? unsigned_intHI_type_node : intHI_type_node; } else if (mode == TYPE_MODE(intSI_type_node)) { return unsignedp ? unsigned_intSI_type_node : intSI_type_node; } else if (mode == TYPE_MODE(intDI_type_node)) { return unsignedp ? unsigned_intDI_type_node : intDI_type_node; } else if (mode == TYPE_MODE(intTI_type_node)) { return unsignedp ? unsigned_intTI_type_node : intTI_type_node; } else if (mode == TYPE_MODE(integer_type_node)) { return unsignedp ? unsigned_type_node : integer_type_node; } else if (mode == TYPE_MODE(long_integer_type_node)) { return unsignedp ? long_unsigned_type_node : long_integer_type_node; } else if (mode == TYPE_MODE(long_long_integer_type_node)) { return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node; } if (COMPLEX_MODE_P(mode)) { if (mode == TYPE_MODE(complex_float_type_node)) { return complex_float_type_node; } if (mode == TYPE_MODE(complex_double_type_node)) { return complex_double_type_node; } if (mode == TYPE_MODE(complex_long_double_type_node)) { return complex_long_double_type_node; } if (mode == TYPE_MODE(complex_integer_type_node) && !unsignedp) { return complex_integer_type_node; } } /* gcc_unreachable */ return nullptr; } static bool global_bindings_p(void) { return current_function_decl == NULL_TREE; } static tree pushdecl(tree decl) { return decl; } static tree elna_langhook_builtin_function(tree decl) { elna_global_decls->put(IDENTIFIER_POINTER(DECL_NAME(decl)), decl); return decl; } /* Creates an expression whose value is that of EXPR, converted to type TYPE. This function implements all reasonable scalar conversions. */ tree convert(tree type, tree expr) { if (error_operand_p(type) || error_operand_p(expr)) { return error_mark_node; } if (TREE_TYPE(expr) == type) { return expr; } return error_mark_node; } #undef LANG_HOOKS_NAME #define LANG_HOOKS_NAME "GNU Elna" #undef LANG_HOOKS_INIT #define LANG_HOOKS_INIT elna_langhook_init #undef LANG_HOOKS_PARSE_FILE #define LANG_HOOKS_PARSE_FILE elna_langhook_parse_file #undef LANG_HOOKS_TYPE_FOR_MODE #define LANG_HOOKS_TYPE_FOR_MODE elna_langhook_type_for_mode #undef LANG_HOOKS_GETDECLS #define LANG_HOOKS_GETDECLS hook_tree_void_null #undef LANG_HOOKS_BUILTIN_FUNCTION #define LANG_HOOKS_BUILTIN_FUNCTION elna_langhook_builtin_function #undef LANG_HOOKS_IDENTIFIER_SIZE #define LANG_HOOKS_IDENTIFIER_SIZE sizeof(struct tree_identifier) struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; #include "gt-elna-elna1.h" #include "gtype-elna.h"