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
This commit is contained in:
Alexandre Petit-Bianco 1998-10-16 19:36:39 +00:00 committed by Alexandre Petit-Bianco
parent 8e52e063af
commit c583dd46ad
5 changed files with 245 additions and 120 deletions

View file

@ -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,

View file

@ -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>

View file

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

View file

@ -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));

View file

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