/* Handle types for the GNU compiler for the Java(TM) language.
- Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003
+ Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004
Free Software Foundation, Inc.
This file is part of GCC.
tree result;
expr = save_expr (expr);
- result = build (COND_EXPR, type,
- build (NE_EXPR, boolean_type_node, expr, expr),
- convert (type, integer_zero_node),
- convert_to_integer (type, expr));
-
- result = build (COND_EXPR, type,
- build (LE_EXPR, boolean_type_node, expr,
- convert (TREE_TYPE (expr), TYPE_MIN_VALUE (type))),
- TYPE_MIN_VALUE (type),
- result);
-
- result = build (COND_EXPR, type,
- build (GE_EXPR, boolean_type_node, expr,
- convert (TREE_TYPE (expr), TYPE_MAX_VALUE (type))),
- TYPE_MAX_VALUE (type),
- result);
+ result = fold (build3 (COND_EXPR, type,
+ fold (build2 (NE_EXPR, boolean_type_node, expr, expr)),
+ convert (type, integer_zero_node),
+ convert_to_integer (type, expr)));
+
+ 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));
+
+ 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));
return result;
}
tree
convert (tree type, tree expr)
{
- register enum tree_code code = TREE_CODE (type);
+ enum tree_code code = TREE_CODE (type);
if (!expr)
return error_mark_node;
return error_mark_node;
if (code == VOID_TYPE)
return build1 (CONVERT_EXPR, type, expr);
- if (code == BOOLEAN_TYPE)
- return fold (convert_to_boolean (type, expr));
+ if (code == BOOLEAN_TYPE || code == CHAR_TYPE)
+ return fold (build1 (CONVERT_EXPR, type, expr));
if (code == INTEGER_TYPE)
{
- if (! flag_unsafe_math_optimizations
- && ! flag_emit_class_files
+ if ((really_constant_p (expr)
+ || (! flag_unsafe_math_optimizations
+ && ! flag_emit_class_files))
&& TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE
&& TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT)
return fold (convert_ieee_real_to_integer (type, expr));
else
- return fold (convert_to_integer (type, expr));
+ {
+ /* 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));
+ TREE_OVERFLOW (tmp) = 0;
+ return tmp;
+ }
}
if (code == REAL_TYPE)
return fold (convert_to_real (type, expr));
- if (code == CHAR_TYPE)
- return fold (convert_to_char (type, expr));
if (code == POINTER_TYPE)
return fold (convert_to_pointer (type, expr));
error ("conversion to non-scalar type requested");
}
-tree
-convert_to_char (tree type, tree expr)
-{
- return build1 (NOP_EXPR, type, expr);
-}
-
-tree
-convert_to_boolean (tree type, tree expr)
-{
- return build1 (NOP_EXPR, type, expr);
-}
-
/* Return a data type that has machine mode MODE.
If the mode is an integer,
then UNSIGNEDP selects between signed and unsigned types. */
bool
java_mark_addressable (tree exp)
{
- register tree x = exp;
+ tree x = exp;
while (1)
switch (TREE_CODE (x))
{
if (length != -1)
{
- tree max_index = build_int_2 (length - 1, (0 == length ? -1 : 0));
- TREE_TYPE (max_index) = sizetype;
+ tree max_index = build_int_cst (sizetype, length - 1);
index = build_index_type (max_index);
}
return build_array_type (element_type, index);
el_name = TYPE_NAME (el_name);
if (TREE_CODE (el_name) == TYPE_DECL)
el_name = DECL_NAME (el_name);
- TYPE_NAME (t) = build_decl (TYPE_DECL,
- identifier_subst (el_name, "", '.', '.', "[]"),
+ {
+ char suffix[12];
+ if (length >= 0)
+ sprintf (suffix, "[%d]", (int)length);
+ else
+ strcpy (suffix, "[]");
+ TYPE_NAME (t)
+ = build_decl (TYPE_DECL,
+ identifier_subst (el_name, "", '.', '.', suffix),
t);
+ }
set_java_signature (t, sig);
set_super_info (0, t, object_type_node, 0);
case 'L':
{
const unsigned char *start = ++(*ptr);
- register const unsigned char *str = start;
+ const unsigned char *str = start;
for ( ; ; str++)
{
if (str >= limit)
break;
}
*ptr = str+1;
- type = lookup_class (unmangle_classname (start, str - start));
+ type = lookup_class (unmangle_classname ((const char *) start, str - start));
break;
}
default:
build_null_signature) != NULL_TREE;
}
+/* 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);
+ 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;
+ }
+ }
+ 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,
+ tree method_name, tree signature,
+ tree (*signature_builder) (tree))
+{
+ 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
+find_method_in_interfaces (tree searched_class, int flags, tree method_name,
+ tree signature, tree (*signature_builder) (tree))
+{
+ int i;
+ tree binfo, base_binfo;
+
+ for (binfo = TYPE_BINFO (searched_class), i = 1;
+ BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
+ {
+ tree iclass = BINFO_TYPE (base_binfo);
+ tree method;
+
+ /* 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);
+
+ /* First, we look in ICLASS. If that doesn't work we'll
+ recursively look through all its superinterfaces. */
+ method = shallow_find_method (iclass, flags, method_name,
+ signature, signature_builder);
+ 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;
+}
+
+
/* Search in class SEARCHED_CLASS (and its superclasses) for a method
matching METHOD_NAME and signature SIGNATURE. FLAGS control some
parameters of the search.
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.
tree signature, tree (*signature_builder) (tree))
{
tree 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;
+
+ if (searched_class == NULL_TREE)
+ return NULL_TREE;
- while (searched_class != NULL_TREE)
+ if (flags & SEARCH_SUPER)
{
- /* 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);
+ if (searched_class == NULL_TREE)
+ return NULL_TREE;
}
- return NULL_TREE;
+ /* 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)
+ method = find_method_in_interfaces (searched_class, flags, method_name,
+ signature, signature_builder);
+
+ return method;
}
/* Search in class CLAS for a constructor matching METHOD_SIGNATURE.