LCOV - code coverage report
Current view: top level - gcc/diagnostics - logging.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 53.8 % 65 35
Test Date: 2026-02-28 14:20:25 Functions: 90.0 % 10 9
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Debugging code for logging what the diagnostics subsystem is doing.
       2              :    Copyright (C) 2025-2026 Free Software Foundation, Inc.
       3              :    Contributed by David Malcolm <dmalcolm@redhat.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_DIAGNOSTICS_LOGGING_H
      22              : #define GCC_DIAGNOSTICS_LOGGING_H
      23              : 
      24              : #include "diagnostics/output-file.h"
      25              : #include "diagnostics/option-id.h"
      26              : #include "diagnostics/kinds.h"
      27              : 
      28              : namespace diagnostics {
      29              : 
      30              : namespace logging {
      31              : 
      32              : /* A class for emitting a temporal log of what the diagnostics subsystem
      33              :    is doing, for debugging.
      34              :    We can't use pretty_printer here as we could potentially be debugging
      35              :    pretty-printing itself.  */
      36              : 
      37            0 : class logger
      38              : {
      39              : public:
      40              :   logger (output_file outfile);
      41              : 
      42              :   /* High-level functions that emit a line of text.  */
      43              :   void log_printf (const char *fmt, ...)
      44              :     __attribute__ ((__format__ (printf, 2, 3)));
      45              :   void log_bool_return (const char *function_name, bool retval);
      46              : 
      47              :   /* Lower-level functions for building up a line of text.  */
      48              :   void emit_indent () const;
      49              :   void emit_newline () const;
      50              : 
      51            0 :   FILE *get_stream () const
      52              :   {
      53            0 :     return m_outfile.get_open_file ();
      54              :   }
      55              : 
      56            0 :   int get_indent () const { return m_log_depth * 2; }
      57              : 
      58            0 :   void inc_depth () { m_log_depth++; }
      59            0 :   void dec_depth () { m_log_depth--; }
      60              : 
      61              : private:
      62              :   output_file m_outfile;
      63              :   int m_log_depth;
      64              : };
      65              : 
      66              : /* RAII class for pushing/popping depth within a logger.  */
      67              : 
      68              : class auto_inc_depth
      69              : {
      70              : public:
      71    219724936 :   auto_inc_depth (logger *log)
      72    219724936 :   : m_logger (log)
      73              :   {
      74    219724936 :     if (m_logger)
      75            0 :       m_logger->inc_depth ();
      76              :   }
      77    327799648 :   ~auto_inc_depth ()
      78              :   {
      79    327799648 :     if (m_logger)
      80            0 :       m_logger->dec_depth ();
      81              :   }
      82              : 
      83              : private:
      84              :   logger *m_logger;
      85              : };
      86              : 
      87              : /* Class for debugging function call parameters.  */
      88              : 
      89              : class log_function_params
      90              : {
      91              : public:
      92    216794222 :   log_function_params (logger *logger_, const char *name)
      93    216794222 :   : m_logger (logger_),
      94    216794222 :     m_first_param (true)
      95              :   {
      96    216794222 :     if (m_logger)
      97              :       {
      98            0 :         m_logger->emit_indent ();
      99            0 :         fprintf (m_logger->get_stream (), "%s (", name);
     100              :       }
     101    216794222 :   }
     102    216794222 :   ~log_function_params ()
     103              :   {
     104    216794222 :     if (m_logger)
     105              :       {
     106            0 :         fprintf (m_logger->get_stream (), ")");
     107            0 :         m_logger->emit_newline ();
     108              :       }
     109    216794222 :   }
     110              : 
     111              :   log_function_params &
     112    203006513 :   log_param_string (const char *name, const char *value)
     113              :   {
     114    203006513 :     if (m_logger)
     115              :       {
     116            0 :         add_any_comma ();
     117            0 :         fprintf (m_logger->get_stream (), "%s: \"%s\"", name, value);
     118              :       }
     119    203006513 :     return *this;
     120              :   }
     121              : 
     122              :   log_function_params &
     123     20092717 :   log_param_location_t (const char *name, location_t value)
     124              :   {
     125     20092717 :     if (m_logger)
     126              :       {
     127            0 :         add_any_comma ();
     128            0 :         fprintf (m_logger->get_stream (),
     129              :                  "%s: " HOST_SIZE_T_PRINT_HEX,
     130              :                  name, (fmt_size_t)value);
     131              :       }
     132     20092717 :     return *this;
     133              :   }
     134              : 
     135              :   log_function_params &
     136        37193 :   log_param_rich_location (const char *name, const rich_location *richloc)
     137              :   {
     138        37193 :     if (m_logger)
     139              :       {
     140            0 :         add_any_comma ();
     141            0 :         fprintf (m_logger->get_stream (),
     142              :                  "%s: %p",
     143              :                  name, const_cast<void *> ((const void *)richloc));
     144              :       }
     145        37193 :     return *this;
     146              :   }
     147              : 
     148              :   log_function_params &
     149    207860446 :   log_param_option_id (const char *name, diagnostics::option_id value)
     150              :   {
     151    207860446 :     if (m_logger)
     152              :       {
     153            0 :         add_any_comma ();
     154            0 :         fprintf (m_logger->get_stream (), "%s: %i", name, value.m_idx);
     155              :       }
     156    207860446 :     return *this;
     157              :   }
     158              : 
     159              :   log_function_params &
     160    106596784 :   log_param_kind (const char *name, enum diagnostics::kind value)
     161              :   {
     162    106596784 :     if (m_logger)
     163              :       {
     164            0 :         add_any_comma ();
     165            0 :         fprintf (m_logger->get_stream (), "%s: %s",
     166              :                  name, get_debug_string_for_kind (value));
     167              :       }
     168    106596784 :     return *this;
     169              :   }
     170              : 
     171              :   log_function_params &
     172        25422 :   log_param_uhwi (const char *name, unsigned HOST_WIDE_INT value)
     173              :   {
     174        25422 :     if (m_logger)
     175              :       {
     176            0 :         add_any_comma ();
     177            0 :         fprintf (m_logger->get_stream (),
     178              :                  "%s: " HOST_WIDE_INT_PRINT_DEC,
     179              :                  name, value);
     180              :       }
     181        25422 :     return *this;
     182              :   }
     183              : 
     184              :   log_function_params &
     185        25422 :   log_params_n_gmsgids (unsigned HOST_WIDE_INT n,
     186              :                         const char *singular_gmsgid,
     187              :                         const char *plural_gmsgid)
     188              :   {
     189        25422 :     return log_param_uhwi ("n", n)
     190        25422 :       .log_param_string ("singular_gmsgid", singular_gmsgid)
     191        25422 :       .log_param_string ("plural_gmsgid", plural_gmsgid);
     192              :   }
     193              : 
     194              : private:
     195              :   void
     196            0 :   add_any_comma ()
     197              :   {
     198            0 :     gcc_assert (m_logger);
     199            0 :     if (m_first_param)
     200            0 :       m_first_param = false;
     201              :     else
     202            0 :       fprintf (m_logger->get_stream (), ", ");
     203            0 :   }
     204              : 
     205              :   logger *m_logger;
     206              :   bool m_first_param;
     207              : };
     208              : 
     209              : } // namespace logging
     210              : } // namespace diagnostics
     211              : 
     212              : /* Various macros for logging a formatted line, and indenting
     213              :    further log messages within a scope.  */
     214              : 
     215              : #define DIAGNOSTICS_LOG_SCOPE_PRINTF0(LOGGER, FMT) \
     216              :   if (LOGGER)                                                   \
     217              :     (LOGGER)->log_printf ((FMT));                            \
     218              :   diagnostics::logging::auto_inc_depth depth_sentinel (LOGGER);
     219              : 
     220              : #define DIAGNOSTICS_LOG_SCOPE_PRINTF1(LOGGER, FMT, ARG0)        \
     221              :   if (LOGGER)                                                   \
     222              :     (LOGGER)->log_printf ((FMT), (ARG0));                    \
     223              :   diagnostics::logging::auto_inc_depth depth_sentinel (LOGGER);
     224              : 
     225              : #define DIAGNOSTICS_LOG_SCOPE_PRINTF2(LOGGER, FMT, ARG0, ARG1) \
     226              :   if (LOGGER)                                                   \
     227              :     (LOGGER)->log_printf ((FMT), (ARG0), (ARG1));            \
     228              :   diagnostics::logging::auto_inc_depth depth_sentinel (LOGGER);
     229              : 
     230              : #endif /* ! GCC_DIAGNOSTICS_LOGGING_H */
        

Generated by: LCOV version 2.4-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.