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 716500 : 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 16892 : gm2_langhook_init (void)
122 : {
123 16892 : build_common_tree_nodes (false);
124 16892 : 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 16892 : mpfr_set_default_prec (256);
130 :
131 : /* GNU Modula-2 uses exceptions. */
132 16892 : using_eh_for_cleanups ();
133 :
134 16892 : 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 38174 : gm2_langhook_option_lang_mask (void)
147 : {
148 38174 : return CL_ModulaX2;
149 : }
150 :
151 : /* Initialize the options structure. */
152 :
153 : static void
154 16892 : gm2_langhook_init_options_struct (struct gcc_options *opts)
155 : {
156 : /* Default to avoiding range issues for complex multiply and divide. */
157 16892 : opts->x_flag_complex_method = 2;
158 :
159 : /* The builtin math functions should not set errno. */
160 16892 : opts->x_flag_errno_math = 0;
161 16892 : opts->frontend_set_flag_errno_math = true;
162 :
163 : /* Exceptions are used. */
164 16892 : opts->x_flag_exceptions = 1;
165 16892 : init_FrontEndInit ();
166 16892 : }
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 16892 : gm2_langhook_init_options (unsigned int decoded_options_count,
180 : struct cl_decoded_option *decoded_options)
181 : {
182 16892 : unsigned int i;
183 16892 : bool in_cpp_args = false;
184 16892 : bool building_cpp_command = false;
185 :
186 868023 : for (i = 1; i < decoded_options_count; i++)
187 : {
188 851131 : enum opt_code code = (enum opt_code)decoded_options[i].opt_index;
189 851131 : const struct cl_option *option = &cl_options[code];
190 851131 : const char *opt = (const char *)option->opt_text;
191 851131 : const char *arg = decoded_options[i].arg;
192 851131 : HOST_WIDE_INT value = decoded_options[i].value;
193 851131 : 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 17420 : case OPT_SPECIAL_input_file:
207 17420 : filename_cpp.safe_push (in_cpp_args);
208 17420 : 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 16892 : case OPT_B:
214 16892 : M2Options_SetB (arg);
215 16892 : break;
216 14081 : case OPT_c:
217 14081 : M2Options_Setc (value);
218 14081 : break;
219 12843 : case OPT_dumpdir:
220 12843 : M2Options_SetDumpDir (arg);
221 12843 : 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 528 : M2Options_CppArg (opt, arg, (option->flags & CL_JOINED)
239 0 : && !(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 16892 : case OPT_o:
288 16892 : M2Options_SetObj (arg);
289 16892 : 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 2112 : M2Options_CppArg (opt, arg, (option->flags & CL_JOINED)
326 0 : && !(option->flags & CL_SEPARATE));
327 : break;
328 :
329 : /* Options we act on and also pass to the preprocessor. */
330 7841 : case OPT_O:
331 7841 : M2Options_SetOptimizing (value);
332 7841 : if (building_cpp_command)
333 704 : M2Options_CppArg (opt, arg, (option->flags & CL_JOINED)
334 352 : && !(option->flags & CL_SEPARATE));
335 : break;
336 17420 : case OPT_quiet:
337 17420 : M2Options_SetQuiet (value);
338 17420 : if (building_cpp_command)
339 2112 : M2Options_CppArg (opt, arg, (option->flags & CL_JOINED)
340 0 : && !(option->flags & CL_SEPARATE));
341 : break;
342 0 : case OPT_v:
343 0 : M2Options_SetVerbose (value);
344 : /* FALLTHROUGH */
345 744467 : default:
346 : /* We handled input files above. */
347 744467 : 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 744467 : if (option->flags & CL_ModulaX2)
352 : break;
353 : /* Otherwise, add this to the CPP command line. */
354 226237 : if (building_cpp_command)
355 12672 : M2Options_CppArg (opt, arg, (option->flags & CL_JOINED)
356 2288 : && !(option->flags & CL_SEPARATE));
357 : break;
358 : }
359 : }
360 16892 : filename_cpp.safe_push (false);
361 16892 : }
362 :
363 : static bool
364 17420 : is_cpp_filename (unsigned int i)
365 : {
366 17420 : gcc_assert (i < filename_cpp.length ());
367 17420 : return filename_cpp[i];
368 : }
369 :
370 : static void
371 237570 : push_back_Ipath (const char *arg)
372 : {
373 237570 : if (Ipaths.empty ())
374 : {
375 16892 : named_path np;
376 16892 : np.path.push_back (arg);
377 16892 : np.name = xstrdup (M2Options_GetM2PathName ());
378 16892 : np.lib_root = false;
379 16892 : Ipaths.push_back (np);
380 16892 : }
381 : else
382 : {
383 220678 : if (strcmp (Ipaths.back ().name,
384 220678 : M2Options_GetM2PathName ()) == 0)
385 71530 : Ipaths.back ().path.push_back (arg);
386 : else
387 : {
388 149148 : named_path np;
389 149148 : np.path.push_back (arg);
390 149148 : np.name = xstrdup (M2Options_GetM2PathName ());
391 149148 : np.lib_root = false;
392 149148 : Ipaths.push_back (np);
393 149148 : }
394 : }
395 237570 : }
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 3402 : 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 7362 : add_path_component (char *dest, const char *src)
425 : {
426 7362 : size_t len = strlen (dest);
427 7362 : const char dir_sep[] = {DIR_SEPARATOR, (char)0};
428 7362 : size_t dir_sep_size = strlen (dir_sep);
429 :
430 7362 : if (len > 0)
431 : {
432 : /* Only add a seperator if dest is not empty and does not end
433 : with a seperator. */
434 7362 : if (len >= dir_sep_size
435 7362 : && (strcmp (&dest[len-dir_sep_size], dir_sep) != 0))
436 3972 : strcat (dest, dir_sep);
437 : }
438 7362 : strcat (dest, src);
439 7362 : }
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 2712 : add_one_import_path (const char *libpath, const char *libname)
446 : {
447 2712 : size_t dir_sep_size = get_dir_sep_size ();
448 2712 : size_t mlib_len = 0;
449 :
450 2712 : if (imultilib)
451 : {
452 1248 : mlib_len = strlen (imultilib);
453 1248 : mlib_len += dir_sep_size;
454 : }
455 :
456 2712 : char *lib = (char *)alloca (strlen (libpath) + dir_sep_size
457 : + strlen ("m2") + dir_sep_size
458 : + strlen (libname) + 1
459 : + mlib_len + 1);
460 2712 : strcpy (lib, libpath);
461 2712 : if (imultilib)
462 1248 : add_path_component (lib, imultilib);
463 2712 : add_path_component (lib, "m2");
464 2712 : add_path_component (lib, libname);
465 2712 : M2Options_SetM2PathName (libname);
466 2712 : M2Options_SetSearchPath (lib);
467 2712 : }
468 :
469 : /* add_non_dialect_specific_path add non dialect specific includes
470 : given a base libpath. */
471 :
472 : static void
473 690 : add_non_dialect_specific_path (const char *libpath)
474 : {
475 690 : char *incpath = (char *)alloca (strlen (libpath)
476 : + strlen ("m2")
477 : + get_dir_sep_size ()
478 : + 1);
479 690 : strcpy (incpath, libpath);
480 690 : add_path_component (incpath, "m2");
481 690 : M2Options_SetM2PathName (""); /* No pathname for non dialect specific libs. */
482 690 : M2Options_SetSearchPath (incpath);
483 690 : }
484 :
485 : /* For each comma-separated standard library name in LIBLIST, add the
486 : corresponding include path. */
487 :
488 : static void
489 690 : foreach_lib_gen_import_path (const char *liblist, const char *libpath)
490 : {
491 3402 : while (*liblist != 0 && *liblist != '-')
492 : {
493 2712 : const char *comma = strstr (liblist, ",");
494 2712 : size_t len;
495 2712 : if (comma)
496 2034 : len = comma - liblist;
497 : else
498 678 : len = strlen (liblist);
499 2712 : char *libname = (char *) alloca (len+1);
500 2712 : strncpy (libname, liblist, len);
501 2712 : libname[len] = 0;
502 2712 : add_one_import_path (libpath, libname);
503 2712 : liblist += len;
504 2712 : if (*liblist == ',')
505 2034 : liblist++;
506 : }
507 690 : add_non_dialect_specific_path (libpath);
508 690 : }
509 :
510 : /* get_module_source_dir return the libpath/{multilib/} as a malloc'd
511 : string. */
512 :
513 : static const char *
514 678 : get_module_source_dir (void)
515 : {
516 678 : const char *libpath = iprefix ? iprefix : LIBSUBDIR;
517 678 : const char dir_sep[] = {DIR_SEPARATOR, (char)0};
518 678 : size_t dir_sep_size = strlen (dir_sep);
519 678 : unsigned int mlib_len = 0;
520 :
521 678 : if (imultilib)
522 : {
523 312 : mlib_len = strlen (imultilib);
524 312 : mlib_len += strlen (dir_sep);
525 : }
526 1356 : char *lib = (char *) xmalloc (strlen (libpath)
527 678 : + dir_sep_size
528 678 : + mlib_len + 1);
529 678 : strcpy (lib, libpath);
530 : /* iprefix has a trailing dir separator, LIBSUBDIR does not. */
531 678 : if (!iprefix)
532 0 : strcat (lib, dir_sep);
533 :
534 678 : if (imultilib)
535 : {
536 312 : strcat (lib, imultilib);
537 312 : strcat (lib, dir_sep);
538 : }
539 678 : 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 678 : 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 678 : 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 678 : }
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 16892 : assign_flibs (void)
629 : {
630 16892 : 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 16892 : }
638 :
639 : /* Handle gm2 specific options. Return 0 if we didn't do anything. */
640 :
641 : bool
642 552391 : 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 552391 : enum opt_code code = (enum opt_code)scode;
648 :
649 552391 : const struct cl_option *option = &cl_options[scode];
650 : /* ignore file names. */
651 552391 : if (code == N_OPTS)
652 : return 1;
653 :
654 552391 : 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 4455 : case OPT_fiso:
663 4455 : M2Options_SetISO (value);
664 4455 : iso = value;
665 4455 : return 1;
666 11944 : case OPT_fpim:
667 11944 : M2Options_SetPIM (value);
668 11944 : iso = value ? false : iso;
669 11944 : 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 16892 : case OPT_flibs_:
689 16892 : allow_libraries = value;
690 16892 : flibs = arg;
691 16892 : return 1;
692 2750 : case OPT_fgen_module_list_:
693 2750 : M2Options_SetGenModuleList (value, arg);
694 2750 : 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 2063 : case OPT_fsoft_check_all:
738 2063 : M2Options_SetCheckAll (value);
739 2063 : 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 16892 : case OPT_fscaffold_dynamic:
832 16892 : M2Options_SetScaffoldDynamic (value);
833 16892 : return 1;
834 54 : case OPT_fscaffold_static:
835 54 : M2Options_SetScaffoldStatic (value);
836 54 : return 1;
837 2812 : case OPT_fscaffold_main:
838 2812 : M2Options_SetScaffoldMain (value);
839 2812 : 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 25 : case OPT_fdump_builtins:
868 25 : M2Options_SetDumpBuiltins (value);
869 25 : return 1;
870 29 : case OPT_fdump_system_exports:
871 29 : M2Options_SetDumpSystemExports (value);
872 29 : return 1;
873 0 : case OPT_fswig:
874 0 : M2Options_SetSwig (value);
875 0 : return 1;
876 0 : case OPT_fshared:
877 0 : M2Options_SetShared (value);
878 0 : return 1;
879 0 : case OPT_fm2_statistics:
880 0 : M2Options_SetStatistics (value);
881 0 : return 1;
882 520 : case OPT_fm2_g:
883 520 : M2Options_SetM2g (value);
884 520 : return 1;
885 166112 : break;
886 166112 : case OPT_fm2_pathname_:
887 166112 : if (strcmp (arg, "-") == 0)
888 31394 : M2Options_SetM2PathName ("");
889 : else
890 134718 : M2Options_SetM2PathName (arg);
891 : return 1;
892 237570 : break;
893 237570 : case OPT_fm2_pathnameI:
894 237570 : push_back_Ipath (arg);
895 237570 : return 1;
896 624 : break;
897 624 : case OPT_fm2_prefix_:
898 624 : if (strcmp (arg, "-") == 0)
899 0 : M2Options_SetM2Prefix ("");
900 : else
901 624 : M2Options_SetM2Prefix (arg);
902 : return 1;
903 16892 : break;
904 16892 : case OPT_iprefix:
905 16892 : iprefix = arg;
906 16892 : return 1;
907 312 : break;
908 312 : case OPT_imultilib:
909 312 : imultilib = arg;
910 312 : return 1;
911 33780 : break;
912 33780 : case OPT_isystem:
913 33780 : isystem.push_back (arg);
914 33780 : return 1;
915 0 : break;
916 0 : case OPT_iquote:
917 0 : iquote.push_back (arg);
918 0 : return 1;
919 0 : break;
920 0 : case OPT_isysroot:
921 0 : target_system_root = arg;
922 0 : return 1;
923 24 : break;
924 24 : case OPT_fm2_whole_program:
925 24 : M2Options_SetWholeProgram (value);
926 24 : return 1;
927 6 : break;
928 6 : case OPT_fwideset:
929 6 : M2Options_SetWideset (value);
930 6 : return 1;
931 0 : break;
932 : #ifdef OPT_mabi_ibmlongdouble
933 : case OPT_mabi_ibmlongdouble:
934 : M2Options_SetIBMLongDouble (value);
935 : return 1;
936 : #endif
937 : #ifdef OPT_mabi_ieeelongdouble
938 : case OPT_mabi_ieeelongdouble:
939 : M2Options_SetIEEELongDouble (value);
940 : return 1;
941 : #endif
942 0 : case OPT_flocation_:
943 0 : if (strcmp (arg, "builtins") == 0)
944 : {
945 0 : M2Options_SetForcedLocation (BUILTINS_LOCATION);
946 0 : return 1;
947 : }
948 0 : else if (strcmp (arg, "unknown") == 0)
949 : {
950 0 : M2Options_SetForcedLocation (UNKNOWN_LOCATION);
951 0 : return 1;
952 : }
953 0 : else if ((arg != NULL) && (ISDIGIT (arg[0])))
954 : {
955 0 : M2Options_SetForcedLocation (atoi (arg));
956 0 : return 1;
957 : }
958 : else
959 : return 0;
960 33204 : default:
961 33204 : if (insideCppArgs)
962 : /* Handled in gm2_langhook_init_options (). */
963 : return 1;
964 31608 : else if (option->flags & CL_DRIVER)
965 : /* Driver options (unless specifically claimed above) should be handled
966 : in gm2_langhook_init_options (). */
967 : return 1;
968 635 : else if (option->flags & CL_C)
969 : /* C options (unless specifically claimed above) should be handled
970 : in gm2_langhook_init_options (). */
971 635 : return 1;
972 : break;
973 : }
974 : return 0;
975 0 : }
976 :
977 : /* Run after parsing options. */
978 :
979 : static bool
980 16892 : gm2_langhook_post_options (const char **pfilename)
981 : {
982 16892 : const char *filename = *pfilename;
983 16892 : flag_excess_precision = EXCESS_PRECISION_FAST;
984 16892 : M2Options_SetCC1Quiet (quiet_flag);
985 16892 : M2Options_FinaliseOptions ();
986 16892 : main_input_filename = filename;
987 :
988 : /* Add the include paths as per the libraries specified.
989 : NOTE: This assumes that the driver has validated the input and makes
990 : no attempt to be defensive of nonsense input in flibs=. */
991 16892 : assign_flibs ();
992 :
993 : /* Add search paths.
994 : We are not handling all of the cases yet (e.g idirafter).
995 : This (barring the missing cases) is intended to follow the directory
996 : search rules used for c-family. It would be less confusing if the
997 : presence of absence of these search paths was not dependent on the
998 : flibs= option. */
999 :
1000 16892 : for (auto *s : iquote)
1001 0 : M2Options_SetSearchPath (s);
1002 16892 : iquote.clear();
1003 182944 : for (auto np : Ipaths)
1004 : {
1005 166052 : if (np.lib_root)
1006 12 : foreach_lib_gen_import_path (flibs, np.name);
1007 : else
1008 : {
1009 166040 : M2Options_SetM2PathName (np.name);
1010 403610 : for (auto *s : np.path)
1011 237570 : M2Options_SetSearchPath (s);
1012 : }
1013 166052 : }
1014 16892 : Ipaths.clear();
1015 50672 : for (auto *s : isystem)
1016 33780 : M2Options_SetSearchPath (s);
1017 16892 : isystem.clear();
1018 : /* FIXME: this is not a good way to suppress the addition of the import
1019 : paths. */
1020 16892 : if (allow_libraries)
1021 678 : add_default_include_paths (flibs);
1022 :
1023 : /* Returning false means that the backend should be used. */
1024 16892 : return M2Options_GetPPOnly ();
1025 : }
1026 :
1027 : /* Call the compiler for every source filename on the command line. */
1028 :
1029 : static void
1030 16892 : gm2_parse_input_files (const char **filenames, unsigned int filename_count)
1031 : {
1032 16892 : unsigned int i;
1033 16892 : gcc_assert (filename_count > 0);
1034 :
1035 32770 : for (i = 0; i < filename_count; i++)
1036 17420 : if (!is_cpp_filename (i))
1037 : {
1038 16892 : main_input_filename = filenames[i];
1039 16892 : init_PerCompilationInit (filenames[i]);
1040 : }
1041 15350 : }
1042 :
1043 : static void
1044 16892 : gm2_langhook_parse_file (void)
1045 : {
1046 16892 : gm2_parse_input_files (in_fnames, num_in_fnames);
1047 15350 : if (!M2Options_GetPPOnly ())
1048 15350 : write_globals ();
1049 15350 : }
1050 :
1051 : static tree
1052 303094 : gm2_langhook_type_for_size (unsigned int bits, int unsignedp)
1053 : {
1054 149959 : return gm2_type_for_size (bits, unsignedp);
1055 : }
1056 :
1057 : static tree
1058 306783 : gm2_langhook_type_for_mode (machine_mode mode, int unsignedp)
1059 : {
1060 306783 : tree type;
1061 :
1062 613516 : for (int i = 0; i < NUM_INT_N_ENTS; i ++)
1063 306783 : if (int_n_enabled_p[i]
1064 306783 : && mode == int_n_data[i].m)
1065 50 : return (unsignedp ? int_n_trees[i].unsigned_type
1066 50 : : int_n_trees[i].signed_type);
1067 :
1068 306733 : if (VECTOR_MODE_P (mode))
1069 : {
1070 72 : tree inner;
1071 :
1072 144 : inner = gm2_langhook_type_for_mode (GET_MODE_INNER (mode), unsignedp);
1073 72 : if (inner != NULL_TREE)
1074 72 : return build_vector_type_for_mode (inner, mode);
1075 : return NULL_TREE;
1076 : }
1077 :
1078 306661 : scalar_int_mode imode;
1079 306661 : if (is_int_mode (mode, &imode))
1080 306270 : return gm2_langhook_type_for_size (GET_MODE_BITSIZE (imode), unsignedp);
1081 :
1082 153526 : if (mode == TYPE_MODE (float_type_node))
1083 511 : return float_type_node;
1084 :
1085 153015 : if (mode == TYPE_MODE (double_type_node))
1086 676 : return double_type_node;
1087 :
1088 152339 : if (mode == TYPE_MODE (long_double_type_node))
1089 225 : return long_double_type_node;
1090 :
1091 152114 : if ((float128_type_node != NULL) && (mode == TYPE_MODE (float128_type_node)))
1092 16892 : return float128_type_node;
1093 :
1094 135222 : if (COMPLEX_MODE_P (mode))
1095 : {
1096 101438 : machine_mode inner_mode;
1097 101438 : tree inner_type;
1098 :
1099 101438 : if (mode == TYPE_MODE (complex_float_type_node))
1100 16918 : return complex_float_type_node;
1101 84520 : if (mode == TYPE_MODE (complex_double_type_node))
1102 16896 : return complex_double_type_node;
1103 67624 : if (mode == TYPE_MODE (complex_long_double_type_node))
1104 16948 : return complex_long_double_type_node;
1105 :
1106 50676 : inner_mode = GET_MODE_INNER (mode);
1107 50676 : inner_type = gm2_langhook_type_for_mode (inner_mode, unsignedp);
1108 50676 : if (inner_type != NULL_TREE)
1109 16892 : return build_complex_type (inner_type);
1110 : }
1111 :
1112 : #if HOST_BITS_PER_WIDE_INT >= 64
1113 : /* The middle-end and some backends rely on TImode being supported
1114 : for 64-bit HWI. */
1115 67568 : if (mode == TImode)
1116 : {
1117 0 : type = build_nonstandard_integer_type (GET_MODE_BITSIZE (TImode),
1118 : unsignedp);
1119 0 : if (type && TYPE_MODE (type) == TImode)
1120 0 : return type;
1121 : }
1122 : #endif
1123 : return NULL_TREE;
1124 : }
1125 :
1126 : /* Record a builtin function. We just ignore builtin functions. */
1127 :
1128 : static tree
1129 2652044 : gm2_langhook_builtin_function (tree decl)
1130 : {
1131 2652044 : return decl;
1132 : }
1133 :
1134 : /* Return true if we are in the global binding level. */
1135 :
1136 : static bool
1137 38412 : gm2_langhook_global_bindings_p (void)
1138 : {
1139 38412 : return current_function_decl == NULL_TREE;
1140 : }
1141 :
1142 : /* Unused langhook. */
1143 :
1144 : static tree
1145 0 : gm2_langhook_pushdecl (tree decl ATTRIBUTE_UNUSED)
1146 : {
1147 0 : gcc_unreachable ();
1148 : }
1149 :
1150 : /* This hook is used to get the current list of declarations as trees.
1151 : We don't support that; instead we use write_globals. This can't
1152 : simply crash because it is called by -gstabs. */
1153 :
1154 : static tree
1155 0 : gm2_langhook_getdecls (void)
1156 : {
1157 0 : return NULL;
1158 : }
1159 :
1160 : /* m2_write_global_declarations writes out globals creating an array
1161 : of the declarations and calling wrapup_global_declarations. */
1162 :
1163 : static void
1164 15350 : m2_write_global_declarations (tree globals)
1165 : {
1166 15350 : auto_vec<tree> global_decls;
1167 15350 : tree decl = globals;
1168 15350 : int n = 0;
1169 :
1170 7597159 : while (decl != NULL)
1171 : {
1172 7581809 : global_decls.safe_push (decl);
1173 7581809 : decl = TREE_CHAIN (decl);
1174 7581809 : n++;
1175 : }
1176 30700 : wrapup_global_declarations (global_decls.address (), n);
1177 15350 : }
1178 :
1179 : /* Write out globals. */
1180 :
1181 : static void
1182 15350 : write_globals (void)
1183 : {
1184 15350 : tree t;
1185 15350 : unsigned i;
1186 :
1187 15350 : m2block_finishGlobals ();
1188 :
1189 : /* Process all file scopes in this compilation, and the
1190 : external_scope, through wrapup_global_declarations and
1191 : check_global_declarations. */
1192 46050 : FOR_EACH_VEC_ELT (*all_translation_units, i, t)
1193 30700 : m2_write_global_declarations (BLOCK_VARS (DECL_INITIAL (t)));
1194 15350 : }
1195 :
1196 :
1197 : /* Gimplify an EXPR_STMT node. */
1198 :
1199 : static void
1200 2950 : gimplify_expr_stmt (tree *stmt_p)
1201 : {
1202 2950 : gcc_assert (EXPR_STMT_EXPR (*stmt_p) != NULL_TREE);
1203 2950 : *stmt_p = EXPR_STMT_EXPR (*stmt_p);
1204 2950 : }
1205 :
1206 : /* Genericize a TRY_BLOCK. */
1207 :
1208 : static void
1209 2950 : genericize_try_block (tree *stmt_p)
1210 : {
1211 2950 : tree body = TRY_STMTS (*stmt_p);
1212 2950 : tree cleanup = TRY_HANDLERS (*stmt_p);
1213 :
1214 2950 : *stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup);
1215 2950 : }
1216 :
1217 : /* Genericize a HANDLER by converting to a CATCH_EXPR. */
1218 :
1219 : static void
1220 2950 : genericize_catch_block (tree *stmt_p)
1221 : {
1222 2950 : tree type = HANDLER_TYPE (*stmt_p);
1223 2950 : tree body = HANDLER_BODY (*stmt_p);
1224 :
1225 : /* FIXME should the caught type go in TREE_TYPE? */
1226 2950 : *stmt_p = build2 (CATCH_EXPR, void_type_node, type, body);
1227 2950 : }
1228 :
1229 : /* Convert the tree representation of FNDECL from m2 frontend trees
1230 : to GENERIC. */
1231 :
1232 : extern void pf (tree);
1233 :
1234 : void
1235 120125 : gm2_genericize (tree fndecl)
1236 : {
1237 120125 : tree t;
1238 120125 : struct cgraph_node *cgn;
1239 :
1240 : #if 0
1241 : pf (fndecl);
1242 : #endif
1243 : /* Fix up the types of parms passed by invisible reference. */
1244 318240 : for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t))
1245 198115 : if (TREE_ADDRESSABLE (TREE_TYPE (t)))
1246 : {
1247 :
1248 : /* If a function's arguments are copied to create a thunk, then
1249 : DECL_BY_REFERENCE will be set -- but the type of the argument will be
1250 : a pointer type, so we will never get here. */
1251 0 : gcc_assert (!DECL_BY_REFERENCE (t));
1252 0 : gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
1253 0 : TREE_TYPE (t) = DECL_ARG_TYPE (t);
1254 0 : DECL_BY_REFERENCE (t) = 1;
1255 0 : TREE_ADDRESSABLE (t) = 0;
1256 0 : relayout_decl (t);
1257 : }
1258 :
1259 : /* Dump all nested functions now. */
1260 120125 : cgn = cgraph_node::get_create (fndecl);
1261 241168 : for (cgn = first_nested_function (cgn);
1262 121043 : cgn != NULL; cgn = next_nested_function (cgn))
1263 918 : gm2_genericize (cgn->decl);
1264 120125 : }
1265 :
1266 : /* gm2 gimplify expression, currently just change THROW in the same
1267 : way as C++ */
1268 :
1269 : static int
1270 10754665 : gm2_langhook_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
1271 : gimple_seq *post_p ATTRIBUTE_UNUSED)
1272 : {
1273 10754665 : enum tree_code code = TREE_CODE (*expr_p);
1274 :
1275 10754665 : switch (code)
1276 : {
1277 326 : case THROW_EXPR:
1278 :
1279 : /* FIXME communicate throw type to back end, probably by moving
1280 : THROW_EXPR into ../tree.def. */
1281 326 : *expr_p = TREE_OPERAND (*expr_p, 0);
1282 326 : return GS_OK;
1283 :
1284 2950 : case EXPR_STMT:
1285 2950 : gimplify_expr_stmt (expr_p);
1286 2950 : return GS_OK;
1287 :
1288 2950 : case TRY_BLOCK:
1289 2950 : genericize_try_block (expr_p);
1290 2950 : return GS_OK;
1291 :
1292 2950 : case HANDLER:
1293 2950 : genericize_catch_block (expr_p);
1294 2950 : return GS_OK;
1295 :
1296 : default:
1297 : return GS_UNHANDLED;
1298 : }
1299 : }
1300 :
1301 : static GTY(()) tree gm2_eh_personality_decl;
1302 :
1303 : static tree
1304 2985 : gm2_langhook_eh_personality (void)
1305 : {
1306 2985 : if (!gm2_eh_personality_decl)
1307 2830 : gm2_eh_personality_decl = build_personality_function ("gxx");
1308 :
1309 2985 : return gm2_eh_personality_decl;
1310 : }
1311 :
1312 : /* Functions called directly by the generic backend. */
1313 :
1314 : tree
1315 9687300 : convert_loc (location_t location, tree type, tree expr)
1316 : {
1317 9687300 : if (type == error_mark_node || expr == error_mark_node
1318 19374594 : || TREE_TYPE (expr) == error_mark_node)
1319 : return error_mark_node;
1320 :
1321 9687294 : if (type == TREE_TYPE (expr))
1322 : return expr;
1323 :
1324 4521109 : gcc_assert (TYPE_MAIN_VARIANT (type) != NULL);
1325 4521109 : if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
1326 0 : return fold_convert (type, expr);
1327 :
1328 4521109 : expr = m2convert_GenericToType (location, type, expr);
1329 4521109 : switch (TREE_CODE (type))
1330 : {
1331 123343 : case VOID_TYPE:
1332 123343 : case BOOLEAN_TYPE:
1333 123343 : return fold (convert_to_integer (type, expr));
1334 3762892 : case INTEGER_TYPE:
1335 3762892 : return fold (convert_to_integer (type, expr));
1336 585280 : case POINTER_TYPE:
1337 585280 : return fold (convert_to_pointer (type, expr));
1338 4160 : case REAL_TYPE:
1339 4160 : return fold (convert_to_real (type, expr));
1340 216 : case COMPLEX_TYPE:
1341 216 : return fold (convert_to_complex (type, expr));
1342 45212 : case ENUMERAL_TYPE:
1343 45212 : return fold (convert_to_integer (type, expr));
1344 6 : default:
1345 6 : error_at (location, "cannot convert expression, only base types can be converted");
1346 6 : break;
1347 : }
1348 6 : return error_mark_node;
1349 : }
1350 :
1351 : /* Functions called directly by the generic backend. */
1352 :
1353 : tree
1354 1004967 : convert (tree type, tree expr)
1355 : {
1356 1004967 : return convert_loc (m2linemap_UnknownLocation (), type, expr);
1357 : }
1358 :
1359 : /* Mark EXP saying that we need to be able to take the address of it;
1360 : it should not be allocated in a register. Returns true if
1361 : successful. */
1362 :
1363 : bool
1364 4309142 : gm2_mark_addressable (tree exp)
1365 : {
1366 4309142 : tree x = exp;
1367 :
1368 4367776 : while (TRUE)
1369 4367776 : switch (TREE_CODE (x))
1370 : {
1371 8582 : case COMPONENT_REF:
1372 8582 : if (DECL_PACKED (TREE_OPERAND (x, 1)))
1373 : return false;
1374 8582 : x = TREE_OPERAND (x, 0);
1375 8582 : break;
1376 :
1377 50052 : case ADDR_EXPR:
1378 50052 : case ARRAY_REF:
1379 50052 : case REALPART_EXPR:
1380 50052 : case IMAGPART_EXPR:
1381 50052 : x = TREE_OPERAND (x, 0);
1382 50052 : break;
1383 :
1384 4300598 : case COMPOUND_LITERAL_EXPR:
1385 4300598 : case CONSTRUCTOR:
1386 4300598 : case STRING_CST:
1387 4300598 : case VAR_DECL:
1388 4300598 : case CONST_DECL:
1389 4300598 : case PARM_DECL:
1390 4300598 : case RESULT_DECL:
1391 4300598 : case FUNCTION_DECL:
1392 4300598 : TREE_ADDRESSABLE (x) = 1;
1393 4300598 : return true;
1394 : default:
1395 : return true;
1396 : }
1397 : /* Never reach here. */
1398 : gcc_unreachable ();
1399 : }
1400 :
1401 : /* Return an integer type with BITS bits of precision, that is
1402 : unsigned if UNSIGNEDP is nonzero, otherwise signed. */
1403 :
1404 : tree
1405 319986 : gm2_type_for_size (unsigned int bits, int unsignedp)
1406 : {
1407 319986 : if (unsignedp)
1408 : {
1409 137253 : if (bits == INT_TYPE_SIZE)
1410 17347 : return unsigned_type_node;
1411 119906 : else if (bits == CHAR_TYPE_SIZE)
1412 62066 : return unsigned_char_type_node;
1413 57840 : else if (bits == SHORT_TYPE_SIZE)
1414 666 : return short_unsigned_type_node;
1415 57675 : else if (bits == LONG_TYPE_SIZE)
1416 56667 : return long_unsigned_type_node;
1417 507 : else if (bits == LONG_LONG_TYPE_SIZE)
1418 501 : return long_long_unsigned_type_node;
1419 : else
1420 6 : return build_nonstandard_integer_type (bits,
1421 6 : unsignedp);
1422 : }
1423 : else
1424 : {
1425 182733 : if (bits == INT_TYPE_SIZE)
1426 3232 : return integer_type_node;
1427 179501 : else if (bits == CHAR_TYPE_SIZE)
1428 128 : return signed_char_type_node;
1429 179373 : else if (bits == SHORT_TYPE_SIZE)
1430 138 : return short_integer_type_node;
1431 179659 : else if (bits == LONG_TYPE_SIZE)
1432 162231 : return long_integer_type_node;
1433 17004 : else if (bits == LONG_LONG_TYPE_SIZE)
1434 424 : return long_long_integer_type_node;
1435 : else
1436 16580 : return build_nonstandard_integer_type (bits,
1437 16580 : unsignedp);
1438 : }
1439 : /* Never reach here. */
1440 : gcc_unreachable ();
1441 : }
1442 :
1443 : /* Allow the analyzer to understand Storage ALLOCATE/DEALLOCATE. */
1444 :
1445 : bool
1446 0 : gm2_langhook_new_dispose_storage_substitution (void)
1447 : {
1448 0 : return true;
1449 : }
1450 :
1451 : #undef LANG_HOOKS_NAME
1452 : #undef LANG_HOOKS_INIT
1453 : #undef LANG_HOOKS_INIT_OPTIONS
1454 : #undef LANG_HOOKS_OPTION_LANG_MASK
1455 : #undef LANG_HOOKS_INIT_OPTIONS_STRUCT
1456 : #undef LANG_HOOKS_HANDLE_OPTION
1457 : #undef LANG_HOOKS_POST_OPTIONS
1458 : #undef LANG_HOOKS_PARSE_FILE
1459 : #undef LANG_HOOKS_TYPE_FOR_MODE
1460 : #undef LANG_HOOKS_TYPE_FOR_SIZE
1461 : #undef LANG_HOOKS_BUILTIN_FUNCTION
1462 : #undef LANG_HOOKS_GLOBAL_BINDINGS_P
1463 : #undef LANG_HOOKS_PUSHDECL
1464 : #undef LANG_HOOKS_GETDECLS
1465 : #undef LANG_HOOKS_GIMPLIFY_EXPR
1466 : #undef LANG_HOOKS_EH_PERSONALITY
1467 : #undef LANG_HOOKS_NEW_DISPOSE_STORAGE_SUBSTITUTION
1468 :
1469 : #define LANG_HOOKS_NAME "GNU Modula-2"
1470 : #define LANG_HOOKS_INIT gm2_langhook_init
1471 : #define LANG_HOOKS_INIT_OPTIONS gm2_langhook_init_options
1472 : #define LANG_HOOKS_OPTION_LANG_MASK gm2_langhook_option_lang_mask
1473 : #define LANG_HOOKS_INIT_OPTIONS_STRUCT gm2_langhook_init_options_struct
1474 : #define LANG_HOOKS_HANDLE_OPTION gm2_langhook_handle_option
1475 : #define LANG_HOOKS_POST_OPTIONS gm2_langhook_post_options
1476 : #define LANG_HOOKS_PARSE_FILE gm2_langhook_parse_file
1477 : #define LANG_HOOKS_TYPE_FOR_MODE gm2_langhook_type_for_mode
1478 : #define LANG_HOOKS_TYPE_FOR_SIZE gm2_langhook_type_for_size
1479 : #define LANG_HOOKS_BUILTIN_FUNCTION gm2_langhook_builtin_function
1480 : #define LANG_HOOKS_GLOBAL_BINDINGS_P gm2_langhook_global_bindings_p
1481 : #define LANG_HOOKS_PUSHDECL gm2_langhook_pushdecl
1482 : #define LANG_HOOKS_GETDECLS gm2_langhook_getdecls
1483 : #define LANG_HOOKS_GIMPLIFY_EXPR gm2_langhook_gimplify_expr
1484 : #define LANG_HOOKS_EH_PERSONALITY gm2_langhook_eh_personality
1485 : #define LANG_HOOKS_NEW_DISPOSE_STORAGE_SUBSTITUTION \
1486 : gm2_langhook_new_dispose_storage_substitution
1487 :
1488 : struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
1489 :
1490 : #include "gt-m2-gm2-lang.h"
1491 : #include "gtype-m2.h"
|