diff options
author | Ranjit Mathew <rmathew@gcc.gnu.org> | 2005-05-27 05:15:26 +0000 |
---|---|---|
committer | Ranjit Mathew <rmathew@gcc.gnu.org> | 2005-05-27 05:15:26 +0000 |
commit | 38c9d142c841e105788c13daf64902c7156a0fb3 (patch) | |
tree | b3937d50c473e4e969f8f4dfe85d2bed7c441069 | |
parent | 27358466f931ecec6692d6d4267318ed1266d729 (diff) | |
download | gcc-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/ChangeLog | 44 | ||||
-rw-r--r-- | gcc/java/java-tree.h | 20 | ||||
-rw-r--r-- | gcc/java/jcf-write.c | 2 | ||||
-rw-r--r-- | gcc/java/parse.y | 399 |
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 |