class.c 97.3 KB
Newer Older
Anthony Green committed
1
/* Functions related to building classes and their related objects.
2
   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3
   2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Anthony Green committed
4

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

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

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

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"
28
#include "system.h"
29 30
#include "coretypes.h"
#include "tm.h"
Anthony Green committed
31 32
#include "tree.h"
#include "rtl.h"
33
#include "flags.h"
Anthony Green committed
34 35 36
#include "java-tree.h"
#include "jcf.h"
#include "obstack.h"
37
#include "toplev.h"
Kaveh R. Ghazi committed
38 39
#include "output.h"
#include "parse.h"
40
#include "function.h"
41
#include "tm_p.h"
42
#include "ggc.h"
43
#include "stdio.h"
44
#include "target.h"
45
#include "except.h"
46
#include "cgraph.h"
47
#include "tree-iterator.h"
Jan Hubicka committed
48
#include "cgraph.h"
49
#include "vecprim.h"
Anthony Green committed
50

51 52 53 54 55
/* DOS brain-damage */
#ifndef O_BINARY
#define O_BINARY 0 /* MS-DOS brain-damage */
#endif

56 57 58 59 60 61
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);
62
static int supers_all_compiled (tree type);
63
static tree maybe_layout_super_class (tree, tree);
64
static void add_miranda_methods (tree, tree);
65
static int assume_compiled (const char *);
66
static tree build_symbol_entry (tree, tree);
67
static tree emit_assertion_table (tree);
68
static void register_class (void);
69

Mark Mitchell committed
70
struct obstack temporary_obstack;
Anthony Green committed
71

72 73
static const char *cyclic_inheritance_report;

74 75 76 77
/* 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
78
   class_flag_node objects.  This tree is queried to determine if
79 80 81
   a class is assume to be compiled or not.  Each node in the tree
   represents either a package or a specific class.  */

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

87
  /* Nonzero if this represents an exclusion.  */
88
  int value;
89 90

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

96 97
static class_flag_node *find_class_flag_node (class_flag_node *, const char *);
static void add_class_flag (class_flag_node **, const char *, int);
98

99 100
/* This is the root of the include/exclude tree.  */

101 102 103
static class_flag_node *assume_compiled_tree;

static class_flag_node *enable_assert_tree;
104

105 106 107 108 109 110 111
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]

static GTY(()) VEC(tree,gc) *registered_class;
112

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

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

121 122
static class_flag_node *
find_class_flag_node (class_flag_node *node, const char *ident)
123 124 125 126 127 128 129 130 131 132 133 134
{
  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
135
	      && (ident[node_ident_length] == '\0'
136 137 138 139 140
		  || ident[node_ident_length] == '.')))
	{
	  /* We've found a match, however, there might be a more
             specific match.  */

141
	  class_flag_node *found = find_class_flag_node (node->child, ident);
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
	  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
157
add_class_flag (class_flag_node **rootp, const char *ident, int value)
158
{
159 160
  class_flag_node *root = *rootp;
  class_flag_node *parent, *node;
161 162 163

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

164
  if (NULL == root)
165
    {
166
      root = XNEW (class_flag_node);
167 168 169 170 171 172
      root->ident = "";
      root->value = 0;
      root->sibling = NULL;
      root->child = NULL;
      root->parent = NULL;
      *rootp = root;
173 174 175
    }

  /* Calling the function with the empty string means we're setting
176
     value for the root of the hierarchy.  */
177 178 179

  if (0 == ident[0])
    {
180
      root->value = value;
181 182 183 184 185 186
      return;
    }

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

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

      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);
}
213

214
/* The default value returned by enable_assertions. */
215

216
#define DEFAULT_ENABLE_ASSERT (optimize == 0)
217 218 219 220 221 222 223 224 225 226

/* 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);
227 228
}

229
/* Returns nonzero if IDENT is the name of a class that the compiler
230
   should assume has been compiled to object code.  */
231

232
static int
233
assume_compiled (const char *ident)
234
{
235
  class_flag_node *i;
236 237 238 239 240
  int result;
  
  if (NULL == assume_compiled_tree)
    return 1;

241
  i = find_class_flag_node (assume_compiled_tree, ident);
242

243
  result = ! i->value;
244 245 246 247
  
  return (result);
}

248 249 250 251 252
/* Return true if we should generate code to check assertions within KLASS. */

bool
enable_assertions (tree klass)
{
253
  /* Check if command-line specifies whether we should check assertions. */
254 255 256 257 258 259 260 261 262 263 264 265 266 267

  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
268 269 270 271 272
/* 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
273 274 275 276 277 278
ident_subst (const char* old_name,
	     int old_length,
	     const char *prefix,
	     int old_char,
	     int new_char,
	     const char *suffix)
Anthony Green committed
279 280 281 282
{
  int prefix_len = strlen (prefix);
  int suffix_len = strlen (suffix);
  int i = prefix_len + old_length + suffix_len + 1;
283
  char *buffer = (char *) alloca (i);
284

Anthony Green committed
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
  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
302 303 304 305 306
identifier_subst (const tree old_id,
		  const char *prefix,
		  int old_char,
		  int new_char,
		  const char *suffix)
Anthony Green committed
307 308 309 310 311 312 313 314 315
{
  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
316
mangled_classname (const char *prefix, tree type)
Anthony Green committed
317
{
318
  tree result;
Anthony Green committed
319 320 321
  tree ident = TYPE_NAME (type);
  if (TREE_CODE (ident) != IDENTIFIER_NODE)
    ident = DECL_NAME (ident);
322 323 324 325 326 327 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
  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)
      {
353
	char *buffer = (char *) alloca (illegal_chars * 4 + len + 1);
354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374
	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
375 376 377
}

tree
378
make_class (void)
Anthony Green committed
379 380 381
{
  tree type;
  type = make_node (RECORD_TYPE);
382 383 384
  /* Unfortunately we must create the binfo here, so that class
     loading works.  */
  TYPE_BINFO (type) = make_tree_binfo (0);
385
  MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC (type);
Anthony Green committed
386 387 388 389 390 391 392 393 394

  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
395
unmangle_classname (const char *name, int name_length)
Anthony Green committed
396
{
397
  tree to_return = ident_subst (name, name_length, "", '/', '.', "");
398 399 400 401 402 403 404 405 406 407 408 409
  /* 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;
      }
  
410
  return to_return;
Anthony Green committed
411 412
}

413 414 415
#define GEN_TABLE(TABLE, NAME, TABLE_TYPE, TYPE)			\
do									\
{									\
416 417 418
  const char *type_name = IDENTIFIER_POINTER (mangled_classname ("", TYPE)); \
  char *buf = (char *) alloca (strlen (type_name)			\
                               + strlen (#NAME "_syms_") + 1);		\
419 420
  tree decl;								\
									\
421
  sprintf (buf, #NAME "_%s", type_name);				\
422
  TYPE_## TABLE ##_DECL (type) = decl =					\
423
    build_decl (input_location, VAR_DECL, get_identifier (buf), TABLE_TYPE); \
424 425 426 427 428 429 430 431 432
  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;						\
433
  sprintf (buf, #NAME "_syms_%s", type_name);				\
434
  TYPE_## TABLE ##_SYMS_DECL (TYPE) =					\
435
    build_decl (input_location, VAR_DECL, get_identifier (buf), symbols_array_type); \
436 437 438 439 440
  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)
441

Ranjit Mathew committed
442 443
/* Given a class, create the DECLs for all its associated indirect
   dispatch tables.  */
444 445 446
void
gen_indirect_dispatch_tables (tree type)
{
447
  const char *type_name = IDENTIFIER_POINTER (mangled_classname ("", type));
448 449
  {  
    tree field = NULL;
450 451
    char *buf = (char *) alloca (strlen (type_name)
				 + strlen ("_catch_classes_") + 1);
452 453
    tree catch_class_type = make_node (RECORD_TYPE);

454
    sprintf (buf, "_catch_classes_%s", type_name);
455 456 457 458
    PUSH_FIELD (input_location,
		catch_class_type, field, "address", utf8const_ptr_type);
    PUSH_FIELD (input_location,
		catch_class_type, field, "classname", ptr_type_node);
459 460 461
    FINISH_RECORD (catch_class_type);
    
    TYPE_CTABLE_DECL (type) 
462
      = build_decl (input_location, VAR_DECL, get_identifier (buf),
463 464 465 466 467 468 469 470 471 472 473
		    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)
    {
474 475 476
      GEN_TABLE (ATABLE, _atable, atable_type, type);
      GEN_TABLE (OTABLE, _otable, otable_type, type);
      GEN_TABLE (ITABLE, _itable, itable_type, type);
477 478 479
    }
}

480 481
#undef GEN_TABLE

Anthony Green committed
482
tree
483
push_class (tree class_type, tree class_name)
Anthony Green committed
484 485
{
  tree decl, signature;
486
  location_t saved_loc = input_location;
487
  CLASS_P (class_type) = 1;
488
  decl = build_decl (input_location, TYPE_DECL, class_name, class_type);
489
  TYPE_DECL_SUPPRESS_DEBUG (decl) = 1;
490 491 492 493

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

494
  input_location = saved_loc;
Anthony Green committed
495
  signature = identifier_subst (class_name, "L", '.', '/', ";");
Per Bothner committed
496
  IDENTIFIER_SIGNATURE_TYPE (signature) = build_pointer_type (class_type);
Anthony Green committed
497

498
  /* Setting DECL_ARTIFICIAL forces dbxout.c to specific the type is
Anthony Green committed
499 500 501 502 503 504 505 506 507 508 509 510 511 512 513
     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
514
lookup_class (tree name)
Anthony Green committed
515 516 517 518 519 520 521 522
{
  tree decl = IDENTIFIER_CLASS_VALUE (name);
  if (decl == NULL_TREE)
    decl = push_class (make_class (), name);
  return TREE_TYPE (decl);
}

void
523 524
set_super_info (int access_flags, tree this_class,
		tree super_class, int interfaces_count)
Anthony Green committed
525 526 527
{
  int total_supers = interfaces_count;
  tree class_decl = TYPE_NAME (this_class);
528
  
Anthony Green committed
529 530 531
  if (super_class)
    total_supers++;

532 533
  if (total_supers)
    TYPE_BINFO (this_class) = make_tree_binfo (total_supers);
534
  TYPE_VFIELD (this_class) = TYPE_VFIELD (object_type_node);
Anthony Green committed
535 536
  if (super_class)
    {
537
      tree super_binfo = make_tree_binfo (0);
Anthony Green committed
538 539
      BINFO_TYPE (super_binfo) = super_class;
      BINFO_OFFSET (super_binfo) = integer_zero_node;
Nathan Sidwell committed
540
      BINFO_BASE_APPEND (TYPE_BINFO (this_class), super_binfo);
541
      CLASS_HAS_SUPER_FLAG (TYPE_BINFO (this_class)) = 1;
Anthony Green committed
542
    }
543

544 545 546 547
  set_class_decl_access_flags (access_flags, class_decl);
}

void
548
set_class_decl_access_flags (int access_flags, tree class_decl)
549
{
Anthony Green committed
550 551 552 553 554
  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;
555
  if (access_flags & ACC_STATIC)    CLASS_STATIC (class_decl) = 1;
556
  if (access_flags & ACC_PRIVATE)   CLASS_PRIVATE (class_decl) = 1;
557
  if (access_flags & ACC_PROTECTED) CLASS_PROTECTED (class_decl) = 1;
558
  if (access_flags & ACC_STRICT)    CLASS_STRICTFP (class_decl) = 1;
559 560 561
  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
562 563 564 565 566 567
}

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

int
568
class_depth (tree clas)
Anthony Green committed
569 570 571 572
{
  int depth = 0;
  if (! CLASS_LOADED_P (clas))
    load_class (clas, 1);
573 574
  if (TYPE_SIZE (clas) == error_mark_node)
    return -1;
Anthony Green committed
575 576 577
  while (clas != object_type_node)
    {
      depth++;
578
      clas = BINFO_TYPE (BINFO_BASE_BINFO (TYPE_BINFO (clas), 0));
Anthony Green committed
579 580 581 582 583 584 585
    }
  return depth;
}

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

int
586
interface_of_p (tree type1, tree type2)
Anthony Green committed
587
{
Nathan Sidwell committed
588 589
  int i;
  tree binfo, base_binfo;
Anthony Green committed
590

591
  if (! TYPE_BINFO (type2))
Anthony Green committed
592
    return 0;
Nathan Sidwell committed
593 594 595 596 597 598 599 600 601 602 603 604

  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
605 606 607 608 609 610
  return 0;
}

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

int
611
inherits_from_p (tree type1, tree type2)
Anthony Green committed
612 613 614 615 616
{
  while (type1 != NULL_TREE && TREE_CODE (type1) == RECORD_TYPE)
    {
      if (type1 == type2)
	return 1;
617

618 619
      if (! CLASS_LOADED_P (type1))
	load_class (type1, 1);
620 621

      type1 = maybe_layout_super_class (CLASSTYPE_SUPER (type1), type1);
Anthony Green committed
622 623 624 625
    }
  return 0;
}

626 627 628
/* Return a 1 iff TYPE1 is an enclosing context for TYPE2 */

int
629
enclosing_context_p (tree type1, tree type2)
630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645
{
  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;
}

646 647 648

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

Ranjit Mathew committed
650 651
int
common_enclosing_context_p (tree type1, tree type2)
652
{
653
  while (type1)
654 655 656 657 658 659 660 661
    {
      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;
662 663 664 665 666

      if (INNER_CLASS_TYPE_P (type1))
        type1 = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type1)));
      else
        break;
667 668 669 670 671 672 673 674 675 676
    }
  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)
{
677
  if (!PURE_INNER_CLASS_TYPE_P (type1) || !PURE_INNER_CLASS_TYPE_P (type2))
678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694
    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
695 696 697 698 699
/* 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
700
maybe_add_interface (tree this_class, tree interface_class)
Anthony Green committed
701
{
Nathan Sidwell committed
702
  tree binfo, base_binfo;
Anthony Green committed
703
  int i;
Nathan Sidwell committed
704 705 706 707 708 709

  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
710 711 712 713 714 715
  return NULL_TREE;
}

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

void
716
add_interface (tree this_class, tree interface_class)
Anthony Green committed
717
{
Nathan Sidwell committed
718 719 720 721 722 723 724 725
  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
726 727
}

728
static tree
729
build_java_method_type (tree fntype, tree this_class, int access_flags)
Anthony Green committed
730 731 732
{
  if (access_flags & ACC_STATIC)
    return fntype;
733 734 735 736 737 738 739 740 741 742 743
  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
744 745
}

746 747
void
java_hide_decl (tree decl ATTRIBUTE_UNUSED)
748
{
749
#ifdef HAVE_GAS_HIDDEN
750 751
  DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
  DECL_VISIBILITY_SPECIFIED (decl) = 1;
752
#endif
753 754
}

Anthony Green committed
755
tree
756
add_method_1 (tree this_class, int access_flags, tree name, tree function_type)
Anthony Green committed
757 758 759 760
{
  tree method_type, fndecl;

  method_type = build_java_method_type (function_type,
761
					this_class, access_flags);
Anthony Green committed
762

763
  fndecl = build_decl (input_location, FUNCTION_DECL, name, method_type);
764
  DECL_CONTEXT (fndecl) = this_class;
Anthony Green committed
765 766

  DECL_LANG_SPECIFIC (fndecl)
767
    = GGC_CNEW (struct lang_decl);
768
  DECL_LANG_SPECIFIC (fndecl)->desc = LANG_DECL_FUNC;
Anthony Green committed
769

770
  /* Initialize the static initializer test table.  */
771 772 773
  
  DECL_FUNCTION_INIT_TEST_TABLE (fndecl) = 
    java_treetreehash_create (10, 1);
774

775 776
  /* Initialize the initialized (static) class table. */
  if (access_flags & ACC_STATIC)
777 778
    DECL_FUNCTION_INITIALIZED_CLASS_TABLE (fndecl) =
      htab_create_ggc (50, htab_hash_pointer, htab_eq_pointer, NULL);
779

780 781
  TREE_CHAIN (fndecl) = TYPE_METHODS (this_class);
  TYPE_METHODS (this_class) = fndecl;
Anthony Green committed
782

783 784 785 786 787 788 789 790
  /* 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;

791 792 793 794 795
  /* 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)
796
    HAS_FINALIZER_P (this_class) = 1;
797

Anthony Green committed
798 799
  if (access_flags & ACC_PUBLIC) METHOD_PUBLIC (fndecl) = 1;
  if (access_flags & ACC_PROTECTED) METHOD_PROTECTED (fndecl) = 1;
800
  if (access_flags & ACC_PRIVATE)
801
    METHOD_PRIVATE (fndecl) = 1;
802 803 804 805 806
  if (access_flags & ACC_NATIVE)
    {
      METHOD_NATIVE (fndecl) = 1;
      DECL_EXTERNAL (fndecl) = 1;
    }
807 808 809 810
  else
    /* FNDECL is external unless we are compiling it into this object
       file.  */
    DECL_EXTERNAL (fndecl) = CLASS_FROM_CURRENTLY_COMPILED_P (this_class) == 0;
811
  if (access_flags & ACC_STATIC) 
812
    METHOD_STATIC (fndecl) = 1;
813
  if (access_flags & ACC_FINAL) 
814
    METHOD_FINAL (fndecl) = 1;
Anthony Green committed
815 816
  if (access_flags & ACC_SYNCHRONIZED) METHOD_SYNCHRONIZED (fndecl) = 1;
  if (access_flags & ACC_ABSTRACT) METHOD_ABSTRACT (fndecl) = 1;
817
  if (access_flags & ACC_STRICT) METHOD_STRICTFP (fndecl) = 1;
818 819 820
  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
821 822 823 824 825 826 827 828
  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
829
add_method (tree this_class, int access_flags, tree name, tree method_sig)
Anthony Green committed
830
{
831
  tree function_type, fndecl;
832 833 834
  const unsigned char *sig
    = (const unsigned char *) IDENTIFIER_POINTER (method_sig);

Anthony Green committed
835
  if (sig[0] != '(')
836 837
    fatal_error ("bad method signature");

Anthony Green committed
838
  function_type = get_type_from_signature (method_sig);
839
  fndecl = add_method_1 (this_class, access_flags, name, function_type);
Anthony Green committed
840 841 842 843 844
  set_java_signature (TREE_TYPE (fndecl), method_sig);
  return fndecl;
}

tree
845
add_field (tree klass, tree name, tree field_type, int flags)
Anthony Green committed
846 847 848
{
  int is_static = (flags & ACC_STATIC) != 0;
  tree field;
849 850
  field = build_decl (input_location,
		      is_static ? VAR_DECL : FIELD_DECL, name, field_type);
851 852 853
  TREE_CHAIN (field) = TYPE_FIELDS (klass);
  TYPE_FIELDS (klass) = field;
  DECL_CONTEXT (field) = klass;
854
  MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (field);
Anthony Green committed
855 856 857 858 859

  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;
860 861 862 863 864
  if (flags & ACC_VOLATILE) 
    {
      FIELD_VOLATILE (field) = 1;
      TREE_THIS_VOLATILE (field) = 1;
    }
Anthony Green committed
865
  if (flags & ACC_TRANSIENT) FIELD_TRANSIENT (field) = 1;
866 867
  if (flags & ACC_ENUM) FIELD_ENUM (field) = 1;
  if (flags & ACC_SYNTHETIC) FIELD_SYNTHETIC (field) = 1;
Anthony Green committed
868 869 870
  if (is_static)
    {
      FIELD_STATIC (field) = 1;
Per Bothner committed
871 872 873
      /* Always make field externally visible.  This is required so
	 that native methods can always access the field.  */
      TREE_PUBLIC (field) = 1;
874 875 876
      /* Hide everything that shouldn't be visible outside a DSO.  */
      if (flag_indirect_classes
	  || (FIELD_PRIVATE (field)))
877
	java_hide_decl (field);
878 879
      /* Considered external unless we are compiling it into this
	 object file.  */
880
      DECL_EXTERNAL (field) = (is_compiled_class (klass) != 2);
Anthony Green committed
881
    }
882

Anthony Green committed
883 884 885 886 887 888
  return field;
}

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

void
889
set_constant_value (tree field, tree constant)
Anthony Green committed
890 891
{
  if (field == NULL_TREE)
892 893
    warning (OPT_Wattributes,
	     "misplaced ConstantValue attribute (not in any field)");
Anthony Green committed
894
  else if (DECL_INITIAL (field) != NULL_TREE)
895 896
    warning (OPT_Wattributes,
	     "duplicate ConstantValue attribute for field '%s'",
Anthony Green committed
897 898
	     IDENTIFIER_POINTER (DECL_NAME (field)));
  else
899 900
    {
      DECL_INITIAL (field) = constant;
901 902 903
      if (TREE_TYPE (constant) != TREE_TYPE (field)
	  && ! (TREE_TYPE (constant) == int_type_node
		&& INTEGRAL_TYPE_P (TREE_TYPE (field))
904 905 906 907
		&& 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",
908
	       IDENTIFIER_POINTER (DECL_NAME (field)));
909
    }
Anthony Green committed
910 911 912 913 914 915
}

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

916
static int32
917
hashUtf8String (const char *str, int len)
Anthony Green committed
918
{
919 920
  const unsigned char* ptr = (const unsigned char*) str;
  const unsigned char *limit = ptr + len;
Anthony Green committed
921 922 923 924 925 926 927 928 929 930 931
  int32 hash = 0;
  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;
}

932
static GTY(()) tree utf8_decl_list = NULL_TREE;
Anthony Green committed
933 934

tree
935
build_utf8_ref (tree name)
Anthony Green committed
936
{
937 938
  const char * name_ptr = IDENTIFIER_POINTER (name);
  int name_len = IDENTIFIER_LENGTH (name), name_pad;
Anthony Green committed
939
  char buf[60];
Kaveh R. Ghazi committed
940
  tree ctype, field = NULL_TREE, str_type, cinit, string;
Anthony Green committed
941
  static int utf8_count = 0;
942
  int name_hash;
Anthony Green committed
943 944 945 946 947 948
  tree ref = IDENTIFIER_UTF8_REF (name);
  tree decl;
  if (ref != NULL_TREE)
    return ref;

  ctype = make_node (RECORD_TYPE);
949 950 951
  /* '\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
952
  str_type = build_prim_array_type (unsigned_byte_type_node,
953
				    name_len + name_pad);
954 955 956 957
  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
958 959
  FINISH_RECORD (ctype);
  START_RECORD_CONSTRUCTOR (cinit, ctype);
960
  name_hash = hashUtf8String (name_ptr, name_len) & 0xFFFF;
961 962
  PUSH_FIELD_VALUE (cinit, "hash", build_int_cst (NULL_TREE, name_hash));
  PUSH_FIELD_VALUE (cinit, "length", build_int_cst (NULL_TREE, name_len));
963
  string = build_string (name_len, name_ptr);
Anthony Green committed
964 965 966
  TREE_TYPE (string) = str_type;
  PUSH_FIELD_VALUE (cinit, "data", string);
  FINISH_RECORD_CONSTRUCTOR (cinit);
Anthony Green committed
967
  TREE_CONSTANT (cinit) = 1;
Anthony Green committed
968

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

972 973
  decl = build_decl (input_location,
		     VAR_DECL, get_identifier (buf), utf8const_type);
Anthony Green committed
974 975 976 977
  TREE_STATIC (decl) = 1;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_IGNORED_P (decl) = 1;
  TREE_READONLY (decl) = 1;
Anthony Green committed
978
  TREE_THIS_VOLATILE (decl) = 0;
Anthony Green committed
979
  DECL_INITIAL (decl) = cinit;
980 981 982 983 984

  if (HAVE_GAS_SHF_MERGE)
    {
      int decl_size;
      /* Ensure decl_size is a multiple of utf8const_type's alignment. */
985
      decl_size = name_len + 4 + name_pad;
986 987 988 989 990 991
      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);
992
	  switch_to_section (get_section (buf, flags, NULL));
993 994 995 996
	  DECL_SECTION_NAME (decl) = build_string (strlen (buf), buf);
	}
    }

Anthony Green committed
997 998
  TREE_CHAIN (decl) = utf8_decl_list;
  layout_decl (decl, 0);
999 1000
  DECL_SIZE (decl) = TYPE_SIZE (ctype);
  DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (ctype);
Anthony Green committed
1001
  pushdecl (decl);
1002
  rest_of_decl_compilation (decl, global_bindings_p (), 0);
1003
  varpool_mark_needed_node (varpool_node (decl));
Anthony Green committed
1004 1005 1006 1007 1008 1009
  utf8_decl_list = decl;
  ref = build1 (ADDR_EXPR, utf8const_ptr_type, decl);
  IDENTIFIER_UTF8_REF (name) = ref;
  return ref;
}

1010 1011 1012 1013 1014 1015 1016 1017 1018 1019
/* 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); 
1020
  return convert (promote_type (class_ptr_type), cl);
1021 1022
}

1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034
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)
    {
1035
      decl = build_decl (input_location, VAR_DECL, decl_name, class_type_node);
1036 1037
      TREE_STATIC (decl) = 1;
      if (! flag_indirect_classes)
1038 1039 1040
	{
	  TREE_PUBLIC (decl) = 1;
	  if (CLASS_PRIVATE (TYPE_NAME (type)))
1041
	    java_hide_decl (decl);
1042
	}
1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069
      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 
1070 1071
	= build_decl (input_location,
		      VAR_DECL, decl_name, 
1072 1073 1074 1075 1076 1077 1078 1079 1080
		      (build_type_variant 
		       (build_pointer_type 
			(build_type_variant (class_type_node, 
					     /* const */ 1, 0)),
			/* const */ 1, 0)));
      TREE_STATIC (decl) = 1;
      TREE_CONSTANT (decl) = 1;
      TREE_READONLY (decl) = 1;
      TREE_PUBLIC (decl) = 1;
1081
      java_hide_decl (decl);
1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092
      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;
}

1093
/* Create a local variable that holds the current class$.  */
1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105

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);

1106 1107
      this_classdollar = build_decl (input_location,
				     VAR_DECL, NULL_TREE, 
1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124
				     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))))
    {
1125 1126
      tree init = build_call_expr (soft_initclass_node, 1,
				   this_classdollar);
1127 1128 1129 1130
      java_add_stmt (init);
    }
}

1131 1132 1133 1134 1135 1136 1137 1138 1139
/* 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
1140 1141 1142 1143
/* Build a reference to the class TYPE.
   Also handles primitive types and array types. */

tree
1144
build_class_ref (tree type)
Anthony Green committed
1145 1146 1147 1148
{
  int is_compiled = is_compiled_class (type);
  if (is_compiled)
    {
1149
      tree ref, decl;
Anthony Green committed
1150 1151
      if (TREE_CODE (type) == POINTER_TYPE)
	type = TREE_TYPE (type);
1152

1153 1154 1155
      if (flag_indirect_dispatch
	  && type != output_class
	  && TREE_CODE (type) == RECORD_TYPE)
1156 1157
	return build_indirect_class_ref (type);

1158
      if (type == output_class && flag_indirect_classes)
1159 1160 1161 1162 1163 1164 1165
	{
	  /* 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;
	}
1166
      
Anthony Green committed
1167
      if (TREE_CODE (type) == RECORD_TYPE)
1168
	return build_static_class_ref (type);
Anthony Green committed
1169 1170
      else
	{
1171
	  const char *name;
1172
	  tree decl_name;
1173
	  char buffer[25];
Anthony Green committed
1174 1175 1176 1177 1178 1179
	  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;
1180
	  sprintf (buffer, "_Jv_%sClass", name);
Anthony Green committed
1181 1182 1183 1184
	  decl_name = get_identifier (buffer);
	  decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
	  if (decl == NULL_TREE)
	    {
1185 1186
	      decl = build_decl (input_location,
				 VAR_DECL, decl_name, class_type_node);
Anthony Green committed
1187 1188
	      TREE_STATIC (decl) = 1;
	      TREE_PUBLIC (decl) = 1;
1189
	      DECL_EXTERNAL (decl) = 1;
1190
	      DECL_ARTIFICIAL (decl) = 1;
Anthony Green committed
1191 1192 1193 1194 1195 1196 1197 1198
	      pushdecl_top_level (decl);
	    }
	}

      ref = build1 (ADDR_EXPR, class_ptr_type, decl);
      return ref;
    }
  else
1199
    return build_indirect_class_ref (type);
Anthony Green committed
1200 1201
}

1202 1203 1204 1205 1206 1207 1208 1209
/* 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));
1210
  char *buf = (char *) alloca (strlen (name) + 20);
1211 1212 1213 1214 1215
  sprintf (buf, "%s_%d_ref", name, index);
  decl_name = get_identifier (buf);
  decl = IDENTIFIER_GLOBAL_VALUE (decl_name);
  if (decl == NULL_TREE)
    {
1216 1217
      decl = build_decl (input_location,
			 VAR_DECL, decl_name, ptr_type_node);
1218 1219 1220 1221
      TREE_STATIC (decl) = 1;
      TREE_PUBLIC (decl) = 0;
      DECL_EXTERNAL (decl) = 0;
      DECL_ARTIFICIAL (decl) = 1;
1222
      DECL_IGNORED_P (decl) = 1;
1223 1224 1225 1226 1227
      pushdecl_top_level (decl);
    }
  return decl;
}

Anthony Green committed
1228
tree
1229
build_static_field_ref (tree fdecl)
Anthony Green committed
1230 1231 1232
{
  tree fclass = DECL_CONTEXT (fdecl);
  int is_compiled = is_compiled_class (fclass);
1233

1234
  /* Allow static final fields to fold to a constant.  When using
1235 1236 1237
     -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.  */
1238
  if (!flag_indirect_dispatch
1239 1240 1241 1242 1243
      && (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
1244
    {
1245 1246
      if (is_compiled == 1)
	DECL_EXTERNAL (fdecl) = 1;
1247
    }
1248
  else
Anthony Green committed
1249
    {
1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267
      /* 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);
1268 1269 1270 1271 1272
      tree test
        = build_call_expr (built_in_decls[BUILT_IN_EXPECT], 2,
			   build2 (EQ_EXPR, boolean_type_node,
				   cache_entry, null_pointer_node),
			   boolean_false_node);
1273 1274
      tree cpool_index_cst = build_int_cst (NULL_TREE, cpool_index);
      tree init
1275 1276 1277
	= build_call_expr (soft_resolvepoolentry_node, 2,
			   build_class_ref (output_class),
			   cpool_index_cst);
1278 1279 1280 1281
      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
1282
    }
1283
  return fdecl;
Anthony Green committed
1284 1285 1286
}

int
1287
get_access_flags_from_decl (tree decl)
Anthony Green committed
1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305
{
  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;
1306 1307 1308 1309
      if (FIELD_ENUM (decl))
	access_flags |= ACC_ENUM;
      if (FIELD_SYNTHETIC (decl))
	access_flags |= ACC_SYNTHETIC;
Anthony Green committed
1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323
      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;
1324 1325
      if (CLASS_STATIC (decl))
	access_flags |= ACC_STATIC;
1326 1327 1328 1329
      if (CLASS_PRIVATE (decl))
	access_flags |= ACC_PRIVATE;
      if (CLASS_PROTECTED (decl))
	access_flags |= ACC_PROTECTED;
1330 1331
      if (CLASS_STRICTFP (decl))
	access_flags |= ACC_STRICT;
1332 1333 1334 1335 1336 1337
      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
1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357
      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;
1358 1359
      if (METHOD_STRICTFP (decl))
	access_flags |= ACC_STRICT;
1360 1361
      if (METHOD_INVISIBLE (decl))
	access_flags |= ACC_INVISIBLE;
1362 1363 1364 1365 1366 1367
      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
1368 1369
      return access_flags;
    }
1370
  gcc_unreachable ();
Anthony Green committed
1371 1372
}

1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385
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));
1386 1387
  char *name = (char *) alloca (strlen (method_name) + 2);
  char *buf = (char *) alloca (strlen (method_name) + 128);
1388 1389 1390 1391 1392 1393 1394 1395 1396 1397

  /* 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);

  ASM_GENERATE_INTERNAL_LABEL (buf, name, alias_labelno++);  
1398 1399
  alias = build_decl (input_location,
		      FUNCTION_DECL, get_identifier (buf),
1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418
		      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;
  TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (alias)) = 1;
  if (!flag_syntax_only)
    assemble_alias (alias, DECL_ASSEMBLER_NAME (method));
  return alias;
#else
  return method;
#endif
}

1419 1420
/** Make reflection data (_Jv_Field) for field FDECL. */

1421
static tree
1422
make_field_value (tree fdecl)
Anthony Green committed
1423
{
1424
  tree finit;
1425
  int flags;
Anthony Green committed
1426
  tree type = TREE_TYPE (fdecl);
1427
  int resolved = is_compiled_class (type) && ! flag_indirect_dispatch;
1428

Anthony Green committed
1429 1430 1431 1432 1433
  START_RECORD_CONSTRUCTOR (finit, field_type_node);
  PUSH_FIELD_VALUE (finit, "name", build_utf8_ref (DECL_NAME (fdecl)));
  if (resolved)
    type = build_class_ref (type);
  else
1434 1435
    {
      tree signature = build_java_signature (type);
1436

1437
      type = build_utf8_ref (unmangle_classname 
1438 1439
			     (IDENTIFIER_POINTER (signature),
			      IDENTIFIER_LENGTH (signature)));
1440
    }
Anthony Green committed
1441
  PUSH_FIELD_VALUE (finit, "type", type);
1442

Anthony Green committed
1443 1444 1445
  flags = get_access_flags_from_decl (fdecl);
  if (! resolved)
    flags |= 0x8000 /* FIELD_UNRESOLVED_FLAG */;
1446

1447
  PUSH_FIELD_VALUE (finit, "accflags", build_int_cst (NULL_TREE, flags));
1448 1449
  PUSH_FIELD_VALUE (finit, "bsize", TYPE_SIZE_UNIT (TREE_TYPE (fdecl)));

1450 1451
  {
    tree field_address = integer_zero_node;
Andrew Haley committed
1452 1453
    if ((DECL_INITIAL (fdecl) || ! flag_indirect_classes) 
	&& FIELD_STATIC (fdecl))
1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466
      field_address = build_address_of (fdecl);

    PUSH_FIELD_VALUE
      (finit, "info",
       build_constructor_from_list (field_info_union_node,
	 build_tree_list
	   ((FIELD_STATIC (fdecl)
	     ? TREE_CHAIN (TYPE_FIELDS (field_info_union_node))
	     : TYPE_FIELDS (field_info_union_node)),
	    (FIELD_STATIC (fdecl)
	     ? field_address
	     : byte_position (fdecl)))));
  }
Anthony Green committed
1467 1468 1469 1470 1471

  FINISH_RECORD_CONSTRUCTOR (finit);
  return finit;
}

1472 1473
/** Make reflection data (_Jv_Method) for method MDECL. */

1474
static tree
1475
make_method_value (tree mdecl)
Anthony Green committed
1476
{
1477
  static int method_name_count = 0;
Anthony Green committed
1478
  tree minit;
1479
  tree index;
Anthony Green committed
1480
  tree code;
Bryce McKinlay committed
1481
  tree class_decl;
Anthony Green committed
1482 1483
#define ACC_TRANSLATED          0x4000
  int accflags = get_access_flags_from_decl (mdecl) | ACC_TRANSLATED;
1484

Bryce McKinlay committed
1485 1486 1487
  class_decl = DECL_CONTEXT (mdecl);
  /* For interfaces, the index field contains the dispatch index. */
  if (CLASS_INTERFACE (TYPE_NAME (class_decl)))
1488
    index = build_int_cst (NULL_TREE,
1489
			   get_interface_method_index (mdecl, class_decl));
1490 1491
  else if (!flag_indirect_dispatch && get_method_index (mdecl) != NULL_TREE)
    index = get_method_index (mdecl);
1492 1493 1494
  else
    index = integer_minus_one_node;

Anthony Green committed
1495
  code = null_pointer_node;
1496 1497 1498 1499
  if (METHOD_ABSTRACT (mdecl))
    code = build1 (ADDR_EXPR, nativecode_ptr_type_node,
		   soft_abstractmethod_node);
  else
1500 1501
    code = build1 (ADDR_EXPR, nativecode_ptr_type_node, 
		   make_local_function_alias (mdecl));
Anthony Green committed
1502 1503 1504 1505 1506
  START_RECORD_CONSTRUCTOR (minit, method_type_node);
  PUSH_FIELD_VALUE (minit, "name",
		    build_utf8_ref (DECL_CONSTRUCTOR_P (mdecl) ?
				    init_identifier_node
				    : DECL_NAME (mdecl)));
1507 1508 1509 1510 1511 1512 1513 1514
  {
    tree signature = build_java_signature (TREE_TYPE (mdecl));
    PUSH_FIELD_VALUE (minit, "signature", 
		      (build_utf8_ref 
		       (unmangle_classname 
			(IDENTIFIER_POINTER(signature),
			 IDENTIFIER_LENGTH(signature)))));
  }
1515
  PUSH_FIELD_VALUE (minit, "accflags", build_int_cst (NULL_TREE, accflags));
1516
  PUSH_FIELD_VALUE (minit, "index", index);
Anthony Green committed
1517
  PUSH_FIELD_VALUE (minit, "ncode", code);
1518 1519 1520

  {
    /* Compute the `throws' information for the method.  */
1521
    tree table = null_pointer_node;
1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532
    if (DECL_FUNCTION_THROWS (mdecl) != NULL_TREE)
      {
	int length = 1 + list_length (DECL_FUNCTION_THROWS (mdecl));
	tree iter, type, array;
	char buf[60];

	table = tree_cons (NULL_TREE, table, NULL_TREE);
	for (iter = DECL_FUNCTION_THROWS (mdecl);
	     iter != NULL_TREE;
	     iter = TREE_CHAIN (iter))
	  {
1533
	    tree sig = DECL_NAME (TYPE_NAME (TREE_VALUE (iter)));
1534 1535 1536 1537 1538 1539
	    tree utf8
	      = build_utf8_ref (unmangle_classname (IDENTIFIER_POINTER (sig),
						    IDENTIFIER_LENGTH (sig)));
	    table = tree_cons (NULL_TREE, utf8, table);
	  }
	type = build_prim_array_type (ptr_type_node, length);
1540
	table = build_constructor_from_list (type, table);
1541 1542
	/* Compute something unique enough.  */
	sprintf (buf, "_methods%d", method_name_count++);
1543 1544
	array = build_decl (input_location,
			    VAR_DECL, get_identifier (buf), type);
1545 1546 1547 1548
	DECL_INITIAL (array) = table;
	TREE_STATIC (array) = 1;
	DECL_ARTIFICIAL (array) = 1;
	DECL_IGNORED_P (array) = 1;
1549
	rest_of_decl_compilation (array, 1, 0);
1550 1551 1552 1553 1554 1555 1556

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

    PUSH_FIELD_VALUE (minit, "throws", table);
  }

Anthony Green committed
1557 1558 1559 1560
  FINISH_RECORD_CONSTRUCTOR (minit);
  return minit;
}

1561
static tree
1562
get_dispatch_vector (tree type)
Anthony Green committed
1563 1564
{
  tree vtable = TYPE_VTABLE (type);
1565 1566

  if (vtable == NULL_TREE)
Anthony Green committed
1567
    {
1568
      HOST_WIDE_INT i;
Anthony Green committed
1569 1570
      tree method;
      tree super = CLASSTYPE_SUPER (type);
1571
      HOST_WIDE_INT nvirtuals = tree_low_cst (TYPE_NVIRTUALS (type), 0);
Anthony Green committed
1572 1573 1574 1575 1576
      vtable = make_tree_vec (nvirtuals);
      TYPE_VTABLE (type) = vtable;
      if (super != NULL_TREE)
	{
	  tree super_vtable = get_dispatch_vector (super);
1577 1578

	  for (i = tree_low_cst (TYPE_NVIRTUALS (super), 0); --i >= 0; )
Anthony Green committed
1579 1580
	    TREE_VEC_ELT (vtable, i) = TREE_VEC_ELT (super_vtable, i);
	}
1581

Anthony Green committed
1582 1583
      for (method = TYPE_METHODS (type);  method != NULL_TREE;
	   method = TREE_CHAIN (method))
1584 1585 1586 1587 1588 1589
	{
	  tree method_index = get_method_index (method);
	  if (method_index != NULL_TREE
	      && host_integerp (method_index, 0))
	    TREE_VEC_ELT (vtable, tree_low_cst (method_index, 0)) = method;
	}
Anthony Green committed
1590
    }
1591

Anthony Green committed
1592 1593 1594
  return vtable;
}

1595
static tree
1596
get_dispatch_table (tree type, tree this_class_addr)
Anthony Green committed
1597
{
1598
  int abstract_p = CLASS_ABSTRACT (TYPE_NAME (type));
Anthony Green committed
1599
  tree vtable = get_dispatch_vector (type);
1600
  int i, j;
Anthony Green committed
1601 1602
  tree list = NULL_TREE;
  int nvirtuals = TREE_VEC_LENGTH (vtable);
1603
  int arraysize;
1604
  tree gc_descr;
1605

Anthony Green committed
1606 1607 1608 1609
  for (i = nvirtuals;  --i >= 0; )
    {
      tree method = TREE_VEC_ELT (vtable, i);
      if (METHOD_ABSTRACT (method))
1610 1611
	{
	  if (! abstract_p)
1612 1613
	    warning_at (DECL_SOURCE_LOCATION (method), 0,
			"abstract method in non-abstract class");
1614 1615 1616 1617 1618 1619

	  if (TARGET_VTABLE_USES_DESCRIPTORS)
	    for (j = 0; j < TARGET_VTABLE_USES_DESCRIPTORS; ++j)
	      list = tree_cons (NULL_TREE, null_pointer_node, list);
	  else
	    list = tree_cons (NULL_TREE, null_pointer_node, list);
1620 1621 1622
	}
      else
	{
1623 1624 1625
	  if (TARGET_VTABLE_USES_DESCRIPTORS)
	    for (j = 0; j < TARGET_VTABLE_USES_DESCRIPTORS; ++j)
	      {
1626
		tree fdesc = build2 (FDESC_EXPR, nativecode_ptr_type_node, 
1627
				     method, build_int_cst (NULL_TREE, j));
1628 1629 1630 1631 1632 1633 1634 1635
		TREE_CONSTANT (fdesc) = 1;
	        list = tree_cons (NULL_TREE, fdesc, list);
	      }
	  else
	    list = tree_cons (NULL_TREE,
			      build1 (ADDR_EXPR, nativecode_ptr_type_node,
				      method),
			      list);
1636
	}
Anthony Green committed
1637
    }
1638

1639 1640
  /* Dummy entry for compatibility with G++ -fvtable-thunks.  When
     using the Boehm GC we sometimes stash a GC type descriptor
1641 1642
     there. We set the PURPOSE to NULL_TREE not to interfere (reset)
     the emitted byte count during the output to the assembly file. */
1643 1644 1645 1646 1647 1648 1649 1650
  /* 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);
  list = tree_cons (NULL_TREE, gc_descr, list);
  for (j = 1; j < TARGET_VTABLE_USES_DESCRIPTORS-1; ++j)
    list = tree_cons (NULL_TREE, gc_descr, list);
1651 1652 1653 1654 1655 1656
  list = tree_cons (NULL_TREE, this_class_addr, list);

  /** Pointer to type_info object (to be implemented), according to g++ ABI. */
  list = tree_cons (NULL_TREE, null_pointer_node, list);
  /** Offset to start of whole object.  Always (ptrdiff_t)0 for Java. */
  list = tree_cons (integer_zero_node, null_pointer_node, list);
1657

1658
  arraysize = (TARGET_VTABLE_USES_DESCRIPTORS? nvirtuals + 1 : nvirtuals + 2);
1659 1660
  if (TARGET_VTABLE_USES_DESCRIPTORS)
    arraysize *= TARGET_VTABLE_USES_DESCRIPTORS;
1661
  arraysize += 2;
1662 1663 1664
  return build_constructor_from_list
	  (build_prim_array_type (nativecode_ptr_type_node,
				  arraysize), list);
Anthony Green committed
1665 1666
}

1667 1668 1669 1670 1671

/* Set the method_index for a method decl.  */
void
set_method_index (tree decl, tree method_index)
{
1672 1673 1674 1675
  if (method_index != NULL_TREE)
    {
      /* method_index is null if we're using indirect dispatch.  */
      method_index = fold (convert (sizetype, method_index));
1676

1677 1678 1679 1680 1681 1682 1683 1684
      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));
    }
1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707

  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;
}

1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719
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;
}

Anthony Green committed
1720
void
1721
make_class_data (tree type)
Anthony Green committed
1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741
{
  tree decl, cons, temp;
  tree field, fields_decl;
  tree static_fields = NULL_TREE;
  tree instance_fields = NULL_TREE;
  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 methods = NULL_TREE;
  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;
1742
  int uses_jv_markobj = 0;
Anthony Green committed
1743
  tree type_decl = TYPE_NAME (type);
1744 1745
  tree id_main = get_identifier("main");
  tree id_class = get_identifier("java.lang.Class");
1746 1747
  /** Offset from start of virtual function table declaration
      to where objects actually point at, following new g++ ABI. */
Andrew Pinski committed
1748
  tree dtable_start_offset = size_int (2 * POINTER_SIZE / BITS_PER_UNIT);
1749 1750
  VEC(int, heap) *field_indexes;
  tree first_real_field;
Anthony Green committed
1751

1752
  this_class_addr = build_static_class_ref (type);
Anthony Green committed
1753 1754
  decl = TREE_OPERAND (this_class_addr, 0);

1755 1756 1757 1758
  if (supers_all_compiled (type) && ! CLASS_INTERFACE (type_decl)
      && !flag_indirect_dispatch)
    {
      tree dtable = get_dispatch_table (type, this_class_addr);
1759
      uses_jv_markobj = uses_jv_markobj_p (dtable);
1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774
      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;
	}

1775
      TREE_PUBLIC (dtable_decl) = 1;
1776
      DECL_INITIAL (dtable_decl) = dtable;
1777 1778 1779
      /* The only dispatch table exported from a DSO is the dispatch
	 table for java.lang.Class.  */
      if (DECL_NAME (type_decl) != id_class)
1780
	java_hide_decl (dtable_decl);
1781 1782
      if (! flag_indirect_classes)
	rest_of_decl_compilation (dtable_decl, 1, 0);
1783 1784 1785
      /* 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)
1786 1787 1788
	class_dtable_decl = dtable_decl;
    }

Anthony Green committed
1789 1790
  /* Build Field array. */
  field = TYPE_FIELDS (type);
1791 1792 1793
  while (field && DECL_ARTIFICIAL (field))
    field = TREE_CHAIN (field);  /* Skip dummy fields.  */
  if (field && DECL_NAME (field) == NULL_TREE)
Anthony Green committed
1794
    field = TREE_CHAIN (field);  /* Skip dummy field for inherited data. */
1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813
  first_real_field = field;

  /* First count static and instance fields.  */
  for ( ; field != NULL_TREE; field = TREE_CHAIN (field))
    {
      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;
  field_indexes = VEC_alloc (int, heap, field_count);
  
  /* 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
1814
     that data contains indexes into the fields.  So, we generate a
1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835
     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; 
	 field = TREE_CHAIN (field), i++)
    {
      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++;
1836 1837
	  else
	    continue;
1838 1839 1840 1841 1842 1843 1844
	  VEC_quick_push (int, field_indexes, field_index);
	}
    }
  }

  for (field = first_real_field; field != NULL_TREE; 
       field = TREE_CHAIN (field))
Anthony Green committed
1845 1846 1847 1848 1849
    {
      if (! DECL_ARTIFICIAL (field))
	{
	  if (FIELD_STATIC (field))
	    {
1850 1851 1852
              /* 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);
1853
	      tree initial = DECL_INITIAL (field);
Anthony Green committed
1854
	      static_fields = tree_cons (NULL_TREE, init, static_fields);
1855 1856 1857 1858 1859
	      /* 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;
1860
	      rest_of_decl_compilation (field, 1, 1);
1861
	      DECL_INITIAL (field) = initial;
Anthony Green committed
1862
	    }
1863
	  else if (uses_jv_markobj || !flag_reduced_reflection)
Anthony Green committed
1864
	    {
1865
              tree init = make_field_value (field);
Anthony Green committed
1866 1867 1868 1869
	      instance_fields = tree_cons (NULL_TREE, init, instance_fields);
	    }
	}
    }
1870

Anthony Green committed
1871 1872 1873 1874 1875 1876
  if (field_count > 0)
    {
      static_fields = nreverse (static_fields);
      instance_fields = nreverse (instance_fields);
      static_fields = chainon (static_fields, instance_fields);
      field_array_type = build_prim_array_type (field_type_node, field_count);
1877 1878
      fields_decl = build_decl (input_location,
				VAR_DECL, mangled_classname ("_FL_", type),
Anthony Green committed
1879
				field_array_type);
1880 1881
      DECL_INITIAL (fields_decl) = build_constructor_from_list
				    (field_array_type, static_fields);
Anthony Green committed
1882 1883 1884
      TREE_STATIC (fields_decl) = 1;
      DECL_ARTIFICIAL (fields_decl) = 1;
      DECL_IGNORED_P (fields_decl) = 1;
1885
      rest_of_decl_compilation (fields_decl, 1, 0);
Anthony Green committed
1886 1887 1888 1889 1890
    }
  else
    fields_decl = NULL_TREE;

  /* Build Method array. */
1891
  for (method = TYPE_METHODS (type);
Anthony Green committed
1892 1893
       method != NULL_TREE; method = TREE_CHAIN (method))
    {
1894 1895
      tree init;
      if (METHOD_PRIVATE (method)
1896
	  && ! flag_keep_inline_functions
1897
	  && optimize)
1898
	continue;
1899
      /* Even if we have a decl, we don't necessarily have the code.
1900 1901 1902 1903
	 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;
1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925

      /* 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
1926
          || (METHOD_PUBLIC (method) && !METHOD_STATIC (method)))
1927 1928 1929 1930 1931
        {
          init = make_method_value (method);
          method_count++;
          methods = tree_cons (NULL_TREE, init, methods);
        }
Anthony Green committed
1932 1933
    }
  method_array_type = build_prim_array_type (method_type_node, method_count);
1934 1935
  methods_decl = build_decl (input_location,
			     VAR_DECL, mangled_classname ("_MT_", type),
Anthony Green committed
1936
			     method_array_type);
1937 1938
  DECL_INITIAL (methods_decl) = build_constructor_from_list
				 (method_array_type, nreverse (methods));
Anthony Green committed
1939 1940 1941
  TREE_STATIC (methods_decl) = 1;
  DECL_ARTIFICIAL (methods_decl) = 1;
  DECL_IGNORED_P (methods_decl) = 1;
1942
  rest_of_decl_compilation (methods_decl, 1, 0);
Anthony Green committed
1943

1944 1945 1946 1947 1948 1949
  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;
1950
      if (is_compiled_class (class_type_node) != 2)
1951 1952 1953 1954
	{
	  DECL_EXTERNAL (class_dtable_decl) = 1;
	  rest_of_decl_compilation (class_dtable_decl, 1, 0);
	}
Anthony Green committed
1955 1956 1957 1958 1959
    }

  super = CLASSTYPE_SUPER (type);
  if (super == NULL_TREE)
    super = null_pointer_node;
1960 1961
  else if (! flag_indirect_dispatch
	   && assume_compiled (IDENTIFIER_POINTER (DECL_NAME (type_decl)))
1962
	   && assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (super)))))
Anthony Green committed
1963 1964 1965 1966
    super = build_class_ref (super);
  else
    {
      int super_index = alloc_class_constant (super);
1967
      super = build_int_cst (ptr_type_node, super_index);
Anthony Green committed
1968 1969 1970 1971
    }

  /* Build and emit the array of implemented interfaces. */
  if (type != object_type_node)
1972 1973
    interface_len = BINFO_N_BASE_BINFOS (TYPE_BINFO (type)) - 1;
  
Anthony Green committed
1974 1975 1976 1977 1978 1979 1980
  if (interface_len > 0)
    {
      tree init = NULL_TREE;
      int i;
      tree interface_array_type, idecl;
      interface_array_type
	= build_prim_array_type (class_ptr_type, interface_len);
1981 1982
      idecl = build_decl (input_location,
			  VAR_DECL, mangled_classname ("_IF_", type),
Anthony Green committed
1983
			  interface_array_type);
Nathan Sidwell committed
1984
      
Anthony Green committed
1985 1986
      for (i = interface_len;  i > 0; i--)
	{
Nathan Sidwell committed
1987
	  tree child = BINFO_BASE_BINFO (TYPE_BINFO (type), i);
Anthony Green committed
1988 1989
	  tree iclass = BINFO_TYPE (child);
	  tree index;
1990 1991 1992
	  if (! flag_indirect_dispatch
	      && (assume_compiled 
		  (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (iclass))))))
Anthony Green committed
1993 1994 1995
	    index = build_class_ref (iclass);
	  else
	    {
1996
	      int int_index = alloc_class_constant (iclass);
1997
	      index = build_int_cst (ptr_type_node, int_index);
Anthony Green committed
1998 1999 2000
	    }
	  init = tree_cons (NULL_TREE, index, init); 
	}
2001 2002
      DECL_INITIAL (idecl) = build_constructor_from_list (interface_array_type,
							  init);
Anthony Green committed
2003 2004 2005 2006
      TREE_STATIC (idecl) = 1;
      DECL_ARTIFICIAL (idecl) = 1;
      DECL_IGNORED_P (idecl) = 1;
      interfaces = build1 (ADDR_EXPR, ptr_type_node, idecl);
2007
      rest_of_decl_compilation (idecl, 1, 0);
Anthony Green committed
2008 2009 2010 2011
    }

  constant_pool_constructor = build_constants_constructor ();

2012 2013 2014 2015 2016 2017
  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), 
2018
	 TYPE_OTABLE_SYMS_DECL (type), integer_type_node, 1);
2019 2020 2021 2022 2023
       
      TYPE_ATABLE_DECL (type) 
	= emit_symbol_table 
	(DECL_NAME (TYPE_ATABLE_DECL (type)), 
	 TYPE_ATABLE_DECL (type), TYPE_ATABLE_METHODS (type), 
2024 2025 2026 2027 2028 2029 2030
	 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);
2031 2032 2033 2034
    }
  
  TYPE_CTABLE_DECL (type) = emit_catch_table (type);

Anthony Green committed
2035
  START_RECORD_CONSTRUCTOR (temp, object_type_node);
2036
  PUSH_FIELD_VALUE (temp, "vtable",
2037 2038
		    (flag_indirect_classes 
		     ? null_pointer_node
Andrew Pinski committed
2039
		     : build2 (POINTER_PLUS_EXPR, dtable_ptr_type,
2040 2041 2042
			       build1 (ADDR_EXPR, dtable_ptr_type,
				       class_dtable_decl),
			       dtable_start_offset)));
2043 2044
  if (! flag_hash_synchronization)
    PUSH_FIELD_VALUE (temp, "sync_info", null_pointer_node);
Anthony Green committed
2045 2046 2047
  FINISH_RECORD_CONSTRUCTOR (temp);
  START_RECORD_CONSTRUCTOR (cons, class_type_node);
  PUSH_SUPER_VALUE (cons, temp);
2048
  PUSH_FIELD_VALUE (cons, "next_or_version", gcj_abi_version);
2049
  PUSH_FIELD_VALUE (cons, "name", build_utf8_ref (DECL_NAME (type_decl)));
Anthony Green committed
2050
  PUSH_FIELD_VALUE (cons, "accflags",
2051
		    build_int_cst (NULL_TREE,
2052
				   get_access_flags_from_decl (type_decl)));
Anthony Green committed
2053

2054 2055
  PUSH_FIELD_VALUE (cons, "superclass", 
		    CLASS_INTERFACE (type_decl) ? null_pointer_node : super);
Anthony Green committed
2056 2057
  PUSH_FIELD_VALUE (cons, "constants", constant_pool_constructor);
  PUSH_FIELD_VALUE (cons, "methods",
2058 2059
                    methods_decl == NULL_TREE ? null_pointer_node
		    : build1 (ADDR_EXPR, method_ptr_type_node, methods_decl));
2060
  PUSH_FIELD_VALUE (cons, "method_count",
2061
		    build_int_cst (NULL_TREE, method_count));
2062 2063

  if (flag_indirect_dispatch)
2064
    PUSH_FIELD_VALUE (cons, "vtable_method_count", integer_minus_one_node);
2065 2066 2067
  else
    PUSH_FIELD_VALUE (cons, "vtable_method_count", TYPE_NVIRTUALS (type));
    
Anthony Green committed
2068 2069 2070
  PUSH_FIELD_VALUE (cons, "fields",
		    fields_decl == NULL_TREE ? null_pointer_node
		    : build1 (ADDR_EXPR, field_ptr_type_node, fields_decl));
2071 2072 2073 2074 2075 2076 2077
  /* If we're using the binary compatibility ABI we don't know the
     size until load time.  */
  PUSH_FIELD_VALUE (cons, "size_in_bytes", 
		    (flag_indirect_dispatch 
		     ? integer_minus_one_node 
		     : size_in_bytes (type)));
  PUSH_FIELD_VALUE (cons, "field_count", 
2078
		    build_int_cst (NULL_TREE, field_count));
2079
  PUSH_FIELD_VALUE (cons, "static_field_count",
2080
		    build_int_cst (NULL_TREE, static_field_count));
2081 2082

  if (flag_indirect_dispatch)
2083
    PUSH_FIELD_VALUE (cons, "vtable", null_pointer_node);
2084 2085 2086
  else
    PUSH_FIELD_VALUE (cons, "vtable",
		      dtable_decl == NULL_TREE ? null_pointer_node
Andrew Pinski committed
2087
		      : build2 (POINTER_PLUS_EXPR, dtable_ptr_type,
2088 2089 2090
				build1 (ADDR_EXPR, dtable_ptr_type,
					dtable_decl),
				dtable_start_offset));
2091
  if (TYPE_OTABLE_METHODS (type) == NULL_TREE)
2092 2093 2094 2095 2096 2097
    {
      PUSH_FIELD_VALUE (cons, "otable", null_pointer_node);
      PUSH_FIELD_VALUE (cons, "otable_syms", null_pointer_node);
    }
  else
    {
2098
      pushdecl_top_level (TYPE_OTABLE_SYMS_DECL (type));
2099
      PUSH_FIELD_VALUE (cons, "otable",
2100
			build1 (ADDR_EXPR, otable_ptr_type, TYPE_OTABLE_DECL (type)));
2101
      PUSH_FIELD_VALUE (cons, "otable_syms",
2102
			build1 (ADDR_EXPR, symbols_array_ptr_type,
2103 2104
				TYPE_OTABLE_SYMS_DECL (type)));
      TREE_CONSTANT (TYPE_OTABLE_DECL (type)) = 1;
2105
    }
2106
  if (TYPE_ATABLE_METHODS(type) == NULL_TREE)
2107 2108 2109
    {
      PUSH_FIELD_VALUE (cons, "atable", null_pointer_node);
      PUSH_FIELD_VALUE (cons, "atable_syms", null_pointer_node);
2110
    }
2111 2112
  else
    {
2113
      pushdecl_top_level (TYPE_ATABLE_SYMS_DECL (type));
2114
      PUSH_FIELD_VALUE (cons, "atable",
2115
			build1 (ADDR_EXPR, atable_ptr_type, TYPE_ATABLE_DECL (type)));
2116 2117
      PUSH_FIELD_VALUE (cons, "atable_syms",
			build1 (ADDR_EXPR, symbols_array_ptr_type,
2118 2119
				TYPE_ATABLE_SYMS_DECL (type)));
      TREE_CONSTANT (TYPE_ATABLE_DECL (type)) = 1;
2120
    }
2121 2122 2123 2124 2125 2126 2127
   if (TYPE_ITABLE_METHODS(type) == NULL_TREE)
    {
      PUSH_FIELD_VALUE (cons, "itable", null_pointer_node);
      PUSH_FIELD_VALUE (cons, "itable_syms", null_pointer_node);
    }
  else
    {
2128
      pushdecl_top_level (TYPE_ITABLE_SYMS_DECL (type));
2129 2130 2131 2132 2133 2134 2135
      PUSH_FIELD_VALUE (cons, "itable",
			build1 (ADDR_EXPR, itable_ptr_type, TYPE_ITABLE_DECL (type)));
      PUSH_FIELD_VALUE (cons, "itable_syms",
			build1 (ADDR_EXPR, symbols_array_ptr_type,
				TYPE_ITABLE_SYMS_DECL (type)));
      TREE_CONSTANT (TYPE_ITABLE_DECL (type)) = 1;
    }
2136 2137
 
  PUSH_FIELD_VALUE (cons, "catch_classes",
2138
		    build1 (ADDR_EXPR, ptr_type_node, TYPE_CTABLE_DECL (type))); 
Anthony Green committed
2139 2140
  PUSH_FIELD_VALUE (cons, "interfaces", interfaces);
  PUSH_FIELD_VALUE (cons, "loader", null_pointer_node);
2141
  PUSH_FIELD_VALUE (cons, "interface_count",
2142
		    build_int_cst (NULL_TREE, interface_len));
2143 2144 2145
  PUSH_FIELD_VALUE (cons, "state",
		    convert (byte_type_node,
			     build_int_cst (NULL_TREE, JV_STATE_PRELOADING)));
Anthony Green committed
2146

Per Bothner committed
2147
  PUSH_FIELD_VALUE (cons, "thread", null_pointer_node);
2148 2149 2150
  PUSH_FIELD_VALUE (cons, "depth", integer_zero_node);
  PUSH_FIELD_VALUE (cons, "ancestors", null_pointer_node);
  PUSH_FIELD_VALUE (cons, "idt", null_pointer_node);
Bryce McKinlay committed
2151
  PUSH_FIELD_VALUE (cons, "arrayclass", null_pointer_node);
2152
  PUSH_FIELD_VALUE (cons, "protectionDomain", null_pointer_node);
2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165

  {
    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));
    
    PUSH_FIELD_VALUE (cons, "assertion_table", assertion_table_ref);
  }

2166
  PUSH_FIELD_VALUE (cons, "hack_signers", null_pointer_node);
2167
  PUSH_FIELD_VALUE (cons, "chain", null_pointer_node);
2168
  PUSH_FIELD_VALUE (cons, "aux_info", null_pointer_node);
2169
  PUSH_FIELD_VALUE (cons, "engine", null_pointer_node);
Per Bothner committed
2170

2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185
  if (TYPE_REFLECTION_DATA (current_class))
    {
      int i;
      int count = TYPE_REFLECTION_DATASIZE (current_class);
      VEC (constructor_elt, gc) *v
	= VEC_alloc (constructor_elt, gc, count);
      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++);
2186 2187
      array = build_decl (input_location,
			  VAR_DECL, get_identifier (buf), type);
2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213

      rewrite_reflection_indexes (field_indexes);

      for (i = 0; i < count; i++)
	{
	  constructor_elt *elt = VEC_quick_push (constructor_elt, v, NULL);
 	  elt->index = build_int_cst (sizetype, i);
	  elt->value = build_int_cstu (byte_type_node, data[i]);
	}

      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);
      
      PUSH_FIELD_VALUE (cons, "reflection_data", build_address_of (array));

      free (data);
      TYPE_REFLECTION_DATA (current_class) = NULL;
    }
  else
    PUSH_FIELD_VALUE (cons, "reflection_data", null_pointer_node);

Anthony Green committed
2214 2215 2216
  FINISH_RECORD_CONSTRUCTOR (cons);

  DECL_INITIAL (decl) = cons;
2217 2218 2219 2220 2221
  
  /* Hash synchronization requires at least 64-bit alignment. */
  if (flag_hash_synchronization && POINTER_SIZE < 64)
    DECL_ALIGN (decl) = 64; 
  
2222 2223 2224 2225 2226 2227
  if (flag_indirect_classes)
    {
      TREE_READONLY (decl) = 1;
      TREE_CONSTANT (DECL_INITIAL (decl)) = 1;
    }

2228
  rest_of_decl_compilation (decl, 1, 0);
2229
  
2230 2231 2232 2233 2234 2235 2236
  {
    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);
  }

2237 2238 2239
  TYPE_OTABLE_DECL (type) = NULL_TREE;
  TYPE_ATABLE_DECL (type) = NULL_TREE;
  TYPE_CTABLE_DECL (type) = NULL_TREE;
Anthony Green committed
2240 2241
}

2242
void
2243
finish_class (void)
2244
{
2245 2246
  java_expand_catch_classes (current_class);

2247
  current_function_decl = NULL_TREE;
2248
  TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (current_class)) = 0;
2249 2250
  make_class_data (current_class);
  register_class ();
2251
  rest_of_decl_compilation (TYPE_NAME (current_class), 1, 0);
2252 2253
}

2254 2255 2256
/* 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
2257 2258
   Returns 1 for primitive and 0 for array types.  */
int
2259
is_compiled_class (tree klass)
Anthony Green committed
2260
{
2261
  int seen_in_zip;
2262 2263 2264
  if (TREE_CODE (klass) == POINTER_TYPE)
    klass = TREE_TYPE (klass);
  if (TREE_CODE (klass) != RECORD_TYPE)  /* Primitive types are static. */
Anthony Green committed
2265
    return 1;
2266
  if (TYPE_ARRAY_P (klass))
Anthony Green committed
2267
    return 0;
2268

2269 2270
  seen_in_zip = (TYPE_JCF (klass) && JCF_SEEN_IN_ZIP (TYPE_JCF (klass)));
  if (CLASS_FROM_CURRENTLY_COMPILED_P (klass))
Anthony Green committed
2271 2272 2273 2274
    {
      /* 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
2275
	 build_class_ref () from crashing. */
Anthony Green committed
2276

2277 2278
      if (seen_in_zip && !CLASS_LOADED_P (klass) && (klass != current_class))
        load_class (klass, 1);
2279 2280 2281

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

2285
  if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (klass)))))
Anthony Green committed
2286
    {
2287
      if (!CLASS_LOADED_P (klass))
2288
	{
2289 2290
	  if (klass != current_class)
	    load_class (klass, 1);
2291
	}
Anthony Green committed
2292 2293 2294 2295 2296 2297 2298 2299 2300
      return 1;
    }

  return 0;
}

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

tree
2301
build_dtable_decl (tree type)
Anthony Green committed
2302
{
2303
  tree dtype, decl;
2304 2305 2306 2307

  /* 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
2308
     compiler.) We know we're not faking a class when CURRENT_CLASS is
2309 2310 2311
     TYPE. */
  if (current_class == type)
    {
2312 2313
      tree dummy = NULL_TREE;
      int n;
2314 2315

      dtype = make_node (RECORD_TYPE);
2316

2317 2318
      PUSH_FIELD (input_location, dtype, dummy, "top_offset", ptr_type_node);
      PUSH_FIELD (input_location, dtype, dummy, "type_info", ptr_type_node);
2319

2320
      PUSH_FIELD (input_location, dtype, dummy, "class", class_ptr_type);
2321 2322
      for (n = 1; n < TARGET_VTABLE_USES_DESCRIPTORS; ++n)
	{
2323 2324
	  tree tmp_field = build_decl (input_location,
				       FIELD_DECL, NULL_TREE, ptr_type_node);
2325 2326 2327 2328 2329 2330
	  TREE_CHAIN (dummy) = tmp_field;
	  DECL_CONTEXT (tmp_field) = dtype;
	  DECL_ARTIFICIAL (tmp_field) = 1;
	  dummy = tmp_field;
	}

2331
      PUSH_FIELD (input_location, dtype, dummy, "gc_descr", ptr_type_node);
2332 2333
      for (n = 1; n < TARGET_VTABLE_USES_DESCRIPTORS; ++n)
	{
2334 2335
	  tree tmp_field = build_decl (input_location,
				       FIELD_DECL, NULL_TREE, ptr_type_node);
2336 2337 2338 2339 2340 2341 2342 2343 2344 2345
	  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;

2346
      PUSH_FIELD (input_location, dtype, dummy, "methods",
2347
		  build_prim_array_type (nativecode_ptr_type_node, n));
2348 2349 2350 2351 2352
      layout_type (dtype);
    }
  else
    dtype = dtable_type;

2353 2354
  decl = build_decl (input_location,
		     VAR_DECL, get_identifier ("vt$"), dtype);
2355 2356 2357 2358 2359
  DECL_CONTEXT (decl) = type;
  MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
  DECL_VTABLE_P (decl) = 1;

  return decl;
Anthony Green committed
2360 2361 2362 2363 2364 2365
}

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

void
2366
push_super_field (tree this_class, tree super_class)
Anthony Green committed
2367 2368
{
  tree base_decl;
2369 2370 2371
  /* 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;
2372 2373
  base_decl = build_decl (input_location,
			  FIELD_DECL, NULL_TREE, super_class);
Anthony Green committed
2374 2375 2376 2377
  DECL_IGNORED_P (base_decl) = 1;
  TREE_CHAIN (base_decl) = TYPE_FIELDS (this_class);
  TYPE_FIELDS (this_class) = base_decl;
  DECL_SIZE (base_decl) = TYPE_SIZE (super_class);
2378
  DECL_SIZE_UNIT (base_decl) = TYPE_SIZE_UNIT (super_class);
Anthony Green committed
2379 2380
}

2381 2382 2383
/* Handle the different manners we may have to lay out a super class.  */

static tree
2384
maybe_layout_super_class (tree super_class, tree this_class ATTRIBUTE_UNUSED)
2385
{
2386 2387 2388
  if (!super_class)
    return NULL_TREE;
  else if (TREE_CODE (super_class) == RECORD_TYPE)
2389 2390 2391 2392 2393 2394
    {
      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  */
2395
  else if (TREE_CODE (super_class) == POINTER_TYPE)
2396
    {
2397 2398 2399
      if (TREE_TYPE (super_class) != NULL_TREE)
	super_class = TREE_TYPE (super_class);
      else
2400
	gcc_unreachable ();
2401 2402 2403 2404 2405 2406 2407
    }
  if (!TYPE_SIZE (super_class))
    safe_layout_class (super_class);

  return super_class;
}

2408 2409 2410 2411 2412
/* safe_layout_class just makes sure that we can load a class without
   disrupting the current_class, input_file, input_line, etc, information
   about the class processed currently.  */

void
2413
safe_layout_class (tree klass)
2414 2415 2416 2417
{
  tree save_current_class = current_class;
  location_t save_location = input_location;

2418
  layout_class (klass);
2419 2420 2421 2422 2423

  current_class = save_current_class;
  input_location = save_location;
}

Anthony Green committed
2424
void
2425
layout_class (tree this_class)
Anthony Green committed
2426
{
2427
  int i;
Anthony Green committed
2428
  tree super_class = CLASSTYPE_SUPER (this_class);
2429

2430
  class_list = tree_cons (this_class, NULL_TREE, class_list);
2431 2432 2433
  if (CLASS_BEING_LAIDOUT (this_class))
    {
      char buffer [1024];
Mark Mitchell committed
2434
      char *report;
2435
      tree current;
2436

2437
      sprintf (buffer, " with '%s'",
2438 2439 2440
	       IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class))));
      obstack_grow (&temporary_obstack, buffer, strlen (buffer));

2441
      for (current = TREE_CHAIN (class_list); current; 
2442 2443 2444
	   current = TREE_CHAIN (current))
	{
	  tree decl = TYPE_NAME (TREE_PURPOSE (current));
2445
	  sprintf (buffer, "\n  which inherits from '%s' (%s:%d)",
2446
		   IDENTIFIER_POINTER (DECL_NAME (decl)),
2447 2448
		   DECL_SOURCE_FILE (decl),
		   DECL_SOURCE_LINE (decl));
2449 2450 2451
	  obstack_grow (&temporary_obstack, buffer, strlen (buffer));
	}
      obstack_1grow (&temporary_obstack, '\0');
2452
      report = XOBFINISH (&temporary_obstack, char *);
Mark Mitchell committed
2453 2454
      cyclic_inheritance_report = ggc_strdup (report);
      obstack_free (&temporary_obstack, report);
2455 2456 2457 2458
      TYPE_SIZE (this_class) = error_mark_node;
      return;
    }
  CLASS_BEING_LAIDOUT (this_class) = 1;
Anthony Green committed
2459

2460
  if (super_class && !CLASS_BEING_LAIDOUT (super_class))
Anthony Green committed
2461
    {
2462 2463 2464 2465
      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
2466 2467
	{
	  TYPE_SIZE (this_class) = error_mark_node;
2468
	  CLASS_BEING_LAIDOUT (this_class) = 0;
2469
	  class_list = TREE_CHAIN (class_list);
Anthony Green committed
2470 2471 2472
	  return;
	}
      if (TYPE_SIZE (this_class) == NULL_TREE)
2473
	push_super_field (this_class, maybe_super_class);
Anthony Green committed
2474 2475 2476
    }

  layout_type (this_class);
2477

2478 2479
  /* Also recursively load/layout any superinterfaces.  */
  if (TYPE_BINFO (this_class))
2480
    {
2481
      for (i = BINFO_N_BASE_BINFOS (TYPE_BINFO (this_class)) - 1; i > 0; i--)
2482
	{
2483 2484 2485 2486 2487 2488
	  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)
2489
	    {
2490 2491 2492 2493
	      TYPE_SIZE (this_class) = error_mark_node;
	      CLASS_BEING_LAIDOUT (this_class) = 0;
	      class_list = TREE_CHAIN (class_list);
	      return;
2494 2495 2496 2497
	    }
	}
    }

2498 2499
  /* Convert the size back to an SI integer value.  */
  TYPE_SIZE_UNIT (this_class) =
2500
    fold (convert (int_type_node, TYPE_SIZE_UNIT (this_class)));
2501 2502

  CLASS_BEING_LAIDOUT (this_class) = 0;
2503
  class_list = TREE_CHAIN (class_list);
2504
}
Anthony Green committed
2505

2506 2507 2508
static void
add_miranda_methods (tree base_class, tree search_class)
{
Nathan Sidwell committed
2509
  int i;
2510 2511 2512 2513
  tree binfo, base_binfo;

  if (!CLASS_PARSED_P (search_class))
    load_class (search_class, 1);
Nathan Sidwell committed
2514 2515 2516
  
  for (binfo = TYPE_BINFO (search_class), i = 1;
       BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
2517 2518
    {
      tree method_decl;
Nathan Sidwell committed
2519
      tree elt = BINFO_TYPE (base_binfo);
2520

2521 2522 2523 2524 2525
      /* 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;

2526
      /* Ensure that interface methods are seen in declared order.  */
2527 2528
      if (!CLASS_LOADED_P (elt))
	load_class (elt, 1);
2529 2530 2531 2532 2533
      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.  */
2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563
      for (method_decl = TYPE_METHODS (elt);
	   method_decl; method_decl = TREE_CHAIN (method_decl))
	{
	  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);
    }
}

2564
void
2565
layout_class_methods (tree this_class)
2566 2567
{
  tree method_decl, dtable_count;
2568
  tree super_class, type_name;
2569 2570 2571

  if (TYPE_NVIRTUALS (this_class))
    return;
2572
  
2573
  super_class = CLASSTYPE_SUPER (this_class);
Anthony Green committed
2574

2575
  if (super_class)
Anthony Green committed
2576
    {
2577
      super_class = maybe_layout_super_class (super_class, this_class);
2578 2579 2580 2581 2582 2583
      if (!TYPE_NVIRTUALS (super_class))
	layout_class_methods (super_class);
      dtable_count = TYPE_NVIRTUALS (super_class);
    }
  else
    dtable_count = integer_zero_node;
2584

2585
  type_name = TYPE_NAME (this_class);
2586 2587
  if (!flag_indirect_dispatch
      && (CLASS_ABSTRACT (type_name) || CLASS_INTERFACE (type_name)))
2588 2589 2590 2591 2592 2593 2594 2595
    {
      /* 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);
    }

2596
  TYPE_METHODS (this_class) = nreverse (TYPE_METHODS (this_class));
2597

2598
  for (method_decl = TYPE_METHODS (this_class);
2599
       method_decl; method_decl = TREE_CHAIN (method_decl))
2600
    dtable_count = layout_class_method (this_class, super_class,
2601 2602 2603 2604 2605
					method_decl, dtable_count);

  TYPE_NVIRTUALS (this_class) = dtable_count;
}

2606 2607
/* Return the index of METHOD in INTERFACE.  This index begins at 1
   and is used as an argument for _Jv_LookupInterfaceMethodIdx(). */
Bryce McKinlay committed
2608 2609 2610 2611 2612 2613
int
get_interface_method_index (tree method, tree interface)
{
  tree meth;
  int i = 1;

2614
  for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth))
Bryce McKinlay committed
2615 2616 2617
    {
      if (meth == method)
	return i;
2618 2619 2620
      /* We don't want to put <clinit> into the interface table.  */
      if (! ID_CLINIT_P (DECL_NAME (meth)))
	++i;
2621
      gcc_assert (meth != NULL_TREE);
Bryce McKinlay committed
2622 2623 2624
    }
}

2625
/* Lay METHOD_DECL out, returning a possibly new value of
2626
   DTABLE_COUNT. Also mangle the method's name. */
2627 2628

tree
2629 2630
layout_class_method (tree this_class, tree super_class,
		     tree method_decl, tree dtable_count)
2631 2632
{
  tree method_name = DECL_NAME (method_decl);
2633 2634

  TREE_PUBLIC (method_decl) = 1;
2635

2636 2637 2638 2639
  if (flag_indirect_classes
      || (METHOD_PRIVATE (method_decl) && METHOD_STATIC (method_decl)
	  && ! METHOD_NATIVE (method_decl)
	  && ! special_method_p (method_decl)))
2640
    java_hide_decl (method_decl);
2641

2642
  /* Considered external unless it is being compiled into this object
2643 2644 2645 2646
     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));
2647

2648
  if (ID_INIT_P (method_name))
2649
    {
2650
      const char *p = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class)));
2651
      const char *ptr;
2652
      for (ptr = p; *ptr; )
Anthony Green committed
2653
	{
2654 2655 2656 2657
	  if (*ptr++ == '.')
	    p = ptr;
	}
      DECL_CONSTRUCTOR_P (method_decl) = 1;
2658
      build_java_signature (TREE_TYPE (method_decl));
2659
    }
2660
  else if (! METHOD_STATIC (method_decl))
2661
    {
2662
      tree method_sig =
2663
	build_java_signature (TREE_TYPE (method_decl));
2664
      bool method_override = false;
2665
      tree super_method = lookup_java_method (super_class, method_name,
Anthony Green committed
2666
						  method_sig);
2667
      if (super_method != NULL_TREE
2668
	  && ! METHOD_DUMMY (super_method))
2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682
        {
	  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)
2683
	{
2684 2685 2686
	  tree method_index = get_method_index (super_method);
	  set_method_index (method_decl, method_index);
	  if (method_index == NULL_TREE 
2687
	      && ! flag_indirect_dispatch
2688
	      && ! DECL_ARTIFICIAL (super_method))
2689 2690
	    error ("non-static method %q+D overrides static method",
                   method_decl);
2691
	}
2692 2693 2694 2695 2696 2697 2698 2699 2700
      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)
2701 2702
	       && dtable_count)
	{
2703 2704
	  /* We generate vtable entries for final methods because they
	     may one day be changed to non-final.  */
2705
	  set_method_index (method_decl, dtable_count);
2706 2707
	  dtable_count = fold_build2 (PLUS_EXPR, integer_type_node,
				      dtable_count, integer_one_node);
Anthony Green committed
2708 2709
	}
    }
2710

2711
  return dtable_count;
Anthony Green committed
2712 2713
}

2714
static void
2715
register_class (void)
Anthony Green committed
2716
{
2717 2718
  tree node;

Anthony Green committed
2719
  if (!registered_class)
2720
    registered_class = VEC_alloc (tree, gc, 8);
Anthony Green committed
2721

2722 2723 2724 2725
  if (flag_indirect_classes)
    node = current_class;
  else
    node = TREE_OPERAND (build_class_ref (current_class), 0);
2726
  VEC_safe_push (tree, gc, registered_class, node);
Anthony Green committed
2727 2728
}

2729 2730
/* Emit a function that calls _Jv_RegisterNewClasses with a list of
   all the classes we have emitted.  */
2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741

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

  tree init = NULL_TREE;
  int size = VEC_length (tree, registered_class) * 2 + 1;
  tree class_array_type
    = build_prim_array_type (ptr_type_node, size);
2742 2743
  tree cdecl = build_decl (input_location,
			   VAR_DECL, get_identifier ("_Jv_CLS"),
2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770
			   class_array_type);
  tree reg_class_list;
  for (i = 0; VEC_iterate (tree, registered_class, i, klass); ++i)
    {
      init = tree_cons (NULL_TREE, 
			fold_convert (ptr_type_node, 
				      build_static_class_ref (klass)), init);
      init = tree_cons 
	(NULL_TREE, 
	 fold_convert (ptr_type_node, 
		       build_address_of (build_classdollar_field (klass))),
	 init);
    }
  init = tree_cons (NULL_TREE, integer_zero_node, init); 
  DECL_INITIAL (cdecl) = build_constructor_from_list (class_array_type,
						      nreverse (init));
  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);
2771 2772
  t = build_decl (input_location,
		  FUNCTION_DECL, 
2773 2774 2775 2776
		  get_identifier ("_Jv_RegisterNewClasses"), t);
  TREE_PUBLIC (t) = 1;
  DECL_EXTERNAL (t) = 1;
  register_class_fn = t;
2777
  t = build_call_expr (register_class_fn, 1, reg_class_list);
2778 2779 2780 2781
  append_to_statement_list (t, list_p);
}


2782 2783 2784
/* Emit something to register classes at start-up time.

   The preferred mechanism is through the .jcr section, which contain
2785 2786 2787 2788 2789 2790
   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
2791 2792

void
2793
emit_register_classes (tree *list_p)
Anthony Green committed
2794
{
2795 2796 2797
  if (registered_class == NULL)
    return;

2798 2799 2800 2801 2802 2803
  if (flag_indirect_classes)
    {
      emit_indirect_register_classes (list_p);
      return;
    }

2804 2805 2806
  /* 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
2807
     targets can override the default in tm.h to use the fallback mechanism.  */
2808
  if (TARGET_USE_JCR_SECTION)
2809
    {
2810 2811 2812
      tree klass, t;
      int i;

2813
#ifdef JCR_SECTION_NAME
2814
      switch_to_section (get_section (JCR_SECTION_NAME, SECTION_WRITE, NULL));
2815 2816 2817 2818 2819
#else
      /* A target has defined TARGET_USE_JCR_SECTION,
	 but doesn't have a JCR_SECTION_NAME.  */
      gcc_unreachable ();
#endif
2820
      assemble_align (POINTER_SIZE);
2821 2822

      for (i = 0; VEC_iterate (tree, registered_class, i, klass); ++i)
Jan Hubicka committed
2823
	{
2824 2825
	  t = build_fold_addr_expr (klass);
	  output_constant (t, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE);
Jan Hubicka committed
2826
	}
2827 2828 2829
    }
  else
    {
2830
      tree klass, t, register_class_fn;
2831
      int i;
2832 2833

      t = build_function_type_list (void_type_node, class_ptr_type, NULL);
2834 2835
      t = build_decl (input_location,
		      FUNCTION_DECL, get_identifier ("_Jv_RegisterClass"), t);
2836 2837 2838 2839
      TREE_PUBLIC (t) = 1;
      DECL_EXTERNAL (t) = 1;
      register_class_fn = t;

2840
      for (i = 0; VEC_iterate (tree, registered_class, i, klass); ++i)
2841 2842
	{
	  t = build_fold_addr_expr (klass);
2843
	  t = build_call_expr (register_class_fn, 1, t);
2844 2845
	  append_to_statement_list (t, list_p);
	}
2846
    }
Anthony Green committed
2847 2848
}

2849
/* Make a symbol_type (_Jv_MethodSymbol) node for DECL. */
2850

2851
static tree
2852
build_symbol_entry (tree decl, tree special)
2853
{
2854 2855
  tree clname, name, signature, sym;
  clname = build_utf8_ref (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl))));
2856 2857 2858 2859 2860 2861 2862 2863
  /* ???  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));
2864
  signature = build_java_signature (TREE_TYPE (decl));
2865 2866 2867
  signature = build_utf8_ref (unmangle_classname 
			      (IDENTIFIER_POINTER (signature),
			       IDENTIFIER_LENGTH (signature)));
2868 2869 2870 2871 2872
  /* 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)
Andrew Pinski committed
2873 2874
    signature = build2 (POINTER_PLUS_EXPR, TREE_TYPE (signature), signature,
			fold_convert (sizetype, special));
2875
      
2876 2877 2878 2879 2880 2881
  START_RECORD_CONSTRUCTOR (sym, symbol_type);
  PUSH_FIELD_VALUE (sym, "clname", clname);
  PUSH_FIELD_VALUE (sym, "name", name);
  PUSH_FIELD_VALUE (sym, "signature", signature);
  FINISH_RECORD_CONSTRUCTOR (sym);
  TREE_CONSTANT (sym) = 1;
2882

2883
  return sym;
2884 2885
} 

2886
/* Emit a symbol table: used by -findirect-dispatch.  */
2887

2888
tree
Ranjit Mathew committed
2889
emit_symbol_table (tree name, tree the_table, tree decl_list,
2890 2891
                   tree the_syms_decl, tree the_array_element_type,
		   int element_size)
2892 2893
{
  tree method_list, method, table, list, null_symbol;
2894
  tree table_size, the_array_type;
2895 2896
  int index;
  
2897 2898 2899 2900
  /* Only emit a table if this translation unit actually made any
     references via it. */
  if (decl_list == NULL_TREE)
    return the_table;
2901 2902 2903

  /* Build a list of _Jv_MethodSymbols for each entry in otable_methods. */
  index = 0;
2904
  method_list = decl_list;
2905 2906 2907
  list = NULL_TREE;  
  while (method_list != NULL_TREE)
    {
2908
      tree special = TREE_PURPOSE (method_list);
2909
      method = TREE_VALUE (method_list);
2910
      list = tree_cons (NULL_TREE, build_symbol_entry (method, special), list);
2911 2912 2913 2914 2915
      method_list = TREE_CHAIN (method_list);
      index++;
    }

  /* Terminate the list with a "null" entry. */
2916
  START_RECORD_CONSTRUCTOR (null_symbol, symbol_type);
2917 2918 2919 2920 2921 2922 2923 2924 2925
  PUSH_FIELD_VALUE (null_symbol, "clname", null_pointer_node);
  PUSH_FIELD_VALUE (null_symbol, "name", null_pointer_node);
  PUSH_FIELD_VALUE (null_symbol, "signature", null_pointer_node);
  FINISH_RECORD_CONSTRUCTOR (null_symbol);
  TREE_CONSTANT (null_symbol) = 1;  
  list = tree_cons (NULL_TREE, null_symbol, list);

  /* Put the list in the right order and make it a constructor. */
  list = nreverse (list);
2926
  table = build_constructor_from_list (symbols_array_type, list);  
2927 2928

  /* Make it the initial value for otable_syms and emit the decl. */
2929 2930 2931
  DECL_INITIAL (the_syms_decl) = table;
  DECL_ARTIFICIAL (the_syms_decl) = 1;
  DECL_IGNORED_P (the_syms_decl) = 1;
2932
  rest_of_decl_compilation (the_syms_decl, 1, 0);
2933
  
2934 2935 2936 2937
  /* 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. */
2938 2939
  table_size 
    = build_index_type (build_int_cst (NULL_TREE, index * element_size + 1));
2940
  the_array_type = build_array_type (the_array_element_type, table_size);
2941 2942
  the_table = build_decl (input_location,
			  VAR_DECL, name, the_array_type);
2943 2944
  TREE_STATIC (the_table) = 1;
  TREE_READONLY (the_table) = 1;  
2945
  rest_of_decl_compilation (the_table, 1, 0);
2946 2947

  return the_table;
2948 2949
}

2950
/* Make an entry for the catch_classes list.  */
2951 2952 2953 2954
tree
make_catch_class_record (tree catch_class, tree classname)
{
  tree entry;
2955
  tree type = TREE_TYPE (TREE_TYPE (TYPE_CTABLE_DECL (output_class)));
2956 2957 2958 2959 2960 2961 2962 2963 2964
  START_RECORD_CONSTRUCTOR (entry, type);
  PUSH_FIELD_VALUE (entry, "address", catch_class);
  PUSH_FIELD_VALUE (entry, "classname", classname);
  FINISH_RECORD_CONSTRUCTOR (entry);
  return entry;
}


/* Generate the list of Throwable classes that are caught by exception
2965 2966 2967
   handlers in this class.  */
tree 
emit_catch_table (tree this_class)
2968 2969
{
  tree table, table_size, array_type;
2970 2971 2972 2973 2974 2975 2976 2977 2978
  TYPE_CATCH_CLASSES (this_class) =
    tree_cons (NULL,
	       make_catch_class_record (null_pointer_node, null_pointer_node),
	       TYPE_CATCH_CLASSES (this_class));
  TYPE_CATCH_CLASSES (this_class) = nreverse (TYPE_CATCH_CLASSES (this_class));
  TYPE_CATCH_CLASSES (this_class) = 
    tree_cons (NULL,
	       make_catch_class_record (null_pointer_node, null_pointer_node),
	       TYPE_CATCH_CLASSES (this_class));
2979 2980
  table_size = build_index_type
    (build_int_cst (NULL_TREE,
2981
		    list_length (TYPE_CATCH_CLASSES (this_class))));
2982
  array_type 
2983 2984 2985
    = build_array_type (TREE_TYPE (TREE_TYPE (TYPE_CTABLE_DECL (this_class))),
			table_size);
  table = 
2986 2987
    build_decl (input_location,
		VAR_DECL, DECL_NAME (TYPE_CTABLE_DECL (this_class)), array_type);
2988
  DECL_INITIAL (table) = 
2989
    build_constructor_from_list (array_type, TYPE_CATCH_CLASSES (this_class));
2990 2991
  TREE_STATIC (table) = 1;
  TREE_READONLY (table) = 1;  
2992
  DECL_IGNORED_P (table) = 1;
2993
  rest_of_decl_compilation (table, 1, 0);
2994
  return table;
2995
}
2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045

/* 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;
}

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

static int
add_assertion_table_entry (void **htab_entry, void *ptr)
{
  tree entry;
  tree code_val, op1_utf8, op2_utf8;
  tree *list = (tree *) ptr;
  type_assertion *as = (type_assertion *) *htab_entry;

  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);
  
  START_RECORD_CONSTRUCTOR (entry, assertion_entry_type);
  PUSH_FIELD_VALUE (entry, "assertion_code", code_val);
  PUSH_FIELD_VALUE (entry, "op1", op1_utf8);
  PUSH_FIELD_VALUE (entry, "op2", op2_utf8);
  FINISH_RECORD_CONSTRUCTOR (entry);
  
  *list = tree_cons (NULL_TREE, entry, *list);
  return true;
}

3046
/* Generate the type assertion table for KLASS, and return its DECL.  */
3047 3048

static tree
3049
emit_assertion_table (tree klass)
3050 3051 3052
{
  tree null_entry, ctor, table_decl;
  tree list = NULL_TREE;
3053
  htab_t assertions_htab = TYPE_ASSERTIONS (klass);
3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068

  /* Iterate through the hash table.  */
  htab_traverse (assertions_htab, add_assertion_table_entry, &list);

  /* Finish with a null entry.  */
  START_RECORD_CONSTRUCTOR (null_entry, assertion_entry_type);
  PUSH_FIELD_VALUE (null_entry, "assertion_code", integer_zero_node);
  PUSH_FIELD_VALUE (null_entry, "op1", null_pointer_node);
  PUSH_FIELD_VALUE (null_entry, "op2", null_pointer_node);
  FINISH_RECORD_CONSTRUCTOR (null_entry);
  
  list = tree_cons (NULL_TREE, null_entry, list);
  
  /* Put the list in the right order and make it a constructor. */
  list = nreverse (list);
3069
  ctor = build_constructor_from_list (assertion_table_type, list);
3070

3071 3072
  table_decl = build_decl (input_location,
			   VAR_DECL, mangled_classname ("_type_assert_", klass),
3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085
			   assertion_table_type);

  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;
}
3086

Anthony Green committed
3087
void
3088
init_class_processing (void)
Anthony Green committed
3089
{
3090 3091
  fields_ident = get_identifier ("fields");
  info_ident = get_identifier ("info");
3092

Mark Mitchell committed
3093
  gcc_obstack_init (&temporary_obstack);
Anthony Green committed
3094
}
3095

3096 3097
static hashval_t java_treetreehash_hash (const void *);
static int java_treetreehash_compare (const void *, const void *);
3098 3099 3100

/* A hash table mapping trees to trees.  Used generally.  */

3101
#define JAVA_TREEHASHHASH_H(t) ((hashval_t)TYPE_UID (t))
3102 3103

static hashval_t
3104
java_treetreehash_hash (const void *k_p)
3105
{
3106 3107
  const struct treetreehash_entry *const k
    = (const struct treetreehash_entry *) k_p;
3108 3109 3110 3111
  return JAVA_TREEHASHHASH_H (k->key);
}

static int
3112
java_treetreehash_compare (const void * k1_p, const void * k2_p)
3113
{
3114 3115 3116
  const struct treetreehash_entry *const k1
    = (const struct treetreehash_entry *) k1_p;
  const_tree const k2 = (const_tree) k2_p;
3117 3118 3119 3120
  return (k1->key == k2);
}

tree 
3121
java_treetreehash_find (htab_t ht, tree t)
3122 3123 3124
{
  struct treetreehash_entry *e;
  hashval_t hv = JAVA_TREEHASHHASH_H (t);
3125
  e = (struct treetreehash_entry *) htab_find_with_hash (ht, t, hv);
3126 3127 3128 3129 3130 3131 3132
  if (e == NULL)
    return NULL;
  else
    return e->value;
}

tree *
3133
java_treetreehash_new (htab_t ht, tree t)
3134
{
3135
  void **e;
3136 3137 3138 3139 3140 3141
  struct treetreehash_entry *tthe;
  hashval_t hv = JAVA_TREEHASHHASH_H (t);

  e = htab_find_slot_with_hash (ht, t, hv, INSERT);
  if (*e == NULL)
    {
3142
      tthe = (struct treetreehash_entry *) (*ht->alloc_f) (1, sizeof (*tthe));
3143
      tthe->key = t;
3144
      *e = tthe;
3145 3146 3147 3148 3149 3150 3151
    }
  else
    tthe = (struct treetreehash_entry *) *e;
  return &tthe->value;
}

htab_t
3152
java_treetreehash_create (size_t size, int gc)
3153 3154 3155 3156 3157 3158 3159 3160 3161
{
  if (gc)
    return htab_create_ggc (size, java_treetreehash_hash,
			    java_treetreehash_compare, NULL);
  else
    return htab_create_alloc (size, java_treetreehash_hash,
			      java_treetreehash_compare, free, xcalloc, free);
}

3162 3163 3164 3165 3166 3167 3168 3169 3170 3171
/* 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);

3172
  base = (char *) alloca (l + 1);
3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220
  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);
}

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