Commit 38c9d142 by Ranjit Mathew

re PR java/19870 (gcj -C doesn't generate accessors for private members across…

re PR java/19870 (gcj -C doesn't generate accessors for private members across nested class boundaries)

	PR java/19870.
	* java-tree.h (OUTER_FIELD_ACCESS_IDENTIFIER_P): Rename to
	NESTED_FIELD_ACCESS_IDENTIFIER_P.
	(FIELD_INNER_ACCESS): Rename to FIELD_NESTED_ACCESS.
	(FIELD_INNER_ACCESS_P): Rename to FIELD_NESTED_ACCESS_P.
	* jcf-write.c (generate_classfile): Use
	NESTED_FIELD_ACCESS_IDENTIFIER_P instead of
	OUTER_FIELD_ACCESS_IDENTIFIER_P.
	* parse.y (build_outer_field_access): Rename to
	build_nested_field_access. Support static fields and outer-to-inner
	class accesses.
	(outer_field_access_p): Rename to nested_field_access_p. Support
	static fields and generalise to outer-to-inner class and sibling
	inner class accesses.
	(outer_field_expanded_access_p): Rename to
	nested_field_expanded_access_p and support static fields.
	(outer_field_access_fix): Rename to nested_field_access_fix and
	support static fields.
	(build_outer_field_access_expr): Rename to
	build_nested_field_access_expr and support static fields.
	(build_outer_field_access_methods): Rename to
	build_nested_field_access_methods and support static fields. For
	static fields, generate accessors without class instance parameters.
	(build_outer_field_access_method): Rename to
	build_nested_field_access_method and support static fields.
	(build_outer_method_access_method): Use
	NESTED_FIELD_ACCESS_IDENTIFIER_P instead of
	OUTER_FIELD_ACCESS_IDENTIFIER_P.
	(resolve_expression_name): Consider static field accesses across
	nested classes.
	(resolve_qualified_expression_name): Likewise.
	(java_complete_lhs): Use nested_field_access_fix instead of
	outer_field_access_fix.
	(patch_unary_op): Rename outer_field_flag to nested_field_flag.
	Use nested_field_expanded_access_p instead of
	outer_field_expanded_access_p. Use nested_field_access_fix instead
	of outer_field_access_fix.
	(check_thrown_exceptions): Use NESTED_FIELD_ACCESS_IDENTIFIER_P
	instead of OUTER_FIELD_ACCESS_IDENTIFIER_P.

From-SVN: r100246
parent 27358466
2005-05-26 Ranjit Mathew <rmathew@hotmail.com>
PR java/19870.
* java-tree.h (OUTER_FIELD_ACCESS_IDENTIFIER_P): Rename to
NESTED_FIELD_ACCESS_IDENTIFIER_P.
(FIELD_INNER_ACCESS): Rename to FIELD_NESTED_ACCESS.
(FIELD_INNER_ACCESS_P): Rename to FIELD_NESTED_ACCESS_P.
* jcf-write.c (generate_classfile): Use
NESTED_FIELD_ACCESS_IDENTIFIER_P instead of
OUTER_FIELD_ACCESS_IDENTIFIER_P.
* parse.y (build_outer_field_access): Rename to
build_nested_field_access. Support static fields and outer-to-inner
class accesses.
(outer_field_access_p): Rename to nested_field_access_p. Support
static fields and generalise to outer-to-inner class and sibling
inner class accesses.
(outer_field_expanded_access_p): Rename to
nested_field_expanded_access_p and support static fields.
(outer_field_access_fix): Rename to nested_field_access_fix and
support static fields.
(build_outer_field_access_expr): Rename to
build_nested_field_access_expr and support static fields.
(build_outer_field_access_methods): Rename to
build_nested_field_access_methods and support static fields. For
static fields, generate accessors without class instance parameters.
(build_outer_field_access_method): Rename to
build_nested_field_access_method and support static fields.
(build_outer_method_access_method): Use
NESTED_FIELD_ACCESS_IDENTIFIER_P instead of
OUTER_FIELD_ACCESS_IDENTIFIER_P.
(resolve_expression_name): Consider static field accesses across
nested classes.
(resolve_qualified_expression_name): Likewise.
(java_complete_lhs): Use nested_field_access_fix instead of
outer_field_access_fix.
(patch_unary_op): Rename outer_field_flag to nested_field_flag.
Use nested_field_expanded_access_p instead of
outer_field_expanded_access_p. Use nested_field_access_fix instead
of outer_field_access_fix.
(check_thrown_exceptions): Use NESTED_FIELD_ACCESS_IDENTIFIER_P
instead of OUTER_FIELD_ACCESS_IDENTIFIER_P.
2005-05-26 Bryce McKinlay <mckinlay@redhat.com>
* decl.c (GCJ_BINARYCOMPAT_ADDITION,
......@@ -10461,7 +10503,7 @@
properly initialize `finished_label'. Don't emit gotos for empty
try statements.
2000-03-19 Martin v. Lwis <loewis@informatik.hu-berlin.de>
2000-03-19 Martin v. Lis <loewis@informatik.hu-berlin.de>
* except.c (emit_handlers): Clear catch_clauses_last.
......
......@@ -71,7 +71,7 @@ struct JCF;
IS_CRAFTED_STRING_BUFFER_P (in CALL_EXPR)
IS_INIT_CHECKED (in SAVE_EXPR)
6: CAN_COMPLETE_NORMALLY (in statement nodes)
OUTER_FIELD_ACCESS_IDENTIFIER_P (in IDENTIFIER_NODE)
NESTED_FIELD_ACCESS_IDENTIFIER_P (in IDENTIFIER_NODE)
Usage of TYPE_LANG_FLAG_?:
0: CLASS_ACCESS0_GENERATED_P (in RECORD_TYPE)
......@@ -896,16 +896,16 @@ union lang_tree_node
#define DECL_LOCAL_START_PC(NODE) (DECL_LANG_SPECIFIC (NODE)->u.v.start_pc)
/* The end (bytecode) pc for the valid range of this local variable. */
#define DECL_LOCAL_END_PC(NODE) (DECL_LANG_SPECIFIC (NODE)->u.v.end_pc)
/* For a VAR_DECLor PARM_DECL, used to chain decls with the same
/* For a VAR_DECL or PARM_DECL, used to chain decls with the same
slot_number in decl_map. */
#define DECL_LOCAL_SLOT_CHAIN(NODE) (DECL_LANG_SPECIFIC(NODE)->u.v.slot_chain)
/* For a FIELD_DECL, holds the name of the access method. Used to
read/write the content of the field from an inner class. */
#define FIELD_INNER_ACCESS(DECL) \
read/write the content of the field across nested class boundaries. */
#define FIELD_NESTED_ACCESS(DECL) \
(DECL_LANG_SPECIFIC (VAR_OR_FIELD_CHECK (DECL))->u.v.am)
/* Safely tests whether FIELD_INNER_ACCESS exists or not. */
#define FIELD_INNER_ACCESS_P(DECL) \
DECL_LANG_SPECIFIC (DECL) && FIELD_INNER_ACCESS (DECL)
/* Safely tests whether FIELD_NESTED_ACCESS exists or not. */
#define FIELD_NESTED_ACCESS_P(DECL) \
DECL_LANG_SPECIFIC (DECL) && FIELD_NESTED_ACCESS (DECL)
/* True if a final field was initialized upon its declaration
or in an initializer. Set after definite assignment. */
#define DECL_FIELD_FINAL_IUD(NODE) (DECL_LANG_SPECIFIC (NODE)->u.v.final_iud)
......@@ -1689,9 +1689,9 @@ extern tree *type_map;
/* True if NODE (a statement) can complete normally. */
#define CAN_COMPLETE_NORMALLY(NODE) TREE_LANG_FLAG_6 (NODE)
/* True if NODE (an IDENTIFIER) bears the name of a outer field from
inner class access function. */
#define OUTER_FIELD_ACCESS_IDENTIFIER_P(NODE) \
/* True if NODE (an IDENTIFIER) bears the name of an outer field from
inner class (or vice versa) access function. */
#define NESTED_FIELD_ACCESS_IDENTIFIER_P(NODE) \
TREE_LANG_FLAG_6 (IDENTIFIER_NODE_CHECK (NODE))
/* True if NODE belongs to an inner class TYPE_DECL node.
......
......@@ -3087,7 +3087,7 @@ generate_classfile (tree clas, struct jcf_partial *state)
/* Make room for the Synthetic attribute (of zero length.) */
if (DECL_FINIT_P (part)
|| DECL_INSTINIT_P (part)
|| OUTER_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (part))
|| NESTED_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (part))
|| TYPE_DOT_CLASS (clas) == part)
{
i++;
......
......@@ -320,19 +320,17 @@ static tree build_current_thisn (tree);
static tree build_access_to_thisn (tree, tree, int);
static tree maybe_build_thisn_access_method (tree);
static tree build_outer_field_access (tree, tree);
static tree build_outer_field_access_methods (tree);
static tree build_outer_field_access_expr (int, tree, tree,
tree, tree);
static tree build_nested_field_access (tree, tree);
static tree build_nested_field_access_methods (tree);
static tree build_nested_field_access_method (tree, tree, tree, tree, tree);
static tree build_nested_field_access_expr (int, tree, tree, tree, tree);
static tree build_outer_method_access_method (tree);
static tree build_new_access_id (void);
static tree build_outer_field_access_method (tree, tree, tree,
tree, tree);
static int outer_field_access_p (tree, tree);
static int outer_field_expanded_access_p (tree, tree *,
tree *, tree *);
static tree outer_field_access_fix (tree, tree, tree);
static int nested_field_access_p (tree, tree);
static int nested_field_expanded_access_p (tree, tree *, tree *, tree *);
static tree nested_field_access_fix (tree, tree, tree);
static tree build_incomplete_class_ref (int, tree);
static tree patch_incomplete_class_ref (tree);
static tree create_anonymous_class (tree);
......@@ -8289,101 +8287,146 @@ java_expand_method_bodies (tree class)
fields either directly by using the relevant access to this$<n> or
by invoking an access method crafted for that purpose. */
/* Build the necessary access from an inner class to an outer
class. This routine could be optimized to cache previous result
/* Build the necessary access across nested class boundaries.
This routine could be optimized to cache previous result
(decl, current_class and returned access). When an access method
needs to be generated, it always takes the form of a read. It might
be later turned into a write by calling outer_field_access_fix. */
be later turned into a write by calling nested_field_access_fix. */
static tree
build_outer_field_access (tree id, tree decl)
build_nested_field_access (tree id, tree decl)
{
tree access = NULL_TREE;
tree ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
tree ctx = NULL_TREE;
tree decl_ctx = DECL_CONTEXT (decl);
bool is_static = FIELD_STATIC (decl);
if (DECL_CONTEXT (TYPE_NAME (current_class)))
ctx = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (current_class)));
/* If the immediate enclosing context of the current class is the
field decl's class or inherits from it; build the access as
`this$<n>.<field>'. Note that we will break the `private' barrier
if we're not emitting bytecodes. */
if ((ctx == decl_ctx || inherits_from_p (ctx, decl_ctx))
&& (!FIELD_PRIVATE (decl) || !flag_emit_class_files ))
/* For non-static fields, if the immediate enclosing context of the
current class is the field decl's class or inherits from it,
build the access as `this$<n>.<field>'. Note that we will break
the `private' barrier if we're not emitting bytecodes. */
if (!is_static
&& ctx
&& (ctx == decl_ctx || inherits_from_p (ctx, decl_ctx))
&& (!FIELD_PRIVATE (decl) || !flag_emit_class_files))
{
tree thisn = build_current_thisn (current_class);
access = make_qualified_primary (build_wfl_node (thisn),
id, EXPR_WFL_LINECOL (id));
}
/* Otherwise, generate access methods to outer this and access the
field (either using an access method or by direct access.) */
/* Otherwise, generate and use accessor methods for the field as
needed. */
else
{
int lc = EXPR_WFL_LINECOL (id);
/* Now we chain the required number of calls to the access$0 to
get a hold to the enclosing instance we need, and then we
build the field access. */
get a hold to the enclosing instance we need for a non-static
field, and then we build the field access. */
if (!is_static)
access = build_access_to_thisn (current_class, decl_ctx, lc);
/* If the field is private and we're generating bytecode, then
we generate an access method */
if (FIELD_PRIVATE (decl) && flag_emit_class_files )
we generate an access method. */
if (FIELD_PRIVATE (decl) && flag_emit_class_files)
{
tree name = build_outer_field_access_methods (decl);
access = build_outer_field_access_expr (lc, decl_ctx,
tree name = build_nested_field_access_methods (decl);
access = build_nested_field_access_expr (lc, decl_ctx,
name, access, NULL_TREE);
}
/* Otherwise we use `access$(this$<j>). ... access$(this$<i>).<field>'.
/* Otherwise we use `access$(this$<j>). ... access$(this$<i>).<field>'
for non-static fields.
Once again we break the `private' access rule from a foreign
class. */
else if (is_static)
{
tree class_name = DECL_NAME (TYPE_NAME (decl_ctx));
access
= make_qualified_primary (build_wfl_node (class_name), id, lc);
}
else
access = make_qualified_primary (access, id, lc);
}
return resolve_expression_name (access, NULL);
}
/* Return a nonzero value if NODE describes an outer field inner
access. */
/* Return a nonzero value if DECL describes a field access across nested
class boundaries. That is, DECL is in a class that either encloses,
is enclosed by or shares a common enclosing class with, the class
TYPE. */
static int
outer_field_access_p (tree type, tree decl)
nested_field_access_p (tree type, tree decl)
{
bool is_static = false;
tree decl_type = DECL_CONTEXT (decl);
tree type_root, decl_type_root;
if (decl_type == type
|| (TREE_CODE (decl) != FIELD_DECL && TREE_CODE (decl) != VAR_DECL))
return 0;
if (!INNER_CLASS_TYPE_P (type)
|| TREE_CODE (decl) != FIELD_DECL
|| DECL_CONTEXT (decl) == type)
&& !(TREE_CODE (decl_type) == RECORD_TYPE
&& INNER_CLASS_TYPE_P (decl_type)))
return 0;
/* If the inner class extends the declaration context of the field
we're trying to access, then this isn't an outer field access */
if (inherits_from_p (type, DECL_CONTEXT (decl)))
is_static = FIELD_STATIC (decl);
/* If TYPE extends the declaration context of the non-static
field we're trying to access, then this isn't a nested field
access we need to worry about. */
if (!is_static && inherits_from_p (type, decl_type))
return 0;
for (type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))); ;
type = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type))))
for (type_root = type;
DECL_CONTEXT (TYPE_NAME (type_root));
type_root = TREE_TYPE (DECL_CONTEXT (TYPE_NAME (type_root))))
{
if (type == DECL_CONTEXT (decl))
if (type_root == decl_type)
return 1;
if (!DECL_CONTEXT (TYPE_NAME (type)))
/* Before we give up, see whether it is a non-static field
inherited from the enclosing context we are considering. */
if (!DECL_CONTEXT (TYPE_NAME (type_root))
&& !is_static
&& inherits_from_p (type_root, decl_type))
return 1;
}
if (TREE_CODE (decl_type) == RECORD_TYPE
&& INNER_CLASS_TYPE_P (decl_type))
{
/* Before we give up, see whether the field is inherited from
the enclosing context we're considering. */
if (inherits_from_p (type, DECL_CONTEXT (decl)))
for (decl_type_root = decl_type;
DECL_CONTEXT (TYPE_NAME (decl_type_root));
decl_type_root
= TREE_TYPE (DECL_CONTEXT (TYPE_NAME (decl_type_root))))
{
if (decl_type_root == type)
return 1;
break;
}
}
else
decl_type_root = decl_type;
if (type_root == decl_type_root)
return 1;
return 0;
}
/* Return a nonzero value if NODE represents an outer field inner
access that was been already expanded. As a side effect, it returns
/* Return a nonzero value if NODE represents a cross-nested-class
access that has already been expanded. As a side effect, it returns
the name of the field being accessed and the argument passed to the
access function, suitable for a regeneration of the access method
call if necessary. */
static int
outer_field_expanded_access_p (tree node, tree *name, tree *arg_type,
nested_field_expanded_access_p (tree node, tree *name, tree *arg_type,
tree *arg)
{
int identified = 0;
......@@ -8391,12 +8434,12 @@ outer_field_expanded_access_p (tree node, tree *name, tree *arg_type,
if (TREE_CODE (node) != CALL_EXPR)
return 0;
/* Well, gcj generates slightly different tree nodes when compiling
/* Well, GCJ generates slightly different tree nodes when compiling
to native or bytecodes. It's the case for function calls. */
if (flag_emit_class_files
&& TREE_CODE (node) == CALL_EXPR
&& OUTER_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (TREE_OPERAND (node, 0))))
&& NESTED_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (TREE_OPERAND (node, 0))))
identified = 1;
else if (!flag_emit_class_files)
{
......@@ -8408,7 +8451,7 @@ outer_field_expanded_access_p (tree node, tree *name, tree *arg_type,
node = TREE_OPERAND (node, 0);
if (TREE_OPERAND (node, 0)
&& TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
&& (OUTER_FIELD_ACCESS_IDENTIFIER_P
&& (NESTED_FIELD_ACCESS_IDENTIFIER_P
(DECL_NAME (TREE_OPERAND (node, 0)))))
identified = 1;
}
......@@ -8418,25 +8461,36 @@ outer_field_expanded_access_p (tree node, tree *name, tree *arg_type,
{
tree argument = TREE_OPERAND (node, 1);
*name = DECL_NAME (TREE_OPERAND (node, 0));
/* The accessors for static fields do not take in a this$<n> argument,
so we take the class name from the accessor's context instead. */
if (argument)
{
*arg_type = TREE_TYPE (TREE_TYPE (TREE_VALUE (argument)));
*arg = TREE_VALUE (argument);
}
else
{
*arg_type = DECL_CONTEXT (TREE_OPERAND (node, 0));
*arg = NULL_TREE;
}
}
return identified;
}
/* Detect in NODE an outer field read access from an inner class and
transform it into a write with RHS as an argument. This function is
called from the java_complete_lhs when an assignment to a LHS can
/* Detect in NODE cross-nested-class field read access and
transform it into a write with RHS as an argument. This function
is called from the java_complete_lhs when an assignment to a LHS can
be identified. */
static tree
outer_field_access_fix (tree wfl, tree node, tree rhs)
nested_field_access_fix (tree wfl, tree node, tree rhs)
{
tree name, arg_type, arg;
if (outer_field_expanded_access_p (node, &name, &arg_type, &arg))
if (nested_field_expanded_access_p (node, &name, &arg_type, &arg))
{
node = build_outer_field_access_expr (EXPR_WFL_LINECOL (wfl),
node = build_nested_field_access_expr (EXPR_WFL_LINECOL (wfl),
arg_type, name, arg, rhs);
return java_complete_tree (node);
}
......@@ -8450,23 +8504,34 @@ outer_field_access_fix (tree wfl, tree node, tree rhs)
read access. */
static tree
build_outer_field_access_expr (int lc, tree type, tree access_method_name,
build_nested_field_access_expr (int lc, tree type, tree access_method_name,
tree arg1, tree arg2)
{
tree args, cn, access;
args = arg1 ? arg1 :
build_wfl_node (build_current_thisn (current_class));
args = build_tree_list (NULL_TREE, args);
if (arg1)
args = build_tree_list (NULL_TREE, arg1);
else
args = NULL_TREE;
if (arg2)
{
if (args)
args = tree_cons (NULL_TREE, arg2, args);
else
args = build_tree_list (NULL_TREE, arg2);
}
access = build_method_invocation (build_wfl_node (access_method_name), args);
access
= build_method_invocation (build_wfl_node (access_method_name), args);
cn = build_wfl_node (DECL_NAME (TYPE_NAME (type)));
return make_qualified_primary (cn, access, lc);
}
/* Build the name of a synthetic accessor used to access class members
across nested class boundaries. */
static tree
build_new_access_id (void)
{
......@@ -8477,8 +8542,8 @@ build_new_access_id (void)
return get_identifier (buffer);
}
/* Create the static access functions for the outer field DECL. We define a
read:
/* Create the static access functions for the cross-nested-class field DECL.
We define a read:
TREE_TYPE (<field>) access$<n> (DECL_CONTEXT (<field>) inst$) {
return inst$.field;
}
......@@ -8487,17 +8552,20 @@ build_new_access_id (void)
TREE_TYPE (<field>) value$) {
return inst$.field = value$;
}
We should have a usage flags on the DECL so we can lazily turn the ones
For static fields, these methods are generated without the instance
parameter.
We should have a usage flag on the DECL so we can lazily turn the ones
we're using for code generation. FIXME.
*/
static tree
build_outer_field_access_methods (tree decl)
build_nested_field_access_methods (tree decl)
{
tree id, args, stmt, mdecl;
tree id, args, stmt, mdecl, class_name = NULL_TREE;
bool is_static = FIELD_STATIC (decl);
if (FIELD_INNER_ACCESS_P (decl))
return FIELD_INNER_ACCESS (decl);
if (FIELD_NESTED_ACCESS_P (decl))
return FIELD_NESTED_ACCESS (decl);
MAYBE_CREATE_VAR_LANG_DECL_SPECIFIC (decl);
......@@ -8506,43 +8574,66 @@ build_outer_field_access_methods (tree decl)
/* The identifier is marked as bearing the name of a generated write
access function for outer field accessed from inner classes. */
OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
NESTED_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
/* Create the read access */
args = build_tree_list (inst_id, build_pointer_type (DECL_CONTEXT (decl)));
/* Create the read access. */
if (!is_static)
{
args = build_tree_list (inst_id,
build_pointer_type (DECL_CONTEXT (decl)));
TREE_CHAIN (args) = end_params_node;
stmt = make_qualified_primary (build_wfl_node (inst_id),
build_wfl_node (DECL_NAME (decl)), 0);
}
else
{
args = end_params_node;
class_name = DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl)));
stmt = make_qualified_primary (build_wfl_node (class_name),
build_wfl_node (DECL_NAME (decl)), 0);
}
stmt = build_return (0, stmt);
mdecl = build_outer_field_access_method (DECL_CONTEXT (decl),
mdecl = build_nested_field_access_method (DECL_CONTEXT (decl),
TREE_TYPE (decl), id, args, stmt);
DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
/* Create the write access method. No write access for final variable */
if (!FIELD_FINAL (decl))
{
if (!is_static)
{
args = build_tree_list (inst_id,
build_pointer_type (DECL_CONTEXT (decl)));
TREE_CHAIN (args) = build_tree_list (wpv_id, TREE_TYPE (decl));
TREE_CHAIN (TREE_CHAIN (args)) = end_params_node;
stmt = make_qualified_primary (build_wfl_node (inst_id),
build_wfl_node (DECL_NAME (decl)), 0);
build_wfl_node (DECL_NAME (decl)),
0);
}
else
{
args = build_tree_list (wpv_id, TREE_TYPE (decl));
TREE_CHAIN (args) = end_params_node;
stmt = make_qualified_primary (build_wfl_node (class_name),
build_wfl_node (DECL_NAME (decl)),
0);
}
stmt = build_return (0, build_assignment (ASSIGN_TK, 0, stmt,
build_wfl_node (wpv_id)));
mdecl = build_outer_field_access_method (DECL_CONTEXT (decl),
mdecl = build_nested_field_access_method (DECL_CONTEXT (decl),
TREE_TYPE (decl), id,
args, stmt);
}
DECL_FUNCTION_ACCESS_DECL (mdecl) = decl;
/* Return the access name */
return FIELD_INNER_ACCESS (decl) = id;
return FIELD_NESTED_ACCESS (decl) = id;
}
/* Build an field access method NAME. */
/* Build a field access method NAME. */
static tree
build_outer_field_access_method (tree class, tree type, tree name,
build_nested_field_access_method (tree class, tree type, tree name,
tree args, tree body)
{
tree saved_current_function_decl, mdecl;
......@@ -8587,7 +8678,7 @@ build_outer_method_access_method (tree decl)
/* Obtain an access identifier and mark it */
id = build_new_access_id ();
OUTER_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
NESTED_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
carg = TYPE_ARG_TYPES (TREE_TYPE (decl));
/* Create the arguments, as much as the original */
......@@ -8653,7 +8744,7 @@ build_outer_method_access_method (tree decl)
others. Access methods to this$<n> are build on the fly if
necessary. This CAN'T be used to solely access this$<n-1> from
this$<n> (which alway yield to special cases and optimization, see
for example build_outer_field_access). */
for example build_nested_field_access). */
static tree
build_access_to_thisn (tree from, tree to, int lc)
......@@ -9456,15 +9547,15 @@ resolve_expression_name (tree id, tree *orig)
/* If we're processing an inner class and we're trying
to access a field belonging to an outer class, build
the access to the field */
if (!fs && outer_field_access_p (current_class, decl))
the access to the field. */
if (nested_field_access_p (current_class, decl))
{
if (CLASS_STATIC (TYPE_NAME (current_class)))
if (!fs && CLASS_STATIC (TYPE_NAME (current_class)))
{
static_ref_err (id, DECL_NAME (decl), current_class);
return error_mark_node;
}
access = build_outer_field_access (id, decl);
access = build_nested_field_access (id, decl);
if (orig)
*orig = access;
return access;
......@@ -9993,7 +10084,11 @@ resolve_qualified_expression_name (tree wfl, tree *found_decl,
decl = QUAL_RESOLUTION (q);
if (!type)
{
if (TREE_CODE (decl) == FIELD_DECL && !FIELD_STATIC (decl))
if (TREE_CODE (decl) == FIELD_DECL
|| TREE_CODE (decl) == VAR_DECL)
{
if (TREE_CODE (decl) == FIELD_DECL
&& !FIELD_STATIC (decl))
{
if (current_this)
*where_found = current_this;
......@@ -10003,8 +10098,15 @@ resolve_qualified_expression_name (tree wfl, tree *found_decl,
current_class);
return 1;
}
if (outer_field_access_p (current_class, decl))
decl = build_outer_field_access (qual_wfl, decl);
}
else
{
*where_found = TREE_TYPE (decl);
if (TREE_CODE (*where_found) == POINTER_TYPE)
*where_found = TREE_TYPE (*where_found);
}
if (nested_field_access_p (current_class, decl))
decl = build_nested_field_access (qual_wfl, decl);
}
else
{
......@@ -10113,7 +10215,7 @@ resolve_qualified_expression_name (tree wfl, tree *found_decl,
}
from_cast = from_super = 0;
/* It's an access from a type but it isn't static, we
/* If it's an access from a type but isn't static, we
make it relative to `this'. */
if (!is_static && from_type)
decl = current_this;
......@@ -10128,8 +10230,8 @@ resolve_qualified_expression_name (tree wfl, tree *found_decl,
return 1;
}
/* We want to keep the location were found it, and the type
we found. */
/* We want to keep the location where we found it, and the
type we found. */
*where_found = decl;
*type_found = type;
......@@ -10137,10 +10239,18 @@ resolve_qualified_expression_name (tree wfl, tree *found_decl,
qualified this */
if (from_qualified_this)
{
field_decl = build_outer_field_access (qual_wfl, field_decl);
field_decl
= build_nested_field_access (qual_wfl, field_decl);
from_qualified_this = 0;
}
/* If needed, generate accessors for static field access. */
if (is_static
&& FIELD_PRIVATE (field_decl)
&& flag_emit_class_files
&& nested_field_access_p (current_class, field_decl))
field_decl = build_nested_field_access (qual_wfl, field_decl);
/* This is the decl found and eventually the next one to
search from */
decl = field_decl;
......@@ -12120,10 +12230,10 @@ java_complete_lhs (tree node)
if ((nn = patch_string (TREE_OPERAND (node, 1))))
TREE_OPERAND (node, 1) = nn;
if ((nn = outer_field_access_fix (wfl_op1, TREE_OPERAND (node, 0),
if ((nn = nested_field_access_fix (wfl_op1, TREE_OPERAND (node, 0),
TREE_OPERAND (node, 1))))
{
/* We return error_mark_node if outer_field_access_fix
/* We return error_mark_node if nested_field_access_fix
detects we write into a final. */
if (nn == error_mark_node)
return error_mark_node;
......@@ -14143,7 +14253,7 @@ patch_unaryop (tree node, tree wfl_op)
tree op = TREE_OPERAND (node, 0);
tree op_type = TREE_TYPE (op);
tree prom_type = NULL_TREE, value, decl;
int outer_field_flag = 0;
int nested_field_flag = 0;
int code = TREE_CODE (node);
int error_found = 0;
......@@ -14160,10 +14270,11 @@ patch_unaryop (tree node, tree wfl_op)
/* 15.14.2 Prefix Decrement Operator -- */
case PREDECREMENT_EXPR:
op = decl = extract_field_decl (op);
outer_field_flag = outer_field_expanded_access_p (op, NULL, NULL, NULL);
nested_field_flag
= nested_field_expanded_access_p (op, NULL, NULL, NULL);
/* We might be trying to change an outer field accessed using
access method. */
if (outer_field_flag)
if (nested_field_flag)
{
/* Retrieve the decl of the field we're trying to access. We
do that by first retrieving the function we would call to
......@@ -14217,15 +14328,15 @@ patch_unaryop (tree node, tree wfl_op)
}
/* We remember we might be accessing an outer field */
if (outer_field_flag)
if (nested_field_flag)
{
/* We re-generate an access to the field */
value = build2 (PLUS_EXPR, TREE_TYPE (op),
build_outer_field_access (wfl_op, decl), value);
build_nested_field_access (wfl_op, decl), value);
/* And we patch the original access$() into a write
with plus_op as a rhs */
return outer_field_access_fix (node, op, value);
return nested_field_access_fix (node, op, value);
}
/* And write back into the node. */
......@@ -15809,7 +15920,7 @@ check_thrown_exceptions (
int is_array_call = 0;
/* Skip check within generated methods, such as access$<n>. */
if (OUTER_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (current_function_decl)))
if (NESTED_FIELD_ACCESS_IDENTIFIER_P (DECL_NAME (current_function_decl)))
return;
if (this_expr != NULL_TREE
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment