LCOV - code coverage report
Current view: top level - gcc - opts-diagnostic.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 92.6 % 54 50
Test Date: 2026-02-28 14:20:25 Functions: 87.5 % 8 7
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Support for -fdiagnostics-add-output= and -fdiagnostics-set-output=.
       2              :    Copyright (C) 2024-2026 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              : /* This file implements the options -fdiagnostics-add-output=,
      22              :    -fdiagnostics-set-output=.  Most of the work is done
      23              :    by diagnostics/output-spec.cc so it can be shared by libgdiagnostics.  */
      24              : 
      25              : #include "config.h"
      26              : #define INCLUDE_ARRAY
      27              : #define INCLUDE_LIST
      28              : #define INCLUDE_STRING
      29              : #define INCLUDE_VECTOR
      30              : #include "system.h"
      31              : #include "coretypes.h"
      32              : #include "version.h"
      33              : #include "intl.h"
      34              : #include "diagnostic.h"
      35              : #include "diagnostics/output-spec.h"
      36              : #include "diagnostics/logging.h"
      37              : #include "diagnostics/sarif-sink.h"
      38              : #include "opts.h"
      39              : #include "options.h"
      40              : #include "tree-diagnostic-sink-extensions.h"
      41              : #include "opts-diagnostic.h"
      42              : #include "pub-sub.h"
      43              : 
      44              : /* Decls.  */
      45              : 
      46              : namespace {
      47              : 
      48              : class gcc_extra_keys : public diagnostics::output_spec::key_handler
      49              : {
      50              : public:
      51           50 :   gcc_extra_keys ()
      52           50 :   : m_cfgs (false)
      53              :   {
      54              :   }
      55              :   enum result
      56            2 :   maybe_handle_kv (const diagnostics::output_spec::context &ctxt,
      57              :                    const std::string &key,
      58              :                    const std::string &value) final override
      59              :   {
      60            2 :     if (key == "cfgs")
      61            2 :       return parse_bool_value (ctxt, key, value, m_cfgs);
      62              :     return result::unrecognized;
      63              :   }
      64              : 
      65              :   void
      66            0 :   get_keys (auto_vec<const char *> &out_known_keys) const final override
      67              :   {
      68            0 :     out_known_keys.safe_push ("cfgs");
      69            0 :   }
      70              : 
      71              :   bool m_cfgs;
      72              : };
      73              : 
      74           50 : struct opt_spec_context : public diagnostics::output_spec::dc_spec_context
      75              : {
      76              : public:
      77           50 :   opt_spec_context (const gcc_options &opts,
      78              :                     diagnostics::context &dc,
      79              :                     line_maps *location_mgr,
      80              :                     location_t loc,
      81              :                     const char *option_name,
      82              :                     const char *option_value,
      83              :                     diagnostics::output_spec::key_handler *client_keys)
      84           50 :   : dc_spec_context (option_name,
      85              :                      option_value,
      86              :                      client_keys,
      87              :                      location_mgr,
      88              :                      dc,
      89              :                      location_mgr,
      90              :                      loc),
      91           50 :     m_opts (opts)
      92              :   {}
      93              : 
      94              :   const char *
      95           36 :   get_base_filename () const final override
      96              :   {
      97           36 :     return get_diagnostic_file_output_basename (m_opts);
      98              :   }
      99              : 
     100              :   const gcc_options &m_opts;
     101              : };
     102              : 
     103              : static void
     104           50 : handle_gcc_specific_keys (const gcc_extra_keys &gcc_keys,
     105              :                           diagnostics::sink &sink,
     106              :                           const gcc_extension_factory &ext_factory)
     107              : {
     108           50 :   if (gcc_keys.m_cfgs)
     109            2 :     sink.add_extension (ext_factory.make_cfg_extension (sink));
     110           50 : }
     111              : 
     112              : static std::unique_ptr<diagnostics::sink>
     113           50 : try_to_make_sink (const gcc_options &opts,
     114              :                   diagnostics::context &dc,
     115              :                   const char *option_name,
     116              :                   const char *unparsed_spec,
     117              :                   location_t loc)
     118              : {
     119           50 :   gcc_assert (line_table);
     120              : 
     121           50 :   gcc_extra_keys gcc_keys;
     122           50 :   opt_spec_context ctxt (opts, dc, line_table, loc, option_name, unparsed_spec,
     123           50 :                          &gcc_keys);
     124           50 :   auto sink = ctxt.parse_and_make_sink (dc);
     125           50 :   if (!sink)
     126            0 :     return nullptr;
     127              : 
     128           50 :   sink->set_main_input_filename (opts.x_main_input_filename);
     129              : 
     130           50 :   if (auto ext_factory = gcc_extension_factory::singleton)
     131           50 :     handle_gcc_specific_keys (gcc_keys, *sink, *ext_factory);
     132              : 
     133           50 :   return sink;
     134           50 : }
     135              : 
     136              : } // anon namespace
     137              : 
     138              : // class gcc_extension_factory
     139              : 
     140              : const gcc_extension_factory *gcc_extension_factory::singleton;
     141              : 
     142              : void
     143           36 : handle_OPT_fdiagnostics_add_output_ (const gcc_options &opts,
     144              :                                      diagnostics::context &dc,
     145              :                                      const char *unparsed_spec,
     146              :                                      location_t loc)
     147              : {
     148           36 :   gcc_assert (unparsed_spec);
     149              : 
     150           36 :   const char *const option_name = "-fdiagnostics-add-output=";
     151           36 :   DIAGNOSTICS_LOG_SCOPE_PRINTF2 (dc.get_logger (),
     152           36 :                                  "handling: %s%s", option_name, unparsed_spec);
     153           36 :   if (auto sink = try_to_make_sink (opts, dc, option_name, unparsed_spec, loc))
     154           36 :     dc.add_sink (std::move (sink));
     155           36 : }
     156              : 
     157              : void
     158           14 : handle_OPT_fdiagnostics_set_output_ (const gcc_options &opts,
     159              :                                      diagnostics::context &dc,
     160              :                                      const char *unparsed_spec,
     161              :                                      location_t loc)
     162              : {
     163           14 :   gcc_assert (unparsed_spec);
     164              : 
     165           14 :   const char *const option_name = "-fdiagnostics-set-output=";
     166           14 :   DIAGNOSTICS_LOG_SCOPE_PRINTF2 (dc.get_logger (),
     167           14 :                                  "handling: %s%s", option_name, unparsed_spec);
     168           14 :   if (auto sink = try_to_make_sink (opts, dc, option_name, unparsed_spec, loc))
     169           14 :     dc.set_sink (std::move (sink));
     170           14 : }
     171              : 
     172              : /* Return the base name to use when choosing names for output file for
     173              :    diagnostic sinks (e.g. BASENAME.sarif or BASENAME.html).  */
     174              : 
     175              : const char *
     176          126 : get_diagnostic_file_output_basename (const gcc_options &opts)
     177              : {
     178              :   /* This might have been called before finish_options, which prepends
     179              :      the dump dir to the dump base name.  If so, make a prepended copy
     180              :      now and use it.  */
     181          126 :   if (opts.x_dump_base_name
     182          118 :       && ! opts.x_dump_base_name_prefixed)
     183          236 :     if (const char *prepended_dump_base_name
     184          118 :           = maybe_prepend_dump_dir_name (opts))
     185              :       /* Allocated in opts_obstack.  */
     186              :       return prepended_dump_base_name;
     187              : 
     188          126 :   return (opts.x_dump_base_name
     189              :           ? opts.x_dump_base_name
     190          126 :           : opts.x_main_input_basename);
     191              : }
        

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.