OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [java/] [lang.c] - Blame information for rev 826

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 287 jeremybenn
/* Java(TM) language-specific utility routines.
2
   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3
   2005, 2006, 2007, 2008 Free Software Foundation, Inc.
4
 
5
This file is part of GCC.
6
 
7
GCC is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 3, or (at your option)
10
any later version.
11
 
12
GCC is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
GNU General Public License for more details.
16
 
17
You should have received a copy of the GNU General Public License
18
along with GCC; see the file COPYING3.  If not see
19
<http://www.gnu.org/licenses/>.
20
 
21
Java and all Java-based marks are trademarks or registered trademarks
22
of Sun Microsystems, Inc. in the United States and other countries.
23
The Free Software Foundation is independent of Sun Microsystems, Inc.  */
24
 
25
/* Hacked by Per Bothner <bothner@cygnus.com> February 1996. */
26
 
27
#include "config.h"
28
#include "system.h"
29
#include "coretypes.h"
30
#include "tm.h"
31
#include "tree.h"
32
#include "input.h"
33
#include "rtl.h"
34
#include "expr.h"
35
#include "java-tree.h"
36
#include "jcf.h"
37
#include "toplev.h"
38
#include "langhooks.h"
39
#include "langhooks-def.h"
40
#include "flags.h"
41
#include "ggc.h"
42
#include "diagnostic.h"
43
#include "tree-inline.h"
44
#include "splay-tree.h"
45
#include "tree-dump.h"
46
#include "opts.h"
47
#include "options.h"
48
#include "except.h"
49
 
50
static bool java_init (void);
51
static void java_finish (void);
52
static unsigned int java_init_options (unsigned int, const char **);
53
static bool java_post_options (const char **);
54
 
55
static int java_handle_option (size_t scode, const char *arg, int value);
56
static void put_decl_string (const char *, int);
57
static void put_decl_node (tree, int);
58
static void java_print_error_function (diagnostic_context *, const char *,
59
                                       diagnostic_info *);
60
static int merge_init_test_initialization (void * *, void *);
61
static int inline_init_test_initialization (void * *, void *);
62
static bool java_dump_tree (void *, tree);
63
static void dump_compound_expr (dump_info_p, tree);
64
static bool java_decl_ok_for_sibcall (const_tree);
65
 
66
static enum classify_record java_classify_record (tree type);
67
 
68
static tree java_eh_personality (void);
69
 
70
#ifndef TARGET_OBJECT_SUFFIX
71
# define TARGET_OBJECT_SUFFIX ".o"
72
#endif
73
 
74
/* Table of machine-independent attributes.  */
75
const struct attribute_spec java_attribute_table[] =
76
{
77
 { "nonnull",                0, -1, false, true, true,
78
                              NULL },
79
  { NULL,                     0, 0, false, false, false, NULL }
80
};
81
 
82
/* Used to avoid printing error messages with bogus function
83
   prototypes.  Starts out false.  */
84
static bool inhibit_error_function_printing;
85
 
86
const char *resource_name;
87
 
88
/* When nonzero, -Wall was turned on.  */
89
int flag_wall = 0;
90
 
91
/* When nonzero, report use of deprecated classes, methods, or fields.  */
92
int flag_deprecated = 1;
93
 
94
/* When zero, don't optimize static class initialization. This flag shouldn't
95
   be tested alone, use STATIC_CLASS_INITIALIZATION_OPTIMIZATION_P instead.  */
96
/* FIXME: Make this work with gimplify.  */
97
/* int flag_optimize_sci = 0;  */
98
 
99
/* Don't attempt to verify invocations.  */
100
int flag_verify_invocations = 0;
101
 
102
/* When nonzero, print extra version information.  */
103
static int v_flag = 0;
104
 
105
JCF *current_jcf;
106
 
107
/* Variable controlling how dependency tracking is enabled in
108
   java_init.  */
109
static int dependency_tracking = 0;
110
 
111
/* Flag values for DEPENDENCY_TRACKING.  */
112
#define DEPEND_SET_FILE 1
113
#define DEPEND_ENABLE   2
114
#define DEPEND_TARGET_SET 4
115
#define DEPEND_FILE_ALREADY_SET 8
116
 
117
struct GTY(()) language_function {
118
  int unused;
119
};
120
 
121
#undef LANG_HOOKS_NAME
122
#define LANG_HOOKS_NAME "GNU Java"
123
#undef LANG_HOOKS_INIT
124
#define LANG_HOOKS_INIT java_init
125
#undef LANG_HOOKS_FINISH
126
#define LANG_HOOKS_FINISH java_finish
127
#undef LANG_HOOKS_INIT_OPTIONS
128
#define LANG_HOOKS_INIT_OPTIONS java_init_options
129
#undef LANG_HOOKS_HANDLE_OPTION
130
#define LANG_HOOKS_HANDLE_OPTION java_handle_option
131
#undef LANG_HOOKS_POST_OPTIONS
132
#define LANG_HOOKS_POST_OPTIONS java_post_options
133
#undef LANG_HOOKS_PARSE_FILE
134
#define LANG_HOOKS_PARSE_FILE java_parse_file
135
#undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
136
#define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL java_dup_lang_specific_decl
137
#undef LANG_HOOKS_DECL_PRINTABLE_NAME
138
#define LANG_HOOKS_DECL_PRINTABLE_NAME lang_printable_name
139
#undef LANG_HOOKS_PRINT_ERROR_FUNCTION
140
#define LANG_HOOKS_PRINT_ERROR_FUNCTION java_print_error_function
141
 
142
#undef LANG_HOOKS_TYPE_FOR_MODE
143
#define LANG_HOOKS_TYPE_FOR_MODE java_type_for_mode
144
#undef LANG_HOOKS_TYPE_FOR_SIZE
145
#define LANG_HOOKS_TYPE_FOR_SIZE java_type_for_size
146
#undef LANG_HOOKS_CLASSIFY_RECORD
147
#define LANG_HOOKS_CLASSIFY_RECORD java_classify_record
148
 
149
#undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN
150
#define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN java_dump_tree
151
 
152
#undef LANG_HOOKS_GIMPLIFY_EXPR
153
#define LANG_HOOKS_GIMPLIFY_EXPR java_gimplify_expr
154
 
155
#undef LANG_HOOKS_DECL_OK_FOR_SIBCALL
156
#define LANG_HOOKS_DECL_OK_FOR_SIBCALL java_decl_ok_for_sibcall
157
 
158
#undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME
159
#define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME java_mangle_decl
160
 
161
#undef LANG_HOOKS_ATTRIBUTE_TABLE
162
#define LANG_HOOKS_ATTRIBUTE_TABLE java_attribute_table
163
 
164
#undef LANG_HOOKS_EH_PERSONALITY
165
#define LANG_HOOKS_EH_PERSONALITY java_eh_personality
166
 
167
#undef LANG_HOOKS_EH_USE_CXA_END_CLEANUP
168
#define LANG_HOOKS_EH_USE_CXA_END_CLEANUP  true
169
 
170
/* Each front end provides its own.  */
171
struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
172
 
173
/*
174
 * process java-specific compiler command-line options
175
 * return 0, but do not complain if the option is not recognized.
176
 */
177
static int
178
java_handle_option (size_t scode, const char *arg, int value)
179
{
180
  enum opt_code code = (enum opt_code) scode;
181
 
182
  switch (code)
183
    {
184
    case OPT_I:
185
      jcf_path_include_arg (arg);
186
      break;
187
 
188
    case OPT_M:
189
      jcf_dependency_init (1);
190
      dependency_tracking |= DEPEND_ENABLE;
191
      break;
192
 
193
    case OPT_MD_:
194
      jcf_dependency_init (1);
195
      dependency_tracking |= DEPEND_SET_FILE | DEPEND_ENABLE;
196
      break;
197
 
198
    case OPT_MF:
199
      jcf_dependency_set_dep_file (arg);
200
      dependency_tracking |= DEPEND_FILE_ALREADY_SET;
201
      break;
202
 
203
    case OPT_MM:
204
      jcf_dependency_init (0);
205
      dependency_tracking |= DEPEND_ENABLE;
206
      break;
207
 
208
    case OPT_MMD_:
209
      jcf_dependency_init (0);
210
      dependency_tracking |= DEPEND_SET_FILE | DEPEND_ENABLE;
211
      break;
212
 
213
    case OPT_MP:
214
      jcf_dependency_print_dummies ();
215
      break;
216
 
217
    case OPT_MT:
218
      jcf_dependency_set_target (arg);
219
      dependency_tracking |= DEPEND_TARGET_SET;
220
      break;
221
 
222
    case OPT_Wall:
223
      flag_wall = value;
224
      /* When -Wall given, enable -Wunused.  We do this because the C
225
         compiler does it, and people expect it.  */
226
      warn_unused = value;
227
      break;
228
 
229
    case OPT_fenable_assertions_:
230
      add_enable_assert (arg, value);
231
      break;
232
 
233
    case OPT_fenable_assertions:
234
      add_enable_assert ("", value);
235
      break;
236
 
237
    case OPT_fdisable_assertions_:
238
      add_enable_assert (arg, !value);
239
      break;
240
 
241
    case OPT_fdisable_assertions:
242
      add_enable_assert ("", !value);
243
      break;
244
 
245
    case OPT_fassume_compiled_:
246
      add_assume_compiled (arg, !value);
247
      break;
248
 
249
    case OPT_fassume_compiled:
250
      add_assume_compiled ("", !value);
251
      break;
252
 
253
    case OPT_fbootclasspath_:
254
      jcf_path_bootclasspath_arg (arg);
255
      break;
256
 
257
    case OPT_faux_classpath:
258
    case OPT_fclasspath_:
259
    case OPT_fCLASSPATH_:
260
      jcf_path_classpath_arg (arg);
261
      break;
262
 
263
    case OPT_fcompile_resource_:
264
      resource_name = arg;
265
      break;
266
 
267
    case OPT_fdump_:
268
      if (!dump_switch_p (arg))
269
        return 0;
270
      break;
271
 
272
    case OPT_fencoding_:
273
      /* Nothing.  */
274
      break;
275
 
276
    case OPT_fextdirs_:
277
      jcf_path_extdirs_arg (arg);
278
      break;
279
 
280
    case OPT_foutput_class_dir_:
281
      /* FIXME: remove; this is handled by ecj1 now.  */
282
      break;
283
 
284
    case OPT_version:
285
      v_flag = 1;
286
      break;
287
 
288
    case OPT_fsource_filename_:
289
      java_read_sourcefilenames (arg);
290
      break;
291
 
292
    default:
293
      if (cl_options[code].flags & CL_Java)
294
        break;
295
      gcc_unreachable ();
296
    }
297
 
298
  return 1;
299
}
300
 
301
/* Global open file.  */
302
FILE *finput;
303
 
304
static bool
305
java_init (void)
306
{
307
  /* FIXME: Indirect dispatch isn't yet compatible with static class
308
     init optimization.  */
309
  if (flag_indirect_dispatch)
310
    always_initialize_class_p = true;
311
 
312
  if (!flag_indirect_dispatch)
313
    flag_indirect_classes = false;
314
 
315
  jcf_path_seal (v_flag);
316
 
317
  java_init_decl_processing ();
318
 
319
  using_eh_for_cleanups ();
320
 
321
  return true;
322
}
323
 
324
static void
325
java_finish (void)
326
{
327
  jcf_dependency_write ();
328
}
329
 
330
/* Buffer used by lang_printable_name. */
331
static char *decl_buf = NULL;
332
 
333
/* Allocated size of decl_buf. */
334
static int decl_buflen = 0;
335
 
336
/* Length of used part of decl_buf;  position for next character. */
337
static int decl_bufpos = 0;
338
 
339
/* Append the string STR to decl_buf.
340
   It length is given by LEN;  -1 means the string is nul-terminated. */
341
 
342
static void
343
put_decl_string (const char *str, int len)
344
{
345
  if (len < 0)
346
    len = strlen (str);
347
  if (decl_bufpos + len >= decl_buflen)
348
    {
349
      if (decl_buf == NULL)
350
        {
351
          decl_buflen = len + 100;
352
          decl_buf = XNEWVEC (char, decl_buflen);
353
        }
354
      else
355
        {
356
          decl_buflen *= 2;
357
          decl_buf = XRESIZEVAR (char, decl_buf, decl_buflen);
358
        }
359
    }
360
  strcpy (decl_buf + decl_bufpos, str);
361
  decl_bufpos += len;
362
}
363
 
364
/* Append to decl_buf a printable name for NODE.
365
   Depending on VERBOSITY, more information about NODE
366
   is printed. Read the comments of decl_printable_name in
367
   langhooks.h for more.  */
368
 
369
static void
370
put_decl_node (tree node, int verbosity)
371
{
372
  int was_pointer = 0;
373
  if (TREE_CODE (node) == POINTER_TYPE)
374
    {
375
      node = TREE_TYPE (node);
376
      was_pointer = 1;
377
    }
378
  if (DECL_P (node) && DECL_NAME (node) != NULL_TREE)
379
    {
380
      if (TREE_CODE (node) == FUNCTION_DECL)
381
        {
382
          if (verbosity == 0 && DECL_NAME (node))
383
          /* We have been instructed to just print the bare name
384
             of the function.  */
385
            {
386
              put_decl_node (DECL_NAME (node), 0);
387
              return;
388
            }
389
 
390
          /* We want to print the type the DECL belongs to. We don't do
391
             that when we handle constructors. */
392
          if (! DECL_CONSTRUCTOR_P (node)
393
              && ! DECL_ARTIFICIAL (node) && DECL_CONTEXT (node)
394
              /* We want to print qualified DECL names only
395
                 if verbosity is higher than 1.  */
396
              && verbosity >= 1)
397
            {
398
              put_decl_node (TYPE_NAME (DECL_CONTEXT (node)),
399
                               verbosity);
400
              put_decl_string (".", 1);
401
            }
402
          if (! DECL_CONSTRUCTOR_P (node))
403
            put_decl_node (DECL_NAME (node), verbosity);
404
          if (TREE_TYPE (node) != NULL_TREE
405
              /* We want to print function parameters only if verbosity
406
                 is higher than 2.  */
407
              && verbosity >= 2)
408
            {
409
              int i = 0;
410
              tree args = TYPE_ARG_TYPES (TREE_TYPE (node));
411
              if (TREE_CODE (TREE_TYPE (node)) == METHOD_TYPE)
412
                args = TREE_CHAIN (args);
413
              put_decl_string ("(", 1);
414
              for ( ; args != end_params_node;  args = TREE_CHAIN (args), i++)
415
                {
416
                  if (i > 0)
417
                    put_decl_string (",", 1);
418
                  put_decl_node (TREE_VALUE (args), verbosity);
419
                }
420
              put_decl_string (")", 1);
421
            }
422
        }
423
      else
424
        put_decl_node (DECL_NAME (node), verbosity);
425
    }
426
  else if (TYPE_P (node) && TYPE_NAME (node) != NULL_TREE)
427
    {
428
      if (TREE_CODE (node) == RECORD_TYPE && TYPE_ARRAY_P (node)
429
          /* Print detailed array information only if verbosity is higher
430
            than 2.  */
431
          && verbosity >= 2)
432
        {
433
          put_decl_node (TYPE_ARRAY_ELEMENT (node), verbosity);
434
          put_decl_string("[]", 2);
435
        }
436
      else if (node == promoted_byte_type_node)
437
        put_decl_string ("byte", 4);
438
      else if (node == promoted_short_type_node)
439
        put_decl_string ("short", 5);
440
      else if (node == promoted_char_type_node)
441
        put_decl_string ("char", 4);
442
      else if (node == promoted_boolean_type_node)
443
        put_decl_string ("boolean", 7);
444
      else if (node == void_type_node && was_pointer)
445
        put_decl_string ("null", 4);
446
      else
447
        put_decl_node (TYPE_NAME (node), verbosity);
448
    }
449
  else if (TREE_CODE (node) == IDENTIFIER_NODE)
450
    put_decl_string (IDENTIFIER_POINTER (node), IDENTIFIER_LENGTH (node));
451
  else
452
    put_decl_string ("<unknown>", -1);
453
}
454
 
455
/* Return a user-friendly name for DECL.
456
   The resulting string is only valid until the next call.
457
   The value of the hook decl_printable_name is this function,
458
   which is also called directly by java_print_error_function. */
459
 
460
const char *
461
lang_printable_name (tree decl, int v)
462
{
463
  decl_bufpos = 0;
464
  put_decl_node (decl, v);
465
  put_decl_string ("", 1);
466
  return decl_buf;
467
}
468
 
469
/* Print on stderr the current class and method context.  This function
470
   is the value of the hook print_error_function. */
471
 
472
static GTY(()) tree last_error_function_context;
473
static GTY(()) tree last_error_function;
474
static void
475
java_print_error_function (diagnostic_context *context ATTRIBUTE_UNUSED,
476
                           const char *file,
477
                           diagnostic_info *diagnostic ATTRIBUTE_UNUSED)
478
{
479
  /* Don't print error messages with bogus function prototypes.  */
480
  if (inhibit_error_function_printing)
481
    return;
482
 
483
  if (current_function_decl != NULL
484
      && DECL_CONTEXT (current_function_decl) != last_error_function_context)
485
    {
486
      if (file)
487
        fprintf (stderr, "%s: ", file);
488
 
489
      last_error_function_context = DECL_CONTEXT (current_function_decl);
490
      fprintf (stderr, "In class '%s':\n",
491
               lang_printable_name (last_error_function_context, 0));
492
    }
493
  if (last_error_function != current_function_decl)
494
    {
495
      if (file)
496
        fprintf (stderr, "%s: ", file);
497
 
498
      if (current_function_decl == NULL)
499
        fprintf (stderr, "At top level:\n");
500
      else
501
        {
502
          const char *name = lang_printable_name (current_function_decl, 2);
503
          fprintf (stderr, "In %s '%s':\n",
504
                   (DECL_CONSTRUCTOR_P (current_function_decl) ? "constructor"
505
                    : "method"),
506
                   name);
507
        }
508
 
509
      last_error_function = current_function_decl;
510
    }
511
 
512
}
513
 
514
/* Called to install the PRINT_ERROR_FUNCTION hook differently
515
   according to LEVEL. LEVEL is 1 during early parsing, when function
516
   prototypes aren't fully resolved. java_print_error_function is set
517
   so it doesn't print incomplete function prototypes. When LEVEL is
518
   2, function prototypes are fully resolved and can be printed when
519
   reporting errors.  */
520
 
521
void
522
lang_init_source (int level)
523
{
524
  inhibit_error_function_printing = (level == 1);
525
}
526
 
527
static unsigned int
528
java_init_options (unsigned int argc ATTRIBUTE_UNUSED,
529
                   const char **argv ATTRIBUTE_UNUSED)
530
{
531
  flag_bounds_check = 1;
532
  flag_exceptions = 1;
533
  flag_non_call_exceptions = 1;
534
 
535
  /* In Java floating point operations never trap.  */
536
  flag_trapping_math = 0;
537
 
538
  /* In Java arithmetic overflow always wraps around.  */
539
  flag_wrapv = 1;
540
 
541
  /* Java requires left-to-right evaluation of subexpressions.  */
542
  flag_evaluation_order = 1;
543
 
544
  jcf_path_init ();
545
 
546
  return CL_Java;
547
}
548
 
549
/* Post-switch processing.  */
550
static bool
551
java_post_options (const char **pfilename)
552
{
553
  const char *filename = *pfilename;
554
 
555
  /* Excess precision other than "fast" requires front-end
556
     support.  */
557
  if (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD
558
      && TARGET_FLT_EVAL_METHOD_NON_DEFAULT)
559
    sorry ("-fexcess-precision=standard for Java");
560
  flag_excess_precision_cmdline = EXCESS_PRECISION_FAST;
561
 
562
  /* An absolute requirement: if we're not using indirect dispatch, we
563
     must always verify everything.  */
564
  if (! flag_indirect_dispatch)
565
    flag_verify_invocations = true;
566
 
567
  if (flag_reduced_reflection)
568
    {
569
      if (flag_indirect_dispatch)
570
        error ("-findirect-dispatch is incompatible "
571
               "with -freduced-reflection");
572
      if (flag_jni)
573
        error ("-fjni is incompatible with -freduced-reflection");
574
    }
575
 
576
  /* Open input file.  */
577
 
578
  if (filename == 0 || !strcmp (filename, "-"))
579
    {
580
      finput = stdin;
581
      filename = "stdin";
582
 
583
      if (dependency_tracking)
584
        error ("can't do dependency tracking with input from stdin");
585
    }
586
  else
587
    {
588
      if (dependency_tracking)
589
        {
590
          const char *dot;
591
 
592
          /* If the target is set and the output filename is set, then
593
             there's no processing to do here.  Otherwise we must
594
             compute one or the other.  */
595
          if (! ((dependency_tracking & DEPEND_TARGET_SET)
596
                 && (dependency_tracking & DEPEND_FILE_ALREADY_SET)))
597
            {
598
              dot = strrchr (filename, '.');
599
              if (dot == NULL)
600
                error ("couldn't determine target name for dependency tracking");
601
              else
602
                {
603
                  char *buf = XNEWVEC (char, dot - filename +
604
                                       3 + sizeof (TARGET_OBJECT_SUFFIX));
605
                  strncpy (buf, filename, dot - filename);
606
 
607
                  /* If emitting class files, we might have multiple
608
                     targets.  The class generation code takes care of
609
                     registering them.  Otherwise we compute the
610
                     target name here.  */
611
                  if ((dependency_tracking & DEPEND_TARGET_SET))
612
                    ; /* Nothing.  */
613
                  else
614
                    {
615
                      strcpy (buf + (dot - filename), TARGET_OBJECT_SUFFIX);
616
                      jcf_dependency_set_target (buf);
617
                    }
618
 
619
                  if ((dependency_tracking & DEPEND_FILE_ALREADY_SET))
620
                    ; /* Nothing.  */
621
                  else if ((dependency_tracking & DEPEND_SET_FILE))
622
                    {
623
                      strcpy (buf + (dot - filename), ".d");
624
                      jcf_dependency_set_dep_file (buf);
625
                    }
626
                  else
627
                    jcf_dependency_set_dep_file ("-");
628
 
629
                  free (buf);
630
                }
631
            }
632
        }
633
    }
634
  linemap_add (line_table, LC_ENTER, false, filename, 0);
635
  linemap_add (line_table, LC_RENAME, false, "<built-in>", 0);
636
 
637
  /* Initialize the compiler back end.  */
638
  return false;
639
}
640
 
641
/* Return either DECL or its known constant value (if it has one).  */
642
 
643
tree
644
decl_constant_value (tree decl)
645
{
646
  if (/* Don't change a variable array bound or initial value to a constant
647
         in a place where a variable is invalid.  */
648
      current_function_decl != 0
649
      && ! TREE_THIS_VOLATILE (decl)
650
      && TREE_READONLY (decl)
651
      && DECL_INITIAL (decl) != 0
652
      && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK
653
      /* This is invalid if initial value is not constant.
654
         If it has either a function call, a memory reference,
655
         or a variable, then re-evaluating it could give different results.  */
656
      && TREE_CONSTANT (DECL_INITIAL (decl))
657
      /* Check for cases where this is sub-optimal, even though valid.  */
658
      && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR)
659
    return DECL_INITIAL (decl);
660
  return decl;
661
}
662
 
663
/* Every call to a static constructor has an associated boolean
664
   variable which is in the outermost scope of the calling method.
665
   This variable is used to avoid multiple calls to the static
666
   constructor for each class.
667
 
668
   It looks something like this:
669
 
670
   foo ()
671
   {
672
      boolean dummy = OtherClass.is_initialized;
673
 
674
     ...
675
 
676
     if (! dummy)
677
       OtherClass.initialize();
678
 
679
     ... use OtherClass.data ...
680
   }
681
 
682
   Each of these boolean variables has an entry in the
683
   DECL_FUNCTION_INIT_TEST_TABLE of a method.  When inlining a method
684
   we must merge the DECL_FUNCTION_INIT_TEST_TABLE from the function
685
   being inlined and create the boolean variables in the outermost
686
   scope of the method being inlined into.  */
687
 
688
/* Create a mapping from a boolean variable in a method being inlined
689
   to one in the scope of the method being inlined into.  */
690
 
691
static int
692
merge_init_test_initialization (void **entry, void *x)
693
{
694
  struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
695
  splay_tree decl_map = (splay_tree)x;
696
  splay_tree_node n;
697
  tree *init_test_decl;
698
 
699
  /* See if we have remapped this declaration.  If we haven't there's
700
     a bug in the inliner.  */
701
  n = splay_tree_lookup (decl_map, (splay_tree_key) ite->value);
702
  gcc_assert (n);
703
 
704
  /* Create a new entry for the class and its remapped boolean
705
     variable.  If we already have a mapping for this class we've
706
     already initialized it, so don't overwrite the value.  */
707
  init_test_decl = java_treetreehash_new
708
    (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl), ite->key);
709
  if (!*init_test_decl)
710
    *init_test_decl = (tree)n->value;
711
 
712
  /* This fixes a weird case.
713
 
714
  The front end assumes that once we have called a method that
715
  initializes some class, we can assume the class is initialized.  It
716
  does this by setting the DECL_INITIAL of the init_test_decl for that
717
  class, and no initializations are emitted for that class.
718
 
719
  However, what if the method that is supposed to do the initialization
720
  is itself inlined in the caller?  When expanding the called method
721
  we'll assume that the class initialization has already been done,
722
  because the DECL_INITIAL of the init_test_decl is set.
723
 
724
  To fix this we remove the DECL_INITIAL (in the caller scope) of all
725
  the init_test_decls corresponding to classes initialized by the
726
  inlined method.  This makes the caller no longer assume that the
727
  method being inlined does any class initializations.  */
728
  DECL_INITIAL (*init_test_decl) = NULL;
729
 
730
  return true;
731
}
732
 
733
/* Merge the DECL_FUNCTION_INIT_TEST_TABLE from the function we're
734
   inlining.  */
735
 
736
void
737
java_inlining_merge_static_initializers (tree fn, void *decl_map)
738
{
739
  htab_traverse
740
    (DECL_FUNCTION_INIT_TEST_TABLE (fn),
741
     merge_init_test_initialization, decl_map);
742
}
743
 
744
/* Lookup a DECL_FUNCTION_INIT_TEST_TABLE entry in the method we're
745
   inlining into.  If we already have a corresponding entry in that
746
   class we don't need to create another one, so we create a mapping
747
   from the variable in the inlined class to the corresponding
748
   pre-existing one.  */
749
 
750
static int
751
inline_init_test_initialization (void **entry, void *x)
752
{
753
  struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
754
  splay_tree decl_map = (splay_tree)x;
755
 
756
  tree h = java_treetreehash_find
757
    (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl), ite->key);
758
  if (! h)
759
    return true;
760
  splay_tree_insert (decl_map,
761
                     (splay_tree_key) ite->value,
762
                     (splay_tree_value) h);
763
  return true;
764
}
765
 
766
/* Look up the boolean variables in the DECL_FUNCTION_INIT_TEST_TABLE
767
   of a method being inlined.  For each hone, if we already have a
768
   variable associated with the same class in the method being inlined
769
   into, create a new mapping for it.  */
770
 
771
void
772
java_inlining_map_static_initializers (tree fn, void *decl_map)
773
{
774
  htab_traverse
775
    (DECL_FUNCTION_INIT_TEST_TABLE (fn),
776
     inline_init_test_initialization, decl_map);
777
}
778
 
779
/* Avoid voluminous output for deep recursion of compound exprs.  */
780
 
781
static void
782
dump_compound_expr (dump_info_p di, tree t)
783
{
784
  int i;
785
 
786
  for (i=0; i<2; i++)
787
    {
788
      switch (TREE_CODE (TREE_OPERAND (t, i)))
789
        {
790
        case COMPOUND_EXPR:
791
          dump_compound_expr (di, TREE_OPERAND (t, i));
792
          break;
793
 
794
        default:
795
          dump_child ("expr", TREE_OPERAND (t, i));
796
        }
797
    }
798
}
799
 
800
static bool
801
java_dump_tree (void *dump_info, tree t)
802
{
803
  enum tree_code code;
804
  dump_info_p di = (dump_info_p) dump_info;
805
 
806
  /* Figure out what kind of node this is.  */
807
  code = TREE_CODE (t);
808
 
809
  switch (code)
810
    {
811
    case FUNCTION_DECL:
812
      dump_child ("args", DECL_ARGUMENTS (t));
813
      if (DECL_EXTERNAL (t))
814
        dump_string (di, "undefined");
815
      if (TREE_PUBLIC (t))
816
        dump_string (di, "extern");
817
      else
818
        dump_string (di, "static");
819
      if (DECL_LANG_SPECIFIC (t) && !dump_flag (di, TDF_SLIM, t))
820
        dump_child ("inline body", DECL_SAVED_TREE (t));
821
      return true;
822
 
823
    case RETURN_EXPR:
824
      dump_child ("expr", TREE_OPERAND (t, 0));
825
      return true;
826
 
827
    case GOTO_EXPR:
828
      dump_child ("goto", TREE_OPERAND (t, 0));
829
      return true;
830
 
831
    case LABEL_EXPR:
832
      dump_child ("label", TREE_OPERAND (t, 0));
833
      return true;
834
 
835
    case BLOCK:
836
      if (BLOCK_EXPR_BODY (t))
837
        {
838
          tree local = BLOCK_VARS (t);
839
          while (local)
840
            {
841
              tree next = TREE_CHAIN (local);
842
              dump_child ("var", local);
843
              local = next;
844
            }
845
 
846
          {
847
            tree block = BLOCK_EXPR_BODY (t);
848
            dump_child ("body", block);
849
            block = TREE_CHAIN (block);
850
          }
851
        }
852
      return true;
853
 
854
    case COMPOUND_EXPR:
855
      if (!dump_flag (di, TDF_SLIM, t))
856
        return false;
857
      dump_compound_expr (di, t);
858
      return true;
859
 
860
    default:
861
      break;
862
    }
863
  return false;
864
}
865
 
866
/* Java calls can't, in general, be sibcalls because we need an
867
   accurate stack trace in order to guarantee correct operation of
868
   methods such as Class.forName(String) and
869
   SecurityManager.getClassContext().  */
870
 
871
static bool
872
java_decl_ok_for_sibcall (const_tree decl)
873
{
874
  return (decl != NULL && DECL_CONTEXT (decl) == output_class
875
          && !DECL_UNINLINABLE (decl));
876
}
877
 
878
static enum classify_record
879
java_classify_record (tree type)
880
{
881
  if (! CLASS_P (type))
882
    return RECORD_IS_STRUCT;
883
 
884
  /* ??? GDB does not support DW_TAG_interface_type as of December,
885
     2007.  Re-enable this at a later time.  */
886
  if (0 && CLASS_INTERFACE (TYPE_NAME (type)))
887
    return RECORD_IS_INTERFACE;
888
 
889
  return RECORD_IS_CLASS;
890
}
891
 
892
static GTY(()) tree java_eh_personality_decl;
893
 
894
static tree
895
java_eh_personality (void)
896
{
897
  if (!java_eh_personality_decl)
898
    java_eh_personality_decl
899
      = build_personality_function (USING_SJLJ_EXCEPTIONS
900
                                    ? "__gcj_personality_sj0"
901
                                    : "__gcj_personality_v0");
902
 
903
  return java_eh_personality_decl;
904
}
905
 
906
#include "gt-java-lang.h"

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.