class.c 99.1 KB
Newer Older
Anthony Green committed
1
/* Functions related to building classes and their related objects.
2
   Copyright (C) 1996-2014 Free Software Foundation, Inc.
Anthony Green committed
3

4
This file is part of GCC.
Anthony Green committed
5

6
GCC is free software; you can redistribute it and/or modify
Anthony Green committed
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 3, or (at your option)
Anthony Green committed
9 10
any later version.

11
GCC is distributed in the hope that it will be useful,
Anthony Green committed
12 13 14 15 16
but WITHOUT 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 Public License
17 18
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.
Anthony Green committed
19 20 21 22 23 24 25 26

Java and all Java-based marks are trademarks or registered trademarks
of Sun Microsystems, Inc. in the United States and other countries.
The Free Software Foundation is independent of Sun Microsystems, Inc.  */

/* Written by Per Bothner <bothner@cygnus.com> */

#include "config.h"
27
#include "system.h"
28
#include "coretypes.h"
Anthony Green committed
29
#include "tree.h"
30 31 32
#include "stringpool.h"
#include "stor-layout.h"
#include "varasm.h"
33
#include "flags.h"
Anthony Green committed
34 35 36
#include "java-tree.h"
#include "jcf.h"
#include "obstack.h"
37
#include "diagnostic-core.h"
38
#include "toplev.h"
39
#include "output.h" /* for switch_to_section and get_section */
Kaveh R. Ghazi committed
40
#include "parse.h"
41 42 43 44 45 46 47
#include "hashtab.h"
#include "hash-set.h"
#include "vec.h"
#include "machmode.h"
#include "tm.h"
#include "hard-reg-set.h"
#include "input.h"
48
#include "function.h"
49
#include "ggc.h"
Andrew MacLeod committed
50 51 52 53
#include "hash-map.h"
#include "is-a.h"
#include "plugin-api.h"
#include "ipa-ref.h"
54
#include "cgraph.h"
55
#include "tree-iterator.h"
56
#include "target.h"
Anthony Green committed
57

58 59 60 61 62 63
static tree make_method_value (tree);
static tree build_java_method_type (tree, tree, int);
static int32 hashUtf8String (const char *, int);
static tree make_field_value (tree);
static tree get_dispatch_vector (tree);
static tree get_dispatch_table (tree, tree);
64
static int supers_all_compiled (tree type);
65
static tree maybe_layout_super_class (tree, tree);
66
static void add_miranda_methods (tree, tree);
67
static int assume_compiled (const char *);
68
static tree build_symbol_entry (tree, tree);
69
static tree emit_assertion_table (tree);
70
static void register_class (void);
71

Mark Mitchell committed
72
struct obstack temporary_obstack;
Anthony Green committed
73

74 75
static const char *cyclic_inheritance_report;

76 77 78 79
/* The compiler generates different code depending on whether or not
   it can assume certain classes have been compiled down to native
   code or not.  The compiler options -fassume-compiled= and
   -fno-assume-compiled= are used to create a tree of
80
   class_flag_node objects.  This tree is queried to determine if
81 82 83
   a class is assume to be compiled or not.  Each node in the tree
   represents either a package or a specific class.  */

84
typedef struct class_flag_node_struct
85 86 87 88
{
  /* The class or package name.  */
  const char *ident;

89
  /* Nonzero if this represents an exclusion.  */
90
  int value;
91 92

  /* Pointers to other nodes in the tree.  */
93 94 95 96
  struct class_flag_node_struct *parent;
  struct class_flag_node_struct *sibling;
  struct class_flag_node_struct *child;
} class_flag_node;
97

98 99
static class_flag_node *find_class_flag_node (class_flag_node *, const char *);
static void add_class_flag (class_flag_node **, const char *, int);
100

101 102
/* This is the root of the include/exclude tree.  */

103 104 105
static class_flag_node *assume_compiled_tree;

static class_flag_node *enable_assert_tree;
106

107 108 109 110 111 112
static GTY(()) tree class_roots[4];
#define fields_ident class_roots[0]  /* get_identifier ("fields") */
#define info_ident class_roots[1]  /* get_identifier ("info") */
#define class_list class_roots[2]
#define class_dtable_decl class_roots[3]

113
static GTY(()) vec<tree, va_gc> *registered_class;
114

115 116 117 118
/* A tree that returns the address of the class$ of the class
   currently being compiled.  */
static GTY(()) tree this_classdollar;

119 120
/* A list of static class fields.  This is to emit proper debug
   info for them.  */
121
vec<tree, va_gc> *pending_static_fields;
122

123
/* Return the node that most closely represents the class whose name
124 125
   is IDENT.  Start the search from NODE (followed by its siblings).
   Return NULL if an appropriate node does not exist.  */
126

127 128
static class_flag_node *
find_class_flag_node (class_flag_node *node, const char *ident)
129 130 131 132 133 134 135 136 137 138 139 140
{
  while (node)
    {
      size_t node_ident_length = strlen (node->ident);

      /* node_ident_length is zero at the root of the tree.  If the
	 identifiers are the same length, then we have matching
	 classes.  Otherwise check if we've matched an enclosing
	 package name.  */

      if (node_ident_length == 0
	  || (strncmp (ident, node->ident, node_ident_length) == 0
141
	      && (ident[node_ident_length] == '\0'
142 143 144 145 146
		  || ident[node_ident_length] == '.')))
	{
	  /* We've found a match, however, there might be a more
             specific match.  */

147
	  class_flag_node *found = find_class_flag_node (node->child, ident);
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
	  if (found)
	    return found;
	  else
	    return node;
	}

      /* No match yet.  Continue through the sibling list.  */
      node = node->sibling;
    }

  /* No match at all in this tree.  */
  return NULL;
}

void
163
add_class_flag (class_flag_node **rootp, const char *ident, int value)
164
{
165 166
  class_flag_node *root = *rootp;
  class_flag_node *parent, *node;
167 168 169

  /* Create the root of the tree if it doesn't exist yet.  */

170
  if (NULL == root)
171
    {
172
      root = XNEW (class_flag_node);
173 174 175 176 177 178
      root->ident = "";
      root->value = 0;
      root->sibling = NULL;
      root->child = NULL;
      root->parent = NULL;
      *rootp = root;
179 180 181
    }

  /* Calling the function with the empty string means we're setting
182
     value for the root of the hierarchy.  */
183 184 185

  if (0 == ident[0])
    {
186
      root->value = value;
187 188 189 190 191 192
      return;
    }

  /* Find the parent node for this new node.  PARENT will either be a
     class or a package name.  Adjust PARENT accordingly.  */

193 194 195 196 197 198
  parent = find_class_flag_node (root, ident);
  if (strcmp (ident, parent->ident) == 0)
    parent->value = value;
  else
    {
      /* Insert new node into the tree.  */
199
      node = XNEW (class_flag_node);
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218

      node->ident = xstrdup (ident);
      node->value = value;
      node->child = NULL;

      node->parent = parent;
      node->sibling = parent->child;
      parent->child = node;
    }
}

/* Add a new IDENT to the include/exclude tree.  It's an exclusion
   if EXCLUDEP is nonzero.  */

void
add_assume_compiled (const char *ident, int excludep)
{
  add_class_flag (&assume_compiled_tree, ident, excludep);
}
219

220
/* The default value returned by enable_assertions. */
221

222
#define DEFAULT_ENABLE_ASSERT (optimize == 0)
223 224 225 226 227 228 229 230 231 232

/* Enter IDENT (a class or package name) into the enable-assertions table.
   VALUE is true to enable and false to disable. */

void
add_enable_assert (const char *ident, int value)
{
  if (enable_assert_tree == NULL)
    add_class_flag (&enable_assert_tree, "", DEFAULT_ENABLE_ASSERT);
  add_class_flag (&enable_assert_tree, ident, value);
233 234
}

235
/* Returns nonzero if IDENT is the name of a class that the compiler
236
   should assume has been compiled to object code.  */
237

238
static int
239
assume_compiled (const char *ident)
240
{
241
  class_flag_node *i;
242 243 244 245 246
  int result;
  
  if (NULL == assume_compiled_tree)
    return 1;

247
  i = find_class_flag_node (assume_compiled_tree, ident);
248

249
  result = ! i->value;
250 251 252 253
  
  return (result);
}

254 255 256 257 258
/* Return true if we should generate code to check assertions within KLASS. */

bool
enable_assertions (tree klass)
{
259
  /* Check if command-line specifies whether we should check assertions. */
260 261 262 263 264 265 266 267 268 269 270 271 272 273

  if (klass != NULL_TREE && DECL_NAME (klass) && enable_assert_tree != NULL)
    {
      const char *ident = IDENTIFIER_POINTER (DECL_NAME (klass));
      class_flag_node *node
	= find_class_flag_node (enable_assert_tree, ident);
      return node->value;
    }

  /* The default is to enable assertions if generating class files,
     or not optimizing. */
  return DEFAULT_ENABLE_ASSERT;
}

Anthony Green committed
274 275 276 277 278
/* Return an IDENTIFIER_NODE the same as (OLD_NAME, OLD_LENGTH).
   except that characters matching OLD_CHAR are substituted by NEW_CHAR.
   Also, PREFIX is prepended, and SUFFIX is appended. */

tree
279 280 281 282 283 284
ident_subst (const char* old_name,
	     int old_length,
	     const char *prefix,
	     int old_char,
	     int new_char,
	     const char *suffix)
Anthony Green committed
285 286 287 288
{
  int prefix_len = strlen (prefix);
  int suffix_len = strlen (suffix);
  int i = prefix_len + old_length + suffix_len + 1;
289
  char *buffer = (char *) alloca (i);
290

Anthony Green committed
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307
  strcpy (buffer, prefix);
  for (i = 0; i < old_length; i++)
    {
      char ch = old_name[i];
      if (ch == old_char)
	ch = new_char;
      buffer[prefix_len + i] = ch;
    }
  strcpy (buffer + prefix_len + old_length, suffix);
  return get_identifier (buffer);
}

/* Return an IDENTIFIER_NODE the same as OLD_ID,
   except that characters matching OLD_CHAR are substituted by NEW_CHAR.
   Also, PREFIX is prepended, and SUFFIX is appended. */

tree
308 309 310 311 312
identifier_subst (const tree old_id,
		  const char *prefix,
		  int old_char,
		  int new_char,
		  const char *suffix)
Anthony Green committed
313 314 315 316 317 318 319 320 321
{
  return ident_subst (IDENTIFIER_POINTER (old_id), IDENTIFIER_LENGTH (old_id),
		      prefix, old_char, new_char, suffix);
}

/* Generate a valid C identifier from the name of the class TYPE,
   prefixed by PREFIX. */

tree
322
mangled_classname (const char *prefix, tree type)
Anthony Green committed
323
{
324
  tree result;
Anthony Green committed
325 326 327
  tree ident = TYPE_NAME (type);
  if (TREE_CODE (ident) != IDENTIFIER_NODE)
    ident = DECL_NAME (ident);
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
  result = identifier_subst (ident, prefix, '.', '_', "");

  /* Replace any characters that aren't in the set [0-9a-zA-Z_$] with
     "_0xXX".  Class names containing such chracters are uncommon, but
     they do sometimes occur in class files.  Without this check,
     these names cause assembly errors.

     There is a possibility that a real class name could conflict with
     the identifier we generate, but it is unlikely and will
     immediately be detected as an assembler error.  At some point we
     should do something more elaborate (perhaps using the full
     unicode mangling scheme) in order to prevent such a conflict.  */
  {
    int i;
    const int len = IDENTIFIER_LENGTH (result);
    const char *p = IDENTIFIER_POINTER (result);
    int illegal_chars = 0;

    /* Make two passes over the identifier.  The first pass is merely
       to count illegal characters; we need to do this in order to
       allocate a buffer.  */
    for (i = 0; i < len; i++)
      {
	char c = p[i];
	illegal_chars += (! ISALNUM (c) && c != '_' && c != '$');
      }

    /* And the second pass, which is rarely executed, does the
       rewriting.  */
    if (illegal_chars != 0)
      {
359
	char *buffer = (char *) alloca (illegal_chars * 4 + len + 1);
360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
	int j;

	for (i = 0, j = 0; i < len; i++)
	  {
	    char c = p[i];
	    if (! ISALNUM (c) && c != '_' && c != '$')
	      {
		buffer[j++] = '_';
		sprintf (&buffer[j], "0x%02x", c);
		j += 4;
	      }
	    else
	      buffer[j++] = c;
	  }

	buffer[j] = 0;
	result = get_identifier (buffer);
      }
  }

  return result;
Anthony Green committed
381 382 383
}

tree
384
make_class (void)
Anthony Green committed
385 386 387
{
  tree type;
  type = make_node (RECORD_TYPE);
388 389 390
  /* Unfortunately we must create the binfo here, so that class
     loading works.  */
  TYPE_BINFO (type) = make_tree_binfo (0);
391
  MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC (type);
392 393 394 395 396 397
  TYPE_CATCH_CLASSES (type) = NULL;
  /* Push a dummy entry; we can't call make_catch_class_record here
     because other infrastructure may not be set up yet.  We'll come
     back and fill it in later once said infrastructure is
     initialized.  */
  CONSTRUCTOR_APPEND_ELT (TYPE_CATCH_CLASSES (type), NULL_TREE, NULL_TREE);
Anthony Green committed
398 399 400 401 402 403 404 405 406

  return type;
}

/* Given a fully-qualified classname in NAME (whose length is NAME_LENGTH),
   and where each of the constituents is separated by '/',
   return a corresponding IDENTIFIER_NODE, except using '.' as separator. */

tree
407
unmangle_classname (const char *name, int name_length)
Anthony Green committed
408
{
409
  tree to_return = ident_subst (name, name_length, "", '/', '.', "");
410 411 412 413 414 415 416 417 418 419 420 421
  /* It's not sufficient to compare to_return and get_identifier
     (name) to determine whether to_return is qualified. There are
     cases in signature analysis where name will be stripped of a
     trailing ';'. */
  name = IDENTIFIER_POINTER (to_return);
  while (*name)
    if (*name++ == '.') 
      {
	QUALIFIED_P (to_return) = 1;
	break;
      }
  
422
  return to_return;
Anthony Green committed
423 424
}

425 426 427
#define GEN_TABLE(TABLE, NAME, TABLE_TYPE, TYPE)			\
do									\
{									\
428 429 430
  const char *type_name = IDENTIFIER_POINTER (mangled_classname ("", TYPE)); \
  char *buf = (char *) alloca (strlen (type_name)			\
                               + strlen (#NAME "_syms_") + 1);		\
431 432
  tree decl;								\
									\
433
  sprintf (buf, #NAME "_%s", type_name);				\
434
  TYPE_## TABLE ##_DECL (type) = decl =					\
435
    build_decl (input_location, VAR_DECL, get_identifier (buf), TABLE_TYPE); \
436 437 438 439 440 441 442 443 444
  DECL_EXTERNAL (decl) = 1;						\
  TREE_STATIC (decl) = 1;						\
  TREE_READONLY (decl) = 1;						\
  TREE_CONSTANT (decl) = 1;						\
  DECL_IGNORED_P (decl) = 1;						\
  /* Mark the table as belonging to this class.  */			\
  pushdecl (decl);							\
  MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);				\
  DECL_OWNER (decl) = TYPE;						\
445
  sprintf (buf, #NAME "_syms_%s", type_name);				\
446
  TYPE_## TABLE ##_SYMS_DECL (TYPE) =					\
447
    build_decl (input_location, VAR_DECL, get_identifier (buf), symbols_array_type); \
448 449 450 451 452
  TREE_STATIC (TYPE_## TABLE ##_SYMS_DECL (TYPE)) = 1;			\
  TREE_CONSTANT (TYPE_## TABLE ##_SYMS_DECL (TYPE)) = 1;		\
  DECL_IGNORED_P (TYPE_## TABLE ##_SYMS_DECL (TYPE)) = 1;		\
}									\
while (0)
453

Ranjit Mathew committed
454 455
/* Given a class, create the DECLs for all its associated indirect
   dispatch tables.  */
456 457 458
void
gen_indirect_dispatch_tables (tree type)
{
459
  const char *type_name = IDENTIFIER_POINTER (mangled_classname ("", type));
460 461
  {  
    tree field = NULL;
462 463
    char *buf = (char *) alloca (strlen (type_name)
				 + strlen ("_catch_classes_") + 1);
464 465
    tree catch_class_type = make_node (RECORD_TYPE);

466
    sprintf (buf, "_catch_classes_%s", type_name);
467 468 469 470
    PUSH_FIELD (input_location,
		catch_class_type, field, "address", utf8const_ptr_type);
    PUSH_FIELD (input_location,
		catch_class_type, field, "classname", ptr_type_node);
471 472 473
    FINISH_RECORD (catch_class_type);
    
    TYPE_CTABLE_DECL (type) 
474
      = build_decl (input_location, VAR_DECL, get_identifier (buf),
475 476 477 478 479 480 481 482 483 484 485
		    build_array_type (catch_class_type, 0));
    DECL_EXTERNAL (TYPE_CTABLE_DECL (type)) = 1;
    TREE_STATIC (TYPE_CTABLE_DECL (type)) = 1;
    TREE_READONLY (TYPE_CTABLE_DECL (type)) = 1;
    TREE_CONSTANT (TYPE_CTABLE_DECL (type)) = 1;
    DECL_IGNORED_P (TYPE_CTABLE_DECL (type)) = 1;
    pushdecl (TYPE_CTABLE_DECL (type));  
  }

  if (flag_indirect_dispatch)
    {
486 487 488
      GEN_TABLE (ATABLE, _atable, atable_type, type);
      GEN_TABLE (OTABLE, _otable, otable_type, type);
      GEN_TABLE (ITABLE, _itable, itable_type, type);
489 490 491
    }
}

492 493
#undef GEN_TABLE

Anthony Green committed
494
tree
495
push_class (tree class_type, tree class_name)
Anthony Green committed
496 497
{
  tree decl, signature;
498
  location_t saved_loc = input_location;
499
  CLASS_P (class_type) = 1;
500
  decl = build_decl (input_location, TYPE_DECL, class_name, class_type);
501
  TYPE_DECL_SUPPRESS_DEBUG (decl) = 1;
502 503 504 505

  /* dbxout needs a DECL_SIZE if in gstabs mode */
  DECL_SIZE (decl) = integer_zero_node;

506
  input_location = saved_loc;
Anthony Green committed
507
  signature = identifier_subst (class_name, "L", '.', '/', ";");
Per Bothner committed
508
  IDENTIFIER_SIGNATURE_TYPE (signature) = build_pointer_type (class_type);
Anthony Green committed
509

510
  /* Setting DECL_ARTIFICIAL forces dbxout.c to specific the type is
Anthony Green committed
511 512 513 514 515 516 517 518 519 520 521 522 523 524 525
     both a typedef and in the struct name-space.  We may want to re-visit
     this later, but for now it reduces the changes needed for gdb. */
  DECL_ARTIFICIAL (decl) = 1;

  pushdecl_top_level (decl);

  return decl;
}

/* Finds the (global) class named NAME.  Creates the class if not found.
   Also creates associated TYPE_DECL.
   Does not check if the class actually exists, load the class,
   fill in field or methods, or do layout_type. */

tree
526
lookup_class (tree name)
Anthony Green committed
527 528 529 530 531 532 533 534
{
  tree decl = IDENTIFIER_CLASS_VALUE (name);
  if (decl == NULL_TREE)
    decl = push_class (make_class (), name);
  return TREE_TYPE (decl);
}

void
535 536
set_super_info (int access_flags, tree this_class,
		tree super_class, int interfaces_count)
Anthony Green committed
537 538 539
{
  int total_supers = interfaces_count;
  tree class_decl = TYPE_NAME (this_class);
540
  
Anthony Green committed
541 542 543
  if (super_class)
    total_supers++;

544 545
  if (total_supers)
    TYPE_BINFO (this_class) = make_tree_binfo (total_supers);
546
  TYPE_VFIELD (this_class) = TYPE_VFIELD (object_type_node);
Anthony Green committed
547 548
  if (super_class)
    {
549
      tree super_binfo = make_tree_binfo (0);
Anthony Green committed
550 551
      BINFO_TYPE (super_binfo) = super_class;
      BINFO_OFFSET (super_binfo) = integer_zero_node;
Nathan Sidwell committed
552
      BINFO_BASE_APPEND (TYPE_BINFO (this_class), super_binfo);
553
      CLASS_HAS_SUPER_FLAG (TYPE_BINFO (this_class)) = 1;
Anthony Green committed
554
    }
555

556 557 558 559
  set_class_decl_access_flags (access_flags, class_decl);
}

void
560
set_class_decl_access_flags (int access_flags, tree class_decl)
561
{
Anthony Green committed
562 563 564 565 566
  if (access_flags & ACC_PUBLIC)    CLASS_PUBLIC (class_decl) = 1;
  if (access_flags & ACC_FINAL)     CLASS_FINAL (class_decl) = 1;
  if (access_flags & ACC_SUPER)     CLASS_SUPER (class_decl) = 1;
  if (access_flags & ACC_INTERFACE) CLASS_INTERFACE (class_decl) = 1;
  if (access_flags & ACC_ABSTRACT)  CLASS_ABSTRACT (class_decl) = 1;
567
  if (access_flags & ACC_STATIC)    CLASS_STATIC (class_decl) = 1;
568
  if (access_flags & ACC_PRIVATE)   CLASS_PRIVATE (class_decl) = 1;
569
  if (access_flags & ACC_PROTECTED) CLASS_PROTECTED (class_decl) = 1;
570
  if (access_flags & ACC_STRICT)    CLASS_STRICTFP (class_decl) = 1;
571 572 573
  if (access_flags & ACC_ENUM)      CLASS_ENUM (class_decl) = 1;
  if (access_flags & ACC_SYNTHETIC) CLASS_SYNTHETIC (class_decl) = 1;
  if (access_flags & ACC_ANNOTATION) CLASS_ANNOTATION (class_decl) = 1;
Anthony Green committed
574 575 576 577 578 579
}

/* Return length of inheritance chain of CLAS, where java.lang.Object is 0,
   direct sub-classes of Object are 1, and so on. */

int
580
class_depth (tree clas)
Anthony Green committed
581 582 583 584
{
  int depth = 0;
  if (! CLASS_LOADED_P (clas))
    load_class (clas, 1);
585 586
  if (TYPE_SIZE (clas) == error_mark_node)
    return -1;
Anthony Green committed
587 588 589
  while (clas != object_type_node)
    {
      depth++;
590
      clas = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (clas), 0));
Anthony Green committed
591 592 593 594 595 596 597
    }
  return depth;
}

/* Return true iff TYPE2 is an interface that extends interface TYPE1 */

int
598
interface_of_p (tree type1, tree type2)
Anthony Green committed
599
{
Nathan Sidwell committed
600 601
  int i;
  tree binfo, base_binfo;
Anthony Green committed
602

603
  if (! TYPE_BINFO (type2))
Anthony Green committed
604
    return 0;
Nathan Sidwell committed
605 606 607 608 609 610 611 612 613 614 615 616

  for (binfo = TYPE_BINFO (type2), i = 0;
       BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
    if (BINFO_TYPE (base_binfo) == type1)
      return 1;
  
  for (binfo = TYPE_BINFO (type2), i = 0;
       BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) /*  */
    if (BINFO_TYPE (base_binfo)
	&& interface_of_p (type1, BINFO_TYPE (base_binfo)))
      return 1;
  
Anthony Green committed
617 618 619 620 621 622
  return 0;
}

/* Return true iff TYPE1 inherits from TYPE2. */

int
623
inherits_from_p (tree type1, tree type2)
Anthony Green committed
624 625 626 627 628
{
  while (type1 != NULL_TREE && TREE_CODE (type1) == RECORD_TYPE)
    {
      if (type1 == type2)
	return 1;
629

630 631
      if (! CLASS_LOADED_P (type1))
	load_class (type1, 1);
632 633

      type1 = maybe_layout_super_class (CLASSTYPE_SUPER (type1), type1);
Anthony Green committed
634 635 636 637
    }
  return 0;
}

638 639 640
/* Return a 1 iff TYPE1 is an enclosing context for TYPE2 */

int
641
enclosing_context_p (tree type1, tree type2)
642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657
{
  if (!INNER_CLASS_TYPE_P (type2))
    return 0;

  for (type2 = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type2)));
       type2; 
       type2 = (INNER_CLASS_TYPE_P (type2) ?
		TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type2))) : NULL_TREE))
    {
      if (type2 == type1)
	return 1;
    }

  return 0;
}

658 659 660

/* Return 1 iff TYPE1 and TYPE2 share a common enclosing class, regardless of
   nesting level.  */
661

Ranjit Mathew committed
662 663
int
common_enclosing_context_p (tree type1, tree type2)
664
{
665
  while (type1)
666 667 668 669 670 671 672 673
    {
      tree current;
      for (current = type2; current;
	   current = (INNER_CLASS_TYPE_P (current) ?
		      TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current))) : 
		      NULL_TREE))
	if (type1 == current)
	  return 1;
674 675 676 677 678

      if (INNER_CLASS_TYPE_P (type1))
        type1 = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type1)));
      else
        break;
679 680 681 682 683 684 685 686 687 688
    }
  return 0;
}

/* Return 1 iff there exists a common enclosing "this" between TYPE1
   and TYPE2, without crossing any static context.  */

int
common_enclosing_instance_p (tree type1, tree type2)
{
689
  if (!PURE_INNER_CLASS_TYPE_P (type1) || !PURE_INNER_CLASS_TYPE_P (type2))
690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706
    return 0;
  
  for (type1 = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type1))); type1; 
       type1 = (PURE_INNER_CLASS_TYPE_P (type1) ?
		TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type1))) : NULL_TREE))
    {
      tree current;
      for (current = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type2))); current;
	   current = (PURE_INNER_CLASS_TYPE_P (current) ?
		      TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current))) : 
		      NULL_TREE))
	if (type1 == current)
	  return 1;
    }
  return 0;
}

Anthony Green committed
707 708 709 710 711
/* Add INTERFACE_CLASS to THIS_CLASS iff INTERFACE_CLASS can't be
   found in THIS_CLASS. Returns NULL_TREE upon success, INTERFACE_CLASS
   if attempt is made to add it twice. */

tree
712
maybe_add_interface (tree this_class, tree interface_class)
Anthony Green committed
713
{
Nathan Sidwell committed
714
  tree binfo, base_binfo;
Anthony Green committed
715
  int i;
Nathan Sidwell committed
716 717 718 719 720 721

  for (binfo = TYPE_BINFO (this_class), i = 0;
       BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
    if (BINFO_TYPE (base_binfo) == interface_class)
      return interface_class;
  add_interface (this_class, interface_class);
Anthony Green committed
722 723 724 725 726 727
  return NULL_TREE;
}

/* Add the INTERFACE_CLASS as one of the interfaces of THIS_CLASS. */

void
728
add_interface (tree this_class, tree interface_class)
Anthony Green committed
729
{
Nathan Sidwell committed
730 731 732 733 734 735 736 737
  tree interface_binfo = make_tree_binfo (0);
  
  BINFO_TYPE (interface_binfo) = interface_class;
  BINFO_OFFSET (interface_binfo) = integer_zero_node;
  BINFO_VPTR_FIELD (interface_binfo) = integer_zero_node;
  BINFO_VIRTUAL_P (interface_binfo) = 1;
  
  BINFO_BASE_APPEND (TYPE_BINFO (this_class), interface_binfo);
Anthony Green committed
738 739
}

740
static tree
741
build_java_method_type (tree fntype, tree this_class, int access_flags)
Anthony Green committed
742 743 744
{
  if (access_flags & ACC_STATIC)
    return fntype;
745 746 747 748 749 750 751 752 753 754 755
  fntype = build_method_type (this_class, fntype);

  /* We know that arg 1 of every nonstatic method is non-null; tell
     the back-end so.  */
  TYPE_ATTRIBUTES (fntype) = (tree_cons 
			      (get_identifier ("nonnull"),
			       tree_cons (NULL_TREE, 
					  build_int_cst (NULL_TREE, 1),
					  NULL_TREE),
			       TYPE_ATTRIBUTES (fntype)));
  return fntype;
Anthony Green committed
756 757
}

758 759
void
java_hide_decl (tree decl ATTRIBUTE_UNUSED)
760
{
761
#ifdef HAVE_GAS_HIDDEN
762 763
  DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
  DECL_VISIBILITY_SPECIFIED (decl) = 1;
764
#endif
765 766
}

Anthony Green committed
767
tree
768
add_method_1 (tree this_class, int access_flags, tree name, tree function_type)
Anthony Green committed
769 770 771 772
{
  tree method_type, fndecl;

  method_type = build_java_method_type (function_type,
773
					this_class, access_flags);
Anthony Green committed
774

775
  fndecl = build_decl (input_location, FUNCTION_DECL, name, method_type);
776
  DECL_CONTEXT (fndecl) = this_class;
Anthony Green committed
777

778
  DECL_LANG_SPECIFIC (fndecl) = ggc_cleared_alloc<struct lang_decl> ();
779
  DECL_LANG_SPECIFIC (fndecl)->desc = LANG_DECL_FUNC;
Anthony Green committed
780

781
  /* Initialize the static initializer test table.  */
782 783

  DECL_FUNCTION_INIT_TEST_TABLE (fndecl) = java_treetreehash_create (10);
784

785 786
  /* Initialize the initialized (static) class table. */
  if (access_flags & ACC_STATIC)
787
    DECL_FUNCTION_INITIALIZED_CLASS_TABLE (fndecl) =
788
      hash_table<ict_hasher>::create_ggc (50);
789

790
  DECL_CHAIN (fndecl) = TYPE_METHODS (this_class);
791
  TYPE_METHODS (this_class) = fndecl;
Anthony Green committed
792

793 794 795 796 797 798 799 800
  /* If pointers to member functions use the least significant bit to
     indicate whether a function is virtual, ensure a pointer
     to this function will have that bit clear.  */
  if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
      && !(access_flags & ACC_STATIC)
      && DECL_ALIGN (fndecl) < 2 * BITS_PER_UNIT)
    DECL_ALIGN (fndecl) = 2 * BITS_PER_UNIT;

801 802 803 804 805
  /* Notice that this is a finalizer and update the class type
     accordingly. This is used to optimize instance allocation. */
  if (name == finalize_identifier_node
      && TREE_TYPE (function_type) == void_type_node
      && TREE_VALUE (TYPE_ARG_TYPES (function_type)) == void_type_node)
806
    HAS_FINALIZER_P (this_class) = 1;
807

Anthony Green committed
808 809
  if (access_flags & ACC_PUBLIC) METHOD_PUBLIC (fndecl) = 1;
  if (access_flags & ACC_PROTECTED) METHOD_PROTECTED (fndecl) = 1;
810
  if (access_flags & ACC_PRIVATE)
811
    METHOD_PRIVATE (fndecl) = 1;
812 813 814 815 816
  if (access_flags & ACC_NATIVE)
    {
      METHOD_NATIVE (fndecl) = 1;
      DECL_EXTERNAL (fndecl) = 1;
    }
817 818 819 820
  else
    /* FNDECL is external unless we are compiling it into this object
       file.  */
    DECL_EXTERNAL (fndecl) = CLASS_FROM_CURRENTLY_COMPILED_P (this_class) == 0;
821
  if (access_flags & ACC_STATIC) 
822
    METHOD_STATIC (fndecl) = 1;
823
  if (access_flags & ACC_FINAL) 
824
    METHOD_FINAL (fndecl) = 1;
Anthony Green committed
825 826
  if (access_flags & ACC_SYNCHRONIZED) METHOD_SYNCHRONIZED (fndecl) = 1;
  if (access_flags & ACC_ABSTRACT) METHOD_ABSTRACT (fndecl) = 1;
827
  if (access_flags & ACC_STRICT) METHOD_STRICTFP (fndecl) = 1;
828 829 830
  if (access_flags & ACC_SYNTHETIC) DECL_ARTIFICIAL (fndecl) = 1;
  if (access_flags & ACC_BRIDGE) METHOD_BRIDGE (fndecl) = 1;
  if (access_flags & ACC_VARARGS) METHOD_VARARGS (fndecl) = 1;
Anthony Green committed
831 832 833 834 835 836 837 838
  return fndecl;
}

/* Add a method to THIS_CLASS.
   The method's name is NAME.
   Its signature (mangled type) is METHOD_SIG (an IDENTIFIER_NODE). */

tree
839
add_method (tree this_class, int access_flags, tree name, tree method_sig)
Anthony Green committed
840
{
841
  tree function_type, fndecl;
842 843 844
  const unsigned char *sig
    = (const unsigned char *) IDENTIFIER_POINTER (method_sig);

Anthony Green committed
845
  if (sig[0] != '(')
846 847
    fatal_error ("bad method signature");

Anthony Green committed
848
  function_type = get_type_from_signature (method_sig);
849
  fndecl = add_method_1 (this_class, access_flags, name, function_type);
Anthony Green committed
850 851 852 853 854
  set_java_signature (TREE_TYPE (fndecl), method_sig);
  return fndecl;
}

tree
855
add_field (tree klass, tree name, tree field_type, int flags)
Anthony Green committed
856 857 858
{
  int is_static = (flags & ACC_STATIC) != 0;
  tree field;
859 860
  field = build_decl (input_location,
		      is_static ? VAR_DECL : FIELD_DECL, name, field_type);
861
  DECL_CHAIN (field) = TYPE_FIELDS (klass);
862 863
  TYPE_FIELDS (klass) = field;
  DECL_CONTEXT (field) = klass;
864
  MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (field);
Anthony Green committed
865 866 867 868 869

  if (flags & ACC_PUBLIC) FIELD_PUBLIC (field) = 1;
  if (flags & ACC_PROTECTED) FIELD_PROTECTED (field) = 1;
  if (flags & ACC_PRIVATE) FIELD_PRIVATE (field) = 1;
  if (flags & ACC_FINAL) FIELD_FINAL (field) = 1;
870 871 872 873 874
  if (flags & ACC_VOLATILE) 
    {
      FIELD_VOLATILE (field) = 1;
      TREE_THIS_VOLATILE (field) = 1;
    }
Anthony Green committed
875
  if (flags & ACC_TRANSIENT) FIELD_TRANSIENT (field) = 1;
876 877
  if (flags & ACC_ENUM) FIELD_ENUM (field) = 1;
  if (flags & ACC_SYNTHETIC) FIELD_SYNTHETIC (field) = 1;
Anthony Green committed
878 879 880
  if (is_static)
    {
      FIELD_STATIC (field) = 1;
Per Bothner committed
881 882 883
      /* Always make field externally visible.  This is required so
	 that native methods can always access the field.  */
      TREE_PUBLIC (field) = 1;
884 885 886
      /* Hide everything that shouldn't be visible outside a DSO.  */
      if (flag_indirect_classes
	  || (FIELD_PRIVATE (field)))
887
	java_hide_decl (field);
888 889
      /* Considered external unless we are compiling it into this
	 object file.  */
890
      DECL_EXTERNAL (field) = (is_compiled_class (klass) != 2);
891
      if (!DECL_EXTERNAL (field))
892
	vec_safe_push (pending_static_fields, field);
Anthony Green committed
893
    }
894

Anthony Green committed
895 896 897 898 899 900
  return field;
}

/* Associate a constant value CONSTANT with VAR_DECL FIELD. */

void
901
set_constant_value (tree field, tree constant)
Anthony Green committed
902 903
{
  if (field == NULL_TREE)
904 905
    warning (OPT_Wattributes,
	     "misplaced ConstantValue attribute (not in any field)");
Anthony Green committed
906
  else if (DECL_INITIAL (field) != NULL_TREE)
907 908
    warning (OPT_Wattributes,
	     "duplicate ConstantValue attribute for field '%s'",
Anthony Green committed
909 910
	     IDENTIFIER_POINTER (DECL_NAME (field)));
  else
911 912
    {
      DECL_INITIAL (field) = constant;
913 914 915
      if (TREE_TYPE (constant) != TREE_TYPE (field)
	  && ! (TREE_TYPE (constant) == int_type_node
		&& INTEGRAL_TYPE_P (TREE_TYPE (field))
916 917 918 919
		&& TYPE_PRECISION (TREE_TYPE (field)) <= 32)
	  && ! (TREE_TYPE (constant) == utf8const_ptr_type
		&& TREE_TYPE (field) == string_ptr_type_node))
	error ("ConstantValue attribute of field '%s' has wrong type",
920
	       IDENTIFIER_POINTER (DECL_NAME (field)));
921
    }
Anthony Green committed
922 923 924 925 926 927
}

/* Calculate a hash value for a string encoded in Utf8 format.
 * This returns the same hash value as specified for java.lang.String.hashCode.
 */

928
static int32
929
hashUtf8String (const char *str, int len)
Anthony Green committed
930
{
931 932
  const unsigned char* ptr = (const unsigned char*) str;
  const unsigned char *limit = ptr + len;
933
  uint32 hash = 0;
Anthony Green committed
934 935 936 937 938 939 940 941 942 943 944
  for (; ptr < limit;)
    {
      int ch = UTF8_GET (ptr, limit);
      /* Updated specification from
	 http://www.javasoft.com/docs/books/jls/clarify.html. */
      hash = (31 * hash) + ch;
    }
  return hash;
}

tree
945
build_utf8_ref (tree name)
Anthony Green committed
946
{
947 948
  const char * name_ptr = IDENTIFIER_POINTER (name);
  int name_len = IDENTIFIER_LENGTH (name), name_pad;
Anthony Green committed
949
  char buf[60];
Kaveh R. Ghazi committed
950
  tree ctype, field = NULL_TREE, str_type, cinit, string;
Anthony Green committed
951
  static int utf8_count = 0;
952
  int name_hash;
Anthony Green committed
953 954
  tree ref = IDENTIFIER_UTF8_REF (name);
  tree decl;
955
  vec<constructor_elt, va_gc> *v = NULL;
Anthony Green committed
956 957 958 959
  if (ref != NULL_TREE)
    return ref;

  ctype = make_node (RECORD_TYPE);
960 961 962
  /* '\0' byte plus padding to utf8const_type's alignment.  */
  name_pad = TYPE_ALIGN_UNIT (utf8const_type)
	     - (name_len & (TYPE_ALIGN_UNIT (utf8const_type) - 1));
Anthony Green committed
963
  str_type = build_prim_array_type (unsigned_byte_type_node,
964
				    name_len + name_pad);
965 966 967 968
  PUSH_FIELD (input_location, ctype, field, "hash", unsigned_short_type_node);
  PUSH_FIELD (input_location,
	      ctype, field, "length", unsigned_short_type_node);
  PUSH_FIELD (input_location, ctype, field, "data", str_type);
Anthony Green committed
969
  FINISH_RECORD (ctype);
970
  START_RECORD_CONSTRUCTOR (v, ctype);
971
  name_hash = hashUtf8String (name_ptr, name_len) & 0xFFFF;
972 973
  PUSH_FIELD_VALUE (v, "hash", build_int_cst (NULL_TREE, name_hash));
  PUSH_FIELD_VALUE (v, "length", build_int_cst (NULL_TREE, name_len));
974
  string = build_string (name_len, name_ptr);
Anthony Green committed
975
  TREE_TYPE (string) = str_type;
976 977
  PUSH_FIELD_VALUE (v, "data", string);
  FINISH_RECORD_CONSTRUCTOR (cinit, v, ctype);
Anthony Green committed
978
  TREE_CONSTANT (cinit) = 1;
Anthony Green committed
979

980
  /* Generate a unique-enough identifier.  */
Anthony Green committed
981 982
  sprintf(buf, "_Utf%d", ++utf8_count);

983 984
  decl = build_decl (input_location,
		     VAR_DECL, get_identifier (buf), utf8const_type);
Anthony Green committed
985 986 987 988
  TREE_STATIC (decl) = 1;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_IGNORED_P (decl) = 1;
  TREE_READONLY (decl) = 1;
Anthony Green committed
989
  TREE_THIS_VOLATILE (decl) = 0;
Anthony Green committed
990
  DECL_INITIAL (decl) = cinit;
991
  DECL_USER_ALIGN (decl) = 1;
992 993 994 995 996

  if (HAVE_GAS_SHF_MERGE)
    {
      int decl_size;
      /* Ensure decl_size is a multiple of utf8const_type's alignment. */
997
      decl_size = name_len + 4 + name_pad;
998 999 1000 1001 1002 1003
      if (flag_merge_constants && decl_size < 256)
	{
	  char buf[32];
	  int flags = (SECTION_OVERRIDE
		       | SECTION_MERGE | (SECTION_ENTSIZE & decl_size));
	  sprintf (buf, ".rodata.jutf8.%d", decl_size);
1004
	  switch_to_section (get_section (buf, flags, NULL));
1005
	  set_decl_section_name (decl, buf);
1006 1007 1008
	}
    }

Anthony Green committed
1009
  layout_decl (decl, 0);
1010 1011
  DECL_SIZE (decl) = TYPE_SIZE (ctype);
  DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (ctype);
Anthony Green committed
1012
  pushdecl (decl);
1013
  rest_of_decl_compilation (decl, global_bindings_p (), 0);
Anthony Green committed
1014 1015 1016 1017 1018
  ref = build1 (ADDR_EXPR, utf8const_ptr_type, decl);
  IDENTIFIER_UTF8_REF (name) = ref;
  return ref;
}

1019 1020 1021 1022 1023 1024 1025 1026 1027 1028
/* Like build_class_ref, but instead of a direct reference generate a
   pointer into the constant pool.  */

static tree
build_indirect_class_ref (tree type)
{
  int index;
  tree cl;
  index = alloc_class_constant (type);
  cl = build_ref_from_constant_pool (index); 
1029
  return convert (promote_type (class_ptr_type), cl);
1030 1031
}

1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043
static tree
build_static_class_ref (tree type)
{
  tree decl_name, decl, ref;

  if (TYPE_SIZE (type) == error_mark_node)
    return null_pointer_node;
  decl_name = identifier_subst (DECL_NAME (TYPE_NAME (type)),
				"", '/', '/', ".class$$");
  decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
  if (decl == NULL_TREE)
    {
1044
      decl = build_decl (input_location, VAR_DECL, decl_name, class_type_node);
1045 1046
      TREE_STATIC (decl) = 1;
      if (! flag_indirect_classes)
1047 1048 1049
	{
	  TREE_PUBLIC (decl) = 1;
	  if (CLASS_PRIVATE (TYPE_NAME (type)))
1050
	    java_hide_decl (decl);
1051
	}
1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078
      DECL_IGNORED_P (decl) = 1;
      DECL_ARTIFICIAL (decl) = 1;
      if (is_compiled_class (type) == 1)
	DECL_EXTERNAL (decl) = 1;
      MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
      DECL_CLASS_FIELD_P (decl) = 1;
      DECL_CONTEXT (decl) = type;

      /* ??? We want to preserve the DECL_CONTEXT we set just above,
	 that that means not calling pushdecl_top_level.  */
      IDENTIFIER_GLOBAL_VALUE (decl_name) = decl;
    }

  ref = build1 (ADDR_EXPR, class_ptr_type, decl);
  return ref;
}

static tree
build_classdollar_field (tree type)
{
  tree decl_name = identifier_subst (DECL_NAME (TYPE_NAME (type)),
				     "", '/', '/', ".class$");
  tree decl = IDENTIFIER_GLOBAL_VALUE (decl_name);

  if (decl == NULL_TREE)
    {
      decl 
1079 1080
	= build_decl (input_location,
		      VAR_DECL, decl_name, 
1081
		      (build_qualified_type
1082
		       (build_pointer_type 
1083 1084 1085
			(build_qualified_type (class_type_node,
					       TYPE_QUAL_CONST)),
			TYPE_QUAL_CONST)));
1086 1087 1088 1089
      TREE_STATIC (decl) = 1;
      TREE_CONSTANT (decl) = 1;
      TREE_READONLY (decl) = 1;
      TREE_PUBLIC (decl) = 1;
1090
      java_hide_decl (decl);
1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101
      DECL_IGNORED_P (decl) = 1;
      DECL_ARTIFICIAL (decl) = 1;
      MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
      IDENTIFIER_GLOBAL_VALUE (decl_name) = decl;
      DECL_CLASS_FIELD_P (decl) = 1;
      DECL_CONTEXT (decl) = type;
    }

  return decl;
}

1102
/* Create a local variable that holds the current class$.  */
1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114

void
cache_this_class_ref (tree fndecl)
{
  if (optimize)
    {
      tree classdollar_field;
      if (flag_indirect_classes)
	classdollar_field = build_classdollar_field (output_class);
      else
	classdollar_field = build_static_class_ref (output_class);

1115 1116
      this_classdollar = build_decl (input_location,
				     VAR_DECL, NULL_TREE, 
1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133
				     TREE_TYPE (classdollar_field));
      
      java_add_local_var (this_classdollar);
      java_add_stmt (build2 (MODIFY_EXPR, TREE_TYPE (this_classdollar), 
			     this_classdollar, classdollar_field));
    }
  else
    this_classdollar = build_classdollar_field (output_class);

  /* Prepend class initialization for static methods reachable from
     other classes.  */
  if (METHOD_STATIC (fndecl)
      && (! METHOD_PRIVATE (fndecl)
          || INNER_CLASS_P (DECL_CONTEXT (fndecl)))
      && ! DECL_CLINIT_P (fndecl)
      && ! CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (fndecl))))
    {
1134 1135
      tree init = build_call_expr (soft_initclass_node, 1,
				   this_classdollar);
1136 1137 1138 1139
      java_add_stmt (init);
    }
}

1140 1141 1142 1143 1144 1145 1146 1147 1148
/* Remove the reference to the local variable that holds the current
   class$.  */

void
uncache_this_class_ref (tree fndecl ATTRIBUTE_UNUSED)
{
  this_classdollar = build_classdollar_field (output_class);
}

Anthony Green committed
1149 1150 1151 1152
/* Build a reference to the class TYPE.
   Also handles primitive types and array types. */

tree
1153
build_class_ref (tree type)
Anthony Green committed
1154 1155 1156 1157
{
  int is_compiled = is_compiled_class (type);
  if (is_compiled)
    {
1158
      tree ref, decl;
Anthony Green committed
1159 1160
      if (TREE_CODE (type) == POINTER_TYPE)
	type = TREE_TYPE (type);
1161

1162 1163 1164
      if (flag_indirect_dispatch
	  && type != output_class
	  && TREE_CODE (type) == RECORD_TYPE)
1165 1166
	return build_indirect_class_ref (type);

1167
      if (type == output_class && flag_indirect_classes)
1168 1169 1170 1171 1172 1173 1174
	{
	  /* This can be NULL if we see a JNI stub before we see any
	     other method.  */
	  if (! this_classdollar)
	    this_classdollar = build_classdollar_field (output_class);
	  return this_classdollar;
	}
1175
      
Anthony Green committed
1176
      if (TREE_CODE (type) == RECORD_TYPE)
1177
	return build_static_class_ref (type);
Anthony Green committed
1178 1179
      else
	{
1180
	  const char *name;
1181
	  tree decl_name;
1182
	  char buffer[25];
Anthony Green committed
1183 1184 1185 1186 1187 1188
	  decl_name = TYPE_NAME (type);
	  if (TREE_CODE (decl_name) == TYPE_DECL)
	    decl_name = DECL_NAME (decl_name);
	  name = IDENTIFIER_POINTER (decl_name);
	  if (strncmp (name, "promoted_", 9) == 0)
	    name += 9;
1189
	  sprintf (buffer, "_Jv_%sClass", name);
Anthony Green committed
1190 1191 1192 1193
	  decl_name = get_identifier (buffer);
	  decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
	  if (decl == NULL_TREE)
	    {
1194 1195
	      decl = build_decl (input_location,
				 VAR_DECL, decl_name, class_type_node);
Anthony Green committed
1196 1197
	      TREE_STATIC (decl) = 1;
	      TREE_PUBLIC (decl) = 1;
1198
	      DECL_EXTERNAL (decl) = 1;
1199
	      DECL_ARTIFICIAL (decl) = 1;
Anthony Green committed
1200 1201 1202 1203 1204 1205 1206 1207
	      pushdecl_top_level (decl);
	    }
	}

      ref = build1 (ADDR_EXPR, class_ptr_type, decl);
      return ref;
    }
  else
1208
    return build_indirect_class_ref (type);
Anthony Green committed
1209 1210
}

1211 1212 1213 1214 1215 1216 1217 1218
/* Create a local statically allocated variable that will hold a
   pointer to a static field.  */

static tree
build_fieldref_cache_entry (int index, tree fdecl ATTRIBUTE_UNUSED)
{
  tree decl, decl_name;
  const char *name = IDENTIFIER_POINTER (mangled_classname ("_cpool_", output_class));
1219
  char *buf = (char *) alloca (strlen (name) + 20);
1220 1221 1222 1223 1224
  sprintf (buf, "%s_%d_ref", name, index);
  decl_name = get_identifier (buf);
  decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
  if (decl == NULL_TREE)
    {
1225 1226
      decl = build_decl (input_location,
			 VAR_DECL, decl_name, ptr_type_node);
1227 1228 1229 1230
      TREE_STATIC (decl) = 1;
      TREE_PUBLIC (decl) = 0;
      DECL_EXTERNAL (decl) = 0;
      DECL_ARTIFICIAL (decl) = 1;
1231
      DECL_IGNORED_P (decl) = 1;
1232 1233 1234 1235 1236
      pushdecl_top_level (decl);
    }
  return decl;
}

Anthony Green committed
1237
tree
1238
build_static_field_ref (tree fdecl)
Anthony Green committed
1239 1240 1241
{
  tree fclass = DECL_CONTEXT (fdecl);
  int is_compiled = is_compiled_class (fclass);
1242

1243
  /* Allow static final fields to fold to a constant.  When using
1244 1245 1246
     -findirect-dispatch, we simply never do this folding if compiling
     from .class; in the .class file constants will be referred to via
     the constant pool.  */
1247
  if (!flag_indirect_dispatch
1248 1249 1250 1251 1252
      && (is_compiled
	  || (FIELD_FINAL (fdecl) && DECL_INITIAL (fdecl) != NULL_TREE
	      && (JSTRING_TYPE_P (TREE_TYPE (fdecl))
		  || JNUMERIC_TYPE_P (TREE_TYPE (fdecl)))
	      && TREE_CONSTANT (DECL_INITIAL (fdecl)))))
Anthony Green committed
1253
    {
1254 1255
      if (is_compiled == 1)
	DECL_EXTERNAL (fdecl) = 1;
1256
    }
1257
  else
Anthony Green committed
1258
    {
1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276
      /* Generate a CONSTANT_FieldRef for FDECL in the constant pool
	 and a class local static variable CACHE_ENTRY, then
      
      *(fdecl **)((__builtin_expect (cache_entry == null, false)) 
		  ? cache_entry = _Jv_ResolvePoolEntry (output_class, cpool_index)
		  : cache_entry)

      This can mostly be optimized away, so that the usual path is a
      load followed by a test and branch.  _Jv_ResolvePoolEntry is
      only called once for each constant pool entry.

      There is an optimization that we don't do: at the start of a
      method, create a local copy of CACHE_ENTRY and use that instead.

      */

      int cpool_index = alloc_constant_fieldref (output_class, fdecl);
      tree cache_entry = build_fieldref_cache_entry (cpool_index, fdecl);
1277
      tree test
1278
        = build_call_expr (builtin_decl_implicit (BUILT_IN_EXPECT), 2,
1279 1280 1281
			   build2 (EQ_EXPR, boolean_type_node,
				   cache_entry, null_pointer_node),
			   boolean_false_node);
1282 1283
      tree cpool_index_cst = build_int_cst (NULL_TREE, cpool_index);
      tree init
1284 1285 1286
	= build_call_expr (soft_resolvepoolentry_node, 2,
			   build_class_ref (output_class),
			   cpool_index_cst);
1287 1288 1289 1290
      init = build2 (MODIFY_EXPR, ptr_type_node, cache_entry, init);
      init = build3 (COND_EXPR, ptr_type_node, test, init, cache_entry);
      init = fold_convert (build_pointer_type (TREE_TYPE (fdecl)), init);
      fdecl = build1 (INDIRECT_REF, TREE_TYPE (fdecl), init);
Anthony Green committed
1291
    }
1292
  return fdecl;
Anthony Green committed
1293 1294 1295
}

int
1296
get_access_flags_from_decl (tree decl)
Anthony Green committed
1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314
{
  int access_flags = 0;
  if (TREE_CODE (decl) == FIELD_DECL || TREE_CODE (decl) == VAR_DECL)
    {
      if (FIELD_STATIC (decl))
	access_flags |= ACC_STATIC;
      if (FIELD_PUBLIC (decl))
	access_flags |= ACC_PUBLIC;
      if (FIELD_PROTECTED (decl))
	access_flags |= ACC_PROTECTED;
      if (FIELD_PRIVATE (decl))
	access_flags |= ACC_PRIVATE;
      if (FIELD_FINAL (decl))
	access_flags |= ACC_FINAL;
      if (FIELD_VOLATILE (decl))
	access_flags |= ACC_VOLATILE;
      if (FIELD_TRANSIENT (decl))
	access_flags |= ACC_TRANSIENT;
1315 1316 1317 1318
      if (FIELD_ENUM (decl))
	access_flags |= ACC_ENUM;
      if (FIELD_SYNTHETIC (decl))
	access_flags |= ACC_SYNTHETIC;
Anthony Green committed
1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332
      return access_flags;
    }
  if (TREE_CODE (decl) == TYPE_DECL)
    {
      if (CLASS_PUBLIC (decl))
	access_flags |= ACC_PUBLIC;
      if (CLASS_FINAL (decl))
	access_flags |= ACC_FINAL;
      if (CLASS_SUPER (decl))
	access_flags |= ACC_SUPER;
      if (CLASS_INTERFACE (decl))
	access_flags |= ACC_INTERFACE;
      if (CLASS_ABSTRACT (decl))
	access_flags |= ACC_ABSTRACT;
1333 1334
      if (CLASS_STATIC (decl))
	access_flags |= ACC_STATIC;
1335 1336 1337 1338
      if (CLASS_PRIVATE (decl))
	access_flags |= ACC_PRIVATE;
      if (CLASS_PROTECTED (decl))
	access_flags |= ACC_PROTECTED;
1339 1340
      if (CLASS_STRICTFP (decl))
	access_flags |= ACC_STRICT;
1341 1342 1343 1344 1345 1346
      if (CLASS_ENUM (decl))
	access_flags |= ACC_ENUM;
      if (CLASS_SYNTHETIC (decl))
	access_flags |= ACC_SYNTHETIC;
      if (CLASS_ANNOTATION (decl))
	access_flags |= ACC_ANNOTATION;
Anthony Green committed
1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366
      return access_flags;
    }
  if (TREE_CODE (decl) == FUNCTION_DECL)
    {
      if (METHOD_PUBLIC (decl))
	access_flags |= ACC_PUBLIC;
      if (METHOD_PRIVATE (decl))
	access_flags |= ACC_PRIVATE;
      if (METHOD_PROTECTED (decl))
	access_flags |= ACC_PROTECTED;
      if (METHOD_STATIC (decl))
	access_flags |= ACC_STATIC;
      if (METHOD_FINAL (decl))
	access_flags |= ACC_FINAL;
      if (METHOD_SYNCHRONIZED (decl))
	access_flags |= ACC_SYNCHRONIZED;
      if (METHOD_NATIVE (decl))
	access_flags |= ACC_NATIVE;
      if (METHOD_ABSTRACT (decl))
	access_flags |= ACC_ABSTRACT;
1367 1368
      if (METHOD_STRICTFP (decl))
	access_flags |= ACC_STRICT;
1369 1370
      if (METHOD_INVISIBLE (decl))
	access_flags |= ACC_INVISIBLE;
1371 1372 1373 1374 1375 1376
      if (DECL_ARTIFICIAL (decl))
	access_flags |= ACC_SYNTHETIC;
      if (METHOD_BRIDGE (decl))
	access_flags |= ACC_BRIDGE;
      if (METHOD_VARARGS (decl))
	access_flags |= ACC_VARARGS;
Anthony Green committed
1377 1378
      return access_flags;
    }
1379
  gcc_unreachable ();
Anthony Green committed
1380 1381
}

1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394
static GTY (()) int alias_labelno = 0;

/* Create a private alias for METHOD. Using this alias instead of the method
   decl ensures that ncode entries in the method table point to the real function 
   at runtime, not a PLT entry.  */

static tree
make_local_function_alias (tree method)
{
#ifdef ASM_OUTPUT_DEF
  tree alias;
  
  const char *method_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (method));
1395 1396
  char *name = (char *) alloca (strlen (method_name) + 2);
  char *buf = (char *) alloca (strlen (method_name) + 128);
1397 1398 1399 1400 1401 1402 1403 1404 1405

  /* Only create aliases for local functions.  */
  if (DECL_EXTERNAL (method))
    return method;
    
  /* Prefix method_name with 'L' for the alias label.  */
  *name = 'L';
  strcpy (name + 1, method_name);

1406
  targetm.asm_out.generate_internal_label (buf, name, alias_labelno++);  
1407 1408
  alias = build_decl (input_location,
		      FUNCTION_DECL, get_identifier (buf),
1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426
		      TREE_TYPE (method));
  DECL_CONTEXT (alias) = NULL;
  TREE_READONLY (alias) = TREE_READONLY (method);
  TREE_THIS_VOLATILE (alias) = TREE_THIS_VOLATILE (method);
  TREE_PUBLIC (alias) = 0;
  DECL_EXTERNAL (alias) = 0;
  DECL_ARTIFICIAL (alias) = 1;
  DECL_INITIAL (alias) = error_mark_node;
  TREE_ADDRESSABLE (alias) = 1;
  TREE_USED (alias) = 1;
  if (!flag_syntax_only)
    assemble_alias (alias, DECL_ASSEMBLER_NAME (method));
  return alias;
#else
  return method;
#endif
}

1427 1428
/** Make reflection data (_Jv_Field) for field FDECL. */

1429
static tree
1430
make_field_value (tree fdecl)
Anthony Green committed
1431
{
1432
  tree finit;
1433
  int flags;
Anthony Green committed
1434
  tree type = TREE_TYPE (fdecl);
1435
  int resolved = is_compiled_class (type) && ! flag_indirect_dispatch;
1436
  vec<constructor_elt, va_gc> *v = NULL;
1437

1438 1439
  START_RECORD_CONSTRUCTOR (v, field_type_node);
  PUSH_FIELD_VALUE (v, "name", build_utf8_ref (DECL_NAME (fdecl)));
Anthony Green committed
1440 1441 1442
  if (resolved)
    type = build_class_ref (type);
  else
1443 1444
    {
      tree signature = build_java_signature (type);
1445

1446
      type = build_utf8_ref (unmangle_classname 
1447 1448
			     (IDENTIFIER_POINTER (signature),
			      IDENTIFIER_LENGTH (signature)));
1449
    }
1450
  PUSH_FIELD_VALUE (v, "type", type);
1451

Anthony Green committed
1452 1453 1454
  flags = get_access_flags_from_decl (fdecl);
  if (! resolved)
    flags |= 0x8000 /* FIELD_UNRESOLVED_FLAG */;
1455

1456 1457
  PUSH_FIELD_VALUE (v, "accflags", build_int_cst (NULL_TREE, flags));
  PUSH_FIELD_VALUE (v, "bsize", TYPE_SIZE_UNIT (TREE_TYPE (fdecl)));
1458

1459 1460
  {
    tree field_address = integer_zero_node;
1461
    tree index, value;
Andrew Haley committed
1462 1463
    if ((DECL_INITIAL (fdecl) || ! flag_indirect_classes) 
	&& FIELD_STATIC (fdecl))
1464 1465
      field_address = build_address_of (fdecl);

1466
    index = (FIELD_STATIC (fdecl)
1467
	     ? DECL_CHAIN (TYPE_FIELDS (field_info_union_node))
1468 1469
	     : TYPE_FIELDS (field_info_union_node));
    value = (FIELD_STATIC (fdecl)
1470
	     ? field_address
1471 1472 1473 1474 1475
	     : byte_position (fdecl));

    PUSH_FIELD_VALUE
      (v, "info",
       build_constructor_single (field_info_union_node, index, value));
1476
  }
Anthony Green committed
1477

1478
  FINISH_RECORD_CONSTRUCTOR (finit, v, field_type_node);
Anthony Green committed
1479 1480 1481
  return finit;
}

1482 1483
/** Make reflection data (_Jv_Method) for method MDECL. */

1484
static tree
1485
make_method_value (tree mdecl)
Anthony Green committed
1486
{
1487
  static int method_name_count = 0;
Anthony Green committed
1488
  tree minit;
1489
  tree index;
Anthony Green committed
1490
  tree code;
Bryce McKinlay committed
1491
  tree class_decl;
Anthony Green committed
1492 1493
#define ACC_TRANSLATED          0x4000
  int accflags = get_access_flags_from_decl (mdecl) | ACC_TRANSLATED;
1494
  vec<constructor_elt, va_gc> *v = NULL;
1495

Bryce McKinlay committed
1496 1497 1498
  class_decl = DECL_CONTEXT (mdecl);
  /* For interfaces, the index field contains the dispatch index. */
  if (CLASS_INTERFACE (TYPE_NAME (class_decl)))
1499
    index = build_int_cst (NULL_TREE,
1500
			   get_interface_method_index (mdecl, class_decl));
1501 1502
  else if (!flag_indirect_dispatch && get_method_index (mdecl) != NULL_TREE)
    index = get_method_index (mdecl);
1503 1504 1505
  else
    index = integer_minus_one_node;

Anthony Green committed
1506
  code = null_pointer_node;
1507 1508 1509 1510
  if (METHOD_ABSTRACT (mdecl))
    code = build1 (ADDR_EXPR, nativecode_ptr_type_node,
		   soft_abstractmethod_node);
  else
1511 1512
    code = build1 (ADDR_EXPR, nativecode_ptr_type_node, 
		   make_local_function_alias (mdecl));
1513 1514
  START_RECORD_CONSTRUCTOR (v, method_type_node);
  PUSH_FIELD_VALUE (v, "name",
Anthony Green committed
1515 1516 1517
		    build_utf8_ref (DECL_CONSTRUCTOR_P (mdecl) ?
				    init_identifier_node
				    : DECL_NAME (mdecl)));
1518 1519
  {
    tree signature = build_java_signature (TREE_TYPE (mdecl));
1520
    PUSH_FIELD_VALUE (v, "signature", 
1521 1522 1523 1524 1525
		      (build_utf8_ref 
		       (unmangle_classname 
			(IDENTIFIER_POINTER(signature),
			 IDENTIFIER_LENGTH(signature)))));
  }
1526 1527 1528
  PUSH_FIELD_VALUE (v, "accflags", build_int_cst (NULL_TREE, accflags));
  PUSH_FIELD_VALUE (v, "index", index);
  PUSH_FIELD_VALUE (v, "ncode", code);
1529 1530 1531

  {
    /* Compute the `throws' information for the method.  */
1532
    tree table = null_pointer_node;
1533

1534
    if (!vec_safe_is_empty (DECL_FUNCTION_THROWS (mdecl)))
1535
      {
1536
	int length = 1 + DECL_FUNCTION_THROWS (mdecl)->length ();
1537
	tree t, type, array;
1538
	char buf[60];
1539
	vec<constructor_elt, va_gc> *v = NULL;
1540 1541 1542 1543
	int idx = length - 1;
	unsigned ix;
	constructor_elt *e;

1544 1545
	vec_alloc (v, length);
	v->quick_grow_cleared (length);
1546

1547
	e = &(*v)[idx--];
1548
	e->value = null_pointer_node;
1549

1550
	FOR_EACH_VEC_SAFE_ELT (DECL_FUNCTION_THROWS (mdecl), ix, t)
1551
	  {
1552
	    tree sig = DECL_NAME (TYPE_NAME (t));
1553 1554 1555
	    tree utf8
	      = build_utf8_ref (unmangle_classname (IDENTIFIER_POINTER (sig),
						    IDENTIFIER_LENGTH (sig)));
1556
	    e = &(*v)[idx--];
1557
	    e->value = utf8;
1558
	  }
1559
	gcc_assert (idx == -1);
1560
	type = build_prim_array_type (ptr_type_node, length);
1561
	table = build_constructor (type, v);
1562 1563
	/* Compute something unique enough.  */
	sprintf (buf, "_methods%d", method_name_count++);
1564 1565
	array = build_decl (input_location,
			    VAR_DECL, get_identifier (buf), type);
1566 1567 1568 1569
	DECL_INITIAL (array) = table;
	TREE_STATIC (array) = 1;
	DECL_ARTIFICIAL (array) = 1;
	DECL_IGNORED_P (array) = 1;
1570
	rest_of_decl_compilation (array, 1, 0);
1571 1572 1573 1574

	table = build1 (ADDR_EXPR, ptr_type_node, array);
      }

1575
    PUSH_FIELD_VALUE (v, "throws", table);
1576 1577
  }

1578
  FINISH_RECORD_CONSTRUCTOR (minit, v, method_type_node);
Anthony Green committed
1579 1580 1581
  return minit;
}

1582
static tree
1583
get_dispatch_vector (tree type)
Anthony Green committed
1584 1585
{
  tree vtable = TYPE_VTABLE (type);
1586 1587

  if (vtable == NULL_TREE)
Anthony Green committed
1588
    {
1589
      HOST_WIDE_INT i;
Anthony Green committed
1590 1591
      tree method;
      tree super = CLASSTYPE_SUPER (type);
1592
      HOST_WIDE_INT nvirtuals = tree_to_shwi (TYPE_NVIRTUALS (type));
Anthony Green committed
1593 1594 1595 1596 1597
      vtable = make_tree_vec (nvirtuals);
      TYPE_VTABLE (type) = vtable;
      if (super != NULL_TREE)
	{
	  tree super_vtable = get_dispatch_vector (super);
1598

1599
	  for (i = tree_to_shwi (TYPE_NVIRTUALS (super)); --i >= 0; )
Anthony Green committed
1600 1601
	    TREE_VEC_ELT (vtable, i) = TREE_VEC_ELT (super_vtable, i);
	}
1602

Anthony Green committed
1603
      for (method = TYPE_METHODS (type);  method != NULL_TREE;
1604
	   method = DECL_CHAIN (method))
1605 1606 1607
	{
	  tree method_index = get_method_index (method);
	  if (method_index != NULL_TREE
1608
	      && tree_fits_shwi_p (method_index))
1609
	    TREE_VEC_ELT (vtable, tree_to_shwi (method_index)) = method;
1610
	}
Anthony Green committed
1611
    }
1612

Anthony Green committed
1613 1614 1615
  return vtable;
}

1616
static tree
1617
get_dispatch_table (tree type, tree this_class_addr)
Anthony Green committed
1618
{
1619
  int abstract_p = CLASS_ABSTRACT (TYPE_NAME (type));
Anthony Green committed
1620
  tree vtable = get_dispatch_vector (type);
1621
  int i, j;
Anthony Green committed
1622
  int nvirtuals = TREE_VEC_LENGTH (vtable);
1623
  int arraysize;
1624
  tree gc_descr;
1625
  vec<constructor_elt, va_gc> *v = NULL;
1626 1627 1628 1629 1630 1631 1632
  constructor_elt *e;
  tree arraytype;

  arraysize = (TARGET_VTABLE_USES_DESCRIPTORS? nvirtuals + 1 : nvirtuals + 2);
  if (TARGET_VTABLE_USES_DESCRIPTORS)
    arraysize *= TARGET_VTABLE_USES_DESCRIPTORS;
  arraysize += 2;
1633

1634 1635
  vec_safe_grow_cleared (v, arraysize);
  e = &(*v)[arraysize - 1];
1636 1637

#define CONSTRUCTOR_PREPEND_VALUE(E, V) E->value = V, E--
Anthony Green committed
1638 1639 1640 1641
  for (i = nvirtuals;  --i >= 0; )
    {
      tree method = TREE_VEC_ELT (vtable, i);
      if (METHOD_ABSTRACT (method))
1642 1643
	{
	  if (! abstract_p)
1644 1645
	    warning_at (DECL_SOURCE_LOCATION (method), 0,
			"abstract method in non-abstract class");
1646 1647 1648

	  if (TARGET_VTABLE_USES_DESCRIPTORS)
	    for (j = 0; j < TARGET_VTABLE_USES_DESCRIPTORS; ++j)
1649
	      CONSTRUCTOR_PREPEND_VALUE (e, null_pointer_node);
1650
	  else
1651
	    CONSTRUCTOR_PREPEND_VALUE (e, null_pointer_node);
1652 1653 1654
	}
      else
	{
1655 1656 1657
	  if (TARGET_VTABLE_USES_DESCRIPTORS)
	    for (j = 0; j < TARGET_VTABLE_USES_DESCRIPTORS; ++j)
	      {
1658
		tree fdesc = build2 (FDESC_EXPR, nativecode_ptr_type_node, 
1659
				     method, build_int_cst (NULL_TREE, j));
1660
		TREE_CONSTANT (fdesc) = 1;
1661
		CONSTRUCTOR_PREPEND_VALUE (e, fdesc);
1662 1663
	      }
	  else
1664 1665 1666 1667
	    CONSTRUCTOR_PREPEND_VALUE (e,
				       build1 (ADDR_EXPR,
					       nativecode_ptr_type_node,
					       method));
1668
	}
Anthony Green committed
1669
    }
1670

1671 1672
  /* Dummy entry for compatibility with G++ -fvtable-thunks.  When
     using the Boehm GC we sometimes stash a GC type descriptor
1673 1674
     there. We set the PURPOSE to NULL_TREE not to interfere (reset)
     the emitted byte count during the output to the assembly file. */
1675 1676 1677 1678 1679
  /* With TARGET_VTABLE_USES_DESCRIPTORS, we only add one extra
     fake "function descriptor".  It's first word is the is the class
     pointer, and subsequent words (usually one) contain the GC descriptor.
     In all other cases, we reserve two extra vtable slots. */
  gc_descr =  get_boehm_type_descriptor (type);
1680
  CONSTRUCTOR_PREPEND_VALUE (e, gc_descr);
1681
  for (j = 1; j < TARGET_VTABLE_USES_DESCRIPTORS-1; ++j)
1682 1683
    CONSTRUCTOR_PREPEND_VALUE (e, gc_descr);
  CONSTRUCTOR_PREPEND_VALUE (e, this_class_addr);
1684 1685

  /** Pointer to type_info object (to be implemented), according to g++ ABI. */
1686
  CONSTRUCTOR_PREPEND_VALUE (e, null_pointer_node);
1687
  /** Offset to start of whole object.  Always (ptrdiff_t)0 for Java. */
1688
  gcc_assert (e == v->address ());
1689 1690 1691
  e->index = integer_zero_node;
  e->value = null_pointer_node;
#undef CONSTRUCTOR_PREPEND_VALUE
1692

1693 1694
  arraytype = build_prim_array_type (nativecode_ptr_type_node, arraysize);
  return build_constructor (arraytype, v);
Anthony Green committed
1695 1696
}

1697 1698 1699 1700 1701

/* Set the method_index for a method decl.  */
void
set_method_index (tree decl, tree method_index)
{
1702 1703 1704 1705
  if (method_index != NULL_TREE)
    {
      /* method_index is null if we're using indirect dispatch.  */
      method_index = fold (convert (sizetype, method_index));
1706

1707 1708 1709 1710 1711 1712 1713 1714
      if (TARGET_VTABLE_USES_DESCRIPTORS)
	/* Add one to skip bogus descriptor for class and GC descriptor. */
	method_index = size_binop (PLUS_EXPR, method_index, size_int (1));
      else
	/* Add 1 to skip "class" field of dtable, and 1 to skip GC
	   descriptor.  */
	method_index = size_binop (PLUS_EXPR, method_index, size_int (2));
    }
1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737

  DECL_VINDEX (decl) = method_index;
}

/* Get the method_index for a method decl.  */
tree
get_method_index (tree decl)
{
  tree method_index = DECL_VINDEX (decl);

  if (! method_index)
    return NULL;

  if (TARGET_VTABLE_USES_DESCRIPTORS)
    /* Sub one to skip bogus descriptor for class and GC descriptor. */
    method_index = size_binop (MINUS_EXPR, method_index, size_int (1));
  else
    /* Sub 1 to skip "class" field of dtable, and 1 to skip GC descriptor.  */
    method_index = size_binop (MINUS_EXPR, method_index, size_int (2));

  return method_index;
}

1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749
static int
supers_all_compiled (tree type)
{
  while (type != NULL_TREE)
    {
      if (!assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)))))
	return 0;
      type = CLASSTYPE_SUPER (type);
    }
  return 1;
}

1750
static void
1751 1752
add_table_and_syms (vec<constructor_elt, va_gc> **v,
                    vec<method_entry, va_gc> *methods,
1753 1754 1755
                    const char *table_name, tree table_slot, tree table_type,
                    const char *syms_name, tree syms_slot)
{
1756
  if (methods == NULL)
1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772
    {
      PUSH_FIELD_VALUE (*v, table_name, null_pointer_node);
      PUSH_FIELD_VALUE (*v, syms_name, null_pointer_node);
    }
  else
    {
      pushdecl_top_level (syms_slot);
      PUSH_FIELD_VALUE (*v, table_name,
                        build1 (ADDR_EXPR, table_type, table_slot));
      PUSH_FIELD_VALUE (*v, syms_name,
                        build1 (ADDR_EXPR, symbols_array_ptr_type,
                                syms_slot));
      TREE_CONSTANT (table_slot) = 1;
    }
}
                    
Anthony Green committed
1773
void
1774
make_class_data (tree type)
Anthony Green committed
1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791
{
  tree decl, cons, temp;
  tree field, fields_decl;
  HOST_WIDE_INT static_field_count = 0;
  HOST_WIDE_INT instance_field_count = 0;
  HOST_WIDE_INT field_count;
  tree field_array_type;
  tree method;
  tree dtable_decl = NULL_TREE;
  HOST_WIDE_INT method_count = 0;
  tree method_array_type;
  tree methods_decl;
  tree super;
  tree this_class_addr;
  tree constant_pool_constructor;
  tree interfaces = null_pointer_node;
  int interface_len = 0;
1792
  int uses_jv_markobj = 0;
Anthony Green committed
1793
  tree type_decl = TYPE_NAME (type);
1794 1795
  tree id_main = get_identifier("main");
  tree id_class = get_identifier("java.lang.Class");
1796 1797
  /** Offset from start of virtual function table declaration
      to where objects actually point at, following new g++ ABI. */
Andrew Pinski committed
1798
  tree dtable_start_offset = size_int (2 * POINTER_SIZE / BITS_PER_UNIT);
1799
  vec<int> field_indexes;
1800
  tree first_real_field;
1801
  vec<constructor_elt, va_gc> *v1 = NULL, *v2 = NULL;
1802
  tree reflection_data;
1803 1804 1805
  vec<constructor_elt, va_gc> *static_fields = NULL;
  vec<constructor_elt, va_gc> *instance_fields = NULL;
  vec<constructor_elt, va_gc> *methods = NULL;
Anthony Green committed
1806

1807
  this_class_addr = build_static_class_ref (type);
Anthony Green committed
1808 1809
  decl = TREE_OPERAND (this_class_addr, 0);

1810 1811 1812 1813
  if (supers_all_compiled (type) && ! CLASS_INTERFACE (type_decl)
      && !flag_indirect_dispatch)
    {
      tree dtable = get_dispatch_table (type, this_class_addr);
1814
      uses_jv_markobj = uses_jv_markobj_p (dtable);
1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829
      if (type == class_type_node && class_dtable_decl != NULL_TREE)
	{
	  /* We've already created some other class, and consequently
	     we made class_dtable_decl.  Now we just want to fill it
	     in.  */
	  dtable_decl = class_dtable_decl;
	}
      else
	{
	  dtable_decl = build_dtable_decl (type);
	  TREE_STATIC (dtable_decl) = 1;
	  DECL_ARTIFICIAL (dtable_decl) = 1;
	  DECL_IGNORED_P (dtable_decl) = 1;
	}

1830
      TREE_PUBLIC (dtable_decl) = 1;
1831
      DECL_INITIAL (dtable_decl) = dtable;
1832 1833 1834
      /* The only dispatch table exported from a DSO is the dispatch
	 table for java.lang.Class.  */
      if (DECL_NAME (type_decl) != id_class)
1835
	java_hide_decl (dtable_decl);
1836 1837
      if (! flag_indirect_classes)
	rest_of_decl_compilation (dtable_decl, 1, 0);
1838 1839 1840
      /* Maybe we're compiling Class as the first class.  If so, set
	 class_dtable_decl to the decl we just made.  */
      if (type == class_type_node && class_dtable_decl == NULL_TREE)
1841 1842 1843
	class_dtable_decl = dtable_decl;
    }

Anthony Green committed
1844 1845
  /* Build Field array. */
  field = TYPE_FIELDS (type);
1846
  while (field && DECL_ARTIFICIAL (field))
1847
    field = DECL_CHAIN (field);  /* Skip dummy fields.  */
1848
  if (field && DECL_NAME (field) == NULL_TREE)
1849
    field = DECL_CHAIN (field);  /* Skip dummy field for inherited data. */
1850 1851 1852
  first_real_field = field;

  /* First count static and instance fields.  */
1853
  for ( ; field != NULL_TREE; field = DECL_CHAIN (field))
1854 1855 1856 1857 1858 1859 1860 1861 1862 1863
    {
      if (! DECL_ARTIFICIAL (field))
	{
	  if (FIELD_STATIC (field))
	    static_field_count++;
	  else if (uses_jv_markobj || !flag_reduced_reflection)
	    instance_field_count++;
	}
    }
  field_count = static_field_count + instance_field_count;
1864
  field_indexes.create (field_count);
1865 1866 1867 1868
  
  /* gcj sorts fields so that static fields come first, followed by
     instance fields.  Unfortunately, by the time this takes place we
     have already generated the reflection_data for this class, and
1869
     that data contains indexes into the fields.  So, we generate a
1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881
     permutation that maps each original field index to its final
     position.  Then we pass this permutation to
     rewrite_reflection_indexes(), which fixes up the reflection
     data.  */
  {
    int i;
    int static_count = 0;
    int instance_count = static_field_count;
    int field_index;

    for (i = 0, field = first_real_field; 
	 field != NULL_TREE; 
1882
	 field = DECL_CHAIN (field), i++)
1883 1884 1885 1886 1887 1888 1889 1890
    {
      if (! DECL_ARTIFICIAL (field))
	{
	  field_index = 0;
	  if (FIELD_STATIC (field))
	    field_index = static_count++;
	  else if (uses_jv_markobj || !flag_reduced_reflection)
	    field_index = instance_count++;
1891 1892
	  else
	    continue;
1893
	  field_indexes.quick_push (field_index);
1894 1895 1896 1897 1898
	}
    }
  }

  for (field = first_real_field; field != NULL_TREE; 
1899
       field = DECL_CHAIN (field))
Anthony Green committed
1900 1901 1902 1903 1904
    {
      if (! DECL_ARTIFICIAL (field))
	{
	  if (FIELD_STATIC (field))
	    {
1905 1906 1907
              /* We must always create reflection data for static fields
                 as it is used in the creation of the field itself. */
              tree init = make_field_value (field);
1908
	      tree initial = DECL_INITIAL (field);
1909
              CONSTRUCTOR_APPEND_ELT (static_fields, NULL_TREE, init);
1910 1911 1912 1913 1914
	      /* If the initial value is a string constant,
		 prevent output_constant from trying to assemble the value. */
	      if (initial != NULL_TREE
		  && TREE_TYPE (initial) == string_ptr_type_node)
		DECL_INITIAL (field) = NULL_TREE;
1915
	      rest_of_decl_compilation (field, 1, 1);
1916
	      DECL_INITIAL (field) = initial;
Anthony Green committed
1917
	    }
1918
	  else if (uses_jv_markobj || !flag_reduced_reflection)
Anthony Green committed
1919
	    {
1920
              tree init = make_field_value (field);
1921
              CONSTRUCTOR_APPEND_ELT (instance_fields, NULL_TREE, init);
Anthony Green committed
1922 1923 1924
	    }
	}
    }
1925

1926 1927
  gcc_assert (static_field_count == (int) vec_safe_length (static_fields));
  gcc_assert (instance_field_count == (int) vec_safe_length (instance_fields));
1928

Anthony Green committed
1929 1930
  if (field_count > 0)
    {
1931
      vec_safe_splice (static_fields, instance_fields);
Anthony Green committed
1932
      field_array_type = build_prim_array_type (field_type_node, field_count);
1933 1934
      fields_decl = build_decl (input_location,
				VAR_DECL, mangled_classname ("_FL_", type),
Anthony Green committed
1935
				field_array_type);
1936 1937
      DECL_INITIAL (fields_decl)
        = build_constructor (field_array_type, static_fields);
Anthony Green committed
1938 1939 1940
      TREE_STATIC (fields_decl) = 1;
      DECL_ARTIFICIAL (fields_decl) = 1;
      DECL_IGNORED_P (fields_decl) = 1;
1941
      rest_of_decl_compilation (fields_decl, 1, 0);
Anthony Green committed
1942 1943 1944 1945 1946
    }
  else
    fields_decl = NULL_TREE;

  /* Build Method array. */
1947
  for (method = TYPE_METHODS (type);
1948
       method != NULL_TREE; method = DECL_CHAIN (method))
Anthony Green committed
1949
    {
1950 1951
      tree init;
      if (METHOD_PRIVATE (method)
1952
	  && ! flag_keep_inline_functions
1953
	  && optimize)
1954
	continue;
1955
      /* Even if we have a decl, we don't necessarily have the code.
1956 1957 1958 1959
	 This can happen if we inherit a method from a superclass for
	 which we don't have a .class file.  */
      if (METHOD_DUMMY (method))
	continue;
1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981

      /* Generate method reflection data if:

          - !flag_reduced_reflection.

          - <clinit> -- The runtime uses reflection to initialize the
            class.

          - Any method in class java.lang.Class -- Class.forName() and
            perhaps other things require it.

          - class$ -- It does not work if reflection data missing.

          - main -- Reflection is used to find main(String[]) methods.

          - public not static -- It is potentially part of an
            interface.  The runtime uses reflection data to build
            interface dispatch tables.  */
      if (!flag_reduced_reflection
          || DECL_CLINIT_P (method)
          || DECL_NAME (type_decl) == id_class
          || DECL_NAME (method) == id_main
1982
          || (METHOD_PUBLIC (method) && !METHOD_STATIC (method)))
1983 1984 1985
        {
          init = make_method_value (method);
          method_count++;
1986
          CONSTRUCTOR_APPEND_ELT (methods, NULL_TREE, init);
1987
        }
Anthony Green committed
1988 1989
    }
  method_array_type = build_prim_array_type (method_type_node, method_count);
1990 1991
  methods_decl = build_decl (input_location,
			     VAR_DECL, mangled_classname ("_MT_", type),
Anthony Green committed
1992
			     method_array_type);
1993
  DECL_INITIAL (methods_decl) = build_constructor (method_array_type, methods);
Anthony Green committed
1994 1995 1996
  TREE_STATIC (methods_decl) = 1;
  DECL_ARTIFICIAL (methods_decl) = 1;
  DECL_IGNORED_P (methods_decl) = 1;
1997
  rest_of_decl_compilation (methods_decl, 1, 0);
Anthony Green committed
1998

1999 2000 2001 2002 2003 2004
  if (class_dtable_decl == NULL_TREE)
    {
      class_dtable_decl = build_dtable_decl (class_type_node);
      TREE_STATIC (class_dtable_decl) = 1;
      DECL_ARTIFICIAL (class_dtable_decl) = 1;
      DECL_IGNORED_P (class_dtable_decl) = 1;
2005
      if (is_compiled_class (class_type_node) != 2)
2006 2007 2008 2009
	{
	  DECL_EXTERNAL (class_dtable_decl) = 1;
	  rest_of_decl_compilation (class_dtable_decl, 1, 0);
	}
Anthony Green committed
2010 2011 2012 2013 2014
    }

  super = CLASSTYPE_SUPER (type);
  if (super == NULL_TREE)
    super = null_pointer_node;
2015 2016
  else if (! flag_indirect_dispatch
	   && assume_compiled (IDENTIFIER_POINTER (DECL_NAME (type_decl)))
2017
	   && assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (super)))))
Anthony Green committed
2018 2019 2020 2021
    super = build_class_ref (super);
  else
    {
      int super_index = alloc_class_constant (super);
2022
      super = build_int_cst (ptr_type_node, super_index);
Anthony Green committed
2023 2024 2025 2026
    }

  /* Build and emit the array of implemented interfaces. */
  if (type != object_type_node)
2027 2028
    interface_len = BINFO_N_BASE_BINFOS (TYPE_BINFO (type)) - 1;
  
Anthony Green committed
2029 2030 2031 2032
  if (interface_len > 0)
    {
      int i;
      tree interface_array_type, idecl;
2033 2034
      vec<constructor_elt, va_gc> *init;
      vec_alloc (init, interface_len);
Anthony Green committed
2035 2036
      interface_array_type
	= build_prim_array_type (class_ptr_type, interface_len);
2037 2038
      idecl = build_decl (input_location,
			  VAR_DECL, mangled_classname ("_IF_", type),
Anthony Green committed
2039
			  interface_array_type);
Nathan Sidwell committed
2040
      
2041
      for (i = 1; i <= interface_len; i++)
Anthony Green committed
2042
	{
Nathan Sidwell committed
2043
	  tree child = BINFO_BASE_BINFO (TYPE_BINFO (type), i);
Anthony Green committed
2044 2045
	  tree iclass = BINFO_TYPE (child);
	  tree index;
2046 2047 2048
	  if (! flag_indirect_dispatch
	      && (assume_compiled 
		  (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (iclass))))))
Anthony Green committed
2049 2050 2051
	    index = build_class_ref (iclass);
	  else
	    {
2052
	      int int_index = alloc_class_constant (iclass);
2053
	      index = build_int_cst (ptr_type_node, int_index);
Anthony Green committed
2054
	    }
2055
	  CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, index);
Anthony Green committed
2056
	}
2057
      DECL_INITIAL (idecl) = build_constructor (interface_array_type, init);
Anthony Green committed
2058 2059 2060 2061
      TREE_STATIC (idecl) = 1;
      DECL_ARTIFICIAL (idecl) = 1;
      DECL_IGNORED_P (idecl) = 1;
      interfaces = build1 (ADDR_EXPR, ptr_type_node, idecl);
2062
      rest_of_decl_compilation (idecl, 1, 0);
Anthony Green committed
2063 2064 2065 2066
    }

  constant_pool_constructor = build_constants_constructor ();

2067 2068 2069 2070 2071 2072
  if (flag_indirect_dispatch)
    {
      TYPE_OTABLE_DECL (type) 
	= emit_symbol_table 
	(DECL_NAME (TYPE_OTABLE_DECL (type)), 
	 TYPE_OTABLE_DECL (type), TYPE_OTABLE_METHODS (type), 
2073
	 TYPE_OTABLE_SYMS_DECL (type), integer_type_node, 1);
2074 2075 2076 2077 2078
       
      TYPE_ATABLE_DECL (type) 
	= emit_symbol_table 
	(DECL_NAME (TYPE_ATABLE_DECL (type)), 
	 TYPE_ATABLE_DECL (type), TYPE_ATABLE_METHODS (type), 
2079 2080 2081 2082 2083 2084 2085
	 TYPE_ATABLE_SYMS_DECL (type), ptr_type_node, 1);
       
      TYPE_ITABLE_DECL (type) 
	= emit_symbol_table 
	(DECL_NAME (TYPE_ITABLE_DECL (type)), 
	 TYPE_ITABLE_DECL (type), TYPE_ITABLE_METHODS (type), 
	 TYPE_ITABLE_SYMS_DECL (type), ptr_type_node, 2);
2086 2087 2088 2089
    }
  
  TYPE_CTABLE_DECL (type) = emit_catch_table (type);

2090 2091
  START_RECORD_CONSTRUCTOR (v1, object_type_node);
  PUSH_FIELD_VALUE (v1, "vtable",
2092 2093
		    (flag_indirect_classes 
		     ? null_pointer_node
2094 2095 2096 2097
		     : fold_build_pointer_plus
			 (build1 (ADDR_EXPR, dtable_ptr_type,
				  class_dtable_decl),
			  dtable_start_offset)));
2098
  if (! flag_hash_synchronization)
2099 2100 2101 2102 2103 2104 2105
    PUSH_FIELD_VALUE (v1, "sync_info", null_pointer_node);
  FINISH_RECORD_CONSTRUCTOR (temp, v1, object_type_node);
  START_RECORD_CONSTRUCTOR (v2, class_type_node);
  PUSH_SUPER_VALUE (v2, temp);
  PUSH_FIELD_VALUE (v2, "next_or_version", gcj_abi_version);
  PUSH_FIELD_VALUE (v2, "name", build_utf8_ref (DECL_NAME (type_decl)));
  PUSH_FIELD_VALUE (v2, "accflags",
2106
		    build_int_cst (NULL_TREE,
2107
				   get_access_flags_from_decl (type_decl)));
Anthony Green committed
2108

2109
  PUSH_FIELD_VALUE (v2, "superclass", 
2110
		    CLASS_INTERFACE (type_decl) ? null_pointer_node : super);
2111 2112
  PUSH_FIELD_VALUE (v2, "constants", constant_pool_constructor);
  PUSH_FIELD_VALUE (v2, "methods",
2113 2114
                    methods_decl == NULL_TREE ? null_pointer_node
		    : build1 (ADDR_EXPR, method_ptr_type_node, methods_decl));
2115
  PUSH_FIELD_VALUE (v2, "method_count",
2116
		    build_int_cst (NULL_TREE, method_count));
2117

2118 2119 2120 2121
  PUSH_FIELD_VALUE (v2, "vtable_method_count",
                    (flag_indirect_dispatch
                     ? integer_minus_one_node
                     : TYPE_NVIRTUALS (type)));
2122
    
2123
  PUSH_FIELD_VALUE (v2, "fields",
Anthony Green committed
2124 2125
		    fields_decl == NULL_TREE ? null_pointer_node
		    : build1 (ADDR_EXPR, field_ptr_type_node, fields_decl));
2126 2127
  /* If we're using the binary compatibility ABI we don't know the
     size until load time.  */
2128
  PUSH_FIELD_VALUE (v2, "size_in_bytes", 
2129 2130 2131
		    (flag_indirect_dispatch 
		     ? integer_minus_one_node 
		     : size_in_bytes (type)));
2132
  PUSH_FIELD_VALUE (v2, "field_count", 
2133
		    build_int_cst (NULL_TREE, field_count));
2134
  PUSH_FIELD_VALUE (v2, "static_field_count",
2135
		    build_int_cst (NULL_TREE, static_field_count));
2136

2137 2138 2139
  PUSH_FIELD_VALUE (v2, "vtable",
                    (flag_indirect_dispatch || dtable_decl == NULL_TREE
                     ? null_pointer_node
2140 2141 2142 2143
                     : fold_build_pointer_plus
			 (build1 (ADDR_EXPR, dtable_ptr_type,
				  dtable_decl),
			  dtable_start_offset)));
2144 2145 2146 2147 2148 2149 2150 2151 2152
  add_table_and_syms (&v2, TYPE_OTABLE_METHODS (type),
                      "otable", TYPE_OTABLE_DECL (type), otable_ptr_type,
                      "otable_syms", TYPE_OTABLE_SYMS_DECL (type));
  add_table_and_syms (&v2, TYPE_ATABLE_METHODS (type),
                      "atable", TYPE_ATABLE_DECL (type), atable_ptr_type,
                      "atable_syms", TYPE_ATABLE_SYMS_DECL (type));
  add_table_and_syms (&v2, TYPE_ITABLE_METHODS (type),
                      "itable", TYPE_ITABLE_DECL (type), itable_ptr_type,
                      "itable_syms", TYPE_ITABLE_SYMS_DECL (type));
2153
 
2154
  PUSH_FIELD_VALUE (v2, "catch_classes",
2155
		    build1 (ADDR_EXPR, ptr_type_node, TYPE_CTABLE_DECL (type)));
2156 2157 2158
  PUSH_FIELD_VALUE (v2, "interfaces", interfaces);
  PUSH_FIELD_VALUE (v2, "loader", null_pointer_node);
  PUSH_FIELD_VALUE (v2, "interface_count",
2159
		    build_int_cst (NULL_TREE, interface_len));
2160
  PUSH_FIELD_VALUE (v2, "state",
2161 2162
		    convert (byte_type_node,
			     build_int_cst (NULL_TREE, JV_STATE_PRELOADING)));
Anthony Green committed
2163

2164 2165 2166 2167 2168 2169
  PUSH_FIELD_VALUE (v2, "thread", null_pointer_node);
  PUSH_FIELD_VALUE (v2, "depth", integer_zero_node);
  PUSH_FIELD_VALUE (v2, "ancestors", null_pointer_node);
  PUSH_FIELD_VALUE (v2, "idt", null_pointer_node);
  PUSH_FIELD_VALUE (v2, "arrayclass", null_pointer_node);
  PUSH_FIELD_VALUE (v2, "protectionDomain", null_pointer_node);
2170 2171 2172 2173 2174 2175 2176 2177 2178 2179

  {
    tree assertion_table_ref;
    if (TYPE_ASSERTIONS (type) == NULL)
      assertion_table_ref = null_pointer_node;
    else
      assertion_table_ref = build1 (ADDR_EXPR, 
				    build_pointer_type (assertion_table_type),
				    emit_assertion_table (type));
    
2180
    PUSH_FIELD_VALUE (v2, "assertion_table", assertion_table_ref);
2181 2182
  }

2183 2184 2185 2186
  PUSH_FIELD_VALUE (v2, "hack_signers", null_pointer_node);
  PUSH_FIELD_VALUE (v2, "chain", null_pointer_node);
  PUSH_FIELD_VALUE (v2, "aux_info", null_pointer_node);
  PUSH_FIELD_VALUE (v2, "engine", null_pointer_node);
Per Bothner committed
2187

2188 2189 2190 2191
  if (TYPE_REFLECTION_DATA (current_class))
    {
      int i;
      int count = TYPE_REFLECTION_DATASIZE (current_class);
2192 2193
      vec<constructor_elt, va_gc> *v;
      vec_alloc (v, count);
2194 2195 2196 2197 2198 2199 2200 2201 2202
      unsigned char *data = TYPE_REFLECTION_DATA (current_class);
      tree max_index = build_int_cst (sizetype, count);
      tree index = build_index_type (max_index);
      tree type = build_array_type (unsigned_byte_type_node, index);
      char buf[64];
      tree array;
      static int reflection_data_count;

      sprintf (buf, "_reflection_data_%d", reflection_data_count++);
2203 2204
      array = build_decl (input_location,
			  VAR_DECL, get_identifier (buf), type);
2205

2206
      rewrite_reflection_indexes (&field_indexes);
2207 2208 2209

      for (i = 0; i < count; i++)
	{
2210 2211 2212
	  constructor_elt elt;
 	  elt.index = build_int_cst (sizetype, i);
	  elt.value = build_int_cstu (byte_type_node, data[i]);
2213
	  v->quick_push (elt);
2214 2215 2216 2217 2218 2219 2220 2221 2222
	}

      DECL_INITIAL (array) = build_constructor (type, v);
      TREE_STATIC (array) = 1;
      DECL_ARTIFICIAL (array) = 1;
      DECL_IGNORED_P (array) = 1;
      TREE_READONLY (array) = 1;
      TREE_CONSTANT (DECL_INITIAL (array)) = 1;
      rest_of_decl_compilation (array, 1, 0);
2223 2224

      reflection_data = build_address_of (array);
2225 2226 2227 2228 2229

      free (data);
      TYPE_REFLECTION_DATA (current_class) = NULL;
    }
  else
2230
    reflection_data = null_pointer_node;
2231

2232 2233
  PUSH_FIELD_VALUE (v2, "reflection_data", reflection_data);
  FINISH_RECORD_CONSTRUCTOR (cons, v2, class_type_node);
Anthony Green committed
2234 2235

  DECL_INITIAL (decl) = cons;
2236 2237 2238 2239 2240
  
  /* Hash synchronization requires at least 64-bit alignment. */
  if (flag_hash_synchronization && POINTER_SIZE < 64)
    DECL_ALIGN (decl) = 64; 
  
2241 2242 2243 2244 2245 2246
  if (flag_indirect_classes)
    {
      TREE_READONLY (decl) = 1;
      TREE_CONSTANT (DECL_INITIAL (decl)) = 1;
    }

2247
  rest_of_decl_compilation (decl, 1, 0);
2248
  
2249 2250 2251 2252 2253 2254 2255
  {
    tree classdollar_field = build_classdollar_field (type);
    if (!flag_indirect_classes)
      DECL_INITIAL (classdollar_field) = build_static_class_ref (type);
    rest_of_decl_compilation (classdollar_field, 1, 0);
  }

2256 2257 2258
  TYPE_OTABLE_DECL (type) = NULL_TREE;
  TYPE_ATABLE_DECL (type) = NULL_TREE;
  TYPE_CTABLE_DECL (type) = NULL_TREE;
Anthony Green committed
2259 2260
}

2261
void
2262
finish_class (void)
2263
{
2264 2265
  java_expand_catch_classes (current_class);

2266
  current_function_decl = NULL_TREE;
2267
  TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (current_class)) = 0;
2268 2269
  make_class_data (current_class);
  register_class ();
2270
  rest_of_decl_compilation (TYPE_NAME (current_class), 1, 0);
2271 2272
}

2273 2274 2275
/* Return 2 if KLASS is compiled by this compilation job;
   return 1 if KLASS can otherwise be assumed to be compiled;
   return 0 if we cannot assume that KLASS is compiled.
Anthony Green committed
2276 2277
   Returns 1 for primitive and 0 for array types.  */
int
2278
is_compiled_class (tree klass)
Anthony Green committed
2279
{
2280
  int seen_in_zip;
2281 2282 2283
  if (TREE_CODE (klass) == POINTER_TYPE)
    klass = TREE_TYPE (klass);
  if (TREE_CODE (klass) != RECORD_TYPE)  /* Primitive types are static. */
Anthony Green committed
2284
    return 1;
2285
  if (TYPE_ARRAY_P (klass))
Anthony Green committed
2286
    return 0;
2287

2288 2289
  seen_in_zip = (TYPE_JCF (klass) && JCF_SEEN_IN_ZIP (TYPE_JCF (klass)));
  if (CLASS_FROM_CURRENTLY_COMPILED_P (klass))
Anthony Green committed
2290 2291 2292 2293
    {
      /* The class was seen in the current ZIP file and will be
	 available as a compiled class in the future but may not have
	 been loaded already. Load it if necessary. This prevent
2294
	 build_class_ref () from crashing. */
Anthony Green committed
2295

2296 2297
      if (seen_in_zip && !CLASS_LOADED_P (klass) && (klass != current_class))
        load_class (klass, 1);
2298 2299 2300

      /* We return 2 for class seen in ZIP and class from files
         belonging to the same compilation unit */
Anthony Green committed
2301 2302 2303
      return 2;
    }

2304
  if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (klass)))))
Anthony Green committed
2305
    {
2306
      if (!CLASS_LOADED_P (klass))
2307
	{
2308 2309
	  if (klass != current_class)
	    load_class (klass, 1);
2310
	}
Anthony Green committed
2311 2312 2313 2314 2315 2316 2317 2318 2319
      return 1;
    }

  return 0;
}

/* Build a VAR_DECL for the dispatch table (vtable) for class TYPE. */

tree
2320
build_dtable_decl (tree type)
Anthony Green committed
2321
{
2322
  tree dtype, decl;
2323 2324 2325 2326

  /* We need to build a new dtable type so that its size is uniquely
     computed when we're dealing with the class for real and not just
     faking it (like java.lang.Class during the initialization of the
2327
     compiler.) We know we're not faking a class when CURRENT_CLASS is
2328 2329 2330
     TYPE. */
  if (current_class == type)
    {
2331 2332
      tree dummy = NULL_TREE;
      int n;
2333 2334

      dtype = make_node (RECORD_TYPE);
2335

2336 2337
      PUSH_FIELD (input_location, dtype, dummy, "top_offset", ptr_type_node);
      PUSH_FIELD (input_location, dtype, dummy, "type_info", ptr_type_node);
2338

2339
      PUSH_FIELD (input_location, dtype, dummy, "class", class_ptr_type);
2340 2341
      for (n = 1; n < TARGET_VTABLE_USES_DESCRIPTORS; ++n)
	{
2342 2343
	  tree tmp_field = build_decl (input_location,
				       FIELD_DECL, NULL_TREE, ptr_type_node);
2344 2345 2346 2347 2348 2349
	  TREE_CHAIN (dummy) = tmp_field;
	  DECL_CONTEXT (tmp_field) = dtype;
	  DECL_ARTIFICIAL (tmp_field) = 1;
	  dummy = tmp_field;
	}

2350
      PUSH_FIELD (input_location, dtype, dummy, "gc_descr", ptr_type_node);
2351 2352
      for (n = 1; n < TARGET_VTABLE_USES_DESCRIPTORS; ++n)
	{
2353 2354
	  tree tmp_field = build_decl (input_location,
				       FIELD_DECL, NULL_TREE, ptr_type_node);
2355 2356 2357 2358 2359 2360 2361 2362 2363 2364
	  TREE_CHAIN (dummy) = tmp_field;
	  DECL_CONTEXT (tmp_field) = dtype;
	  DECL_ARTIFICIAL (tmp_field) = 1;
	  dummy = tmp_field;
	}

      n = TREE_VEC_LENGTH (get_dispatch_vector (type));
      if (TARGET_VTABLE_USES_DESCRIPTORS)
	n *= TARGET_VTABLE_USES_DESCRIPTORS;

2365
      PUSH_FIELD (input_location, dtype, dummy, "methods",
2366
		  build_prim_array_type (nativecode_ptr_type_node, n));
2367 2368 2369 2370 2371
      layout_type (dtype);
    }
  else
    dtype = dtable_type;

2372 2373
  decl = build_decl (input_location,
		     VAR_DECL, get_identifier ("vt$"), dtype);
2374 2375 2376 2377 2378
  DECL_CONTEXT (decl) = type;
  MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
  DECL_VTABLE_P (decl) = 1;

  return decl;
Anthony Green committed
2379 2380 2381 2382 2383 2384
}

/* Pre-pend the TYPE_FIELDS of THIS_CLASS with a dummy FIELD_DECL for the
   fields inherited from SUPER_CLASS. */

void
2385
push_super_field (tree this_class, tree super_class)
Anthony Green committed
2386 2387
{
  tree base_decl;
2388 2389 2390
  /* Don't insert the field if we're just re-laying the class out. */ 
  if (TYPE_FIELDS (this_class) && !DECL_NAME (TYPE_FIELDS (this_class)))
    return;
2391 2392
  base_decl = build_decl (input_location,
			  FIELD_DECL, NULL_TREE, super_class);
Anthony Green committed
2393
  DECL_IGNORED_P (base_decl) = 1;
2394
  DECL_CHAIN (base_decl) = TYPE_FIELDS (this_class);
Anthony Green committed
2395 2396
  TYPE_FIELDS (this_class) = base_decl;
  DECL_SIZE (base_decl) = TYPE_SIZE (super_class);
2397
  DECL_SIZE_UNIT (base_decl) = TYPE_SIZE_UNIT (super_class);
Anthony Green committed
2398 2399
}

2400 2401 2402
/* Handle the different manners we may have to lay out a super class.  */

static tree
2403
maybe_layout_super_class (tree super_class, tree this_class ATTRIBUTE_UNUSED)
2404
{
2405 2406 2407
  if (!super_class)
    return NULL_TREE;
  else if (TREE_CODE (super_class) == RECORD_TYPE)
2408 2409 2410 2411 2412 2413
    {
      if (!CLASS_LOADED_P (super_class))
	load_class (super_class, 1);
    }
  /* We might have to layout the class before its dependency on
     the super class gets resolved by java_complete_class  */
2414
  else if (TREE_CODE (super_class) == POINTER_TYPE)
2415
    {
2416 2417 2418
      if (TREE_TYPE (super_class) != NULL_TREE)
	super_class = TREE_TYPE (super_class);
      else
2419
	gcc_unreachable ();
2420 2421 2422 2423 2424 2425 2426
    }
  if (!TYPE_SIZE (super_class))
    safe_layout_class (super_class);

  return super_class;
}

2427
/* safe_layout_class just makes sure that we can load a class without
2428
   disrupting the current_class, input_location, etc, information
2429 2430 2431
   about the class processed currently.  */

void
2432
safe_layout_class (tree klass)
2433 2434 2435 2436
{
  tree save_current_class = current_class;
  location_t save_location = input_location;

2437
  layout_class (klass);
2438 2439 2440 2441 2442

  current_class = save_current_class;
  input_location = save_location;
}

Anthony Green committed
2443
void
2444
layout_class (tree this_class)
Anthony Green committed
2445
{
2446
  int i;
Anthony Green committed
2447
  tree super_class = CLASSTYPE_SUPER (this_class);
2448

2449
  class_list = tree_cons (this_class, NULL_TREE, class_list);
2450 2451 2452
  if (CLASS_BEING_LAIDOUT (this_class))
    {
      char buffer [1024];
Mark Mitchell committed
2453
      char *report;
2454
      tree current;
2455

2456
      sprintf (buffer, " with '%s'",
2457 2458 2459
	       IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class))));
      obstack_grow (&temporary_obstack, buffer, strlen (buffer));

2460
      for (current = TREE_CHAIN (class_list); current; 
2461 2462 2463
	   current = TREE_CHAIN (current))
	{
	  tree decl = TYPE_NAME (TREE_PURPOSE (current));
2464
	  sprintf (buffer, "\n  which inherits from '%s' (%s:%d)",
2465
		   IDENTIFIER_POINTER (DECL_NAME (decl)),
2466 2467
		   DECL_SOURCE_FILE (decl),
		   DECL_SOURCE_LINE (decl));
2468 2469 2470
	  obstack_grow (&temporary_obstack, buffer, strlen (buffer));
	}
      obstack_1grow (&temporary_obstack, '\0');
2471
      report = XOBFINISH (&temporary_obstack, char *);
Mark Mitchell committed
2472 2473
      cyclic_inheritance_report = ggc_strdup (report);
      obstack_free (&temporary_obstack, report);
2474 2475 2476 2477
      TYPE_SIZE (this_class) = error_mark_node;
      return;
    }
  CLASS_BEING_LAIDOUT (this_class) = 1;
Anthony Green committed
2478

2479
  if (super_class && !CLASS_BEING_LAIDOUT (super_class))
Anthony Green committed
2480
    {
2481 2482 2483 2484
      tree maybe_super_class 
	= maybe_layout_super_class (super_class, this_class);
      if (maybe_super_class == NULL
	  || TREE_CODE (TYPE_SIZE (maybe_super_class)) == ERROR_MARK)
Anthony Green committed
2485 2486
	{
	  TYPE_SIZE (this_class) = error_mark_node;
2487
	  CLASS_BEING_LAIDOUT (this_class) = 0;
2488
	  class_list = TREE_CHAIN (class_list);
Anthony Green committed
2489 2490 2491
	  return;
	}
      if (TYPE_SIZE (this_class) == NULL_TREE)
2492
	push_super_field (this_class, maybe_super_class);
Anthony Green committed
2493 2494 2495
    }

  layout_type (this_class);
2496

2497 2498
  /* Also recursively load/layout any superinterfaces.  */
  if (TYPE_BINFO (this_class))
2499
    {
2500
      for (i = BINFO_N_BASE_BINFOS (TYPE_BINFO (this_class)) - 1; i > 0; i--)
2501
	{
2502 2503 2504 2505 2506 2507
	  tree binfo = BINFO_BASE_BINFO (TYPE_BINFO (this_class), i);
	  tree super_interface = BINFO_TYPE (binfo);
	  tree maybe_super_interface 
	    = maybe_layout_super_class (super_interface, NULL_TREE);
	  if (maybe_super_interface == NULL
	      || TREE_CODE (TYPE_SIZE (maybe_super_interface)) == ERROR_MARK)
2508
	    {
2509 2510 2511 2512
	      TYPE_SIZE (this_class) = error_mark_node;
	      CLASS_BEING_LAIDOUT (this_class) = 0;
	      class_list = TREE_CHAIN (class_list);
	      return;
2513 2514 2515 2516
	    }
	}
    }

2517 2518
  /* Convert the size back to an SI integer value.  */
  TYPE_SIZE_UNIT (this_class) =
2519
    fold (convert (int_type_node, TYPE_SIZE_UNIT (this_class)));
2520 2521

  CLASS_BEING_LAIDOUT (this_class) = 0;
2522
  class_list = TREE_CHAIN (class_list);
2523
}
Anthony Green committed
2524

2525 2526 2527
static void
add_miranda_methods (tree base_class, tree search_class)
{
Nathan Sidwell committed
2528
  int i;
2529 2530 2531 2532
  tree binfo, base_binfo;

  if (!CLASS_PARSED_P (search_class))
    load_class (search_class, 1);
Nathan Sidwell committed
2533 2534 2535
  
  for (binfo = TYPE_BINFO (search_class), i = 1;
       BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
2536 2537
    {
      tree method_decl;
Nathan Sidwell committed
2538
      tree elt = BINFO_TYPE (base_binfo);
2539

2540 2541 2542 2543 2544
      /* FIXME: This is totally bogus.  We should not be handling
	 Miranda methods at all if we're using the BC ABI.  */
      if (TYPE_DUMMY (elt))
	continue;

2545
      /* Ensure that interface methods are seen in declared order.  */
2546 2547
      if (!CLASS_LOADED_P (elt))
	load_class (elt, 1);
2548 2549 2550 2551 2552
      layout_class_methods (elt);

      /* All base classes will have been laid out at this point, so the order 
         will be correct.  This code must match similar layout code in the 
         runtime.  */
2553
      for (method_decl = TYPE_METHODS (elt);
2554
	   method_decl; method_decl = DECL_CHAIN (method_decl))
2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582
	{
	  tree sig, override;

	  /* An interface can have <clinit>.  */
	  if (ID_CLINIT_P (DECL_NAME (method_decl)))
	    continue;

	  sig = build_java_argument_signature (TREE_TYPE (method_decl));
	  override = lookup_argument_method (base_class,
					     DECL_NAME (method_decl), sig);
	  if (override == NULL_TREE)
	    {
	      /* Found a Miranda method.  Add it.  */
	      tree new_method;
	      sig = build_java_signature (TREE_TYPE (method_decl));
	      new_method
		= add_method (base_class,
			      get_access_flags_from_decl (method_decl),
			      DECL_NAME (method_decl), sig);
	      METHOD_INVISIBLE (new_method) = 1;
	    }
	}

      /* Try superinterfaces.  */
      add_miranda_methods (base_class, elt);
    }
}

2583
void
2584
layout_class_methods (tree this_class)
2585 2586
{
  tree method_decl, dtable_count;
2587
  tree super_class, type_name;
2588 2589 2590

  if (TYPE_NVIRTUALS (this_class))
    return;
2591
  
2592
  super_class = CLASSTYPE_SUPER (this_class);
Anthony Green committed
2593

2594
  if (super_class)
Anthony Green committed
2595
    {
2596
      super_class = maybe_layout_super_class (super_class, this_class);
2597 2598 2599 2600 2601 2602
      if (!TYPE_NVIRTUALS (super_class))
	layout_class_methods (super_class);
      dtable_count = TYPE_NVIRTUALS (super_class);
    }
  else
    dtable_count = integer_zero_node;
2603

2604
  type_name = TYPE_NAME (this_class);
2605 2606
  if (!flag_indirect_dispatch
      && (CLASS_ABSTRACT (type_name) || CLASS_INTERFACE (type_name)))
2607 2608 2609 2610 2611 2612 2613 2614
    {
      /* An abstract class can have methods which are declared only in
	 an implemented interface.  These are called "Miranda
	 methods".  We make a dummy method entry for such methods
	 here.  */
      add_miranda_methods (this_class, this_class);
    }

2615
  TYPE_METHODS (this_class) = nreverse (TYPE_METHODS (this_class));
2616

2617
  for (method_decl = TYPE_METHODS (this_class);
2618
       method_decl; method_decl = DECL_CHAIN (method_decl))
2619
    dtable_count = layout_class_method (this_class, super_class,
2620 2621 2622 2623 2624
					method_decl, dtable_count);

  TYPE_NVIRTUALS (this_class) = dtable_count;
}

2625 2626
/* Return the index of METHOD in INTERFACE.  This index begins at 1
   and is used as an argument for _Jv_LookupInterfaceMethodIdx(). */
Bryce McKinlay committed
2627 2628 2629 2630 2631 2632
int
get_interface_method_index (tree method, tree interface)
{
  tree meth;
  int i = 1;

2633
  for (meth = TYPE_METHODS (interface); ; meth = DECL_CHAIN (meth))
Bryce McKinlay committed
2634 2635 2636
    {
      if (meth == method)
	return i;
2637 2638 2639
      /* We don't want to put <clinit> into the interface table.  */
      if (! ID_CLINIT_P (DECL_NAME (meth)))
	++i;
2640
      gcc_assert (meth != NULL_TREE);
Bryce McKinlay committed
2641 2642 2643
    }
}

2644
/* Lay METHOD_DECL out, returning a possibly new value of
2645
   DTABLE_COUNT. Also mangle the method's name. */
2646 2647

tree
2648 2649
layout_class_method (tree this_class, tree super_class,
		     tree method_decl, tree dtable_count)
2650 2651
{
  tree method_name = DECL_NAME (method_decl);
2652 2653

  TREE_PUBLIC (method_decl) = 1;
2654

2655 2656 2657 2658
  if (flag_indirect_classes
      || (METHOD_PRIVATE (method_decl) && METHOD_STATIC (method_decl)
	  && ! METHOD_NATIVE (method_decl)
	  && ! special_method_p (method_decl)))
2659
    java_hide_decl (method_decl);
2660

2661
  /* Considered external unless it is being compiled into this object
2662 2663 2664 2665
     file, or it was already flagged as external.  */
  if (!DECL_EXTERNAL (method_decl))
    DECL_EXTERNAL (method_decl) = ((is_compiled_class (this_class) != 2)
                                   || METHOD_NATIVE (method_decl));
2666

2667
  if (ID_INIT_P (method_name))
2668
    {
2669
      const char *p = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class)));
2670
      const char *ptr;
2671
      for (ptr = p; *ptr; )
Anthony Green committed
2672
	{
2673 2674 2675 2676
	  if (*ptr++ == '.')
	    p = ptr;
	}
      DECL_CONSTRUCTOR_P (method_decl) = 1;
2677
      build_java_signature (TREE_TYPE (method_decl));
2678
    }
2679
  else if (! METHOD_STATIC (method_decl))
2680
    {
2681
      tree method_sig =
2682
	build_java_signature (TREE_TYPE (method_decl));
2683
      bool method_override = false;
2684
      tree super_method = lookup_java_method (super_class, method_name,
Anthony Green committed
2685
						  method_sig);
2686
      if (super_method != NULL_TREE
2687
	  && ! METHOD_DUMMY (super_method))
2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701
        {
	  method_override = true;
	  if (! METHOD_PUBLIC (super_method) && 
	      ! METHOD_PROTECTED (super_method))
	    {
	      /* Don't override private method, or default-access method in 
		 another package.  */
	      if (METHOD_PRIVATE (super_method) ||
		  ! in_same_package (TYPE_NAME (this_class), 
				     TYPE_NAME (super_class)))
		method_override = false;
	   }
	}
      if (method_override)
2702
	{
2703 2704 2705
	  tree method_index = get_method_index (super_method);
	  set_method_index (method_decl, method_index);
	  if (method_index == NULL_TREE 
2706
	      && ! flag_indirect_dispatch
2707
	      && ! DECL_ARTIFICIAL (super_method))
2708 2709
	    error ("non-static method %q+D overrides static method",
                   method_decl);
2710
	}
2711 2712 2713 2714 2715 2716 2717 2718 2719
      else if (this_class == object_type_node
	       && (METHOD_FINAL (method_decl)
		   || METHOD_PRIVATE (method_decl)))
	{
	  /* We don't generate vtable entries for final Object
	     methods.  This is simply to save space, since every
	     object would otherwise have to define them.  */
	}
      else if (! METHOD_PRIVATE (method_decl)
2720 2721
	       && dtable_count)
	{
2722 2723
	  /* We generate vtable entries for final methods because they
	     may one day be changed to non-final.  */
2724
	  set_method_index (method_decl, dtable_count);
2725 2726
	  dtable_count = fold_build2 (PLUS_EXPR, integer_type_node,
				      dtable_count, integer_one_node);
Anthony Green committed
2727 2728
	}
    }
2729

2730
  return dtable_count;
Anthony Green committed
2731 2732
}

2733
static void
2734
register_class (void)
Anthony Green committed
2735
{
2736 2737
  tree node;

Anthony Green committed
2738
  if (!registered_class)
2739
    vec_alloc (registered_class, 8);
Anthony Green committed
2740

2741 2742 2743 2744
  if (flag_indirect_classes)
    node = current_class;
  else
    node = TREE_OPERAND (build_class_ref (current_class), 0);
2745
  vec_safe_push (registered_class, node);
Anthony Green committed
2746 2747
}

2748 2749
/* Emit a function that calls _Jv_RegisterNewClasses with a list of
   all the classes we have emitted.  */
2750 2751 2752 2753 2754 2755 2756

static void
emit_indirect_register_classes (tree *list_p)
{
  tree klass, t, register_class_fn;
  int i;

2757 2758 2759
  int size = vec_safe_length (registered_class) * 2 + 1;
  vec<constructor_elt, va_gc> *init;
  vec_alloc (init, size);
2760 2761
  tree class_array_type
    = build_prim_array_type (ptr_type_node, size);
2762 2763
  tree cdecl = build_decl (input_location,
			   VAR_DECL, get_identifier ("_Jv_CLS"),
2764 2765
			   class_array_type);
  tree reg_class_list;
2766
  FOR_EACH_VEC_SAFE_ELT (registered_class, i, klass)
2767
    {
2768 2769 2770 2771 2772 2773 2774 2775
      t = fold_convert (ptr_type_node, build_static_class_ref (klass));
      CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, t);
      t = fold_convert (ptr_type_node,
                        build_address_of (build_classdollar_field (klass)));
      CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, t);
    }
  CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, integer_zero_node);
  DECL_INITIAL (cdecl) = build_constructor (class_array_type, init);
2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786
  TREE_CONSTANT (DECL_INITIAL (cdecl)) = 1;
  TREE_STATIC (cdecl) = 1;
  DECL_ARTIFICIAL (cdecl) = 1;
  DECL_IGNORED_P (cdecl) = 1;
  TREE_READONLY (cdecl) = 1;
  TREE_CONSTANT (cdecl) = 1;
  rest_of_decl_compilation (cdecl, 1, 0);
  reg_class_list = fold_convert (ptr_type_node, build_address_of (cdecl));

  t = build_function_type_list (void_type_node, 
				build_pointer_type (ptr_type_node), NULL);
2787 2788
  t = build_decl (input_location,
		  FUNCTION_DECL, 
2789 2790 2791 2792
		  get_identifier ("_Jv_RegisterNewClasses"), t);
  TREE_PUBLIC (t) = 1;
  DECL_EXTERNAL (t) = 1;
  register_class_fn = t;
2793
  t = build_call_expr (register_class_fn, 1, reg_class_list);
2794 2795 2796
  append_to_statement_list (t, list_p);
}

2797 2798 2799 2800 2801
/* Emit a list of pointers to all classes we have emitted to JCR_SECTION.  */

static void
emit_register_classes_in_jcr_section (void)
{
2802
#ifdef JCR_SECTION_NAME
2803 2804
  tree klass, cdecl, class_array_type;
  int i;
2805 2806 2807
  int size = vec_safe_length (registered_class);
  vec<constructor_elt, va_gc> *init;
  vec_alloc (init, size);
2808

2809
  FOR_EACH_VEC_SAFE_ELT (registered_class, i, klass)
2810 2811 2812 2813 2814 2815 2816 2817 2818 2819
    CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, build_fold_addr_expr (klass));

  /* ??? I would like to use tree_output_constant_def() but there is no way
	 to put the data in a named section name, or to set the alignment,
	 via that function.  So do everything manually here.  */
  class_array_type = build_prim_array_type (ptr_type_node, size);
  cdecl = build_decl (UNKNOWN_LOCATION,
		      VAR_DECL, get_identifier ("_Jv_JCR_SECTION_data"),
		      class_array_type);
  DECL_ALIGN (cdecl) = POINTER_SIZE;
Rainer Orth committed
2820
  DECL_USER_ALIGN (cdecl) = 1;
2821 2822 2823
  DECL_INITIAL (cdecl) = build_constructor (class_array_type, init);
  TREE_CONSTANT (DECL_INITIAL (cdecl)) = 1;
  TREE_STATIC (cdecl) = 1;
Rainer Orth committed
2824
  TREE_READONLY (cdecl) = 0;
2825 2826 2827
  TREE_CONSTANT (cdecl) = 1;
  DECL_ARTIFICIAL (cdecl) = 1;
  DECL_IGNORED_P (cdecl) = 1;
2828
  DECL_PRESERVE_P (cdecl) = 1;
2829
  set_decl_section_name (cdecl, JCR_SECTION_NAME);
2830 2831 2832
  pushdecl_top_level (cdecl);
  relayout_decl (cdecl);
  rest_of_decl_compilation (cdecl, 1, 0);
2833 2834 2835 2836 2837
#else
  /* A target has defined TARGET_USE_JCR_SECTION,
     but doesn't have a JCR_SECTION_NAME.  */
  gcc_unreachable ();
#endif
2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856
}


/* Emit a series of calls to _Jv_RegisterClass for every class we emitted.
   A series of calls is added to LIST_P.  */

static void
emit_Jv_RegisterClass_calls (tree *list_p)
{
  tree klass, t, register_class_fn;
  int i;

  t = build_function_type_list (void_type_node, class_ptr_type, NULL);
  t = build_decl (input_location,
		  FUNCTION_DECL, get_identifier ("_Jv_RegisterClass"), t);
  TREE_PUBLIC (t) = 1;
  DECL_EXTERNAL (t) = 1;
  register_class_fn = t;

2857
  FOR_EACH_VEC_SAFE_ELT (registered_class, i, klass)
2858 2859 2860 2861 2862 2863
    {
      t = build_fold_addr_expr (klass);
      t = build_call_expr (register_class_fn, 1, t);
      append_to_statement_list (t, list_p);
    }
}
2864

2865 2866
/* Emit something to register classes at start-up time.

2867 2868 2869
   The default mechanism is to generate instances at run-time.

   An alternative mechanism is through the .jcr section, which contain
2870 2871 2872 2873 2874 2875
   a list of pointers to classes which get registered during constructor
   invocation time.

   The fallback mechanism is to add statements to *LIST_P to call
   _Jv_RegisterClass for each class in this file.  These statements will
   be added to a static constructor function for this translation unit.  */
Anthony Green committed
2876 2877

void
2878
emit_register_classes (tree *list_p)
Anthony Green committed
2879
{
2880 2881 2882
  if (registered_class == NULL)
    return;

2883
  /* By default, generate instances of Class at runtime.  */
2884
  if (flag_indirect_classes)
2885
    emit_indirect_register_classes (list_p);
2886 2887 2888
  /* TARGET_USE_JCR_SECTION defaults to 1 if SUPPORTS_WEAK and
     TARGET_ASM_NAMED_SECTION, else 0.  Some targets meet those conditions
     but lack suitable crtbegin/end objects or linker support.  These
2889
     targets can override the default in tm.h to use the fallback mechanism.  */
2890 2891 2892
  else if (TARGET_USE_JCR_SECTION)
    emit_register_classes_in_jcr_section ();
  /* Use the fallback mechanism.  */
2893
  else
2894
    emit_Jv_RegisterClass_calls (list_p);
Anthony Green committed
2895 2896
}

2897 2898 2899 2900 2901 2902
/* Build a constructor for an entry in the symbol table.  */

static tree
build_symbol_table_entry (tree clname, tree name, tree signature)
{
  tree symbol;
2903
  vec<constructor_elt, va_gc> *v = NULL;
2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914

  START_RECORD_CONSTRUCTOR (v, symbol_type);
  PUSH_FIELD_VALUE (v, "clname", clname);
  PUSH_FIELD_VALUE (v, "name", name);
  PUSH_FIELD_VALUE (v, "signature", signature);
  FINISH_RECORD_CONSTRUCTOR (symbol, v, symbol_type);
  TREE_CONSTANT (symbol) = 1;

  return symbol;
}

2915
/* Make a symbol_type (_Jv_MethodSymbol) node for DECL. */
2916

2917
static tree
2918
build_symbol_entry (tree decl, tree special)
2919
{
2920
  tree clname, name, signature;
2921
  clname = build_utf8_ref (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl))));
2922 2923 2924 2925 2926 2927 2928 2929
  /* ???  Constructors are given the name foo.foo all the way through
     the compiler, but in the method table they're all renamed
     foo.<init>.  So, we have to do the same here unless we want an
     unresolved reference at runtime.  */
  name = build_utf8_ref ((TREE_CODE (decl) == FUNCTION_DECL 
			  && DECL_CONSTRUCTOR_P (decl))
			 ? init_identifier_node
			 : DECL_NAME (decl));
2930
  signature = build_java_signature (TREE_TYPE (decl));
2931 2932 2933
  signature = build_utf8_ref (unmangle_classname 
			      (IDENTIFIER_POINTER (signature),
			       IDENTIFIER_LENGTH (signature)));
2934 2935 2936 2937 2938
  /* SPECIAL is either NULL_TREE or integer_one_node.  We emit
     signature addr+1 if SPECIAL, and this indicates to the runtime
     system that this is a "special" symbol, i.e. one that should
     bypass access controls.  */
  if (special != NULL_TREE)
2939
    signature = fold_build_pointer_plus (signature, special);
2940 2941

  return build_symbol_table_entry (clname, name, signature);
2942 2943
} 

2944
/* Emit a symbol table: used by -findirect-dispatch.  */
2945

2946
tree
2947
emit_symbol_table (tree name, tree the_table,
2948
		   vec<method_entry, va_gc> *decl_table,
2949 2950
                   tree the_syms_decl, tree the_array_element_type,
		   int element_size)
2951
{
2952
  tree table, null_symbol, table_size, the_array_type;
2953 2954
  unsigned index;
  method_entry *e;
2955
  vec<constructor_elt, va_gc> *v = NULL;
2956
  
2957 2958
  /* Only emit a table if this translation unit actually made any
     references via it. */
2959
  if (!decl_table)
2960
    return the_table;
2961 2962

  /* Build a list of _Jv_MethodSymbols for each entry in otable_methods. */
2963
  FOR_EACH_VEC_ELT (*decl_table, index, e)
2964 2965
    CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
			    build_symbol_entry (e->method, e->special));
2966 2967

  /* Terminate the list with a "null" entry. */
2968 2969 2970
  null_symbol = build_symbol_table_entry (null_pointer_node,
                                          null_pointer_node,
                                          null_pointer_node);
2971
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, null_symbol);
2972

2973 2974 2975 2976
  tree symbols_arr_type
    = build_prim_array_type (symbol_type, vec_safe_length (v));

  table = build_constructor (symbols_arr_type, v);
2977 2978

  /* Make it the initial value for otable_syms and emit the decl. */
2979 2980
  TREE_TYPE (the_syms_decl) = symbols_arr_type;
  relayout_decl (the_syms_decl);
2981 2982 2983
  DECL_INITIAL (the_syms_decl) = table;
  DECL_ARTIFICIAL (the_syms_decl) = 1;
  DECL_IGNORED_P (the_syms_decl) = 1;
2984
  rest_of_decl_compilation (the_syms_decl, 1, 0);
2985
  
2986 2987 2988 2989
  /* Now that its size is known, redefine the table as an
     uninitialized static array of INDEX + 1 elements. The extra entry
     is used by the runtime to track whether the table has been
     initialized. */
2990 2991
  table_size 
    = build_index_type (build_int_cst (NULL_TREE, index * element_size + 1));
2992
  the_array_type = build_array_type (the_array_element_type, table_size);
2993 2994
  the_table = build_decl (input_location,
			  VAR_DECL, name, the_array_type);
2995 2996
  TREE_STATIC (the_table) = 1;
  TREE_READONLY (the_table) = 1;  
2997
  rest_of_decl_compilation (the_table, 1, 0);
2998 2999

  return the_table;
3000 3001
}

3002
/* Make an entry for the catch_classes list.  */
3003 3004 3005 3006
tree
make_catch_class_record (tree catch_class, tree classname)
{
  tree entry;
3007
  tree type = TREE_TYPE (TREE_TYPE (TYPE_CTABLE_DECL (output_class)));
3008
  vec<constructor_elt, va_gc> *v = NULL;
3009 3010 3011 3012
  START_RECORD_CONSTRUCTOR (v, type);
  PUSH_FIELD_VALUE (v, "address", catch_class);
  PUSH_FIELD_VALUE (v, "classname", classname);
  FINISH_RECORD_CONSTRUCTOR (entry, v, type);
3013 3014 3015 3016 3017
  return entry;
}


/* Generate the list of Throwable classes that are caught by exception
3018 3019 3020
   handlers in this class.  */
tree 
emit_catch_table (tree this_class)
3021 3022
{
  tree table, table_size, array_type;
3023 3024 3025
  int n_catch_classes;
  constructor_elt *e;
  /* Fill in the dummy entry that make_class created.  */
3026
  e = &(*TYPE_CATCH_CLASSES (this_class))[0];
3027 3028 3029 3030
  e->value = make_catch_class_record (null_pointer_node, null_pointer_node);
  CONSTRUCTOR_APPEND_ELT (TYPE_CATCH_CLASSES (this_class), NULL_TREE,
			  make_catch_class_record (null_pointer_node,
						   null_pointer_node));
3031
  n_catch_classes = TYPE_CATCH_CLASSES (this_class)->length ();
3032
  table_size = build_index_type (build_int_cst (NULL_TREE, n_catch_classes));
3033
  array_type 
3034 3035 3036
    = build_array_type (TREE_TYPE (TREE_TYPE (TYPE_CTABLE_DECL (this_class))),
			table_size);
  table = 
3037 3038
    build_decl (input_location,
		VAR_DECL, DECL_NAME (TYPE_CTABLE_DECL (this_class)), array_type);
3039
  DECL_INITIAL (table) = 
3040
    build_constructor (array_type, TYPE_CATCH_CLASSES (this_class));
3041 3042
  TREE_STATIC (table) = 1;
  TREE_READONLY (table) = 1;  
3043
  DECL_IGNORED_P (table) = 1;
3044
  rest_of_decl_compilation (table, 1, 0);
3045
  return table;
3046
}
3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063

/* Given a type, return the signature used by
   _Jv_FindClassFromSignature() in libgcj.  This isn't exactly the
   same as build_java_signature() because we want the canonical array
   type.  */

static tree
build_signature_for_libgcj (tree type)
{
  tree sig, ref;

  sig = build_java_signature (type);
  ref = build_utf8_ref (unmangle_classname (IDENTIFIER_POINTER (sig),
					    IDENTIFIER_LENGTH (sig)));
  return ref;
}

3064 3065 3066 3067 3068
/* Build an entry in the type assertion table.  */

static tree
build_assertion_table_entry (tree code, tree op1, tree op2)
{
3069
  vec<constructor_elt, va_gc> *v = NULL;
3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080
  tree entry;

  START_RECORD_CONSTRUCTOR (v, assertion_entry_type);
  PUSH_FIELD_VALUE (v, "assertion_code", code);
  PUSH_FIELD_VALUE (v, "op1", op1);
  PUSH_FIELD_VALUE (v, "op2", op2);
  FINISH_RECORD_CONSTRUCTOR (entry, v, assertion_entry_type);

  return entry;
}

3081 3082 3083
/* Add an entry to the type assertion table. Callback used during hashtable
   traversal.  */

3084 3085
int
add_assertion_table_entry (type_assertion **slot, vec<constructor_elt, va_gc> **v)
3086 3087 3088
{
  tree entry;
  tree code_val, op1_utf8, op2_utf8;
3089
  type_assertion *as = *slot;
3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101

  code_val = build_int_cst (NULL_TREE, as->assertion_code);

  if (as->op1 == NULL_TREE)
    op1_utf8 = null_pointer_node;
  else
    op1_utf8 = build_signature_for_libgcj (as->op1);

  if (as->op2 == NULL_TREE)
    op2_utf8 = null_pointer_node;
  else
    op2_utf8 = build_signature_for_libgcj (as->op2);
3102 3103

  entry = build_assertion_table_entry (code_val, op1_utf8, op2_utf8);
3104
  
3105
  CONSTRUCTOR_APPEND_ELT (*v, NULL_TREE, entry);
3106 3107 3108
  return true;
}

3109
/* Generate the type assertion table for KLASS, and return its DECL.  */
3110 3111

static tree
3112
emit_assertion_table (tree klass)
3113 3114
{
  tree null_entry, ctor, table_decl;
3115
  hash_table<type_assertion_hasher> *assertions_htab = TYPE_ASSERTIONS (klass);
3116
  vec<constructor_elt, va_gc> *v = NULL;
3117 3118

  /* Iterate through the hash table.  */
3119 3120
  assertions_htab
    ->traverse<vec<constructor_elt, va_gc> **, add_assertion_table_entry> (&v);
3121 3122

  /* Finish with a null entry.  */
3123 3124 3125
  null_entry = build_assertion_table_entry (integer_zero_node,
                                            null_pointer_node,
                                            null_pointer_node);
3126
  
3127
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, null_entry);
3128 3129 3130

  tree type
    = build_prim_array_type (assertion_entry_type, vec_safe_length (v));
3131
  
3132
  ctor = build_constructor (type, v);
3133

3134 3135
  table_decl = build_decl (input_location,
			   VAR_DECL, mangled_classname ("_type_assert_", klass),
3136
			   type);
3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148

  TREE_STATIC (table_decl) = 1;
  TREE_READONLY (table_decl) = 1;
  TREE_CONSTANT (table_decl) = 1;
  DECL_IGNORED_P (table_decl) = 1;

  DECL_INITIAL (table_decl) = ctor;
  DECL_ARTIFICIAL (table_decl) = 1;
  rest_of_decl_compilation (table_decl, 1, 0);

  return table_decl;
}
3149

Anthony Green committed
3150
void
3151
init_class_processing (void)
Anthony Green committed
3152
{
3153 3154
  fields_ident = get_identifier ("fields");
  info_ident = get_identifier ("info");
3155

Mark Mitchell committed
3156
  gcc_obstack_init (&temporary_obstack);
Anthony Green committed
3157
}
3158 3159 3160

/* A hash table mapping trees to trees.  Used generally.  */

3161
#define JAVA_TREEHASHHASH_H(t) ((hashval_t)TYPE_UID (t))
3162

3163 3164
hashval_t
treetreehasher::hash (treetreehash_entry *k)
3165 3166 3167 3168
{
  return JAVA_TREEHASHHASH_H (k->key);
}

3169 3170
bool
treetreehasher::equal (treetreehash_entry *k1, tree k2)
3171 3172 3173 3174 3175
{
  return (k1->key == k2);
}

tree 
3176
java_treetreehash_find (hash_table<treetreehasher> *ht, tree t)
3177 3178 3179
{
  struct treetreehash_entry *e;
  hashval_t hv = JAVA_TREEHASHHASH_H (t);
3180
  e = ht->find_with_hash (t, hv);
3181 3182 3183 3184 3185 3186 3187
  if (e == NULL)
    return NULL;
  else
    return e->value;
}

tree *
3188
java_treetreehash_new (hash_table<treetreehasher> *ht, tree t)
3189 3190 3191 3192
{
  struct treetreehash_entry *tthe;
  hashval_t hv = JAVA_TREEHASHHASH_H (t);

3193
  treetreehash_entry **e = ht->find_slot_with_hash (t, hv, INSERT);
3194 3195
  if (*e == NULL)
    {
3196
      tthe = ggc_cleared_alloc<treetreehash_entry> ();
3197
      tthe->key = t;
3198
      *e = tthe;
3199 3200
    }
  else
3201
    tthe = *e;
3202 3203 3204
  return &tthe->value;
}

3205
hash_table<treetreehasher> *
3206
java_treetreehash_create (size_t size)
3207
{
3208
  return hash_table<treetreehasher>::create_ggc (size);
3209 3210
}

3211 3212 3213 3214 3215 3216 3217 3218 3219 3220
/* Break down qualified IDENTIFIER into package and class-name components.
   For example, given SOURCE "pkg.foo.Bar", LEFT will be set to
   "pkg.foo", and RIGHT to "Bar". */

int
split_qualified_name (tree *left, tree *right, tree source)
{
  char *p, *base;
  int l = IDENTIFIER_LENGTH (source);

3221
  base = (char *) alloca (l + 1);
3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269
  memcpy (base, IDENTIFIER_POINTER (source), l + 1);

  /* Breakdown NAME into REMAINDER . IDENTIFIER.  */
  p = base + l - 1;
  while (*p != '.' && p != base)
    p--;

  /* We didn't find a '.'. Return an error.  */
  if (p == base)
    return 1;

  *p = '\0';
  if (right)
    *right = get_identifier (p+1);
  *left = get_identifier (base);

  return 0;
}

/* Given two classes (TYPE_DECL) or class names (IDENTIFIER), return TRUE 
   if the classes are from the same package. */

int
in_same_package (tree name1, tree name2)
{
  tree tmp;
  tree pkg1;
  tree pkg2;

  if (TREE_CODE (name1) == TYPE_DECL)
    name1 = DECL_NAME (name1);
  if (TREE_CODE (name2) == TYPE_DECL)
    name2 = DECL_NAME (name2);

  if (QUALIFIED_P (name1) != QUALIFIED_P (name2))
    /* One in empty package. */
    return 0;

  if (QUALIFIED_P (name1) == 0 && QUALIFIED_P (name2) == 0)
    /* Both in empty package. */
    return 1;

  split_qualified_name (&pkg1, &tmp, name1);
  split_qualified_name (&pkg2, &tmp, name2);

  return (pkg1 == pkg2);
}

3270 3271 3272 3273 3274 3275
/* lang_hooks.decls.final_write_globals: perform final processing on
   global variables.  */

void
java_write_globals (void)
{
3276 3277
  tree *vec = vec_safe_address (pending_static_fields);
  int len = vec_safe_length (pending_static_fields);
3278 3279
  write_global_declarations ();
  emit_debug_global_declarations (vec, len);
3280
  vec_free (pending_static_fields);
3281 3282
}

3283
#include "gt-java-class.h"