Branch data Line data Source code
1 : : /* gm2-lang.cc language-dependent hooks for GNU Modula-2.
2 : :
3 : : Copyright (C) 2002-2025 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 : 673027 : 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 : 15928 : gm2_langhook_init (void)
122 : : {
123 : 15928 : build_common_tree_nodes (false);
124 : 15928 : 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 : 15928 : mpfr_set_default_prec (256);
130 : :
131 : : /* GNU Modula-2 uses exceptions. */
132 : 15928 : using_eh_for_cleanups ();
133 : :
134 : 15928 : 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 : 34878 : gm2_langhook_option_lang_mask (void)
147 : : {
148 : 34878 : return CL_ModulaX2;
149 : : }
150 : :
151 : : /* Initialize the options structure. */
152 : :
153 : : static void
154 : 15929 : gm2_langhook_init_options_struct (struct gcc_options *opts)
155 : : {
156 : : /* Default to avoiding range issues for complex multiply and divide. */
157 : 15929 : opts->x_flag_complex_method = 2;
158 : :
159 : : /* The builtin math functions should not set errno. */
160 : 15929 : opts->x_flag_errno_math = 0;
161 : 15929 : opts->frontend_set_flag_errno_math = true;
162 : :
163 : : /* Exceptions are used. */
164 : 15929 : opts->x_flag_exceptions = 1;
165 : 15929 : init_FrontEndInit ();
166 : 15929 : }
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 : 15929 : gm2_langhook_init_options (unsigned int decoded_options_count,
180 : : struct cl_decoded_option *decoded_options)
181 : : {
182 : 15929 : unsigned int i;
183 : 15929 : bool in_cpp_args = false;
184 : 15929 : bool building_cpp_command = false;
185 : :
186 : 804363 : for (i = 1; i < decoded_options_count; i++)
187 : : {
188 : 788434 : enum opt_code code = (enum opt_code)decoded_options[i].opt_index;
189 : 788434 : const struct cl_option *option = &cl_options[code];
190 : 788434 : const char *opt = (const char *)option->opt_text;
191 : 788434 : const char *arg = decoded_options[i].arg;
192 : 788434 : HOST_WIDE_INT value = decoded_options[i].value;
193 : 788434 : 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 : 16457 : case OPT_SPECIAL_input_file:
207 : 16457 : filename_cpp.safe_push (in_cpp_args);
208 : 16457 : 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 : 15929 : case OPT_B:
214 : 15929 : M2Options_SetB (arg);
215 : 15929 : break;
216 : 13283 : case OPT_c:
217 : 13283 : M2Options_Setc (value);
218 : 13283 : break;
219 : 12543 : case OPT_dumpdir:
220 : 12543 : M2Options_SetDumpDir (arg);
221 : 12543 : 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 : 15929 : case OPT_o:
288 : 15929 : M2Options_SetObj (arg);
289 : 15929 : 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 : 7701 : case OPT_O:
331 : 7701 : M2Options_SetOptimizing (value);
332 : 7701 : if (building_cpp_command)
333 : 352 : M2Options_CppArg (opt, arg, (option->flags & CL_JOINED)
334 : 352 : && !(option->flags & CL_SEPARATE));
335 : : break;
336 : 16457 : case OPT_quiet:
337 : 16457 : M2Options_SetQuiet (value);
338 : 16457 : 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 : 686860 : default:
346 : : /* We handled input files above. */
347 : 686860 : 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 : 686860 : if (option->flags & CL_ModulaX2)
352 : : break;
353 : : /* Otherwise, add this to the CPP command line. */
354 : 198554 : 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 : 15929 : filename_cpp.safe_push (false);
361 : 15929 : }
362 : :
363 : : static bool
364 : 16456 : is_cpp_filename (unsigned int i)
365 : : {
366 : 16456 : gcc_assert (i < filename_cpp.length ());
367 : 16456 : return filename_cpp[i];
368 : : }
369 : :
370 : : static void
371 : 224010 : push_back_Ipath (const char *arg)
372 : : {
373 : 224010 : if (Ipaths.empty ())
374 : : {
375 : 15929 : named_path np;
376 : 15929 : np.path.push_back (arg);
377 : 15929 : np.name = xstrdup (M2Options_GetM2PathName ());
378 : 15929 : np.lib_root = false;
379 : 15929 : Ipaths.push_back (np);
380 : 15929 : }
381 : : else
382 : : {
383 : 208081 : if (strcmp (Ipaths.back ().name,
384 : 208081 : M2Options_GetM2PathName ()) == 0)
385 : 67886 : Ipaths.back ().path.push_back (arg);
386 : : else
387 : : {
388 : 140195 : named_path np;
389 : 140195 : np.path.push_back (arg);
390 : 140195 : np.name = xstrdup (M2Options_GetM2PathName ());
391 : 140195 : np.lib_root = false;
392 : 140195 : Ipaths.push_back (np);
393 : 140195 : }
394 : : }
395 : 224010 : }
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 : 3182 : 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 : 6942 : add_path_component (char *dest, const char *src)
425 : : {
426 : 6942 : size_t len = strlen (dest);
427 : 6942 : const char dir_sep[] = {DIR_SEPARATOR, (char)0};
428 : 6942 : size_t dir_sep_size = strlen (dir_sep);
429 : :
430 : 6942 : if (len > 0)
431 : : {
432 : : /* Only add a seperator if dest is not empty and does not end
433 : : with a seperator. */
434 : 6942 : if (len >= dir_sep_size
435 : 6942 : && (strcmp (&dest[len-dir_sep_size], dir_sep) != 0))
436 : 3772 : strcat (dest, dir_sep);
437 : : }
438 : 6942 : strcat (dest, src);
439 : 6942 : }
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 : 2536 : add_one_import_path (const char *libpath, const char *libname)
446 : : {
447 : 2536 : size_t dir_sep_size = get_dir_sep_size ();
448 : 2536 : size_t mlib_len = 0;
449 : :
450 : 2536 : if (imultilib)
451 : : {
452 : 1224 : mlib_len = strlen (imultilib);
453 : 1224 : mlib_len += dir_sep_size;
454 : : }
455 : :
456 : 2536 : char *lib = (char *)alloca (strlen (libpath) + dir_sep_size
457 : : + strlen ("m2") + dir_sep_size
458 : : + strlen (libname) + 1
459 : : + mlib_len + 1);
460 : 2536 : strcpy (lib, libpath);
461 : 2536 : if (imultilib)
462 : 1224 : add_path_component (lib, imultilib);
463 : 2536 : add_path_component (lib, "m2");
464 : 2536 : add_path_component (lib, libname);
465 : 2536 : M2Options_SetM2PathName (libname);
466 : 2536 : M2Options_SetSearchPath (lib);
467 : 2536 : }
468 : :
469 : : /* add_non_dialect_specific_path add non dialect specific includes
470 : : given a base libpath. */
471 : :
472 : : static void
473 : 646 : add_non_dialect_specific_path (const char *libpath)
474 : : {
475 : 646 : char *incpath = (char *)alloca (strlen (libpath)
476 : : + strlen ("m2")
477 : : + get_dir_sep_size ()
478 : : + 1);
479 : 646 : strcpy (incpath, libpath);
480 : 646 : add_path_component (incpath, "m2");
481 : 646 : M2Options_SetM2PathName (""); /* No pathname for non dialect specific libs. */
482 : 646 : M2Options_SetSearchPath (incpath);
483 : 646 : }
484 : :
485 : : /* For each comma-separated standard library name in LIBLIST, add the
486 : : corresponding include path. */
487 : :
488 : : static void
489 : 646 : foreach_lib_gen_import_path (const char *liblist, const char *libpath)
490 : : {
491 : 3182 : while (*liblist != 0 && *liblist != '-')
492 : : {
493 : 2536 : const char *comma = strstr (liblist, ",");
494 : 2536 : size_t len;
495 : 2536 : if (comma)
496 : 1902 : len = comma - liblist;
497 : : else
498 : 634 : len = strlen (liblist);
499 : 2536 : char *libname = (char *) alloca (len+1);
500 : 2536 : strncpy (libname, liblist, len);
501 : 2536 : libname[len] = 0;
502 : 2536 : add_one_import_path (libpath, libname);
503 : 2536 : liblist += len;
504 : 2536 : if (*liblist == ',')
505 : 1902 : liblist++;
506 : : }
507 : 646 : add_non_dialect_specific_path (libpath);
508 : 646 : }
509 : :
510 : : /* get_module_source_dir return the libpath/{multilib/} as a malloc'd
511 : : string. */
512 : :
513 : : static const char *
514 : 634 : get_module_source_dir (void)
515 : : {
516 : 634 : const char *libpath = iprefix ? iprefix : LIBSUBDIR;
517 : 634 : const char dir_sep[] = {DIR_SEPARATOR, (char)0};
518 : 634 : size_t dir_sep_size = strlen (dir_sep);
519 : 634 : unsigned int mlib_len = 0;
520 : :
521 : 634 : if (imultilib)
522 : : {
523 : 306 : mlib_len = strlen (imultilib);
524 : 306 : mlib_len += strlen (dir_sep);
525 : : }
526 : 1268 : char *lib = (char *) xmalloc (strlen (libpath)
527 : 634 : + dir_sep_size
528 : 634 : + mlib_len + 1);
529 : 634 : strcpy (lib, libpath);
530 : : /* iprefix has a trailing dir separator, LIBSUBDIR does not. */
531 : 634 : if (!iprefix)
532 : 0 : strcat (lib, dir_sep);
533 : :
534 : 634 : if (imultilib)
535 : : {
536 : 306 : strcat (lib, imultilib);
537 : 306 : strcat (lib, dir_sep);
538 : : }
539 : 634 : 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 : 634 : 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 : 634 : 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 : 634 : }
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 : 15929 : assign_flibs (void)
629 : : {
630 : 15929 : 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 : 15929 : }
638 : :
639 : : /* Handle gm2 specific options. Return 0 if we didn't do anything. */
640 : :
641 : : bool
642 : 520705 : 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 : 520705 : enum opt_code code = (enum opt_code)scode;
648 : :
649 : 520705 : const struct cl_option *option = &cl_options[scode];
650 : : /* ignore file names. */
651 : 520705 : if (code == N_OPTS)
652 : : return 1;
653 : :
654 : 520705 : 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 : 4124 : case OPT_fiso:
663 : 4124 : M2Options_SetISO (value);
664 : 4124 : iso = value;
665 : 4124 : return 1;
666 : 11324 : case OPT_fpim:
667 : 11324 : M2Options_SetPIM (value);
668 : 11324 : iso = value ? false : iso;
669 : 11324 : 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 : 15929 : case OPT_flibs_:
689 : 15929 : allow_libraries = value;
690 : 15929 : flibs = arg;
691 : 15929 : return 1;
692 : 2630 : case OPT_fgen_module_list_:
693 : 2630 : M2Options_SetGenModuleList (value, arg);
694 : 2630 : return 1;
695 : 0 : case OPT_fnil:
696 : 0 : M2Options_SetNilCheck (value);
697 : 0 : return 1;
698 : 0 : case OPT_fwholediv:
699 : 0 : M2Options_SetWholeDiv (value);
700 : 0 : return 1;
701 : 0 : case OPT_findex:
702 : 0 : M2Options_SetIndex (value);
703 : 0 : return 1;
704 : 6 : case OPT_frange:
705 : 6 : M2Options_SetRange (value);
706 : 6 : return 1;
707 : 0 : case OPT_ffloatvalue:
708 : 0 : M2Options_SetFloatValueCheck (value);
709 : 0 : return 1;
710 : 0 : case OPT_fwholevalue:
711 : 0 : M2Options_SetWholeValueCheck (value);
712 : 0 : return 1;
713 : 0 : case OPT_freturn:
714 : 0 : M2Options_SetReturnCheck (value);
715 : 0 : return 1;
716 : 604 : case OPT_fcase:
717 : 604 : M2Options_SetCaseCheck (value);
718 : 604 : return 1;
719 : 0 : case OPT_fd:
720 : 0 : M2Options_SetCompilerDebugging (value);
721 : 0 : return 1;
722 : 0 : case OPT_fdebug_builtins:
723 : 0 : M2Options_SetDebugBuiltins (value);
724 : 0 : return 1;
725 : 0 : case OPT_fdebug_function_line_numbers:
726 : 0 : M2Options_SetDebugFunctionLineNumbers (value);
727 : 0 : return 1;
728 : 12 : case OPT_fauto_init:
729 : 12 : M2Options_SetAutoInit (value);
730 : 12 : return 1;
731 : 1853 : case OPT_fsoft_check_all:
732 : 1853 : M2Options_SetCheckAll (value);
733 : 1853 : return 1;
734 : 18 : case OPT_fexceptions:
735 : 18 : M2Options_SetExceptions (value);
736 : 18 : return 1;
737 : 0 : case OPT_Wstyle:
738 : 0 : M2Options_SetStyle (value);
739 : 0 : return 1;
740 : 366 : case OPT_Wpedantic:
741 : 366 : M2Options_SetPedantic (value);
742 : 366 : return 1;
743 : 12 : case OPT_Wpedantic_param_names:
744 : 12 : M2Options_SetPedanticParamNames (value);
745 : 12 : return 1;
746 : 0 : case OPT_Wpedantic_cast:
747 : 0 : M2Options_SetPedanticCast (value);
748 : 0 : return 1;
749 : 328 : case OPT_fextended_opaque:
750 : 328 : M2Options_SetExtendedOpaque (value);
751 : 328 : return 1;
752 : 0 : case OPT_Wverbose_unbounded:
753 : 0 : M2Options_SetVerboseUnbounded (value);
754 : 0 : return 1;
755 : 354 : case OPT_Wunused_variable:
756 : 354 : M2Options_SetUnusedVariableChecking (value);
757 : 354 : return 1;
758 : 0 : case OPT_Wunused_parameter:
759 : 0 : M2Options_SetUnusedParameterChecking (value);
760 : 0 : return 1;
761 : 198 : case OPT_Wuninit_variable_checking:
762 : 198 : return M2Options_SetUninitVariableChecking (value, "known");
763 : 427 : case OPT_Wuninit_variable_checking_:
764 : 427 : return M2Options_SetUninitVariableChecking (value, arg);
765 : 0 : case OPT_fm2_file_offset_bits_:
766 : 0 : {
767 : 0 : if (arg != NULL)
768 : : {
769 : 0 : unsigned int bits = atoi (arg);
770 : 0 : if (bits > 0)
771 : 0 : return M2Options_SetFileOffsetBits (value, bits);
772 : : }
773 : : return 0;
774 : : }
775 : 0 : case OPT_fm2_strict_type:
776 : 0 : M2Options_SetStrictTypeChecking (value);
777 : 0 : return 1;
778 : 0 : case OPT_fm2_strict_type_reason:
779 : 0 : M2Options_SetStrictTypeReason (value);
780 : 0 : return 1;
781 : 0 : case OPT_fm2_debug_trace_:
782 : 0 : M2Options_SetM2DebugTraceFilter (value, arg);
783 : 0 : return 1;
784 : 0 : case OPT_fm2_dump_:
785 : 0 : return M2Options_SetM2Dump (value, arg);
786 : 0 : case OPT_fm2_dump_decl_:
787 : 0 : M2Options_SetDumpDeclFilename (value, arg);
788 : 0 : return 1;
789 : 0 : case OPT_fm2_dump_gimple_:
790 : 0 : M2Options_SetDumpGimpleFilename (value, arg);
791 : 0 : return 1;
792 : 0 : case OPT_fm2_dump_quad_:
793 : 0 : M2Options_SetDumpQuadFilename (value, arg);
794 : 0 : return 1;
795 : 0 : case OPT_fm2_dump_filter_:
796 : 0 : M2Options_SetM2DumpFilter (value, arg);
797 : 0 : return 1;
798 : 600 : case OPT_Wall:
799 : 600 : M2Options_SetWall (value);
800 : 600 : return 1;
801 : 688 : case OPT_Wcase_enum:
802 : 688 : M2Options_SetCaseEnumChecking (value);
803 : 688 : return 1;
804 : : #if 0
805 : : /* Not yet implemented. */
806 : : case OPT_fxcode:
807 : : M2Options_SetXCode (value);
808 : : return 1;
809 : : #endif
810 : 0 : case OPT_fm2_lower_case:
811 : 0 : M2Options_SetLowerCaseKeywords (value);
812 : 0 : return 1;
813 : 0 : case OPT_fuse_list_:
814 : 0 : M2Options_SetUselist (value, arg);
815 : 0 : return 1;
816 : 0 : case OPT_fruntime_modules_:
817 : 0 : M2Options_SetRuntimeModuleOverride (arg);
818 : 0 : return 1;
819 : : case OPT_fpthread:
820 : : /* Handled in the driver. */
821 : : return 1;
822 : : case OPT_fm2_plugin:
823 : : /* Handled in the driver. */
824 : : return 1;
825 : 15929 : case OPT_fscaffold_dynamic:
826 : 15929 : M2Options_SetScaffoldDynamic (value);
827 : 15929 : return 1;
828 : 22 : case OPT_fscaffold_static:
829 : 22 : M2Options_SetScaffoldStatic (value);
830 : 22 : return 1;
831 : 2660 : case OPT_fscaffold_main:
832 : 2660 : M2Options_SetScaffoldMain (value);
833 : 2660 : return 1;
834 : 528 : case OPT_fcpp:
835 : 528 : M2Options_SetCpp (value);
836 : 528 : return 1;
837 : : case OPT_fpreprocessed:
838 : : /* Provided for compatibility; ignore for now. */
839 : : return 1;
840 : 528 : case OPT_fcpp_begin:
841 : 528 : insideCppArgs = TRUE;
842 : 528 : return 1;
843 : 528 : case OPT_fcpp_end:
844 : 528 : insideCppArgs = FALSE;
845 : 528 : return 1;
846 : 0 : case OPT_fq:
847 : 0 : M2Options_SetQuadDebugging (value);
848 : 0 : return 1;
849 : 0 : case OPT_fsources:
850 : 0 : M2Options_SetSources (value);
851 : 0 : return 1;
852 : 0 : case OPT_funbounded_by_reference:
853 : 0 : M2Options_SetUnboundedByReference (value);
854 : 0 : return 1;
855 : 6 : case OPT_fdef_:
856 : 6 : M2Options_setdefextension (arg);
857 : 6 : return 1;
858 : 6 : case OPT_fmod_:
859 : 6 : M2Options_setmodextension (arg);
860 : 6 : return 1;
861 : 22 : case OPT_fdump_system_exports:
862 : 22 : M2Options_SetDumpSystemExports (value);
863 : 22 : return 1;
864 : 0 : case OPT_fswig:
865 : 0 : M2Options_SetSwig (value);
866 : 0 : return 1;
867 : 0 : case OPT_fshared:
868 : 0 : M2Options_SetShared (value);
869 : 0 : return 1;
870 : 0 : case OPT_fm2_statistics:
871 : 0 : M2Options_SetStatistics (value);
872 : 0 : return 1;
873 : 508 : case OPT_fm2_g:
874 : 508 : M2Options_SetM2g (value);
875 : 508 : return 1;
876 : 156152 : break;
877 : 156152 : case OPT_fm2_pathname_:
878 : 156152 : if (strcmp (arg, "-") == 0)
879 : 29516 : M2Options_SetM2PathName ("");
880 : : else
881 : 126636 : M2Options_SetM2PathName (arg);
882 : : return 1;
883 : 224010 : break;
884 : 224010 : case OPT_fm2_pathnameI:
885 : 224010 : push_back_Ipath (arg);
886 : 224010 : return 1;
887 : 612 : break;
888 : 612 : case OPT_fm2_prefix_:
889 : 612 : if (strcmp (arg, "-") == 0)
890 : 0 : M2Options_SetM2Prefix ("");
891 : : else
892 : 612 : M2Options_SetM2Prefix (arg);
893 : : return 1;
894 : 15929 : break;
895 : 15929 : case OPT_iprefix:
896 : 15929 : iprefix = arg;
897 : 15929 : return 1;
898 : 306 : break;
899 : 306 : case OPT_imultilib:
900 : 306 : imultilib = arg;
901 : 306 : return 1;
902 : 31846 : break;
903 : 31846 : case OPT_isystem:
904 : 31846 : isystem.push_back (arg);
905 : 31846 : return 1;
906 : 0 : break;
907 : 0 : case OPT_iquote:
908 : 0 : iquote.push_back (arg);
909 : 0 : return 1;
910 : 0 : break;
911 : 0 : case OPT_isysroot:
912 : 0 : target_system_root = arg;
913 : 0 : return 1;
914 : 24 : break;
915 : 24 : case OPT_fm2_whole_program:
916 : 24 : M2Options_SetWholeProgram (value);
917 : 24 : return 1;
918 : : #ifdef OPT_mabi_ibmlongdouble
919 : : case OPT_mabi_ibmlongdouble:
920 : : M2Options_SetIBMLongDouble (value);
921 : : return 1;
922 : : #endif
923 : : #ifdef OPT_mabi_ieeelongdouble
924 : : case OPT_mabi_ieeelongdouble:
925 : : M2Options_SetIEEELongDouble (value);
926 : : return 1;
927 : : #endif
928 : 0 : case OPT_flocation_:
929 : 0 : if (strcmp (arg, "builtins") == 0)
930 : : {
931 : 0 : M2Options_SetForcedLocation (BUILTINS_LOCATION);
932 : 0 : return 1;
933 : : }
934 : 0 : else if (strcmp (arg, "unknown") == 0)
935 : : {
936 : 0 : M2Options_SetForcedLocation (UNKNOWN_LOCATION);
937 : 0 : return 1;
938 : : }
939 : 0 : else if ((arg != NULL) && (ISDIGIT (arg[0])))
940 : : {
941 : 0 : M2Options_SetForcedLocation (atoi (arg));
942 : 0 : return 1;
943 : : }
944 : : else
945 : : return 0;
946 : 31431 : default:
947 : 31431 : if (insideCppArgs)
948 : : /* Handled in gm2_langhook_init_options (). */
949 : : return 1;
950 : 29835 : else if (option->flags & CL_DRIVER)
951 : : /* Driver options (unless specifically claimed above) should be handled
952 : : in gm2_langhook_init_options (). */
953 : : return 1;
954 : 623 : else if (option->flags & CL_C)
955 : : /* C options (unless specifically claimed above) should be handled
956 : : in gm2_langhook_init_options (). */
957 : : return 1;
958 : : break;
959 : : }
960 : : return 0;
961 : 0 : }
962 : :
963 : : /* Run after parsing options. */
964 : :
965 : : static bool
966 : 15929 : gm2_langhook_post_options (const char **pfilename)
967 : : {
968 : 15929 : const char *filename = *pfilename;
969 : 15929 : flag_excess_precision = EXCESS_PRECISION_FAST;
970 : 15929 : M2Options_SetCC1Quiet (quiet_flag);
971 : 15929 : M2Options_FinaliseOptions ();
972 : 15929 : main_input_filename = filename;
973 : :
974 : : /* Add the include paths as per the libraries specified.
975 : : NOTE: This assumes that the driver has validated the input and makes
976 : : no attempt to be defensive of nonsense input in flibs=. */
977 : 15929 : assign_flibs ();
978 : :
979 : : /* Add search paths.
980 : : We are not handling all of the cases yet (e.g idirafter).
981 : : This (barring the missing cases) is intended to follow the directory
982 : : search rules used for c-family. It would be less confusing if the
983 : : presence of absence of these search paths was not dependent on the
984 : : flibs= option. */
985 : :
986 : 15929 : for (auto *s : iquote)
987 : 0 : M2Options_SetSearchPath (s);
988 : 15929 : iquote.clear();
989 : 172065 : for (auto np : Ipaths)
990 : : {
991 : 156136 : if (np.lib_root)
992 : 12 : foreach_lib_gen_import_path (flibs, np.name);
993 : : else
994 : : {
995 : 156124 : M2Options_SetM2PathName (np.name);
996 : 380134 : for (auto *s : np.path)
997 : 224010 : M2Options_SetSearchPath (s);
998 : : }
999 : 156136 : }
1000 : 15929 : Ipaths.clear();
1001 : 47775 : for (auto *s : isystem)
1002 : 31846 : M2Options_SetSearchPath (s);
1003 : 15929 : isystem.clear();
1004 : : /* FIXME: this is not a good way to suppress the addition of the import
1005 : : paths. */
1006 : 15929 : if (allow_libraries)
1007 : 634 : add_default_include_paths (flibs);
1008 : :
1009 : : /* Returning false means that the backend should be used. */
1010 : 15929 : return M2Options_GetPPOnly ();
1011 : : }
1012 : :
1013 : : /* Call the compiler for every source filename on the command line. */
1014 : :
1015 : : static void
1016 : 15928 : gm2_parse_input_files (const char **filenames, unsigned int filename_count)
1017 : : {
1018 : 15928 : unsigned int i;
1019 : 15928 : gcc_assert (filename_count > 0);
1020 : :
1021 : 30915 : for (i = 0; i < filename_count; i++)
1022 : 16456 : if (!is_cpp_filename (i))
1023 : : {
1024 : 15928 : main_input_filename = filenames[i];
1025 : 15928 : init_PerCompilationInit (filenames[i]);
1026 : : }
1027 : 14459 : }
1028 : :
1029 : : static void
1030 : 15928 : gm2_langhook_parse_file (void)
1031 : : {
1032 : 15928 : gm2_parse_input_files (in_fnames, num_in_fnames);
1033 : 14459 : if (!M2Options_GetPPOnly ())
1034 : 14459 : write_globals ();
1035 : 14459 : }
1036 : :
1037 : : static tree
1038 : 231184 : gm2_langhook_type_for_size (unsigned int bits, int unsignedp)
1039 : : {
1040 : 130365 : return gm2_type_for_size (bits, unsignedp);
1041 : : }
1042 : :
1043 : : static tree
1044 : 245461 : gm2_langhook_type_for_mode (machine_mode mode, int unsignedp)
1045 : : {
1046 : 245461 : tree type;
1047 : :
1048 : 736333 : for (int i = 0; i < NUM_INT_N_ENTS; i ++)
1049 : 245461 : if (int_n_enabled_p[i]
1050 : 245461 : && mode == int_n_data[i].m)
1051 : 50 : return (unsignedp ? int_n_trees[i].unsigned_type
1052 : 50 : : int_n_trees[i].signed_type);
1053 : :
1054 : 245411 : if (VECTOR_MODE_P (mode))
1055 : : {
1056 : 5 : tree inner;
1057 : :
1058 : 10 : inner = gm2_langhook_type_for_mode (GET_MODE_INNER (mode), unsignedp);
1059 : 5 : if (inner != NULL_TREE)
1060 : 5 : return build_vector_type_for_mode (inner, mode);
1061 : : return NULL_TREE;
1062 : : }
1063 : :
1064 : 245406 : scalar_int_mode imode;
1065 : 245406 : if (is_int_mode (mode, &imode))
1066 : 201638 : return gm2_langhook_type_for_size (GET_MODE_BITSIZE (imode), unsignedp);
1067 : :
1068 : 144587 : if (mode == TYPE_MODE (float_type_node))
1069 : 342 : return float_type_node;
1070 : :
1071 : 144245 : if (mode == TYPE_MODE (double_type_node))
1072 : 506 : return double_type_node;
1073 : :
1074 : 143739 : if (mode == TYPE_MODE (long_double_type_node))
1075 : 201 : return long_double_type_node;
1076 : :
1077 : 143538 : if ((float128_type_node != NULL) && (mode == TYPE_MODE (float128_type_node)))
1078 : 15928 : return float128_type_node;
1079 : :
1080 : 127610 : if (COMPLEX_MODE_P (mode))
1081 : : {
1082 : 95754 : machine_mode inner_mode;
1083 : 95754 : tree inner_type;
1084 : :
1085 : 95754 : if (mode == TYPE_MODE (complex_float_type_node))
1086 : 16054 : return complex_float_type_node;
1087 : 79700 : if (mode == TYPE_MODE (complex_double_type_node))
1088 : 15932 : return complex_double_type_node;
1089 : 63768 : if (mode == TYPE_MODE (complex_long_double_type_node))
1090 : 15984 : return complex_long_double_type_node;
1091 : :
1092 : 47784 : inner_mode = GET_MODE_INNER (mode);
1093 : 47784 : inner_type = gm2_langhook_type_for_mode (inner_mode, unsignedp);
1094 : 47784 : if (inner_type != NULL_TREE)
1095 : 15928 : return build_complex_type (inner_type);
1096 : : }
1097 : :
1098 : : #if HOST_BITS_PER_WIDE_INT >= 64
1099 : : /* The middle-end and some backends rely on TImode being supported
1100 : : for 64-bit HWI. */
1101 : 63712 : if (mode == TImode)
1102 : : {
1103 : 0 : type = build_nonstandard_integer_type (GET_MODE_BITSIZE (TImode),
1104 : : unsignedp);
1105 : 0 : if (type && TYPE_MODE (type) == TImode)
1106 : : return type;
1107 : : }
1108 : : #endif
1109 : : return NULL_TREE;
1110 : : }
1111 : :
1112 : : /* Record a builtin function. We just ignore builtin functions. */
1113 : :
1114 : : static tree
1115 : 2484768 : gm2_langhook_builtin_function (tree decl)
1116 : : {
1117 : 2484768 : return decl;
1118 : : }
1119 : :
1120 : : /* Return true if we are in the global binding level. */
1121 : :
1122 : : static bool
1123 : 30220 : gm2_langhook_global_bindings_p (void)
1124 : : {
1125 : 30220 : return current_function_decl == NULL_TREE;
1126 : : }
1127 : :
1128 : : /* Unused langhook. */
1129 : :
1130 : : static tree
1131 : 0 : gm2_langhook_pushdecl (tree decl ATTRIBUTE_UNUSED)
1132 : : {
1133 : 0 : gcc_unreachable ();
1134 : : }
1135 : :
1136 : : /* This hook is used to get the current list of declarations as trees.
1137 : : We don't support that; instead we use write_globals. This can't
1138 : : simply crash because it is called by -gstabs. */
1139 : :
1140 : : static tree
1141 : 0 : gm2_langhook_getdecls (void)
1142 : : {
1143 : 0 : return NULL;
1144 : : }
1145 : :
1146 : : /* m2_write_global_declarations writes out globals creating an array
1147 : : of the declarations and calling wrapup_global_declarations. */
1148 : :
1149 : : static void
1150 : 14459 : m2_write_global_declarations (tree globals)
1151 : : {
1152 : 14459 : auto_vec<tree> global_decls;
1153 : 14459 : tree decl = globals;
1154 : 14459 : int n = 0;
1155 : :
1156 : 5783418 : while (decl != NULL)
1157 : : {
1158 : 5768959 : global_decls.safe_push (decl);
1159 : 5768959 : decl = TREE_CHAIN (decl);
1160 : 5768959 : n++;
1161 : : }
1162 : 28918 : wrapup_global_declarations (global_decls.address (), n);
1163 : 14459 : }
1164 : :
1165 : : /* Write out globals. */
1166 : :
1167 : : static void
1168 : 14459 : write_globals (void)
1169 : : {
1170 : 14459 : tree t;
1171 : 14459 : unsigned i;
1172 : :
1173 : 14459 : m2block_finishGlobals ();
1174 : :
1175 : : /* Process all file scopes in this compilation, and the
1176 : : external_scope, through wrapup_global_declarations and
1177 : : check_global_declarations. */
1178 : 43377 : FOR_EACH_VEC_ELT (*all_translation_units, i, t)
1179 : 14459 : m2_write_global_declarations (BLOCK_VARS (DECL_INITIAL (t)));
1180 : 14459 : }
1181 : :
1182 : :
1183 : : /* Gimplify an EXPR_STMT node. */
1184 : :
1185 : : static void
1186 : 2830 : gimplify_expr_stmt (tree *stmt_p)
1187 : : {
1188 : 2830 : gcc_assert (EXPR_STMT_EXPR (*stmt_p) != NULL_TREE);
1189 : 2830 : *stmt_p = EXPR_STMT_EXPR (*stmt_p);
1190 : 2830 : }
1191 : :
1192 : : /* Genericize a TRY_BLOCK. */
1193 : :
1194 : : static void
1195 : 2830 : genericize_try_block (tree *stmt_p)
1196 : : {
1197 : 2830 : tree body = TRY_STMTS (*stmt_p);
1198 : 2830 : tree cleanup = TRY_HANDLERS (*stmt_p);
1199 : :
1200 : 2830 : *stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup);
1201 : 2830 : }
1202 : :
1203 : : /* Genericize a HANDLER by converting to a CATCH_EXPR. */
1204 : :
1205 : : static void
1206 : 2830 : genericize_catch_block (tree *stmt_p)
1207 : : {
1208 : 2830 : tree type = HANDLER_TYPE (*stmt_p);
1209 : 2830 : tree body = HANDLER_BODY (*stmt_p);
1210 : :
1211 : : /* FIXME should the caught type go in TREE_TYPE? */
1212 : 2830 : *stmt_p = build2 (CATCH_EXPR, void_type_node, type, body);
1213 : 2830 : }
1214 : :
1215 : : /* Convert the tree representation of FNDECL from m2 frontend trees
1216 : : to GENERIC. */
1217 : :
1218 : : extern void pf (tree);
1219 : :
1220 : : void
1221 : 103684 : gm2_genericize (tree fndecl)
1222 : : {
1223 : 103684 : tree t;
1224 : 103684 : struct cgraph_node *cgn;
1225 : :
1226 : : #if 0
1227 : : pf (fndecl);
1228 : : #endif
1229 : : /* Fix up the types of parms passed by invisible reference. */
1230 : 275145 : for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t))
1231 : 171461 : if (TREE_ADDRESSABLE (TREE_TYPE (t)))
1232 : : {
1233 : :
1234 : : /* If a function's arguments are copied to create a thunk, then
1235 : : DECL_BY_REFERENCE will be set -- but the type of the argument will be
1236 : : a pointer type, so we will never get here. */
1237 : 0 : gcc_assert (!DECL_BY_REFERENCE (t));
1238 : 0 : gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
1239 : 0 : TREE_TYPE (t) = DECL_ARG_TYPE (t);
1240 : 0 : DECL_BY_REFERENCE (t) = 1;
1241 : 0 : TREE_ADDRESSABLE (t) = 0;
1242 : 0 : relayout_decl (t);
1243 : : }
1244 : :
1245 : : /* Dump all nested functions now. */
1246 : 103684 : cgn = cgraph_node::get_create (fndecl);
1247 : 104602 : for (cgn = first_nested_function (cgn);
1248 : 104602 : cgn != NULL; cgn = next_nested_function (cgn))
1249 : 918 : gm2_genericize (cgn->decl);
1250 : 103684 : }
1251 : :
1252 : : /* gm2 gimplify expression, currently just change THROW in the same
1253 : : way as C++ */
1254 : :
1255 : : static int
1256 : 8895809 : gm2_langhook_gimplify_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED,
1257 : : gimple_seq *post_p ATTRIBUTE_UNUSED)
1258 : : {
1259 : 8895809 : enum tree_code code = TREE_CODE (*expr_p);
1260 : :
1261 : 8895809 : switch (code)
1262 : : {
1263 : 324 : case THROW_EXPR:
1264 : :
1265 : : /* FIXME communicate throw type to back end, probably by moving
1266 : : THROW_EXPR into ../tree.def. */
1267 : 324 : *expr_p = TREE_OPERAND (*expr_p, 0);
1268 : 324 : return GS_OK;
1269 : :
1270 : 2830 : case EXPR_STMT:
1271 : 2830 : gimplify_expr_stmt (expr_p);
1272 : 2830 : return GS_OK;
1273 : :
1274 : 2830 : case TRY_BLOCK:
1275 : 2830 : genericize_try_block (expr_p);
1276 : 2830 : return GS_OK;
1277 : :
1278 : 2830 : case HANDLER:
1279 : 2830 : genericize_catch_block (expr_p);
1280 : 2830 : return GS_OK;
1281 : :
1282 : : default:
1283 : : return GS_UNHANDLED;
1284 : : }
1285 : : }
1286 : :
1287 : : static GTY(()) tree gm2_eh_personality_decl;
1288 : :
1289 : : static tree
1290 : 2865 : gm2_langhook_eh_personality (void)
1291 : : {
1292 : 2865 : if (!gm2_eh_personality_decl)
1293 : 2710 : gm2_eh_personality_decl = build_personality_function ("gxx");
1294 : :
1295 : 2865 : return gm2_eh_personality_decl;
1296 : : }
1297 : :
1298 : : /* Functions called directly by the generic backend. */
1299 : :
1300 : : tree
1301 : 7410204 : convert_loc (location_t location, tree type, tree expr)
1302 : : {
1303 : 7410204 : if (type == error_mark_node || expr == error_mark_node
1304 : 14820402 : || TREE_TYPE (expr) == error_mark_node)
1305 : : return error_mark_node;
1306 : :
1307 : 7410198 : if (type == TREE_TYPE (expr))
1308 : : return expr;
1309 : :
1310 : 3406754 : gcc_assert (TYPE_MAIN_VARIANT (type) != NULL);
1311 : 3406754 : if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
1312 : 0 : return fold_convert (type, expr);
1313 : :
1314 : 3406754 : expr = m2convert_GenericToType (location, type, expr);
1315 : 3406754 : switch (TREE_CODE (type))
1316 : : {
1317 : 88821 : case VOID_TYPE:
1318 : 88821 : case BOOLEAN_TYPE:
1319 : 88821 : return fold (convert_to_integer (type, expr));
1320 : 2752056 : case INTEGER_TYPE:
1321 : 2752056 : return fold (convert_to_integer (type, expr));
1322 : 517881 : case POINTER_TYPE:
1323 : 517881 : return fold (convert_to_pointer (type, expr));
1324 : 3968 : case REAL_TYPE:
1325 : 3968 : return fold (convert_to_real (type, expr));
1326 : 216 : case COMPLEX_TYPE:
1327 : 216 : return fold (convert_to_complex (type, expr));
1328 : 43806 : case ENUMERAL_TYPE:
1329 : 43806 : return fold (convert_to_integer (type, expr));
1330 : 6 : default:
1331 : 6 : error_at (location, "cannot convert expression, only base types can be converted");
1332 : 6 : break;
1333 : : }
1334 : 6 : return error_mark_node;
1335 : : }
1336 : :
1337 : : /* Functions called directly by the generic backend. */
1338 : :
1339 : : tree
1340 : 650183 : convert (tree type, tree expr)
1341 : : {
1342 : 650183 : return convert_loc (m2linemap_UnknownLocation (), type, expr);
1343 : : }
1344 : :
1345 : : /* Mark EXP saying that we need to be able to take the address of it;
1346 : : it should not be allocated in a register. Returns true if
1347 : : successful. */
1348 : :
1349 : : bool
1350 : 2717321 : gm2_mark_addressable (tree exp)
1351 : : {
1352 : 2717321 : tree x = exp;
1353 : :
1354 : 2767777 : while (TRUE)
1355 : 2767777 : switch (TREE_CODE (x))
1356 : : {
1357 : 7266 : case COMPONENT_REF:
1358 : 7266 : if (DECL_PACKED (TREE_OPERAND (x, 1)))
1359 : : return false;
1360 : 7266 : x = TREE_OPERAND (x, 0);
1361 : 7266 : break;
1362 : :
1363 : 43190 : case ADDR_EXPR:
1364 : 43190 : case ARRAY_REF:
1365 : 43190 : case REALPART_EXPR:
1366 : 43190 : case IMAGPART_EXPR:
1367 : 43190 : x = TREE_OPERAND (x, 0);
1368 : 43190 : break;
1369 : :
1370 : 2710359 : case COMPOUND_LITERAL_EXPR:
1371 : 2710359 : case CONSTRUCTOR:
1372 : 2710359 : case STRING_CST:
1373 : 2710359 : case VAR_DECL:
1374 : 2710359 : case CONST_DECL:
1375 : 2710359 : case PARM_DECL:
1376 : 2710359 : case RESULT_DECL:
1377 : 2710359 : case FUNCTION_DECL:
1378 : 2710359 : TREE_ADDRESSABLE (x) = 1;
1379 : 2710359 : return true;
1380 : : default:
1381 : : return true;
1382 : : }
1383 : : /* Never reach here. */
1384 : : gcc_unreachable ();
1385 : : }
1386 : :
1387 : : /* Return an integer type with BITS bits of precision, that is
1388 : : unsigned if UNSIGNEDP is nonzero, otherwise signed. */
1389 : :
1390 : : tree
1391 : 247112 : gm2_type_for_size (unsigned int bits, int unsignedp)
1392 : : {
1393 : 247112 : if (unsignedp)
1394 : : {
1395 : 85973 : if (bits == INT_TYPE_SIZE)
1396 : 26336 : return unsigned_type_node;
1397 : 59637 : else if (bits == CHAR_TYPE_SIZE)
1398 : 22392 : return unsigned_char_type_node;
1399 : 37245 : else if (bits == SHORT_TYPE_SIZE)
1400 : 172 : return short_unsigned_type_node;
1401 : 37526 : else if (bits == LONG_TYPE_SIZE)
1402 : 36614 : return long_unsigned_type_node;
1403 : 459 : else if (bits == LONG_LONG_TYPE_SIZE)
1404 : 453 : return long_long_unsigned_type_node;
1405 : : else
1406 : 6 : return build_nonstandard_integer_type (bits,
1407 : 6 : unsignedp);
1408 : : }
1409 : : else
1410 : : {
1411 : 161139 : if (bits == INT_TYPE_SIZE)
1412 : 3047 : return integer_type_node;
1413 : 158092 : else if (bits == CHAR_TYPE_SIZE)
1414 : 24 : return signed_char_type_node;
1415 : 158068 : else if (bits == SHORT_TYPE_SIZE)
1416 : 138 : return short_integer_type_node;
1417 : 158330 : else if (bits == LONG_TYPE_SIZE)
1418 : 141908 : return long_integer_type_node;
1419 : 16022 : else if (bits == LONG_LONG_TYPE_SIZE)
1420 : 400 : return long_long_integer_type_node;
1421 : : else
1422 : 15622 : return build_nonstandard_integer_type (bits,
1423 : 15622 : unsignedp);
1424 : : }
1425 : : /* Never reach here. */
1426 : : gcc_unreachable ();
1427 : : }
1428 : :
1429 : : /* Allow the analyzer to understand Storage ALLOCATE/DEALLOCATE. */
1430 : :
1431 : : bool
1432 : 0 : gm2_langhook_new_dispose_storage_substitution (void)
1433 : : {
1434 : 0 : return true;
1435 : : }
1436 : :
1437 : : #undef LANG_HOOKS_NAME
1438 : : #undef LANG_HOOKS_INIT
1439 : : #undef LANG_HOOKS_INIT_OPTIONS
1440 : : #undef LANG_HOOKS_OPTION_LANG_MASK
1441 : : #undef LANG_HOOKS_INIT_OPTIONS_STRUCT
1442 : : #undef LANG_HOOKS_HANDLE_OPTION
1443 : : #undef LANG_HOOKS_POST_OPTIONS
1444 : : #undef LANG_HOOKS_PARSE_FILE
1445 : : #undef LANG_HOOKS_TYPE_FOR_MODE
1446 : : #undef LANG_HOOKS_TYPE_FOR_SIZE
1447 : : #undef LANG_HOOKS_BUILTIN_FUNCTION
1448 : : #undef LANG_HOOKS_GLOBAL_BINDINGS_P
1449 : : #undef LANG_HOOKS_PUSHDECL
1450 : : #undef LANG_HOOKS_GETDECLS
1451 : : #undef LANG_HOOKS_GIMPLIFY_EXPR
1452 : : #undef LANG_HOOKS_EH_PERSONALITY
1453 : : #undef LANG_HOOKS_NEW_DISPOSE_STORAGE_SUBSTITUTION
1454 : :
1455 : : #define LANG_HOOKS_NAME "GNU Modula-2"
1456 : : #define LANG_HOOKS_INIT gm2_langhook_init
1457 : : #define LANG_HOOKS_INIT_OPTIONS gm2_langhook_init_options
1458 : : #define LANG_HOOKS_OPTION_LANG_MASK gm2_langhook_option_lang_mask
1459 : : #define LANG_HOOKS_INIT_OPTIONS_STRUCT gm2_langhook_init_options_struct
1460 : : #define LANG_HOOKS_HANDLE_OPTION gm2_langhook_handle_option
1461 : : #define LANG_HOOKS_POST_OPTIONS gm2_langhook_post_options
1462 : : #define LANG_HOOKS_PARSE_FILE gm2_langhook_parse_file
1463 : : #define LANG_HOOKS_TYPE_FOR_MODE gm2_langhook_type_for_mode
1464 : : #define LANG_HOOKS_TYPE_FOR_SIZE gm2_langhook_type_for_size
1465 : : #define LANG_HOOKS_BUILTIN_FUNCTION gm2_langhook_builtin_function
1466 : : #define LANG_HOOKS_GLOBAL_BINDINGS_P gm2_langhook_global_bindings_p
1467 : : #define LANG_HOOKS_PUSHDECL gm2_langhook_pushdecl
1468 : : #define LANG_HOOKS_GETDECLS gm2_langhook_getdecls
1469 : : #define LANG_HOOKS_GIMPLIFY_EXPR gm2_langhook_gimplify_expr
1470 : : #define LANG_HOOKS_EH_PERSONALITY gm2_langhook_eh_personality
1471 : : #define LANG_HOOKS_NEW_DISPOSE_STORAGE_SUBSTITUTION \
1472 : : gm2_langhook_new_dispose_storage_substitution
1473 : :
1474 : : struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
1475 : :
1476 : : #include "gt-m2-gm2-lang.h"
1477 : : #include "gtype-m2.h"
|