LCOV - code coverage report
Current view: top level - gcc/analyzer - analyzer-logging.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 95.7 % 93 89
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 16 16
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Hierarchical log messages for the analyzer.
       2              :    Copyright (C) 2014-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
       8              : under the terms of the GNU General Public License as published by
       9              : the Free Software Foundation; either version 3, or (at your option)
      10              : any later version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful, but
      13              : WITHOUT ANY WARRANTY; without even the implied warranty of
      14              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15              : General Public License 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              : #include "config.h"
      22              : #include "system.h"
      23              : #include "coretypes.h"
      24              : #include "toplev.h" /* for print_version */
      25              : #include "pretty-print.h" /* for print_version */
      26              : #include "diagnostic.h"
      27              : #include "tree-diagnostic.h"
      28              : 
      29              : #include "analyzer/analyzer-logging.h"
      30              : 
      31              : #if ENABLE_ANALYZER
      32              : 
      33              : #if __GNUC__ >= 10
      34              : #pragma GCC diagnostic ignored "-Wformat-diag"
      35              : #endif
      36              : 
      37              : namespace ana {
      38              : 
      39              : /* Implementation of class logger.  */
      40              : 
      41              : /* ctor for logger.  */
      42              : 
      43           10 : logger::logger (FILE *f_out,
      44              :                 int, /* flags */
      45              :                 int /* verbosity */,
      46           10 :                 const pretty_printer &reference_pp) :
      47           10 :   m_refcount (0),
      48           10 :   m_f_out (f_out),
      49           10 :   m_indent_level (0),
      50           10 :   m_log_refcount_changes (false),
      51           10 :   m_pp (reference_pp.clone ())
      52              : {
      53           10 :   pp_show_color (m_pp.get ()) = 0;
      54           10 :   pp_buffer (m_pp.get ())->m_stream = f_out;
      55              : 
      56              :   /* %qE in logs for SSA_NAMEs should show the ssa names, rather than
      57              :      trying to prettify things by showing the underlying var.  */
      58           10 :   pp_format_decoder (m_pp.get ()) = default_tree_printer;
      59              : 
      60              :   /* Begin the log by writing the GCC version.  */
      61           10 :   print_version (f_out, "", false);
      62           10 : }
      63              : 
      64              : /* The destructor for logger, invoked via
      65              :    the decref method when the refcount hits zero.
      66              :    Note that we do not close the underlying FILE * (m_f_out).  */
      67              : 
      68           10 : logger::~logger ()
      69              : {
      70              :   /* This should be the last message emitted.  */
      71           10 :   log ("%s", __PRETTY_FUNCTION__);
      72           10 :   gcc_assert (m_refcount == 0);
      73           10 : }
      74              : 
      75              : /* Increment the reference count of the logger.  */
      76              : 
      77              : void
      78         4621 : logger::incref (const char *reason)
      79              : {
      80         4621 :   m_refcount++;
      81         4621 :   if (m_log_refcount_changes)
      82            0 :     log ("%s: reason: %s refcount now %i ",
      83              :          __PRETTY_FUNCTION__, reason, m_refcount);
      84         4621 : }
      85              : 
      86              : /* Decrement the reference count of the logger,
      87              :    deleting it if nothing is referring to it.  */
      88              : 
      89              : void
      90         4621 : logger::decref (const char *reason)
      91              : {
      92         4621 :   gcc_assert (m_refcount > 0);
      93         4621 :   --m_refcount;
      94         4621 :   if (m_log_refcount_changes)
      95            0 :     log ("%s: reason: %s refcount now %i",
      96              :          __PRETTY_FUNCTION__, reason, m_refcount);
      97         4621 :   if (m_refcount == 0)
      98           10 :     delete this;
      99         4621 : }
     100              : 
     101              : /* Write a formatted message to the log, by calling the log_va method.  */
     102              : 
     103              : void
     104         8752 : logger::log (const char *fmt, ...)
     105              : {
     106         8752 :   va_list ap;
     107         8752 :   va_start (ap, fmt);
     108         8752 :   log_va (fmt, &ap);
     109         8752 :   va_end (ap);
     110         8752 : }
     111              : 
     112              : /* Write an indented line to the log file.
     113              : 
     114              :    We explicitly flush after each line: if something crashes the process,
     115              :    we want the logfile/stream to contain the most up-to-date hint about the
     116              :    last thing that was happening, without it being hidden in an in-process
     117              :    buffer.  */
     118              : 
     119              : void
     120         9035 : logger::log_va (const char *fmt, va_list *ap)
     121              : {
     122         9035 :   start_log_line ();
     123         9035 :   log_va_partial (fmt, ap);
     124         9035 :   end_log_line ();
     125         9035 : }
     126              : 
     127              : void
     128        14493 : logger::start_log_line ()
     129              : {
     130        94667 :   for (int i = 0; i < m_indent_level; i++)
     131        80174 :     fputc (' ', m_f_out);
     132        14493 : }
     133              : 
     134              : void
     135          675 : logger::log_partial (const char *fmt, ...)
     136              : {
     137          675 :   va_list ap;
     138          675 :   va_start (ap, fmt);
     139          675 :   log_va_partial (fmt, &ap);
     140          675 :   va_end (ap);
     141          675 : }
     142              : 
     143              : void
     144        10469 : logger::log_va_partial (const char *fmt, va_list *ap)
     145              : {
     146        10469 :   text_info text (fmt, ap, 0);
     147        10469 :   pp_format (m_pp.get (), &text);
     148        10469 :   pp_output_formatted_text (m_pp.get ());
     149        10469 : }
     150              : 
     151              : void
     152        14493 : logger::end_log_line ()
     153              : {
     154        14493 :   pp_flush (m_pp.get ());
     155        14493 :   pp_clear_output_area (m_pp.get ());
     156        14493 :   fprintf (m_f_out, "\n");
     157        14493 :   fflush (m_f_out);
     158        14493 : }
     159              : 
     160              : /* Record the entry within a particular scope, indenting subsequent
     161              :    log lines accordingly.  */
     162              : 
     163              : void
     164         2023 : logger::enter_scope (const char *scope_name)
     165              : {
     166         2023 :   log ("entering: %s", scope_name);
     167         2023 :   inc_indent ();
     168         2023 : }
     169              : 
     170              : void
     171          513 : logger::enter_scope (const char *scope_name, const char *fmt, va_list *ap)
     172              : {
     173          513 :   start_log_line ();
     174          513 :   log_partial ("entering: %s: ", scope_name);
     175          513 :   log_va_partial (fmt, ap);
     176          513 :   end_log_line ();
     177              : 
     178          513 :   inc_indent ();
     179          513 : }
     180              : 
     181              : 
     182              : /* Record the exit from a particular scope, restoring the indent level to
     183              :    before the scope was entered.  */
     184              : 
     185              : void
     186         2536 : logger::exit_scope (const char *scope_name)
     187              : {
     188         2536 :   if (m_indent_level)
     189         2536 :     dec_indent ();
     190              :   else
     191            0 :     log ("(mismatching indentation)");
     192         2536 :   log ("exiting: %s", scope_name);
     193         2536 : }
     194              : 
     195              : /* Implementation of class log_user.  */
     196              : 
     197              : /* The constructor for log_user.  */
     198              : 
     199      3973895 : log_user::log_user (logger *logger) : m_logger (logger)
     200              : {
     201      3973895 :   if (m_logger)
     202         2075 :     m_logger->incref("log_user ctor");
     203      3973895 : }
     204              : 
     205              : /* The destructor for log_user.  */
     206              : 
     207      3973895 : log_user::~log_user ()
     208              : {
     209      3973895 :   if (m_logger)
     210         2085 :     m_logger->decref("log_user dtor");
     211      3973895 : }
     212              : 
     213              : /* Set the logger for a log_user, managing the reference counts
     214              :    of the old and new logger (either of which might be NULL).  */
     215              : 
     216              : void
     217           10 : log_user::set_logger (logger *logger)
     218              : {
     219           10 :   if (logger)
     220           10 :     logger->incref ("log_user::set_logger");
     221           10 :   if (m_logger)
     222            0 :     m_logger->decref ("log_user::set_logger");
     223           10 :   m_logger = logger;
     224           10 : }
     225              : 
     226              : } // namespace ana
     227              : 
     228              : #endif /* #if ENABLE_ANALYZER */
        

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.