diff options
| author | Eugen Wissner <belka@caraus.de> | 2025-12-02 10:22:06 +0100 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2025-12-02 17:14:18 +0100 |
| commit | 23b6f074c7f560d701e9a1fa5713a965af3a18a3 (patch) | |
| tree | 87549a4eba3da8d8ed6e3fbb2e337e152a8bc96a /gcc/elna-diagnostic.cc | |
| parent | 5f7d83974114c73327ce9fff3635927df050b5e4 (diff) | |
| download | elna-23b6f074c7f560d701e9a1fa5713a965af3a18a3.tar.gz | |
Merge GCC frontend into the branch
Diffstat (limited to 'gcc/elna-diagnostic.cc')
| -rw-r--r-- | gcc/elna-diagnostic.cc | 167 |
1 files changed, 167 insertions, 0 deletions
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 +<http://www.gnu.org/licenses/>. */ + +#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 "<<unknown-type>>"; + } + gcc_unreachable(); + } + + void report_errors(const std::deque<std::unique_ptr<frontend::error>>& 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()); + } + } +} |
