typeck.c 24.1 KB
Newer Older
Anthony Green committed
1
/* Handle types for the GNU compiler for the Java(TM) language.
2
   Copyright (C) 1996-2013 Free Software Foundation, Inc.
Anthony Green committed
3

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

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

11
GCC is distributed in the hope that it will be useful,
Anthony Green committed
12 13 14 15 16
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
17 18
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  
Anthony Green committed
19 20 21 22 23 24 25 26

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

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

#include "config.h"
27
#include "system.h"
28
#include "coretypes.h"
Anthony Green committed
29 30
#include "tree.h"
#include "obstack.h"
Andrew Haley committed
31
#include "flags.h"
Anthony Green committed
32 33 34
#include "java-tree.h"
#include "jcf.h"
#include "convert.h"
35
#include "diagnostic-core.h"
36
#include "ggc.h"
Anthony Green committed
37

38 39 40
static tree convert_ieee_real_to_integer (tree, tree);
static tree parse_signature_type (const unsigned char **,
				  const unsigned char *);
41
static tree lookup_do (tree, int, tree, tree, tree (*)(tree));
42
static tree build_null_signature (tree);
43

Anthony Green committed
44 45 46 47 48
tree * type_map;

/* Set the type of the local variable with index SLOT to TYPE. */

void
49
set_local_type (int slot, tree type)
Anthony Green committed
50 51 52
{
  int max_locals = DECL_MAX_LOCALS(current_function_decl);
  int nslots = TYPE_IS_WIDE (type) ? 2 : 1;
53

54
  gcc_assert (slot >= 0 && (slot + nslots - 1 < max_locals));
55

Anthony Green committed
56 57 58 59 60
  type_map[slot] = type;
  while (--nslots > 0)
    type_map[++slot] = void_type_node;
}

Andrew Haley committed
61 62
/* Convert an IEEE real to an integer type.  The result of such a
   conversion when the source operand is a NaN isn't defined by
63 64 65 66 67 68 69 70 71 72 73
   IEEE754, but by the Java language standard: it must be zero.  Also,
   overflows must be clipped to within range.  This conversion
   produces something like:

      ((expr >= (float)MAX_INT)
       ? MAX_INT 
       : ((expr <= (float)MIN_INT)
	  ? MIN_INT
	  : ((expr != expr)
	     ? 0 
	     : (int)expr))) */
Andrew Haley committed
74 75

static tree
76
convert_ieee_real_to_integer (tree type, tree expr)
Andrew Haley committed
77
{
78
  tree result;
79
  expr = save_expr (expr);
Andrew Haley committed
80

81 82
  result = fold_build3 (COND_EXPR, type,
			fold_build2 (NE_EXPR, boolean_type_node, expr, expr),
83
			 convert (type, integer_zero_node),
84
			 convert_to_integer (type, expr));
85
  
86 87 88 89 90 91
  result = fold_build3 (COND_EXPR, type, 
			fold_build2 (LE_EXPR, boolean_type_node, expr, 
				     convert (TREE_TYPE (expr), 
					      TYPE_MIN_VALUE (type))),
			TYPE_MIN_VALUE (type),
			result);
92
  
93 94 95 96 97 98
  result = fold_build3 (COND_EXPR, type,
			fold_build2 (GE_EXPR, boolean_type_node, expr, 
				     convert (TREE_TYPE (expr), 
					      TYPE_MAX_VALUE (type))),
			TYPE_MAX_VALUE (type),
			result);
99 100

  return result;
Andrew Haley committed
101 102
}  

Anthony Green committed
103 104 105 106 107 108 109
/* Create an expression whose value is that of EXPR,
   converted to type TYPE.  The TREE_TYPE of the value
   is always TYPE.  This function implements all reasonable
   conversions; callers should filter out those that are
   not permitted by the language being compiled.  */

tree
110
convert (tree type, tree expr)
Anthony Green committed
111
{
112
  enum tree_code code = TREE_CODE (type);
Anthony Green committed
113

114 115 116
  if (!expr)
   return error_mark_node;

Anthony Green committed
117 118 119 120 121
  if (type == TREE_TYPE (expr)
      || TREE_CODE (expr) == ERROR_MARK)
    return expr;
  if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)
    return error_mark_node;
Andrew Haley committed
122 123
  if (code == VOID_TYPE)
    return build1 (CONVERT_EXPR, type, expr);
124
  if (code == BOOLEAN_TYPE)
125
    return fold_convert (type, expr);
Anthony Green committed
126
  if (code == INTEGER_TYPE)
Andrew Haley committed
127
    {
128 129
      if (type == char_type_node || type == promoted_char_type_node)
	return fold_convert (type, expr);
130
      if ((really_constant_p (expr) || ! flag_unsafe_math_optimizations)
131
	  && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE)
132
	return convert_ieee_real_to_integer (type, expr);
Andrew Haley committed
133
      else
134 135 136 137 138
	{
	  /* fold very helpfully sets the overflow status if a type
	     overflows in a narrowing integer conversion, but Java
	     doesn't care.  */
	  tree tmp = fold (convert_to_integer (type, expr));
139 140
	  if (TREE_CODE (tmp) == INTEGER_CST)
	    TREE_OVERFLOW (tmp) = 0;
141 142
	  return tmp;
	}
Andrew Haley committed
143
    }	  
Anthony Green committed
144 145 146 147 148 149 150 151
  if (code == REAL_TYPE)
    return fold (convert_to_real (type, expr));
  if (code == POINTER_TYPE)
    return fold (convert_to_pointer (type, expr));
  error ("conversion to non-scalar type requested");
  return error_mark_node;
}

Andrew Haley committed
152

Anthony Green committed
153 154 155 156 157
/* Return a data type that has machine mode MODE.
   If the mode is an integer,
   then UNSIGNEDP selects between signed and unsigned types.  */

tree
158
java_type_for_mode (enum machine_mode mode, int unsignedp)
Anthony Green committed
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
{
  if (mode == TYPE_MODE (int_type_node))
    return unsignedp ? unsigned_int_type_node : int_type_node;
  if (mode == TYPE_MODE (long_type_node))
    return unsignedp ? unsigned_long_type_node : long_type_node;
  if (mode == TYPE_MODE (short_type_node))
    return unsignedp ? unsigned_short_type_node : short_type_node;
  if (mode == TYPE_MODE (byte_type_node))
    return unsignedp ? unsigned_byte_type_node : byte_type_node;
  if (mode == TYPE_MODE (float_type_node))
    return float_type_node;
  if (mode == TYPE_MODE (double_type_node))
    return double_type_node;

  return 0;
}

/* Return an integer type with BITS bits of precision,
   that is unsigned if UNSIGNEDP is nonzero, otherwise signed.  */

tree
180
java_type_for_size (unsigned bits, int unsignedp)
Anthony Green committed
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
{
  if (bits <= TYPE_PRECISION (byte_type_node))
    return unsignedp ? unsigned_byte_type_node : byte_type_node;
  if (bits <= TYPE_PRECISION (short_type_node))
    return unsignedp ? unsigned_short_type_node : short_type_node;
  if (bits <= TYPE_PRECISION (int_type_node))
    return unsignedp ? unsigned_int_type_node : int_type_node;
  if (bits <= TYPE_PRECISION (long_type_node))
    return unsignedp ? unsigned_long_type_node : long_type_node;
  return 0;
}

/* Thorough checking of the arrayness of TYPE.  */

int
196
is_array_type_p (tree type)
Anthony Green committed
197 198 199 200 201 202 203 204 205 206
{
  return TREE_CODE (type) == POINTER_TYPE
    && TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE
    && TYPE_ARRAY_P (TREE_TYPE (type));
}

/* Return the length of a Java array type.
   Return -1 if the length is unknown or non-constant. */

HOST_WIDE_INT
207
java_array_type_length (tree array_type)
Anthony Green committed
208 209 210 211
{
  tree arfld;
  if (TREE_CODE (array_type) == POINTER_TYPE)
    array_type = TREE_TYPE (array_type);
212
  arfld = DECL_CHAIN (DECL_CHAIN (TYPE_FIELDS (array_type)));
Anthony Green committed
213 214 215
  if (arfld != NULL_TREE)
    {
      tree index_type = TYPE_DOMAIN (TREE_TYPE (arfld));
216 217 218 219 220 221
      if (index_type != NULL_TREE)
	{
	  tree high = TYPE_MAX_VALUE (index_type);
	  if (TREE_CODE (high) == INTEGER_CST)
	    return TREE_INT_CST_LOW (high) + 1;
	}
Anthony Green committed
222 223 224 225
    }
  return -1;
}

226
/* An array of unknown length will be ultimately given a length of
227
   -2, so that we can still have `length' producing a negative value
228
   even if found. This was part of an optimization aiming at removing
229 230
   `length' from static arrays. We could restore it, FIXME.  */

Anthony Green committed
231
tree
232
build_prim_array_type (tree element_type, HOST_WIDE_INT length)
Anthony Green committed
233
{
234 235 236 237
  tree index = NULL;

  if (length != -1)
    {
238
      tree max_index = build_int_cst (sizetype, length - 1);
239 240 241
      index = build_index_type (max_index);
    }
  return build_array_type (element_type, index);
Anthony Green committed
242 243 244 245 246 247 248
}

/* Return a Java array type with a given ELEMENT_TYPE and LENGTH.
   These are hashed (shared) using IDENTIFIER_SIGNATURE_TYPE.
   The LENGTH is -1 if the length is unknown. */

tree
249
build_java_array_type (tree element_type, HOST_WIDE_INT length)
Anthony Green committed
250
{
251
  tree sig, t, fld, atype, arfld;
252
  char buf[23];
Anthony Green committed
253 254
  tree elsig = build_java_signature (element_type);
  tree el_name = element_type;
255 256 257 258 259
  buf[0] = '[';
  if (length >= 0)
    sprintf (buf+1, HOST_WIDE_INT_PRINT_DEC, length);
  else
    buf[1] = '\0';
Anthony Green committed
260 261 262 263
  sig = ident_subst (IDENTIFIER_POINTER (elsig), IDENTIFIER_LENGTH (elsig),
		     buf, 0, 0, "");
  t = IDENTIFIER_SIGNATURE_TYPE (sig);
  if (t != NULL_TREE)
Per Bothner committed
264
    return TREE_TYPE (t);
Anthony Green committed
265
  t = make_class ();
Per Bothner committed
266
  IDENTIFIER_SIGNATURE_TYPE (sig) = build_pointer_type (t);
Anthony Green committed
267 268 269 270 271 272 273
  TYPE_ARRAY_P (t) = 1;

  if (TREE_CODE (el_name) == POINTER_TYPE)
    el_name = TREE_TYPE (el_name);
  el_name = TYPE_NAME (el_name);
  if (TREE_CODE (el_name) == TYPE_DECL)
    el_name = DECL_NAME (el_name);
274
  {
275
    char suffix[23];
276 277 278 279 280
    if (length >= 0)
      sprintf (suffix, "[%d]", (int)length); 
    else
      strcpy (suffix, "[]");
    TYPE_NAME (t) 
281
      = TYPE_STUB_DECL (t)
282
      = build_decl (input_location, TYPE_DECL,
283
		    identifier_subst (el_name, "", '.', '.', suffix),
284
                             t);
285
    TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (t)) = true;
286
  }
Anthony Green committed
287 288 289

  set_java_signature (t, sig);
  set_super_info (0, t, object_type_node, 0);
Per Bothner committed
290 291
  if (TREE_CODE (element_type) == RECORD_TYPE)
    element_type = promote_type (element_type);
Anthony Green committed
292 293 294
  TYPE_ARRAY_ELEMENT (t) = element_type;

  /* Add length pseudo-field. */
295 296
  fld = build_decl (input_location,
		    FIELD_DECL, get_identifier ("length"), int_type_node);
Anthony Green committed
297 298 299 300
  TYPE_FIELDS (t) = fld;
  DECL_CONTEXT (fld) = t;
  FIELD_PUBLIC (fld) = 1;
  FIELD_FINAL (fld) = 1;
301 302
  TREE_READONLY (fld) = 1;

303
  atype = build_prim_array_type (element_type, length);
304 305
  arfld = build_decl (input_location,
		      FIELD_DECL, get_identifier ("data"), atype);
306
  DECL_CONTEXT (arfld) = t;
307
  DECL_CHAIN (fld) = arfld;
308
  DECL_ALIGN (arfld) = TYPE_ALIGN (element_type);
Anthony Green committed
309

310 311 312 313 314 315
  /* We could layout_class, but that loads java.lang.Object prematurely.
   * This is called by the parser, and it is a bad idea to do load_class
   * in the middle of parsing, because of possible circularity problems. */
  push_super_field (t, object_type_node);
  layout_type (t);

Anthony Green committed
316 317 318 319 320 321
  return t;
}

/* Promote TYPE to the type actually used for fields and parameters. */

tree
322
promote_type (tree type)
Anthony Green committed
323 324 325 326
{
  switch (TREE_CODE (type))
    {
    case RECORD_TYPE:
327
      return build_pointer_type (type);
Anthony Green committed
328 329 330 331
    case BOOLEAN_TYPE:
      if (type == boolean_type_node)
	return promoted_boolean_type_node;
      goto handle_int;
332
    case INTEGER_TYPE:
Anthony Green committed
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353
      if (type == char_type_node)
	return promoted_char_type_node;
    handle_int:
      if (TYPE_PRECISION (type) < TYPE_PRECISION (int_type_node))
	{
	  if (type == short_type_node)
	    return promoted_short_type_node;
	  if (type == byte_type_node)
	    return promoted_byte_type_node;
	  return int_type_node;
	}
      /* ... else fall through ... */
    default:
      return type;
    }
}

/* Parse a signature string, starting at *PTR and ending at LIMIT.
   Return the seen TREE_TYPE, updating *PTR. */

static tree
354
parse_signature_type (const unsigned char **ptr, const unsigned char *limit)
Anthony Green committed
355
{
Per Bothner committed
356
  tree type;
357
  gcc_assert (*ptr < limit);
358 359

  switch (**ptr)
Anthony Green committed
360 361 362 363 364 365 366 367 368 369 370
    {
    case 'B':  (*ptr)++;  return byte_type_node;
    case 'C':  (*ptr)++;  return char_type_node;
    case 'D':  (*ptr)++;  return double_type_node;
    case 'F':  (*ptr)++;  return float_type_node;
    case 'S':  (*ptr)++;  return short_type_node;
    case 'I':  (*ptr)++;  return int_type_node;
    case 'J':  (*ptr)++;  return long_type_node;
    case 'Z':  (*ptr)++;  return boolean_type_node;
    case 'V':  (*ptr)++;  return void_type_node;
    case '[':
Kaveh R. Ghazi committed
371
      for ((*ptr)++; (*ptr) < limit && ISDIGIT (**ptr); ) (*ptr)++;
Per Bothner committed
372 373 374
      type = parse_signature_type (ptr, limit);
      type = build_java_array_type (type, -1); 
      break;
Anthony Green committed
375 376 377
    case 'L':
      {
	const unsigned char *start = ++(*ptr);
378
	const unsigned char *str = start;
Anthony Green committed
379 380
	for ( ; ; str++)
	  {
381
	    gcc_assert (str < limit);
Anthony Green committed
382 383 384 385
	    if (*str == ';')
	      break;
	  }
	*ptr = str+1;
386
	type = lookup_class (unmangle_classname ((const char *) start, str - start));
Per Bothner committed
387
	break;
Anthony Green committed
388 389
      }
    default:
390
      gcc_unreachable ();
Anthony Green committed
391
    }
Per Bothner committed
392
  return promote_type (type);
Anthony Green committed
393 394 395 396 397 398 399
}

/* Parse a Java "mangled" signature string, starting at SIG_STRING,
   and SIG_LENGTH bytes long.
   Return a gcc type node. */

tree
400
parse_signature_string (const unsigned char *sig_string, int sig_length)
Anthony Green committed
401 402 403 404 405 406 407 408 409 410 411
{
  tree result_type;
  const unsigned char *str = sig_string;
  const unsigned char *limit = str + sig_length;

  if (str < limit && str[0] == '(')
    {
      tree argtype_list = NULL_TREE;
      str++;
      while (str < limit && str[0] != ')')
	{
Per Bothner committed
412
	  tree argtype = parse_signature_type (&str, limit);
Anthony Green committed
413 414 415
	  argtype_list = tree_cons (NULL_TREE, argtype, argtype_list);
	}
      if (str++, str >= limit)
416
	abort ();
Per Bothner committed
417
      result_type = parse_signature_type (&str, limit);
418 419
      argtype_list = chainon (nreverse (argtype_list), end_params_node);
      result_type = build_function_type (result_type, argtype_list);
Anthony Green committed
420 421 422 423 424 425 426 427 428 429 430 431 432 433 434
    }
  else
    result_type = parse_signature_type (&str, limit);
  if (str != limit)
    error ("junk at end of signature string");
  return result_type;
}

/* Convert a signature to its type.
 * Uses IDENTIFIER_SIGNATURE_TYPE as a cache (except for primitive types).
 */

tree
get_type_from_signature (tree signature)
{
435
  const unsigned char *sig = (const unsigned char *) IDENTIFIER_POINTER (signature);
Anthony Green committed
436 437 438 439 440 441 442 443 444 445 446 447 448 449
  int len = IDENTIFIER_LENGTH (signature);
  tree type;
  /* Primitive types aren't cached. */
  if (len <= 1)
    return parse_signature_string (sig, len);
  type = IDENTIFIER_SIGNATURE_TYPE (signature);
  if (type == NULL_TREE)
    {
      type = parse_signature_string (sig, len);
      IDENTIFIER_SIGNATURE_TYPE (signature) = type;
    }
  return type;
}

450 451
/* Ignore signature and always return null.  Used by has_method. */

452
static tree
453
build_null_signature (tree type ATTRIBUTE_UNUSED)
454 455 456 457
{
  return NULL_TREE;
}

Anthony Green committed
458 459 460
/* Return the signature string for the arguments of method type TYPE. */

tree
461
build_java_argument_signature (tree type)
Anthony Green committed
462 463 464 465 466 467 468 469
{
  extern struct obstack temporary_obstack;
  tree sig = TYPE_ARGUMENT_SIGNATURE (type);
  if (sig == NULL_TREE)
    {
      tree args = TYPE_ARG_TYPES (type);
      if (TREE_CODE (type) == METHOD_TYPE)
	args = TREE_CHAIN (args);  /* Skip "this" argument. */
470
      for (; args != end_params_node; args = TREE_CHAIN (args))
Anthony Green committed
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487
	{
	  tree t = build_java_signature (TREE_VALUE (args));
	  obstack_grow (&temporary_obstack,
			IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t));
	}
      obstack_1grow (&temporary_obstack, '\0');

      sig = get_identifier (obstack_base (&temporary_obstack));
      TYPE_ARGUMENT_SIGNATURE (type) = sig;
      obstack_free (&temporary_obstack, obstack_base (&temporary_obstack));
    }
  return sig;
}

/* Return the signature of the given TYPE. */

tree
488
build_java_signature (tree type)
Anthony Green committed
489 490 491 492
{
  tree sig, t;
  while (TREE_CODE (type) == POINTER_TYPE)
    type = TREE_TYPE (type);
493 494
  MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC (type);
  sig = TYPE_SIGNATURE (type);
Anthony Green committed
495 496 497 498 499 500 501 502
  if (sig == NULL_TREE)
    {
      char sg[2];
      switch (TREE_CODE (type))
	{
	case BOOLEAN_TYPE: sg[0] = 'Z';  goto native;
	case VOID_TYPE:    sg[0] = 'V';  goto native;
	case INTEGER_TYPE:
503 504 505 506 507
          if (type == char_type_node || type == promoted_char_type_node)
	    {
	      sg[0] = 'C';
	      goto native;
	    }
Anthony Green committed
508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549
	  switch (TYPE_PRECISION (type))
	    {
	    case  8:       sg[0] = 'B';  goto native;
	    case 16:       sg[0] = 'S';  goto native;
	    case 32:       sg[0] = 'I';  goto native;
	    case 64:       sg[0] = 'J';  goto native;
	    default:  goto bad_type;
	    }
	case REAL_TYPE:
	  switch (TYPE_PRECISION (type))
	    {
	    case 32:       sg[0] = 'F';  goto native;
	    case 64:       sg[0] = 'D';  goto native;
	    default:  goto bad_type;
	    }
	native:
	  sg[1] = 0;
	  sig = get_identifier (sg);
	  break;
	case RECORD_TYPE:
	  if (TYPE_ARRAY_P (type))
	    {
	      t = build_java_signature (TYPE_ARRAY_ELEMENT (type));
	      sig = ident_subst (IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t),
				 "[", 0, 0, "");
	    }
	  else
	    {
	      t = DECL_NAME (TYPE_NAME (type));
	      sig = ident_subst (IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t),
				 "L", '.', '/', ";");
	    }
	  break;
	case METHOD_TYPE:
	case FUNCTION_TYPE:
	  {
	    extern struct obstack temporary_obstack;
	    sig = build_java_argument_signature (type);
	    obstack_1grow (&temporary_obstack, '(');
	    obstack_grow (&temporary_obstack,
			  IDENTIFIER_POINTER (sig), IDENTIFIER_LENGTH (sig));
	    obstack_1grow (&temporary_obstack, ')');
550

Anthony Green committed
551 552 553 554 555 556 557 558 559 560 561
	    t = build_java_signature (TREE_TYPE (type));
	    obstack_grow0 (&temporary_obstack,
			   IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t));

	    sig = get_identifier (obstack_base (&temporary_obstack));
	    obstack_free (&temporary_obstack,
			  obstack_base (&temporary_obstack));
	  }
	  break;
	bad_type:
	default:
562
	  gcc_unreachable ();
Anthony Green committed
563
	}
564
      TYPE_SIGNATURE (type) = sig;
Anthony Green committed
565 566 567 568 569 570 571
    }
  return sig;
}

/* Save signature string SIG (an IDENTIFIER_NODE) in TYPE for future use. */

void
572
set_java_signature (tree type, tree sig)
Anthony Green committed
573 574 575 576
{
  tree old_sig;
  while (TREE_CODE (type) == POINTER_TYPE)
    type = TREE_TYPE (type);
577 578
  MAYBE_CREATE_TYPE_TYPE_LANG_SPECIFIC (type);
  old_sig = TYPE_SIGNATURE (type);
Anthony Green committed
579
  if (old_sig != NULL_TREE && old_sig != sig)
580
    abort ();
581
  TYPE_SIGNATURE (type) = sig;
Anthony Green committed
582 583 584 585 586 587
#if 0 /* careful about METHOD_TYPE */
  if (IDENTIFIER_SIGNATURE_TYPE (sig) == NULL_TREE && TREE_PERMANENT (type))
    IDENTIFIER_SIGNATURE_TYPE (sig) = type;
#endif
}

588 589 590 591 592
/* Search in SEARCHED_CLASS and its superclasses for a method matching
   METHOD_NAME and signature METHOD_SIGNATURE.  This function will
   only search for methods declared in the class hierarchy; interfaces
   will not be considered.  Returns NULL_TREE if the method is not
   found.  */
Anthony Green committed
593
tree
594 595
lookup_argument_method (tree searched_class, tree method_name,
			tree method_signature)
Anthony Green committed
596
{
597 598
  return lookup_do (searched_class, 0,
		    method_name, method_signature, 
599
		    build_java_argument_signature);
Anthony Green committed
600 601
}

602 603
/* Like lookup_argument_method, but lets the caller set any flags
   desired.  */
Anthony Green committed
604
tree
605 606
lookup_argument_method_generic (tree searched_class, tree method_name,
				tree method_signature, int flags)
Anthony Green committed
607
{
608
  return lookup_do (searched_class, flags,
609 610 611
		    method_name, method_signature, 
		    build_java_argument_signature);
}
612

613

614 615 616
/* Search in class SEARCHED_CLASS (and its superclasses) for a method
   matching METHOD_NAME and signature METHOD_SIGNATURE.  Return a
   FUNCTION_DECL on success, or NULL_TREE if none found.  (Contrast
617
   lookup_argument_method, which ignores return type.)  If
618 619
   SEARCHED_CLASS is an interface, search it too. */
tree
620 621
lookup_java_method (tree searched_class, tree method_name,
		    tree method_signature)
622
{
623
  return lookup_do (searched_class, SEARCH_INTERFACE, method_name, 
624 625
		    method_signature, build_java_signature);
}
626

627
/* Return true iff KLASS (or its ancestors) has a method METHOD_NAME. */
628
int
629
has_method (tree klass, tree method_name)
630
{
631
  return lookup_do (klass, SEARCH_INTERFACE,
632 633
		    method_name, NULL_TREE,
		    build_null_signature) != NULL_TREE;
634 635
}

636 637 638 639 640 641 642 643 644
/* Search in class SEARCHED_CLASS, but not its superclasses, for a
   method matching METHOD_NAME and signature SIGNATURE.  A private
   helper for lookup_do.  */
static tree
shallow_find_method (tree searched_class, int flags, tree method_name, 
	     tree signature, tree (*signature_builder) (tree))
{
  tree method;
  for (method = TYPE_METHODS (searched_class);
645
       method != NULL_TREE;  method = DECL_CHAIN (method))
646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664
    {
      tree method_sig = (*signature_builder) (TREE_TYPE (method));
      if (DECL_NAME (method) == method_name && method_sig == signature)
	{
	  /* If the caller requires a visible method, then we
	     skip invisible methods here.  */
	  if (! (flags & SEARCH_VISIBLE)
	      || ! METHOD_INVISIBLE (method))
	    return method;
	}
    }
  return NULL_TREE;
}

/* Search in the superclasses of SEARCHED_CLASS for a method matching
   METHOD_NAME and signature SIGNATURE.  A private helper for
   lookup_do.  */
static tree
find_method_in_superclasses (tree searched_class, int flags, 
Ranjit Mathew committed
665 666
                             tree method_name, tree signature,
                             tree (*signature_builder) (tree))
667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685
{
  tree klass;
  for (klass = CLASSTYPE_SUPER (searched_class); klass != NULL_TREE;
       klass = CLASSTYPE_SUPER (klass))
    {
      tree method;
      method = shallow_find_method (klass, flags, method_name, 
				    signature, signature_builder);
      if (method != NULL_TREE)
	return method;
    }

  return NULL_TREE;
}

/* Search in the interfaces of SEARCHED_CLASS and its superinterfaces
   for a method matching METHOD_NAME and signature SIGNATURE.  A
   private helper for lookup_do.  */
static tree
Ranjit Mathew committed
686 687
find_method_in_interfaces (tree searched_class, int flags, tree method_name,
                           tree signature, tree (*signature_builder) (tree))
688 689
{
  int i;
Nathan Sidwell committed
690
  tree binfo, base_binfo;
691

Nathan Sidwell committed
692 693
  for (binfo = TYPE_BINFO (searched_class), i = 1;
       BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
694
    {
Nathan Sidwell committed
695
      tree iclass = BINFO_TYPE (base_binfo);
696
      tree method;
697 698
	  
      /* If the superinterface hasn't been loaded yet, do so now.  */
699
      if (!CLASS_LOADED_P (iclass))
700 701 702 703
	load_class (iclass, 1);
	  
      /* First, we look in ICLASS.  If that doesn't work we'll
	 recursively look through all its superinterfaces.  */
704
      method = shallow_find_method (iclass, flags, method_name, 
Nathan Sidwell committed
705
				    signature, signature_builder);      
706 707 708 709 710 711 712 713 714 715 716 717 718
      if (method != NULL_TREE)
	return method;
  
      method = find_method_in_interfaces 
	(iclass, flags, method_name, signature, signature_builder);
      if (method != NULL_TREE)
	return method;
    }
  
  return NULL_TREE;
}


719
/* Search in class SEARCHED_CLASS (and its superclasses) for a method
720 721 722 723 724 725 726 727 728 729 730 731
   matching METHOD_NAME and signature SIGNATURE.  FLAGS control some
   parameters of the search.
   
   SEARCH_INTERFACE means also search interfaces and superinterfaces
   of SEARCHED_CLASS.
   
   SEARCH_SUPER means skip SEARCHED_CLASS and start with its
   superclass.
   
   SEARCH_VISIBLE means skip methods for which METHOD_INVISIBLE is
   set.

732 733 734 735
   Return the matched method DECL or NULL_TREE.  SIGNATURE_BUILDER is
   used on method candidates to build their (sometimes partial)
   signature.  */
static tree
736
lookup_do (tree searched_class, int flags, tree method_name,
737
	   tree signature, tree (*signature_builder) (tree))
738 739
{
  tree method;
740
  tree orig_class = searched_class;
741 742 743
    
  if (searched_class == NULL_TREE)
    return NULL_TREE;
744

745
  if (flags & SEARCH_SUPER)
746 747
    {
      searched_class = CLASSTYPE_SUPER (searched_class);
748 749
      if (searched_class == NULL_TREE)
	return NULL_TREE;
750 751
    }

752 753 754 755 756 757 758 759 760 761 762 763 764 765 766
  /* First look in our own methods.  */
  method = shallow_find_method (searched_class, flags, method_name,
				signature, signature_builder);  
  if (method)
    return method;

  /* Then look in our superclasses.  */
  if (! CLASS_INTERFACE (TYPE_NAME (searched_class)))
    method = find_method_in_superclasses (searched_class, flags, method_name,
					  signature, signature_builder);  
  if (method)
    return method;
  
  /* If that doesn't work, look in our interfaces.  */
  if (flags & SEARCH_INTERFACE)
767
    method = find_method_in_interfaces (orig_class, flags, method_name, 
768 769 770
					signature, signature_builder);
  
  return method;
Anthony Green committed
771 772 773 774 775 776
}

/* Search in class CLAS for a constructor matching METHOD_SIGNATURE.
   Return a FUNCTION_DECL on success, or NULL_TREE if none found. */

tree
777
lookup_java_constructor (tree clas, tree method_signature)
Anthony Green committed
778 779
{
  tree method = TYPE_METHODS (clas);
780
  for ( ; method != NULL_TREE;  method = DECL_CHAIN (method))
Anthony Green committed
781 782 783 784 785 786 787 788 789 790
    {
      tree method_sig = build_java_signature (TREE_TYPE (method));
      if (DECL_CONSTRUCTOR_P (method) && method_sig == method_signature)
	return method;
    }
  return NULL_TREE;
}

/* Return a type which is the Binary Numeric Promotion of the pair T1,
   T2 and convert EXP1 and/or EXP2. See 5.6.2 Binary Numeric
791
   Promotion. It assumes that both T1 and T2 are eligible to BNP. */
Anthony Green committed
792 793

tree
794
binary_numeric_promotion (tree t1, tree t2, tree *exp1, tree *exp2)
Anthony Green committed
795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826
{
  if (t1 == double_type_node || t2 == double_type_node)
    {
      if (t1 != double_type_node)
	*exp1 = convert (double_type_node, *exp1);
      if (t2 != double_type_node)
	*exp2 = convert (double_type_node, *exp2);
      return double_type_node;
    }
  if (t1 == float_type_node || t2 == float_type_node)
    {
      if (t1 != float_type_node)
	*exp1 = convert (float_type_node, *exp1);
      if (t2 != float_type_node)
	*exp2 = convert (float_type_node, *exp2);
      return float_type_node;
    }
  if (t1 == long_type_node || t2 == long_type_node)
    {
      if (t1 != long_type_node)
	*exp1 = convert (long_type_node, *exp1);
      if (t2 != long_type_node)
	*exp2 = convert (long_type_node, *exp2);
      return long_type_node;
    }

  if (t1 != int_type_node)
    *exp1 = convert (int_type_node, *exp1);
  if (t2 != int_type_node)
    *exp2 = convert (int_type_node, *exp2);
  return int_type_node;
}