class.c 98.5 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, 2010 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
#include "coretypes.h"
Anthony Green committed
30
#include "tree.h"
31
#include "flags.h"
Anthony Green committed
32 33 34
#include "java-tree.h"
#include "jcf.h"
#include "obstack.h"
35
#include "diagnostic-core.h"
36
#include "toplev.h"
Kaveh R. Ghazi committed
37 38
#include "output.h"
#include "parse.h"
39
#include "function.h"
40
#include "ggc.h"
41
#include "cgraph.h"
42
#include "tree-iterator.h"
43
#include "vecprim.h"
44
#include "tm.h"         /* FIXME: For gcc_obstack_init from defaults.h.  */
45
#include "target.h"
Anthony Green committed
46

47 48 49 50 51 52
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);
53
static int supers_all_compiled (tree type);
54
static tree maybe_layout_super_class (tree, tree);
55
static void add_miranda_methods (tree, tree);
56
static int assume_compiled (const char *);
57
static tree build_symbol_entry (tree, tree);
58
static tree emit_assertion_table (tree);
59
static void register_class (void);
60

Mark Mitchell committed
61
struct obstack temporary_obstack;
Anthony Green committed
62

63 64
static const char *cyclic_inheritance_report;

65 66 67 68
/* 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
69
   class_flag_node objects.  This tree is queried to determine if
70 71 72
   a class is assume to be compiled or not.  Each node in the tree
   represents either a package or a specific class.  */

73
typedef struct class_flag_node_struct
74 75 76 77
{
  /* The class or package name.  */
  const char *ident;

78
  /* Nonzero if this represents an exclusion.  */
79
  int value;
80 81

  /* Pointers to other nodes in the tree.  */
82 83 84 85
  struct class_flag_node_struct *parent;
  struct class_flag_node_struct *sibling;
  struct class_flag_node_struct *child;
} class_flag_node;
86

87 88
static class_flag_node *find_class_flag_node (class_flag_node *, const char *);
static void add_class_flag (class_flag_node **, const char *, int);
89

90 91
/* This is the root of the include/exclude tree.  */

92 93 94
static class_flag_node *assume_compiled_tree;

static class_flag_node *enable_assert_tree;
95

96 97 98 99 100 101 102
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;
103

104 105 106 107
/* A tree that returns the address of the class$ of the class
   currently being compiled.  */
static GTY(()) tree this_classdollar;

108 109 110 111
/* A list of static class fields.  This is to emit proper debug
   info for them.  */
VEC(tree,gc) *pending_static_fields;

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

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

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

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

159
  if (NULL == root)
160
    {
161
      root = XNEW (class_flag_node);
162 163 164 165 166 167
      root->ident = "";
      root->value = 0;
      root->sibling = NULL;
      root->child = NULL;
      root->parent = NULL;
      *rootp = root;
168 169 170
    }

  /* Calling the function with the empty string means we're setting
171
     value for the root of the hierarchy.  */
172 173 174

  if (0 == ident[0])
    {
175
      root->value = value;
176 177 178 179 180 181
      return;
    }

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

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

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

209
/* The default value returned by enable_assertions. */
210

211
#define DEFAULT_ENABLE_ASSERT (optimize == 0)
212 213 214 215 216 217 218 219 220 221

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

224
/* Returns nonzero if IDENT is the name of a class that the compiler
225
   should assume has been compiled to object code.  */
226

227
static int
228
assume_compiled (const char *ident)
229
{
230
  class_flag_node *i;
231 232 233 234 235
  int result;
  
  if (NULL == assume_compiled_tree)
    return 1;

236
  i = find_class_flag_node (assume_compiled_tree, ident);
237

238
  result = ! i->value;
239 240 241 242
  
  return (result);
}

243 244 245 246 247
/* Return true if we should generate code to check assertions within KLASS. */

bool
enable_assertions (tree klass)
{
248
  /* Check if command-line specifies whether we should check assertions. */
249 250 251 252 253 254 255 256 257 258 259 260 261 262

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

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

tree
373
make_class (void)
Anthony Green committed
374 375 376
{
  tree type;
  type = make_node (RECORD_TYPE);
377 378 379
  /* Unfortunately we must create the binfo here, so that class
     loading works.  */
  TYPE_BINFO (type) = make_tree_binfo (0);
380
  MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC (type);
381 382 383 384 385 386
  TYPE_CATCH_CLASSES (type) = NULL;
  /* Push a dummy entry; we can't call make_catch_class_record here
     because other infrastructure may not be set up yet.  We'll come
     back and fill it in later once said infrastructure is
     initialized.  */
  CONSTRUCTOR_APPEND_ELT (TYPE_CATCH_CLASSES (type), NULL_TREE, NULL_TREE);
Anthony Green committed
387 388 389 390 391 392 393 394 395

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

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

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

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

481 482
#undef GEN_TABLE

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

647 648 649

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

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

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

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

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

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

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

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

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

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

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

  DECL_LANG_SPECIFIC (fndecl)
768
    = ggc_alloc_cleared_lang_decl(sizeof (struct lang_decl));
769
  DECL_LANG_SPECIFIC (fndecl)->desc = LANG_DECL_FUNC;
Anthony Green committed
770

771
  /* Initialize the static initializer test table.  */
772 773

  DECL_FUNCTION_INIT_TEST_TABLE (fndecl) = java_treetreehash_create (10);
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
  DECL_CHAIN (fndecl) = TYPE_METHODS (this_class);
781
  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
  DECL_CHAIN (field) = TYPE_FIELDS (klass);
852 853
  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);
881 882
      if (!DECL_EXTERNAL (field))
	VEC_safe_push (tree, gc, pending_static_fields, field);
Anthony Green committed
883
    }
884

Anthony Green committed
885 886 887 888 889 890
  return field;
}

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

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

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

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

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
  tree ref = IDENTIFIER_UTF8_REF (name);
  tree decl;
945
  VEC(constructor_elt,gc) *v = NULL;
Anthony Green committed
946 947 948 949
  if (ref != NULL_TREE)
    return ref;

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

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

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

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

Anthony Green committed
999
  layout_decl (decl, 0);
1000 1001
  DECL_SIZE (decl) = TYPE_SIZE (ctype);
  DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (ctype);
Anthony Green committed
1002
  pushdecl (decl);
1003
  rest_of_decl_compilation (decl, global_bindings_p (), 0);
1004
  varpool_mark_needed_node (varpool_node (decl));
Anthony Green committed
1005 1006 1007 1008 1009
  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

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

1397
  targetm.asm_out.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
  VEC(constructor_elt,gc) *v = NULL;
1429

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

1438
      type = build_utf8_ref (unmangle_classname 
1439 1440
			     (IDENTIFIER_POINTER (signature),
			      IDENTIFIER_LENGTH (signature)));
1441
    }
1442
  PUSH_FIELD_VALUE (v, "type", type);
1443

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

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

1451 1452
  {
    tree field_address = integer_zero_node;
1453
    tree index, value;
Andrew Haley committed
1454 1455
    if ((DECL_INITIAL (fdecl) || ! flag_indirect_classes) 
	&& FIELD_STATIC (fdecl))
1456 1457
      field_address = build_address_of (fdecl);

1458
    index = (FIELD_STATIC (fdecl)
1459
	     ? DECL_CHAIN (TYPE_FIELDS (field_info_union_node))
1460 1461
	     : TYPE_FIELDS (field_info_union_node));
    value = (FIELD_STATIC (fdecl)
1462
	     ? field_address
1463 1464 1465 1466 1467
	     : byte_position (fdecl));

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

1470
  FINISH_RECORD_CONSTRUCTOR (finit, v, field_type_node);
Anthony Green committed
1471 1472 1473
  return finit;
}

1474 1475
/** Make reflection data (_Jv_Method) for method MDECL. */

1476
static tree
1477
make_method_value (tree mdecl)
Anthony Green committed
1478
{
1479
  static int method_name_count = 0;
Anthony Green committed
1480
  tree minit;
1481
  tree index;
Anthony Green committed
1482
  tree code;
Bryce McKinlay committed
1483
  tree class_decl;
Anthony Green committed
1484 1485
#define ACC_TRANSLATED          0x4000
  int accflags = get_access_flags_from_decl (mdecl) | ACC_TRANSLATED;
1486
  VEC(constructor_elt,gc) *v = NULL;
1487

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

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

  {
    /* Compute the `throws' information for the method.  */
1524
    tree table = null_pointer_node;
1525 1526

    if (!VEC_empty (tree, DECL_FUNCTION_THROWS (mdecl)))
1527
      {
1528 1529
	int length = 1 + VEC_length (tree, DECL_FUNCTION_THROWS (mdecl));
	tree t, type, array;
1530
	char buf[60];
1531 1532 1533 1534 1535 1536 1537 1538 1539 1540
	VEC(constructor_elt,gc) *v = NULL;
	int idx = length - 1;
	unsigned ix;
	constructor_elt *e;

	v = VEC_alloc (constructor_elt, gc, length);
	VEC_safe_grow_cleared (constructor_elt, gc, v, length);

	e = VEC_index (constructor_elt, v, idx--);
	e->value = null_pointer_node;
1541

1542
	FOR_EACH_VEC_ELT (tree, DECL_FUNCTION_THROWS (mdecl), ix, t)
1543
	  {
1544
	    tree sig = DECL_NAME (TYPE_NAME (t));
1545 1546 1547
	    tree utf8
	      = build_utf8_ref (unmangle_classname (IDENTIFIER_POINTER (sig),
						    IDENTIFIER_LENGTH (sig)));
1548 1549
	    e = VEC_index (constructor_elt, v, idx--);
	    e->value = utf8;
1550
	  }
1551
	gcc_assert (idx == -1);
1552
	type = build_prim_array_type (ptr_type_node, length);
1553
	table = build_constructor (type, v);
1554 1555
	/* Compute something unique enough.  */
	sprintf (buf, "_methods%d", method_name_count++);
1556 1557
	array = build_decl (input_location,
			    VAR_DECL, get_identifier (buf), type);
1558 1559 1560 1561
	DECL_INITIAL (array) = table;
	TREE_STATIC (array) = 1;
	DECL_ARTIFICIAL (array) = 1;
	DECL_IGNORED_P (array) = 1;
1562
	rest_of_decl_compilation (array, 1, 0);
1563 1564 1565 1566

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

1567
    PUSH_FIELD_VALUE (v, "throws", table);
1568 1569
  }

1570
  FINISH_RECORD_CONSTRUCTOR (minit, v, method_type_node);
Anthony Green committed
1571 1572 1573
  return minit;
}

1574
static tree
1575
get_dispatch_vector (tree type)
Anthony Green committed
1576 1577
{
  tree vtable = TYPE_VTABLE (type);
1578 1579

  if (vtable == NULL_TREE)
Anthony Green committed
1580
    {
1581
      HOST_WIDE_INT i;
Anthony Green committed
1582 1583
      tree method;
      tree super = CLASSTYPE_SUPER (type);
1584
      HOST_WIDE_INT nvirtuals = tree_low_cst (TYPE_NVIRTUALS (type), 0);
Anthony Green committed
1585 1586 1587 1588 1589
      vtable = make_tree_vec (nvirtuals);
      TYPE_VTABLE (type) = vtable;
      if (super != NULL_TREE)
	{
	  tree super_vtable = get_dispatch_vector (super);
1590 1591

	  for (i = tree_low_cst (TYPE_NVIRTUALS (super), 0); --i >= 0; )
Anthony Green committed
1592 1593
	    TREE_VEC_ELT (vtable, i) = TREE_VEC_ELT (super_vtable, i);
	}
1594

Anthony Green committed
1595
      for (method = TYPE_METHODS (type);  method != NULL_TREE;
1596
	   method = DECL_CHAIN (method))
1597 1598 1599 1600 1601 1602
	{
	  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
1603
    }
1604

Anthony Green committed
1605 1606 1607
  return vtable;
}

1608
static tree
1609
get_dispatch_table (tree type, tree this_class_addr)
Anthony Green committed
1610
{
1611
  int abstract_p = CLASS_ABSTRACT (TYPE_NAME (type));
Anthony Green committed
1612
  tree vtable = get_dispatch_vector (type);
1613
  int i, j;
Anthony Green committed
1614
  int nvirtuals = TREE_VEC_LENGTH (vtable);
1615
  int arraysize;
1616
  tree gc_descr;
1617 1618 1619 1620 1621 1622 1623 1624
  VEC(constructor_elt,gc) *v = NULL;
  constructor_elt *e;
  tree arraytype;

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

1626 1627 1628 1629
  VEC_safe_grow_cleared (constructor_elt, gc, v, arraysize);
  e = VEC_index (constructor_elt, v, arraysize - 1);

#define CONSTRUCTOR_PREPEND_VALUE(E, V) E->value = V, E--
Anthony Green committed
1630 1631 1632 1633
  for (i = nvirtuals;  --i >= 0; )
    {
      tree method = TREE_VEC_ELT (vtable, i);
      if (METHOD_ABSTRACT (method))
1634 1635
	{
	  if (! abstract_p)
1636 1637
	    warning_at (DECL_SOURCE_LOCATION (method), 0,
			"abstract method in non-abstract class");
1638 1639 1640

	  if (TARGET_VTABLE_USES_DESCRIPTORS)
	    for (j = 0; j < TARGET_VTABLE_USES_DESCRIPTORS; ++j)
1641
	      CONSTRUCTOR_PREPEND_VALUE (e, null_pointer_node);
1642
	  else
1643
	    CONSTRUCTOR_PREPEND_VALUE (e, null_pointer_node);
1644 1645 1646
	}
      else
	{
1647 1648 1649
	  if (TARGET_VTABLE_USES_DESCRIPTORS)
	    for (j = 0; j < TARGET_VTABLE_USES_DESCRIPTORS; ++j)
	      {
1650
		tree fdesc = build2 (FDESC_EXPR, nativecode_ptr_type_node, 
1651
				     method, build_int_cst (NULL_TREE, j));
1652
		TREE_CONSTANT (fdesc) = 1;
1653
		CONSTRUCTOR_PREPEND_VALUE (e, fdesc);
1654 1655
	      }
	  else
1656 1657 1658 1659
	    CONSTRUCTOR_PREPEND_VALUE (e,
				       build1 (ADDR_EXPR,
					       nativecode_ptr_type_node,
					       method));
1660
	}
Anthony Green committed
1661
    }
1662

1663 1664
  /* Dummy entry for compatibility with G++ -fvtable-thunks.  When
     using the Boehm GC we sometimes stash a GC type descriptor
1665 1666
     there. We set the PURPOSE to NULL_TREE not to interfere (reset)
     the emitted byte count during the output to the assembly file. */
1667 1668 1669 1670 1671
  /* 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);
1672
  CONSTRUCTOR_PREPEND_VALUE (e, gc_descr);
1673
  for (j = 1; j < TARGET_VTABLE_USES_DESCRIPTORS-1; ++j)
1674 1675
    CONSTRUCTOR_PREPEND_VALUE (e, gc_descr);
  CONSTRUCTOR_PREPEND_VALUE (e, this_class_addr);
1676 1677

  /** Pointer to type_info object (to be implemented), according to g++ ABI. */
1678
  CONSTRUCTOR_PREPEND_VALUE (e, null_pointer_node);
1679
  /** Offset to start of whole object.  Always (ptrdiff_t)0 for Java. */
1680 1681 1682 1683
  gcc_assert (e == VEC_address (constructor_elt, v));
  e->index = integer_zero_node;
  e->value = null_pointer_node;
#undef CONSTRUCTOR_PREPEND_VALUE
1684

1685 1686
  arraytype = build_prim_array_type (nativecode_ptr_type_node, arraysize);
  return build_constructor (arraytype, v);
Anthony Green committed
1687 1688
}

1689 1690 1691 1692 1693

/* Set the method_index for a method decl.  */
void
set_method_index (tree decl, tree method_index)
{
1694 1695 1696 1697
  if (method_index != NULL_TREE)
    {
      /* method_index is null if we're using indirect dispatch.  */
      method_index = fold (convert (sizetype, method_index));
1698

1699 1700 1701 1702 1703 1704 1705 1706
      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));
    }
1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729

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

1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741
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;
}

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

1799
  this_class_addr = build_static_class_ref (type);
Anthony Green committed
1800 1801
  decl = TREE_OPERAND (this_class_addr, 0);

1802 1803 1804 1805
  if (supers_all_compiled (type) && ! CLASS_INTERFACE (type_decl)
      && !flag_indirect_dispatch)
    {
      tree dtable = get_dispatch_table (type, this_class_addr);
1806
      uses_jv_markobj = uses_jv_markobj_p (dtable);
1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821
      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;
	}

1822
      TREE_PUBLIC (dtable_decl) = 1;
1823
      DECL_INITIAL (dtable_decl) = dtable;
1824 1825 1826
      /* The only dispatch table exported from a DSO is the dispatch
	 table for java.lang.Class.  */
      if (DECL_NAME (type_decl) != id_class)
1827
	java_hide_decl (dtable_decl);
1828 1829
      if (! flag_indirect_classes)
	rest_of_decl_compilation (dtable_decl, 1, 0);
1830 1831 1832
      /* 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)
1833 1834 1835
	class_dtable_decl = dtable_decl;
    }

Anthony Green committed
1836 1837
  /* Build Field array. */
  field = TYPE_FIELDS (type);
1838
  while (field && DECL_ARTIFICIAL (field))
1839
    field = DECL_CHAIN (field);  /* Skip dummy fields.  */
1840
  if (field && DECL_NAME (field) == NULL_TREE)
1841
    field = DECL_CHAIN (field);  /* Skip dummy field for inherited data. */
1842 1843 1844
  first_real_field = field;

  /* First count static and instance fields.  */
1845
  for ( ; field != NULL_TREE; field = DECL_CHAIN (field))
1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860
    {
      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
1861
     that data contains indexes into the fields.  So, we generate a
1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873
     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; 
1874
	 field = DECL_CHAIN (field), i++)
1875 1876 1877 1878 1879 1880 1881 1882
    {
      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++;
1883 1884
	  else
	    continue;
1885 1886 1887 1888 1889 1890
	  VEC_quick_push (int, field_indexes, field_index);
	}
    }
  }

  for (field = first_real_field; field != NULL_TREE; 
1891
       field = DECL_CHAIN (field))
Anthony Green committed
1892 1893 1894 1895 1896
    {
      if (! DECL_ARTIFICIAL (field))
	{
	  if (FIELD_STATIC (field))
	    {
1897 1898 1899
              /* 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);
1900
	      tree initial = DECL_INITIAL (field);
1901
              CONSTRUCTOR_APPEND_ELT (static_fields, NULL_TREE, init);
1902 1903 1904 1905 1906
	      /* 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;
1907
	      rest_of_decl_compilation (field, 1, 1);
1908
	      DECL_INITIAL (field) = initial;
Anthony Green committed
1909
	    }
1910
	  else if (uses_jv_markobj || !flag_reduced_reflection)
Anthony Green committed
1911
	    {
1912
              tree init = make_field_value (field);
1913
              CONSTRUCTOR_APPEND_ELT (instance_fields, NULL_TREE, init);
Anthony Green committed
1914 1915 1916
	    }
	}
    }
1917

1918
  gcc_assert (static_field_count
1919
              == (int) VEC_length (constructor_elt, static_fields));
1920
  gcc_assert (instance_field_count
1921
              == (int) VEC_length (constructor_elt, instance_fields));
1922

Anthony Green committed
1923 1924
  if (field_count > 0)
    {
1925
      VEC_safe_splice (constructor_elt, gc, static_fields, instance_fields);
Anthony Green committed
1926
      field_array_type = build_prim_array_type (field_type_node, field_count);
1927 1928
      fields_decl = build_decl (input_location,
				VAR_DECL, mangled_classname ("_FL_", type),
Anthony Green committed
1929
				field_array_type);
1930 1931
      DECL_INITIAL (fields_decl)
        = build_constructor (field_array_type, static_fields);
Anthony Green committed
1932 1933 1934
      TREE_STATIC (fields_decl) = 1;
      DECL_ARTIFICIAL (fields_decl) = 1;
      DECL_IGNORED_P (fields_decl) = 1;
1935
      rest_of_decl_compilation (fields_decl, 1, 0);
Anthony Green committed
1936 1937 1938 1939 1940
    }
  else
    fields_decl = NULL_TREE;

  /* Build Method array. */
1941
  for (method = TYPE_METHODS (type);
1942
       method != NULL_TREE; method = DECL_CHAIN (method))
Anthony Green committed
1943
    {
1944 1945
      tree init;
      if (METHOD_PRIVATE (method)
1946
	  && ! flag_keep_inline_functions
1947
	  && optimize)
1948
	continue;
1949
      /* Even if we have a decl, we don't necessarily have the code.
1950 1951 1952 1953
	 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;
1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975

      /* 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
1976
          || (METHOD_PUBLIC (method) && !METHOD_STATIC (method)))
1977 1978 1979
        {
          init = make_method_value (method);
          method_count++;
1980
          CONSTRUCTOR_APPEND_ELT (methods, NULL_TREE, init);
1981
        }
Anthony Green committed
1982 1983
    }
  method_array_type = build_prim_array_type (method_type_node, method_count);
1984 1985
  methods_decl = build_decl (input_location,
			     VAR_DECL, mangled_classname ("_MT_", type),
Anthony Green committed
1986
			     method_array_type);
1987
  DECL_INITIAL (methods_decl) = build_constructor (method_array_type, methods);
Anthony Green committed
1988 1989 1990
  TREE_STATIC (methods_decl) = 1;
  DECL_ARTIFICIAL (methods_decl) = 1;
  DECL_IGNORED_P (methods_decl) = 1;
1991
  rest_of_decl_compilation (methods_decl, 1, 0);
Anthony Green committed
1992

1993 1994 1995 1996 1997 1998
  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;
1999
      if (is_compiled_class (class_type_node) != 2)
2000 2001 2002 2003
	{
	  DECL_EXTERNAL (class_dtable_decl) = 1;
	  rest_of_decl_compilation (class_dtable_decl, 1, 0);
	}
Anthony Green committed
2004 2005 2006 2007 2008
    }

  super = CLASSTYPE_SUPER (type);
  if (super == NULL_TREE)
    super = null_pointer_node;
2009 2010
  else if (! flag_indirect_dispatch
	   && assume_compiled (IDENTIFIER_POINTER (DECL_NAME (type_decl)))
2011
	   && assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (super)))))
Anthony Green committed
2012 2013 2014 2015
    super = build_class_ref (super);
  else
    {
      int super_index = alloc_class_constant (super);
2016
      super = build_int_cst (ptr_type_node, super_index);
Anthony Green committed
2017 2018 2019 2020
    }

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

  constant_pool_constructor = build_constants_constructor ();

2061 2062 2063 2064 2065 2066
  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), 
2067
	 TYPE_OTABLE_SYMS_DECL (type), integer_type_node, 1);
2068 2069 2070 2071 2072
       
      TYPE_ATABLE_DECL (type) 
	= emit_symbol_table 
	(DECL_NAME (TYPE_ATABLE_DECL (type)), 
	 TYPE_ATABLE_DECL (type), TYPE_ATABLE_METHODS (type), 
2073 2074 2075 2076 2077 2078 2079
	 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);
2080 2081 2082 2083
    }
  
  TYPE_CTABLE_DECL (type) = emit_catch_table (type);

2084 2085
  START_RECORD_CONSTRUCTOR (v1, object_type_node);
  PUSH_FIELD_VALUE (v1, "vtable",
2086 2087
		    (flag_indirect_classes 
		     ? null_pointer_node
Andrew Pinski committed
2088
		     : build2 (POINTER_PLUS_EXPR, dtable_ptr_type,
2089 2090 2091
			       build1 (ADDR_EXPR, dtable_ptr_type,
				       class_dtable_decl),
			       dtable_start_offset)));
2092
  if (! flag_hash_synchronization)
2093 2094 2095 2096 2097 2098 2099
    PUSH_FIELD_VALUE (v1, "sync_info", null_pointer_node);
  FINISH_RECORD_CONSTRUCTOR (temp, v1, object_type_node);
  START_RECORD_CONSTRUCTOR (v2, class_type_node);
  PUSH_SUPER_VALUE (v2, temp);
  PUSH_FIELD_VALUE (v2, "next_or_version", gcj_abi_version);
  PUSH_FIELD_VALUE (v2, "name", build_utf8_ref (DECL_NAME (type_decl)));
  PUSH_FIELD_VALUE (v2, "accflags",
2100
		    build_int_cst (NULL_TREE,
2101
				   get_access_flags_from_decl (type_decl)));
Anthony Green committed
2102

2103
  PUSH_FIELD_VALUE (v2, "superclass", 
2104
		    CLASS_INTERFACE (type_decl) ? null_pointer_node : super);
2105 2106
  PUSH_FIELD_VALUE (v2, "constants", constant_pool_constructor);
  PUSH_FIELD_VALUE (v2, "methods",
2107 2108
                    methods_decl == NULL_TREE ? null_pointer_node
		    : build1 (ADDR_EXPR, method_ptr_type_node, methods_decl));
2109
  PUSH_FIELD_VALUE (v2, "method_count",
2110
		    build_int_cst (NULL_TREE, method_count));
2111

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

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

2158 2159 2160 2161 2162 2163
  PUSH_FIELD_VALUE (v2, "thread", null_pointer_node);
  PUSH_FIELD_VALUE (v2, "depth", integer_zero_node);
  PUSH_FIELD_VALUE (v2, "ancestors", null_pointer_node);
  PUSH_FIELD_VALUE (v2, "idt", null_pointer_node);
  PUSH_FIELD_VALUE (v2, "arrayclass", null_pointer_node);
  PUSH_FIELD_VALUE (v2, "protectionDomain", null_pointer_node);
2164 2165 2166 2167 2168 2169 2170 2171 2172 2173

  {
    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));
    
2174
    PUSH_FIELD_VALUE (v2, "assertion_table", assertion_table_ref);
2175 2176
  }

2177 2178 2179 2180
  PUSH_FIELD_VALUE (v2, "hack_signers", null_pointer_node);
  PUSH_FIELD_VALUE (v2, "chain", null_pointer_node);
  PUSH_FIELD_VALUE (v2, "aux_info", null_pointer_node);
  PUSH_FIELD_VALUE (v2, "engine", null_pointer_node);
Per Bothner committed
2181

2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196
  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++);
2197 2198
      array = build_decl (input_location,
			  VAR_DECL, get_identifier (buf), type);
2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215

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

      reflection_data = build_address_of (array);
2218 2219 2220 2221 2222

      free (data);
      TYPE_REFLECTION_DATA (current_class) = NULL;
    }
  else
2223
    reflection_data = null_pointer_node;
2224

2225 2226
  PUSH_FIELD_VALUE (v2, "reflection_data", reflection_data);
  FINISH_RECORD_CONSTRUCTOR (cons, v2, class_type_node);
Anthony Green committed
2227 2228

  DECL_INITIAL (decl) = cons;
2229 2230 2231 2232 2233
  
  /* Hash synchronization requires at least 64-bit alignment. */
  if (flag_hash_synchronization && POINTER_SIZE < 64)
    DECL_ALIGN (decl) = 64; 
  
2234 2235 2236 2237 2238 2239
  if (flag_indirect_classes)
    {
      TREE_READONLY (decl) = 1;
      TREE_CONSTANT (DECL_INITIAL (decl)) = 1;
    }

2240
  rest_of_decl_compilation (decl, 1, 0);
2241
  
2242 2243 2244 2245 2246 2247 2248
  {
    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);
  }

2249 2250 2251
  TYPE_OTABLE_DECL (type) = NULL_TREE;
  TYPE_ATABLE_DECL (type) = NULL_TREE;
  TYPE_CTABLE_DECL (type) = NULL_TREE;
Anthony Green committed
2252 2253
}

2254
void
2255
finish_class (void)
2256
{
2257 2258
  java_expand_catch_classes (current_class);

2259
  current_function_decl = NULL_TREE;
2260
  TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (current_class)) = 0;
2261 2262
  make_class_data (current_class);
  register_class ();
2263
  rest_of_decl_compilation (TYPE_NAME (current_class), 1, 0);
2264 2265
}

2266 2267 2268
/* 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
2269 2270
   Returns 1 for primitive and 0 for array types.  */
int
2271
is_compiled_class (tree klass)
Anthony Green committed
2272
{
2273
  int seen_in_zip;
2274 2275 2276
  if (TREE_CODE (klass) == POINTER_TYPE)
    klass = TREE_TYPE (klass);
  if (TREE_CODE (klass) != RECORD_TYPE)  /* Primitive types are static. */
Anthony Green committed
2277
    return 1;
2278
  if (TYPE_ARRAY_P (klass))
Anthony Green committed
2279
    return 0;
2280

2281 2282
  seen_in_zip = (TYPE_JCF (klass) && JCF_SEEN_IN_ZIP (TYPE_JCF (klass)));
  if (CLASS_FROM_CURRENTLY_COMPILED_P (klass))
Anthony Green committed
2283 2284 2285 2286
    {
      /* 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
2287
	 build_class_ref () from crashing. */
Anthony Green committed
2288

2289 2290
      if (seen_in_zip && !CLASS_LOADED_P (klass) && (klass != current_class))
        load_class (klass, 1);
2291 2292 2293

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

2297
  if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (klass)))))
Anthony Green committed
2298
    {
2299
      if (!CLASS_LOADED_P (klass))
2300
	{
2301 2302
	  if (klass != current_class)
	    load_class (klass, 1);
2303
	}
Anthony Green committed
2304 2305 2306 2307 2308 2309 2310 2311 2312
      return 1;
    }

  return 0;
}

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

tree
2313
build_dtable_decl (tree type)
Anthony Green committed
2314
{
2315
  tree dtype, decl;
2316 2317 2318 2319

  /* 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
2320
     compiler.) We know we're not faking a class when CURRENT_CLASS is
2321 2322 2323
     TYPE. */
  if (current_class == type)
    {
2324 2325
      tree dummy = NULL_TREE;
      int n;
2326 2327

      dtype = make_node (RECORD_TYPE);
2328

2329 2330
      PUSH_FIELD (input_location, dtype, dummy, "top_offset", ptr_type_node);
      PUSH_FIELD (input_location, dtype, dummy, "type_info", ptr_type_node);
2331

2332
      PUSH_FIELD (input_location, dtype, dummy, "class", class_ptr_type);
2333 2334
      for (n = 1; n < TARGET_VTABLE_USES_DESCRIPTORS; ++n)
	{
2335 2336
	  tree tmp_field = build_decl (input_location,
				       FIELD_DECL, NULL_TREE, ptr_type_node);
2337 2338 2339 2340 2341 2342
	  TREE_CHAIN (dummy) = tmp_field;
	  DECL_CONTEXT (tmp_field) = dtype;
	  DECL_ARTIFICIAL (tmp_field) = 1;
	  dummy = tmp_field;
	}

2343
      PUSH_FIELD (input_location, dtype, dummy, "gc_descr", ptr_type_node);
2344 2345
      for (n = 1; n < TARGET_VTABLE_USES_DESCRIPTORS; ++n)
	{
2346 2347
	  tree tmp_field = build_decl (input_location,
				       FIELD_DECL, NULL_TREE, ptr_type_node);
2348 2349 2350 2351 2352 2353 2354 2355 2356 2357
	  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;

2358
      PUSH_FIELD (input_location, dtype, dummy, "methods",
2359
		  build_prim_array_type (nativecode_ptr_type_node, n));
2360 2361 2362 2363 2364
      layout_type (dtype);
    }
  else
    dtype = dtable_type;

2365 2366
  decl = build_decl (input_location,
		     VAR_DECL, get_identifier ("vt$"), dtype);
2367 2368 2369 2370 2371
  DECL_CONTEXT (decl) = type;
  MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
  DECL_VTABLE_P (decl) = 1;

  return decl;
Anthony Green committed
2372 2373 2374 2375 2376 2377
}

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

void
2378
push_super_field (tree this_class, tree super_class)
Anthony Green committed
2379 2380
{
  tree base_decl;
2381 2382 2383
  /* 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;
2384 2385
  base_decl = build_decl (input_location,
			  FIELD_DECL, NULL_TREE, super_class);
Anthony Green committed
2386
  DECL_IGNORED_P (base_decl) = 1;
2387
  DECL_CHAIN (base_decl) = TYPE_FIELDS (this_class);
Anthony Green committed
2388 2389
  TYPE_FIELDS (this_class) = base_decl;
  DECL_SIZE (base_decl) = TYPE_SIZE (super_class);
2390
  DECL_SIZE_UNIT (base_decl) = TYPE_SIZE_UNIT (super_class);
Anthony Green committed
2391 2392
}

2393 2394 2395
/* Handle the different manners we may have to lay out a super class.  */

static tree
2396
maybe_layout_super_class (tree super_class, tree this_class ATTRIBUTE_UNUSED)
2397
{
2398 2399 2400
  if (!super_class)
    return NULL_TREE;
  else if (TREE_CODE (super_class) == RECORD_TYPE)
2401 2402 2403 2404 2405 2406
    {
      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  */
2407
  else if (TREE_CODE (super_class) == POINTER_TYPE)
2408
    {
2409 2410 2411
      if (TREE_TYPE (super_class) != NULL_TREE)
	super_class = TREE_TYPE (super_class);
      else
2412
	gcc_unreachable ();
2413 2414 2415 2416 2417 2418 2419
    }
  if (!TYPE_SIZE (super_class))
    safe_layout_class (super_class);

  return super_class;
}

2420 2421 2422 2423 2424
/* 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
2425
safe_layout_class (tree klass)
2426 2427 2428 2429
{
  tree save_current_class = current_class;
  location_t save_location = input_location;

2430
  layout_class (klass);
2431 2432 2433 2434 2435

  current_class = save_current_class;
  input_location = save_location;
}

Anthony Green committed
2436
void
2437
layout_class (tree this_class)
Anthony Green committed
2438
{
2439
  int i;
Anthony Green committed
2440
  tree super_class = CLASSTYPE_SUPER (this_class);
2441

2442
  class_list = tree_cons (this_class, NULL_TREE, class_list);
2443 2444 2445
  if (CLASS_BEING_LAIDOUT (this_class))
    {
      char buffer [1024];
Mark Mitchell committed
2446
      char *report;
2447
      tree current;
2448

2449
      sprintf (buffer, " with '%s'",
2450 2451 2452
	       IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (this_class))));
      obstack_grow (&temporary_obstack, buffer, strlen (buffer));

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

2472
  if (super_class && !CLASS_BEING_LAIDOUT (super_class))
Anthony Green committed
2473
    {
2474 2475 2476 2477
      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
2478 2479
	{
	  TYPE_SIZE (this_class) = error_mark_node;
2480
	  CLASS_BEING_LAIDOUT (this_class) = 0;
2481
	  class_list = TREE_CHAIN (class_list);
Anthony Green committed
2482 2483 2484
	  return;
	}
      if (TYPE_SIZE (this_class) == NULL_TREE)
2485
	push_super_field (this_class, maybe_super_class);
Anthony Green committed
2486 2487 2488
    }

  layout_type (this_class);
2489

2490 2491
  /* Also recursively load/layout any superinterfaces.  */
  if (TYPE_BINFO (this_class))
2492
    {
2493
      for (i = BINFO_N_BASE_BINFOS (TYPE_BINFO (this_class)) - 1; i > 0; i--)
2494
	{
2495 2496 2497 2498 2499 2500
	  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)
2501
	    {
2502 2503 2504 2505
	      TYPE_SIZE (this_class) = error_mark_node;
	      CLASS_BEING_LAIDOUT (this_class) = 0;
	      class_list = TREE_CHAIN (class_list);
	      return;
2506 2507 2508 2509
	    }
	}
    }

2510 2511
  /* Convert the size back to an SI integer value.  */
  TYPE_SIZE_UNIT (this_class) =
2512
    fold (convert (int_type_node, TYPE_SIZE_UNIT (this_class)));
2513 2514

  CLASS_BEING_LAIDOUT (this_class) = 0;
2515
  class_list = TREE_CHAIN (class_list);
2516
}
Anthony Green committed
2517

2518 2519 2520
static void
add_miranda_methods (tree base_class, tree search_class)
{
Nathan Sidwell committed
2521
  int i;
2522 2523 2524 2525
  tree binfo, base_binfo;

  if (!CLASS_PARSED_P (search_class))
    load_class (search_class, 1);
Nathan Sidwell committed
2526 2527 2528
  
  for (binfo = TYPE_BINFO (search_class), i = 1;
       BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
2529 2530
    {
      tree method_decl;
Nathan Sidwell committed
2531
      tree elt = BINFO_TYPE (base_binfo);
2532

2533 2534 2535 2536 2537
      /* 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;

2538
      /* Ensure that interface methods are seen in declared order.  */
2539 2540
      if (!CLASS_LOADED_P (elt))
	load_class (elt, 1);
2541 2542 2543 2544 2545
      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.  */
2546
      for (method_decl = TYPE_METHODS (elt);
2547
	   method_decl; method_decl = DECL_CHAIN (method_decl))
2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575
	{
	  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);
    }
}

2576
void
2577
layout_class_methods (tree this_class)
2578 2579
{
  tree method_decl, dtable_count;
2580
  tree super_class, type_name;
2581 2582 2583

  if (TYPE_NVIRTUALS (this_class))
    return;
2584
  
2585
  super_class = CLASSTYPE_SUPER (this_class);
Anthony Green committed
2586

2587
  if (super_class)
Anthony Green committed
2588
    {
2589
      super_class = maybe_layout_super_class (super_class, this_class);
2590 2591 2592 2593 2594 2595
      if (!TYPE_NVIRTUALS (super_class))
	layout_class_methods (super_class);
      dtable_count = TYPE_NVIRTUALS (super_class);
    }
  else
    dtable_count = integer_zero_node;
2596

2597
  type_name = TYPE_NAME (this_class);
2598 2599
  if (!flag_indirect_dispatch
      && (CLASS_ABSTRACT (type_name) || CLASS_INTERFACE (type_name)))
2600 2601 2602 2603 2604 2605 2606 2607
    {
      /* 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);
    }

2608
  TYPE_METHODS (this_class) = nreverse (TYPE_METHODS (this_class));
2609

2610
  for (method_decl = TYPE_METHODS (this_class);
2611
       method_decl; method_decl = DECL_CHAIN (method_decl))
2612
    dtable_count = layout_class_method (this_class, super_class,
2613 2614 2615 2616 2617
					method_decl, dtable_count);

  TYPE_NVIRTUALS (this_class) = dtable_count;
}

2618 2619
/* Return the index of METHOD in INTERFACE.  This index begins at 1
   and is used as an argument for _Jv_LookupInterfaceMethodIdx(). */
Bryce McKinlay committed
2620 2621 2622 2623 2624 2625
int
get_interface_method_index (tree method, tree interface)
{
  tree meth;
  int i = 1;

2626
  for (meth = TYPE_METHODS (interface); ; meth = DECL_CHAIN (meth))
Bryce McKinlay committed
2627 2628 2629
    {
      if (meth == method)
	return i;
2630 2631 2632
      /* We don't want to put <clinit> into the interface table.  */
      if (! ID_CLINIT_P (DECL_NAME (meth)))
	++i;
2633
      gcc_assert (meth != NULL_TREE);
Bryce McKinlay committed
2634 2635 2636
    }
}

2637
/* Lay METHOD_DECL out, returning a possibly new value of
2638
   DTABLE_COUNT. Also mangle the method's name. */
2639 2640

tree
2641 2642
layout_class_method (tree this_class, tree super_class,
		     tree method_decl, tree dtable_count)
2643 2644
{
  tree method_name = DECL_NAME (method_decl);
2645 2646

  TREE_PUBLIC (method_decl) = 1;
2647

2648 2649 2650 2651
  if (flag_indirect_classes
      || (METHOD_PRIVATE (method_decl) && METHOD_STATIC (method_decl)
	  && ! METHOD_NATIVE (method_decl)
	  && ! special_method_p (method_decl)))
2652
    java_hide_decl (method_decl);
2653

2654
  /* Considered external unless it is being compiled into this object
2655 2656 2657 2658
     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));
2659

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

2723
  return dtable_count;
Anthony Green committed
2724 2725
}

2726
static void
2727
register_class (void)
Anthony Green committed
2728
{
2729 2730
  tree node;

Anthony Green committed
2731
  if (!registered_class)
2732
    registered_class = VEC_alloc (tree, gc, 8);
Anthony Green committed
2733

2734 2735 2736 2737
  if (flag_indirect_classes)
    node = current_class;
  else
    node = TREE_OPERAND (build_class_ref (current_class), 0);
2738
  VEC_safe_push (tree, gc, registered_class, node);
Anthony Green committed
2739 2740
}

2741 2742
/* Emit a function that calls _Jv_RegisterNewClasses with a list of
   all the classes we have emitted.  */
2743 2744 2745 2746 2747 2748 2749 2750

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

  int size = VEC_length (tree, registered_class) * 2 + 1;
2751
  VEC(constructor_elt,gc) *init = VEC_alloc (constructor_elt, gc, size);
2752 2753
  tree class_array_type
    = build_prim_array_type (ptr_type_node, size);
2754 2755
  tree cdecl = build_decl (input_location,
			   VAR_DECL, get_identifier ("_Jv_CLS"),
2756 2757
			   class_array_type);
  tree reg_class_list;
2758
  FOR_EACH_VEC_ELT (tree, registered_class, i, klass)
2759
    {
2760 2761 2762 2763 2764 2765 2766 2767
      t = fold_convert (ptr_type_node, build_static_class_ref (klass));
      CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, t);
      t = fold_convert (ptr_type_node,
                        build_address_of (build_classdollar_field (klass)));
      CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, t);
    }
  CONSTRUCTOR_APPEND_ELT (init, NULL_TREE, integer_zero_node);
  DECL_INITIAL (cdecl) = build_constructor (class_array_type, init);
2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778
  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);
2779 2780
  t = build_decl (input_location,
		  FUNCTION_DECL, 
2781 2782 2783 2784
		  get_identifier ("_Jv_RegisterNewClasses"), t);
  TREE_PUBLIC (t) = 1;
  DECL_EXTERNAL (t) = 1;
  register_class_fn = t;
2785
  t = build_call_expr (register_class_fn, 1, reg_class_list);
2786 2787 2788 2789
  append_to_statement_list (t, list_p);
}


2790 2791 2792
/* Emit something to register classes at start-up time.

   The preferred mechanism is through the .jcr section, which contain
2793 2794 2795 2796 2797 2798
   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
2799 2800

void
2801
emit_register_classes (tree *list_p)
Anthony Green committed
2802
{
2803 2804 2805
  if (registered_class == NULL)
    return;

2806 2807 2808 2809 2810 2811
  if (flag_indirect_classes)
    {
      emit_indirect_register_classes (list_p);
      return;
    }

2812 2813 2814
  /* 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
2815
     targets can override the default in tm.h to use the fallback mechanism.  */
2816
  if (TARGET_USE_JCR_SECTION)
2817
    {
2818 2819 2820
      tree klass, t;
      int i;

2821
#ifdef JCR_SECTION_NAME
2822
      switch_to_section (get_section (JCR_SECTION_NAME, SECTION_WRITE, NULL));
2823 2824 2825 2826 2827
#else
      /* A target has defined TARGET_USE_JCR_SECTION,
	 but doesn't have a JCR_SECTION_NAME.  */
      gcc_unreachable ();
#endif
2828
      assemble_align (POINTER_SIZE);
2829

2830
      FOR_EACH_VEC_ELT (tree, registered_class, i, klass)
Jan Hubicka committed
2831
	{
2832 2833
	  t = build_fold_addr_expr (klass);
	  output_constant (t, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE);
Jan Hubicka committed
2834
	}
2835 2836 2837
    }
  else
    {
2838
      tree klass, t, register_class_fn;
2839
      int i;
2840 2841

      t = build_function_type_list (void_type_node, class_ptr_type, NULL);
2842 2843
      t = build_decl (input_location,
		      FUNCTION_DECL, get_identifier ("_Jv_RegisterClass"), t);
2844 2845 2846 2847
      TREE_PUBLIC (t) = 1;
      DECL_EXTERNAL (t) = 1;
      register_class_fn = t;

2848
      FOR_EACH_VEC_ELT (tree, registered_class, i, klass)
2849 2850
	{
	  t = build_fold_addr_expr (klass);
2851
	  t = build_call_expr (register_class_fn, 1, t);
2852 2853
	  append_to_statement_list (t, list_p);
	}
2854
    }
Anthony Green committed
2855 2856
}

2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874
/* Build a constructor for an entry in the symbol table.  */

static tree
build_symbol_table_entry (tree clname, tree name, tree signature)
{
  tree symbol;
  VEC(constructor_elt,gc) *v = NULL;

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

  return symbol;
}

2875
/* Make a symbol_type (_Jv_MethodSymbol) node for DECL. */
2876

2877
static tree
2878
build_symbol_entry (tree decl, tree special)
2879
{
2880
  tree clname, name, signature;
2881
  clname = build_utf8_ref (DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl))));
2882 2883 2884 2885 2886 2887 2888 2889
  /* ???  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));
2890
  signature = build_java_signature (TREE_TYPE (decl));
2891 2892 2893
  signature = build_utf8_ref (unmangle_classname 
			      (IDENTIFIER_POINTER (signature),
			       IDENTIFIER_LENGTH (signature)));
2894 2895 2896 2897 2898
  /* 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
2899 2900
    signature = build2 (POINTER_PLUS_EXPR, TREE_TYPE (signature), signature,
			fold_convert (sizetype, special));
2901 2902

  return build_symbol_table_entry (clname, name, signature);
2903 2904
} 

2905
/* Emit a symbol table: used by -findirect-dispatch.  */
2906

2907
tree
2908 2909
emit_symbol_table (tree name, tree the_table,
		   VEC(method_entry,gc) *decl_table,
2910 2911
                   tree the_syms_decl, tree the_array_element_type,
		   int element_size)
2912
{
2913
  tree table, null_symbol, table_size, the_array_type;
2914 2915
  unsigned index;
  method_entry *e;
2916
  VEC(constructor_elt,gc) *v = NULL;
2917
  
2918 2919
  /* Only emit a table if this translation unit actually made any
     references via it. */
2920
  if (decl_table == NULL)
2921
    return the_table;
2922 2923

  /* Build a list of _Jv_MethodSymbols for each entry in otable_methods. */
2924
  FOR_EACH_VEC_ELT (method_entry, decl_table, index, e)
2925 2926
    CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
			    build_symbol_entry (e->method, e->special));
2927 2928

  /* Terminate the list with a "null" entry. */
2929 2930 2931
  null_symbol = build_symbol_table_entry (null_pointer_node,
                                          null_pointer_node,
                                          null_pointer_node);
2932
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, null_symbol);
2933

2934
  table = build_constructor (symbols_array_type, v);
2935 2936

  /* Make it the initial value for otable_syms and emit the decl. */
2937 2938 2939
  DECL_INITIAL (the_syms_decl) = table;
  DECL_ARTIFICIAL (the_syms_decl) = 1;
  DECL_IGNORED_P (the_syms_decl) = 1;
2940
  rest_of_decl_compilation (the_syms_decl, 1, 0);
2941
  
2942 2943 2944 2945
  /* 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. */
2946 2947
  table_size 
    = build_index_type (build_int_cst (NULL_TREE, index * element_size + 1));
2948
  the_array_type = build_array_type (the_array_element_type, table_size);
2949 2950
  the_table = build_decl (input_location,
			  VAR_DECL, name, the_array_type);
2951 2952
  TREE_STATIC (the_table) = 1;
  TREE_READONLY (the_table) = 1;  
2953
  rest_of_decl_compilation (the_table, 1, 0);
2954 2955

  return the_table;
2956 2957
}

2958
/* Make an entry for the catch_classes list.  */
2959 2960 2961 2962
tree
make_catch_class_record (tree catch_class, tree classname)
{
  tree entry;
2963
  tree type = TREE_TYPE (TREE_TYPE (TYPE_CTABLE_DECL (output_class)));
2964 2965 2966 2967 2968
  VEC(constructor_elt,gc) *v = NULL;
  START_RECORD_CONSTRUCTOR (v, type);
  PUSH_FIELD_VALUE (v, "address", catch_class);
  PUSH_FIELD_VALUE (v, "classname", classname);
  FINISH_RECORD_CONSTRUCTOR (entry, v, type);
2969 2970 2971 2972 2973
  return entry;
}


/* Generate the list of Throwable classes that are caught by exception
2974 2975 2976
   handlers in this class.  */
tree 
emit_catch_table (tree this_class)
2977 2978
{
  tree table, table_size, array_type;
2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989
  int n_catch_classes;
  constructor_elt *e;
  /* Fill in the dummy entry that make_class created.  */
  e = VEC_index (constructor_elt, TYPE_CATCH_CLASSES (this_class), 0);
  e->value = make_catch_class_record (null_pointer_node, null_pointer_node);
  CONSTRUCTOR_APPEND_ELT (TYPE_CATCH_CLASSES (this_class), NULL_TREE,
			  make_catch_class_record (null_pointer_node,
						   null_pointer_node));
  n_catch_classes = VEC_length (constructor_elt,
				TYPE_CATCH_CLASSES (this_class));
  table_size = build_index_type (build_int_cst (NULL_TREE, n_catch_classes));
2990
  array_type 
2991 2992 2993
    = build_array_type (TREE_TYPE (TREE_TYPE (TYPE_CTABLE_DECL (this_class))),
			table_size);
  table = 
2994 2995
    build_decl (input_location,
		VAR_DECL, DECL_NAME (TYPE_CTABLE_DECL (this_class)), array_type);
2996
  DECL_INITIAL (table) = 
2997
    build_constructor (array_type, TYPE_CATCH_CLASSES (this_class));
2998 2999
  TREE_STATIC (table) = 1;
  TREE_READONLY (table) = 1;  
3000
  DECL_IGNORED_P (table) = 1;
3001
  rest_of_decl_compilation (table, 1, 0);
3002
  return table;
3003
}
3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020

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

3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037
/* Build an entry in the type assertion table.  */

static tree
build_assertion_table_entry (tree code, tree op1, tree op2)
{
  VEC(constructor_elt,gc) *v = NULL;
  tree entry;

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

  return entry;
}

3038 3039 3040 3041 3042 3043 3044 3045
/* 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;
3046
  VEC(constructor_elt,gc) **v = (VEC(constructor_elt,gc) **) ptr;
3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059
  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);
3060 3061

  entry = build_assertion_table_entry (code_val, op1_utf8, op2_utf8);
3062
  
3063
  CONSTRUCTOR_APPEND_ELT (*v, NULL_TREE, entry);
3064 3065 3066
  return true;
}

3067
/* Generate the type assertion table for KLASS, and return its DECL.  */
3068 3069

static tree
3070
emit_assertion_table (tree klass)
3071 3072
{
  tree null_entry, ctor, table_decl;
3073
  htab_t assertions_htab = TYPE_ASSERTIONS (klass);
3074
  VEC(constructor_elt,gc) *v = NULL;
3075 3076

  /* Iterate through the hash table.  */
3077
  htab_traverse (assertions_htab, add_assertion_table_entry, &v);
3078 3079

  /* Finish with a null entry.  */
3080 3081 3082
  null_entry = build_assertion_table_entry (integer_zero_node,
                                            null_pointer_node,
                                            null_pointer_node);
3083
  
3084
  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, null_entry);
3085
  
3086
  ctor = build_constructor (assertion_table_type, v);
3087

3088 3089
  table_decl = build_decl (input_location,
			   VAR_DECL, mangled_classname ("_type_assert_", klass),
3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102
			   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;
}
3103

Anthony Green committed
3104
void
3105
init_class_processing (void)
Anthony Green committed
3106
{
3107 3108
  fields_ident = get_identifier ("fields");
  info_ident = get_identifier ("info");
3109

Mark Mitchell committed
3110
  gcc_obstack_init (&temporary_obstack);
Anthony Green committed
3111
}
3112

3113 3114
static hashval_t java_treetreehash_hash (const void *);
static int java_treetreehash_compare (const void *, const void *);
3115 3116 3117

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

3118
#define JAVA_TREEHASHHASH_H(t) ((hashval_t)TYPE_UID (t))
3119 3120

static hashval_t
3121
java_treetreehash_hash (const void *k_p)
3122
{
3123 3124
  const struct treetreehash_entry *const k
    = (const struct treetreehash_entry *) k_p;
3125 3126 3127 3128
  return JAVA_TREEHASHHASH_H (k->key);
}

static int
3129
java_treetreehash_compare (const void * k1_p, const void * k2_p)
3130
{
3131 3132 3133
  const struct treetreehash_entry *const k1
    = (const struct treetreehash_entry *) k1_p;
  const_tree const k2 = (const_tree) k2_p;
3134 3135 3136 3137
  return (k1->key == k2);
}

tree 
3138
java_treetreehash_find (htab_t ht, tree t)
3139 3140 3141
{
  struct treetreehash_entry *e;
  hashval_t hv = JAVA_TREEHASHHASH_H (t);
3142
  e = (struct treetreehash_entry *) htab_find_with_hash (ht, t, hv);
3143 3144 3145 3146 3147 3148 3149
  if (e == NULL)
    return NULL;
  else
    return e->value;
}

tree *
3150
java_treetreehash_new (htab_t ht, tree t)
3151
{
3152
  void **e;
3153 3154 3155 3156 3157 3158
  struct treetreehash_entry *tthe;
  hashval_t hv = JAVA_TREEHASHHASH_H (t);

  e = htab_find_slot_with_hash (ht, t, hv, INSERT);
  if (*e == NULL)
    {
3159
      tthe = ggc_alloc_cleared_treetreehash_entry ();
3160
      tthe->key = t;
3161
      *e = tthe;
3162 3163 3164 3165 3166 3167 3168
    }
  else
    tthe = (struct treetreehash_entry *) *e;
  return &tthe->value;
}

htab_t
3169
java_treetreehash_create (size_t size)
3170
{
3171 3172
  return htab_create_ggc (size, java_treetreehash_hash,
			  java_treetreehash_compare, NULL);
3173 3174
}

3175 3176 3177 3178 3179 3180 3181 3182 3183 3184
/* 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);

3185
  base = (char *) alloca (l + 1);
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 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233
  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);
}

3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246
/* lang_hooks.decls.final_write_globals: perform final processing on
   global variables.  */

void
java_write_globals (void)
{
  tree *vec = VEC_address (tree, pending_static_fields);
  int len = VEC_length (tree, pending_static_fields);
  write_global_declarations ();
  emit_debug_global_declarations (vec, len);
  VEC_free (tree, gc, pending_static_fields);
}

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