Home | History | Annotate | Line # | Download | only in gcc
diagnostic.h revision 1.11
      1 /* Various declarations for language-independent diagnostics subroutines.
      2    Copyright (C) 2000-2020 Free Software Foundation, Inc.
      3    Contributed by Gabriel Dos Reis <gdr (at) codesourcery.com>
      4 
      5 This file is part of GCC.
      6 
      7 GCC is free software; you can redistribute it and/or modify it under
      8 the terms of the GNU General Public License as published by the Free
      9 Software Foundation; either version 3, or (at your option) any later
     10 version.
     11 
     12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
     14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     15 for more details.
     16 
     17 You should have received a copy of the GNU General Public License
     18 along with GCC; see the file COPYING3.  If not see
     19 <http://www.gnu.org/licenses/>.  */
     20 
     21 #ifndef GCC_DIAGNOSTIC_H
     22 #define GCC_DIAGNOSTIC_H
     23 
     24 #include "pretty-print.h"
     25 #include "diagnostic-core.h"
     26 
     27 /* Enum for overriding the standard output format.  */
     28 
     29 enum diagnostics_output_format
     30 {
     31   /* The default: textual output.  */
     32   DIAGNOSTICS_OUTPUT_FORMAT_TEXT,
     33 
     34   /* JSON-based output.  */
     35   DIAGNOSTICS_OUTPUT_FORMAT_JSON
     36 };
     37 
     38 /* An enum for controlling how diagnostic_paths should be printed.  */
     39 enum diagnostic_path_format
     40 {
     41   /* Don't print diagnostic_paths.  */
     42   DPF_NONE,
     43 
     44   /* Print diagnostic_paths by emitting a separate "note" for every event
     45      in the path.  */
     46   DPF_SEPARATE_EVENTS,
     47 
     48   /* Print diagnostic_paths by consolidating events together where they
     49      are close enough, and printing such runs of events with multiple
     50      calls to diagnostic_show_locus, showing the individual events in
     51      each run via labels in the source.  */
     52   DPF_INLINE_EVENTS
     53 };
     54 
     55 /* A diagnostic is described by the MESSAGE to send, the FILE and LINE of
     56    its context and its KIND (ice, error, warning, note, ...)  See complete
     57    list in diagnostic.def.  */
     58 struct diagnostic_info
     59 {
     60   /* Text to be formatted.  */
     61   text_info message;
     62 
     63   /* The location at which the diagnostic is to be reported.  */
     64   rich_location *richloc;
     65 
     66   /* An optional bundle of metadata associated with the diagnostic
     67      (or NULL).  */
     68   const diagnostic_metadata *metadata;
     69 
     70   /* Auxiliary data for client.  */
     71   void *x_data;
     72   /* The kind of diagnostic it is about.  */
     73   diagnostic_t kind;
     74   /* Which OPT_* directly controls this diagnostic.  */
     75   int option_index;
     76 };
     77 
     78 /* Each time a diagnostic's classification is changed with a pragma,
     79    we record the change and the location of the change in an array of
     80    these structs.  */
     81 struct diagnostic_classification_change_t
     82 {
     83   location_t location;
     84   int option;
     85   diagnostic_t kind;
     86 };
     87 
     88 /*  Forward declarations.  */
     89 typedef void (*diagnostic_starter_fn) (diagnostic_context *,
     90 				       diagnostic_info *);
     91 
     92 typedef void (*diagnostic_start_span_fn) (diagnostic_context *,
     93 					  expanded_location);
     94 
     95 typedef void (*diagnostic_finalizer_fn) (diagnostic_context *,
     96 					 diagnostic_info *,
     97 					 diagnostic_t);
     98 
     99 class edit_context;
    100 namespace json { class value; }
    101 
    102 /* This data structure bundles altogether any information relevant to
    103    the context of a diagnostic message.  */
    104 struct diagnostic_context
    105 {
    106   /* Where most of the diagnostic formatting work is done.  */
    107   pretty_printer *printer;
    108 
    109   /* The number of times we have issued diagnostics.  */
    110   int diagnostic_count[DK_LAST_DIAGNOSTIC_KIND];
    111 
    112   /* True if it has been requested that warnings be treated as errors.  */
    113   bool warning_as_error_requested;
    114 
    115   /* The number of option indexes that can be passed to warning() et
    116      al.  */
    117   int n_opts;
    118 
    119   /* For each option index that can be passed to warning() et al
    120      (OPT_* from options.h when using this code with the core GCC
    121      options), this array may contain a new kind that the diagnostic
    122      should be changed to before reporting, or DK_UNSPECIFIED to leave
    123      it as the reported kind, or DK_IGNORED to not report it at
    124      all.  */
    125   diagnostic_t *classify_diagnostic;
    126 
    127   /* History of all changes to the classifications above.  This list
    128      is stored in location-order, so we can search it, either
    129      binary-wise or end-to-front, to find the most recent
    130      classification for a given diagnostic, given the location of the
    131      diagnostic.  */
    132   diagnostic_classification_change_t *classification_history;
    133 
    134   /* The size of the above array.  */
    135   int n_classification_history;
    136 
    137   /* For pragma push/pop.  */
    138   int *push_list;
    139   int n_push;
    140 
    141   /* True if we should print the source line with a caret indicating
    142      the location.  */
    143   bool show_caret;
    144 
    145   /* Maximum width of the source line printed.  */
    146   int caret_max_width;
    147 
    148   /* Character used for caret diagnostics.  */
    149   char caret_chars[rich_location::STATICALLY_ALLOCATED_RANGES];
    150 
    151   /* True if we should print any CWE identifiers associated with
    152      diagnostics.  */
    153   bool show_cwe;
    154 
    155   /* How should diagnostic_path objects be printed.  */
    156   enum diagnostic_path_format path_format;
    157 
    158   /* True if we should print stack depths when printing diagnostic paths.  */
    159   bool show_path_depths;
    160 
    161   /* True if we should print the command line option which controls
    162      each diagnostic, if known.  */
    163   bool show_option_requested;
    164 
    165   /* True if we should raise a SIGABRT on errors.  */
    166   bool abort_on_error;
    167 
    168   /* True if we should show the column number on diagnostics.  */
    169   bool show_column;
    170 
    171   /* True if pedwarns are errors.  */
    172   bool pedantic_errors;
    173 
    174   /* True if permerrors are warnings.  */
    175   bool permissive;
    176 
    177   /* The index of the option to associate with turning permerrors into
    178      warnings.  */
    179   int opt_permissive;
    180 
    181   /* True if errors are fatal.  */
    182   bool fatal_errors;
    183 
    184   /* True if all warnings should be disabled.  */
    185   bool dc_inhibit_warnings;
    186 
    187   /* True if warnings should be given in system headers.  */
    188   bool dc_warn_system_headers;
    189 
    190   /* Maximum number of errors to report.  */
    191   int max_errors;
    192 
    193   /* This function is called before any message is printed out.  It is
    194      responsible for preparing message prefix and such.  For example, it
    195      might say:
    196      In file included from "/usr/local/include/curses.h:5:
    197                       from "/home/gdr/src/nifty_printer.h:56:
    198                       ...
    199   */
    200   diagnostic_starter_fn begin_diagnostic;
    201 
    202   /* This function is called by diagnostic_show_locus in between
    203      disjoint spans of source code, so that the context can print
    204      something to indicate that a new span of source code has begun.  */
    205   diagnostic_start_span_fn start_span;
    206 
    207   /* This function is called after the diagnostic message is printed.  */
    208   diagnostic_finalizer_fn end_diagnostic;
    209 
    210   /* Client hook to report an internal error.  */
    211   void (*internal_error) (diagnostic_context *, const char *, va_list *);
    212 
    213   /* Client hook to say whether the option controlling a diagnostic is
    214      enabled.  Returns nonzero if enabled, zero if disabled.  */
    215   int (*option_enabled) (int, unsigned, void *);
    216 
    217   /* Client information to pass as second argument to
    218      option_enabled.  */
    219   void *option_state;
    220 
    221   /* Client hook to return the name of an option that controls a
    222      diagnostic.  Returns malloced memory.  The first diagnostic_t
    223      argument is the kind of diagnostic before any reclassification
    224      (of warnings as errors, etc.); the second is the kind after any
    225      reclassification.  May return NULL if no name is to be printed.
    226      May be passed 0 as well as the index of a particular option.  */
    227   char *(*option_name) (diagnostic_context *, int, diagnostic_t, diagnostic_t);
    228 
    229   /* Client hook to return a URL describing the option that controls
    230      a diagnostic.  Returns malloced memory.  May return NULL if no URL
    231      is available.  May be passed 0 as well as the index of a
    232      particular option.  */
    233   char *(*get_option_url) (diagnostic_context *, int);
    234 
    235   void (*print_path) (diagnostic_context *, const diagnostic_path *);
    236   json::value *(*make_json_for_path) (diagnostic_context *, const diagnostic_path *);
    237 
    238   /* Auxiliary data for client.  */
    239   void *x_data;
    240 
    241   /* Used to detect that the last caret was printed at the same location.  */
    242   location_t last_location;
    243 
    244   /* Used to detect when the input file stack has changed since last
    245      described.  */
    246   const line_map_ordinary *last_module;
    247 
    248   int lock;
    249 
    250   /* A copy of lang_hooks.option_lang_mask ().  */
    251   unsigned lang_mask;
    252 
    253   bool inhibit_notes_p;
    254 
    255   /* When printing source code, should the characters at carets and ranges
    256      be colorized? (assuming colorization is on at all).
    257      This should be true for frontends that generate range information
    258      (so that the ranges of code are colorized),
    259      and false for frontends that merely specify points within the
    260      source code (to avoid e.g. colorizing just the first character in
    261      a token, which would look strange).  */
    262   bool colorize_source_p;
    263 
    264   /* When printing source code, should labelled ranges be printed?  */
    265   bool show_labels_p;
    266 
    267   /* When printing source code, should there be a left-hand margin
    268      showing line numbers?  */
    269   bool show_line_numbers_p;
    270 
    271   /* If printing source code, what should the minimum width of the margin
    272      be?  Line numbers will be right-aligned, and padded to this width.  */
    273   int min_margin_width;
    274 
    275   /* Usable by plugins; if true, print a debugging ruler above the
    276      source output.  */
    277   bool show_ruler_p;
    278 
    279   /* If true, print fixits in machine-parseable form after the
    280      rest of the diagnostic.  */
    281   bool parseable_fixits_p;
    282 
    283   /* If non-NULL, an edit_context to which fix-it hints should be
    284      applied, for generating patches.  */
    285   edit_context *edit_context_ptr;
    286 
    287   /* How many diagnostic_group instances are currently alive.  */
    288   int diagnostic_group_nesting_depth;
    289 
    290   /* How many diagnostics have been emitted since the bottommost
    291      diagnostic_group was pushed.  */
    292   int diagnostic_group_emission_count;
    293 
    294   /* Optional callbacks for handling diagnostic groups.  */
    295 
    296   /* If non-NULL, this will be called immediately before the first
    297      time a diagnostic is emitted within a stack of groups.  */
    298   void (*begin_group_cb) (diagnostic_context * context);
    299 
    300   /* If non-NULL, this will be called when a stack of groups is
    301      popped if any diagnostics were emitted within that group.  */
    302   void (*end_group_cb) (diagnostic_context * context);
    303 
    304   /* Callback for final cleanup.  */
    305   void (*final_cb) (diagnostic_context *context);
    306 };
    307 
    308 static inline void
    309 diagnostic_inhibit_notes (diagnostic_context * context)
    310 {
    311   context->inhibit_notes_p = true;
    312 }
    313 
    314 
    315 /* Client supplied function to announce a diagnostic.  */
    316 #define diagnostic_starter(DC) (DC)->begin_diagnostic
    317 
    318 /* Client supplied function called after a diagnostic message is
    319    displayed.  */
    320 #define diagnostic_finalizer(DC) (DC)->end_diagnostic
    321 
    322 /* Extension hooks for client.  */
    323 #define diagnostic_context_auxiliary_data(DC) (DC)->x_data
    324 #define diagnostic_info_auxiliary_data(DI) (DI)->x_data
    325 
    326 /* Same as pp_format_decoder.  Works on 'diagnostic_context *'.  */
    327 #define diagnostic_format_decoder(DC) ((DC)->printer->format_decoder)
    328 
    329 /* Same as output_prefixing_rule.  Works on 'diagnostic_context *'.  */
    330 #define diagnostic_prefixing_rule(DC) ((DC)->printer->wrapping.rule)
    331 
    332 /* Raise SIGABRT on any diagnostic of severity DK_ERROR or higher.  */
    333 #define diagnostic_abort_on_error(DC) \
    334   (DC)->abort_on_error = true
    335 
    336 /* This diagnostic_context is used by front-ends that directly output
    337    diagnostic messages without going through `error', `warning',
    338    and similar functions.  */
    339 extern diagnostic_context *global_dc;
    340 
    341 /* Returns whether the diagnostic framework has been intialized already and is
    342    ready for use.  */
    343 #define diagnostic_ready_p() (global_dc->printer != NULL)
    344 
    345 /* The total count of a KIND of diagnostics emitted so far.  */
    346 #define diagnostic_kind_count(DC, DK) (DC)->diagnostic_count[(int) (DK)]
    347 
    348 /* The number of errors that have been issued so far.  Ideally, these
    349    would take a diagnostic_context as an argument.  */
    350 #define errorcount diagnostic_kind_count (global_dc, DK_ERROR)
    351 /* Similarly, but for warnings.  */
    352 #define warningcount diagnostic_kind_count (global_dc, DK_WARNING)
    353 /* Similarly, but for warnings promoted to errors.  */
    354 #define werrorcount diagnostic_kind_count (global_dc, DK_WERROR)
    355 /* Similarly, but for sorrys.  */
    356 #define sorrycount diagnostic_kind_count (global_dc, DK_SORRY)
    357 
    358 /* Returns nonzero if warnings should be emitted.  */
    359 #define diagnostic_report_warnings_p(DC, LOC)				\
    360   (!(DC)->dc_inhibit_warnings						\
    361    && !(in_system_header_at (LOC) && !(DC)->dc_warn_system_headers))
    362 
    363 /* Override the option index to be used for reporting a
    364    diagnostic.  */
    365 
    366 static inline void
    367 diagnostic_override_option_index (diagnostic_info *info, int optidx)
    368 {
    369   info->option_index = optidx;
    370 }
    371 
    372 /* Diagnostic related functions.  */
    373 extern void diagnostic_initialize (diagnostic_context *, int);
    374 extern void diagnostic_color_init (diagnostic_context *, int value = -1);
    375 extern void diagnostic_urls_init (diagnostic_context *, int value = -1);
    376 extern void diagnostic_finish (diagnostic_context *);
    377 extern void diagnostic_report_current_module (diagnostic_context *, location_t);
    378 extern void diagnostic_show_locus (diagnostic_context *,
    379 				   rich_location *richloc,
    380 				   diagnostic_t diagnostic_kind);
    381 extern void diagnostic_show_any_path (diagnostic_context *, diagnostic_info *);
    382 
    383 /* Force diagnostics controlled by OPTIDX to be kind KIND.  */
    384 extern diagnostic_t diagnostic_classify_diagnostic (diagnostic_context *,
    385 						    int /* optidx */,
    386 						    diagnostic_t /* kind */,
    387 						    location_t);
    388 extern void diagnostic_push_diagnostics (diagnostic_context *, location_t);
    389 extern void diagnostic_pop_diagnostics (diagnostic_context *, location_t);
    390 extern bool diagnostic_report_diagnostic (diagnostic_context *,
    391 					  diagnostic_info *);
    392 #ifdef ATTRIBUTE_GCC_DIAG
    393 extern void diagnostic_set_info (diagnostic_info *, const char *, va_list *,
    394 				 rich_location *, diagnostic_t) ATTRIBUTE_GCC_DIAG(2,0);
    395 extern void diagnostic_set_info_translated (diagnostic_info *, const char *,
    396 					    va_list *, rich_location *,
    397 					    diagnostic_t)
    398      ATTRIBUTE_GCC_DIAG(2,0);
    399 extern void diagnostic_append_note (diagnostic_context *, location_t,
    400                                     const char *, ...) ATTRIBUTE_GCC_DIAG(3,4);
    401 #endif
    402 extern char *diagnostic_build_prefix (diagnostic_context *, const diagnostic_info *);
    403 void default_diagnostic_starter (diagnostic_context *, diagnostic_info *);
    404 void default_diagnostic_start_span_fn (diagnostic_context *,
    405 				       expanded_location);
    406 void default_diagnostic_finalizer (diagnostic_context *, diagnostic_info *,
    407 				   diagnostic_t);
    408 void diagnostic_set_caret_max_width (diagnostic_context *context, int value);
    409 void diagnostic_action_after_output (diagnostic_context *, diagnostic_t);
    410 void diagnostic_check_max_errors (diagnostic_context *, bool flush = false);
    411 
    412 void diagnostic_file_cache_fini (void);
    413 
    414 int get_terminal_width (void);
    415 
    416 /* Return the location associated to this diagnostic. Parameter WHICH
    417    specifies which location. By default, expand the first one.  */
    418 
    419 static inline location_t
    420 diagnostic_location (const diagnostic_info * diagnostic, int which = 0)
    421 {
    422   return diagnostic->message.get_location (which);
    423 }
    424 
    425 /* Return the number of locations to be printed in DIAGNOSTIC.  */
    426 
    427 static inline unsigned int
    428 diagnostic_num_locations (const diagnostic_info * diagnostic)
    429 {
    430   return diagnostic->message.m_richloc->get_num_locations ();
    431 }
    432 
    433 /* Expand the location of this diagnostic. Use this function for
    434    consistency.  Parameter WHICH specifies which location. By default,
    435    expand the first one.  */
    436 
    437 static inline expanded_location
    438 diagnostic_expand_location (const diagnostic_info * diagnostic, int which = 0)
    439 {
    440   return diagnostic->richloc->get_expanded_location (which);
    441 }
    442 
    443 /* This is somehow the right-side margin of a caret line, that is, we
    444    print at least these many characters after the position pointed at
    445    by the caret.  */
    446 const int CARET_LINE_MARGIN = 10;
    447 
    448 /* Return true if the two locations can be represented within the same
    449    caret line.  This is used to build a prefix and also to determine
    450    whether to print one or two caret lines.  */
    451 
    452 static inline bool
    453 diagnostic_same_line (const diagnostic_context *context,
    454 		       expanded_location s1, expanded_location s2)
    455 {
    456   return s2.column && s1.line == s2.line
    457     && context->caret_max_width - CARET_LINE_MARGIN > abs (s1.column - s2.column);
    458 }
    459 
    460 extern const char *diagnostic_get_color_for_kind (diagnostic_t kind);
    461 
    462 /* Pure text formatting support functions.  */
    463 extern char *file_name_as_prefix (diagnostic_context *, const char *);
    464 
    465 extern char *build_message_string (const char *, ...) ATTRIBUTE_PRINTF_1;
    466 
    467 extern void diagnostic_output_format_init (diagnostic_context *,
    468 					   enum diagnostics_output_format);
    469 
    470 /* Compute the number of digits in the decimal representation of an integer.  */
    471 extern int num_digits (int);
    472 
    473 extern json::value *json_from_expanded_location (location_t loc);
    474 
    475 #endif /* ! GCC_DIAGNOSTIC_H */
    476