LCOV - code coverage report
Current view: top level - gcc/fortran - cpp.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 55.9 % 567 317
Test Date: 2026-02-28 14:20:25 Functions: 59.5 % 37 22
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Copyright (C) 2008-2026 Free Software Foundation, Inc.
       2              : 
       3              : This file is part of GCC.
       4              : 
       5              : GCC is free software; you can redistribute it and/or modify it under
       6              : the terms of the GNU General Public License as published by the Free
       7              : Software Foundation; either version 3, or (at your option) any later
       8              : version.
       9              : 
      10              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      11              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      13              : for more details.
      14              : 
      15              : You should have received a copy of the GNU General Public License
      16              : along with GCC; see the file COPYING3.  If not see
      17              : <http://www.gnu.org/licenses/>.  */
      18              : 
      19              : #include "config.h"
      20              : #include "system.h"
      21              : #include "coretypes.h"
      22              : 
      23              : #define GCC_C_COMMON_C
      24              : #include "options.h"  /* For cpp_reason_option_codes. */
      25              : #undef GCC_C_COMMON_C
      26              : 
      27              : #include "target.h"
      28              : #include "gfortran.h"
      29              : #include "diagnostic.h"
      30              : 
      31              : #include "toplev.h"
      32              : 
      33              : #include "../../libcpp/internal.h"
      34              : #include "cpp.h"
      35              : #include "incpath.h"
      36              : #include "cppbuiltin.h"
      37              : #include "mkdeps.h"
      38              : 
      39              : #ifndef TARGET_SYSTEM_ROOT
      40              : # define TARGET_SYSTEM_ROOT NULL
      41              : #endif
      42              : 
      43              : #ifndef TARGET_CPU_CPP_BUILTINS
      44              : # define TARGET_CPU_CPP_BUILTINS()
      45              : #endif
      46              : 
      47              : #ifndef TARGET_OS_CPP_BUILTINS
      48              : # define TARGET_OS_CPP_BUILTINS()
      49              : #endif
      50              : 
      51              : #ifndef TARGET_OBJFMT_CPP_BUILTINS
      52              : # define TARGET_OBJFMT_CPP_BUILTINS()
      53              : #endif
      54              : 
      55              : 
      56              : /* Holds switches parsed by gfc_cpp_handle_option (), but whose
      57              :    handling is deferred to gfc_cpp_init ().  */
      58              : typedef struct
      59              : {
      60              :     enum opt_code code;
      61              :     const char *arg;
      62              : }
      63              : gfc_cpp_deferred_opt_t;
      64              : 
      65              : 
      66              : /* Defined and undefined macros being queued for output with -dU at
      67              :    the next newline.  */
      68              : typedef struct gfc_cpp_macro_queue
      69              : {
      70              :   struct gfc_cpp_macro_queue *next;     /* Next macro in the list.  */
      71              :   char *macro;                          /* The name of the macro if not
      72              :                                            defined, the full definition if
      73              :                                            defined.  */
      74              : } gfc_cpp_macro_queue;
      75              : static gfc_cpp_macro_queue *cpp_define_queue, *cpp_undefine_queue;
      76              : 
      77              : struct gfc_cpp_option_data
      78              : {
      79              :   /* Argument of -cpp, implied by SPEC;
      80              :      if NULL, preprocessing disabled.  */
      81              :   const char *temporary_filename;
      82              : 
      83              :   const char *output_filename;          /* -o <arg>  */
      84              :   int preprocess_only;                  /* -E  */
      85              :   int discard_comments;                 /* -C  */
      86              :   int discard_comments_in_macro_exp;    /* -CC  */
      87              :   int print_include_names;              /* -H  */
      88              :   int no_line_commands;                 /* -P  */
      89              :   char dump_macros;                     /* -d[DMNU]  */
      90              :   int dump_includes;                    /* -dI  */
      91              :   int working_directory;                /* -fworking-directory  */
      92              :   int no_predefined;                    /* -undef */
      93              :   int standard_include_paths;           /* -nostdinc */
      94              :   int verbose;                          /* -v */
      95              :   int deps;                             /* -M */
      96              :   int deps_skip_system;                 /* -MM */
      97              :   const char *deps_filename;            /* -M[M]D */
      98              :   const char *deps_filename_user;       /* -MF <arg> */
      99              :   const char *deps_target_filename;     /* -MT / -MQ <arg> */
     100              :   bool quote_deps_target_filename;      /* -MQ */
     101              :   int deps_missing_are_generated;       /* -MG */
     102              :   int deps_phony;                       /* -MP */
     103              :   int warn_date_time;                   /* -Wdate-time */
     104              : 
     105              :   const char *multilib;                 /* -imultilib <dir>  */
     106              :   const char *prefix;                   /* -iprefix <dir>  */
     107              :   const char *sysroot;                  /* -isysroot <dir>  */
     108              : 
     109              :   /* Options whose handling needs to be deferred until the
     110              :      appropriate cpp-objects are created:
     111              :       -A predicate=answer
     112              :       -D <macro>[=<val>]
     113              :       -U <macro>  */
     114              :   gfc_cpp_deferred_opt_t *deferred_opt;
     115              :   int deferred_opt_count;
     116              : }
     117              : gfc_cpp_option;
     118              : 
     119              : /* Structures used with libcpp:  */
     120              : static cpp_options *cpp_option = NULL;
     121              : static cpp_reader *cpp_in = NULL;
     122              : 
     123              : /* Encapsulates state used to convert a stream of cpp-tokens into
     124              :    a text file.  */
     125              : static struct
     126              : {
     127              :   FILE *outf;                   /* Stream to write to.  */
     128              :   const cpp_token *prev;        /* Previous token.  */
     129              :   const cpp_token *source;      /* Source token for spacing.  */
     130              :   int src_line;                 /* Line number currently being written.  */
     131              :   unsigned char printed;        /* Nonzero if something output at line.  */
     132              :   bool first_time;              /* cb_file_change hasn't been called yet.  */
     133              : } print;
     134              : 
     135              : /* General output routines.  */
     136              : static void scan_translation_unit (cpp_reader *);
     137              : static void scan_translation_unit_trad (cpp_reader *);
     138              : 
     139              : /* Callback routines for the parser. Most of these are active only
     140              :    in specific modes.  */
     141              : static void cb_file_change (cpp_reader *, const line_map_ordinary *);
     142              : static void cb_line_change (cpp_reader *, const cpp_token *, int);
     143              : static void cb_define (cpp_reader *, location_t, cpp_hashnode *);
     144              : static void cb_undef (cpp_reader *, location_t, cpp_hashnode *);
     145              : static void cb_def_pragma (cpp_reader *, location_t);
     146              : static void cb_include (cpp_reader *, location_t, const unsigned char *,
     147              :                         const char *, int, const cpp_token **);
     148              : static void cb_ident (cpp_reader *, location_t, const cpp_string *);
     149              : static void cb_used_define (cpp_reader *, location_t, cpp_hashnode *);
     150              : static void cb_used_undef (cpp_reader *, location_t, cpp_hashnode *);
     151              : static bool cb_cpp_diagnostic (cpp_reader *, enum cpp_diagnostic_level,
     152              :                                enum cpp_warning_reason, rich_location *,
     153              :                                const char *, va_list *)
     154              :      ATTRIBUTE_GCC_DIAG(5,0);
     155              : void pp_dir_change (cpp_reader *, const char *);
     156              : 
     157              : static int dump_macro (cpp_reader *, cpp_hashnode *, void *);
     158              : static void dump_queued_macros (cpp_reader *);
     159              : 
     160              : 
     161              : static void
     162         1153 : cpp_define_builtins (cpp_reader *pfile)
     163              : {
     164              :   /* Initialize CPP built-ins; '1' corresponds to 'flag_hosted'
     165              :      in C, defines __STDC_HOSTED__?!  */
     166         1153 :   cpp_init_builtins (pfile, 0);
     167              : 
     168              :   /* Initialize GFORTRAN specific builtins.
     169              :      These are documented.  */
     170         1153 :   define_language_independent_builtin_macros (pfile);
     171         1153 :   cpp_define (pfile, "__GFORTRAN__=1");
     172         1153 :   cpp_define (pfile, "_LANGUAGE_FORTRAN=1");
     173              : 
     174         1153 :   if (flag_openacc)
     175          121 :     cpp_define (pfile, "_OPENACC=201711");
     176              : 
     177         1153 :   if (flag_openmp)
     178           65 :     cpp_define (pfile, "_OPENMP=202111");
     179              : 
     180              :   /* The defines below are necessary for the TARGET_* macros.
     181              : 
     182              :      FIXME:  Note that builtin_define_std() actually is a function
     183              :      in c-cppbuiltin.cc which uses flags undefined for Fortran.
     184              :      Let's skip this for now. If needed, one needs to look into it
     185              :      once more.  */
     186              : 
     187              : # define builtin_define(TXT) cpp_define (pfile, TXT)
     188              : # define builtin_define_std(TXT)
     189              : # define builtin_assert(TXT) cpp_assert (pfile, TXT)
     190              : 
     191              :   /* FIXME: Pandora's Box
     192              :     Using the macros below results in multiple breakages:
     193              :      - mingw will fail to compile this file as dependent macros
     194              :        assume to be used in c-cppbuiltin.cc only. Further, they use
     195              :        flags only valid/defined in C (same as noted above).
     196              :        [config/i386/mingw32.h, config/i386/cygming.h]
     197              :      - other platforms (not as popular) break similarly
     198              :        [grep for 'builtin_define_with_int_value' in gcc/config/]
     199              : 
     200              :   TARGET_CPU_CPP_BUILTINS ();
     201              :   TARGET_OS_CPP_BUILTINS ();
     202              :   TARGET_OBJFMT_CPP_BUILTINS (); */
     203              : 
     204              : #undef builtin_define
     205              : #undef builtin_define_std
     206              : #undef builtin_assert
     207         1153 : }
     208              : 
     209              : bool
     210       220287 : gfc_cpp_enabled (void)
     211              : {
     212       220287 :   return gfc_cpp_option.temporary_filename != NULL;
     213              : }
     214              : 
     215              : bool
     216        66084 : gfc_cpp_preprocess_only (void)
     217              : {
     218        66084 :   return gfc_cpp_option.preprocess_only;
     219              : }
     220              : 
     221              : bool
     222        86978 : gfc_cpp_makedep (void)
     223              : {
     224        86978 :   return gfc_cpp_option.deps;
     225              : }
     226              : 
     227              : void
     228            0 : gfc_cpp_add_dep (const char *name, bool system)
     229              : {
     230            0 :   if (!gfc_cpp_option.deps_skip_system || !system)
     231            0 :     if (mkdeps *deps = cpp_get_deps (cpp_in))
     232            0 :       deps_add_dep (deps, name);
     233            0 : }
     234              : 
     235              : void
     236            0 : gfc_cpp_add_target (const char *name)
     237              : {
     238            0 :   if (mkdeps *deps = cpp_get_deps (cpp_in))
     239            0 :     deps_add_target (deps, name, 0);
     240            0 : }
     241              : 
     242              : 
     243              : const char *
     244         1140 : gfc_cpp_temporary_file (void)
     245              : {
     246         1140 :   return gfc_cpp_option.temporary_filename;
     247              : }
     248              : 
     249              : static void
     250         1155 : gfc_cpp_register_include_paths (bool verbose_missing_dir_warn)
     251              : {
     252         1155 :   int cxx_stdinc = 0;
     253         2310 :   cpp_get_options (cpp_in)->warn_missing_include_dirs
     254         2310 :     = (global_options.x_cpp_warn_missing_include_dirs
     255         1155 :        && verbose_missing_dir_warn);
     256         1155 :   register_include_chains (cpp_in, gfc_cpp_option.sysroot,
     257              :                            gfc_cpp_option.prefix, gfc_cpp_option.multilib,
     258              :                            gfc_cpp_option.standard_include_paths, cxx_stdinc,
     259              :                            gfc_cpp_option.verbose);
     260         1155 : }
     261              : 
     262              : void
     263        31307 : gfc_cpp_init_options (unsigned int decoded_options_count,
     264              :                       struct cl_decoded_option *decoded_options ATTRIBUTE_UNUSED)
     265              : {
     266              :   /* Do not create any objects from libcpp here. If no
     267              :      preprocessing is requested, this would be wasted
     268              :      time and effort.
     269              : 
     270              :      See gfc_cpp_post_options() instead.  */
     271              : 
     272        31307 :   gfc_cpp_option.temporary_filename = NULL;
     273        31307 :   gfc_cpp_option.output_filename = NULL;
     274        31307 :   gfc_cpp_option.preprocess_only = 0;
     275        31307 :   gfc_cpp_option.discard_comments = 1;
     276        31307 :   gfc_cpp_option.discard_comments_in_macro_exp = 1;
     277        31307 :   gfc_cpp_option.print_include_names = 0;
     278        31307 :   gfc_cpp_option.no_line_commands = 0;
     279        31307 :   gfc_cpp_option.dump_macros = '\0';
     280        31307 :   gfc_cpp_option.dump_includes = 0;
     281        31307 :   gfc_cpp_option.working_directory = -1;
     282        31307 :   gfc_cpp_option.no_predefined = 0;
     283        31307 :   gfc_cpp_option.standard_include_paths = 1;
     284        31307 :   gfc_cpp_option.verbose = 0;
     285        31307 :   gfc_cpp_option.warn_date_time = 0;
     286        31307 :   gfc_cpp_option.deps = 0;
     287        31307 :   gfc_cpp_option.deps_skip_system = 0;
     288        31307 :   gfc_cpp_option.deps_phony = 0;
     289        31307 :   gfc_cpp_option.deps_missing_are_generated = 0;
     290        31307 :   gfc_cpp_option.deps_filename = NULL;
     291        31307 :   gfc_cpp_option.deps_filename_user = NULL;
     292        31307 :   gfc_cpp_option.deps_target_filename = NULL;
     293        31307 :   gfc_cpp_option.quote_deps_target_filename = false;
     294              : 
     295        31307 :   gfc_cpp_option.multilib = NULL;
     296        31307 :   gfc_cpp_option.prefix = NULL;
     297        31307 :   gfc_cpp_option.sysroot = TARGET_SYSTEM_ROOT;
     298              : 
     299        31307 :   gfc_cpp_option.deferred_opt = XNEWVEC (gfc_cpp_deferred_opt_t,
     300              :                                          decoded_options_count);
     301        31307 :   gfc_cpp_option.deferred_opt_count = 0;
     302        31307 : }
     303              : 
     304              : bool
     305       209804 : gfc_cpp_handle_option (size_t scode, const char *arg, int value ATTRIBUTE_UNUSED)
     306              : {
     307       209804 :   bool result = true;
     308       209804 :   enum opt_code code = (enum opt_code) scode;
     309              : 
     310       209804 :   switch (code)
     311              :   {
     312              :     default:
     313              :       result = false;
     314              :       break;
     315              : 
     316         1155 :     case OPT_cpp_:
     317         1155 :       gfc_cpp_option.temporary_filename = arg;
     318         1155 :       break;
     319              : 
     320            0 :     case OPT_nocpp:
     321            0 :       gfc_cpp_option.temporary_filename = 0L;
     322            0 :       break;
     323              : 
     324              :     case OPT_d:
     325           14 :       for ( ; *arg; ++arg)
     326            7 :         switch (*arg)
     327              :         {
     328            0 :           case 'D':
     329            0 :           case 'M':
     330            0 :           case 'N':
     331            0 :           case 'U':
     332            0 :             gfc_cpp_option.dump_macros = *arg;
     333            0 :             break;
     334              : 
     335            0 :           case 'I':
     336            0 :             gfc_cpp_option.dump_includes = 1;
     337            0 :             break;
     338              :         }
     339              :       break;
     340              : 
     341            0 :     case OPT_fworking_directory:
     342            0 :       gfc_cpp_option.working_directory = value;
     343            0 :       break;
     344              : 
     345            3 :     case OPT_idirafter:
     346            3 :       gfc_cpp_add_include_path_after (xstrdup(arg), true);
     347            3 :       break;
     348              : 
     349          347 :     case OPT_imultilib:
     350          347 :       gfc_cpp_option.multilib = arg;
     351          347 :       break;
     352              : 
     353         1155 :     case OPT_iprefix:
     354         1155 :       gfc_cpp_option.prefix = arg;
     355         1155 :       break;
     356              : 
     357            0 :     case OPT_isysroot:
     358            0 :       gfc_cpp_option.sysroot = arg;
     359            0 :       break;
     360              : 
     361         4909 :     case OPT_iquote:
     362         4909 :     case OPT_isystem:
     363         4909 :       gfc_cpp_add_include_path (xstrdup(arg), true);
     364         4909 :       break;
     365              : 
     366            0 :     case OPT_nostdinc:
     367            0 :       gfc_cpp_option.standard_include_paths = value;
     368            0 :       break;
     369              : 
     370        31307 :     case OPT_o:
     371        31307 :       if (!gfc_cpp_option.output_filename)
     372        31307 :         gfc_cpp_option.output_filename = arg;
     373              :       else
     374            0 :         gfc_fatal_error ("output filename specified twice");
     375        31307 :       break;
     376              : 
     377            0 :     case OPT_undef:
     378            0 :       gfc_cpp_option.no_predefined = value;
     379            0 :       break;
     380              : 
     381            0 :     case OPT_v:
     382            0 :       gfc_cpp_option.verbose = value;
     383            0 :       break;
     384              : 
     385            1 :     case OPT_Wdate_time:
     386            1 :       gfc_cpp_option.warn_date_time = value;
     387            1 :       break;
     388              : 
     389         1144 :     case OPT_A:
     390         1144 :     case OPT_D:
     391         1144 :     case OPT_U:
     392         1144 :       gfc_cpp_option.deferred_opt[gfc_cpp_option.deferred_opt_count].code = code;
     393         1144 :       gfc_cpp_option.deferred_opt[gfc_cpp_option.deferred_opt_count].arg = arg;
     394         1144 :       gfc_cpp_option.deferred_opt_count++;
     395         1144 :       break;
     396              : 
     397            0 :     case OPT_C:
     398            0 :       gfc_cpp_option.discard_comments = 0;
     399            0 :       break;
     400              : 
     401            0 :     case OPT_CC:
     402            0 :       gfc_cpp_option.discard_comments = 0;
     403            0 :       gfc_cpp_option.discard_comments_in_macro_exp = 0;
     404            0 :       break;
     405              : 
     406           14 :     case OPT_E:
     407           14 :       gfc_cpp_option.preprocess_only = 1;
     408           14 :       break;
     409              : 
     410            0 :     case OPT_H:
     411            0 :       gfc_cpp_option.print_include_names = 1;
     412            0 :       break;
     413              : 
     414            0 :     case OPT_MM:
     415            0 :       gfc_cpp_option.deps_skip_system = 1;
     416              :       /* fall through */
     417              : 
     418            1 :     case OPT_M:
     419            1 :       gfc_cpp_option.deps = 1;
     420            1 :       break;
     421              : 
     422            0 :     case OPT_MMD:
     423            0 :       gfc_cpp_option.deps_skip_system = 1;
     424              :       /* fall through */
     425              : 
     426            0 :     case OPT_MD:
     427            0 :       gfc_cpp_option.deps = 1;
     428            0 :       gfc_cpp_option.deps_filename = arg;
     429            0 :       break;
     430              : 
     431            1 :     case OPT_MF:
     432              :       /* If specified multiple times, last one wins.  */
     433            1 :       gfc_cpp_option.deps_filename_user = arg;
     434            1 :       break;
     435              : 
     436            0 :     case OPT_MG:
     437            0 :       gfc_cpp_option.deps_missing_are_generated = 1;
     438            0 :       break;
     439              : 
     440            0 :     case OPT_MP:
     441            0 :       gfc_cpp_option.deps_phony = 1;
     442            0 :       break;
     443              : 
     444            1 :     case OPT_MQ:
     445            1 :     case OPT_MT:
     446            1 :       gfc_cpp_option.quote_deps_target_filename = (code == OPT_MQ);
     447            1 :       gfc_cpp_option.deps_target_filename = arg;
     448            1 :       break;
     449              : 
     450            0 :     case OPT_P:
     451            0 :       gfc_cpp_option.no_line_commands = 1;
     452            0 :       break;
     453              :   }
     454              : 
     455       209804 :   return result;
     456              : }
     457              : 
     458              : /* This function needs to be called before gfc_cpp_register_include_paths
     459              :    as the latter may diagnose missing include directories.  */
     460              : static void
     461         1155 : gfc_cpp_init_cb (void)
     462              : {
     463         1155 :   struct cpp_callbacks *cb;
     464              : 
     465         1155 :   cb = cpp_get_callbacks (cpp_in);
     466         1155 :   cb->file_change = cb_file_change;
     467         1155 :   cb->line_change = cb_line_change;
     468         1155 :   cb->ident = cb_ident;
     469         1155 :   cb->def_pragma = cb_def_pragma;
     470         1155 :   cb->diagnostic = cb_cpp_diagnostic;
     471              : 
     472         1155 :   if (gfc_cpp_option.dump_includes)
     473            0 :     cb->include = cb_include;
     474              : 
     475         1155 :   if ((gfc_cpp_option.dump_macros == 'D')
     476         1155 :       || (gfc_cpp_option.dump_macros == 'N'))
     477              :     {
     478            0 :       cb->define = cb_define;
     479            0 :       cb->undef  = cb_undef;
     480              :     }
     481              : 
     482         1155 :   if (gfc_cpp_option.dump_macros == 'U')
     483              :     {
     484            0 :       cb->before_define = dump_queued_macros;
     485            0 :       cb->used_define = cb_used_define;
     486            0 :       cb->used_undef = cb_used_undef;
     487              :     }
     488         1155 : }
     489              : 
     490              : void
     491        31306 : gfc_cpp_post_options (bool verbose_missing_dir_warn)
     492              : {
     493              :   /* Any preprocessing-related option without '-cpp' is considered
     494              :      an error.  */
     495        31306 :   if (!gfc_cpp_enabled ()
     496        31306 :       && (gfc_cpp_preprocess_only ()
     497        30151 :           || gfc_cpp_makedep ()
     498        30151 :           || !gfc_cpp_option.discard_comments
     499        30151 :           || !gfc_cpp_option.discard_comments_in_macro_exp
     500        30151 :           || gfc_cpp_option.print_include_names
     501        30151 :           || gfc_cpp_option.no_line_commands
     502        30151 :           || gfc_cpp_option.dump_macros
     503        30151 :           || gfc_cpp_option.dump_includes))
     504            0 :     gfc_fatal_error ("To enable preprocessing, use %<-cpp%>");
     505              : 
     506        31306 :   if (!gfc_cpp_enabled ())
     507              :     return;
     508              : 
     509         1155 :   cpp_in = cpp_create_reader (CLK_GNUC89, NULL, line_table);
     510         1155 :   gcc_assert (cpp_in);
     511              : 
     512              :   /* The cpp_options-structure defines far more flags than those set here.
     513              :      If any other is implemented, see c-opt.c (sanitize_cpp_opts) for
     514              :      inter-option dependencies that may need to be enforced.  */
     515         1155 :   cpp_option = cpp_get_options (cpp_in);
     516         1155 :   gcc_assert (cpp_option);
     517              : 
     518              :   /* TODO: allow non-traditional modes, e.g. by -cpp-std=...?  */
     519         1155 :   cpp_option->traditional = 1;
     520         1155 :   cpp_option->cplusplus_comments = 0;
     521              : 
     522         1155 :   cpp_option->cpp_pedantic = pedantic;
     523              : 
     524         1155 :   cpp_option->dollars_in_ident = flag_dollar_ok;
     525         1155 :   cpp_option->discard_comments = gfc_cpp_option.discard_comments;
     526         1155 :   cpp_option->discard_comments_in_macro_exp = gfc_cpp_option.discard_comments_in_macro_exp;
     527         1155 :   cpp_option->print_include_names = gfc_cpp_option.print_include_names;
     528         1155 :   cpp_option->preprocessed = gfc_option.flag_preprocessed;
     529         1155 :   cpp_option->warn_date_time = gfc_cpp_option.warn_date_time;
     530              : 
     531         1155 :   if (gfc_cpp_makedep ())
     532              :     {
     533            1 :       cpp_option->deps.style = DEPS_USER;
     534            1 :       cpp_option->deps.phony_targets = gfc_cpp_option.deps_phony;
     535            1 :       cpp_option->deps.missing_files = gfc_cpp_option.deps_missing_are_generated;
     536              : 
     537              :       /* -MF <arg> overrides -M[M]D.  */
     538            1 :       if (gfc_cpp_option.deps_filename_user)
     539            1 :         gfc_cpp_option.deps_filename = gfc_cpp_option.deps_filename_user;
     540              :   }
     541              : 
     542         1155 :   if (gfc_cpp_option.working_directory == -1)
     543         1155 :     gfc_cpp_option.working_directory = (debug_info_level != DINFO_LEVEL_NONE);
     544              : 
     545         1155 :   cpp_post_options (cpp_in);
     546              : 
     547              : 
     548              :   /* Let diagnostics infrastructure know how to convert input files the same
     549              :      way libcpp will do it, namely, with no charset conversion but with
     550              :      skipping of a UTF-8 BOM if present.  */
     551         1155 :   diagnostic_initialize_input_context (global_dc, nullptr, true);
     552         1155 :   gfc_cpp_init_cb ();
     553              : 
     554         1155 :   gfc_cpp_register_include_paths (verbose_missing_dir_warn);
     555              : }
     556              : 
     557              : 
     558              : void
     559         1153 : gfc_cpp_init_0 (void)
     560              : {
     561              :   /* Initialize the print structure.  Setting print.src_line to -1 here is
     562              :      a trick to guarantee that the first token of the file will cause
     563              :      a linemarker to be output by maybe_print_line.  */
     564         1153 :   print.src_line = -1;
     565         1153 :   print.printed = 0;
     566         1153 :   print.prev = 0;
     567         1153 :   print.first_time = 1;
     568              : 
     569         1153 :   if (gfc_cpp_preprocess_only ())
     570              :     {
     571           13 :       if (gfc_cpp_option.output_filename)
     572              :         {
     573              :           /* This needs cheating: with "-E -o <file>", the user wants the
     574              :              preprocessed output in <file>. However, if nothing is done
     575              :              about it <file> is also used for assembler output. Hence, it
     576              :              is necessary to redirect assembler output (actually nothing
     577              :              as -E implies -fsyntax-only) to another file, otherwise the
     578              :              output from preprocessing is lost.  */
     579           13 :           asm_file_name = gfc_cpp_option.temporary_filename;
     580              : 
     581           13 :           print.outf = fopen (gfc_cpp_option.output_filename, "w");
     582           13 :           if (print.outf == NULL)
     583            0 :             gfc_fatal_error ("opening output file %qs: %s",
     584              :                              gfc_cpp_option.output_filename,
     585            0 :                              xstrerror (errno));
     586              :         }
     587              :       else
     588            0 :         print.outf = stdout;
     589              :     }
     590              :   else
     591              :     {
     592         1140 :       print.outf = fopen (gfc_cpp_option.temporary_filename, "w");
     593         1140 :       if (print.outf == NULL)
     594            0 :         gfc_fatal_error ("opening output file %qs: %s",
     595            0 :                          gfc_cpp_option.temporary_filename, xstrerror (errno));
     596              :     }
     597              : 
     598         1153 :   gcc_assert(cpp_in);
     599              : 
     600         1153 :   if (gfc_cpp_option.deps_target_filename)
     601            1 :     if (mkdeps *deps = cpp_get_deps (cpp_in))
     602            1 :       deps_add_target (deps, gfc_cpp_option.deps_target_filename,
     603            1 :                        gfc_cpp_option.quote_deps_target_filename);
     604              : 
     605         1153 :   if (!cpp_read_main_file (cpp_in, gfc_source_file))
     606            0 :     errorcount++;
     607         1153 : }
     608              : 
     609              : void
     610         1153 : gfc_cpp_init (void)
     611              : {
     612         1153 :   int i;
     613              : 
     614         1153 :   if (gfc_option.flag_preprocessed)
     615              :     return;
     616              : 
     617         1153 :   cpp_change_file (cpp_in, LC_RENAME, special_fname_builtin ());
     618         1153 :   if (!gfc_cpp_option.no_predefined)
     619              :     {
     620              :       /* Make sure all of the builtins about to be declared have
     621              :         BUILTINS_LOCATION has their location_t.  */
     622         1153 :       cpp_force_token_locations (cpp_in, BUILTINS_LOCATION);
     623              : 
     624         1153 :       cpp_define_builtins (cpp_in);
     625              : 
     626         1153 :       cpp_stop_forcing_token_locations (cpp_in);
     627              :     }
     628              : 
     629              :   /* Handle deferred options from command-line.  */
     630         1153 :   cpp_change_file (cpp_in, LC_RENAME, _("<command-line>"));
     631              : 
     632         2297 :   for (i = 0; i < gfc_cpp_option.deferred_opt_count; i++)
     633              :     {
     634         1144 :       gfc_cpp_deferred_opt_t *opt = &gfc_cpp_option.deferred_opt[i];
     635              : 
     636         1144 :       if (opt->code == OPT_D)
     637         1144 :         cpp_define (cpp_in, opt->arg);
     638            0 :       else if (opt->code == OPT_U)
     639            0 :         cpp_undef (cpp_in, opt->arg);
     640            0 :       else if (opt->code == OPT_A)
     641              :         {
     642            0 :           if (opt->arg[0] == '-')
     643            0 :             cpp_unassert (cpp_in, opt->arg + 1);
     644              :           else
     645            0 :             cpp_assert (cpp_in, opt->arg);
     646              :         }
     647              :     }
     648              : 
     649              :   /* Pre-defined macros for non-required INTEGER kind types.  */
     650         6571 :   for (gfc_integer_info *itype = gfc_integer_kinds; itype->kind != 0; itype++)
     651              :     {
     652         5418 :       if (itype->kind == 1)
     653         1153 :         cpp_define (cpp_in, "__GFC_INT_1__=1");
     654         5418 :       if (itype->kind == 2)
     655         1153 :         cpp_define (cpp_in, "__GFC_INT_2__=1");
     656         5418 :       if (itype->kind == 8)
     657         1153 :         cpp_define (cpp_in, "__GFC_INT_8__=1");
     658         5418 :       if (itype->kind == 16)
     659          806 :         cpp_define (cpp_in, "__GFC_INT_16__=1");
     660              :     }
     661              : 
     662              :   /* Pre-defined macros for non-required REAL kind types.  */
     663         5765 :   for (gfc_real_info *rtype = gfc_real_kinds; rtype->kind != 0; rtype++)
     664              :     {
     665         4612 :       if (rtype->kind == 10)
     666         1153 :         cpp_define (cpp_in, "__GFC_REAL_10__=1");
     667         4612 :       if (rtype->kind == 16)
     668         1153 :         cpp_define (cpp_in, "__GFC_REAL_16__=1");
     669              :     }
     670              : 
     671         1153 :   if (gfc_cpp_option.working_directory
     672          772 :       && gfc_cpp_option.preprocess_only && !gfc_cpp_option.no_line_commands)
     673            0 :     pp_dir_change (cpp_in, get_src_pwd ());
     674              : }
     675              : 
     676              : bool
     677         1155 : gfc_cpp_preprocess (const char *source_file)
     678              : {
     679         1155 :   if (!gfc_cpp_enabled ())
     680              :     return false;
     681              : 
     682         1155 :   if (gfc_option.flag_preprocessed)
     683              :     {
     684            2 :       if (gfc_cpp_preprocess_only ())
     685            1 :         gfc_fatal_error ("%<-E%> is not supported with %<-fpreprocessed%>");
     686              :       return false;
     687              :     }
     688              : 
     689         1153 :   cpp_change_file (cpp_in, LC_RENAME, source_file);
     690              : 
     691         1153 :   if (cpp_option->traditional)
     692         1153 :     scan_translation_unit_trad (cpp_in);
     693              :   else
     694            0 :     scan_translation_unit (cpp_in);
     695              : 
     696              :   /* -dM command line option.  */
     697         1153 :   if (gfc_cpp_preprocess_only () &&
     698           13 :       gfc_cpp_option.dump_macros == 'M')
     699              :     {
     700            0 :       putc ('\n', print.outf);
     701            0 :       cpp_forall_identifiers (cpp_in, dump_macro, NULL);
     702              :     }
     703              : 
     704         1153 :   putc ('\n', print.outf);
     705              : 
     706         1153 :   if (!gfc_cpp_preprocess_only ()
     707         1153 :       || (gfc_cpp_preprocess_only () && gfc_cpp_option.output_filename))
     708         1153 :     fclose (print.outf);
     709              : 
     710              :   return true;
     711              : }
     712              : 
     713              : void
     714        31287 : gfc_cpp_done (void)
     715              : {
     716        31287 :   if (!gfc_cpp_enabled ())
     717              :     return;
     718              : 
     719         1154 :   gcc_assert (cpp_in);
     720              : 
     721         1154 :   if (gfc_cpp_makedep ())
     722              :     {
     723            1 :       if (gfc_cpp_option.deps_filename)
     724              :         {
     725            1 :           FILE *f = fopen (gfc_cpp_option.deps_filename, "w");
     726            1 :           if (f)
     727              :             {
     728            1 :               cpp_finish (cpp_in, f);
     729            1 :               fclose (f);
     730              :             }
     731              :           else
     732            0 :             gfc_fatal_error ("opening output file %qs: %s",
     733              :                              gfc_cpp_option.deps_filename,
     734            0 :                              xstrerror (errno));
     735              :         }
     736              :       else
     737            0 :         cpp_finish (cpp_in, stdout);
     738              :     }
     739              : 
     740         1154 :   cpp_undef_all (cpp_in);
     741         1154 :   cpp_clear_file_cache (cpp_in);
     742              : }
     743              : 
     744              : /* PATH must be malloc-ed and NULL-terminated.  */
     745              : void
     746        58138 : gfc_cpp_add_include_path (char *path, bool user_supplied)
     747              : {
     748              :   /* CHAIN sets cpp_dir->sysp which differs from 0 if PATH is a system
     749              :      include path. Fortran does not define any system include paths.  */
     750        58138 :   int cxx_aware = 0;
     751              : 
     752        58138 :   add_path (path, INC_BRACKET, cxx_aware, user_supplied);
     753        58138 : }
     754              : 
     755              : void
     756            3 : gfc_cpp_add_include_path_after (char *path, bool user_supplied)
     757              : {
     758            3 :   int cxx_aware = 0;
     759            3 :   add_path (path, INC_AFTER, cxx_aware, user_supplied);
     760            3 : }
     761              : 
     762              : 
     763              : static void scan_translation_unit_trad (cpp_reader *);
     764              : static void account_for_newlines (const unsigned char *, size_t);
     765              : 
     766              : static void print_line (location_t, const char *);
     767              : static void maybe_print_line (location_t);
     768              : 
     769              : 
     770              : /* Writes out the preprocessed file, handling spacing and paste
     771              :    avoidance issues.  */
     772              : static void
     773            0 : scan_translation_unit (cpp_reader *pfile)
     774              : {
     775            0 :   bool avoid_paste = false;
     776              : 
     777            0 :   print.source = NULL;
     778            0 :   for (;;)
     779              :     {
     780            0 :       const cpp_token *token = cpp_get_token (pfile);
     781              : 
     782            0 :       if (token->type == CPP_PADDING)
     783              :         {
     784            0 :           avoid_paste = true;
     785            0 :           if (print.source == NULL
     786            0 :               || (!(print.source->flags & PREV_WHITE)
     787            0 :                   && token->val.source == NULL))
     788            0 :             print.source = token->val.source;
     789            0 :           continue;
     790              :         }
     791              : 
     792            0 :       if (token->type == CPP_EOF)
     793              :         break;
     794              : 
     795              :       /* Subtle logic to output a space if and only if necessary.  */
     796            0 :       if (avoid_paste)
     797              :         {
     798            0 :           if (print.source == NULL)
     799            0 :             print.source = token;
     800            0 :           if (print.source->flags & PREV_WHITE
     801            0 :               || (print.prev
     802            0 :                   && cpp_avoid_paste (pfile, print.prev, token))
     803            0 :               || (print.prev == NULL && token->type == CPP_HASH))
     804            0 :             putc (' ', print.outf);
     805              :         }
     806            0 :       else if (token->flags & PREV_WHITE)
     807            0 :         putc (' ', print.outf);
     808              : 
     809            0 :       avoid_paste = false;
     810            0 :       print.source = NULL;
     811            0 :       print.prev = token;
     812            0 :       cpp_output_token (token, print.outf);
     813              : 
     814            0 :       if (token->type == CPP_COMMENT)
     815            0 :         account_for_newlines (token->val.str.text, token->val.str.len);
     816              :     }
     817            0 : }
     818              : 
     819              : /* Adjust print.src_line for newlines embedded in output.  */
     820              : static void
     821            0 : account_for_newlines (const unsigned char *str, size_t len)
     822              : {
     823            0 :   while (len--)
     824            0 :     if (*str++ == '\n')
     825            0 :       print.src_line++;
     826            0 : }
     827              : 
     828              : /* Writes out a traditionally preprocessed file.  */
     829              : static void
     830         1153 : scan_translation_unit_trad (cpp_reader *pfile)
     831              : {
     832       701857 :   while (_cpp_read_logical_line_trad (pfile))
     833              :     {
     834       699551 :       size_t len = pfile->out.cur - pfile->out.base;
     835       699551 :       maybe_print_line (pfile->out.first_line);
     836       699551 :       fwrite (pfile->out.base, 1, len, print.outf);
     837       699551 :       print.printed = 1;
     838       699551 :       if (!CPP_OPTION (pfile, discard_comments))
     839            0 :         account_for_newlines (pfile->out.base, len);
     840              :     }
     841         1153 : }
     842              : 
     843              : /* If the token read on logical line LINE needs to be output on a
     844              :    different line to the current one, output the required newlines or
     845              :    a line marker.  */
     846              : static void
     847       701665 : maybe_print_line (location_t src_loc)
     848              : {
     849       701665 :   const line_map_ordinary *map
     850       701665 :     = linemap_check_ordinary (linemap_lookup (line_table, src_loc));
     851       701665 :   int src_line = SOURCE_LINE (map, src_loc);
     852              : 
     853              :   /* End the previous line of text.  */
     854       701665 :   if (print.printed)
     855              :     {
     856       697699 :       putc ('\n', print.outf);
     857       697699 :       print.src_line++;
     858       697699 :       print.printed = 0;
     859              :     }
     860              : 
     861       701665 :   if (src_line >= print.src_line && src_line < print.src_line + 8)
     862              :     {
     863       965256 :       while (src_line > print.src_line)
     864              :         {
     865       263679 :           putc ('\n', print.outf);
     866       263679 :           print.src_line++;
     867              :         }
     868              :     }
     869              :   else
     870           88 :     print_line (src_loc, "");
     871       701665 : }
     872              : 
     873              : /* Output a line marker for logical line LINE.  Special flags are "1"
     874              :    or "2" indicating entering or leaving a file.  */
     875              : static void
     876         8928 : print_line (location_t src_loc, const char *special_flags)
     877              : {
     878              :   /* End any previous line of text.  */
     879         8928 :   if (print.printed)
     880          750 :     putc ('\n', print.outf);
     881         8928 :   print.printed = 0;
     882              : 
     883         8928 :   if (!gfc_cpp_option.no_line_commands)
     884              :     {
     885         8928 :       expanded_location loc;
     886         8928 :       size_t to_file_len;
     887         8928 :       unsigned char *to_file_quoted;
     888         8928 :       unsigned char *p;
     889         8928 :       int sysp;
     890              : 
     891         8928 :       loc = expand_location (src_loc);
     892         8928 :       to_file_len = strlen (loc.file);
     893         8928 :       to_file_quoted = (unsigned char *) alloca (to_file_len * 4 + 1);
     894              : 
     895         8928 :       print.src_line = loc.line;
     896              : 
     897              :       /* cpp_quote_string does not nul-terminate, so we have to do it
     898              :          ourselves.  */
     899         8928 :       p = cpp_quote_string (to_file_quoted,
     900              :                             (const unsigned char *) loc.file, to_file_len);
     901         8928 :       *p = '\0';
     902         8928 :       fprintf (print.outf, "# %u \"%s\"%s",
     903         8928 :                print.src_line == 0 ? 1 : print.src_line,
     904              :                to_file_quoted, special_flags);
     905              : 
     906         8928 :       sysp = in_system_header_at (src_loc);
     907         8928 :       if (sysp == 2)
     908            0 :         fputs (" 3 4", print.outf);
     909         8928 :       else if (sysp == 1)
     910            0 :         fputs (" 3", print.outf);
     911              : 
     912         8928 :       putc ('\n', print.outf);
     913              :     }
     914         8928 : }
     915              : 
     916              : static void
     917         9993 : cb_file_change (cpp_reader * ARG_UNUSED (pfile), const line_map_ordinary *map)
     918              : {
     919         9993 :   const char *flags = "";
     920              : 
     921         9993 :   if (gfc_cpp_option.no_line_commands)
     922              :     return;
     923              : 
     924         9993 :   if (!map)
     925              :     return;
     926              : 
     927         8840 :       if (print.first_time)
     928              :         {
     929              :           /* Avoid printing foo.i when the main file is foo.c.  */
     930         1153 :           if (!cpp_get_options (cpp_in)->preprocessed)
     931         1153 :             print_line (map->start_location, flags);
     932         1153 :           print.first_time = 0;
     933              :         }
     934              :       else
     935              :         {
     936              :           /* Bring current file to correct line when entering a new file.  */
     937         7687 :           if (map->reason == LC_ENTER)
     938         2114 :             maybe_print_line (linemap_included_from (map));
     939         7687 :           if (map->reason == LC_ENTER)
     940              :             flags = " 1";
     941         5573 :           else if (map->reason == LC_LEAVE)
     942         2114 :             flags = " 2";
     943         7687 :           print_line (map->start_location, flags);
     944              :         }
     945              : 
     946              : }
     947              : 
     948              : /* Called when a line of output is started.  TOKEN is the first token
     949              :    of the line, and at end of file will be CPP_EOF.  */
     950              : static void
     951            0 : cb_line_change (cpp_reader *pfile, const cpp_token *token,
     952              :                 int parsing_args)
     953              : {
     954            0 :   location_t src_loc = token->src_loc;
     955              : 
     956            0 :   if (token->type == CPP_EOF || parsing_args)
     957              :     return;
     958              : 
     959            0 :   maybe_print_line (src_loc);
     960            0 :   print.prev = 0;
     961            0 :   print.source = 0;
     962              : 
     963              :   /* Supply enough spaces to put this token in its original column,
     964              :      one space per column greater than 2, since scan_translation_unit
     965              :      will provide a space if PREV_WHITE.  Don't bother trying to
     966              :      reconstruct tabs; we can't get it right in general, and nothing
     967              :      ought to care.  Some things do care; the fault lies with them.  */
     968            0 :   if (!CPP_OPTION (pfile, traditional))
     969              :     {
     970            0 :       const line_map_ordinary *map
     971            0 :         = linemap_check_ordinary (linemap_lookup (line_table, src_loc));
     972            0 :       int spaces = SOURCE_COLUMN (map, src_loc) - 2;
     973            0 :       print.printed = 1;
     974              : 
     975            0 :       while (-- spaces >= 0)
     976            0 :         putc (' ', print.outf);
     977              :     }
     978              : }
     979              : 
     980              : static void
     981            0 : cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED, location_t line,
     982              :           const cpp_string *str)
     983              : {
     984            0 :   maybe_print_line (line);
     985            0 :   fprintf (print.outf, "#ident %s\n", str->text);
     986            0 :   print.src_line++;
     987            0 : }
     988              : 
     989              : static void
     990            0 : cb_define (cpp_reader *pfile ATTRIBUTE_UNUSED, location_t line,
     991              :            cpp_hashnode *node ATTRIBUTE_UNUSED)
     992              : {
     993            0 :   maybe_print_line (line);
     994            0 :   fputs ("#define ", print.outf);
     995              : 
     996              :   /* 'D' is whole definition; 'N' is name only.  */
     997            0 :   if (gfc_cpp_option.dump_macros == 'D')
     998            0 :     fputs ((const char *) cpp_macro_definition (pfile, node),
     999              :            print.outf);
    1000              :   else
    1001            0 :     fputs ((const char *) NODE_NAME (node), print.outf);
    1002              : 
    1003            0 :   putc ('\n', print.outf);
    1004            0 :   if (LOCATION_LINE (line) != 0)
    1005            0 :     print.src_line++;
    1006            0 : }
    1007              : 
    1008              : static void
    1009            0 : cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, location_t line,
    1010              :           cpp_hashnode *node)
    1011              : {
    1012            0 :   maybe_print_line (line);
    1013            0 :   fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
    1014            0 :   print.src_line++;
    1015            0 : }
    1016              : 
    1017              : static void
    1018            0 : cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, location_t line,
    1019              :             const unsigned char *dir, const char *header, int angle_brackets,
    1020              :             const cpp_token **comments)
    1021              : {
    1022            0 :   maybe_print_line (line);
    1023            0 :   if (angle_brackets)
    1024            0 :     fprintf (print.outf, "#%s <%s>", dir, header);
    1025              :   else
    1026            0 :     fprintf (print.outf, "#%s \"%s\"", dir, header);
    1027              : 
    1028            0 :   if (comments != NULL)
    1029              :     {
    1030            0 :       while (*comments != NULL)
    1031              :         {
    1032            0 :           if ((*comments)->flags & PREV_WHITE)
    1033            0 :             putc (' ', print.outf);
    1034            0 :           cpp_output_token (*comments, print.outf);
    1035            0 :           ++comments;
    1036              :         }
    1037              :     }
    1038              : 
    1039            0 :   putc ('\n', print.outf);
    1040            0 :   print.src_line++;
    1041            0 : }
    1042              : 
    1043              : /* Dump out the hash table.  */
    1044              : static int
    1045            0 : dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED)
    1046              : {
    1047            0 :   if (cpp_user_macro_p (node))
    1048              :     {
    1049            0 :       fputs ("#define ", print.outf);
    1050            0 :       fputs ((const char *) cpp_macro_definition (pfile, node),
    1051              :              print.outf);
    1052            0 :       putc ('\n', print.outf);
    1053            0 :       print.src_line++;
    1054              :     }
    1055              : 
    1056            0 :   return 1;
    1057              : }
    1058              : 
    1059              : static void
    1060            0 : cb_used_define (cpp_reader *pfile, location_t line ATTRIBUTE_UNUSED,
    1061              :                 cpp_hashnode *node)
    1062              : {
    1063            0 :   gfc_cpp_macro_queue *q;
    1064            0 :   q = XNEW (gfc_cpp_macro_queue);
    1065            0 :   q->macro = xstrdup ((const char *) cpp_macro_definition (pfile, node));
    1066            0 :   q->next = cpp_define_queue;
    1067            0 :   cpp_define_queue = q;
    1068            0 : }
    1069              : 
    1070              : /* Return the gcc option code associated with the reason for a cpp
    1071              :    message, or 0 if none.  */
    1072              : 
    1073              : static diagnostics::option_id
    1074           12 : cb_cpp_diagnostic_cpp_option (enum cpp_warning_reason reason)
    1075              : {
    1076           12 :   const struct cpp_reason_option_codes_t *entry;
    1077              : 
    1078          255 :   for (entry = cpp_reason_option_codes; entry->reason != CPP_W_NONE; entry++)
    1079          254 :     if (entry->reason == reason)
    1080           11 :       return entry->option_code;
    1081            0 :   return 0;
    1082              : }
    1083              : 
    1084              : 
    1085              : /* Callback from cpp_error for PFILE to print diagnostics from the
    1086              :    preprocessor.  The diagnostic is of type LEVEL, with REASON set
    1087              :    to the reason code if LEVEL is represents a warning, at location
    1088              :    RICHLOC; MSG is the translated message and AP the arguments.
    1089              :    Returns true if a diagnostic was emitted, false otherwise.  */
    1090              : 
    1091              : static bool
    1092           12 : cb_cpp_diagnostic (cpp_reader *pfile ATTRIBUTE_UNUSED,
    1093              :                    enum cpp_diagnostic_level level,
    1094              :                    enum cpp_warning_reason reason,
    1095              :                    rich_location *richloc,
    1096              :                    const char *msg, va_list *ap)
    1097              : {
    1098           12 :   diagnostics::diagnostic_info diagnostic;
    1099           12 :   enum diagnostics::kind dlevel;
    1100           12 :   bool save_warn_system_headers = global_dc->m_warn_system_headers;
    1101           12 :   bool ret;
    1102              : 
    1103           12 :   switch (level)
    1104              :     {
    1105            4 :     case CPP_DL_WARNING_SYSHDR:
    1106            4 :       global_dc->m_warn_system_headers = 1;
    1107              :       /* Fall through.  */
    1108              :     case CPP_DL_WARNING:
    1109              :       dlevel = diagnostics::kind::warning;
    1110              :       break;
    1111              :     case CPP_DL_PEDWARN:
    1112              :       dlevel = diagnostics::kind::pedwarn;
    1113              :       break;
    1114            1 :     case CPP_DL_ERROR:
    1115            1 :       dlevel = diagnostics::kind::error;
    1116            1 :       break;
    1117            0 :     case CPP_DL_ICE:
    1118            0 :       dlevel = diagnostics::kind::ice;
    1119            0 :       break;
    1120            0 :     case CPP_DL_NOTE:
    1121            0 :       dlevel = diagnostics::kind::note;
    1122            0 :       break;
    1123            0 :     case CPP_DL_FATAL:
    1124            0 :       dlevel = diagnostics::kind::fatal;
    1125            0 :       break;
    1126            0 :     default:
    1127            0 :       gcc_unreachable ();
    1128              :     }
    1129           12 :   diagnostic_set_info_translated (&diagnostic, msg, ap,
    1130              :                                   richloc, dlevel);
    1131           24 :   diagnostic_set_option_id (&diagnostic,
    1132              :                             cb_cpp_diagnostic_cpp_option (reason));
    1133           12 :   ret = diagnostic_report_diagnostic (global_dc, &diagnostic);
    1134           12 :   if (level == CPP_DL_WARNING_SYSHDR)
    1135            4 :     global_dc->m_warn_system_headers = save_warn_system_headers;
    1136           12 :   return ret;
    1137           12 : }
    1138              : 
    1139              : /* Callback called when -fworking-director and -E to emit working
    1140              :    directory in cpp output file.  */
    1141              : 
    1142              : void
    1143            0 : pp_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir)
    1144              : {
    1145            0 :   size_t to_file_len = strlen (dir);
    1146            0 :   unsigned char *to_file_quoted =
    1147            0 :      (unsigned char *) alloca (to_file_len * 4 + 1);
    1148            0 :   unsigned char *p;
    1149              : 
    1150              :   /* cpp_quote_string does not nul-terminate, so we have to do it ourselves.  */
    1151            0 :   p = cpp_quote_string (to_file_quoted, (const unsigned char *) dir, to_file_len);
    1152            0 :   *p = '\0';
    1153            0 :   fprintf (print.outf, "# 1 \"%s//\"\n", to_file_quoted);
    1154            0 : }
    1155              : 
    1156              : /* Copy a #pragma directive to the preprocessed output.  */
    1157              : static void
    1158            0 : cb_def_pragma (cpp_reader *pfile, location_t line)
    1159              : {
    1160            0 :   maybe_print_line (line);
    1161            0 :   fputs ("#pragma ", print.outf);
    1162            0 :   cpp_output_line (pfile, print.outf);
    1163            0 :   print.src_line++;
    1164            0 : }
    1165              : 
    1166              : static void
    1167            0 : cb_used_undef (cpp_reader *pfile ATTRIBUTE_UNUSED,
    1168              :                location_t line ATTRIBUTE_UNUSED,
    1169              :                cpp_hashnode *node)
    1170              : {
    1171            0 :   gfc_cpp_macro_queue *q;
    1172            0 :   q = XNEW (gfc_cpp_macro_queue);
    1173            0 :   q->macro = xstrdup ((const char *) NODE_NAME (node));
    1174            0 :   q->next = cpp_undefine_queue;
    1175            0 :   cpp_undefine_queue = q;
    1176            0 : }
    1177              : 
    1178              : static void
    1179            0 : dump_queued_macros (cpp_reader *pfile ATTRIBUTE_UNUSED)
    1180              : {
    1181            0 :   gfc_cpp_macro_queue *q;
    1182              : 
    1183              :   /* End the previous line of text.  */
    1184            0 :   if (print.printed)
    1185              :     {
    1186            0 :       putc ('\n', print.outf);
    1187            0 :       print.src_line++;
    1188            0 :       print.printed = 0;
    1189              :     }
    1190              : 
    1191            0 :   for (q = cpp_define_queue; q;)
    1192              :     {
    1193            0 :       gfc_cpp_macro_queue *oq;
    1194            0 :       fputs ("#define ", print.outf);
    1195            0 :       fputs (q->macro, print.outf);
    1196            0 :       putc ('\n', print.outf);
    1197            0 :       print.src_line++;
    1198            0 :       oq = q;
    1199            0 :       q = q->next;
    1200            0 :       free (oq->macro);
    1201            0 :       free (oq);
    1202              :     }
    1203            0 :   cpp_define_queue = NULL;
    1204            0 :   for (q = cpp_undefine_queue; q;)
    1205              :     {
    1206            0 :       gfc_cpp_macro_queue *oq;
    1207            0 :       fprintf (print.outf, "#undef %s\n", q->macro);
    1208            0 :       print.src_line++;
    1209            0 :       oq = q;
    1210            0 :       q = q->next;
    1211            0 :       free (oq->macro);
    1212            0 :       free (oq);
    1213              :     }
    1214            0 :   cpp_undefine_queue = NULL;
    1215            0 : }
        

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.