This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch] Java PR 12734
- From: Ralph Loader <rcl at ihug dot co dot nz>
- To: java-patches at gcc dot gnu dot org, gcc-patches at gcc dot gnu dot org
- Date: Fri, 17 Oct 2003 10:53:37 +1300
- Subject: [Patch] Java PR 12734
Previous version posted a couple of weeks ago, before I had CVS access.
Ok to commit now? Still passes make bootstrap;cd libjava;make check.
Ralph.
2003-10-17 Ralph Loader <rcl@ihug.co.nz>
PR java/12734:
* parse.y (qualify_ambiguous_name): Remove lots of broken
field access processing - there's no need to do that here,
because we have resolve_field_access. Remove
RESOLVE_EXPRESSION_NAME_P as it isn't used anywhere else.
* java-tree.h: Remove RESOLVE_EXPRESSION_NAME_P as it isn't
used.
2003-10-17 Ralph Loader <rcl@ihug.co.nz>
* libjava/testsuite/libjava.compile/PR12734.java: New file.
* libjava/testsuite/libjava.compile/PR12734_B.java: New file.
Index: gcc/java/java-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/java-tree.h,v
retrieving revision 1.185
diff -u -u -r1.185 java-tree.h
--- gcc/java/java-tree.h 1 Oct 2003 16:22:11 -0000 1.185
+++ gcc/java/java-tree.h 16 Oct 2003 21:37:34 -0000
@@ -44,7 +44,6 @@
/* Usage of TREE_LANG_FLAG_?:
0: IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P (in IDENTIFIER_NODE)
- RESOLVE_EXPRESSION_NAME_P (in EXPR_WITH_FILE_LOCATION)
FOR_LOOP_P (in LOOP_EXPR)
SUPPRESS_UNREACHABLE_ERROR (for other _EXPR nodes)
ANONYMOUS_CLASS_P (in RECORD_TYPE)
@@ -1544,9 +1543,6 @@
/* True if TYPE (a TREE_TYPE denoting a class type) was found to
feature a finalizer method. */
#define HAS_FINALIZER_P(EXPR) TREE_LANG_FLAG_3 (EXPR)
-
-/* True if EXPR (a WFL in that case) resolves into an expression name */
-#define RESOLVE_EXPRESSION_NAME_P(WFL) TREE_LANG_FLAG_0 (WFL)
/* True if EXPR (a LOOP_EXPR in that case) is part of a for statement */
#define FOR_LOOP_P(EXPR) TREE_LANG_FLAG_0 (EXPR)
Index: gcc/java/parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.449
diff -u -u -r1.449 parse.y
--- gcc/java/parse.y 9 Oct 2003 05:44:57 -0000 1.449
+++ gcc/java/parse.y 16 Oct 2003 21:38:12 -0000
@@ -9796,7 +9796,6 @@
list = TREE_CHAIN (q);
while (list)
{
- RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (list)) = 1;
RESOLVE_PACKAGE_NAME_P (QUAL_WFL (list)) = 0;
list = TREE_CHAIN (list);
}
@@ -11274,211 +11273,58 @@
/* Qualification routines */
+/* Given a name x.y.z, look up x locally. If it's found, save the
+ decl. If it's not found, mark the name as RESOLVE_PACKAGE_NAME_P,
+ so that we later try and load the appropriate classes. */
static void
qualify_ambiguous_name (tree id)
{
- tree qual, qual_wfl, name = NULL_TREE, decl, ptr_type = NULL_TREE,
- saved_current_class;
- int again, super_found = 0, this_found = 0, new_array_found = 0;
- int code;
-
- /* We first qualify the first element, then derive qualification of
- others based on the first one. If the first element is qualified
- by a resolution (field or type), this resolution is stored in the
- QUAL_RESOLUTION of the qual element being examined. We need to
- save the current_class since the use of SUPER might change the
- its value. */
- saved_current_class = current_class;
- qual = EXPR_WFL_QUALIFICATION (id);
- do {
-
- /* Simple qualified expression feature a qual_wfl that is a
- WFL. Expression derived from a primary feature more complicated
- things like a CALL_EXPR. Expression from primary need to be
- worked out to extract the part on which the qualification will
- take place. */
- qual_wfl = QUAL_WFL (qual);
- switch (TREE_CODE (qual_wfl))
- {
- case CALL_EXPR:
- qual_wfl = TREE_OPERAND (qual_wfl, 0);
- if (TREE_CODE (qual_wfl) != EXPR_WITH_FILE_LOCATION
- || (EXPR_WFL_QUALIFICATION (qual_wfl)
- && TREE_CODE (EXPR_WFL_QUALIFICATION (qual_wfl)) == TREE_LIST))
- {
- qual = EXPR_WFL_QUALIFICATION (qual_wfl);
- qual_wfl = QUAL_WFL (qual);
- }
- break;
- case NEW_ARRAY_EXPR:
- case NEW_ANONYMOUS_ARRAY_EXPR:
- qual = TREE_CHAIN (qual);
- again = new_array_found = 1;
- continue;
- case CONVERT_EXPR:
- break;
- case NEW_CLASS_EXPR:
- 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;
- case STRING_CST:
- qual = TREE_CHAIN (qual);
- qual_wfl = QUAL_WFL (qual);
- break;
- case CLASS_LITERAL:
- qual = TREE_CHAIN (qual);
- qual_wfl = QUAL_WFL (qual);
- break;
- default:
- /* Fix for -Wall. Just break doing nothing */
- break;
- }
+ tree name, decl;
- ptr_type = current_class;
- again = 0;
- code = TREE_CODE (qual_wfl);
-
- /* Pos evaluation: non WFL leading expression nodes */
- if (code == CONVERT_EXPR
- && TREE_CODE (TREE_TYPE (qual_wfl)) == EXPR_WITH_FILE_LOCATION)
- name = EXPR_WFL_NODE (TREE_TYPE (qual_wfl));
-
- else if (code == INTEGER_CST)
- name = qual_wfl;
-
- else if (code == CONVERT_EXPR &&
- TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == EXPR_WITH_FILE_LOCATION)
- name = TREE_OPERAND (qual_wfl, 0);
-
- else if (code == CONVERT_EXPR
- && TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == CALL_EXPR
- && (TREE_CODE (TREE_OPERAND (TREE_OPERAND (qual_wfl, 0), 0))
- == EXPR_WITH_FILE_LOCATION))
- name = TREE_OPERAND (TREE_OPERAND (qual_wfl, 0), 0);
-
- else if ((code == ARRAY_REF || code == CALL_EXPR || code == MODIFY_EXPR) &&
- TREE_CODE (TREE_OPERAND (qual_wfl, 0)) == EXPR_WITH_FILE_LOCATION)
- name = EXPR_WFL_NODE (TREE_OPERAND (qual_wfl, 0));
+ /* We inspect the first item of the qualification list. As a sanity
+ check, make sure that it is an identfier node. */
+ tree qual = EXPR_WFL_QUALIFICATION (id);
+ tree qual_wfl = QUAL_WFL (qual);
- else if (code == TREE_LIST)
- name = EXPR_WFL_NODE (TREE_PURPOSE (qual_wfl));
+ if (TREE_CODE (qual_wfl) != EXPR_WITH_FILE_LOCATION)
+ return;
- else if (code == STRING_CST || code == CONDITIONAL_EXPR
- || code == PLUS_EXPR)
- {
- qual = TREE_CHAIN (qual);
- qual_wfl = QUAL_WFL (qual);
- again = 1;
- }
- else
- {
- name = EXPR_WFL_NODE (qual_wfl);
- if (!name)
- {
- qual = EXPR_WFL_QUALIFICATION (qual_wfl);
- again = 1;
- }
- }
+ name = EXPR_WFL_NODE (qual_wfl);
- /* If we have a THIS (from a primary), we set the context accordingly */
- if (name == this_identifier_node)
- {
- /* This isn't really elegant. One more added irregularity
- before I start using COMPONENT_REF (hopefully very soon.) */
- if (TREE_CODE (TREE_PURPOSE (qual)) == ARRAY_REF
- && TREE_CODE (TREE_OPERAND (TREE_PURPOSE (qual), 0)) ==
- EXPR_WITH_FILE_LOCATION
- && EXPR_WFL_NODE (TREE_OPERAND (TREE_PURPOSE (qual), 0)) ==
- this_identifier_node)
- {
- qual = TREE_OPERAND (TREE_PURPOSE (qual), 0);
- qual = EXPR_WFL_QUALIFICATION (qual);
- }
- qual = TREE_CHAIN (qual);
- qual_wfl = QUAL_WFL (qual);
- if (TREE_CODE (qual_wfl) == CALL_EXPR)
- again = 1;
- else if (TREE_CODE (qual_wfl) == EXPR_WITH_FILE_LOCATION)
- name = EXPR_WFL_NODE (qual_wfl);
- else if (TREE_CODE (qual_wfl) == NEW_CLASS_EXPR)
- name = TREE_OPERAND (qual_wfl, 0);
- this_found = 1;
- }
- /* If we have a SUPER, we set the context accordingly */
- if (name == super_identifier_node)
- {
- current_class = CLASSTYPE_SUPER (ptr_type);
- /* Check that there is such a thing as a super class. If not,
- return. The error will be caught later on, during the
- resolution */
- if (!current_class)
- {
- current_class = saved_current_class;
- return;
- }
- qual = TREE_CHAIN (qual);
- /* Do one more interation to set things up */
- super_found = again = 1;
- }
- } while (again);
+ /* If we don't have an identifier, or we have a 'this' or 'super',
+ then field access processing is all we need : there is nothing
+ for us to do. */
+ if (!name || TREE_CODE (name) != IDENTIFIER_NODE ||
+ name == this_identifier_node ||
+ name == super_identifier_node)
+ return;
/* If name appears within the scope of a local variable declaration
- or parameter declaration, then it is an expression name. We don't
- carry this test out if we're in the context of the use of SUPER
- or THIS */
- if (!this_found && !super_found
- && TREE_CODE (name) != STRING_CST && TREE_CODE (name) != INTEGER_CST
- && (decl = IDENTIFIER_LOCAL_VALUE (name)))
+ or parameter declaration, or is a field within an enclosing
+ class, then it is an expression name. Save the decl and let
+ resolve_field_access do it's work. */
+ if ((decl = IDENTIFIER_LOCAL_VALUE (name)) ||
+ (decl = lookup_field_wrapper (current_class, name)))
{
- RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
QUAL_RESOLUTION (qual) = decl;
+ return;
}
- /* If within the class/interface NAME was found to be used there
- exists a (possibly inherited) field named NAME, then this is an
- expression name. If we saw a NEW_ARRAY_EXPR before and want to
- address length, it is OK. */
- else if ((decl = lookup_field_wrapper (ptr_type, name))
- || name == length_identifier_node)
- {
- RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
- QUAL_RESOLUTION (qual) = (new_array_found ? NULL_TREE : decl);
- }
-
- /* We reclassify NAME as yielding to a type name resolution if:
- - NAME is a class/interface declared within the compilation
- unit containing NAME,
- - NAME is imported via a single-type-import declaration,
- - NAME is declared in an another compilation unit of the package
- of the compilation unit containing NAME,
- - NAME is declared by exactly on type-import-on-demand declaration
- of the compilation unit containing NAME.
- - NAME is actually a STRING_CST.
- This can't happen if the expression was qualified by `this.' */
- else if (! this_found &&
- (TREE_CODE (name) == STRING_CST ||
- TREE_CODE (name) == INTEGER_CST ||
- (decl = resolve_and_layout (name, NULL_TREE))))
+ /* If name is a known class name (either declared or imported), mark
+ us as a type name. */
+ if ((decl = resolve_and_layout (name, NULL_TREE)))
{
RESOLVE_TYPE_NAME_P (qual_wfl) = 1;
QUAL_RESOLUTION (qual) = decl;
}
- /* Method call, array references and cast are expression name */
- else if (TREE_CODE (QUAL_WFL (qual)) == CALL_EXPR
- || TREE_CODE (QUAL_WFL (qual)) == ARRAY_REF
- || TREE_CODE (QUAL_WFL (qual)) == CONVERT_EXPR
- || TREE_CODE (QUAL_WFL (qual)) == MODIFY_EXPR)
- RESOLVE_EXPRESSION_NAME_P (qual_wfl) = 1;
-
/* Check here that NAME isn't declared by more than one
type-import-on-demand declaration of the compilation unit
containing NAME. FIXME */
- /* Otherwise, NAME is reclassified as a package name */
+ /* We couldn't find a declaration for the name. Assume for now that
+ we have a qualified class name that needs to be loaded from an
+ external class file. */
else
RESOLVE_PACKAGE_NAME_P (qual_wfl) = 1;
@@ -11489,21 +11335,14 @@
{
if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
RESOLVE_PACKAGE_NAME_P (QUAL_WFL (qual)) = 1;
- else
- RESOLVE_EXPRESSION_NAME_P (QUAL_WFL (qual)) = 1;
}
/* Store the global qualification for the ambiguous part of ID back
into ID fields */
- if (RESOLVE_EXPRESSION_NAME_P (qual_wfl))
- RESOLVE_EXPRESSION_NAME_P (id) = 1;
- else if (RESOLVE_TYPE_NAME_P (qual_wfl))
+ if (RESOLVE_TYPE_NAME_P (qual_wfl))
RESOLVE_TYPE_NAME_P (id) = 1;
else if (RESOLVE_PACKAGE_NAME_P (qual_wfl))
RESOLVE_PACKAGE_NAME_P (id) = 1;
-
- /* Restore the current class */
- current_class = saved_current_class;
}
static int
--- /dev/null 2003-09-16 01:40:47.000000000 +1200
+++ libjava/testsuite/libjava.compile/PR12734.java 2003-09-29 13:31:58.000000000 +1200
@@ -0,0 +1,7 @@
+class PR12734 {
+ Object Foo()
+ {
+ return "".CASE_INSENSITIVE_ORDER;
+ }
+}
+
--- /dev/null 2003-09-16 01:40:47.000000000 +1200
+++ libjava/testsuite/libjava.compile/PR12734_B.java 2003-10-01 07:47:50.000000000 +1200
@@ -0,0 +1,15 @@
+/* Special casing access to array.length while analysing syntax is
+ evil. Especially when it means we can't cope with a type called
+ length. */
+class PR12734_B
+{
+ class length
+ {
+ static final int i = 2;
+ }
+
+ int foo()
+ {
+ return length.i;
+ }
+}