1 /* gm2-lang.cc language-dependent hooks for GNU Modula-2.
3 Copyright (C) 2002-2022 Free Software Foundation, Inc.
4 Contributed by Gaius Mulley <gaius@glam.ac.uk>.
6 This file is part of GNU Modula-2.
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)
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.
18 You should have received a copy of the GNU General Public License
19 along with GNU Modula-2; see the file COPYING. If not, write to the
20 Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
23 #include "gm2-gcc/gcc-consolidation.h"
25 #include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name. */
26 #include "tree-pass.h" /* FIXME: only for PROP_gimple_any. */
35 #include "dynamicstrings.h"
36 #include "m2options.h"
37 #include "m2convert.h"
38 #include "m2linemap.h"
44 static void write_globals (void);
46 static int insideCppArgs
= FALSE
;
48 #define EXPR_STMT_EXPR(NODE) TREE_OPERAND (EXPR_STMT_CHECK (NODE), 0)
50 /* start of new stuff. */
52 /* Language-dependent contents of a type. */
54 struct GTY (()) lang_type
59 /* Language-dependent contents of a decl. */
61 struct GTY (()) lang_decl
66 /* Language-dependent contents of an identifier. This must include a
69 struct GTY (()) lang_identifier
71 struct tree_identifier common
;
74 /* The resulting tree type. */
76 union GTY ((desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
77 chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), "
78 "TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN "
79 "(&%h.generic)) : NULL"))) lang_tree_node
81 union tree_node
GTY ((tag ("0"),
82 desc ("tree_node_structure (&%h)"))) generic
;
83 struct lang_identifier
GTY ((tag ("1"))) identifier
;
86 struct GTY (()) language_function
89 /* While we are parsing the function, this contains information about
90 the statement-tree that we are building. */
91 /* struct stmt_tree_s stmt_tree; */
98 gm2_langhook_init (void)
100 build_common_tree_nodes (false);
101 build_common_builtin_nodes ();
103 /* The default precision for floating point numbers. This is used
104 for floating point constants with abstract type. This may eventually
105 be controllable by a command line option. */
106 mpfr_set_default_prec (256);
108 /* GNU Modula-2 uses exceptions. */
109 using_eh_for_cleanups ();
113 /* The option mask. */
116 gm2_langhook_option_lang_mask (void)
121 /* Initialize the options structure. */
124 gm2_langhook_init_options_struct (struct gcc_options
*opts
)
126 /* Default to avoiding range issues for complex multiply and divide. */
127 opts
->x_flag_complex_method
= 2;
129 /* The builtin math functions should not set errno. */
130 opts
->x_flag_errno_math
= 0;
131 opts
->frontend_set_flag_errno_math
= true;
133 /* Exceptions are used. */
134 opts
->x_flag_exceptions
= 1;
135 init_FrontEndInit ();
138 /* Infrastructure for a VEC of bool values. */
140 /* This array determines whether the filename is associated with the
143 static vec
<bool> filename_cpp
;
146 gm2_langhook_init_options (unsigned int decoded_options_count
,
147 struct cl_decoded_option
*decoded_options
)
150 bool in_cpp_args
= false;
152 for (i
= 1; i
< decoded_options_count
; i
++)
154 switch (decoded_options
[i
].opt_index
)
162 case OPT_SPECIAL_input_file
:
163 case OPT_SPECIAL_program_name
:
164 filename_cpp
.safe_push (in_cpp_args
);
167 filename_cpp
.safe_push (false);
171 is_cpp_filename (unsigned int i
)
173 gcc_assert (i
< filename_cpp
.length ());
174 return filename_cpp
[i
];
177 /* Handle gm2 specific options. Return 0 if we didn't do anything. */
180 gm2_langhook_handle_option (
181 size_t scode
, const char *arg
, HOST_WIDE_INT value
, int kind ATTRIBUTE_UNUSED
,
182 location_t loc ATTRIBUTE_UNUSED
,
183 const struct cl_option_handlers
*handlers ATTRIBUTE_UNUSED
)
185 enum opt_code code
= (enum opt_code
)scode
;
187 /* ignore file names. */
194 M2Options_SetB (arg
);
197 M2Options_Setc (value
);
202 const struct cl_option
*option
= &cl_options
[scode
];
203 const char *opt
= (const char *)option
->opt_text
;
204 M2Options_CppArg (opt
, arg
, TRUE
);
207 M2Options_SetSearchPath (arg
);
210 M2Options_SetISO (value
);
213 M2Options_SetPIM (value
);
216 M2Options_SetPIM2 (value
);
219 M2Options_SetPIM3 (value
);
222 M2Options_SetPIM4 (value
);
224 case OPT_fpositive_mod_floor_div
:
225 M2Options_SetPositiveModFloor (value
);
228 /* handled in the gm2 driver. */
230 case OPT_fgen_module_list_
:
231 M2Options_SetGenModuleList (value
, arg
);
234 M2Options_SetNilCheck (value
);
237 M2Options_SetWholeDiv (value
);
240 M2Options_SetIndex (value
);
243 M2Options_SetRange (value
);
245 case OPT_ffloatvalue
:
246 M2Options_SetFloatValueCheck (value
);
248 case OPT_fwholevalue
:
249 M2Options_SetWholeValueCheck (value
);
252 M2Options_SetReturnCheck (value
);
255 M2Options_SetCaseCheck (value
);
258 M2Options_SetCompilerDebugging (value
);
260 case OPT_fdebug_trace_quad
:
261 M2Options_SetDebugTraceQuad (value
);
263 case OPT_fdebug_trace_api
:
264 M2Options_SetDebugTraceAPI (value
);
266 case OPT_fdebug_function_line_numbers
:
267 M2Options_SetDebugFunctionLineNumbers (value
);
270 M2Options_SetAutoInit (value
);
272 case OPT_fsoft_check_all
:
273 M2Options_SetCheckAll (value
);
275 case OPT_fexceptions
:
276 M2Options_SetExceptions (value
);
279 M2Options_SetStyle (value
);
282 M2Options_SetPedantic (value
);
284 case OPT_Wpedantic_param_names
:
285 M2Options_SetPedanticParamNames (value
);
287 case OPT_Wpedantic_cast
:
288 M2Options_SetPedanticCast (value
);
290 case OPT_fextended_opaque
:
291 M2Options_SetExtendedOpaque (value
);
293 case OPT_Wverbose_unbounded
:
294 M2Options_SetVerboseUnbounded (value
);
296 case OPT_Wunused_variable
:
297 M2Options_SetUnusedVariableChecking (value
);
299 case OPT_Wunused_parameter
:
300 M2Options_SetUnusedParameterChecking (value
);
302 case OPT_fm2_strict_type
:
303 M2Options_SetStrictTypeChecking (value
);
306 M2Options_SetWall (value
);
309 /* Not yet implemented. */
311 M2Options_SetXCode (value
);
314 case OPT_fm2_lower_case
:
315 M2Options_SetLowerCaseKeywords (value
);
318 M2Options_SetUselist (value
, arg
);
320 case OPT_fruntime_modules_
:
321 M2Options_SetRuntimeModuleOverride (arg
);
324 /* Handled in the driver. */
327 /* Handled in the driver. */
329 case OPT_fscaffold_dynamic
:
330 M2Options_SetScaffoldDynamic (value
);
332 case OPT_fscaffold_static
:
333 M2Options_SetScaffoldStatic (value
);
335 case OPT_fscaffold_main
:
336 M2Options_SetScaffoldMain (value
);
339 M2Options_SetCpp (value
);
342 insideCppArgs
= TRUE
;
345 insideCppArgs
= FALSE
;
348 M2Options_SetQuadDebugging (value
);
351 M2Options_SetSources (value
);
353 case OPT_funbounded_by_reference
:
354 M2Options_SetUnboundedByReference (value
);
357 M2Options_setdefextension (arg
);
360 M2Options_setmodextension (arg
);
362 case OPT_fdump_system_exports
:
363 M2Options_SetDumpSystemExports (value
);
366 M2Options_SetSwig (value
);
369 M2Options_SetShared (value
);
371 case OPT_fm2_statistics
:
372 M2Options_SetStatistics (value
);
375 M2Options_SetM2g (value
);
378 M2Options_SetOptimizing (value
);
381 M2Options_SetQuiet (value
);
383 case OPT_fm2_whole_program
:
384 M2Options_SetWholeProgram (value
);
387 if (strcmp (arg
, "builtins") == 0)
389 M2Options_SetForcedLocation (BUILTINS_LOCATION
);
392 else if (strcmp (arg
, "unknown") == 0)
394 M2Options_SetForcedLocation (UNKNOWN_LOCATION
);
397 else if ((arg
!= NULL
) && (ISDIGIT (arg
[0])))
399 M2Options_SetForcedLocation (atoi (arg
));
405 M2Options_SetSaveTemps (value
);
407 case OPT_save_temps_
:
408 M2Options_SetSaveTempsDir (arg
);
413 const struct cl_option
*option
= &cl_options
[scode
];
414 const char *opt
= (const char *)option
->opt_text
;
416 M2Options_CppArg (opt
, arg
, TRUE
);
424 /* Run after parsing options. */
427 gm2_langhook_post_options (const char **pfilename
)
429 const char *filename
= *pfilename
;
430 flag_excess_precision
= EXCESS_PRECISION_FAST
;
431 M2Options_SetCC1Quiet (quiet_flag
);
432 M2Options_FinaliseOptions ();
433 main_input_filename
= filename
;
435 /* Returning false means that the backend should be used. */
439 /* Call the compiler for every source filename on the command line. */
442 gm2_parse_input_files (const char **filenames
, unsigned int filename_count
)
445 gcc_assert (filename_count
> 0);
447 for (i
= 0; i
< filename_count
; i
++)
448 if (!is_cpp_filename (i
))
450 main_input_filename
= filenames
[i
];
451 init_PerCompilationInit (filenames
[i
]);
456 gm2_langhook_parse_file (void)
458 gm2_parse_input_files (in_fnames
, num_in_fnames
);
463 gm2_langhook_type_for_size (unsigned int bits
, int unsignedp
)
465 return gm2_type_for_size (bits
, unsignedp
);
469 gm2_langhook_type_for_mode (machine_mode mode
, int unsignedp
)
473 for (int i
= 0; i
< NUM_INT_N_ENTS
; i
++)
474 if (int_n_enabled_p
[i
]
475 && mode
== int_n_data
[i
].m
)
476 return (unsignedp
? int_n_trees
[i
].unsigned_type
477 : int_n_trees
[i
].signed_type
);
479 if (VECTOR_MODE_P (mode
))
483 inner
= gm2_langhook_type_for_mode (GET_MODE_INNER (mode
), unsignedp
);
484 if (inner
!= NULL_TREE
)
485 return build_vector_type_for_mode (inner
, mode
);
489 scalar_int_mode imode
;
490 if (is_int_mode (mode
, &imode
))
491 return gm2_langhook_type_for_size (GET_MODE_BITSIZE (imode
), unsignedp
);
493 if (mode
== TYPE_MODE (float_type_node
))
494 return float_type_node
;
496 if (mode
== TYPE_MODE (double_type_node
))
497 return double_type_node
;
499 if (mode
== TYPE_MODE (long_double_type_node
))
500 return long_double_type_node
;
502 if (COMPLEX_MODE_P (mode
))
504 if (mode
== TYPE_MODE (complex_float_type_node
))
505 return complex_float_type_node
;
506 if (mode
== TYPE_MODE (complex_double_type_node
))
507 return complex_double_type_node
;
508 if (mode
== TYPE_MODE (complex_long_double_type_node
))
509 return complex_long_double_type_node
;
512 #if HOST_BITS_PER_WIDE_INT >= 64
513 /* The middle-end and some backends rely on TImode being supported
517 type
= build_nonstandard_integer_type (GET_MODE_BITSIZE (TImode
),
519 if (type
&& TYPE_MODE (type
) == TImode
)
526 /* Record a builtin function. We just ignore builtin functions. */
529 gm2_langhook_builtin_function (tree decl
)
534 /* Return true if we are in the global binding level. */
537 gm2_langhook_global_bindings_p (void)
539 return current_function_decl
== NULL_TREE
;
542 /* Unused langhook. */
545 gm2_langhook_pushdecl (tree decl ATTRIBUTE_UNUSED
)
550 /* This hook is used to get the current list of declarations as trees.
551 We don't support that; instead we use write_globals. This can't
552 simply crash because it is called by -gstabs. */
555 gm2_langhook_getdecls (void)
560 /* m2_write_global_declarations writes out globals creating an array
561 of the declarations and calling wrapup_global_declarations. */
564 m2_write_global_declarations (tree globals
)
566 auto_vec
<tree
> global_decls
;
572 global_decls
.safe_push (decl
);
573 decl
= TREE_CHAIN (decl
);
576 wrapup_global_declarations (global_decls
.address (), n
);
579 /* Write out globals. */
587 m2block_finishGlobals ();
589 /* Process all file scopes in this compilation, and the
590 external_scope, through wrapup_global_declarations and
591 check_global_declarations. */
592 FOR_EACH_VEC_ELT (*all_translation_units
, i
, t
)
593 m2_write_global_declarations (BLOCK_VARS (DECL_INITIAL (t
)));
597 /* Gimplify an EXPR_STMT node. */
600 gimplify_expr_stmt (tree
*stmt_p
)
602 gcc_assert (EXPR_STMT_EXPR (*stmt_p
) != NULL_TREE
);
603 *stmt_p
= EXPR_STMT_EXPR (*stmt_p
);
606 /* Genericize a TRY_BLOCK. */
609 genericize_try_block (tree
*stmt_p
)
611 tree body
= TRY_STMTS (*stmt_p
);
612 tree cleanup
= TRY_HANDLERS (*stmt_p
);
614 *stmt_p
= build2 (TRY_CATCH_EXPR
, void_type_node
, body
, cleanup
);
617 /* Genericize a HANDLER by converting to a CATCH_EXPR. */
620 genericize_catch_block (tree
*stmt_p
)
622 tree type
= HANDLER_TYPE (*stmt_p
);
623 tree body
= HANDLER_BODY (*stmt_p
);
625 /* FIXME should the caught type go in TREE_TYPE? */
626 *stmt_p
= build2 (CATCH_EXPR
, void_type_node
, type
, body
);
629 /* Convert the tree representation of FNDECL from m2 frontend trees
632 extern void pf (tree
);
635 gm2_genericize (tree fndecl
)
638 struct cgraph_node
*cgn
;
643 /* Fix up the types of parms passed by invisible reference. */
644 for (t
= DECL_ARGUMENTS (fndecl
); t
; t
= DECL_CHAIN (t
))
645 if (TREE_ADDRESSABLE (TREE_TYPE (t
)))
648 /* If a function's arguments are copied to create a thunk, then
649 DECL_BY_REFERENCE will be set -- but the type of the argument will be
650 a pointer type, so we will never get here. */
651 gcc_assert (!DECL_BY_REFERENCE (t
));
652 gcc_assert (DECL_ARG_TYPE (t
) != TREE_TYPE (t
));
653 TREE_TYPE (t
) = DECL_ARG_TYPE (t
);
654 DECL_BY_REFERENCE (t
) = 1;
655 TREE_ADDRESSABLE (t
) = 0;
659 /* Dump all nested functions now. */
660 cgn
= cgraph_node::get_create (fndecl
);
661 for (cgn
= first_nested_function (cgn
);
662 cgn
!= NULL
; cgn
= next_nested_function (cgn
))
663 gm2_genericize (cgn
->decl
);
666 /* gm2 gimplify expression, currently just change THROW in the same
670 gm2_langhook_gimplify_expr (tree
*expr_p
, gimple_seq
*pre_p ATTRIBUTE_UNUSED
,
671 gimple_seq
*post_p ATTRIBUTE_UNUSED
)
673 enum tree_code code
= TREE_CODE (*expr_p
);
679 /* FIXME communicate throw type to back end, probably by moving
680 THROW_EXPR into ../tree.def. */
681 *expr_p
= TREE_OPERAND (*expr_p
, 0);
685 gimplify_expr_stmt (expr_p
);
689 genericize_try_block (expr_p
);
693 genericize_catch_block (expr_p
);
701 static GTY(()) tree gm2_eh_personality_decl
;
704 gm2_langhook_eh_personality (void)
706 if (!gm2_eh_personality_decl
)
707 gm2_eh_personality_decl
= build_personality_function ("gxx");
709 return gm2_eh_personality_decl
;
712 /* Functions called directly by the generic backend. */
715 convert_loc (location_t location
, tree type
, tree expr
)
717 if (type
== error_mark_node
|| expr
== error_mark_node
718 || TREE_TYPE (expr
) == error_mark_node
)
719 return error_mark_node
;
721 if (type
== TREE_TYPE (expr
))
724 gcc_assert (TYPE_MAIN_VARIANT (type
) != NULL
);
725 if (TYPE_MAIN_VARIANT (type
) == TYPE_MAIN_VARIANT (TREE_TYPE (expr
)))
726 return fold_convert (type
, expr
);
728 expr
= m2convert_GenericToType (location
, type
, expr
);
729 switch (TREE_CODE (type
))
733 return fold_convert (type
, expr
);
735 return fold (convert_to_integer (type
, expr
));
737 return fold (convert_to_pointer (type
, expr
));
739 return fold (convert_to_real (type
, expr
));
741 return fold (convert_to_complex (type
, expr
));
743 return fold (convert_to_integer (type
, expr
));
745 error_at (location
, "cannot convert expression, only base types can be converted");
748 return error_mark_node
;
751 /* Functions called directly by the generic backend. */
754 convert (tree type
, tree expr
)
756 return convert_loc (m2linemap_UnknownLocation (), type
, expr
);
759 /* Mark EXP saying that we need to be able to take the address of it;
760 it should not be allocated in a register. Returns true if
764 gm2_mark_addressable (tree exp
)
769 switch (TREE_CODE (x
))
772 if (DECL_PACKED (TREE_OPERAND (x
, 1)))
774 x
= TREE_OPERAND (x
, 0);
781 x
= TREE_OPERAND (x
, 0);
784 case COMPOUND_LITERAL_EXPR
:
792 TREE_ADDRESSABLE (x
) = 1;
797 /* Never reach here. */
801 /* Return an integer type with BITS bits of precision, that is
802 unsigned if UNSIGNEDP is nonzero, otherwise signed. */
805 gm2_type_for_size (unsigned int bits
, int unsignedp
)
811 if (bits
== INT_TYPE_SIZE
)
812 type
= unsigned_type_node
;
813 else if (bits
== CHAR_TYPE_SIZE
)
814 type
= unsigned_char_type_node
;
815 else if (bits
== SHORT_TYPE_SIZE
)
816 type
= short_unsigned_type_node
;
817 else if (bits
== LONG_TYPE_SIZE
)
818 type
= long_unsigned_type_node
;
819 else if (bits
== LONG_LONG_TYPE_SIZE
)
820 type
= long_long_unsigned_type_node
;
822 type
= build_nonstandard_integer_type (bits
,
827 if (bits
== INT_TYPE_SIZE
)
828 type
= integer_type_node
;
829 else if (bits
== CHAR_TYPE_SIZE
)
830 type
= signed_char_type_node
;
831 else if (bits
== SHORT_TYPE_SIZE
)
832 type
= short_integer_type_node
;
833 else if (bits
== LONG_TYPE_SIZE
)
834 type
= long_integer_type_node
;
835 else if (bits
== LONG_LONG_TYPE_SIZE
)
836 type
= long_long_integer_type_node
;
838 type
= build_nonstandard_integer_type (bits
,
844 /* Allow the analyzer to understand Storage ALLOCATE/DEALLOCATE. */
847 gm2_langhook_new_dispose_storage_substitution (void)
852 #undef LANG_HOOKS_NAME
853 #undef LANG_HOOKS_INIT
854 #undef LANG_HOOKS_INIT_OPTIONS
855 #undef LANG_HOOKS_OPTION_LANG_MASK
856 #undef LANG_HOOKS_INIT_OPTIONS_STRUCT
857 #undef LANG_HOOKS_HANDLE_OPTION
858 #undef LANG_HOOKS_POST_OPTIONS
859 #undef LANG_HOOKS_PARSE_FILE
860 #undef LANG_HOOKS_TYPE_FOR_MODE
861 #undef LANG_HOOKS_TYPE_FOR_SIZE
862 #undef LANG_HOOKS_BUILTIN_FUNCTION
863 #undef LANG_HOOKS_GLOBAL_BINDINGS_P
864 #undef LANG_HOOKS_PUSHDECL
865 #undef LANG_HOOKS_GETDECLS
866 #undef LANG_HOOKS_GIMPLIFY_EXPR
867 #undef LANG_HOOKS_EH_PERSONALITY
868 #undef LANG_HOOKS_NEW_DISPOSE_STORAGE_SUBSTITUTION
870 #define LANG_HOOKS_NAME "GNU Modula-2"
871 #define LANG_HOOKS_INIT gm2_langhook_init
872 #define LANG_HOOKS_INIT_OPTIONS gm2_langhook_init_options
873 #define LANG_HOOKS_OPTION_LANG_MASK gm2_langhook_option_lang_mask
874 #define LANG_HOOKS_INIT_OPTIONS_STRUCT gm2_langhook_init_options_struct
875 #define LANG_HOOKS_HANDLE_OPTION gm2_langhook_handle_option
876 #define LANG_HOOKS_POST_OPTIONS gm2_langhook_post_options
877 #define LANG_HOOKS_PARSE_FILE gm2_langhook_parse_file
878 #define LANG_HOOKS_TYPE_FOR_MODE gm2_langhook_type_for_mode
879 #define LANG_HOOKS_TYPE_FOR_SIZE gm2_langhook_type_for_size
880 #define LANG_HOOKS_BUILTIN_FUNCTION gm2_langhook_builtin_function
881 #define LANG_HOOKS_GLOBAL_BINDINGS_P gm2_langhook_global_bindings_p
882 #define LANG_HOOKS_PUSHDECL gm2_langhook_pushdecl
883 #define LANG_HOOKS_GETDECLS gm2_langhook_getdecls
884 #define LANG_HOOKS_GIMPLIFY_EXPR gm2_langhook_gimplify_expr
885 #define LANG_HOOKS_EH_PERSONALITY gm2_langhook_eh_personality
886 #define LANG_HOOKS_NEW_DISPOSE_STORAGE_SUBSTITUTION \
887 gm2_langhook_new_dispose_storage_substitution
889 struct lang_hooks lang_hooks
= LANG_HOOKS_INITIALIZER
;
891 #include "gt-m2-gm2-lang.h"
892 #include "gtype-m2.h"