From 5959fbb5524bbeb05a96eb15aba59e961a3efcb7 Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Sun, 15 Feb 2026 04:10:38 +0100 Subject: Initial commit --- gcc/elna-diagnostic.cc | 167 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 gcc/elna-diagnostic.cc (limited to 'gcc/elna-diagnostic.cc') diff --git a/gcc/elna-diagnostic.cc b/gcc/elna-diagnostic.cc new file mode 100644 index 0000000..162d6cb --- /dev/null +++ b/gcc/elna-diagnostic.cc @@ -0,0 +1,167 @@ +/* Elna frontend specific diagnostic routines. + 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 "elna/gcc/elna-diagnostic.h" +#include "elna/gcc/elna-tree.h" +#include "elna/gcc/elna1.h" + +namespace elna::gcc +{ + linemap_guard::linemap_guard(const char *filename) + { + linemap_add(line_table, LC_ENTER, 0, filename, 1); + } + + linemap_guard::~linemap_guard() + { + linemap_add(line_table, LC_LEAVE, 0, NULL, 0); + } + + location_t get_location(const frontend::position *position) + { + linemap_line_start(line_table, position->line, 0); + + return linemap_position_for_column(line_table, position->column); + } + + std::string print_aggregate_name(tree type, const std::string& kind_name) + { + if (TYPE_IDENTIFIER(type) == NULL_TREE) + { + return kind_name; + } + else + { + return std::string(IDENTIFIER_POINTER(TYPE_IDENTIFIER(type))); + } + } + + std::string print_type(tree type) + { + gcc_assert(TYPE_P(type)); + + tree unqualified_type = get_qualified_type(type, TYPE_UNQUALIFIED); + tree_code code = TREE_CODE(type); + + if (unqualified_type == elna_int_type_node) + { + return "Int"; + } + else if (unqualified_type == elna_word_type_node) + { + return "Word"; + } + else if (unqualified_type == elna_bool_type_node) + { + return "Bool"; + } + else if (unqualified_type == elna_pointer_type_node) + { + return "Pointer"; + } + else if (unqualified_type == elna_float_type_node) + { + return "Float"; + } + else if (unqualified_type == elna_char_type_node) + { + return "Char"; + } + else if (unqualified_type == elna_string_type_node) + { + return "String"; + } + else if (is_void_type(unqualified_type)) // For procedures without a return type. + { + return "()"; + } + else if (POINTER_TYPE_P(unqualified_type)) + { + tree pointer_target_type = TREE_TYPE(type); + + if (TREE_CODE(pointer_target_type) == FUNCTION_TYPE) + { + return print_type(pointer_target_type); + } + else + { + return std::string("^" + print_type(pointer_target_type)); + } + } + else if (code == FUNCTION_TYPE) + { + std::string output = "proc("; + tree parameter_type = TYPE_ARG_TYPES(type); + while (TREE_VALUE(parameter_type) != void_type_node) + { + output += print_type(TREE_VALUE(parameter_type)); + parameter_type = TREE_CHAIN(parameter_type); + if (TREE_VALUE(parameter_type) == void_type_node) + { + break; + } + else + { + output += ", "; + } + } + output += ')'; + tree return_type = TREE_TYPE(type); + + if (!is_void_type(return_type)) + { + output += " -> " + print_type(return_type); + } + return output; + } + else if (code == ARRAY_TYPE) + { + return "array"; + } + else if (code == RECORD_TYPE) + { + return print_aggregate_name(unqualified_type, "record"); + } + else if (code == UNION_TYPE) + { + return print_aggregate_name(unqualified_type, "union"); + } + else if (code == ENUMERAL_TYPE) + { + return print_aggregate_name(unqualified_type, "enumeration"); + } + else + { + return "<>"; + } + gcc_unreachable(); + } + + void report_errors(const std::deque>& errors) + { + for (const auto& error : errors) + { + location_t gcc_location{ UNKNOWN_LOCATION }; + + if (error->position.line != 0 || error->position.column != 0) + { + gcc_location = elna::gcc::get_location(&error->position); + } + error_at(gcc_location, error->what().c_str()); + } + } +} -- cgit v1.2.3