LCOV - code coverage report
Current view: top level - gcc - diagnostic-format-text.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 87.6 % 340 298
Test Date: 2024-12-21 13:15:12 Functions: 84.8 % 33 28
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Classic text-based output of diagnostics.
       2                 :             :    Copyright (C) 1999-2024 Free Software Foundation, Inc.
       3                 :             : 
       4                 :             : This file is part of GCC.
       5                 :             : 
       6                 :             : GCC is free software; you can redistribute it and/or modify it under
       7                 :             : the terms of the GNU General Public License as published by the Free
       8                 :             : Software Foundation; either version 3, or (at your option) any later
       9                 :             : version.
      10                 :             : 
      11                 :             : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12                 :             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13                 :             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14                 :             : for more details.
      15                 :             : 
      16                 :             : You should have received a copy of the GNU General Public License
      17                 :             : along with GCC; see the file COPYING3.  If not see
      18                 :             : <http://www.gnu.org/licenses/>.  */
      19                 :             : 
      20                 :             : 
      21                 :             : #include "config.h"
      22                 :             : #define INCLUDE_VECTOR
      23                 :             : #include "system.h"
      24                 :             : #include "coretypes.h"
      25                 :             : #include "version.h"
      26                 :             : #include "intl.h"
      27                 :             : #include "diagnostic.h"
      28                 :             : #include "diagnostic-color.h"
      29                 :             : #include "diagnostic-url.h"
      30                 :             : #include "diagnostic-metadata.h"
      31                 :             : #include "diagnostic-path.h"
      32                 :             : #include "diagnostic-client-data-hooks.h"
      33                 :             : #include "diagnostic-diagram.h"
      34                 :             : #include "diagnostic-format-text.h"
      35                 :             : #include "diagnostic-buffer.h"
      36                 :             : #include "text-art/theme.h"
      37                 :             : #include "make-unique.h"
      38                 :             : 
      39                 :             : /* Disable warnings about quoting issues in the pp_xxx calls below
      40                 :             :    that (intentionally) don't follow GCC diagnostic conventions.  */
      41                 :             : #if __GNUC__ >= 10
      42                 :             : #  pragma GCC diagnostic push
      43                 :             : #  pragma GCC diagnostic ignored "-Wformat-diag"
      44                 :             : #endif
      45                 :             : 
      46                 :             : /* Concrete buffering implementation subclass for JSON output.  */
      47                 :             : 
      48                 :             : class diagnostic_text_format_buffer : public diagnostic_per_format_buffer
      49                 :             : {
      50                 :             : public:
      51                 :             :   friend class diagnostic_text_output_format;
      52                 :             : 
      53                 :             :   diagnostic_text_format_buffer (diagnostic_output_format &format);
      54                 :             : 
      55                 :             :   void dump (FILE *out, int indent) const final override;
      56                 :             : 
      57                 :             :   bool empty_p () const final override;
      58                 :             :   void move_to (diagnostic_per_format_buffer &dest) final override;
      59                 :             :   void clear () final override;
      60                 :             :   void flush () final override;
      61                 :             : 
      62                 :             : private:
      63                 :             :   diagnostic_output_format &m_format;
      64                 :             :   output_buffer m_output_buffer;
      65                 :             : };
      66                 :             : 
      67                 :             : /* class diagnostic_text_format_buffer : public diagnostic_per_format_buffer.  */
      68                 :             : 
      69                 :       95350 : diagnostic_text_format_buffer::
      70                 :       95350 : diagnostic_text_format_buffer (diagnostic_output_format &format)
      71                 :       95350 : : m_format (format)
      72                 :             : {
      73                 :       95350 :   m_output_buffer.m_flush_p = false;
      74                 :       95350 : }
      75                 :             : 
      76                 :             : void
      77                 :           0 : diagnostic_text_format_buffer::dump (FILE *out, int indent) const
      78                 :             : {
      79                 :           0 :   fprintf (out, "%*sdiagnostic_text_format_buffer:\n", indent, "");
      80                 :           0 :   m_output_buffer.dump (out, indent + 2);
      81                 :           0 : }
      82                 :             : 
      83                 :             : bool
      84                 :     7697074 : diagnostic_text_format_buffer::empty_p () const
      85                 :             : {
      86                 :     7697074 :   return output_buffer_last_position_in_text (&m_output_buffer) == nullptr;
      87                 :             : }
      88                 :             : 
      89                 :             : void
      90                 :       21892 : diagnostic_text_format_buffer::move_to (diagnostic_per_format_buffer &base_dest)
      91                 :             : {
      92                 :       21892 :   diagnostic_text_format_buffer &dest
      93                 :             :     = static_cast<diagnostic_text_format_buffer &> (base_dest);
      94                 :       21892 :   const char *str = output_buffer_formatted_text (&m_output_buffer);
      95                 :       21892 :   output_buffer_append_r (&dest.m_output_buffer, str, strlen (str));
      96                 :             : 
      97                 :       21892 :   obstack_free (m_output_buffer.m_obstack,
      98                 :             :                 obstack_base (m_output_buffer.m_obstack));
      99                 :       21892 :   m_output_buffer.m_line_length = 0;
     100                 :       21892 : }
     101                 :             : 
     102                 :             : void
     103                 :     4630209 : diagnostic_text_format_buffer::clear ()
     104                 :             : {
     105                 :     4630209 :   pretty_printer *const pp = m_format.get_printer ();
     106                 :     4630209 :   output_buffer *const old_output_buffer = pp_buffer (pp);
     107                 :             : 
     108                 :     4630209 :   pp_buffer (pp) = &m_output_buffer;
     109                 :             : 
     110                 :     4630209 :   pp_clear_output_area (pp);
     111                 :     4630209 :   gcc_assert (empty_p ());
     112                 :             : 
     113                 :     4630209 :   pp_buffer (pp) = old_output_buffer;
     114                 :     4630209 : }
     115                 :             : 
     116                 :             : void
     117                 :        6944 : diagnostic_text_format_buffer::flush ()
     118                 :             : {
     119                 :        6944 :   pretty_printer *const pp = m_format.get_printer ();
     120                 :        6944 :   output_buffer *const old_output_buffer = pp_buffer (pp);
     121                 :             : 
     122                 :        6944 :   pp_buffer (pp) = &m_output_buffer;
     123                 :             : 
     124                 :        6944 :   pp_really_flush (pp);
     125                 :        6944 :   gcc_assert (empty_p ());
     126                 :             : 
     127                 :        6944 :   pp_buffer (pp) = old_output_buffer;
     128                 :        6944 : }
     129                 :             : 
     130                 :             : /* class diagnostic_text_output_format : public diagnostic_output_format.  */
     131                 :             : 
     132                 :      600988 : diagnostic_text_output_format::~diagnostic_text_output_format ()
     133                 :             : {
     134                 :             :   /* Some of the errors may actually have been warnings.  */
     135                 :      301826 :   if (m_context.diagnostic_count (DK_WERROR))
     136                 :             :     {
     137                 :         192 :       pretty_printer *pp = get_printer ();
     138                 :             :       /* -Werror was given.  */
     139                 :         192 :       if (m_context.warning_as_error_requested_p ())
     140                 :          75 :         pp_verbatim (pp,
     141                 :          75 :                      _("%s: all warnings being treated as errors"),
     142                 :             :                      progname);
     143                 :             :       /* At least one -Werror= was given.  */
     144                 :             :       else
     145                 :         117 :         pp_verbatim (pp,
     146                 :         117 :                      _("%s: some warnings being treated as errors"),
     147                 :             :                      progname);
     148                 :         192 :       pp_newline_and_flush (pp);
     149                 :             :     }
     150                 :             : 
     151                 :      301826 :   if (m_includes_seen)
     152                 :             :     {
     153                 :         981 :       delete m_includes_seen;
     154                 :         981 :       m_includes_seen = nullptr;
     155                 :             :     }
     156                 :      600988 : }
     157                 :             : 
     158                 :             : void
     159                 :           0 : diagnostic_text_output_format::dump (FILE *out, int indent) const
     160                 :             : {
     161                 :           0 :   fprintf (out, "%*sdiagnostic_text_output_format\n", indent, "");
     162                 :           0 :   fprintf (out, "%*sm_follows_reference_printer: %s\n",
     163                 :             :            indent, "",
     164                 :           0 :            m_follows_reference_printer ? "true" : "false");
     165                 :           0 :   diagnostic_output_format::dump (out, indent);
     166                 :           0 :   fprintf (out, "%*ssaved_output_buffer:\n", indent + 2, "");
     167                 :           0 :   if (m_saved_output_buffer)
     168                 :           0 :     m_saved_output_buffer->dump (out, indent + 4);
     169                 :             :   else
     170                 :           0 :     fprintf (out, "%*s(none):\n", indent + 4, "");
     171                 :           0 : }
     172                 :             : 
     173                 :             : void
     174                 :     2596989 : diagnostic_text_output_format::set_buffer (diagnostic_per_format_buffer *base)
     175                 :             : {
     176                 :     2596989 :   diagnostic_text_format_buffer * const buffer
     177                 :             :     = static_cast<diagnostic_text_format_buffer *> (base);
     178                 :             : 
     179                 :     2596989 :   pretty_printer *const pp = get_printer ();
     180                 :             : 
     181                 :     2596989 :   if (!m_saved_output_buffer)
     182                 :      298849 :     m_saved_output_buffer = pp_buffer (pp);
     183                 :             : 
     184                 :     2596989 :   if (buffer)
     185                 :     1149070 :     pp_buffer (pp) = &buffer->m_output_buffer;
     186                 :             :   else
     187                 :             :     {
     188                 :     1447919 :       gcc_assert (m_saved_output_buffer);
     189                 :     1447919 :       pp_buffer (pp) = m_saved_output_buffer;
     190                 :             :     }
     191                 :     2596989 : }
     192                 :             : 
     193                 :             : std::unique_ptr<diagnostic_per_format_buffer>
     194                 :       95350 : diagnostic_text_output_format::make_per_format_buffer ()
     195                 :             : {
     196                 :       95350 :   return ::make_unique<diagnostic_text_format_buffer> (*this);
     197                 :             : }
     198                 :             : 
     199                 :             : /* Implementation of diagnostic_output_format::on_report_diagnostic vfunc
     200                 :             :    for GCC's standard textual output.  */
     201                 :             : 
     202                 :             : void
     203                 :     1469650 : diagnostic_text_output_format::
     204                 :             : on_report_diagnostic (const diagnostic_info &diagnostic,
     205                 :             :                       diagnostic_t orig_diag_kind)
     206                 :             : {
     207                 :     1469650 :   pretty_printer *pp = get_printer ();
     208                 :             : 
     209                 :     1469650 :   (*diagnostic_text_starter (&m_context)) (*this, &diagnostic);
     210                 :             : 
     211                 :     1469650 :   pp_output_formatted_text (pp, m_context.get_urlifier ());
     212                 :             : 
     213                 :     1469650 :   if (m_context.m_show_cwe)
     214                 :     1468439 :     print_any_cwe (diagnostic);
     215                 :             : 
     216                 :     1469650 :   if (m_context.m_show_rules)
     217                 :     1468439 :     print_any_rules (diagnostic);
     218                 :             : 
     219                 :     1469650 :   if (m_context.m_show_option_requested)
     220                 :     1468439 :     print_option_information (diagnostic, orig_diag_kind);
     221                 :             : 
     222                 :             :   /* If we're showing nested diagnostics, then print the location
     223                 :             :      on a new line, indented.  */
     224                 :     1469650 :   if (m_show_nesting && m_show_locations_in_nesting)
     225                 :             :     {
     226                 :          39 :       const int nesting_level = get_context ().get_diagnostic_nesting_level ();
     227                 :          39 :       if (nesting_level > 0)
     228                 :             :         {
     229                 :          36 :           location_t loc = diagnostic_location (&diagnostic);
     230                 :          36 :           pp_set_prefix (pp, nullptr);
     231                 :          36 :           char *indent_prefix = build_indent_prefix (false);
     232                 :             :           /* Only print changes of location.  */
     233                 :          36 :           if (loc != get_context ().m_last_location
     234                 :          36 :               && loc > BUILTINS_LOCATION)
     235                 :             :             {
     236                 :           0 :               const expanded_location s
     237                 :           0 :                 = diagnostic_expand_location (&diagnostic);
     238                 :           0 :               label_text location_text = get_location_text (s);
     239                 :           0 :               pp_newline (pp);
     240                 :           0 :               pp_printf (pp, "%s%s", indent_prefix, location_text.get ());
     241                 :           0 :             }
     242                 :          36 :           pp_set_prefix (pp, indent_prefix);
     243                 :             :         }
     244                 :             :     }
     245                 :             : 
     246                 :     1469650 :   (*diagnostic_text_finalizer (&m_context)) (*this,
     247                 :             :                                              &diagnostic,
     248                 :             :                                              orig_diag_kind);
     249                 :             : 
     250                 :     1469649 :   if (m_show_nesting && m_show_locations_in_nesting)
     251                 :          39 :     get_context ().m_last_location = diagnostic_location (&diagnostic);
     252                 :     1469649 : }
     253                 :             : 
     254                 :             : void
     255                 :           0 : diagnostic_text_output_format::on_report_verbatim (text_info &text)
     256                 :             : {
     257                 :           0 :   pp_format_verbatim (get_printer (), &text);
     258                 :           0 :   pp_newline_and_flush (get_printer ());
     259                 :           0 : }
     260                 :             : 
     261                 :             : void
     262                 :          80 : diagnostic_text_output_format::on_diagram (const diagnostic_diagram &diagram)
     263                 :             : {
     264                 :          80 :   pretty_printer *const pp = get_printer ();
     265                 :             : 
     266                 :          80 :   char *saved_prefix = pp_take_prefix (pp);
     267                 :          80 :   pp_set_prefix (pp, NULL);
     268                 :             :   /* Use a newline before and after and a two-space indent
     269                 :             :      to make the diagram stand out a little from the wall of text.  */
     270                 :          80 :   pp_newline (pp);
     271                 :          80 :   diagram.get_canvas ().print_to_pp (pp, "  ");
     272                 :          80 :   pp_newline (pp);
     273                 :          80 :   pp_set_prefix (pp, saved_prefix);
     274                 :          80 :   pp_flush (pp);
     275                 :          80 : }
     276                 :             : 
     277                 :             : void
     278                 :      319913 : diagnostic_text_output_format::
     279                 :             : after_diagnostic (const diagnostic_info &diagnostic)
     280                 :             : {
     281                 :      319913 :   if (const diagnostic_path *path = diagnostic.richloc->get_path ())
     282                 :        3775 :     print_path (*path);
     283                 :      319913 : }
     284                 :             : 
     285                 :             : /* Return a malloc'd string describing a location and the severity of the
     286                 :             :    diagnostic, e.g. "foo.c:42:10: error: ".
     287                 :             : 
     288                 :             :    If m_show_nesting, then the above will be preceded by indentation to show
     289                 :             :    the level, and a bullet point.
     290                 :             : 
     291                 :             :    The caller is responsible for freeing the memory.  */
     292                 :             : char *
     293                 :      320633 : diagnostic_text_output_format::
     294                 :             : build_prefix (const diagnostic_info &diagnostic) const
     295                 :             : {
     296                 :      320633 :   gcc_assert (diagnostic.kind < DK_LAST_DIAGNOSTIC_KIND);
     297                 :             : 
     298                 :      320633 :   const char *text = _(get_diagnostic_kind_text (diagnostic.kind));
     299                 :      320633 :   const char *text_cs = "", *text_ce = "";
     300                 :      320633 :   pretty_printer *pp = get_printer ();
     301                 :             : 
     302                 :      320633 :   if (const char *color_name = diagnostic_get_color_for_kind (diagnostic.kind))
     303                 :             :     {
     304                 :      320633 :       text_cs = colorize_start (pp_show_color (pp), color_name);
     305                 :      320633 :       text_ce = colorize_stop (pp_show_color (pp));
     306                 :             :     }
     307                 :             : 
     308                 :      320633 :   const int nesting_level = get_context ().get_diagnostic_nesting_level ();
     309                 :      320633 :   if (m_show_nesting && nesting_level > 0)
     310                 :             :     {
     311                 :         138 :       char *indent_prefix = build_indent_prefix (true);
     312                 :             : 
     313                 :             :       /* Reduce verbosity of nested diagnostics by not printing "note: "
     314                 :             :          all the time.  */
     315                 :         138 :       if (diagnostic.kind == DK_NOTE)
     316                 :             :         return indent_prefix;
     317                 :             : 
     318                 :           6 :       char *result = build_message_string ("%s%s%s%s", indent_prefix,
     319                 :             :                                            text_cs, text, text_ce);
     320                 :           6 :       free (indent_prefix);
     321                 :           6 :       return result;
     322                 :             :     }
     323                 :             :   else
     324                 :             :     {
     325                 :      320495 :       const expanded_location s = diagnostic_expand_location (&diagnostic);
     326                 :      320495 :       label_text location_text = get_location_text (s);
     327                 :      320495 :       return build_message_string ("%s %s%s%s", location_text.get (),
     328                 :             :                                    text_cs, text, text_ce);
     329                 :      320495 :     }
     330                 :             : }
     331                 :             : 
     332                 :             : /* Same as build_prefix, but only the source FILE is given.  */
     333                 :             : char *
     334                 :       38302 : diagnostic_text_output_format::file_name_as_prefix (const char *f) const
     335                 :             : {
     336                 :       38302 :   pretty_printer *const pp = get_printer ();
     337                 :       38302 :   const char *locus_cs
     338                 :       38302 :     = colorize_start (pp_show_color (pp), "locus");
     339                 :       38302 :   const char *locus_ce = colorize_stop (pp_show_color (pp));
     340                 :       38302 :   return build_message_string ("%s%s:%s ", locus_cs, f, locus_ce);
     341                 :             : }
     342                 :             : 
     343                 :             : /* Get the unicode code point for bullet points when showing
     344                 :             :    nested diagnostics.  */
     345                 :             : 
     346                 :             : static unsigned
     347                 :         285 : get_bullet_point_unichar (bool unicode)
     348                 :             : {
     349                 :         285 :   if (unicode)
     350                 :             :     return 0x2022; /* U+2022: Bullet */
     351                 :             :   else
     352                 :         273 :     return '*';
     353                 :             : }
     354                 :             : 
     355                 :             : /* Return true if DC's theme supports unicode characters.  */
     356                 :             : 
     357                 :             : static bool
     358                 :         285 : use_unicode_p (const diagnostic_context &dc)
     359                 :             : {
     360                 :         285 :   if (text_art::theme *theme = dc.get_diagram_theme ())
     361                 :          12 :     return theme->unicode_p ();
     362                 :             :   else
     363                 :             :     return false;
     364                 :             : }
     365                 :             : 
     366                 :             : /* Get the unicode code point for bullet points when showing
     367                 :             :    nested diagnostics.  */
     368                 :             : 
     369                 :             : static unsigned
     370                 :         285 : get_bullet_point_unichar (diagnostic_context &dc)
     371                 :             : {
     372                 :         285 :   return get_bullet_point_unichar (use_unicode_p (dc));
     373                 :             : }
     374                 :             : 
     375                 :             : /* Return a malloc'd string for use as a prefix to show indentation.
     376                 :             :    If m_show_nesting is false, or we're at the top-level, then the
     377                 :             :    result will be the empty string.
     378                 :             : 
     379                 :             :    If m_show_nesting, then the result will contain indentation to show
     380                 :             :    the nesting level, then either a bullet point (if WITH_BULLET is true),
     381                 :             :    or a space.
     382                 :             : 
     383                 :             :    The caller is responsible for freeing the memory.  */
     384                 :             : 
     385                 :             : char *
     386                 :      510088 : diagnostic_text_output_format::build_indent_prefix (bool with_bullet) const
     387                 :             : {
     388                 :      510088 :   if (!m_show_nesting)
     389                 :      509608 :     return xstrdup ("");
     390                 :             : 
     391                 :         480 :   const int nesting_level = get_context ().get_diagnostic_nesting_level ();
     392                 :         480 :   if (nesting_level == 0)
     393                 :          21 :     return xstrdup ("");
     394                 :             : 
     395                 :         459 :   pretty_printer pp;
     396                 :        1974 :   for (int i = 0; i < nesting_level; i++)
     397                 :        1515 :     pp_string (&pp, "  ");
     398                 :         459 :   if (with_bullet)
     399                 :         570 :     pp_unicode_character (&pp, get_bullet_point_unichar (get_context ()));
     400                 :             :   else
     401                 :         174 :     pp_space (&pp);
     402                 :         459 :   pp_space (&pp);
     403                 :         459 :   if (m_show_nesting_levels)
     404                 :          36 :     pp_printf (&pp, "(level %i):", nesting_level);
     405                 :         459 :   return xstrdup (pp_formatted_text (&pp));
     406                 :         459 : }
     407                 :             : 
     408                 :             : /* Add a purely textual note with text GMSGID and with LOCATION.  */
     409                 :             : 
     410                 :             : void
     411                 :       12635 : diagnostic_text_output_format::append_note (location_t location,
     412                 :             :                                             const char * gmsgid, ...)
     413                 :             : {
     414                 :       12635 :   diagnostic_context *context = &get_context ();
     415                 :             : 
     416                 :       12635 :   diagnostic_info diagnostic;
     417                 :       12635 :   va_list ap;
     418                 :       12635 :   rich_location richloc (line_table, location);
     419                 :             : 
     420                 :       12635 :   va_start (ap, gmsgid);
     421                 :       12635 :   diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_NOTE);
     422                 :       12635 :   if (context->m_inhibit_notes_p)
     423                 :             :     {
     424                 :           0 :       va_end (ap);
     425                 :           0 :       return;
     426                 :             :     }
     427                 :       12635 :   pretty_printer *pp = get_printer ();
     428                 :       12635 :   char *saved_prefix = pp_take_prefix (pp);
     429                 :       12635 :   pp_set_prefix (pp, build_prefix (diagnostic));
     430                 :       12635 :   pp_format (pp, &diagnostic.message);
     431                 :       12635 :   pp_output_formatted_text (pp);
     432                 :       12635 :   pp_destroy_prefix (pp);
     433                 :       12635 :   pp_set_prefix (pp, saved_prefix);
     434                 :       12635 :   pp_newline (pp);
     435                 :       12635 :   diagnostic_show_locus (context, get_source_printing_options (),
     436                 :             :                          &richloc, DK_NOTE, pp);
     437                 :       12635 :   va_end (ap);
     438                 :       12635 : }
     439                 :             : 
     440                 :             : bool
     441                 :     3289774 : diagnostic_text_output_format::follows_reference_printer_p () const
     442                 :             : {
     443                 :     3289774 :   return m_follows_reference_printer;
     444                 :             : }
     445                 :             : 
     446                 :             : void
     447                 :      483728 : diagnostic_text_output_format::
     448                 :             : update_printer ()
     449                 :             : {
     450                 :      483728 :   pretty_printer *copy_from_pp
     451                 :      483728 :     = (m_follows_reference_printer
     452                 :      483728 :        ? get_context ().get_reference_printer ()
     453                 :           0 :        : m_printer.get ());
     454                 :      483728 :   const bool show_color = pp_show_color (copy_from_pp);
     455                 :      483728 :   const diagnostic_url_format url_format = copy_from_pp->get_url_format ();
     456                 :             : 
     457                 :      483728 :   m_printer = get_context ().clone_printer ();
     458                 :             : 
     459                 :      483728 :   pp_show_color (m_printer.get ()) = show_color;
     460                 :      483728 :   m_printer->set_url_format (url_format);
     461                 :             :   // ...etc
     462                 :             : 
     463                 :      483728 :   m_source_printing = get_context ().m_source_printing;
     464                 :      483728 : }
     465                 :             : 
     466                 :             : /* If DIAGNOSTIC has a CWE identifier, print it.
     467                 :             : 
     468                 :             :    For example, if the diagnostic metadata associates it with CWE-119,
     469                 :             :    " [CWE-119]" will be printed, suitably colorized, and with a URL of a
     470                 :             :    description of the security issue.  */
     471                 :             : 
     472                 :             : void
     473                 :     1468439 : diagnostic_text_output_format::print_any_cwe (const diagnostic_info &diagnostic)
     474                 :             : {
     475                 :     1468439 :   if (diagnostic.metadata == NULL)
     476                 :             :     return;
     477                 :             : 
     478                 :        4046 :   int cwe = diagnostic.metadata->get_cwe ();
     479                 :        4046 :   if (cwe)
     480                 :             :     {
     481                 :        3229 :       pretty_printer * const pp = get_printer ();
     482                 :        3229 :       char *saved_prefix = pp_take_prefix (pp);
     483                 :        3229 :       pp_string (pp, " [");
     484                 :        3229 :       const char *kind_color = diagnostic_get_color_for_kind (diagnostic.kind);
     485                 :        3229 :       pp_string (pp, colorize_start (pp_show_color (pp), kind_color));
     486                 :        3229 :       if (pp->supports_urls_p ())
     487                 :             :         {
     488                 :           0 :           char *cwe_url = get_cwe_url (cwe);
     489                 :           0 :           pp_begin_url (pp, cwe_url);
     490                 :           0 :           free (cwe_url);
     491                 :             :         }
     492                 :        3229 :       pp_printf (pp, "CWE-%i", cwe);
     493                 :        3229 :       pp_set_prefix (pp, saved_prefix);
     494                 :        3229 :       if (pp->supports_urls_p ())
     495                 :           0 :         pp_end_url (pp);
     496                 :        3229 :       pp_string (pp, colorize_stop (pp_show_color (pp)));
     497                 :        3229 :       pp_character (pp, ']');
     498                 :             :     }
     499                 :             : }
     500                 :             : 
     501                 :             : /* If DIAGNOSTIC has any rules associated with it, print them.
     502                 :             : 
     503                 :             :    For example, if the diagnostic metadata associates it with a rule
     504                 :             :    named "STR34-C", then " [STR34-C]" will be printed, suitably colorized,
     505                 :             :    with any URL provided by the rule.  */
     506                 :             : 
     507                 :             : void
     508                 :     1468439 : diagnostic_text_output_format::
     509                 :             : print_any_rules (const diagnostic_info &diagnostic)
     510                 :             : {
     511                 :     1468439 :   if (diagnostic.metadata == NULL)
     512                 :             :     return;
     513                 :             : 
     514                 :        4330 :   for (unsigned idx = 0; idx < diagnostic.metadata->get_num_rules (); idx++)
     515                 :             :     {
     516                 :         284 :       const diagnostic_metadata::rule &rule
     517                 :         284 :         = diagnostic.metadata->get_rule (idx);
     518                 :         284 :       if (char *desc = rule.make_description ())
     519                 :             :         {
     520                 :         284 :           pretty_printer * const pp = get_printer ();
     521                 :         284 :           char *saved_prefix = pp_take_prefix (pp);
     522                 :         284 :           pp_string (pp, " [");
     523                 :         284 :           const char *kind_color
     524                 :         284 :             = diagnostic_get_color_for_kind (diagnostic.kind);
     525                 :         284 :           pp_string (pp, colorize_start (pp_show_color (pp), kind_color));
     526                 :         284 :           char *url = NULL;
     527                 :         284 :           if (pp->supports_urls_p ())
     528                 :             :             {
     529                 :           0 :               url = rule.make_url ();
     530                 :           0 :               if (url)
     531                 :           0 :                 pp_begin_url (pp, url);
     532                 :             :             }
     533                 :         284 :           pp_string (pp, desc);
     534                 :         284 :           pp_set_prefix (pp, saved_prefix);
     535                 :         284 :           if (pp->supports_urls_p ())
     536                 :           0 :             if (url)
     537                 :           0 :               pp_end_url (pp);
     538                 :         284 :           free (url);
     539                 :         284 :           pp_string (pp, colorize_stop (pp_show_color (pp)));
     540                 :         284 :           pp_character (pp, ']');
     541                 :         284 :           free (desc);
     542                 :             :         }
     543                 :             :     }
     544                 :             : }
     545                 :             : 
     546                 :             : /* Print any metadata about the option used to control DIAGNOSTIC to CONTEXT's
     547                 :             :    printer, e.g. " [-Werror=uninitialized]".
     548                 :             :    Subroutine of diagnostic_context::report_diagnostic.  */
     549                 :             : 
     550                 :             : void
     551                 :     1468439 : diagnostic_text_output_format::
     552                 :             : print_option_information (const diagnostic_info &diagnostic,
     553                 :             :                           diagnostic_t orig_diag_kind)
     554                 :             : {
     555                 :     2936878 :   if (char *option_text
     556                 :     1468439 :       = m_context.make_option_name (diagnostic.option_id,
     557                 :     1468439 :                                     orig_diag_kind, diagnostic.kind))
     558                 :             :     {
     559                 :       83984 :       char *option_url = nullptr;
     560                 :       83984 :       pretty_printer * const pp = get_printer ();
     561                 :       83984 :       if (pp->supports_urls_p ())
     562                 :           0 :         option_url = m_context.make_option_url (diagnostic.option_id);
     563                 :       83984 :       pp_string (pp, " [");
     564                 :       83984 :       const char *kind_color = diagnostic_get_color_for_kind (diagnostic.kind);
     565                 :       83984 :       pp_string (pp, colorize_start (pp_show_color (pp), kind_color));
     566                 :       83984 :       if (option_url)
     567                 :           0 :         pp_begin_url (pp, option_url);
     568                 :       83984 :       pp_string (pp, option_text);
     569                 :       83984 :       if (option_url)
     570                 :             :         {
     571                 :           0 :           pp_end_url (pp);
     572                 :           0 :           free (option_url);
     573                 :             :         }
     574                 :       83984 :       pp_string (pp, colorize_stop (pp_show_color (pp)));
     575                 :       83984 :       pp_character (pp, ']');
     576                 :       83984 :       free (option_text);
     577                 :             :     }
     578                 :     1468439 : }
     579                 :             : 
     580                 :             : /* Only dump the "In file included from..." stack once for each file.  */
     581                 :             : 
     582                 :             : bool
     583                 :       58072 : diagnostic_text_output_format::includes_seen_p (const line_map_ordinary *map)
     584                 :             : {
     585                 :             :   /* No include path for main.  */
     586                 :       58072 :   if (MAIN_FILE_P (map))
     587                 :             :     return true;
     588                 :             : 
     589                 :             :   /* Always identify C++ modules, at least for now.  */
     590                 :        7788 :   auto probe = map;
     591                 :        7788 :   if (linemap_check_ordinary (map)->reason == LC_RENAME)
     592                 :             :     /* The module source file shows up as LC_RENAME inside LC_MODULE.  */
     593                 :         455 :     probe = linemap_included_from_linemap (line_table, map);
     594                 :        7788 :   if (MAP_MODULE_P (probe))
     595                 :             :     return false;
     596                 :             : 
     597                 :        6924 :   if (!m_includes_seen)
     598                 :         981 :     m_includes_seen = new hash_set<location_t, false, location_hash>;
     599                 :             : 
     600                 :             :   /* Hash the location of the #include directive to better handle files
     601                 :             :      that are included multiple times with different macros defined.  */
     602                 :        6924 :   return m_includes_seen->add (linemap_included_from (map));
     603                 :             : }
     604                 :             : 
     605                 :             : label_text
     606                 :      320495 : diagnostic_text_output_format::
     607                 :             : get_location_text (const expanded_location &s) const
     608                 :             : {
     609                 :      320495 :   diagnostic_column_policy column_policy (get_context ());
     610                 :      320495 :   return column_policy.get_location_text (s,
     611                 :      320495 :                                           show_column_p (),
     612                 :      320495 :                                           pp_show_color (get_printer ()));
     613                 :             : }
     614                 :             : 
     615                 :             : /* Helpers for writing lang-specific starters/finalizers for text output.  */
     616                 :             : 
     617                 :             : /* Return a formatted line and column ':%line:%column'.  Elided if
     618                 :             :    line == 0 or col < 0.  (A column of 0 may be valid due to the
     619                 :             :    -fdiagnostics-column-origin option.)
     620                 :             :    The result is a statically allocated buffer.  */
     621                 :             : 
     622                 :             : const char *
     623                 :      326402 : maybe_line_and_column (int line, int col)
     624                 :             : {
     625                 :      326402 :   static char result[32];
     626                 :             : 
     627                 :      326402 :   if (line)
     628                 :             :     {
     629                 :      322352 :       size_t l
     630                 :      322352 :         = snprintf (result, sizeof (result),
     631                 :      322352 :                     col >= 0 ? ":%d:%d" : ":%d", line, col);
     632                 :      322352 :       gcc_checking_assert (l < sizeof (result));
     633                 :             :     }
     634                 :             :   else
     635                 :        4050 :     result[0] = 0;
     636                 :      326402 :   return result;
     637                 :             : }
     638                 :             : 
     639                 :             : void
     640                 :      307998 : diagnostic_text_output_format::report_current_module (location_t where)
     641                 :             : {
     642                 :      307998 :   pretty_printer *pp = get_printer ();
     643                 :      307998 :   const line_map_ordinary *map = NULL;
     644                 :             : 
     645                 :      307998 :   if (pp_needs_newline (pp))
     646                 :             :     {
     647                 :           0 :       pp_newline (pp);
     648                 :           0 :       pp_needs_newline (pp) = false;
     649                 :             :     }
     650                 :             : 
     651                 :      307998 :   if (where <= BUILTINS_LOCATION)
     652                 :        2889 :     return;
     653                 :             : 
     654                 :      305109 :   linemap_resolve_location (line_table, where,
     655                 :             :                             LRK_MACRO_DEFINITION_LOCATION,
     656                 :             :                             &map);
     657                 :             : 
     658                 :      305109 :   if (map && m_last_module != map)
     659                 :             :     {
     660                 :       54005 :       m_last_module = map;
     661                 :       54005 :       if (!includes_seen_p (map))
     662                 :             :         {
     663                 :        1790 :           bool first = true, need_inc = true, was_module = MAP_MODULE_P (map);
     664                 :        1790 :           expanded_location s = {};
     665                 :        4067 :           do
     666                 :             :             {
     667                 :        4067 :               where = linemap_included_from (map);
     668                 :        4067 :               map = linemap_included_from_linemap (line_table, map);
     669                 :        4067 :               bool is_module = MAP_MODULE_P (map);
     670                 :        4067 :               s.file = LINEMAP_FILE (map);
     671                 :        4067 :               s.line = SOURCE_LINE (map, where);
     672                 :        4067 :               int col = -1;
     673                 :        4067 :               if (first && show_column_p ())
     674                 :             :                 {
     675                 :         875 :                   s.column = SOURCE_COLUMN (map, where);
     676                 :         875 :                   col = get_column_policy ().converted_column (s);
     677                 :             :                 }
     678                 :        4067 :               const char *line_col = maybe_line_and_column (s.line, col);
     679                 :        4067 :               static const char *const msgs[] =
     680                 :             :                 {
     681                 :             :                  NULL,
     682                 :             :                  N_("                 from"),
     683                 :             :                  N_("In file included from"), /* 2 */
     684                 :             :                  N_("        included from"),
     685                 :             :                  N_("In module"),             /* 4 */
     686                 :             :                  N_("of module"),
     687                 :             :                  N_("In module imported at"), /* 6 */
     688                 :             :                  N_("imported at"),
     689                 :             :                 };
     690                 :             : 
     691                 :        4067 :               unsigned index = (was_module ? 6 : is_module ? 4
     692                 :        3203 :                                 : need_inc ? 2 : 0) + !first;
     693                 :             : 
     694                 :        5941 :               pp_verbatim (pp, "%s%s %r%s%s%R",
     695                 :             :                            first ? "" : was_module ? ", " : ",\n",
     696                 :        4067 :                            _(msgs[index]),
     697                 :             :                            "locus", s.file, line_col);
     698                 :        4067 :               first = false, need_inc = was_module, was_module = is_module;
     699                 :             :             }
     700                 :        4067 :           while (!includes_seen_p (map));
     701                 :        1790 :           pp_verbatim (pp, ":");
     702                 :        1790 :           pp_newline (pp);
     703                 :             :         }
     704                 :             :     }
     705                 :             : }
     706                 :             : 
     707                 :             : void
     708                 :        1211 : default_diagnostic_text_starter (diagnostic_text_output_format &text_output,
     709                 :             :                                  const diagnostic_info *diagnostic)
     710                 :             : {
     711                 :        1211 :   text_output.report_current_module (diagnostic_location (diagnostic));
     712                 :        1211 :   pretty_printer *const pp = text_output.get_printer ();
     713                 :        1211 :   pp_set_prefix (pp, text_output.build_prefix (*diagnostic));
     714                 :        1211 : }
     715                 :             : 
     716                 :             : void
     717                 :       16197 : default_diagnostic_text_finalizer (diagnostic_text_output_format &text_output,
     718                 :             :                                    const diagnostic_info *diagnostic,
     719                 :             :                                    diagnostic_t)
     720                 :             : {
     721                 :       16197 :   pretty_printer *const pp = text_output.get_printer ();
     722                 :       16197 :   char *saved_prefix = pp_take_prefix (pp);
     723                 :       16197 :   pp_set_prefix (pp, NULL);
     724                 :       16197 :   pp_newline (pp);
     725                 :       16197 :   diagnostic_show_locus (&text_output.get_context (),
     726                 :       16197 :                          text_output.get_source_printing_options (),
     727                 :       16197 :                          diagnostic->richloc, diagnostic->kind, pp);
     728                 :       16197 :   pp_set_prefix (pp, saved_prefix);
     729                 :       16197 :   pp_flush (pp);
     730                 :       16197 : }
     731                 :             : 
     732                 :             : #if __GNUC__ >= 10
     733                 :             : #  pragma GCC diagnostic pop
     734                 :             : #endif
        

Generated by: LCOV version 2.1-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.