/* Handle types for the GNU compiler for the Java(TM) language.
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003
Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
+GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
-GNU CC is distributed in the hope that it will be useful,
+GCC is distributed in the hope that it will be useful,
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
-along with GNU CC; see the file COPYING. If not, write to
+along with GCC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
#include "config.h"
#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
#include "tree.h"
+#include "real.h"
#include "obstack.h"
#include "flags.h"
#include "java-tree.h"
#include "toplev.h"
#include "ggc.h"
-static tree convert_ieee_real_to_integer PARAMS ((tree, tree));
-static tree parse_signature_type PARAMS ((const unsigned char **,
- const unsigned char *));
-static tree lookup_do PARAMS ((tree, tree, tree, tree, tree (*)(tree)));
+static tree convert_ieee_real_to_integer (tree, tree);
+static tree parse_signature_type (const unsigned char **,
+ const unsigned char *);
+static tree lookup_do (tree, int, tree, tree, tree (*)(tree));
+static tree build_null_signature (tree);
tree * type_map;
-extern struct obstack permanent_obstack;
/* Set the type of the local variable with index SLOT to TYPE. */
void
-set_local_type (slot, type)
- int slot;
- tree type;
+set_local_type (int slot, tree type)
{
int max_locals = DECL_MAX_LOCALS(current_function_decl);
int nslots = TYPE_IS_WIDE (type) ? 2 : 1;
: (int)expr))) */
static tree
-convert_ieee_real_to_integer (type, expr)
- tree type, expr;
+convert_ieee_real_to_integer (tree type, tree expr)
{
tree result;
expr = save_expr (expr);
not permitted by the language being compiled. */
tree
-convert (type, expr)
- tree type, expr;
+convert (tree type, tree expr)
{
register enum tree_code code = TREE_CODE (type);
tree
-convert_to_char (type, expr)
- tree type, expr;
+convert_to_char (tree type, tree expr)
{
return build1 (NOP_EXPR, type, expr);
}
tree
-convert_to_boolean (type, expr)
- tree type, expr;
+convert_to_boolean (tree type, tree expr)
{
return build1 (NOP_EXPR, type, expr);
}
-/* Print an error message for invalid use of an incomplete type.
- VALUE is the expression that was used (or 0 if that isn't known)
- and TYPE is the type that was invalid. */
-
-void
-incomplete_type_error (value, type)
- tree value ATTRIBUTE_UNUSED;
- tree type ATTRIBUTE_UNUSED;
-{
- error ("internal error - use of undefined type");
-}
-
/* Return a data type that has machine mode MODE.
If the mode is an integer,
then UNSIGNEDP selects between signed and unsigned types. */
tree
-type_for_mode (mode, unsignedp)
- enum machine_mode mode;
- int unsignedp;
+java_type_for_mode (enum machine_mode mode, int unsignedp)
{
if (mode == TYPE_MODE (int_type_node))
return unsignedp ? unsigned_int_type_node : int_type_node;
that is unsigned if UNSIGNEDP is nonzero, otherwise signed. */
tree
-type_for_size (bits, unsignedp)
- unsigned bits;
- int unsignedp;
+java_type_for_size (unsigned bits, int unsignedp)
{
if (bits <= TYPE_PRECISION (byte_type_node))
return unsignedp ? unsigned_byte_type_node : byte_type_node;
signed according to UNSIGNEDP. */
tree
-signed_or_unsigned_type (unsignedp, type)
- int unsignedp;
- tree type;
+java_signed_or_unsigned_type (int unsignedp, tree type)
{
if (! INTEGRAL_TYPE_P (type))
return type;
/* Return a signed type the same as TYPE in other respects. */
tree
-signed_type (type)
- tree type;
+java_signed_type (tree type)
{
- return signed_or_unsigned_type (0, type);
+ return java_signed_or_unsigned_type (0, type);
}
/* Return an unsigned type the same as TYPE in other respects. */
tree
-unsigned_type (type)
- tree type;
+java_unsigned_type (tree type)
{
- return signed_or_unsigned_type (1, type);
-
+ return java_signed_or_unsigned_type (1, type);
}
/* Mark EXP saying that we need to be able to take the
address of it; it should not be allocated in a register.
- Value is 1 if successful. */
+ Value is true if successful. */
-int
-mark_addressable (exp)
- tree exp;
+bool
+java_mark_addressable (tree exp)
{
register tree x = exp;
while (1)
break;
case COND_EXPR:
- return mark_addressable (TREE_OPERAND (x, 1))
- & mark_addressable (TREE_OPERAND (x, 2));
+ return java_mark_addressable (TREE_OPERAND (x, 1))
+ && java_mark_addressable (TREE_OPERAND (x, 2));
case CONSTRUCTOR:
TREE_ADDRESSABLE (x) = 1;
- return 1;
+ return true;
case INDIRECT_REF:
/* We sometimes add a cast *(TYPE*)&FOO to handle type and mode
x = TREE_OPERAND (x, 0);
break;
}
- return 1;
+ return true;
case VAR_DECL:
case CONST_DECL:
#endif
/* drops through */
default:
- return 1;
+ return true;
}
}
/* Thorough checking of the arrayness of TYPE. */
int
-is_array_type_p (type)
- tree type;
+is_array_type_p (tree type)
{
return TREE_CODE (type) == POINTER_TYPE
&& TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE
Return -1 if the length is unknown or non-constant. */
HOST_WIDE_INT
-java_array_type_length (array_type)
- tree array_type;
+java_array_type_length (tree array_type)
{
tree arfld;
if (TREE_CODE (array_type) == POINTER_TYPE)
if (arfld != NULL_TREE)
{
tree index_type = TYPE_DOMAIN (TREE_TYPE (arfld));
- tree high = TYPE_MAX_VALUE (index_type);
- if (TREE_CODE (high) == INTEGER_CST)
- return TREE_INT_CST_LOW (high) + 1;
+ 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;
+ }
}
return -1;
}
/* An array of unknown length will be ultimately given an length of
-2, so that we can still have `length' producing a negative value
- even if found. This was part of an optimization amaing at removing
+ even if found. This was part of an optimization aiming at removing
`length' from static arrays. We could restore it, FIXME. */
tree
-build_prim_array_type (element_type, length)
- tree element_type;
- HOST_WIDE_INT length;
+build_prim_array_type (tree element_type, HOST_WIDE_INT length)
{
- tree max_index = build_int_2 (length - 1, (0 == length ? -1 : 0));
- TREE_TYPE (max_index) = sizetype;
- return build_array_type (element_type, build_index_type (max_index));
+ tree index = NULL;
+
+ if (length != -1)
+ {
+ tree max_index = build_int_2 (length - 1, (0 == length ? -1 : 0));
+ TREE_TYPE (max_index) = sizetype;
+ index = build_index_type (max_index);
+ }
+ return build_array_type (element_type, index);
}
/* Return a Java array type with a given ELEMENT_TYPE and LENGTH.
The LENGTH is -1 if the length is unknown. */
tree
-build_java_array_type (element_type, length)
- tree element_type;
- HOST_WIDE_INT length;
+build_java_array_type (tree element_type, HOST_WIDE_INT length)
{
tree sig, t, fld, atype, arfld;
char buf[12];
/* Promote TYPE to the type actually used for fields and parameters. */
tree
-promote_type (type)
- tree type;
+promote_type (tree type)
{
switch (TREE_CODE (type))
{
case RECORD_TYPE:
- return build_pointer_type (CLASS_TO_HANDLE_TYPE (type));
+ return build_pointer_type (type);
case BOOLEAN_TYPE:
if (type == boolean_type_node)
return promoted_boolean_type_node;
Return the seen TREE_TYPE, updating *PTR. */
static tree
-parse_signature_type (ptr, limit)
- const unsigned char **ptr, *limit;
+parse_signature_type (const unsigned char **ptr, const unsigned char *limit)
{
tree type;
Return a gcc type node. */
tree
-parse_signature_string (sig_string, sig_length)
- const unsigned char *sig_string;
- int sig_length;
+parse_signature_string (const unsigned char *sig_string, int sig_length)
{
tree result_type;
const unsigned char *str = sig_string;
return type;
}
-tree
-build_null_signature (type)
- tree type;
+/* Ignore signature and always return null. Used by has_method. */
+
+static tree
+build_null_signature (tree type ATTRIBUTE_UNUSED)
{
return NULL_TREE;
}
/* Return the signature string for the arguments of method type TYPE. */
tree
-build_java_argument_signature (type)
- tree type;
+build_java_argument_signature (tree type)
{
extern struct obstack temporary_obstack;
tree sig = TYPE_ARGUMENT_SIGNATURE (type);
/* Return the signature of the given TYPE. */
tree
-build_java_signature (type)
- tree type;
+build_java_signature (tree type)
{
tree sig, t;
while (TREE_CODE (type) == POINTER_TYPE)
/* Save signature string SIG (an IDENTIFIER_NODE) in TYPE for future use. */
void
-set_java_signature (type, sig)
- tree type;
- tree sig;
+set_java_signature (tree type, tree sig)
{
tree old_sig;
while (TREE_CODE (type) == POINTER_TYPE)
#endif
}
-/* Search in class SEARCHED_CLASS (and its superclasses) for a method
- matching METHOD_NAME and signature SIGNATURE. If SEARCHED_INTERFACE is
- not NULL_TREE then first search its superinterfaces for a similar match.
- Return the matched method DECL or NULL_TREE. SIGNATURE_BUILDER is
- used on method candidates to build their (sometimes partial)
- signature. */
-
+/* 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. */
tree
-lookup_argument_method (searched_class, method_name, method_signature)
- tree searched_class, method_name, method_signature;
+lookup_argument_method (tree searched_class, tree method_name,
+ tree method_signature)
{
- return lookup_do (searched_class, NULL_TREE, method_name, method_signature,
+ return lookup_do (searched_class, 0,
+ method_name, method_signature,
build_java_argument_signature);
}
-/* Search in class SEARCHED_CLASS (and its superclasses and
- implemented interfaces) for a method matching METHOD_NAME and
- argument signature METHOD_SIGNATURE. Return a FUNCTION_DECL on
- success, or NULL_TREE if none found. (Contrast lookup_java_method,
- which takes into account return type.) */
-
+/* Like lookup_argument_method, but lets the caller set any flags
+ desired. */
tree
-lookup_argument_method2 (searched_class, method_name, method_signature)
- tree searched_class, method_name, method_signature;
+lookup_argument_method_generic (tree searched_class, tree method_name,
+ tree method_signature, int flags)
{
- return lookup_do (CLASSTYPE_SUPER (searched_class), searched_class,
+ return lookup_do (searched_class, flags,
method_name, method_signature,
build_java_argument_signature);
}
+
/* 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
- lookup_argument_method, which ignores return type.) If
+ lookup_argument_method, which ignores return type.) If
SEARCHED_CLASS is an interface, search it too. */
-
tree
-lookup_java_method (searched_class, method_name, method_signature)
- tree searched_class, method_name, method_signature;
+lookup_java_method (tree searched_class, tree method_name,
+ tree method_signature)
{
- tree searched_interface;
-
- /* If this class is an interface class, search its superinterfaces
- * first. A superinterface is not an interface's superclass: a super
- * interface is implemented by the interface. */
-
- searched_interface = (CLASS_INTERFACE (TYPE_NAME (searched_class)) ?
- searched_class : NULL_TREE);
- return lookup_do (searched_class, searched_interface, method_name,
+ return lookup_do (searched_class, SEARCH_INTERFACE, method_name,
method_signature, build_java_signature);
}
-/* Return true iff CLASS (or its ancestors) has a method METHOD_NAME. */
-
+/* Return true iff CLASS (or its ancestors) has a method METHOD_NAME. */
int
-has_method (class, method_name)
- tree class;
- tree method_name;
+has_method (tree class, tree method_name)
{
- return lookup_do (class, class, method_name,
- NULL_TREE, build_null_signature) != NULL_TREE;
+ return lookup_do (class, SEARCH_INTERFACE,
+ method_name, NULL_TREE,
+ build_null_signature) != NULL_TREE;
}
/* Search in class SEARCHED_CLASS (and its superclasses) for a method
- matching METHOD_NAME and signature SIGNATURE. Also search in
- SEARCHED_INTERFACE (and its superinterfaces) for a similar match.
+ 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_ONLY_INTERFACE means don't search ordinary classes, but
+ instead only search interfaces and superinterfaces.
+
+ SEARCH_VISIBLE means skip methods for which METHOD_INVISIBLE is
+ set.
+
Return the matched method DECL or NULL_TREE. SIGNATURE_BUILDER is
used on method candidates to build their (sometimes partial)
signature. */
-
static tree
-lookup_do (searched_class, searched_interface, method_name, signature, signature_builder)
- tree searched_class, searched_interface, method_name, signature;
- tree (*signature_builder) PARAMS ((tree));
+lookup_do (tree searched_class, int flags, tree method_name,
+ tree signature, tree (*signature_builder) (tree))
{
tree method;
-
- if (searched_interface)
- {
- int i;
- int interface_len =
- TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (searched_interface)) - 1;
-
- for (i = interface_len; i > 0; i--)
- {
- tree child =
- TREE_VEC_ELT (TYPE_BINFO_BASETYPES (searched_interface), i);
- tree iclass = BINFO_TYPE (child);
-
- /* If the superinterface hasn't been loaded yet, do so now. */
- if (CLASS_FROM_SOURCE_P (iclass))
- safe_layout_class (iclass);
- else if (!CLASS_LOADED_P (iclass))
- load_class (iclass, 1);
-
- for (method = TYPE_METHODS (iclass);
- method != NULL_TREE; method = TREE_CHAIN (method))
- {
- tree method_sig = (*signature_builder) (TREE_TYPE (method));
-
- if (DECL_NAME (method) == method_name && method_sig == signature)
- return method;
- }
-
- /* it could be defined in a supersuperinterface */
- if (CLASS_INTERFACE (TYPE_NAME (iclass)))
- {
- method = lookup_do (iclass, iclass, method_name,
- signature, signature_builder);
- if (method != NULL_TREE)
- return method;
- }
- }
- }
+ int first_time = 1;
+
+ /* If the incoming class is an interface, then we will only return
+ a method declared in an interface context. */
+ if (searched_class != NULL_TREE
+ && CLASS_INTERFACE (TYPE_NAME (searched_class)))
+ flags |= SEARCH_ONLY_INTERFACE;
while (searched_class != NULL_TREE)
{
- for (method = TYPE_METHODS (searched_class);
- method != NULL_TREE; method = TREE_CHAIN (method))
- {
- tree method_sig = (*signature_builder) (TREE_TYPE (method));
- if (DECL_NAME (method) == method_name && method_sig == signature)
- return method;
- }
+ /* First search this class. If we're only searching the
+ superclass, skip this. */
+ if (! ((flags & SEARCH_SUPER) && first_time))
+ {
+ for (method = TYPE_METHODS (searched_class);
+ method != NULL_TREE; method = TREE_CHAIN (method))
+ {
+ 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;
+ }
+ }
+ }
+ first_time = 0;
+
+ /* Search interfaces, if required. */
+ if ((flags & SEARCH_INTERFACE))
+ {
+ int i;
+ int interface_len =
+ TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (searched_class)) - 1;
+
+ for (i = interface_len; i > 0; i--)
+ {
+ tree child =
+ TREE_VEC_ELT (TYPE_BINFO_BASETYPES (searched_class), i);
+ tree iclass = BINFO_TYPE (child);
+
+ /* If the superinterface hasn't been loaded yet, do so now. */
+ if (CLASS_FROM_SOURCE_P (iclass))
+ safe_layout_class (iclass);
+ else if (!CLASS_LOADED_P (iclass))
+ load_class (iclass, 1);
+
+ /* Note that we don't care about SEARCH_VISIBLE here,
+ since an interface can never have an invisible
+ method. */
+ method = lookup_do (iclass, SEARCH_INTERFACE,
+ method_name, signature, signature_builder);
+ if (method != NULL_TREE)
+ return method;
+ }
+ }
+
+ /* If we're only searching for interface methods, then we've
+ already searched all the superinterfaces. Our superclass is
+ Object, but we don't want to search that. */
+ if ((flags & SEARCH_ONLY_INTERFACE))
+ break;
searched_class = CLASSTYPE_SUPER (searched_class);
}
Return a FUNCTION_DECL on success, or NULL_TREE if none found. */
tree
-lookup_java_constructor (clas, method_signature)
- tree clas, method_signature;
+lookup_java_constructor (tree clas, tree method_signature)
{
tree method = TYPE_METHODS (clas);
for ( ; method != NULL_TREE; method = TREE_CHAIN (method))
Promotion. It assumes that both T1 and T2 are eligible to BNP. */
tree
-binary_numeric_promotion (t1, t2, exp1, exp2)
- tree t1;
- tree t2;
- tree *exp1;
- tree *exp2;
+binary_numeric_promotion (tree t1, tree t2, tree *exp1, tree *exp2)
{
if (t1 == double_type_node || t2 == double_type_node)
{