// Copyright (C) 2020-2022 Free Software Foundation, Inc. // This file is part of GCC. // 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 // . // rust-diagnostics.h -- interface to diagnostic reporting -*- C++ -*- #ifndef RUST_DIAGNOSTICS_H #define RUST_DIAGNOSTICS_H #include "rust-linemap.h" #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) #define RUST_ATTRIBUTE_GCC_DIAG(m, n) \ __attribute__ ((__format__ (__gcc_tdiag__, m, n))) \ __attribute__ ((__nonnull__ (m))) #else #define RUST_ATTRIBUTE_GCC_DIAG(m, n) #endif // These declarations define the interface through which the frontend // reports errors and warnings. These functions accept printf-like // format specifiers (e.g. %d, %f, %s, etc), with the following additional // extensions: // // 1. 'q' qualifier may be applied to a specifier to add quoting, e.g. // %qd produces a quoted decimal output, %qs a quoted string output. // [This extension is supported only with single-character format // specifiers]. // // 2. %m specifier outputs value of "strerror(errno)" at time of call. // // 3. %< outputs an opening quote, %> a closing quote. // // All other format specifiers are as defined by 'sprintf'. The final resulting // message is then sent to the back end via rust_be_error_at/rust_be_warning_at. // clang-format off // simple location extern void rust_internal_error_at (const Location, const char *fmt, ...) RUST_ATTRIBUTE_GCC_DIAG (2, 3) RUST_ATTRIBUTE_NORETURN; extern void rust_error_at (const Location, const char *fmt, ...) RUST_ATTRIBUTE_GCC_DIAG (2, 3); extern void rust_warning_at (const Location, int opt, const char *fmt, ...) RUST_ATTRIBUTE_GCC_DIAG (3, 4); extern void rust_fatal_error (const Location, const char *fmt, ...) RUST_ATTRIBUTE_GCC_DIAG (2, 3) RUST_ATTRIBUTE_NORETURN; extern void rust_inform (const Location, const char *fmt, ...) RUST_ATTRIBUTE_GCC_DIAG (2, 3); // rich locations extern void rust_error_at (const RichLocation &, const char *fmt, ...) RUST_ATTRIBUTE_GCC_DIAG (2, 3); // clang-format on // These interfaces provide a way for the front end to ask for // the open/close quote characters it should use when formatting // diagnostics (warnings, errors). extern const char * rust_open_quote (); extern const char * rust_close_quote (); // These interfaces are used by utilities above to pass warnings and // errors (once format specifiers have been expanded) to the back end, // and to determine quoting style. Avoid calling these routines directly; // instead use the equivalent routines above. The back end is required to // implement these routines. // clang-format off extern void rust_be_internal_error_at (const Location, const std::string &errmsg) RUST_ATTRIBUTE_NORETURN; extern void rust_be_error_at (const Location, const std::string &errmsg); extern void rust_be_error_at (const RichLocation &, const std::string &errmsg); extern void rust_be_warning_at (const Location, int opt, const std::string &warningmsg); extern void rust_be_fatal_error (const Location, const std::string &errmsg) RUST_ATTRIBUTE_NORETURN; extern void rust_be_inform (const Location, const std::string &infomsg); extern void rust_be_get_quotechars (const char **open_quote, const char **close_quote); extern bool rust_be_debug_p (void); // clang-format on namespace Rust { /* A structure used to represent an error. Useful for enabling * errors to be ignored, e.g. if backtracking. */ struct Error { Location locus; std::string message; // TODO: store more stuff? e.g. node id? Error (Location locus, std::string message) : locus (locus), message (std::move (message)) { message.shrink_to_fit (); } // TODO: the attribute part might be incorrect Error (Location locus, const char *fmt, ...) /*RUST_ATTRIBUTE_GCC_DIAG (2, 3)*/ RUST_ATTRIBUTE_GCC_DIAG (3, 4); // Irreversibly emits the error as an error. void emit_error () const { rust_error_at (locus, "%s", message.c_str ()); } // Irreversibly emits the error as a fatal error. void emit_fatal_error () const { rust_fatal_error (locus, "%s", message.c_str ()); } }; } // namespace Rust // rust_debug uses normal printf formatting, not GCC diagnostic formatting. #define rust_debug(...) rust_debug_loc (Location (), __VA_ARGS__) // rust_sorry_at wraps GCC diagnostic "sorry_at" to accept "Location" instead of // "location_t" #define rust_sorry_at(location, ...) \ sorry_at (location.gcc_location (), __VA_ARGS__) void rust_debug_loc (const Location location, const char *fmt, ...) ATTRIBUTE_PRINTF_2; #endif // !defined(RUST_DIAGNOSTICS_H)