summaryrefslogtreecommitdiff
path: root/gcc/elna1.cc
diff options
context:
space:
mode:
authorEugen Wissner <belka@caraus.de>2025-12-02 10:22:06 +0100
committerEugen Wissner <belka@caraus.de>2025-12-02 17:14:18 +0100
commit23b6f074c7f560d701e9a1fa5713a965af3a18a3 (patch)
tree87549a4eba3da8d8ed6e3fbb2e337e152a8bc96a /gcc/elna1.cc
parent5f7d83974114c73327ce9fff3635927df050b5e4 (diff)
downloadelna-23b6f074c7f560d701e9a1fa5713a965af3a18a3.tar.gz
Merge GCC frontend into the branch
Diffstat (limited to 'gcc/elna1.cc')
-rw-r--r--gcc/elna1.cc256
1 files changed, 256 insertions, 0 deletions
diff --git a/gcc/elna1.cc b/gcc/elna1.cc
new file mode 100644
index 0000000..448a24c
--- /dev/null
+++ b/gcc/elna1.cc
@@ -0,0 +1,256 @@
+/* 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
+<http://www.gnu.org/licenses/>. */
+
+#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 <fstream>
+#include "elna/frontend/dependency.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"
+
+tree elna_global_trees[ELNA_TI_MAX];
+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 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<nofree_string_hash, tree>::create_ggc(default_hash_map_size);
+
+ build_common_builtin_nodes();
+
+ return true;
+}
+
+using dependency_state = elna::frontend::dependency_state<std::shared_ptr<elna::gcc::symbol_table>>;
+
+static elna::frontend::dependency elna_parse_file(dependency_state& state, const char *filename)
+{
+ std::ifstream entry_point{ filename, std::ios::in };
+
+ if (!entry_point)
+ {
+ fatal_error(UNKNOWN_LOCATION, "Cannot open filename %s: %m", filename);
+ }
+ elna::gcc::linemap_guard{ filename };
+ elna::frontend::dependency outcome = elna::frontend::read_source(entry_point, filename);
+
+ if (outcome.has_errors())
+ {
+ elna::gcc::report_errors(outcome.errors());
+ return outcome;
+ }
+ elna::frontend::symbol_bag outcome_bag = elna::frontend::symbol_bag{ std::move(outcome.unresolved), state.globals };
+
+ for (const auto& sub_tree : outcome.tree->imports)
+ {
+ std::filesystem::path sub_path = "source" / elna::frontend::build_path(sub_tree->segments);
+ std::unordered_map<std::filesystem::path, elna::frontend::symbol_bag>::const_iterator cached_import =
+ state.cache.find(sub_path);
+
+ if (cached_import == state.cache.end())
+ {
+ elna_parse_file(state, sub_path.c_str());
+ cached_import = state.cache.find(sub_path);
+ }
+ outcome_bag.add_import(cached_import->second);
+ }
+ outcome.errors() = analyze_semantics(filename, outcome.tree, outcome_bag);
+
+ if (outcome.has_errors())
+ {
+ elna::gcc::report_errors(outcome.errors());
+ return outcome;
+ }
+ state.cache.insert({ filename, outcome_bag });
+ elna::gcc::rewrite_symbol_table(outcome_bag.leave(), state.custom);
+
+ return outcome;
+}
+
+static void elna_langhook_parse_file(void)
+{
+ dependency_state state{ elna::gcc::builtin_symbol_table() };
+
+ for (unsigned int i = 0; i < num_in_fnames; i++)
+ {
+ elna::frontend::dependency outcome = elna_parse_file(state, in_fnames[i]);
+
+ linemap_add(line_table, LC_ENTER, 0, in_fnames[i], 1);
+ elna::gcc::generic_visitor generic_visitor{ state.custom, state.cache.find(in_fnames[i])->second };
+ outcome.tree->accept(&generic_visitor);
+ linemap_add(line_table, LC_LEAVE, 0, NULL, 0);
+ }
+}
+
+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;
+}
+
+static unsigned int elna_langhook_option_lang_mask(void)
+{
+ return CL_Elna;
+}
+
+/* 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)
+
+#undef LANG_HOOKS_OPTION_LANG_MASK
+#define LANG_HOOKS_OPTION_LANG_MASK elna_langhook_option_lang_mask
+
+struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
+
+#include "gt-elna-elna1.h"
+#include "gtype-elna.h"