aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlexandre Petit-Bianco <apbianco@cygnus.com>1998-10-16 19:36:39 +0000
committerAlexandre Petit-Bianco <apbianco@gcc.gnu.org>1998-10-16 12:36:39 -0700
commitc583dd46ad05221ee43832d6845ebeb686492579 (patch)
tree0f92c4b1856c87f2362d17e61e9bd4187423ba40 /gcc
parent8e52e063afdb17d8d92e5ceb1c03dc915a5a17a3 (diff)
downloadgcc-c583dd46ad05221ee43832d6845ebeb686492579.zip
gcc-c583dd46ad05221ee43832d6845ebeb686492579.tar.gz
gcc-c583dd46ad05221ee43832d6845ebeb686492579.tar.bz2
lex.c (setjmp.h): No longer included.
Fri Oct 16 10:59:01 1998 Alexandre Petit-Bianco <apbianco@cygnus.com> * lex.c (setjmp.h): No longer included. * lex.h (setjmp.h): Included. * parse.h (SET_TYPE_FOR_RESOLUTION): New macro. (duplicate_declaration_error_p): Renamed from duplicate_declaration_error. (build_array_from_name): New function prototype. * parse.y (setjmp.h): No longer included. (variable_declarator_id): Define action. (build_array_from_name): New function. (duplicate_declaration_error_p): Renamed from duplicate_declaration_error. Fixed leading comment. (register_fields): Main `for' loop reorganized. Uses SET_TYPE_FOR_RESOLUTION and build_array_from_name. (method_declarator): Uses SET_TYPE_FOR_RESOLUTION and call build_array_from_name. (resolve_class): Set CLASS_LOADED_P on newly build array dimension types. (read_import_dir): Don't try to skip `.' and `..'. (declare_local_variables): Uses SET_TYPE_FOR_RESOLUTION and build_array_from_name. Main `for' loop reorganized. (resolve_qualified_expression_name): When building access to a field, use the type where the field was found, not its own type. (maybe_access_field): Use field DECL_CONTEXT if the type where the field was found is null. (qualify_ambiguous_name): Sweep through all successive array dimensions. Implements the alternate form `T a[]' of array declarations. Fixes a bug when building access to certain fields. Fixed a compilation warning when lex.h is included from somewhere else than parse.y From-SVN: r23142
Diffstat (limited to 'gcc')
-rw-r--r--gcc/java/ChangeLog29
-rw-r--r--gcc/java/lex.c1
-rw-r--r--gcc/java/lex.h2
-rw-r--r--gcc/java/parse.h24
-rw-r--r--gcc/java/parse.y309
5 files changed, 245 insertions, 120 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 47467c0..d2ce1fc 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,32 @@
+Fri Oct 16 10:59:01 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
+
+ * lex.c (setjmp.h): No longer included.
+ * lex.h (setjmp.h): Included.
+ * parse.h (SET_TYPE_FOR_RESOLUTION): New macro.
+ (duplicate_declaration_error_p): Renamed from
+ duplicate_declaration_error.
+ (build_array_from_name): New function prototype.
+ * parse.y (setjmp.h): No longer included.
+ (variable_declarator_id): Define action.
+ (build_array_from_name): New function.
+ (duplicate_declaration_error_p): Renamed from
+ duplicate_declaration_error. Fixed leading comment.
+ (register_fields): Main `for' loop reorganized. Uses
+ SET_TYPE_FOR_RESOLUTION and build_array_from_name.
+ (method_declarator): Uses SET_TYPE_FOR_RESOLUTION and call
+ build_array_from_name.
+ (resolve_class): Set CLASS_LOADED_P on newly build array dimension
+ types.
+ (read_import_dir): Don't try to skip `.' and `..'.
+ (declare_local_variables): Uses SET_TYPE_FOR_RESOLUTION and
+ build_array_from_name. Main `for' loop reorganized.
+ (resolve_qualified_expression_name): When building access to a
+ field, use the type where the field was found, not its own type.
+ (maybe_access_field): Use field DECL_CONTEXT if the type where the
+ field was found is null.
+ (qualify_ambiguous_name): Sweep through all successive array
+ dimensions.
+
Wed Oct 14 18:21:29 1998 Alexandre Petit-Bianco <apbianco@cygnus.com>
* java-tree.h (pop_labeled_block, lang_printable_name,
diff --git a/gcc/java/lex.c b/gcc/java/lex.c
index 7caed76..1c103e1 100644
--- a/gcc/java/lex.c
+++ b/gcc/java/lex.c
@@ -37,7 +37,6 @@ Addison Wesley 1996" (http://java.sun.com/docs/books/jls/html/3.doc.html) */
#include <stdio.h>
#include <string.h>
#include <strings.h>
-#include <setjmp.h>
#ifdef JAVA_LEX_DEBUG
#include <ctype.h>
diff --git a/gcc/java/lex.h b/gcc/java/lex.h
index 155e1c3..fdee404 100644
--- a/gcc/java/lex.h
+++ b/gcc/java/lex.h
@@ -26,6 +26,8 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#ifndef JV_LEX_H
#define JV_LEX_H
+#include <setjmp.h> /* set_float_handler argument uses it */
+
/* Extern global variables declarations */
extern FILE *finput;
extern int lineno;
diff --git a/gcc/java/parse.h b/gcc/java/parse.h
index b53eaac..7c2b99d 100644
--- a/gcc/java/parse.h
+++ b/gcc/java/parse.h
@@ -399,6 +399,27 @@ static jdeplist *reverse_jdep_list ();
} \
}
+/* if TYPE can't be resolved, obtain something suitable for its
+ resolution (TYPE is saved in SAVE before being changed). and set
+ CHAIN to 1. Otherwise, type is set to something usable. CHAIN is
+ usually used to determine that a new DEP must be installed on TYPE. */
+#define SET_TYPE_FOR_RESOLUTION(TYPE, SAVE, CHAIN) \
+ { \
+ tree returned_type; \
+ (CHAIN) = 0; \
+ if (unresolved_type_p (type, &returned_type)) \
+ { \
+ if (returned_type) \
+ (TYPE) = returned_type; \
+ else \
+ { \
+ (SAVE) = (TYPE); \
+ (TYPE) = obtain_incomplete_type (TYPE); \
+ CHAIN = 1; \
+ } \
+ } \
+ }
+
/* Insert a DECL in the current block */
#define BLOCK_CHAIN_DECL(NODE) \
{ \
@@ -560,7 +581,7 @@ static tree create_class PROTO ((int, tree, tree, tree));
static tree create_interface PROTO ((int, tree, tree));
static tree find_field PROTO ((tree, tree));
static tree lookup_field_wrapper PROTO ((tree, tree));
-static int duplicate_declaration_error PROTO ((tree, tree, tree));
+static int duplicate_declaration_error_p PROTO ((tree, tree, tree));
static void register_fields PROTO ((int, tree, tree));
static tree parser_qualified_classname PROTO ((tree));
static int parser_check_super PROTO ((tree, tree, tree));
@@ -631,6 +652,7 @@ static int valid_method_invocation_conversion_p PROTO ((tree, tree));
static tree try_builtin_assignconv PROTO ((tree, tree, tree));
static tree try_reference_assignconv PROTO ((tree, tree));
static tree build_unresolved_array_type PROTO ((tree));
+static tree build_array_from_name PROTO ((tree, tree, tree, tree *));
static tree build_array_ref PROTO ((int, tree, tree));
static tree patch_array_ref PROTO ((tree, tree, tree));
static tree make_qualified_name PROTO ((tree, tree, int));
diff --git a/gcc/java/parse.y b/gcc/java/parse.y
index 4bd843f..93d1f81 100644
--- a/gcc/java/parse.y
+++ b/gcc/java/parse.y
@@ -51,7 +51,6 @@ definitions and other extensions. */
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
-#include <setjmp.h> /* set_float_handler argument uses it */
#ifdef __STDC__
#include <stdarg.h>
#else
@@ -619,9 +618,7 @@ variable_declarator:
variable_declarator_id:
identifier
| variable_declarator_id OSB_TK CSB_TK
- {
- $$ = NULL; /* FIXME */
- }
+ { $$ = build_unresolved_array_type ($1); }
| identifier error
{yyerror ("Invalid declaration"); DRECOVER(vdi);}
| variable_declarator_id OSB_TK error
@@ -2341,6 +2338,54 @@ variable_redefinition_error (context, name, type, line)
type_name, IDENTIFIER_POINTER (name), line);
}
+static tree
+build_array_from_name (type, type_wfl, name, ret_name)
+ tree type, type_wfl, name, *ret_name;
+{
+ int more_dims = 0;
+ char *string;
+
+ /* Eventually get more dims */
+ string = IDENTIFIER_POINTER (name);
+ while (string [more_dims] == '[')
+ more_dims++;
+
+ /* If we have, then craft a new type for this variable */
+ if (more_dims)
+ {
+ name = get_identifier (&more_dims [string]);
+
+ /* If type already is a reference on an array, get the base type */
+ if ((TREE_CODE (type) == POINTER_TYPE) &&
+ TYPE_ARRAY_P (TREE_TYPE (type)))
+ type = TREE_TYPE (type);
+
+ /* Building the first dimension of a primitive type uses this
+ function */
+ if (JPRIMITIVE_TYPE_P (type))
+ {
+ type = build_java_array_type (type, -1);
+ more_dims--;
+ }
+ /* Otherwise, if we have a WFL for this type, use it (the type
+ is already an array on an unresolved type, and we just keep
+ on adding dimensions) */
+ else if (type_wfl)
+ type = type_wfl;
+
+ /* Add all the dimensions */
+ while (more_dims--)
+ type = build_unresolved_array_type (type);
+
+ /* The type may have been incomplete in the first place */
+ if (type_wfl)
+ type = obtain_incomplete_type (type);
+ }
+
+ *ret_name = name;
+ return type;
+}
+
/* Build something that the type identifier resolver will identify as
being an array to an unresolved type. TYPE_WFL is a WFL on a
identifier. */
@@ -2661,10 +2706,11 @@ lookup_field_wrapper (class, name)
}
/* Find duplicate field within the same class declarations and report
- the error */
+ the error. Returns 1 if a duplicated field was found, 0
+ otherwise. */
static int
-duplicate_declaration_error (new_field_name, new_type, cl)
+duplicate_declaration_error_p (new_field_name, new_type, cl)
tree new_field_name, new_type, cl;
{
/* This might be modified to work with method decl as well */
@@ -2685,9 +2731,9 @@ duplicate_declaration_error (new_field_name, new_type, cl)
DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
free (t1);
free (t2);
- return 0;
+ return 1;
}
- return 1;
+ return 0;
}
/* Field registration routine. If TYPE doesn't exist, field
@@ -2699,7 +2745,7 @@ register_fields (flags, type, variable_list)
int flags;
tree type, variable_list;
{
- tree current, returned_type;
+ tree current, saved_type;
tree class_type = TREE_TYPE (ctxp->current_parsed_class);
int saved_lineno = lineno;
int must_chain = 0;
@@ -2722,70 +2768,77 @@ register_fields (flags, type, variable_list)
flags |= (ACC_PUBLIC | ACC_STATIC | ACC_FINAL);
}
- if (unresolved_type_p (type, &returned_type))
- {
- if (returned_type)
- type = returned_type;
- else
- {
- wfl = type;
- type = obtain_incomplete_type (type);
- must_chain = 1;
- }
- }
+ /* Obtain a suitable type for resolution, if necessary */
+ SET_TYPE_FOR_RESOLUTION (type, wfl, must_chain);
+
+ /* If TYPE is fully resolved and we don't have a reference, make one */
if (!must_chain && TREE_CODE (type) == RECORD_TYPE)
type = promote_type (type);
- for (current = variable_list; current; current = TREE_CHAIN (current))
+ for (current = variable_list, saved_type = type; current;
+ current = TREE_CHAIN (current), type = saved_type)
{
+ tree field_decl;
tree cl = TREE_PURPOSE (current);
tree init = TREE_VALUE (current);
tree current_name = EXPR_WFL_NODE (cl);
- if (duplicate_declaration_error (current_name, type, cl))
- {
- tree field_decl;
- lineno = EXPR_WFL_LINENO (cl);
- field_decl = add_field (class_type, current_name, type, flags);
+ /* Process NAME, as it may specify extra dimension(s) for it */
+ type = build_array_from_name (type, wfl, current_name, &current_name);
- /* Check if we must chain. */
- if (must_chain)
- register_incomplete_type (JDEP_FIELD, wfl, field_decl, type);
+ /* Check for redeclarations */
+ if (duplicate_declaration_error_p (current_name, type, cl))
+ continue;
+
+ /* Type adjustment. We may have just readjusted TYPE because
+ the variable specified more dimensions. Make sure we have
+ a reference if we can and don't have one already. */
+ if (type != saved_type && !must_chain
+ && (TREE_CODE (type) == RECORD_TYPE))
+ type = promote_type (type);
+
+ /* Set lineno to the line the field was found and create a
+ declaration for it */
+ lineno = EXPR_WFL_LINENO (cl);
+ field_decl = add_field (class_type, current_name, type, flags);
+
+ /* Check if we must chain. */
+ if (must_chain)
+ register_incomplete_type (JDEP_FIELD, wfl, field_decl, type);
- /* Default value of a static field is 0 and it is considered
- initialized. */
+ /* Default value of a static field is 0 and it is considered
+ initialized. */
+ if (flags & ACC_STATIC)
+ INITIALIZED_P (field_decl) = 1;
+
+ /* If we have an initialization value tied to the field */
+ if (init)
+ {
+ /* The field is declared static */
if (flags & ACC_STATIC)
- INITIALIZED_P (field_decl) = 1;
-
- /* If we have an initialization value tied to the field */
- if (init)
{
- /* The field is declared static */
- if (flags & ACC_STATIC)
- {
- /* FIXME */
- if (flags & ACC_FINAL)
- ;
- /* Otherwise, the field should be initialized in
- <clinit>. This field is remembered so we can
- generate <clinit> later. */
- else
- {
- INITIALIZED_P (field_decl) = 1;
- TREE_CHAIN (init) = ctxp->static_initialized;
- ctxp->static_initialized = init;
- }
- }
- /* A non-static field declared with an immediate
- initialization is to be initialized in <init>, if
- any. This field is remembered to be processed at the
- time of the generation of <init>. */
+ /* FIXME */
+ if (flags & ACC_FINAL)
+ ;
+ /* Otherwise, the field should be initialized in
+ <clinit>. This field is remembered so we can
+ generate <clinit> later. */
else
{
- TREE_CHAIN (init) = ctxp->non_static_initialized;
- ctxp->non_static_initialized = init;
+ INITIALIZED_P (field_decl) = 1;
+ TREE_CHAIN (init) = ctxp->static_initialized;
+ ctxp->static_initialized = init;
}
}
+ /* A non-static field declared with an immediate
+ initialization is to be initialized in <init>, if
+ any. This field is remembered to be processed at the
+ time of the generation of <init>. */
+ else
+ {
+ TREE_CHAIN (init) = ctxp->non_static_initialized;
+ ctxp->non_static_initialized = init;
+ }
}
}
lineno = saved_lineno;
@@ -3053,10 +3106,19 @@ method_declarator (id, list)
for (current = list; current; current = TREE_CHAIN (current))
{
+ int must_chain = 0;
tree wfl_name = TREE_PURPOSE (current);
tree type = TREE_VALUE (current);
tree name = EXPR_WFL_NODE (wfl_name);
- tree already, arg_node, returned_type;
+ tree already, arg_node;
+ tree type_wfl = NULL_TREE;
+
+ /* Obtain a suitable type for resolution, if necessary */
+ SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
+
+ /* Process NAME, as it may specify extra dimension(s) for it */
+ type = build_array_from_name (type, type_wfl, name, &name);
+ EXPR_WFL_NODE (wfl_name) = name;
/* Check redefinition */
for (already = arg_types; already; already = TREE_CHAIN (already))
@@ -3072,19 +3134,15 @@ method_declarator (id, list)
/* If we've an incomplete argument type, we know there is a location
to patch when the type get resolved, later. */
jdep = NULL;
- if (unresolved_type_p (type, &returned_type))
+ if (must_chain)
{
- if (returned_type)
- type = returned_type;
- else
- {
- patch_stage = JDEP_METHOD;
- type = register_incomplete_type (patch_stage, type,
- wfl_name, NULL_TREE);
- jdep = CLASSD_LAST (ctxp->classd_list);
- JDEP_MISC (jdep) = id;
- }
+ patch_stage = JDEP_METHOD;
+ type = register_incomplete_type (patch_stage,
+ type_wfl, wfl_name, type);
+ jdep = CLASSD_LAST (ctxp->classd_list);
+ JDEP_MISC (jdep) = id;
}
+
/* The argument node: a name and a (possibly) incomplete type */
arg_node = build_tree_list (name, type);
if (jdep)
@@ -3539,6 +3597,7 @@ resolve_class (class_type, decl, cl)
if (TREE_CODE (resolved_type) == RECORD_TYPE)
resolved_type = promote_type (resolved_type);
resolved_type = build_java_array_type (resolved_type, -1);
+ CLASS_LOADED_P (resolved_type) = 1;
name--;
}
/* Build a fake decl for this, since this is what is expected to
@@ -4260,10 +4319,8 @@ read_import_dir (wfl)
if (jcf->seen_in_zip)
jcf->zipd = ZIPDIR_NEXT ((ZipDirectory *)jcf->zipd);
- else if (founddirname && (dirp = opendir (founddirname)))
- {
- readdir (dirp); readdir (dirp);
- }
+ else if (founddirname)
+ dirp = opendir (founddirname);
if (!founddirname && !dirp)
{
@@ -4429,7 +4486,8 @@ declare_local_variables (modifier, type, vlist)
tree type;
tree vlist;
{
- tree decl, current, returned_type, type_wfl;
+ tree decl, current, saved_type;
+ tree type_wfl = NULL_TREE;
int must_chain = 0;
/* Push a new block if statement were seen between the last time we
@@ -4453,57 +4511,69 @@ declare_local_variables (modifier, type, vlist)
return;
}
- if (unresolved_type_p (type, &returned_type))
- {
- if (returned_type)
- type = returned_type;
- else
- {
- type_wfl = type;
- type = obtain_incomplete_type (type);
- must_chain = 1;
- }
- }
+ /* Obtain an incomplete type if TYPE is not complete. TYPE_WFL will
+ hold the TYPE value if a new incomplete has to be created (as
+ opposed to being found already existing and reused). */
+ SET_TYPE_FOR_RESOLUTION (type, type_wfl, must_chain);
+
+ /* If TYPE is fully resolved and we don't have a reference, make one */
if (!must_chain && TREE_CODE (type) == RECORD_TYPE)
type = promote_type (type);
-
- for (current = vlist; current; current = TREE_CHAIN (current))
+
+ /* Go through all the declared variables */
+ for (current = vlist, saved_type = type; current;
+ current = TREE_CHAIN (current), type = saved_type)
{
+ tree other;
tree wfl = TREE_PURPOSE (current);
tree name = EXPR_WFL_NODE (wfl);
tree init = TREE_VALUE (current);
- tree other = lookup_name_in_blocks (name);
+ /* Process NAME, as it may specify extra dimension(s) for it */
+ type = build_array_from_name (type, type_wfl, name, &name);
+
+ /* Variable redefinition check */
+ if ((other = lookup_name_in_blocks (name)))
+ {
+ variable_redefinition_error (wfl, name, TREE_TYPE (other),
+ DECL_SOURCE_LINE (other));
+ continue;
+ }
+
+ /* Type adjustment. We may have just readjusted TYPE because
+ the variable specified more dimensions. Make sure we have
+ a reference if we can and don't have one already. */
+ if (type != saved_type && !must_chain
+ && (TREE_CODE (type) == RECORD_TYPE))
+ type = promote_type (type);
+
+ /* Never layout this decl. This will be done when its scope
+ will be entered */
+ decl = build_decl_no_layout (VAR_DECL, name, type);
+ BLOCK_CHAIN_DECL (decl);
+
/* Don't try to use an INIT statement when an error was found */
if (init && java_error_count)
init = NULL_TREE;
-
- if (other)
- variable_redefinition_error (wfl, name, TREE_TYPE (other),
- DECL_SOURCE_LINE (other));
- else
+
+ /* Add the initialization function to the current function's code */
+ if (init)
{
- /* Never layout this decl. This will be done when its scope
- will be entered */
- decl = build_decl_no_layout (VAR_DECL, name, type);
- BLOCK_CHAIN_DECL (decl);
-
- /* Add the initialization function to the current function's code */
- if (init)
- {
- MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
- java_method_add_stmt
- (current_function_decl,
- build_debugable_stmt (EXPR_WFL_LINECOL (init), init));
- }
-
- if (must_chain)
- {
- jdep *dep;
- register_incomplete_type (JDEP_VARIABLE, type_wfl, decl, type);
- dep = CLASSD_LAST (ctxp->classd_list);
- JDEP_GET_PATCH (dep) = &TREE_TYPE (decl);
- }
+ /* Name might have been readjusted */
+ EXPR_WFL_NODE (TREE_OPERAND (init, 0)) = name;
+ MODIFY_EXPR_FROM_INITIALIZATION_P (init) = 1;
+ java_method_add_stmt (current_function_decl,
+ build_debugable_stmt (EXPR_WFL_LINECOL (init),
+ init));
+ }
+
+ /* Setup dependency the type of the decl */
+ if (must_chain)
+ {
+ jdep *dep;
+ register_incomplete_type (JDEP_VARIABLE, type_wfl, decl, type);
+ dep = CLASSD_LAST (ctxp->classd_list);
+ JDEP_GET_PATCH (dep) = &TREE_TYPE (decl);
}
}
SOURCE_FRONTEND_DEBUG (("Defined locals"));
@@ -5319,7 +5389,7 @@ resolve_qualified_expression_name (wfl, found_decl, where_found, type_found)
on what this field is accessed from, do it now. */
if (!is_static)
{
- decl = maybe_access_field (decl, *where_found, type);
+ decl = maybe_access_field (decl, *where_found, *type_found);
if (decl == error_mark_node)
return 1;
}
@@ -5451,7 +5521,8 @@ maybe_access_field (decl, where, type)
&& FIELD_STATIC (decl)))
&& !IDENTIFIER_LOCAL_VALUE (DECL_NAME (decl)))
decl = build_field_ref (where ? where : current_this,
- type, DECL_NAME (decl));
+ (type ? type : DECL_CONTEXT (decl)),
+ DECL_NAME (decl));
return decl;
}
@@ -6027,10 +6098,12 @@ qualify_ambiguous_name (id)
break;
case NEW_CLASS_EXPR:
case CONVERT_EXPR:
- case ARRAY_REF:
qual_wfl = TREE_OPERAND (qual_wfl, 0);
break;
-
+ case ARRAY_REF:
+ while (TREE_CODE (qual_wfl) == ARRAY_REF)
+ qual_wfl = TREE_OPERAND (qual_wfl, 0);
+ break;
default:
/* Fix for -Wall. Just break doing nothing */
break;