misc.c 47.2 KB
Newer Older
1 2 3 4 5 6 7 8
/****************************************************************************
 *                                                                          *
 *                         GNAT COMPILER COMPONENTS                         *
 *                                                                          *
 *                                 M I S C                                  *
 *                                                                          *
 *                           C Implementation File                          *
 *                                                                          *
Eric Botcazou committed
9
 *          Copyright (C) 1992-2018, Free Software Foundation, Inc.         *
10 11 12
 *                                                                          *
 * GNAT is free software;  you can  redistribute it  and/or modify it under *
 * terms of the  GNU General Public License as published  by the Free Soft- *
13
 * ware  Foundation;  either version 3,  or (at your option) any later ver- *
14 15 16 17
 * sion.  GNAT is distributed in the hope that it will be useful, but WITH- *
 * OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY *
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License *
 * for  more details.  You should have  received  a copy of the GNU General *
18 19
 * Public License  distributed  with GNAT;  see file  COPYING3.  If not see *
 * <http://www.gnu.org/licenses/>.                                          *
20 21 22 23 24 25 26 27 28
 *                                                                          *
 * GNAT was originally developed  by the GNAT team at  New York University. *
 * Extensive contributions were provided by Ada Core Technologies Inc.      *
 *                                                                          *
 ****************************************************************************/

#include "config.h"
#include "system.h"
#include "coretypes.h"
29 30 31
#include "target.h"
#include "tree.h"
#include "diagnostic.h"
32
#include "opts.h"
33 34
#include "alias.h"
#include "fold-const.h"
35 36
#include "stor-layout.h"
#include "print-tree.h"
37 38 39
#include "toplev.h"
#include "langhooks.h"
#include "langhooks-def.h"
40
#include "plugin.h"
41
#include "calls.h"	/* For pass_by_reference.  */
42
#include "dwarf2out.h"
43 44

#include "ada.h"
45
#include "adadecode.h"
46 47 48 49 50 51 52 53 54 55 56
#include "types.h"
#include "atree.h"
#include "namet.h"
#include "nlists.h"
#include "uintp.h"
#include "fe.h"
#include "sinfo.h"
#include "einfo.h"
#include "ada-tree.h"
#include "gigi.h"

Javier Miranda committed
57 58 59
/* This symbol needs to be defined for the front-end.  */
void *callgraph_info_file = NULL;

60 61
/* Command-line argc and argv.  These variables are global since they are
   imported in back_end.adb.  */
62 63 64
unsigned int save_argc;
const char **save_argv;

65
/* GNAT argc and argv generated by the binder for all Ada programs.  */
66
extern int gnat_argc;
67 68 69 70
extern const char **gnat_argv;

/* Ada code requires variables for these settings rather than elements
   of the global_options structure because they are imported.  */
71 72
#undef gnat_encodings
enum dwarf_gnat_encodings gnat_encodings = DWARF_GNAT_ENCODINGS_DEFAULT;
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87

#undef optimize
int optimize;

#undef optimize_size
int optimize_size;

#undef flag_compare_debug
int flag_compare_debug;

#undef flag_short_enums
int flag_short_enums;

#undef flag_stack_check
enum stack_check_type flag_stack_check = NO_STACK_CHECK;
88

89 90 91 92
#ifdef __cplusplus
extern "C" {
#endif

93
/* Declare functions we use as part of startup.  */
94 95 96 97
extern void __gnat_initialize (void *);
extern void __gnat_install_SEH_handler (void *);
extern void adainit (void);
extern void _ada_gnat1drv (void);
98

99 100 101 102
#ifdef __cplusplus
}
#endif

103 104 105
/* The parser for the language.  For us, we process the GNAT tree.  */

static void
106
gnat_parse_file (void)
107 108 109 110 111 112 113 114
{
  int seh[2];

  /* Call the target specific initializations.  */
  __gnat_initialize (NULL);

  /* ??? Call the SEH initialization routine.  This is to workaround
  a bootstrap path problem.  The call below should be removed at some
115 116
  point and the SEH pointer passed to __gnat_initialize above.  */
  __gnat_install_SEH_handler ((void *)seh);
117 118 119 120 121 122

  /* Call the front-end elaboration procedures.  */
  adainit ();

  /* Call the front end.  */
  _ada_gnat1drv ();
123

124 125
  /* Write the global declarations.  */
  gnat_write_global_declarations ();
126 127
}

128 129 130 131 132 133 134 135
/* Return language mask for option processing.  */

static unsigned int
gnat_option_lang_mask (void)
{
  return CL_Ada;
}

136 137
/* Decode all the language specific options that cannot be decoded by GCC.
   The option decoding phase of GCC calls this routine on the flags that
138
   are marked as Ada-specific.  Return true on success or false on failure.  */
139

140
static bool
141 142
gnat_handle_option (size_t scode, const char *arg, int value, int kind,
		    location_t loc, const struct cl_option_handlers *handlers)
143 144 145 146 147 148
{
  enum opt_code code = (enum opt_code) scode;

  switch (code)
    {
    case OPT_Wall:
149 150 151
      handle_generated_option (&global_options, &global_options_set,
			       OPT_Wunused, NULL, value,
			       gnat_option_lang_mask (), kind, loc,
152
			       handlers, true, global_dc);
153
      warn_uninitialized = value;
154
      warn_maybe_uninitialized = value;
155 156 157 158 159
      break;

    case OPT_gant:
      warning (0, "%<-gnat%> misspelled as %<-gant%>");

160
      /* ... fall through ... */
161 162 163

    case OPT_gnat:
    case OPT_gnatO:
164 165 166 167 168
    case OPT_fRTS_:
    case OPT_I:
    case OPT_nostdinc:
    case OPT_nostdlib:
      /* These are handled by the front-end.  */
169 170
      break;

Arnaud Charlet committed
171
    case OPT_fshort_enums:
172 173
    case OPT_fsigned_char:
      /* These are handled by the middle-end.  */
Arnaud Charlet committed
174 175
      break;

176 177 178 179 180
    case OPT_fbuiltin_printf:
      /* This is ignored in Ada but needs to be accepted so it can be
	 defaulted.  */
      break;

181 182 183 184
    default:
      gcc_unreachable ();
    }

185 186
  Ada_handle_option_auto (&global_options, &global_options_set,
			  scode, arg, value,
187 188
			  gnat_option_lang_mask (), kind, loc,
			  handlers, global_dc);
189
  return true;
190 191
}

192 193 194 195 196 197 198
/* Initialize options structure OPTS.  */

static void
gnat_init_options_struct (struct gcc_options *opts)
{
  /* Uninitialized really means uninitialized in Ada.  */
  opts->x_flag_zero_initialized_in_bss = 0;
199

200 201 202 203
  /* We don't care about errno in Ada and it causes __builtin_sqrt to
     call the libm function rather than do it inline.  */
  opts->x_flag_errno_math = 0;
  opts->frontend_set_flag_errno_math = true;
204 205
}

206 207 208 209 210 211 212 213
/* Initialize for option processing.  */

static void
gnat_init_options (unsigned int decoded_options_count,
		   struct cl_decoded_option *decoded_options)
{
  /* Reconstruct an argv array for use of back_end.adb.

214 215 216
     ??? back_end.adb should not rely on this; instead, it should work with
     decoded options without such reparsing, to ensure consistency in how
     options are decoded.  */
217 218
  save_argv = XNEWVEC (const char *, 2 * decoded_options_count + 1);
  save_argc = 0;
219
  for (unsigned int i = 0; i < decoded_options_count; i++)
220
    {
221 222
      size_t num_elements = decoded_options[i].canonical_option_num_elements;

223
      if (decoded_options[i].errors
224
	  || decoded_options[i].opt_index == OPT_SPECIAL_unknown
225
	  || num_elements == 0)
226
	continue;
227

228 229 230 231 232 233
      /* Deal with -I- specially since it must be a single switch.  */
      if (decoded_options[i].opt_index == OPT_I
	  && num_elements == 2
	  && decoded_options[i].canonical_option[1][0] == '-'
	  && decoded_options[i].canonical_option[1][1] == '\0')
	save_argv[save_argc++] = "-I-";
234 235
      else
	{
236
	  gcc_assert (num_elements >= 1 && num_elements <= 2);
237
	  save_argv[save_argc++] = decoded_options[i].canonical_option[0];
238
	  if (num_elements >= 2)
239 240
	    save_argv[save_argc++] = decoded_options[i].canonical_option[1];
	}
241 242
    }
  save_argv[save_argc] = NULL;
243

244 245 246
  /* Pass just the name of the command through the regular channel.  */
  gnat_argv = (const char **) xmalloc (sizeof (char *));
  gnat_argv[0] = xstrdup (save_argv[0]);
247
  gnat_argc = 1;
248 249
}

Arnaud Charlet committed
250 251 252
/* Settings adjustments after switches processing by the back-end.
   Note that the front-end switches processing (Scan_Compiler_Arguments)
   has not been done yet at this point!  */
253

254
static bool
255 256
gnat_post_options (const char **pfilename ATTRIBUTE_UNUSED)
{
257
  /* Excess precision other than "fast" requires front-end support.  */
258
  if (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD)
259 260 261
    sorry ("-fexcess-precision=standard for Ada");
  flag_excess_precision_cmdline = EXCESS_PRECISION_FAST;

262 263 264
  /* No psABI change warnings for Ada.  */
  warn_psabi = 0;

265 266 267
  /* No return type warnings for Ada.  */
  warn_return_type = 0;

268 269 270 271
  /* No caret by default for Ada.  */
  if (!global_options_set.x_flag_diagnostics_show_caret)
    global_dc->show_caret = false;

272 273 274 275 276 277 278
  /* Warn only if STABS is not the default: we don't want to emit a warning if
     the user did not use a -gstabs option.  */
  if (PREFERRED_DEBUGGING_TYPE != DBX_DEBUG && write_symbols == DBX_DEBUG)
    warning (0, "STABS debugging information for Ada is obsolete and not "
		"supported anymore");

  /* Copy global settings to local versions.  */
279
  gnat_encodings = global_options.x_gnat_encodings;
280 281
  optimize = global_options.x_optimize;
  optimize_size = global_options.x_optimize_size;
282 283
  flag_compare_debug = global_options.x_flag_compare_debug;
  flag_stack_check = global_options.x_flag_stack_check;
284 285
  flag_short_enums = global_options.x_flag_short_enums;

Arnaud Charlet committed
286 287 288 289 290 291
  /* Unfortunately the post_options hook is called before the value of
     flag_short_enums is autodetected, if need be.  Mimic the process
     for our private flag_short_enums.  */
  if (flag_short_enums == 2)
    flag_short_enums = targetm.default_short_enums ();

292 293 294 295 296 297
  return false;
}

/* Here is the function to handle the compiler error processing in GCC.  */

static void
298 299
internal_error_function (diagnostic_context *context, const char *msgid,
			 va_list *ap)
300 301 302 303
{
  text_info tinfo;
  char *buffer, *p, *loc;
  String_Template temp, temp_loc;
304 305
  String_Pointer sp, sp_loc;
  expanded_location xloc;
306

307 308 309
  /* Warn if plugins present.  */
  warn_if_plugins ();

310
  /* Reset the pretty-printer.  */
311
  pp_clear_output_area (context->printer);
312 313 314 315 316

  /* Format the message into the pretty-printer.  */
  tinfo.format_spec = msgid;
  tinfo.args_ptr = ap;
  tinfo.err_no = errno;
317
  pp_format_verbatim (context->printer, &tinfo);
318 319

  /* Extract a (writable) pointer to the formatted text.  */
320
  buffer = xstrdup (pp_formatted_text (context->printer));
321 322 323 324 325 326 327 328 329 330 331

  /* Go up to the first newline.  */
  for (p = buffer; *p; p++)
    if (*p == '\n')
      {
	*p = '\0';
	break;
      }

  temp.Low_Bound = 1;
  temp.High_Bound = p - buffer;
332 333
  sp.Bounds = &temp;
  sp.Array = buffer;
334

335 336
  xloc = expand_location (input_location);
  if (context->show_column && xloc.column != 0)
337
    loc = xasprintf ("%s:%d:%d", xloc.file, xloc.line, xloc.column);
338
  else
339
    loc = xasprintf ("%s:%d", xloc.file, xloc.line);
340 341
  temp_loc.Low_Bound = 1;
  temp_loc.High_Bound = strlen (loc);
342 343
  sp_loc.Bounds = &temp_loc;
  sp_loc.Array = loc;
344 345

  Current_Error_Node = error_gnat_node;
346
  Compiler_Abort (sp, sp_loc, true);
347 348 349 350 351 352 353
}

/* Perform all the initialization steps that are language-specific.  */

static bool
gnat_init (void)
{
354
  /* Do little here, most of the standard declarations are set up after the
355
     front-end has been run.  Use the same `char' as C for Interfaces.C.  */
Bernd Schmidt committed
356
  build_common_tree_nodes (flag_signed_char);
357

358 359 360 361 362 363
  /* In Ada, we use an unsigned 8-bit type for the default boolean type.  */
  boolean_type_node = make_unsigned_type (8);
  TREE_SET_CODE (boolean_type_node, BOOLEAN_TYPE);
  SET_TYPE_RM_MAX_VALUE (boolean_type_node,
			 build_int_cst (boolean_type_node, 1));
  SET_TYPE_RM_SIZE (boolean_type_node, bitsize_int (1));
364 365
  boolean_true_node = TYPE_MAX_VALUE (boolean_type_node);
  boolean_false_node = TYPE_MIN_VALUE (boolean_type_node);
366

367 368
  sbitsize_one_node = sbitsize_int (1);
  sbitsize_unit_node = sbitsize_int (BITS_PER_UNIT);
369 370

  /* Register our internal error function.  */
371 372 373 374 375
  global_dc->internal_error = &internal_error_function;

  return true;
}

376
/* Initialize the GCC support for exception handling.  */
377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393

void
gnat_init_gcc_eh (void)
{
  /* We shouldn't do anything if the No_Exceptions_Handler pragma is set,
     though. This could for instance lead to the emission of tables with
     references to symbols (such as the Ada eh personality routine) within
     libraries we won't link against.  */
  if (No_Exception_Handlers_Set ())
    return;

  /* Tell GCC we are handling cleanup actions through exception propagation.
     This opens possibilities that we don't take advantage of yet, but is
     nonetheless necessary to ensure that fixup code gets assigned to the
     right exception regions.  */
  using_eh_for_cleanups ();

394 395 396 397 398 399 400 401 402 403 404 405
  /* Turn on -fexceptions, -fnon-call-exceptions and -fdelete-dead-exceptions.
     The first one triggers the generation of the necessary exception tables.
     The second one is useful for two reasons: 1/ we map some asynchronous
     signals like SEGV to exceptions, so we need to ensure that the insns
     which can lead to such signals are correctly attached to the exception
     region they pertain to, 2/ some calls to pure subprograms are handled as
     libcall blocks and then marked as "cannot trap" if the flag is not set
     (see emit_libcall_block).  We should not let this be since it is possible
     for such calls to actually raise in Ada.
     The third one is an optimization that makes it possible to delete dead
     instructions that may throw exceptions, most notably loads and stores,
     as permitted in Ada.  */
406 407
  flag_exceptions = 1;
  flag_non_call_exceptions = 1;
408
  flag_delete_dead_exceptions = 1;
409 410 411 412

  init_eh ();
}

413 414 415 416 417 418
/* Initialize the GCC support for floating-point operations.  */

void
gnat_init_gcc_fp (void)
{
  /* Disable FP optimizations that ignore the signedness of zero if
419
     S'Signed_Zeros is true, but don't override the user if not.  */
420 421 422 423 424
  if (Signed_Zeros_On_Target)
    flag_signed_zeros = 1;
  else if (!global_options_set.x_flag_signed_zeros)
    flag_signed_zeros = 0;

425
  /* Assume that FP operations can trap if S'Machine_Overflow is true,
426 427
     but don't override the user if not.  */
  if (Machine_Overflows_On_Target)
428 429 430 431 432
    flag_trapping_math = 1;
  else if (!global_options_set.x_flag_trapping_math)
    flag_trapping_math = 0;
}

433
/* Print language-specific items in declaration NODE.  */
434 435 436 437 438 439 440

static void
gnat_print_decl (FILE *file, tree node, int indent)
{
  switch (TREE_CODE (node))
    {
    case CONST_DECL:
441
      print_node (file, "corresponding var",
442 443 444 445
		  DECL_CONST_CORRESPONDING_VAR (node), indent + 4);
      break;

    case FIELD_DECL:
446
      print_node (file, "original field", DECL_ORIGINAL_FIELD (node),
447 448 449 450
		  indent + 4);
      break;

    case VAR_DECL:
451 452 453 454 455 456
      if (DECL_LOOP_PARM_P (node))
	print_node (file, "induction var", DECL_INDUCTION_VAR (node),
		    indent + 4);
      else
	print_node (file, "renamed object", DECL_RENAMED_OBJECT (node),
		    indent + 4);
457 458 459 460 461 462 463
      break;

    default:
      break;
    }
}

464 465
/* Print language-specific items in type NODE.  */

466 467 468 469 470 471
static void
gnat_print_type (FILE *file, tree node, int indent)
{
  switch (TREE_CODE (node))
    {
    case FUNCTION_TYPE:
472
      print_node (file, "ci/co list", TYPE_CI_CO_LIST (node), indent + 4);
473 474 475 476
      break;

    case INTEGER_TYPE:
      if (TYPE_MODULAR_P (node))
477
	print_node_brief (file, "modulus", TYPE_MODULUS (node), indent + 4);
478 479 480
      else if (TYPE_FIXED_POINT_P (node))
	print_node (file, "scale factor", TYPE_SCALE_FACTOR (node),
		    indent + 4);
481 482 483 484 485 486
      else if (TYPE_HAS_ACTUAL_BOUNDS_P (node))
	print_node (file, "actual bounds", TYPE_ACTUAL_BOUNDS (node),
		    indent + 4);
      else
	print_node (file, "index type", TYPE_INDEX_TYPE (node), indent + 4);

487
      /* ... fall through ... */
488 489 490

    case ENUMERAL_TYPE:
    case BOOLEAN_TYPE:
491
      print_node_brief (file, "RM size", TYPE_RM_SIZE (node), indent + 4);
492

493
      /* ... fall through ... */
494 495 496 497

    case REAL_TYPE:
      print_node_brief (file, "RM min", TYPE_RM_MIN_VALUE (node), indent + 4);
      print_node_brief (file, "RM max", TYPE_RM_MAX_VALUE (node), indent + 4);
498 499 500 501 502 503
      break;

    case ARRAY_TYPE:
      print_node (file,"actual bounds", TYPE_ACTUAL_BOUNDS (node), indent + 4);
      break;

504 505 506 507 508
    case VECTOR_TYPE:
      print_node (file,"representative array",
		  TYPE_REPRESENTATIVE_ARRAY (node), indent + 4);
      break;

509
    case RECORD_TYPE:
510
      if (TYPE_FAT_POINTER_P (node) || TYPE_CONTAINS_TEMPLATE_P (node))
511 512 513 514 515 516 517 518 519 520 521 522 523 524
	print_node (file, "unconstrained array",
		    TYPE_UNCONSTRAINED_ARRAY (node), indent + 4);
      else
	print_node (file, "Ada size", TYPE_ADA_SIZE (node), indent + 4);
      break;

    case UNION_TYPE:
    case QUAL_UNION_TYPE:
      print_node (file, "Ada size", TYPE_ADA_SIZE (node), indent + 4);
      break;

    default:
      break;
    }
525

526
  if (TYPE_CAN_HAVE_DEBUG_TYPE_P (node) && TYPE_DEBUG_TYPE (node))
527
    print_node_brief (file, "debug type", TYPE_DEBUG_TYPE (node), indent + 4);
528 529

  if (TYPE_IMPL_PACKED_ARRAY_P (node) && TYPE_ORIGINAL_PACKED_ARRAY (node))
530 531
    print_node_brief (file, "original packed array",
		      TYPE_ORIGINAL_PACKED_ARRAY (node), indent + 4);
532 533
}

534
/* Return the name to be printed for DECL.  */
535 536 537 538 539

static const char *
gnat_printable_name (tree decl, int verbosity)
{
  const char *coded_name = IDENTIFIER_POINTER (DECL_NAME (decl));
540
  char *ada_name = (char *) ggc_alloc_atomic (strlen (coded_name) * 2 + 60);
541 542 543

  __gnat_decode (coded_name, ada_name, 0);

544
  if (verbosity == 2 && !DECL_IS_BUILTIN (decl))
545
    {
546
      Set_Identifier_Casing (ada_name, DECL_SOURCE_FILE (decl));
547
      return ggc_strdup (Name_Buffer);
548
    }
549 550 551 552 553 554 555 556 557 558 559

  return ada_name;
}

/* Return the name to be used in DWARF debug info for DECL.  */

static const char *
gnat_dwarf_name (tree decl, int verbosity ATTRIBUTE_UNUSED)
{
  gcc_assert (DECL_P (decl));
  return (const char *) IDENTIFIER_POINTER (DECL_NAME (decl));
560 561
}

562 563 564 565 566 567 568 569 570 571 572
/* Return the descriptive type associated with TYPE, if any.  */

static tree
gnat_descriptive_type (const_tree type)
{
  if (TYPE_STUB_DECL (type))
    return DECL_PARALLEL_TYPE (TYPE_STUB_DECL (type));
  else
    return NULL_TREE;
}

573 574 575 576 577 578 579 580 581
/* Return the underlying base type of an enumeration type.  */

static tree
gnat_enum_underlying_base_type (const_tree)
{
  /* Enumeration types are base types in Ada.  */
  return void_type_node;
}

582
/* Return the type to be used for debugging information instead of TYPE or
583 584 585 586 587
   NULL_TREE if TYPE is fine.  */

static tree
gnat_get_debug_type (const_tree type)
{
588
  if (TYPE_CAN_HAVE_DEBUG_TYPE_P (type) && TYPE_DEBUG_TYPE (type))
589 590
    {
      type = TYPE_DEBUG_TYPE (type);
591 592 593 594 595

      /* ??? The get_debug_type language hook is processed after the array
	 descriptor language hook, so if there is an array behind this type,
	 the latter is supposed to handle it.  Still, we can get here with
	 a type we are not supposed to handle (e.g. when the DWARF back-end
596
	 processes the type of a variable), so keep this guard.  */
597
      if (type && TYPE_CAN_HAVE_DEBUG_TYPE_P (type))
598 599
	return const_cast<tree> (type);
    }
600

601
  return NULL_TREE;
602 603
}

604 605 606 607 608 609 610 611 612 613 614
/* Provide information in INFO for debugging output about the TYPE fixed-point
   type.  Return whether TYPE is handled.  */

static bool
gnat_get_fixed_point_type_info (const_tree type,
				struct fixed_point_type_info *info)
{
  tree scale_factor;

  /* GDB cannot handle fixed-point types yet, so rely on GNAT encodings
     instead for it.  */
615 616
  if (!TYPE_IS_FIXED_POINT_P (type)
      || gnat_encodings != DWARF_GNAT_ENCODINGS_MINIMAL)
617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648
    return false;

  scale_factor = TYPE_SCALE_FACTOR (type);

  /* We expect here only a finite set of pattern.  See fixed-point types
     handling in gnat_to_gnu_entity.  */

  /* Put invalid values when compiler internals cannot represent the scale
     factor.  */
  if (scale_factor == integer_zero_node)
    {
      info->scale_factor_kind = fixed_point_scale_factor_arbitrary;
      info->scale_factor.arbitrary.numerator = 0;
      info->scale_factor.arbitrary.denominator = 0;
      return true;
    }

  if (TREE_CODE (scale_factor) == RDIV_EXPR)
    {
      const tree num = TREE_OPERAND (scale_factor, 0);
      const tree den = TREE_OPERAND (scale_factor, 1);

      /* See if we have a binary or decimal scale.  */
      if (TREE_CODE (den) == POWER_EXPR)
	{
	  const tree base = TREE_OPERAND (den, 0);
	  const tree exponent = TREE_OPERAND (den, 1);

	  /* We expect the scale factor to be 1 / 2 ** N or 1 / 10 ** N.  */
	  gcc_assert (num == integer_one_node
		      && TREE_CODE (base) == INTEGER_CST
		      && TREE_CODE (exponent) == INTEGER_CST);
649

650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670
	  switch (tree_to_shwi (base))
	    {
	    case 2:
	      info->scale_factor_kind = fixed_point_scale_factor_binary;
	      info->scale_factor.binary = -tree_to_shwi (exponent);
	      return true;

	    case 10:
	      info->scale_factor_kind = fixed_point_scale_factor_decimal;
	      info->scale_factor.decimal = -tree_to_shwi (exponent);
	      return true;

	    default:
	      gcc_unreachable ();
	    }
	}

      /* If we reach this point, we are handling an arbitrary scale factor.  We
	 expect N / D with constant operands.  */
      gcc_assert (TREE_CODE (num) == INTEGER_CST
		  && TREE_CODE (den) == INTEGER_CST);
671

672 673 674 675 676 677 678 679 680
      info->scale_factor_kind = fixed_point_scale_factor_arbitrary;
      info->scale_factor.arbitrary.numerator = tree_to_uhwi (num);
      info->scale_factor.arbitrary.denominator = tree_to_shwi (den);
      return true;
    }

  gcc_unreachable ();
}

681 682 683 684 685 686 687 688 689 690 691 692 693 694
/* Return true if types T1 and T2 are identical for type hashing purposes.
   Called only after doing all language independent checks.  At present,
   this function is only called when both types are FUNCTION_TYPE.  */

static bool
gnat_type_hash_eq (const_tree t1, const_tree t2)
{
  gcc_assert (TREE_CODE (t1) == FUNCTION_TYPE);
  return fntype_same_flags_p (t1, TYPE_CI_CO_LIST (t2),
			      TYPE_RETURN_UNCONSTRAINED_P (t2),
			      TYPE_RETURN_BY_DIRECT_REF_P (t2),
			      TREE_ADDRESSABLE (t2));
}

695 696 697 698 699 700 701 702 703 704 705 706 707 708
/* Do nothing (return the tree node passed).  */

static tree
gnat_return_tree (tree t)
{
  return t;
}

/* Get the alias set corresponding to a type or expression.  */

static alias_set_type
gnat_get_alias_set (tree type)
{
  /* If this is a padding type, use the type of the first field.  */
709
  if (TYPE_IS_PADDING_P (type))
710 711 712 713 714 715 716 717 718
    return get_alias_set (TREE_TYPE (TYPE_FIELDS (type)));

  /* If the type is an unconstrained array, use the type of the
     self-referential array we make.  */
  else if (TREE_CODE (type) == UNCONSTRAINED_ARRAY_TYPE)
    return
      get_alias_set (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (type)))));

  /* If the type can alias any other types, return the alias set 0.  */
719 720 721
  else if (TYPE_P (type)
	   && !TYPE_IS_DUMMY_P (type)
	   && TYPE_UNIVERSAL_ALIASING_P (type))
722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737
    return 0;

  return -1;
}

/* GNU_TYPE is a type.  Return its maximum size in bytes, if known,
   as a constant when possible.  */

static tree
gnat_type_max_size (const_tree gnu_type)
{
  /* First see what we can get from TYPE_SIZE_UNIT, which might not
     be constant even for simple expressions if it has already been
     elaborated and possibly replaced by a VAR_DECL.  */
  tree max_unitsize = max_size (TYPE_SIZE_UNIT (gnu_type), true);

738 739 740
  /* If we don't have a constant, try to look at attributes which should have
     stayed untouched.  */
  if (!tree_fits_uhwi_p (max_unitsize))
741
    {
742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790
      /* For record types, see what we can get from TYPE_ADA_SIZE.  */
      if (RECORD_OR_UNION_TYPE_P (gnu_type)
	  && !TYPE_FAT_POINTER_P (gnu_type)
	  && TYPE_ADA_SIZE (gnu_type))
	{
	  tree max_adasize = max_size (TYPE_ADA_SIZE (gnu_type), true);

	  /* If we have succeeded in finding a constant, round it up to the
	     type's alignment and return the result in units.  */
	  if (tree_fits_uhwi_p (max_adasize))
	    max_unitsize
	      = size_binop (CEIL_DIV_EXPR,
			    round_up (max_adasize, TYPE_ALIGN (gnu_type)),
			    bitsize_unit_node);
	}

      /* For array types, see what we can get from TYPE_INDEX_TYPE.  */
      else if (TREE_CODE (gnu_type) == ARRAY_TYPE
	       && TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type))
	       && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (gnu_type))))
	{
	  tree lb = TYPE_MIN_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type)));
	  tree hb = TYPE_MAX_VALUE (TYPE_INDEX_TYPE (TYPE_DOMAIN (gnu_type)));
	  if (TREE_CODE (lb) != INTEGER_CST
	      && TYPE_RM_SIZE (TREE_TYPE (lb))
	      && compare_tree_int (TYPE_RM_SIZE (TREE_TYPE (lb)), 16) <= 0)
	    lb = TYPE_MIN_VALUE (TREE_TYPE (lb));
	  if (TREE_CODE (hb) != INTEGER_CST
	      && TYPE_RM_SIZE (TREE_TYPE (hb))
	      && compare_tree_int (TYPE_RM_SIZE (TREE_TYPE (hb)), 16) <= 0)
	    hb = TYPE_MAX_VALUE (TREE_TYPE (hb));
	  if (TREE_CODE (lb) == INTEGER_CST && TREE_CODE (hb) == INTEGER_CST)
	    {
	      tree ctype = get_base_type (TREE_TYPE (lb));
	      lb = fold_convert (ctype, lb);
	      hb = fold_convert (ctype, hb);
	      if (tree_int_cst_le (lb, hb))
		{
		  tree length
		    = fold_build2 (PLUS_EXPR, ctype,
				   fold_build2 (MINUS_EXPR, ctype, hb, lb),
				   build_int_cst (ctype, 1));
		  max_unitsize
		    = fold_build2 (MULT_EXPR, sizetype,
				   fold_convert (sizetype, length),
				   TYPE_SIZE_UNIT (TREE_TYPE (gnu_type)));
		}
	    }
	}
791 792 793 794 795
    }

  return max_unitsize;
}

796
static tree get_array_bit_stride (tree);
797

798 799 800 801
/* Provide information in INFO for debug output about the TYPE array type.
   Return whether TYPE is handled.  */

static bool
802 803
gnat_get_array_descr_info (const_tree const_type,
			   struct array_descr_info *info)
804 805
{
  bool convention_fortran_p;
806 807
  bool is_array = false;
  bool is_fat_ptr = false;
808 809
  bool is_packed_array = false;
  tree type = const_cast<tree> (const_type);
810
  const_tree first_dimen = NULL_TREE;
811
  const_tree last_dimen = NULL_TREE;
812
  const_tree dimen;
813 814
  int i;

815 816 817 818 819 820 821
  /* Temporaries created in the first pass and used in the second one for thin
     pointers.  The first one is an expression that yields the template record
     from the base address (i.e. the PLACEHOLDER_EXPR).  The second one is just
     a cursor through this record's fields.  */
  tree thinptr_template_expr = NULL_TREE;
  tree thinptr_bound_field = NULL_TREE;

822
  /* ??? See gnat_get_debug_type.  */
823
  type = maybe_debug_type (type);
824 825 826

  /* If we have an implementation type for a packed array, get the orignial
     array type.  */
827
  if (TYPE_IMPL_PACKED_ARRAY_P (type) && TYPE_ORIGINAL_PACKED_ARRAY (type))
828 829
    {
      type = TYPE_ORIGINAL_PACKED_ARRAY (type);
830
      is_packed_array = true;
831 832
    }

833 834 835 836 837 838 839 840 841 842 843 844 845
  /* First pass: gather all information about this array except everything
     related to dimensions.  */

  /* Only handle ARRAY_TYPE nodes that come from GNAT.  */
  if (TREE_CODE (type) == ARRAY_TYPE
      && TYPE_DOMAIN (type)
      && TYPE_INDEX_TYPE (TYPE_DOMAIN (type)))
    {
      is_array = true;
      first_dimen = type;
      info->data_location = NULL_TREE;
    }

846 847
  else if (TYPE_IS_FAT_POINTER_P (type)
	   && gnat_encodings == DWARF_GNAT_ENCODINGS_MINIMAL)
848
    {
849
      const tree ua_type = TYPE_UNCONSTRAINED_ARRAY (type);
850 851

      /* This will be our base object address.  */
852
      const tree placeholder_expr = build0 (PLACEHOLDER_EXPR, type);
853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872

      /* We assume below that maybe_unconstrained_array returns an INDIRECT_REF
	 node.  */
      const tree ua_val
        = maybe_unconstrained_array (build_unary_op (INDIRECT_REF,
						     ua_type,
						     placeholder_expr));

      is_fat_ptr = true;
      first_dimen = TREE_TYPE (ua_val);

      /* Get the *address* of the array, not the array itself.  */
      info->data_location = TREE_OPERAND (ua_val, 0);
    }

  /* Unlike fat pointers (which appear for unconstrained arrays passed in
     argument), thin pointers are used only for array access types, so we want
     them to appear in the debug info as pointers to an array type.  That's why
     we match only the RECORD_TYPE here instead of the POINTER_TYPE with the
     TYPE_IS_THIN_POINTER_P predicate.  */
873 874 875
  else if (TREE_CODE (type) == RECORD_TYPE
	   && TYPE_CONTAINS_TEMPLATE_P (type)
	   && gnat_encodings == DWARF_GNAT_ENCODINGS_MINIMAL)
876 877 878 879
    {
      /* This will be our base object address.  Note that we assume that
	 pointers to these will actually point to the array field (thin
	 pointers are shifted).  */
880
      const tree placeholder_expr = build0 (PLACEHOLDER_EXPR, type);
881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909
      const tree placeholder_addr
        = build_unary_op (ADDR_EXPR, NULL_TREE, placeholder_expr);

      const tree bounds_field = TYPE_FIELDS (type);
      const tree bounds_type = TREE_TYPE (bounds_field);
      const tree array_field = DECL_CHAIN (bounds_field);
      const tree array_type = TREE_TYPE (array_field);

      /* Shift the thin pointer address to get the address of the template.  */
      const tree shift_amount
	= fold_build1 (NEGATE_EXPR, sizetype, byte_position (array_field));
      tree template_addr
	= build_binary_op (POINTER_PLUS_EXPR, TREE_TYPE (placeholder_addr),
			   placeholder_addr, shift_amount);
      template_addr
	= fold_convert (TYPE_POINTER_TO (bounds_type), template_addr);

      first_dimen = array_type;

      /* The thin pointer is already the pointer to the array data, so there's
	 no need for a specific "data location" expression.  */
      info->data_location = NULL_TREE;

      thinptr_template_expr = build_unary_op (INDIRECT_REF,
					      bounds_type,
					      template_addr);
      thinptr_bound_field = TYPE_FIELDS (bounds_type);
    }
  else
910 911
    return false;

912 913
  /* Second pass: compute the remaining information: dimensions and
     corresponding bounds.  */
914

915 916
  if (TYPE_PACKED (first_dimen))
    is_packed_array = true;
917 918 919 920
  /* If this array has fortran convention, it's arranged in column-major
     order, so our view here has reversed dimensions.  */
  convention_fortran_p = TYPE_CONVENTION_FORTRAN_P (first_dimen);
  /* ??? For row major ordering, we probably want to emit nothing and
921 922 923 924 925
     instead specify it as the default in Dw_TAG_compile_unit.  */
  info->ordering = (convention_fortran_p
		    ? array_descr_ordering_column_major
		    : array_descr_ordering_row_major);

926 927 928 929 930 931 932 933 934
  /* Count how many dimensions this array has.  */
  for (i = 0, dimen = first_dimen; ; ++i, dimen = TREE_TYPE (dimen))
    {
      if (i > 0
	  && (TREE_CODE (dimen) != ARRAY_TYPE
	      || !TYPE_MULTI_ARRAY_P (dimen)))
	break;
      last_dimen = dimen;
    }
935

936
  info->ndimensions = i;
937
  info->rank = NULL_TREE;
938 939 940 941 942 943 944 945 946 947 948 949

  /* Too many dimensions?  Give up generating proper description: yield instead
     nested arrays.  Note that in this case, this hook is invoked once on each
     intermediate array type: be consistent and output nested arrays for all
     dimensions.  */
  if (info->ndimensions > DWARF2OUT_ARRAY_DESCR_INFO_MAX_DIMEN
      || TYPE_MULTI_ARRAY_P (first_dimen))
    {
      info->ndimensions = 1;
      last_dimen = first_dimen;
    }

950 951 952 953
  info->element_type = TREE_TYPE (last_dimen);

  /* Now iterate over all dimensions in source-order and fill the info
     structure.  */
954
  for (i = (convention_fortran_p ? info->ndimensions - 1 : 0),
955
       dimen = first_dimen;
956
       IN_RANGE (i, 0, info->ndimensions - 1);
957 958 959 960
       i += (convention_fortran_p ? -1 : 1),
       dimen = TREE_TYPE (dimen))
    {
      /* We are interested in the stored bounds for the debug info.  */
961
      tree index_type = TYPE_INDEX_TYPE (TYPE_DOMAIN (dimen));
962

963 964 965 966 967 968 969 970
      if (is_array || is_fat_ptr)
	{
	  /* GDB does not handle very well the self-referencial bound
	     expressions we are able to generate here for XUA types (they are
	     used only by XUP encodings) so avoid them in this case.  Note that
	     there are two cases where we generate self-referencial bound
	     expressions:  arrays that are constrained by record discriminants
	     and XUA types.  */
971 972
	  if (TYPE_CONTEXT (first_dimen)
	      && TREE_CODE (TYPE_CONTEXT (first_dimen)) != RECORD_TYPE
973
	      && CONTAINS_PLACEHOLDER_P (TYPE_MIN_VALUE (index_type))
974
	      && gnat_encodings != DWARF_GNAT_ENCODINGS_MINIMAL)
975 976 977 978 979 980
	    {
	      info->dimen[i].lower_bound = NULL_TREE;
	      info->dimen[i].upper_bound = NULL_TREE;
	    }
	  else
	    {
981 982 983 984
	      info->dimen[i].lower_bound
		= maybe_character_value (TYPE_MIN_VALUE (index_type));
	      info->dimen[i].upper_bound
		= maybe_character_value (TYPE_MAX_VALUE (index_type));
985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001
	    }
	}

      /* This is a thin pointer.  */
      else
	{
	  info->dimen[i].lower_bound
	    = build_component_ref (thinptr_template_expr, thinptr_bound_field,
				   false);
	  thinptr_bound_field = DECL_CHAIN (thinptr_bound_field);

	  info->dimen[i].upper_bound
	    = build_component_ref (thinptr_template_expr, thinptr_bound_field,
				   false);
	  thinptr_bound_field = DECL_CHAIN (thinptr_bound_field);
	}

1002 1003 1004
      /* The DWARF back-end will output BOUNDS_TYPE as the base type of
	 the array index, so get to the base type of INDEX_TYPE.  */
      while (TREE_TYPE (index_type))
1005
	index_type = TREE_TYPE (index_type);
1006

1007
      info->dimen[i].bounds_type = maybe_debug_type (index_type);
1008
      info->dimen[i].stride = NULL_TREE;
1009 1010
    }

1011 1012 1013
  /* These are Fortran-specific fields.  They make no sense here.  */
  info->allocated = NULL_TREE;
  info->associated = NULL_TREE;
1014

1015 1016
  if (gnat_encodings == DWARF_GNAT_ENCODINGS_MINIMAL)
    {
1017 1018 1019 1020 1021
      /* When arrays contain dynamically-sized elements, we usually wrap them
	 in padding types, or we create constrained types for them.  Then, if
	 such types are stripped in the debugging information output, the
	 debugger needs a way to know the size that is reserved for each
	 element.  This is why we emit a stride in such situations.  */
1022 1023
      tree source_element_type = info->element_type;

1024
      while (true)
1025
	{
1026
	  if (TYPE_DEBUG_TYPE (source_element_type))
1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039
	    source_element_type = TYPE_DEBUG_TYPE (source_element_type);
	  else if (TYPE_IS_PADDING_P (source_element_type))
	    source_element_type
	      = TREE_TYPE (TYPE_FIELDS (source_element_type));
	  else
	    break;
	}

      if (TREE_CODE (TYPE_SIZE_UNIT (source_element_type)) != INTEGER_CST)
	{
	  info->stride = TYPE_SIZE_UNIT (info->element_type);
	  info->stride_in_bits = false;
	}
1040 1041 1042 1043 1044 1045 1046 1047 1048

      /* We need to specify a bit stride when it does not correspond to the
	 natural size of the contained elements.  ??? Note that we do not
	 support packed records and nested packed arrays.  */
      else if (is_packed_array)
	{
	  info->stride = get_array_bit_stride (info->element_type);
	  info->stride_in_bits = true;
	}
1049 1050
    }

1051 1052 1053
  return true;
}

1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067
/* Given the component type COMP_TYPE of a packed array, return an expression
   that computes the bit stride of this packed array.  Return NULL_TREE when
   unsuccessful.  */

static tree
get_array_bit_stride (tree comp_type)
{
  struct array_descr_info info;
  tree stride;

  /* Simple case: the array contains an integral type: return its RM size.  */
  if (INTEGRAL_TYPE_P (comp_type))
    return TYPE_RM_SIZE (comp_type);

1068
  /* Otherwise, see if this is an array we can analyze; if it's not, punt.  */
1069
  memset (&info, 0, sizeof (info));
1070
  if (!gnat_get_array_descr_info (comp_type, &info) || !info.stride)
1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081
    return NULL_TREE;

  /* Otherwise, the array stride is the inner array's stride multiplied by the
     number of elements it contains.  Note that if the inner array is not
     packed, then the stride is "natural" and thus does not deserve an
     attribute.  */
  stride = info.stride;
  if (!info.stride_in_bits)
    {
      stride = fold_convert (bitsizetype, stride);
      stride = build_binary_op (MULT_EXPR, bitsizetype,
1082
				stride, build_int_cst (bitsizetype, 8));
1083 1084 1085 1086 1087 1088
    }

  for (int i = 0; i < info.ndimensions; ++i)
    {
      tree count;

1089
      if (!info.dimen[i].lower_bound || !info.dimen[i].upper_bound)
1090 1091 1092 1093 1094 1095 1096 1097 1098 1099
	return NULL_TREE;

      /* Put in count an expression that computes the length of this
	 dimension.  */
      count = build_binary_op (MINUS_EXPR, sbitsizetype,
			       fold_convert (sbitsizetype,
					     info.dimen[i].upper_bound),
			       fold_convert (sbitsizetype,
					     info.dimen[i].lower_bound)),
      count = build_binary_op (PLUS_EXPR, sbitsizetype,
1100
			       count, build_int_cst (sbitsizetype, 1));
1101 1102
      count = build_binary_op (MAX_EXPR, sbitsizetype,
			       count,
1103
			       build_int_cst (sbitsizetype, 0));
1104 1105 1106 1107 1108 1109 1110
      count = fold_convert (bitsizetype, count);
      stride = build_binary_op (MULT_EXPR, bitsizetype, stride, count);
    }

  return stride;
}

1111 1112 1113 1114 1115 1116
/* GNU_TYPE is a subtype of an integral type.  Set LOWVAL to the low bound
   and HIGHVAL to the high bound, respectively.  */

static void
gnat_get_subrange_bounds (const_tree gnu_type, tree *lowval, tree *highval)
{
1117 1118
  *lowval = TYPE_MIN_VALUE (gnu_type);
  *highval = TYPE_MAX_VALUE (gnu_type);
1119 1120
}

1121 1122
/* Return the bias of GNU_TYPE, if any.  */

1123 1124 1125 1126 1127 1128
static tree
gnat_get_type_bias (const_tree gnu_type)
{
  if (TREE_CODE (gnu_type) == INTEGER_TYPE
      && TYPE_BIASED_REPRESENTATION_P (gnu_type)
      && gnat_encodings == DWARF_GNAT_ENCODINGS_MINIMAL)
1129 1130
    return TYPE_RM_MIN_VALUE (gnu_type);

1131 1132 1133
  return NULL_TREE;
}

1134 1135
/* GNU_TYPE is the type of a subprogram parameter.  Determine if it should be
   passed by reference by default.  */
1136 1137 1138 1139

bool
default_pass_by_ref (tree gnu_type)
{
1140 1141
  /* We pass aggregates by reference if they are sufficiently large for
     their alignment.  The ratio is somewhat arbitrary.  We also pass by
1142 1143 1144 1145 1146 1147
     reference if the target machine would either pass or return by
     reference.  Strictly speaking, we need only check the return if this
     is an In Out parameter, but it's probably best to err on the side of
     passing more things by reference.  */

  if (AGGREGATE_TYPE_P (gnu_type)
1148
      && (!valid_constant_size_p (TYPE_SIZE_UNIT (gnu_type))
1149 1150
	  || compare_tree_int (TYPE_SIZE_UNIT (gnu_type),
			       TYPE_ALIGN (gnu_type)) > 0))
1151 1152
    return true;

1153 1154 1155 1156 1157 1158
  if (pass_by_reference (NULL, TYPE_MODE (gnu_type), gnu_type, true))
    return true;

  if (targetm.calls.return_in_memory (gnu_type, NULL_TREE))
    return true;

1159 1160 1161
  return false;
}

1162 1163
/* GNU_TYPE is the type of a subprogram parameter.  Determine if it must be
   passed by reference.  */
1164 1165 1166 1167 1168 1169 1170 1171 1172 1173

bool
must_pass_by_ref (tree gnu_type)
{
  /* We pass only unconstrained objects, those required by the language
     to be passed by reference, and objects of variable size.  The latter
     is more efficient, avoids problems with variable size temporaries,
     and does not produce compatibility problems with C, since C does
     not have such objects.  */
  return (TREE_CODE (gnu_type) == UNCONSTRAINED_ARRAY_TYPE
1174
	  || TYPE_IS_BY_REFERENCE_P (gnu_type)
1175 1176
	  || (TYPE_SIZE_UNIT (gnu_type)
	      && TREE_CODE (TYPE_SIZE_UNIT (gnu_type)) != INTEGER_CST));
1177 1178
}

Arnaud Charlet committed
1179 1180 1181
/* This function is called by the front-end to enumerate all the supported
   modes for the machine, as well as some predefined C types.  F is a function
   which is called back with the parameters as listed below, first a string,
1182
   then seven ints.  The name is any arbitrary null-terminated string and has
Arnaud Charlet committed
1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197
   no particular significance, except for the case of predefined C types, where
   it should be the name of the C type.  For integer types, only signed types
   should be listed, unsigned versions are assumed.  The order of types should
   be in order of preference, with the smallest/cheapest types first.

   In particular, C predefined types should be listed before other types,
   binary floating point types before decimal ones, and narrower/cheaper
   type versions before more expensive ones.  In type selection the first
   matching variant will be used.

   NAME		pointer to first char of type name
   DIGS		number of decimal digits for floating-point modes, else 0
   COMPLEX_P	nonzero is this represents a complex mode
   COUNT	count of number of items, nonzero for vector mode
   FLOAT_REP	Float_Rep_Kind for FP, otherwise undefined
1198 1199
   PRECISION	number of bits used to store data
   SIZE		number of bits occupied by the mode
Arnaud Charlet committed
1200 1201 1202
   ALIGN	number of bits to which mode is aligned.  */

void
1203
enumerate_modes (void (*f) (const char *, int, int, int, int, int, int, int))
Arnaud Charlet committed
1204 1205 1206 1207 1208 1209 1210
{
  const tree c_types[]
    = { float_type_node, double_type_node, long_double_type_node };
  const char *const c_names[]
    = { "float", "double", "long double" };
  int iloop;

Arnaud Charlet committed
1211 1212 1213
  /* We are going to compute it below.  */
  fp_arith_may_widen = false;

Arnaud Charlet committed
1214 1215
  for (iloop = 0; iloop < NUM_MACHINE_MODES; iloop++)
    {
1216 1217
      machine_mode i = (machine_mode) iloop;
      machine_mode inner_mode = i;
Arnaud Charlet committed
1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258
      bool float_p = false;
      bool complex_p = false;
      bool vector_p = false;
      bool skip_p = false;
      int digs = 0;
      unsigned int nameloop;
      Float_Rep_Kind float_rep = IEEE_Binary; /* Until proven otherwise */

      switch (GET_MODE_CLASS (i))
	{
	case MODE_INT:
	  break;
	case MODE_FLOAT:
	  float_p = true;
	  break;
	case MODE_COMPLEX_INT:
	  complex_p = true;
	  inner_mode = GET_MODE_INNER (i);
	  break;
	case MODE_COMPLEX_FLOAT:
	  float_p = true;
	  complex_p = true;
	  inner_mode = GET_MODE_INNER (i);
	  break;
	case MODE_VECTOR_INT:
	  vector_p = true;
	  inner_mode = GET_MODE_INNER (i);
	  break;
	case MODE_VECTOR_FLOAT:
	  float_p = true;
	  vector_p = true;
	  inner_mode = GET_MODE_INNER (i);
	  break;
	default:
	  skip_p = true;
	}

      if (float_p)
	{
	  const struct real_format *fmt = REAL_MODE_FORMAT (inner_mode);

Arnaud Charlet committed
1259 1260 1261 1262
	  /* ??? Cope with the ghost XFmode of the ARM port.  */
	  if (!fmt)
	    continue;

Arnaud Charlet committed
1263 1264 1265 1266 1267 1268 1269
	  /* Be conservative and consider that floating-point arithmetics may
	     use wider intermediate results as soon as there is an extended
	     Motorola or Intel mode supported by the machine.  */
	  if (fmt == &ieee_extended_motorola_format
	      || fmt == &ieee_extended_intel_96_format
	      || fmt == &ieee_extended_intel_96_round_53_format
	      || fmt == &ieee_extended_intel_128_format)
1270 1271 1272 1273 1274 1275
	    {
#ifdef TARGET_FPMATH_DEFAULT
	      if (TARGET_FPMATH_DEFAULT == FPMATH_387)
#endif
		fp_arith_may_widen = true;
	    }
Arnaud Charlet committed
1276

Arnaud Charlet committed
1277 1278 1279 1280 1281 1282 1283
	  if (fmt->b == 2)
	    digs = (fmt->p - 1) * 1233 / 4096; /* scale by log (2) */

	  else if (fmt->b == 10)
	    digs = fmt->p;

	  else
1284
	    gcc_unreachable ();
Arnaud Charlet committed
1285 1286 1287 1288
	}

      /* First register any C types for this mode that the front end
	 may need to know about, unless the mode should be skipped.  */
1289
      if (!skip_p && !vector_p)
Arnaud Charlet committed
1290 1291
	for (nameloop = 0; nameloop < ARRAY_SIZE (c_types); nameloop++)
	  {
1292 1293
	    tree type = c_types[nameloop];
	    const char *name = c_names[nameloop];
Arnaud Charlet committed
1294

1295
	    if (TYPE_MODE (type) == i)
Arnaud Charlet committed
1296
	      {
1297 1298
		f (name, digs, complex_p, 0, float_rep, TYPE_PRECISION (type),
		   TREE_INT_CST_LOW (TYPE_SIZE (type)), TYPE_ALIGN (type));
Arnaud Charlet committed
1299 1300 1301 1302 1303
		skip_p = true;
	      }
	  }

      /* If no predefined C types were found, register the mode itself.  */
1304
      int nunits, precision, bitsize;
1305 1306
      if (!skip_p
	  && GET_MODE_NUNITS (i).is_constant (&nunits)
1307 1308
	  && GET_MODE_PRECISION (i).is_constant (&precision)
	  && GET_MODE_BITSIZE (i).is_constant (&bitsize))
Arnaud Charlet committed
1309
	f (GET_MODE_NAME (i), digs, complex_p,
1310
	   vector_p ? nunits : 0, float_rep,
1311
	   precision, bitsize, GET_MODE_ALIGNMENT (i));
Arnaud Charlet committed
1312 1313 1314
    }
}

1315 1316
/* Return the size of the FP mode with precision PREC.  */

1317 1318 1319
int
fp_prec_to_size (int prec)
{
1320
  opt_scalar_float_mode opt_mode;
1321

1322 1323 1324 1325 1326 1327
  FOR_EACH_MODE_IN_CLASS (opt_mode, MODE_FLOAT)
    {
      scalar_float_mode mode = opt_mode.require ();
      if (GET_MODE_PRECISION (mode) == prec)
	return GET_MODE_BITSIZE (mode);
    }
1328 1329 1330 1331

  gcc_unreachable ();
}

1332 1333
/* Return the precision of the FP mode with size SIZE.  */

1334 1335 1336
int
fp_size_to_prec (int size)
{
1337
  opt_scalar_float_mode opt_mode;
1338

1339 1340 1341 1342 1343 1344
  FOR_EACH_MODE_IN_CLASS (opt_mode, MODE_FLOAT)
    {
      scalar_mode mode = opt_mode.require ();
      if (GET_MODE_BITSIZE (mode) == size)
	return GET_MODE_PRECISION (mode);
    }
1345 1346 1347

  gcc_unreachable ();
}
1348 1349 1350

static GTY(()) tree gnat_eh_personality_decl;

1351 1352
/* Return the GNAT personality function decl.  */

1353 1354 1355 1356
static tree
gnat_eh_personality (void)
{
  if (!gnat_eh_personality_decl)
1357
    gnat_eh_personality_decl = build_personality_function ("gnat");
1358 1359 1360
  return gnat_eh_personality_decl;
}

1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371
/* Initialize language-specific bits of tree_contains_struct.  */

static void
gnat_init_ts (void)
{
  MARK_TS_COMMON (UNCONSTRAINED_ARRAY_TYPE);

  MARK_TS_TYPED (UNCONSTRAINED_ARRAY_REF);
  MARK_TS_TYPED (NULL_EXPR);
  MARK_TS_TYPED (PLUS_NOMOD_EXPR);
  MARK_TS_TYPED (MINUS_NOMOD_EXPR);
1372
  MARK_TS_TYPED (POWER_EXPR);
1373 1374 1375 1376 1377 1378
  MARK_TS_TYPED (ATTR_ADDR_EXPR);
  MARK_TS_TYPED (STMT_STMT);
  MARK_TS_TYPED (LOOP_STMT);
  MARK_TS_TYPED (EXIT_STMT);
}

1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395
/* Return the size of a tree with CODE, which is a language-specific tree code
   in category tcc_constant, tcc_exceptional or tcc_type.  The default expects
   never to be called.  */

static size_t
gnat_tree_size (enum tree_code code)
{
  gcc_checking_assert (code >= NUM_TREE_CODES);
  switch (code)
    {
    case UNCONSTRAINED_ARRAY_TYPE:
      return sizeof (tree_type_non_common);
    default:
      gcc_unreachable ();
    }
}

1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406
/* Return the lang specific structure attached to NODE.  Allocate it (cleared)
   if needed.  */

struct lang_type *
get_lang_specific (tree node)
{
  if (!TYPE_LANG_SPECIFIC (node))
    TYPE_LANG_SPECIFIC (node) = ggc_cleared_alloc<struct lang_type> ();
  return TYPE_LANG_SPECIFIC (node);
}

1407 1408 1409 1410 1411 1412
/* Definitions for our language-specific hooks.  */

#undef  LANG_HOOKS_NAME
#define LANG_HOOKS_NAME			"GNU Ada"
#undef  LANG_HOOKS_IDENTIFIER_SIZE
#define LANG_HOOKS_IDENTIFIER_SIZE	sizeof (struct tree_identifier)
1413 1414
#undef  LANG_HOOKS_TREE_SIZE
#define LANG_HOOKS_TREE_SIZE		gnat_tree_size
1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431
#undef  LANG_HOOKS_INIT
#define LANG_HOOKS_INIT			gnat_init
#undef  LANG_HOOKS_OPTION_LANG_MASK
#define LANG_HOOKS_OPTION_LANG_MASK	gnat_option_lang_mask
#undef  LANG_HOOKS_INIT_OPTIONS_STRUCT
#define LANG_HOOKS_INIT_OPTIONS_STRUCT	gnat_init_options_struct
#undef  LANG_HOOKS_INIT_OPTIONS
#define LANG_HOOKS_INIT_OPTIONS		gnat_init_options
#undef  LANG_HOOKS_HANDLE_OPTION
#define LANG_HOOKS_HANDLE_OPTION	gnat_handle_option
#undef  LANG_HOOKS_POST_OPTIONS
#define LANG_HOOKS_POST_OPTIONS		gnat_post_options
#undef  LANG_HOOKS_PARSE_FILE
#define LANG_HOOKS_PARSE_FILE		gnat_parse_file
#undef  LANG_HOOKS_TYPE_HASH_EQ
#define LANG_HOOKS_TYPE_HASH_EQ		gnat_type_hash_eq
#undef  LANG_HOOKS_GETDECLS
1432
#define LANG_HOOKS_GETDECLS		hook_tree_void_null
1433 1434
#undef  LANG_HOOKS_PUSHDECL
#define LANG_HOOKS_PUSHDECL		gnat_return_tree
1435 1436
#undef  LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL
#define LANG_HOOKS_WARN_UNUSED_GLOBAL_DECL hook_bool_const_tree_false
1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456
#undef  LANG_HOOKS_GET_ALIAS_SET
#define LANG_HOOKS_GET_ALIAS_SET	gnat_get_alias_set
#undef  LANG_HOOKS_PRINT_DECL
#define LANG_HOOKS_PRINT_DECL		gnat_print_decl
#undef  LANG_HOOKS_PRINT_TYPE
#define LANG_HOOKS_PRINT_TYPE		gnat_print_type
#undef  LANG_HOOKS_TYPE_MAX_SIZE
#define LANG_HOOKS_TYPE_MAX_SIZE	gnat_type_max_size
#undef  LANG_HOOKS_DECL_PRINTABLE_NAME
#define LANG_HOOKS_DECL_PRINTABLE_NAME	gnat_printable_name
#undef  LANG_HOOKS_DWARF_NAME
#define LANG_HOOKS_DWARF_NAME		gnat_dwarf_name
#undef  LANG_HOOKS_GIMPLIFY_EXPR
#define LANG_HOOKS_GIMPLIFY_EXPR	gnat_gimplify_expr
#undef  LANG_HOOKS_TYPE_FOR_MODE
#define LANG_HOOKS_TYPE_FOR_MODE	gnat_type_for_mode
#undef  LANG_HOOKS_TYPE_FOR_SIZE
#define LANG_HOOKS_TYPE_FOR_SIZE	gnat_type_for_size
#undef  LANG_HOOKS_TYPES_COMPATIBLE_P
#define LANG_HOOKS_TYPES_COMPATIBLE_P	gnat_types_compatible_p
1457 1458
#undef  LANG_HOOKS_GET_ARRAY_DESCR_INFO
#define LANG_HOOKS_GET_ARRAY_DESCR_INFO	gnat_get_array_descr_info
1459 1460
#undef  LANG_HOOKS_GET_SUBRANGE_BOUNDS
#define LANG_HOOKS_GET_SUBRANGE_BOUNDS  gnat_get_subrange_bounds
1461 1462
#undef  LANG_HOOKS_GET_TYPE_BIAS
#define LANG_HOOKS_GET_TYPE_BIAS	gnat_get_type_bias
1463 1464
#undef  LANG_HOOKS_DESCRIPTIVE_TYPE
#define LANG_HOOKS_DESCRIPTIVE_TYPE	gnat_descriptive_type
1465 1466
#undef  LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE
#define LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE gnat_enum_underlying_base_type
1467 1468
#undef  LANG_HOOKS_GET_DEBUG_TYPE
#define LANG_HOOKS_GET_DEBUG_TYPE	gnat_get_debug_type
1469
#undef  LANG_HOOKS_GET_FIXED_POINT_TYPE_INFO
1470
#define LANG_HOOKS_GET_FIXED_POINT_TYPE_INFO gnat_get_fixed_point_type_info
1471 1472 1473 1474
#undef  LANG_HOOKS_ATTRIBUTE_TABLE
#define LANG_HOOKS_ATTRIBUTE_TABLE	gnat_internal_attribute_table
#undef  LANG_HOOKS_BUILTIN_FUNCTION
#define LANG_HOOKS_BUILTIN_FUNCTION	gnat_builtin_function
1475 1476
#undef  LANG_HOOKS_INIT_TS
#define LANG_HOOKS_INIT_TS		gnat_init_ts
1477 1478 1479 1480
#undef  LANG_HOOKS_EH_PERSONALITY
#define LANG_HOOKS_EH_PERSONALITY	gnat_eh_personality
#undef  LANG_HOOKS_DEEP_UNSHARING
#define LANG_HOOKS_DEEP_UNSHARING	true
1481 1482
#undef  LANG_HOOKS_CUSTOM_FUNCTION_DESCRIPTORS
#define LANG_HOOKS_CUSTOM_FUNCTION_DESCRIPTORS true
1483 1484 1485

struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;

1486
#include "gt-ada-misc.h"