aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRanjit Mathew <rmathew@gcc.gnu.org>2005-05-27 05:15:26 +0000
committerRanjit Mathew <rmathew@gcc.gnu.org>2005-05-27 05:15:26 +0000
commit38c9d142c841e105788c13daf64902c7156a0fb3 (patch)
treeb3937d50c473e4e969f8f4dfe85d2bed7c441069
parent27358466f931ecec6692d6d4267318ed1266d729 (diff)
downloadgcc-38c9d142c841e105788c13daf64902c7156a0fb3.zip
gcc-38c9d142c841e105788c13daf64902c7156a0fb3.tar.gz
gcc-38c9d142c841e105788c13daf64902c7156a0fb3.tar.bz2
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
-rw-r--r--gcc/java/ChangeLog44
-rw-r--r--gcc/java/java-tree.h20
-rw-r--r--gcc/java/jcf-write.c2
-rw-r--r--gcc/java/parse.y399
4 files changed, 309 insertions, 156 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 47b3ebe..e867f83 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,45 @@
+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. Löwis <loewis@informatik.hu-berlin.de>
+2000-03-19 Martin v. L�is <loewis@informatik.hu-berlin.de>
* except.c (emit_handlers): Clear catch_clauses_last.
diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h
index f919741..3799563 100644
--- a/gcc/java/java-tree.h
+++ b/gcc/java/java-tree.h
@@ -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.
diff --git a/gcc/java/jcf-write.c b/gcc/java/jcf-write.c
index 6f1516d..5deb5c8 100644
--- a/gcc/java/jcf-write.c
+++ b/gcc/java/jcf-write.c
@@ -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++;
diff --git a/gcc/java/parse.y b/gcc/java/parse.y
index 388062e..9067dfc1 100644
--- a/gcc/java/parse.y
+++ b/gcc/java/parse.y
@@ -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,114 +8287,159 @@ 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. */
+ needs to be generated, it always takes the form of a read. It might
+ 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. */
- access = build_access_to_thisn (current_class, decl_ctx, lc);
+ 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,
- name, access, NULL_TREE);
+ 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. */
+ 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);
+ 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))
- return 1;
+ if (type_root == decl_type)
+ return 1;
- if (!DECL_CONTEXT (TYPE_NAME (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)))
- return 1;
- break;
- }
+ /* 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))
+ {
+ 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;
+ }
+ }
+ 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. */
+ call if necessary. */
static int
-outer_field_expanded_access_p (tree node, tree *name, tree *arg_type,
- tree *arg)
+nested_field_expanded_access_p (tree node, tree *name, tree *arg_type,
+ tree *arg)
{
int identified = 0;
if (TREE_CODE (node) != CALL_EXPR)
return 0;
- /* Well, gcj generates slightly different tree nodes when compiling
- to native or bytecodes. It's the case for function calls. */
+ /* 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,26 +8461,37 @@ 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));
- *arg_type = TREE_TYPE (TREE_TYPE (TREE_VALUE (argument)));
- *arg = TREE_VALUE (argument);
+
+ /* 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
- be identified. */
+/* 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),
- arg_type, name, arg, rhs);
+ node = build_nested_field_access_expr (EXPR_WFL_LINECOL (wfl),
+ arg_type, name, arg, rhs);
return java_complete_tree (node);
}
return NULL_TREE;
@@ -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,
- tree arg1, tree arg2)
+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)
- args = tree_cons (NULL_TREE, arg2, args);
+ {
+ 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,63 +8552,89 @@ 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
- we're using for code generation. FIXME.
+ 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);
- /* Create the identifier and a function named after it. */
+ /* Create the identifier and a function named after it. */
id = build_new_access_id ();
/* 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;
+ access function for outer field accessed from inner classes. */
+ NESTED_FIELD_ACCESS_IDENTIFIER_P (id) = 1;
- /* Create the read access */
- 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);
+ /* 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),
- TREE_TYPE (decl), id, args, stmt);
+ 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 */
+ /* Create the write access method. No write access for final variable */
if (!FIELD_FINAL (decl))
{
- 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);
+ 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);
+ }
+ 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),
- TREE_TYPE (decl), id,
- args, stmt);
+ 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,
- tree args, tree body)
+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,18 +10084,29 @@ 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 (current_this)
- *where_found = current_this;
- else
- {
- static_ref_err (qual_wfl, DECL_NAME (decl),
- current_class);
- return 1;
- }
- if (outer_field_access_p (current_class, decl))
- decl = build_outer_field_access (qual_wfl, decl);
+ if (TREE_CODE (decl) == FIELD_DECL
+ && !FIELD_STATIC (decl))
+ {
+ if (current_this)
+ *where_found = current_this;
+ else
+ {
+ static_ref_err (qual_wfl, DECL_NAME (decl),
+ current_class);
+ return 1;
+ }
+ }
+ 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),
- TREE_OPERAND (node, 1))))
+ 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