LCOV - code coverage report
Current view: top level - gcc/m2 - gm2-lang.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 70.1 % 766 537
Test Date: 2026-02-28 14:20:25 Functions: 85.4 % 41 35
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* gm2-lang.cc language-dependent hooks for GNU Modula-2.
       2              : 
       3              : Copyright (C) 2002-2026 Free Software Foundation, Inc.
       4              : Contributed by Gaius Mulley <gaius@glam.ac.uk>.
       5              : 
       6              : This file is part of GNU Modula-2.
       7              : 
       8              : GNU Modula-2 is free software; you can redistribute it and/or modify
       9              : it under the terms of the GNU General Public License as published by
      10              : the Free Software Foundation; either version 3, or (at your option)
      11              : any later version.
      12              : 
      13              : GNU Modula-2 is distributed in the hope that it will be useful, but
      14              : WITHOUT ANY WARRANTY; without even the implied warranty of
      15              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16              : General Public License for more details.
      17              : 
      18              : You should have received a copy of the GNU General Public License
      19              : along with GCC; see the file COPYING3.  If not see
      20              : <http://www.gnu.org/licenses/>.  */
      21              : 
      22              : #define INCLUDE_VECTOR
      23              : #include "gm2-gcc/gcc-consolidation.h"
      24              : 
      25              : #include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name.  */
      26              : #include "tree-pass.h"     /* FIXME: only for PROP_gimple_any.  */
      27              : #include "toplev.h"
      28              : #include "debug.h"
      29              : 
      30              : #include "opts.h"
      31              : 
      32              : #define GM2_LANG_C
      33              : #include "gm2-lang.h"
      34              : #include "m2block.h"
      35              : #include "dynamicstrings.h"
      36              : #include "m2options.h"
      37              : #include "m2convert.h"
      38              : #include "m2linemap.h"
      39              : #include "init.h"
      40              : #include "m2-tree.h"
      41              : #include "convert.h"
      42              : #include "rtegraph.h"
      43              : #include "cppdefault.h"
      44              : 
      45              : static void write_globals (void);
      46              : 
      47              : static int insideCppArgs = FALSE;
      48              : 
      49              : /* We default to pim in the absence of fiso.  */
      50              : static bool iso = false;
      51              : 
      52       629140 : typedef struct named_path_s {
      53              :   std::vector<const char*>path;
      54              :   const char *name;
      55              :   bool lib_root;
      56              : } named_path;
      57              : 
      58              : 
      59              : /* The language include paths are based on the libraries in use.  */
      60              : static bool allow_libraries = true;
      61              : static const char *flibs = nullptr;
      62              : static const char *iprefix = nullptr;
      63              : static const char *imultilib = nullptr;
      64              : static const char *target_system_root = nullptr;
      65              : static std::vector<named_path>Ipaths;
      66              : static std::vector<const char*>isystem;
      67              : static std::vector<const char*>iquote;
      68              : 
      69              : #define EXPR_STMT_EXPR(NODE) TREE_OPERAND (EXPR_STMT_CHECK (NODE), 0)
      70              : 
      71              : /* start of new stuff.  */
      72              : 
      73              : /* Language-dependent contents of a type.  */
      74              : 
      75              : struct GTY (()) lang_type
      76              : {
      77              :   char dummy;
      78              : };
      79              : 
      80              : /* Language-dependent contents of a decl.  */
      81              : 
      82              : struct GTY (()) lang_decl
      83              : {
      84              :   char dummy;
      85              : };
      86              : 
      87              : /* Language-dependent contents of an identifier.  This must include a
      88              :    tree_identifier.  */
      89              : 
      90              : struct GTY (()) lang_identifier
      91              : {
      92              :   struct tree_identifier common;
      93              : };
      94              : 
      95              : /* The resulting tree type.  */
      96              : 
      97              : union GTY ((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
      98              :             chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), "
      99              :                         "TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN "
     100              :                         "(&%h.generic)) : NULL"))) lang_tree_node
     101              : {
     102              :   union tree_node GTY ((tag ("0"),
     103              :                         desc ("tree_node_structure (&%h)"))) generic;
     104              :   struct lang_identifier GTY ((tag ("1"))) identifier;
     105              : };
     106              : 
     107              : struct GTY (()) language_function
     108              : {
     109              : 
     110              :   /* While we are parsing the function, this contains information about
     111              :   the statement-tree that we are building.  */
     112              :   /* struct stmt_tree_s stmt_tree;  */
     113              :   tree stmt_tree;
     114              : };
     115              : 
     116              : /* Language hooks.  */
     117              : 
     118              : static void gm2_langhook_parse_file (void);
     119              : 
     120              : bool
     121        14952 : gm2_langhook_init (void)
     122              : {
     123        14952 :   build_common_tree_nodes (false);
     124        14952 :   build_common_builtin_nodes ();
     125              : 
     126              :   /* The default precision for floating point numbers.  This is used
     127              :      for floating point constants with abstract type.  This may eventually
     128              :      be controllable by a command line option.  */
     129        14952 :   mpfr_set_default_prec (256);
     130              : 
     131              :   /* GNU Modula-2 uses exceptions.  */
     132        14952 :   using_eh_for_cleanups ();
     133              : 
     134        14952 :   if (M2Options_GetPPOnly ())
     135              :     {
     136              :       /* Preprocess the file here.  */
     137            0 :       gm2_langhook_parse_file ();
     138            0 :       return false; /* Finish now, no further compilation.  */
     139              :     }
     140              :   return true;
     141              : }
     142              : 
     143              : /* The option mask.  */
     144              : 
     145              : static unsigned int
     146        34292 : gm2_langhook_option_lang_mask (void)
     147              : {
     148        34292 :   return CL_ModulaX2;
     149              : }
     150              : 
     151              : /* Initialize the options structure.  */
     152              : 
     153              : static void
     154        14952 : gm2_langhook_init_options_struct (struct gcc_options *opts)
     155              : {
     156              :   /* Default to avoiding range issues for complex multiply and divide.  */
     157        14952 :   opts->x_flag_complex_method = 2;
     158              : 
     159              :   /* The builtin math functions should not set errno.  */
     160        14952 :   opts->x_flag_errno_math = 0;
     161        14952 :   opts->frontend_set_flag_errno_math = true;
     162              : 
     163              :   /* Exceptions are used.  */
     164        14952 :   opts->x_flag_exceptions = 1;
     165        14952 :   init_FrontEndInit ();
     166        14952 : }
     167              : 
     168              : /* Infrastructure for a VEC of bool values.  */
     169              : 
     170              : /* This array determines whether the filename is associated with the
     171              :    C preprocessor.  */
     172              : 
     173              : static vec<bool> filename_cpp;
     174              : 
     175              : /* Build the C preprocessor command line here, since we need to include
     176              :    options that are not passed to the handle_option function.  */
     177              : 
     178              : void
     179        14952 : gm2_langhook_init_options (unsigned int decoded_options_count,
     180              :                            struct cl_decoded_option *decoded_options)
     181              : {
     182        14952 :   unsigned int i;
     183        14952 :   bool in_cpp_args = false;
     184        14952 :   bool building_cpp_command = false;
     185              : 
     186       760343 :   for (i = 1; i < decoded_options_count; i++)
     187              :     {
     188       745391 :       enum opt_code code = (enum opt_code)decoded_options[i].opt_index;
     189       745391 :       const struct cl_option *option = &cl_options[code];
     190       745391 :       const char *opt = (const char *)option->opt_text;
     191       745391 :       const char *arg = decoded_options[i].arg;
     192       745391 :       HOST_WIDE_INT value = decoded_options[i].value;
     193       745391 :       switch (code)
     194              :         {
     195          528 :         case OPT_fcpp:
     196          528 :           if (value)
     197          528 :             gcc_checking_assert (building_cpp_command);
     198              :           break;
     199          528 :         case OPT_fcpp_begin:
     200          528 :           in_cpp_args = true;
     201          528 :           building_cpp_command = true;
     202          528 :           break;
     203          528 :         case OPT_fcpp_end:
     204          528 :           in_cpp_args = false;
     205          528 :           break;
     206        15480 :         case OPT_SPECIAL_input_file:
     207        15480 :           filename_cpp.safe_push (in_cpp_args);
     208        15480 :           break;
     209              : 
     210              :         /* C and driver opts that are not passed to the preprocessor for
     211              :            modula-2, but that we use internally for building preprocesor
     212              :            command lines.  */
     213        14952 :         case OPT_B:
     214        14952 :           M2Options_SetB (arg);
     215        14952 :           break;
     216        12235 :         case OPT_c:
     217        12235 :           M2Options_Setc (value);
     218        12235 :           break;
     219        12723 :         case OPT_dumpdir:
     220        12723 :           M2Options_SetDumpDir (arg);
     221        12723 :           break;
     222            0 :         case OPT_save_temps:
     223            0 :           if (building_cpp_command)
     224            0 :             M2Options_SetSaveTemps (value);
     225              :           break;
     226            0 :         case OPT_save_temps_:
     227            0 :           if (building_cpp_command)
     228              :             /* Also sets SaveTemps. */
     229            0 :             M2Options_SetSaveTempsDir (arg);
     230              :           break;
     231              : 
     232          528 :         case OPT_E:
     233          528 :           if (!in_cpp_args)
     234              :             {
     235            0 :               M2Options_SetPPOnly (value);
     236            0 :               building_cpp_command = true;
     237              :             }
     238         1056 :           M2Options_CppArg (opt, arg, (option->flags & CL_JOINED)
     239          528 :                             && !(option->flags & CL_SEPARATE));
     240          528 :           break;
     241              : 
     242            0 :         case OPT_M:
     243              :           /* Output a rule suitable for make describing the dependencies of the
     244              :              main source file.  */
     245            0 :           if (in_cpp_args)
     246              :             {
     247            0 :               gcc_checking_assert (building_cpp_command);
     248              :               /* This is a preprocessor command.  */
     249            0 :               M2Options_CppArg (opt, arg, (option->flags & CL_JOINED)
     250            0 :                                 && !(option->flags & CL_SEPARATE));
     251              :             }
     252            0 :           M2Options_SetPPOnly (value);
     253            0 :           M2Options_SetM (value);
     254            0 :           break;
     255              : 
     256            0 :         case OPT_MM:
     257            0 :           if (in_cpp_args)
     258              :             {
     259            0 :               gcc_checking_assert (building_cpp_command);
     260              :               /* This is a preprocessor command.  */
     261            0 :               M2Options_CppArg (opt, arg, (option->flags & CL_JOINED)
     262            0 :                                 && !(option->flags & CL_SEPARATE));
     263              :             }
     264            0 :           M2Options_SetPPOnly (value);
     265            0 :           M2Options_SetMM (value);
     266            0 :           break;
     267              : 
     268            0 :         case OPT_MF:
     269            0 :           if (!in_cpp_args)
     270            0 :             M2Options_SetMF (arg);
     271              :           break;
     272              : 
     273            0 :         case OPT_MP:
     274            0 :           M2Options_SetMP (value);
     275            0 :           break;
     276              : 
     277              :         /* We can only use MQ and MT when the command line is either PP-only, or
     278              :            when there is a MD/MMD on it.  */
     279            0 :         case OPT_MQ:
     280            0 :           M2Options_SetMQ (arg);
     281            0 :           break;
     282              : 
     283            0 :         case OPT_MT:
     284            0 :           M2Options_SetMT (arg);
     285            0 :           break;
     286              : 
     287        14952 :         case OPT_o:
     288        14952 :           M2Options_SetObj (arg);
     289        14952 :           break;
     290              : 
     291              :         /* C and driver options that we ignore for the preprocessor lines.  */
     292              :         case OPT_fpch_deps:
     293              :         case OPT_fpch_preprocess:
     294              :           break;
     295              : 
     296              :         case OPT_fplugin_:
     297              :           /* FIXME: We might need to handle this specially, since the modula-2
     298              :              plugin is not usable here, but others might be.
     299              :              For now skip all plugins to avoid fails with the m2 one.  */
     300              :           break;
     301              : 
     302              :         /* Preprocessor arguments with a following filename.  */
     303            0 :         case OPT_MD:
     304            0 :           M2Options_SetMD (value);
     305            0 :           if (value)
     306              :             {
     307            0 :               M2Options_SetM (true);
     308            0 :               M2Options_SetMF (arg);
     309              :             }
     310              :           break;
     311              : 
     312            0 :         case OPT_MMD:
     313            0 :           M2Options_SetMMD (value);
     314            0 :           if (value)
     315              :             {
     316            0 :               M2Options_SetMM (true);
     317            0 :               M2Options_SetMF (arg);
     318              :             }
     319              :           break;
     320              : 
     321              :         /* Modula 2 claimed options we pass to the preprocessor.  */
     322         1056 :         case OPT_ansi:
     323         1056 :         case OPT_traditional_cpp:
     324         1056 :           if (building_cpp_command)
     325         1056 :             M2Options_CppArg (opt, arg, (option->flags & CL_JOINED)
     326         1056 :                               && !(option->flags & CL_SEPARATE));
     327              :           break;
     328              : 
     329              :         /* Options we act on and also pass to the preprocessor.  */
     330         7801 :         case OPT_O:
     331         7801 :           M2Options_SetOptimizing (value);
     332         7801 :           if (building_cpp_command)
     333          352 :             M2Options_CppArg (opt, arg, (option->flags & CL_JOINED)
     334          352 :                               && !(option->flags & CL_SEPARATE));
     335              :           break;
     336        15480 :         case OPT_quiet:
     337        15480 :           M2Options_SetQuiet (value);
     338        15480 :           if (building_cpp_command)
     339         1056 :             M2Options_CppArg (opt, arg, (option->flags & CL_JOINED)
     340         1056 :                               && !(option->flags & CL_SEPARATE));
     341              :           break;
     342            0 :         case OPT_v:
     343            0 :           M2Options_SetVerbose (value);
     344              :           /* FALLTHROUGH */
     345       648493 :         default:
     346              :           /* We handled input files above.  */
     347       648493 :           if (code >= N_OPTS)
     348              :             break;
     349              :           /* Do not pass Modula-2 args to the preprocessor, any that we care
     350              :              about here should already have been handled above.  */
     351       648493 :           if (option->flags & CL_ModulaX2)
     352              :             break;
     353              :           /* Otherwise, add this to the CPP command line.  */
     354       186811 :           if (building_cpp_command)
     355         5808 :             M2Options_CppArg (opt, arg, (option->flags & CL_JOINED)
     356         5808 :                               && !(option->flags & CL_SEPARATE));
     357              :           break;
     358              :         }
     359              :     }
     360        14952 :   filename_cpp.safe_push (false);
     361        14952 : }
     362              : 
     363              : static bool
     364        15480 : is_cpp_filename (unsigned int i)
     365              : {
     366        15480 :   gcc_assert (i < filename_cpp.length ());
     367        15480 :   return filename_cpp[i];
     368              : }
     369              : 
     370              : static void
     371       212646 : push_back_Ipath (const char *arg)
     372              : {
     373       212646 :   if (Ipaths.empty ())
     374              :     {
     375        14952 :       named_path np;
     376        14952 :       np.path.push_back (arg);
     377        14952 :       np.name = xstrdup (M2Options_GetM2PathName ());
     378        14952 :       np.lib_root = false;
     379        14952 :       Ipaths.push_back (np);
     380        14952 :     }
     381              :   else
     382              :     {
     383       197694 :       if (strcmp (Ipaths.back ().name,
     384       197694 :                   M2Options_GetM2PathName ()) == 0)
     385        66186 :         Ipaths.back ().path.push_back (arg);
     386              :       else
     387              :         {
     388       131508 :           named_path np;
     389       131508 :           np.path.push_back (arg);
     390       131508 :           np.name = xstrdup (M2Options_GetM2PathName ());
     391       131508 :           np.lib_root = false;
     392       131508 :           Ipaths.push_back (np);
     393       131508 :         }
     394              :     }
     395       212646 : }
     396              : 
     397              : /* push_back_lib_root pushes a lib_root onto the Ipaths vector.
     398              :    The ordering of the -fm2_add_lib_root=, -I and named paths
     399              :    must be preserved.  */
     400              : 
     401              : static void
     402           12 : push_back_lib_root (const char *arg)
     403              : {
     404           12 :   named_path np;
     405           12 :   np.name = arg;
     406           12 :   np.lib_root = true;
     407           12 :   Ipaths.push_back (np);
     408           12 : }
     409              : 
     410              : /* get_dir_sep_size return the length of the DIR_SEPARATOR string.  */
     411              : 
     412              : static size_t
     413            0 : get_dir_sep_size (void)
     414              : {
     415            0 :   const char dir_sep[] = {DIR_SEPARATOR, (char)0};
     416         3242 :   size_t dir_sep_size = strlen (dir_sep);
     417            0 :   return dir_sep_size;
     418              : }
     419              : 
     420              : /* add_path_component strcats src into dest and adds a directory seperator
     421              :    if necessary.  */
     422              : 
     423              : static void
     424         7074 : add_path_component (char *dest, const char *src)
     425              : {
     426         7074 :   size_t len = strlen (dest);
     427         7074 :   const char dir_sep[] = {DIR_SEPARATOR, (char)0};
     428         7074 :   size_t dir_sep_size = strlen (dir_sep);
     429              : 
     430         7074 :   if (len > 0)
     431              :     {
     432              :       /* Only add a seperator if dest is not empty and does not end
     433              :          with a seperator.  */
     434         7074 :       if (len >= dir_sep_size
     435         7074 :           && (strcmp (&dest[len-dir_sep_size], dir_sep) != 0))
     436         3844 :         strcat (dest, dir_sep);
     437              :     }
     438         7074 :   strcat (dest, src);
     439         7074 : }
     440              : 
     441              : /* This prefixes LIBNAME with the current compiler prefix (if it has been
     442              :    relocated) or the LIBSUBDIR, if not.  */
     443              : 
     444              : static void
     445         2584 : add_one_import_path (const char *libpath, const char *libname)
     446              : {
     447         2584 :   size_t dir_sep_size = get_dir_sep_size ();
     448         2584 :   size_t mlib_len = 0;
     449              : 
     450         2584 :   if (imultilib)
     451              :     {
     452         1248 :       mlib_len = strlen (imultilib);
     453         1248 :       mlib_len += dir_sep_size;
     454              :     }
     455              : 
     456         2584 :   char *lib = (char *)alloca (strlen (libpath) + dir_sep_size
     457              :                               + strlen ("m2") + dir_sep_size
     458              :                               + strlen (libname) + 1
     459              :                               + mlib_len + 1);
     460         2584 :   strcpy (lib, libpath);
     461         2584 :   if (imultilib)
     462         1248 :     add_path_component (lib, imultilib);
     463         2584 :   add_path_component (lib, "m2");
     464         2584 :   add_path_component (lib, libname);
     465         2584 :   M2Options_SetM2PathName (libname);
     466         2584 :   M2Options_SetSearchPath (lib);
     467         2584 : }
     468              : 
     469              : /* add_non_dialect_specific_path add non dialect specific includes
     470              :    given a base libpath.  */
     471              : 
     472              : static void
     473          658 : add_non_dialect_specific_path (const char *libpath)
     474              : {
     475          658 :   char *incpath = (char *)alloca (strlen (libpath)
     476              :                                   + strlen ("m2")
     477              :                                   + get_dir_sep_size ()
     478              :                                   + 1);
     479          658 :   strcpy (incpath, libpath);
     480          658 :   add_path_component (incpath, "m2");
     481          658 :   M2Options_SetM2PathName ("");   /* No pathname for non dialect specific libs.  */
     482          658 :   M2Options_SetSearchPath (incpath);
     483          658 : }
     484              : 
     485              : /* For each comma-separated standard library name in LIBLIST, add the
     486              :    corresponding include path.  */
     487              : 
     488              : static void
     489          658 : foreach_lib_gen_import_path (const char *liblist, const char *libpath)
     490              : {
     491         3242 :   while (*liblist != 0 && *liblist != '-')
     492              :     {
     493         2584 :       const char *comma = strstr (liblist, ",");
     494         2584 :       size_t len;
     495         2584 :       if (comma)
     496         1938 :         len = comma - liblist;
     497              :       else
     498          646 :         len = strlen (liblist);
     499         2584 :       char *libname = (char *) alloca (len+1);
     500         2584 :       strncpy (libname, liblist, len);
     501         2584 :       libname[len] = 0;
     502         2584 :       add_one_import_path (libpath, libname);
     503         2584 :       liblist += len;
     504         2584 :       if (*liblist == ',')
     505         1938 :         liblist++;
     506              :     }
     507          658 :   add_non_dialect_specific_path (libpath);
     508          658 : }
     509              : 
     510              : /* get_module_source_dir return the libpath/{multilib/} as a malloc'd
     511              :    string.  */
     512              : 
     513              : static const char *
     514          646 : get_module_source_dir (void)
     515              : {
     516          646 :   const char *libpath = iprefix ? iprefix : LIBSUBDIR;
     517          646 :   const char dir_sep[] = {DIR_SEPARATOR, (char)0};
     518          646 :   size_t dir_sep_size = strlen (dir_sep);
     519          646 :   unsigned int mlib_len = 0;
     520              : 
     521          646 :   if (imultilib)
     522              :     {
     523          312 :       mlib_len = strlen (imultilib);
     524          312 :       mlib_len += strlen (dir_sep);
     525              :     }
     526         1292 :   char *lib = (char *) xmalloc (strlen (libpath)
     527          646 :                                 + dir_sep_size
     528          646 :                                 + mlib_len + 1);
     529          646 :   strcpy (lib, libpath);
     530              :   /* iprefix has a trailing dir separator, LIBSUBDIR does not.  */
     531          646 :   if (!iprefix)
     532            0 :     strcat (lib, dir_sep);
     533              : 
     534          646 :   if (imultilib)
     535              :     {
     536          312 :       strcat (lib, imultilib);
     537          312 :       strcat (lib, dir_sep);
     538              :     }
     539          646 :   return lib;
     540              : }
     541              : 
     542              : /* concat_component returns a string containing the path left/right.
     543              :    Pre-requisite, left and right are null terminated strings.  The contents of
     544              :    left and right are held on the heap.  Post-requisite, left and right are
     545              :    freed and a new combined string is malloced.  */
     546              : 
     547              : static char *
     548            0 : concat_component (char *left, char *right)
     549              : {
     550            0 :   size_t len = strlen (left)
     551            0 :     + strlen (right)
     552              :     + get_dir_sep_size ()
     553            0 :     + 1;
     554            0 :   char *new_str = (char *) xmalloc (len);
     555            0 :   strcpy (new_str, left);
     556            0 :   add_path_component (new_str, right);
     557            0 :   free (left);
     558            0 :   free (right);
     559            0 :   return new_str;
     560              : }
     561              : 
     562              : /* find_cpp_entry return the element of the cpp_include_defaults array
     563              :    whose fname matches name.  */
     564              : 
     565              : static const struct default_include *
     566            0 : find_cpp_entry (const char *name)
     567              : {
     568            0 :   const struct default_include *p;
     569              : 
     570            0 :   for (p = cpp_include_defaults; p->fname; p++)
     571            0 :     if (strcmp (p->fname, name) == 0)
     572              :       return p;
     573              :   return NULL;
     574              : }
     575              : 
     576              : /* lookup_cpp_default lookup the entry in cppdefault then add the directory to
     577              :    the m2 search path.  It also honours sysroot, imultilib and imultiarch.  */
     578              : 
     579              : static void
     580            0 : lookup_cpp_default (const char *sysroot, const char *flibs, const char *name)
     581              : {
     582            0 :   const struct default_include *p = find_cpp_entry (name);
     583              : 
     584            0 :   if (p != NULL)
     585              :     {
     586            0 :       char *full_str = xstrdup (p->fname);
     587              : 
     588              :       /* Should this directory start with the sysroot?  */
     589            0 :       if (sysroot && p->add_sysroot)
     590            0 :         full_str = concat_component (xstrdup (sysroot), full_str);
     591              :       /* Should we append the imultilib component?  */
     592            0 :       if (p->multilib == 1 && imultilib)
     593            0 :         full_str = concat_component (full_str, xstrdup (imultilib));
     594              :       /* Or append the imultiarch component?  */
     595            0 :       else if (p->multilib == 2 && imultiarch)
     596            0 :         full_str = concat_component (full_str, xstrdup (imultiarch));
     597              :       else
     598            0 :         full_str = xstrdup (p->fname);
     599            0 :       foreach_lib_gen_import_path (flibs, full_str);
     600            0 :       free (full_str);
     601              :     }
     602            0 : }
     603              : 
     604              : /* add_default_include_paths add include paths for site wide definition modules
     605              :    and also gcc version specific definition modules.  */
     606              : 
     607              : static void
     608          646 : add_default_include_paths (const char *flibs)
     609              : {
     610              :   /* Follow the order found in cppdefaults.cc.  */
     611              : #ifdef LOCAL_INCLUDE_DIR
     612              :   lookup_cpp_default (target_system_root, flibs, LOCAL_INCLUDE_DIR);
     613              : #endif
     614              : #ifdef PREFIX_INCLUDE_DIR
     615              :   lookup_cpp_default (target_system_root, flibs, PREFIX_INCLUDE_DIR);
     616              : #endif
     617              :   /* Add the gcc version specific include path.  */
     618          646 :   foreach_lib_gen_import_path (flibs, get_module_source_dir ());
     619              : #ifdef NATIVE_SYSTEM_HEADER_DIR
     620              :   lookup_cpp_default (target_system_root, flibs, NATIVE_SYSTEM_HEADER_DIR);
     621              : #endif
     622          646 : }
     623              : 
     624              : /* assign_flibs assign flibs to a default providing that allow_libraries
     625              :    is true and flibs has not been set.  */
     626              : 
     627              : static void
     628        14952 : assign_flibs (void)
     629              : {
     630        14952 :   if (allow_libraries && (flibs == NULL))
     631              :     {
     632            0 :       if (iso)
     633            0 :         flibs = "m2iso,m2cor,m2pim,m2log";
     634              :       else
     635            0 :         flibs = "m2pim,m2iso,m2cor,m2log";
     636              :     }
     637        14952 : }
     638              : 
     639              : /* Handle gm2 specific options.  Return 0 if we didn't do anything.  */
     640              : 
     641              : bool
     642       492057 : gm2_langhook_handle_option (
     643              :     size_t scode, const char *arg, HOST_WIDE_INT value, int kind ATTRIBUTE_UNUSED,
     644              :     location_t loc ATTRIBUTE_UNUSED,
     645              :     const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
     646              : {
     647       492057 :   enum opt_code code = (enum opt_code)scode;
     648              : 
     649       492057 :   const struct cl_option *option = &cl_options[scode];
     650              :   /* ignore file names.  */
     651       492057 :   if (code == N_OPTS)
     652              :     return 1;
     653              : 
     654       492057 :   switch (code)
     655              :     {
     656            0 :     case OPT_dumpdir:
     657            0 :       M2Options_SetDumpDir (arg);
     658            0 :       return 1;
     659            0 :     case OPT_I:
     660            0 :       push_back_Ipath (arg);
     661            0 :       return 1;
     662         4301 :     case OPT_fiso:
     663         4301 :       M2Options_SetISO (value);
     664         4301 :       iso = value;
     665         4301 :       return 1;
     666        10158 :     case OPT_fpim:
     667        10158 :       M2Options_SetPIM (value);
     668        10158 :       iso = value ? false : iso;
     669        10158 :       return 1;
     670           86 :     case OPT_fpim2:
     671           86 :       M2Options_SetPIM2 (value);
     672           86 :       iso = value ? false : iso;
     673           86 :       return 1;
     674           12 :     case OPT_fpim3:
     675           12 :       M2Options_SetPIM3 (value);
     676           12 :       iso = value ? false : iso;
     677           12 :       return 1;
     678           75 :     case OPT_fpim4:
     679           75 :       M2Options_SetPIM4 (value);
     680           75 :       iso = value ? false : iso;
     681           75 :       return 1;
     682            0 :     case OPT_fpositive_mod_floor_div:
     683            0 :       M2Options_SetPositiveModFloor (value);
     684            0 :       return 1;
     685           12 :     case OPT_fm2_pathname_rootI_:
     686           12 :       push_back_lib_root (arg);
     687           12 :       return 1;
     688        14952 :     case OPT_flibs_:
     689        14952 :       allow_libraries = value;
     690        14952 :       flibs = arg;
     691        14952 :       return 1;
     692         2690 :     case OPT_fgen_module_list_:
     693         2690 :       M2Options_SetGenModuleList (value, arg);
     694         2690 :       return 1;
     695            0 :     case OPT_fmem_report:
     696            0 :       M2Options_SetMemReport (value);
     697            0 :       return 1;
     698            0 :     case OPT_ftime_report:
     699            0 :       M2Options_SetTimeReport (value);
     700            0 :       return 1;
     701            0 :     case OPT_fnil:
     702            0 :       M2Options_SetNilCheck (value);
     703            0 :       return 1;
     704            0 :     case OPT_fwholediv:
     705            0 :       M2Options_SetWholeDiv (value);
     706            0 :       return 1;
     707            0 :     case OPT_findex:
     708            0 :       M2Options_SetIndex (value);
     709            0 :       return 1;
     710            6 :     case OPT_frange:
     711            6 :       M2Options_SetRange (value);
     712            6 :       return 1;
     713            0 :     case OPT_ffloatvalue:
     714            0 :       M2Options_SetFloatValueCheck (value);
     715            0 :       return 1;
     716            0 :     case OPT_fwholevalue:
     717            0 :       M2Options_SetWholeValueCheck (value);
     718            0 :       return 1;
     719            0 :     case OPT_freturn:
     720            0 :       M2Options_SetReturnCheck (value);
     721            0 :       return 1;
     722          616 :     case OPT_fcase:
     723          616 :       M2Options_SetCaseCheck (value);
     724          616 :       return 1;
     725            0 :     case OPT_fd:
     726            0 :       M2Options_SetCompilerDebugging (value);
     727            0 :       return 1;
     728            0 :     case OPT_fdebug_builtins:
     729            0 :       M2Options_SetDebugBuiltins (value);
     730            0 :       return 1;
     731            0 :     case OPT_fdebug_function_line_numbers:
     732            0 :       M2Options_SetDebugFunctionLineNumbers (value);
     733            0 :       return 1;
     734           12 :     case OPT_fauto_init:
     735           12 :       M2Options_SetAutoInit (value);
     736           12 :       return 1;
     737         1927 :     case OPT_fsoft_check_all:
     738         1927 :       M2Options_SetCheckAll (value);
     739         1927 :       return 1;
     740           18 :     case OPT_fexceptions:
     741           18 :       M2Options_SetExceptions (value);
     742           18 :       return 1;
     743            1 :     case OPT_Wstyle:
     744            1 :       M2Options_SetStyle (value);
     745            1 :       return 1;
     746          366 :     case OPT_Wpedantic:
     747          366 :       M2Options_SetPedantic (value);
     748          366 :       return 1;
     749           12 :     case OPT_Wpedantic_param_names:
     750           12 :       M2Options_SetPedanticParamNames (value);
     751           12 :       return 1;
     752            0 :     case OPT_Wpedantic_cast:
     753            0 :       M2Options_SetPedanticCast (value);
     754            0 :       return 1;
     755          328 :     case OPT_fextended_opaque:
     756          328 :       M2Options_SetExtendedOpaque (value);
     757          328 :       return 1;
     758            0 :     case OPT_Wverbose_unbounded:
     759            0 :       M2Options_SetVerboseUnbounded (value);
     760            0 :       return 1;
     761          354 :     case OPT_Wunused_variable:
     762          354 :       M2Options_SetUnusedVariableChecking (value);
     763          354 :       return 1;
     764            0 :     case OPT_Wunused_parameter:
     765            0 :       M2Options_SetUnusedParameterChecking (value);
     766            0 :       return 1;
     767          198 :     case OPT_Wuninit_variable_checking:
     768          198 :       return M2Options_SetUninitVariableChecking (value, "known");
     769          427 :     case OPT_Wuninit_variable_checking_:
     770          427 :       return M2Options_SetUninitVariableChecking (value, arg);
     771            0 :     case OPT_fm2_file_offset_bits_:
     772            0 :       {
     773            0 :         if (arg != NULL)
     774              :           {
     775            0 :             unsigned int bits = atoi (arg);
     776            0 :             if (bits > 0)
     777            0 :               return M2Options_SetFileOffsetBits (value, bits);
     778              :           }
     779              :         return 0;
     780              :       }
     781            0 :     case OPT_fm2_strict_type:
     782            0 :       M2Options_SetStrictTypeChecking (value);
     783            0 :       return 1;
     784            0 :     case OPT_fm2_strict_type_reason:
     785            0 :       M2Options_SetStrictTypeReason (value);
     786            0 :       return 1;
     787            0 :     case OPT_fm2_debug_trace_:
     788            0 :       M2Options_SetM2DebugTraceFilter (value, arg);
     789            0 :       return 1;
     790            0 :     case OPT_fm2_dump_:
     791            0 :       return M2Options_SetM2Dump (value, arg);
     792            0 :     case OPT_fm2_dump_decl_:
     793            0 :       M2Options_SetDumpDeclFilename (value, arg);
     794            0 :       return 1;
     795            0 :     case OPT_fm2_dump_gimple_:
     796            0 :       M2Options_SetDumpGimpleFilename (value, arg);
     797            0 :       return 1;
     798            0 :     case OPT_fm2_dump_quad_:
     799            0 :       M2Options_SetDumpQuadFilename (value, arg);
     800            0 :       return 1;
     801            0 :     case OPT_fm2_dump_filter_:
     802            0 :       M2Options_SetM2DumpFilter (value, arg);
     803            0 :       return 1;
     804          612 :     case OPT_Wall:
     805          612 :       M2Options_SetWall (value);
     806          612 :       return 1;
     807          700 :     case OPT_Wcase_enum:
     808          700 :       M2Options_SetCaseEnumChecking (value);
     809          700 :       return 1;
     810              : #if 0
     811              :     /* Not yet implemented.  */
     812              :     case OPT_fxcode:
     813              :       M2Options_SetXCode (value);
     814              :       return 1;
     815              : #endif
     816            0 :     case OPT_fm2_lower_case:
     817            0 :       M2Options_SetLowerCaseKeywords (value);
     818            0 :       return 1;
     819            0 :     case OPT_fuse_list_:
     820            0 :       M2Options_SetUselist (value, arg);
     821            0 :       return 1;
     822            0 :     case OPT_fruntime_modules_:
     823            0 :       M2Options_SetRuntimeModuleOverride (arg);
     824            0 :       return 1;
     825              :     case OPT_fpthread:
     826              :       /* Handled in the driver.  */
     827              :       return 1;
     828              :     case OPT_fm2_plugin:
     829              :       /* Handled in the driver.  */
     830              :       return 1;
     831        14952 :     case OPT_fscaffold_dynamic:
     832        14952 :       M2Options_SetScaffoldDynamic (value);
     833        14952 :       return 1;
     834           22 :     case OPT_fscaffold_static:
     835           22 :       M2Options_SetScaffoldStatic (value);
     836           22 :       return 1;
     837         2720 :     case OPT_fscaffold_main:
     838         2720 :       M2Options_SetScaffoldMain (value);
     839         2720 :       return 1;
     840          528 :     case OPT_fcpp:
     841          528 :       M2Options_SetCpp (value);
     842          528 :       return 1;
     843              :     case OPT_fpreprocessed:
     844              :       /* Provided for compatibility; ignore for now.  */
     845              :       return 1;
     846          528 :     case OPT_fcpp_begin:
     847          528 :       insideCppArgs = TRUE;
     848          528 :       return 1;
     849          528 :     case OPT_fcpp_end:
     850          528 :       insideCppArgs = FALSE;
     851          528 :       return 1;
     852            0 :     case OPT_fq:
     853            0 :       M2Options_SetQuadDebugging (value);
     854            0 :       return 1;
     855            0 :     case OPT_fsources:
     856            0 :       M2Options_SetSources (value);
     857            0 :       return 1;
     858            0 :     case OPT_funbounded_by_reference:
     859            0 :       M2Options_SetUnboundedByReference (value);
     860            0 :       return 1;
     861            6 :     case OPT_fdef_:
     862            6 :       M2Options_setdefextension (arg);
     863            6 :       return 1;
     864            6 :     case OPT_fmod_:
     865            6 :       M2Options_setmodextension (arg);
     866            6 :       return 1;
     867           22 :     case OPT_fdump_system_exports:
     868           22 :       M2Options_SetDumpSystemExports (value);
     869           22 :       return 1;
     870            0 :     case OPT_fswig:
     871            0 :       M2Options_SetSwig (value);
     872            0 :       return 1;
     873            0 :     case OPT_fshared:
     874            0 :       M2Options_SetShared (value);
     875            0 :       return 1;
     876            0 :     case OPT_fm2_statistics:
     877            0 :       M2Options_SetStatistics (value);
     878            0 :       return 1;
     879          520 :     case OPT_fm2_g:
     880          520 :       M2Options_SetM2g (value);
     881          520 :       return 1;
     882       146488 :       break;
     883       146488 :     case OPT_fm2_pathname_:
     884       146488 :       if (strcmp (arg, "-") == 0)
     885        27514 :         M2Options_SetM2PathName ("");
     886              :       else
     887       118974 :         M2Options_SetM2PathName (arg);
     888              :       return 1;
     889       212646 :       break;
     890       212646 :     case OPT_fm2_pathnameI:
     891       212646 :       push_back_Ipath (arg);
     892       212646 :       return 1;
     893          624 :       break;
     894          624 :     case OPT_fm2_prefix_:
     895          624 :       if (strcmp (arg, "-") == 0)
     896            0 :         M2Options_SetM2Prefix ("");
     897              :       else
     898          624 :         M2Options_SetM2Prefix (arg);
     899              :       return 1;
     900        14952 :       break;
     901        14952 :     case OPT_iprefix:
     902        14952 :       iprefix = arg;
     903        14952 :       return 1;
     904          312 :       break;
     905          312 :     case OPT_imultilib:
     906          312 :       imultilib = arg;
     907          312 :       return 1;
     908        29892 :       break;
     909        29892 :     case OPT_isystem:
     910        29892 :       isystem.push_back (arg);
     911        29892 :       return 1;
     912            0 :       break;
     913            0 :     case OPT_iquote:
     914            0 :       iquote.push_back (arg);
     915            0 :       return 1;
     916            0 :       break;
     917            0 :     case OPT_isysroot:
     918            0 :       target_system_root = arg;
     919            0 :       return 1;
     920           24 :       break;
     921           24 :     case OPT_fm2_whole_program:
     922           24 :       M2Options_SetWholeProgram (value);
     923           24 :       return 1;
     924            6 :       break;
     925            6 :     case OPT_fwideset:
     926            6 :       M2Options_SetWideset (value);
     927            6 :       return 1;
     928            0 :       break;
     929              : #ifdef OPT_mabi_ibmlongdouble
     930              :     case OPT_mabi_ibmlongdouble:
     931              :       M2Options_SetIBMLongDouble (value);
     932              :       return 1;
     933              : #endif
     934              : #ifdef OPT_mabi_ieeelongdouble
     935              :     case OPT_mabi_ieeelongdouble:
     936              :       M2Options_SetIEEELongDouble (value);
     937              :       return 1;
     938              : #endif
     939            0 :     case OPT_flocation_:
     940            0 :       if (strcmp (arg, "builtins") == 0)
     941              :         {
     942            0 :           M2Options_SetForcedLocation (BUILTINS_LOCATION);
     943            0 :           return 1;
     944              :         }
     945            0 :       else if (strcmp (arg, "unknown") == 0)
     946              :         {
     947            0 :           M2Options_SetForcedLocation (UNKNOWN_LOCATION);
     948            0 :           return 1;
     949              :         }
     950            0 :       else if ((arg != NULL) && (ISDIGIT (arg[0])))
     951              :         {
     952            0 :           M2Options_SetForcedLocation (atoi (arg));
     953            0 :           return 1;
     954              :         }
     955              :       else
     956              :         return 0;
     957        29418 :     default:
     958        29418 :       if (insideCppArgs)
     959              :         /* Handled in gm2_langhook_init_options ().  */
     960              :         return 1;
     961        27822 :       else if (option->flags & CL_DRIVER)
     962              :         /* Driver options (unless specifically claimed above) should be handled
     963              :            in gm2_langhook_init_options ().  */
     964              :         return 1;
     965          635 :       else if (option->flags & CL_C)
     966              :         /* C options (unless specifically claimed above) should be handled
     967              :            in gm2_langhook_init_options ().  */
     968              :         return 1;
     969              :       break;
     970              :     }
     971              :   return 0;
     972            0 : }
     973              : 
     974              : /* Run after parsing options.  */
     975              : 
     976              : static bool
     977        14952 : gm2_langhook_post_options (const char **pfilename)
     978              : {
     979        14952 :   const char *filename = *pfilename;
     980        14952 :   flag_excess_precision = EXCESS_PRECISION_FAST;
     981        14952 :   M2Options_SetCC1Quiet (quiet_flag);
     982        14952 :   M2Options_FinaliseOptions ();
     983        14952 :   main_input_filename = filename;
     984              : 
     985              :   /* Add the include paths as per the libraries specified.
     986              :      NOTE: This assumes that the driver has validated the input and makes
     987              :      no attempt to be defensive of nonsense input in flibs=.  */
     988        14952 :   assign_flibs ();
     989              : 
     990              :   /* Add search paths.
     991              :      We are not handling all of the cases yet (e.g idirafter).
     992              :      This (barring the missing cases) is intended to follow the directory
     993              :      search rules used for c-family.  It would be less confusing if the
     994              :      presence of absence of these search paths was not dependent on the
     995              :      flibs= option. */
     996              : 
     997        14952 :   for (auto *s : iquote)
     998            0 :     M2Options_SetSearchPath (s);
     999        14952 :   iquote.clear();
    1000       161424 :   for (auto np : Ipaths)
    1001              :     {
    1002       146472 :       if (np.lib_root)
    1003           12 :         foreach_lib_gen_import_path (flibs, np.name);
    1004              :       else
    1005              :         {
    1006       146460 :           M2Options_SetM2PathName (np.name);
    1007       359106 :           for (auto *s : np.path)
    1008       212646 :             M2Options_SetSearchPath (s);
    1009              :         }
    1010       146472 :     }
    1011        14952 :   Ipaths.clear();
    1012        44844 :   for (auto *s : isystem)
    1013        29892 :     M2Options_SetSearchPath (s);
    1014        14952 :   isystem.clear();
    1015              :   /* FIXME: this is not a good way to suppress the addition of the import
    1016              :      paths.  */
    1017        14952 :   if (allow_libraries)
    1018          646 :     add_default_include_paths (flibs);
    1019              : 
    1020              :   /* Returning false means that the backend should be used.  */
    1021        14952 :   return M2Options_GetPPOnly ();
    1022              : }
    1023              : 
    1024              : /* Call the compiler for every source filename on the command line.  */
    1025              : 
    1026              : static void
    1027        14952 : gm2_parse_input_files (const char **filenames, unsigned int filename_count)
    1028              : {
    1029        14952 :   unsigned int i;
    1030        14952 :   gcc_assert (filename_count > 0);
    1031              : 
    1032        28898 :   for (i = 0; i < filename_count; i++)
    1033        15480 :     if (!is_cpp_filename (i))
    1034              :       {
    1035        14952 :         main_input_filename = filenames[i];
    1036        14952 :         init_PerCompilationInit (filenames[i]);
    1037              :       }
    1038        13418 : }
    1039              : 
    1040              : static void
    1041        14952 : gm2_langhook_parse_file (void)
    1042              : {
    1043        14952 :   gm2_parse_input_files (in_fnames, num_in_fnames);
    1044        13418 :   if (!M2Options_GetPPOnly ())
    1045        13418 :     write_globals ();
    1046        13418 : }
    1047              : 
    1048              : static tree
    1049       281109 : gm2_langhook_type_for_size (unsigned int bits, int unsignedp)
    1050              : {
    1051       137191 :   return gm2_type_for_size (bits, unsignedp);
    1052              : }
    1053              : 
    1054              : static tree
    1055       280703 : gm2_langhook_type_for_mode (machine_mode mode, int unsignedp)
    1056              : {
    1057       280703 :   tree type;
    1058              : 
    1059       842059 :   for (int i = 0; i < NUM_INT_N_ENTS; i ++)
    1060       280703 :     if (int_n_enabled_p[i]
    1061       280703 :         && mode == int_n_data[i].m)
    1062           50 :       return (unsignedp ? int_n_trees[i].unsigned_type
    1063           50 :               : int_n_trees[i].signed_type);
    1064              : 
    1065       280653 :   if (VECTOR_MODE_P (mode))
    1066              :     {
    1067           72 :       tree inner;
    1068              : 
    1069          144 :       inner = gm2_langhook_type_for_mode (GET_MODE_INNER (mode), unsignedp);
    1070           72 :       if (inner != NULL_TREE)
    1071           72 :         return build_vector_type_for_mode (inner, mode);
    1072              :       return NULL_TREE;
    1073              :     }
    1074              : 
    1075       280581 :   scalar_int_mode imode;
    1076       280581 :   if (is_int_mode (mode, &imode))
    1077       287836 :     return gm2_langhook_type_for_size (GET_MODE_BITSIZE (imode), unsignedp);
    1078              : 
    1079       136663 :   if (mode == TYPE_MODE (float_type_node))
    1080          510 :     return float_type_node;
    1081              : 
    1082       136153 :   if (mode == TYPE_MODE (double_type_node))
    1083          674 :     return double_type_node;
    1084              : 
    1085       135479 :   if (mode == TYPE_MODE (long_double_type_node))
    1086          201 :     return long_double_type_node;
    1087              : 
    1088       135278 :   if ((float128_type_node != NULL) && (mode == TYPE_MODE (float128_type_node)))
    1089        14952 :     return float128_type_node;
    1090              : 
    1091       120326 :   if (COMPLEX_MODE_P (mode))
    1092              :     {
    1093        90422 :       machine_mode inner_mode;
    1094        90422 :       tree inner_type;
    1095              : 
    1096        90422 :       if (mode == TYPE_MODE (complex_float_type_node))
    1097        15602 :         return complex_float_type_node;
    1098        74820 :       if (mode == TYPE_MODE (complex_double_type_node))
    1099        14956 :         return complex_double_type_node;
    1100        59864 :       if (mode == TYPE_MODE (complex_long_double_type_node))
    1101        15008 :         return complex_long_double_type_node;
    1102              : 
    1103        44856 :       inner_mode = GET_MODE_INNER (mode);
    1104        44856 :       inner_type = gm2_langhook_type_for_mode (inner_mode, unsignedp);
    1105        44856 :       if (inner_type != NULL_TREE)
    1106        14952 :         return build_complex_type (inner_type);
    1107              :     }
    1108              : 
    1109              : #if HOST_BITS_PER_WIDE_INT >= 64
    1110              :   /* The middle-end and some backends rely on TImode being supported
    1111              :   for 64-bit HWI.  */
    1112        59808 :   if (mode == TImode)
    1113              :     {
    1114            0 :       type = build_nonstandard_integer_type (GET_MODE_BITSIZE (TImode),
    1115              :                                              unsignedp);
    1116            0 :       if (type && TYPE_MODE (type) == TImode)
    1117              :         return type;
    1118              :     }
    1119              : #endif
    1120              :   return NULL_TREE;
    1121              : }
    1122              : 
    1123              : /* Record a builtin function.  We just ignore builtin functions.  */
    1124              : 
    1125              : static tree
    1126      2347464 : gm2_langhook_builtin_function (tree decl)
    1127              : {
    1128      2347464 :   return decl;
    1129              : }
    1130              : 
    1131              : /* Return true if we are in the global binding level.  */
    1132              : 
    1133              : static bool
    1134        37668 : gm2_langhook_global_bindings_p (void)
    1135              : {
    1136        37668 :   return current_function_decl == NULL_TREE;
    1137              : }
    1138              : 
    1139              : /* Unused langhook.  */
    1140              : 
    1141              : static tree
    1142            0 : gm2_langhook_pushdecl (tree decl ATTRIBUTE_UNUSED)
    1143              : {
    1144            0 :   gcc_unreachable ();
    1145              : }
    1146              : 
    1147              : /* This hook is used to get the current list of declarations as trees.
    1148              :    We don't support that; instead we use write_globals.  This can't
    1149              :    simply crash because it is called by -gstabs.  */
    1150              : 
    1151              : static tree
    1152            0 : gm2_langhook_getdecls (void)
    1153              : {
    1154            0 :   return NULL;
    1155              : }
    1156              : 
    1157              : /* m2_write_global_declarations writes out globals creating an array
    1158              :    of the declarations and calling wrapup_global_declarations.  */
    1159              : 
    1160              : static void
    1161        13418 : m2_write_global_declarations (tree globals)
    1162              : {
    1163        13418 :   auto_vec<tree> global_decls;
    1164        13418 :   tree decl = globals;
    1165        13418 :   int n = 0;
    1166              : 
    1167      6963367 :   while (decl != NULL)
    1168              :     {
    1169      6949949 :       global_decls.safe_push (decl);
    1170      6949949 :       decl = TREE_CHAIN (decl);
    1171      6949949 :       n++;
    1172              :     }
    1173        26836 :   wrapup_global_declarations (global_decls.address (), n);
    1174        13418 : }
    1175              : 
    1176              : /* Write out globals.  */
    1177              : 
    1178              : static void
    1179        13418 : write_globals (void)
    1180              : {
    1181        13418 :   tree t;
    1182        13418 :   unsigned i;
    1183              : 
    1184        13418 :   m2block_finishGlobals ();
    1185              : 
    1186              :   /* Process all file scopes in this compilation, and the
    1187              :      external_scope, through wrapup_global_declarations and
    1188              :      check_global_declarations.  */
    1189        40254 :   FOR_EACH_VEC_ELT (*all_translation_units, i, t)
    1190        13418 :   m2_write_global_declarations (BLOCK_VARS (DECL_INITIAL (t)));
    1191        13418 : }
    1192              : 
    1193              : 
    1194              : /* Gimplify an EXPR_STMT node.  */
    1195              : 
    1196              : static void
    1197         2890 : gimplify_expr_stmt (tree *stmt_p)
    1198              : {
    1199         2890 :   gcc_assert (EXPR_STMT_EXPR (*stmt_p) != NULL_TREE);
    1200         2890 :   *stmt_p = EXPR_STMT_EXPR (*stmt_p);
    1201         2890 : }
    1202              : 
    1203              : /* Genericize a TRY_BLOCK.  */
    1204              : 
    1205              : static void
    1206         2890 : genericize_try_block (tree *stmt_p)
    1207              : {
    1208         2890 :   tree body = TRY_STMTS (*stmt_p);
    1209         2890 :   tree cleanup = TRY_HANDLERS (*stmt_p);
    1210              : 
    1211         2890 :   *stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup);
    1212         2890 : }
    1213              : 
    1214              : /* Genericize a HANDLER by converting to a CATCH_EXPR.  */
    1215              : 
    1216              : static void
    1217         2890 : genericize_catch_block (tree *stmt_p)
    1218              : {
    1219         2890 :   tree type = HANDLER_TYPE (*stmt_p);
    1220         2890 :   tree body = HANDLER_BODY (*stmt_p);
    1221              : 
    1222              :   /* FIXME should the caught type go in TREE_TYPE?  */
    1223         2890 :   *stmt_p = build2 (CATCH_EXPR, void_type_node, type, body);
    1224         2890 : }
    1225              : 
    1226              : /* Convert the tree representation of FNDECL from m2 frontend trees
    1227              :    to GENERIC.  */
    1228              : 
    1229              : extern void pf (tree);
    1230              : 
    1231              : void
    1232       106879 : gm2_genericize (tree fndecl)
    1233              : {
    1234       106879 :   tree t;
    1235       106879 :   struct cgraph_node *cgn;
    1236              : 
    1237              : #if 0
    1238              :   pf (fndecl);
    1239              : #endif
    1240              :   /* Fix up the types of parms passed by invisible reference.  */
    1241       284984 :   for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t))
    1242       178105 :     if (TREE_ADDRESSABLE (TREE_TYPE (t)))
    1243              :       {
    1244              : 
    1245              :         /* If a function's arguments are copied to create a thunk, then
    1246              :            DECL_BY_REFERENCE will be set -- but the type of the argument will be
    1247              :            a pointer type, so we will never get here.  */
    1248            0 :         gcc_assert (!DECL_BY_REFERENCE (t));
    1249            0 :         gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
    1250            0 :         TREE_TYPE (t) = DECL_ARG_TYPE (t);
    1251            0 :         DECL_BY_REFERENCE (t) = 1;
    1252            0 :         TREE_ADDRESSABLE (t) = 0;
    1253            0 :         relayout_decl (t);
    1254              :       }
    1255              : 
    1256              :   /* Dump all nested functions now.  */
    1257       106879 :   cgn = cgraph_node::get_create (fndecl);
    1258       107797 :   for (cgn = first_nested_function (cgn);
    1259       107797 :        cgn != NULL; cgn = next_nested_function (cgn))
    1260          918 :     gm2_genericize (cgn->decl);
    1261       106879 : }
    1262              : 
    1263              : /* gm2 gimplify expression, currently just change THROW in the same
    1264              :    way as C++ */
    1265              : 
    1266              : static int
    1267     10105579 : gm2_langhook_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
    1268              :                             gimple_seq *post_p ATTRIBUTE_UNUSED)
    1269              : {
    1270     10105579 :   enum tree_code code = TREE_CODE (*expr_p);
    1271              : 
    1272     10105579 :   switch (code)
    1273              :     {
    1274          320 :     case THROW_EXPR:
    1275              : 
    1276              :       /* FIXME communicate throw type to back end, probably by moving
    1277              :       THROW_EXPR into ../tree.def.  */
    1278          320 :       *expr_p = TREE_OPERAND (*expr_p, 0);
    1279          320 :       return GS_OK;
    1280              : 
    1281         2890 :     case EXPR_STMT:
    1282         2890 :       gimplify_expr_stmt (expr_p);
    1283         2890 :       return GS_OK;
    1284              : 
    1285         2890 :     case TRY_BLOCK:
    1286         2890 :       genericize_try_block (expr_p);
    1287         2890 :       return GS_OK;
    1288              : 
    1289         2890 :     case HANDLER:
    1290         2890 :       genericize_catch_block (expr_p);
    1291         2890 :       return GS_OK;
    1292              : 
    1293              :     default:
    1294              :       return GS_UNHANDLED;
    1295              :     }
    1296              : }
    1297              : 
    1298              : static GTY(()) tree gm2_eh_personality_decl;
    1299              : 
    1300              : static tree
    1301         2925 : gm2_langhook_eh_personality (void)
    1302              : {
    1303         2925 :   if (!gm2_eh_personality_decl)
    1304         2770 :     gm2_eh_personality_decl = build_personality_function ("gxx");
    1305              : 
    1306         2925 :   return gm2_eh_personality_decl;
    1307              : }
    1308              : 
    1309              : /* Functions called directly by the generic backend.  */
    1310              : 
    1311              : tree
    1312      8999472 : convert_loc (location_t location, tree type, tree expr)
    1313              : {
    1314      8999472 :   if (type == error_mark_node || expr == error_mark_node
    1315     17998938 :       || TREE_TYPE (expr) == error_mark_node)
    1316              :     return error_mark_node;
    1317              : 
    1318      8999466 :   if (type == TREE_TYPE (expr))
    1319              :     return expr;
    1320              : 
    1321      4223231 :   gcc_assert (TYPE_MAIN_VARIANT (type) != NULL);
    1322      4223231 :   if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
    1323            0 :     return fold_convert (type, expr);
    1324              : 
    1325      4223231 :   expr = m2convert_GenericToType (location, type, expr);
    1326      4223231 :   switch (TREE_CODE (type))
    1327              :     {
    1328       112959 :     case VOID_TYPE:
    1329       112959 :     case BOOLEAN_TYPE:
    1330       112959 :       return fold (convert_to_integer (type, expr));
    1331      3514900 :     case INTEGER_TYPE:
    1332      3514900 :       return fold (convert_to_integer (type, expr));
    1333       547716 :     case POINTER_TYPE:
    1334       547716 :       return fold (convert_to_pointer (type, expr));
    1335         4136 :     case REAL_TYPE:
    1336         4136 :       return fold (convert_to_real (type, expr));
    1337          216 :     case COMPLEX_TYPE:
    1338          216 :       return fold (convert_to_complex (type, expr));
    1339        43298 :     case ENUMERAL_TYPE:
    1340        43298 :       return fold (convert_to_integer (type, expr));
    1341            6 :     default:
    1342            6 :       error_at (location, "cannot convert expression, only base types can be converted");
    1343            6 :       break;
    1344              :     }
    1345            6 :   return error_mark_node;
    1346              : }
    1347              : 
    1348              : /* Functions called directly by the generic backend.  */
    1349              : 
    1350              : tree
    1351       951711 : convert (tree type, tree expr)
    1352              : {
    1353       951711 :   return convert_loc (m2linemap_UnknownLocation (), type, expr);
    1354              : }
    1355              : 
    1356              : /* Mark EXP saying that we need to be able to take the address of it;
    1357              :    it should not be allocated in a register.  Returns true if
    1358              :    successful.  */
    1359              : 
    1360              : bool
    1361      4041812 : gm2_mark_addressable (tree exp)
    1362              : {
    1363      4041812 :   tree x = exp;
    1364              : 
    1365      4096132 :   while (TRUE)
    1366      4096132 :     switch (TREE_CODE (x))
    1367              :       {
    1368         7586 :       case COMPONENT_REF:
    1369         7586 :         if (DECL_PACKED (TREE_OPERAND (x, 1)))
    1370              :           return false;
    1371         7586 :         x = TREE_OPERAND (x, 0);
    1372         7586 :         break;
    1373              : 
    1374        46734 :       case ADDR_EXPR:
    1375        46734 :       case ARRAY_REF:
    1376        46734 :       case REALPART_EXPR:
    1377        46734 :       case IMAGPART_EXPR:
    1378        46734 :         x = TREE_OPERAND (x, 0);
    1379        46734 :         break;
    1380              : 
    1381      4034438 :       case COMPOUND_LITERAL_EXPR:
    1382      4034438 :       case CONSTRUCTOR:
    1383      4034438 :       case STRING_CST:
    1384      4034438 :       case VAR_DECL:
    1385      4034438 :       case CONST_DECL:
    1386      4034438 :       case PARM_DECL:
    1387      4034438 :       case RESULT_DECL:
    1388      4034438 :       case FUNCTION_DECL:
    1389      4034438 :         TREE_ADDRESSABLE (x) = 1;
    1390      4034438 :         return true;
    1391              :       default:
    1392              :         return true;
    1393              :       }
    1394              :   /* Never reach here.  */
    1395              :   gcc_unreachable ();
    1396              : }
    1397              : 
    1398              : /* Return an integer type with BITS bits of precision, that is
    1399              :    unsigned if UNSIGNEDP is nonzero, otherwise signed.  */
    1400              : 
    1401              : tree
    1402       296061 : gm2_type_for_size (unsigned int bits, int unsignedp)
    1403              : {
    1404       296061 :   if (unsignedp)
    1405              :     {
    1406       129954 :       if (bits == INT_TYPE_SIZE)
    1407        16296 :         return unsigned_type_node;
    1408       113658 :       else if (bits == CHAR_TYPE_SIZE)
    1409        55803 :         return unsigned_char_type_node;
    1410        57855 :       else if (bits == SHORT_TYPE_SIZE)
    1411          666 :         return short_unsigned_type_node;
    1412        57680 :       else if (bits == LONG_TYPE_SIZE)
    1413        56692 :         return long_unsigned_type_node;
    1414          497 :       else if (bits == LONG_LONG_TYPE_SIZE)
    1415          491 :         return long_long_unsigned_type_node;
    1416              :       else
    1417            6 :         return build_nonstandard_integer_type (bits,
    1418            6 :                                                unsignedp);
    1419              :     }
    1420              :   else
    1421              :     {
    1422       166107 :       if (bits == INT_TYPE_SIZE)
    1423         3206 :         return integer_type_node;
    1424       162901 :       else if (bits == CHAR_TYPE_SIZE)
    1425           96 :         return signed_char_type_node;
    1426       162805 :       else if (bits == SHORT_TYPE_SIZE)
    1427          138 :         return short_integer_type_node;
    1428       163091 :       else if (bits == LONG_TYPE_SIZE)
    1429       147603 :         return long_integer_type_node;
    1430        15064 :       else if (bits == LONG_LONG_TYPE_SIZE)
    1431          424 :         return long_long_integer_type_node;
    1432              :       else
    1433        14640 :         return build_nonstandard_integer_type (bits,
    1434        14640 :                                                unsignedp);
    1435              :     }
    1436              :   /* Never reach here.  */
    1437              :   gcc_unreachable ();
    1438              : }
    1439              : 
    1440              : /* Allow the analyzer to understand Storage ALLOCATE/DEALLOCATE.  */
    1441              : 
    1442              : bool
    1443            0 : gm2_langhook_new_dispose_storage_substitution (void)
    1444              : {
    1445            0 :   return true;
    1446              : }
    1447              : 
    1448              : #undef LANG_HOOKS_NAME
    1449              : #undef LANG_HOOKS_INIT
    1450              : #undef LANG_HOOKS_INIT_OPTIONS
    1451              : #undef LANG_HOOKS_OPTION_LANG_MASK
    1452              : #undef LANG_HOOKS_INIT_OPTIONS_STRUCT
    1453              : #undef LANG_HOOKS_HANDLE_OPTION
    1454              : #undef LANG_HOOKS_POST_OPTIONS
    1455              : #undef LANG_HOOKS_PARSE_FILE
    1456              : #undef LANG_HOOKS_TYPE_FOR_MODE
    1457              : #undef LANG_HOOKS_TYPE_FOR_SIZE
    1458              : #undef LANG_HOOKS_BUILTIN_FUNCTION
    1459              : #undef LANG_HOOKS_GLOBAL_BINDINGS_P
    1460              : #undef LANG_HOOKS_PUSHDECL
    1461              : #undef LANG_HOOKS_GETDECLS
    1462              : #undef LANG_HOOKS_GIMPLIFY_EXPR
    1463              : #undef LANG_HOOKS_EH_PERSONALITY
    1464              : #undef LANG_HOOKS_NEW_DISPOSE_STORAGE_SUBSTITUTION
    1465              : 
    1466              : #define LANG_HOOKS_NAME "GNU Modula-2"
    1467              : #define LANG_HOOKS_INIT gm2_langhook_init
    1468              : #define LANG_HOOKS_INIT_OPTIONS gm2_langhook_init_options
    1469              : #define LANG_HOOKS_OPTION_LANG_MASK gm2_langhook_option_lang_mask
    1470              : #define LANG_HOOKS_INIT_OPTIONS_STRUCT gm2_langhook_init_options_struct
    1471              : #define LANG_HOOKS_HANDLE_OPTION gm2_langhook_handle_option
    1472              : #define LANG_HOOKS_POST_OPTIONS gm2_langhook_post_options
    1473              : #define LANG_HOOKS_PARSE_FILE gm2_langhook_parse_file
    1474              : #define LANG_HOOKS_TYPE_FOR_MODE gm2_langhook_type_for_mode
    1475              : #define LANG_HOOKS_TYPE_FOR_SIZE gm2_langhook_type_for_size
    1476              : #define LANG_HOOKS_BUILTIN_FUNCTION gm2_langhook_builtin_function
    1477              : #define LANG_HOOKS_GLOBAL_BINDINGS_P gm2_langhook_global_bindings_p
    1478              : #define LANG_HOOKS_PUSHDECL gm2_langhook_pushdecl
    1479              : #define LANG_HOOKS_GETDECLS gm2_langhook_getdecls
    1480              : #define LANG_HOOKS_GIMPLIFY_EXPR gm2_langhook_gimplify_expr
    1481              : #define LANG_HOOKS_EH_PERSONALITY gm2_langhook_eh_personality
    1482              : #define LANG_HOOKS_NEW_DISPOSE_STORAGE_SUBSTITUTION \
    1483              :   gm2_langhook_new_dispose_storage_substitution
    1484              : 
    1485              : struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
    1486              : 
    1487              : #include "gt-m2-gm2-lang.h"
    1488              : #include "gtype-m2.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.