(root)/
gcc-13.2.0/
gcc/
rust/
rust-diagnostics.h
       1  // Copyright (C) 2020-2023 Free Software Foundation, Inc.
       2  
       3  // This file is part of GCC.
       4  
       5  // GCC is free software; you can redistribute it and/or modify it under
       6  // the terms of the GNU General Public License as published by the Free
       7  // Software Foundation; either version 3, or (at your option) any later
       8  // version.
       9  
      10  // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      11  // WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12  // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      13  // for more details.
      14  
      15  // You should have received a copy of the GNU General Public License
      16  // along with GCC; see the file COPYING3.  If not see
      17  // <http://www.gnu.org/licenses/>.
      18  
      19  // rust-diagnostics.h -- interface to diagnostic reporting   -*- C++ -*-
      20  
      21  #ifndef RUST_DIAGNOSTICS_H
      22  #define RUST_DIAGNOSTICS_H
      23  
      24  #include "rust-linemap.h"
      25  
      26  #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
      27  #define RUST_ATTRIBUTE_GCC_DIAG(m, n)                                          \
      28    __attribute__ ((__format__ (__gcc_tdiag__, m, n)))                           \
      29      __attribute__ ((__nonnull__ (m)))
      30  #else
      31  #define RUST_ATTRIBUTE_GCC_DIAG(m, n)
      32  #endif
      33  
      34  // These declarations define the interface through which the frontend
      35  // reports errors and warnings. These functions accept printf-like
      36  // format specifiers (e.g. %d, %f, %s, etc), with the following additional
      37  // extensions:
      38  //
      39  //  1.  'q' qualifier may be applied to a specifier to add quoting, e.g.
      40  //      %qd produces a quoted decimal output, %qs a quoted string output.
      41  //      [This extension is supported only with single-character format
      42  //      specifiers].
      43  //
      44  //  2.  %m specifier outputs value of "strerror(errno)" at time of call.
      45  //
      46  //  3.  %< outputs an opening quote, %> a closing quote.
      47  //
      48  // All other format specifiers are as defined by 'sprintf'. The final resulting
      49  // message is then sent to the back end via rust_be_error_at/rust_be_warning_at.
      50  
      51  // clang-format off
      52  // simple location
      53  extern void
      54  rust_internal_error_at (const Location, const char *fmt, ...)
      55    RUST_ATTRIBUTE_GCC_DIAG (2, 3)
      56    RUST_ATTRIBUTE_NORETURN;
      57  extern void
      58  rust_error_at (const Location, const char *fmt, ...)
      59    RUST_ATTRIBUTE_GCC_DIAG (2, 3);
      60  extern void
      61  rust_warning_at (const Location, int opt, const char *fmt, ...)
      62    RUST_ATTRIBUTE_GCC_DIAG (3, 4);
      63  extern void
      64  rust_fatal_error (const Location, const char *fmt, ...)
      65    RUST_ATTRIBUTE_GCC_DIAG (2, 3)
      66    RUST_ATTRIBUTE_NORETURN;
      67  extern void
      68  rust_inform (const Location, const char *fmt, ...)
      69    RUST_ATTRIBUTE_GCC_DIAG (2, 3);
      70  
      71  // rich locations
      72  extern void
      73  rust_error_at (const RichLocation &, const char *fmt, ...)
      74    RUST_ATTRIBUTE_GCC_DIAG (2, 3);
      75  // clang-format on
      76  
      77  // These interfaces provide a way for the front end to ask for
      78  // the open/close quote characters it should use when formatting
      79  // diagnostics (warnings, errors).
      80  extern const char *
      81  rust_open_quote ();
      82  extern const char *
      83  rust_close_quote ();
      84  
      85  // These interfaces are used by utilities above to pass warnings and
      86  // errors (once format specifiers have been expanded) to the back end,
      87  // and to determine quoting style. Avoid calling these routines directly;
      88  // instead use the equivalent routines above. The back end is required to
      89  // implement these routines.
      90  
      91  // clang-format off
      92  extern void
      93  rust_be_internal_error_at (const Location, const std::string &errmsg)
      94    RUST_ATTRIBUTE_NORETURN;
      95  extern void
      96  rust_be_error_at (const Location, const std::string &errmsg);
      97  extern void
      98  rust_be_error_at (const RichLocation &, const std::string &errmsg);
      99  extern void
     100  rust_be_warning_at (const Location, int opt, const std::string &warningmsg);
     101  extern void
     102  rust_be_fatal_error (const Location, const std::string &errmsg)
     103    RUST_ATTRIBUTE_NORETURN;
     104  extern void
     105  rust_be_inform (const Location, const std::string &infomsg);
     106  extern void
     107  rust_be_get_quotechars (const char **open_quote, const char **close_quote);
     108  extern bool
     109  rust_be_debug_p (void);
     110  // clang-format on
     111  
     112  namespace Rust {
     113  /* A structure used to represent an error. Useful for enabling
     114   * errors to be ignored, e.g. if backtracking. */
     115  struct Error
     116  {
     117    enum class Kind
     118    {
     119      Hint,
     120      Err,
     121      FatalErr,
     122    };
     123  
     124    Kind kind;
     125    Location locus;
     126    std::string message;
     127    // TODO: store more stuff? e.g. node id?
     128  
     129    Error (Kind kind, Location locus, std::string message)
     130      : kind (kind), locus (locus), message (std::move (message))
     131    {
     132      message.shrink_to_fit ();
     133    }
     134  
     135    Error (Location locus, std::string message)
     136    {
     137      Error (Kind::Err, locus, std::move (message));
     138    }
     139  
     140    static Error Hint (Location locus, std::string message)
     141    {
     142      return Error (Kind::Hint, locus, std::move (message));
     143    }
     144  
     145    static Error Fatal (Location locus, std::string message)
     146    {
     147      return Error (Kind::FatalErr, locus, std::move (message));
     148    }
     149  
     150    // TODO: the attribute part might be incorrect
     151    Error (Location locus, const char *fmt,
     152  	 ...) /*RUST_ATTRIBUTE_GCC_DIAG (2, 3)*/ RUST_ATTRIBUTE_GCC_DIAG (3, 4);
     153  
     154    /**
     155     * printf-like overload of Error::Hint
     156     */
     157    static Error Hint (Location locus, const char *fmt, ...)
     158      RUST_ATTRIBUTE_GCC_DIAG (2, 3);
     159  
     160    /**
     161     * printf-like overload of Error::Fatal
     162     */
     163    static Error Fatal (Location locus, const char *fmt, ...)
     164      RUST_ATTRIBUTE_GCC_DIAG (2, 3);
     165  
     166    void emit () const
     167    {
     168      switch (kind)
     169        {
     170        case Kind::Hint:
     171  	rust_inform (locus, "%s", message.c_str ());
     172  	break;
     173        case Kind::Err:
     174  	rust_error_at (locus, "%s", message.c_str ());
     175  	break;
     176        case Kind::FatalErr:
     177  	rust_fatal_error (locus, "%s", message.c_str ());
     178  	break;
     179        }
     180    }
     181  };
     182  } // namespace Rust
     183  
     184  // rust_debug uses normal printf formatting, not GCC diagnostic formatting.
     185  #define rust_debug(...) rust_debug_loc (Location (), __VA_ARGS__)
     186  
     187  // rust_sorry_at wraps GCC diagnostic "sorry_at" to accept "Location" instead of
     188  // "location_t"
     189  #define rust_sorry_at(location, ...)                                           \
     190    sorry_at (location.gcc_location (), __VA_ARGS__)
     191  
     192  void
     193  rust_debug_loc (const Location location, const char *fmt,
     194  		...) ATTRIBUTE_PRINTF_2;
     195  
     196  #endif // !defined(RUST_DIAGNOSTICS_H)