aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2002-06-02 16:33:01 +0000
committerTom Tromey <tromey@gcc.gnu.org>2002-06-02 16:33:01 +0000
commit48711f4da92595d5809dad475015809f2308ca71 (patch)
tree8c0c8a5d9b246c0fa0f8e47df39cf81f89cd6df3 /gcc
parente403d80d357106f3a0b12a290e812e9a6305c1ee (diff)
downloadgcc-48711f4da92595d5809dad475015809f2308ca71.zip
gcc-48711f4da92595d5809dad475015809f2308ca71.tar.gz
gcc-48711f4da92595d5809dad475015809f2308ca71.tar.bz2
Fix for PR java/1343, PR java/6336:
* parse.y (make_nested_class_name): Remove extraneous `else'; fix formatting. Changed return type. (anonymous_class_counter): Moved to top of file. (maybe_make_nested_class_name): Append number to class name for function-local classes. From-SVN: r54173
Diffstat (limited to 'gcc')
-rw-r--r--gcc/java/ChangeLog9
-rw-r--r--gcc/java/parse-scan.y187
-rw-r--r--gcc/java/parse.y41
3 files changed, 166 insertions, 71 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 3b630d3..1ddef43 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,12 @@
+2002-06-02 Tom Tromey <tromey@redhat.com>
+
+ Fix for PR java/1343, PR java/6336:
+ * parse.y (make_nested_class_name): Remove extraneous `else'; fix
+ formatting. Changed return type.
+ (anonymous_class_counter): Moved to top of file.
+ (maybe_make_nested_class_name): Append number to class name for
+ function-local classes.
+
2002-05-28 Zack Weinberg <zack@codesourcery.com>
* decl.c, jcf-parse.c, parse.y, typeck.c: Include real.h.
diff --git a/gcc/java/parse-scan.y b/gcc/java/parse-scan.y
index 28d7946..665a7f7 100644
--- a/gcc/java/parse-scan.y
+++ b/gcc/java/parse-scan.y
@@ -1,5 +1,5 @@
/* Parser grammar for quick source code scan of Java(TM) language programs.
- Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
This file is part of GNU CC.
@@ -43,6 +43,9 @@ definitions and other extensions. */
#include "obstack.h"
#include "toplev.h"
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free free
+
extern char *input_filename;
extern FILE *finput, *out;
@@ -62,13 +65,9 @@ int lineno;
static int absorber;
#define USE_ABSORBER absorber = 0
-/* Keep track of the current class name and package name. */
-static char *current_class;
+/* Keep track of the current package name. */
static const char *package_name;
-/* Keep track of the current inner class qualifier. */
-static int current_class_length;
-
/* Keep track of whether things have be listed before. */
static int previous_output;
@@ -85,6 +84,22 @@ static int bracket_count;
/* Numbers anonymous classes */
static int anonymous_count;
+/* This is used to record the current class context. */
+struct class_context
+{
+ char *name;
+ struct class_context *next;
+};
+
+/* The global class context. */
+static struct class_context *current_class_context;
+
+/* A special constant used to represent an anonymous context. */
+static const char *anonymous_context = "ANONYMOUS";
+
+/* Count of method depth. */
+static int method_depth;
+
/* Record a method declaration */
struct method_declarator {
const char *method_name;
@@ -99,6 +114,9 @@ struct method_declarator {
}
/* Two actions for this grammar */
+static int make_class_name_recursive PARAMS ((struct obstack *stack,
+ struct class_context *ctx));
+static char *get_class_name PARAMS ((void));
static void report_class_declaration PARAMS ((const char *));
static void report_main_declaration PARAMS ((struct method_declarator *));
static void push_class_context PARAMS ((const char *));
@@ -430,7 +448,10 @@ variable_initializer:
/* 19.8.3 Productions from 8.4: Method Declarations */
method_declaration:
- method_header method_body
+ method_header
+ { ++method_depth; }
+ method_body
+ { --method_depth; }
;
method_header:
@@ -923,10 +944,10 @@ class_instance_creation_expression:
anonymous_class_creation:
NEW_TK class_type OP_TK CP_TK
- { report_class_declaration (NULL); }
+ { report_class_declaration (anonymous_context); }
class_body
| NEW_TK class_type OP_TK argument_list CP_TK
- { report_class_declaration (NULL); }
+ { report_class_declaration (anonymous_context); }
class_body
;
@@ -1155,58 +1176,100 @@ static void
push_class_context (name)
const char *name;
{
- /* If we already have CURRENT_CLASS set, we're in an inter
- class. Mangle its name. */
- if (current_class)
- {
- const char *p;
- char anonymous [3];
- int additional_length;
-
- /* NAME set to NULL indicates an anonymous class, which are named by
- numbering them. */
- if (!name)
- {
- sprintf (anonymous, "%d", ++anonymous_count);
- p = anonymous;
- }
- else
- p = name;
-
- additional_length = strlen (p)+1; /* +1 for `$' */
- current_class = xrealloc (current_class,
- current_class_length + additional_length + 1);
- current_class [current_class_length] = '$';
- strcpy (&current_class [current_class_length+1], p);
- current_class_length += additional_length;
- }
- else
- {
- if (!name)
- return;
- current_class_length = strlen (name);
- current_class = xmalloc (current_class_length+1);
- strcpy (current_class, name);
- }
+ struct class_context *ctx;
+
+ ctx = (struct class_context *) xmalloc (sizeof (struct class_context));
+ ctx->name = (char *) name;
+ ctx->next = current_class_context;
+ current_class_context = ctx;
}
static void
pop_class_context ()
{
- /* Go back to the last `$' and cut. */
- while (--current_class_length > 0
- && current_class [current_class_length] != '$')
- ;
- if (current_class_length)
+ struct class_context *ctx;
+
+ if (current_class_context == NULL)
+ return;
+
+ ctx = current_class_context->next;
+ if (current_class_context->name != anonymous_context)
+ free (current_class_context->name);
+ free (current_class_context);
+
+ current_class_context = ctx;
+ if (current_class_context == NULL)
+ anonymous_count = 0;
+}
+
+/* Recursively construct the class name. This is just a helper
+ function for get_class_name(). */
+static int
+make_class_name_recursive (stack, ctx)
+ struct obstack *stack;
+ struct class_context *ctx;
+{
+ if (! ctx)
+ return 0;
+
+ make_class_name_recursive (stack, ctx->next);
+
+ /* Replace an anonymous context with the appropriate counter value. */
+ if (ctx->name == anonymous_context)
{
- current_class = xrealloc (current_class, current_class_length+1);
- current_class [current_class_length] = '\0';
+ char buf[50];
+ ++anonymous_count;
+ sprintf (buf, "%d", anonymous_count);
+ ctx->name = xstrdup (buf);
}
- else
+
+ obstack_grow (stack, ctx->name, strlen (ctx->name));
+ obstack_1grow (stack, '$');
+
+ return ISDIGIT (ctx->name[0]);
+}
+
+/* Return a newly allocated string holding the name of the class. */
+static char *
+get_class_name ()
+{
+ char *result;
+ int last_was_digit;
+ struct obstack name_stack;
+
+ obstack_init (&name_stack);
+
+ /* Duplicate the logic of parse.y:maybe_make_nested_class_name(). */
+ last_was_digit = make_class_name_recursive (&name_stack,
+ current_class_context->next);
+
+ if (! last_was_digit
+ && method_depth
+ && current_class_context->name != anonymous_context)
{
- current_class = NULL;
- anonymous_count = 0;
+ char buf[50];
+ ++anonymous_count;
+ sprintf (buf, "%d", anonymous_count);
+ obstack_grow (&name_stack, buf, strlen (buf));
+ obstack_1grow (&name_stack, '$');
}
+
+ if (current_class_context->name == anonymous_context)
+ {
+ char buf[50];
+ ++anonymous_count;
+ sprintf (buf, "%d", anonymous_count);
+ current_class_context->name = xstrdup (buf);
+ obstack_grow0 (&name_stack, buf, strlen (buf));
+ }
+ else
+ obstack_grow0 (&name_stack, current_class_context->name,
+ strlen (current_class_context->name));
+
+ result = xstrdup (obstack_finish (&name_stack));
+ obstack_free (&name_stack, NULL);
+
+ return result;
}
/* Actions defined here */
@@ -1220,17 +1283,21 @@ report_class_declaration (name)
push_class_context (name);
if (flag_dump_class)
{
+ char *name = get_class_name ();
+
if (!previous_output)
{
if (flag_list_filename)
fprintf (out, "%s: ", input_filename);
previous_output = 1;
}
-
+
if (package_name)
- fprintf (out, "%s.%s ", package_name, current_class);
+ fprintf (out, "%s.%s ", package_name, name);
else
- fprintf (out, "%s ", current_class);
+ fprintf (out, "%s ", name);
+
+ free (name);
}
}
@@ -1247,14 +1314,16 @@ report_main_declaration (declarator)
&& declarator->args [0] == '['
&& (! strcmp (declarator->args+1, "String")
|| ! strcmp (declarator->args + 1, "java.lang.String"))
- && current_class)
+ && current_class_context)
{
if (!previous_output)
{
+ char *name = get_class_name ();
if (package_name)
- fprintf (out, "%s.%s ", package_name, current_class);
+ fprintf (out, "%s.%s ", package_name, name);
else
- fprintf (out, "%s", current_class);
+ fprintf (out, "%s", name);
+ free (name);
previous_output = 1;
}
}
@@ -1274,7 +1343,7 @@ void reset_report ()
{
previous_output = 0;
package_name = NULL;
- current_class = NULL;
+ current_class_context = NULL;
complexity = 0;
}
diff --git a/gcc/java/parse.y b/gcc/java/parse.y
index cccb8d7..742cc6f 100644
--- a/gcc/java/parse.y
+++ b/gcc/java/parse.y
@@ -295,7 +295,7 @@ static int pop_current_osb PARAMS ((struct parser_ctxt *));
/* JDK 1.1 work. FIXME */
static tree maybe_make_nested_class_name PARAMS ((tree));
-static void make_nested_class_name PARAMS ((tree));
+static int make_nested_class_name PARAMS ((tree));
static void set_nested_class_simple_name_value PARAMS ((tree, int));
static void link_nested_class_to_enclosing PARAMS ((void));
static tree resolve_inner_class PARAMS ((struct hash_table *, tree, tree *,
@@ -423,6 +423,10 @@ static tree currently_caught_type_list;
`ctxp->current_loop'. */
static tree case_label_list;
+/* Anonymous class counter. Will be reset to 1 every time a non
+ anonymous class gets created. */
+static int anonymous_class_counter = 1;
+
static tree src_parse_roots[1];
/* All classes seen from source code */
@@ -3497,24 +3501,28 @@ check_class_interface_creation (is_interface, flags, raw_name, qualified_name, d
return 0;
}
-static void
+/* Construct a nested class name. If the final component starts with
+ a digit, return true. Otherwise return false. */
+static int
make_nested_class_name (cpc_list)
tree cpc_list;
{
tree name;
if (!cpc_list)
- return;
- else
- make_nested_class_name (TREE_CHAIN (cpc_list));
+ return 0;
+
+ make_nested_class_name (TREE_CHAIN (cpc_list));
/* Pick the qualified name when dealing with the first upmost
enclosing class */
- name = (TREE_CHAIN (cpc_list) ?
- TREE_PURPOSE (cpc_list) : DECL_NAME (TREE_VALUE (cpc_list)));
+ name = (TREE_CHAIN (cpc_list)
+ ? TREE_PURPOSE (cpc_list) : DECL_NAME (TREE_VALUE (cpc_list)));
obstack_grow (&temporary_obstack,
IDENTIFIER_POINTER (name), IDENTIFIER_LENGTH (name));
obstack_1grow (&temporary_obstack, '$');
+
+ return ISDIGIT (IDENTIFIER_POINTER (name)[0]);
}
/* Can't redefine a class already defined in an earlier scope. */
@@ -3723,7 +3731,20 @@ maybe_make_nested_class_name (name)
if (CPC_INNER_P ())
{
- make_nested_class_name (GET_CPC_LIST ());
+ /* If we're in a function, we must append a number to create the
+ nested class name. However, we don't do this if the class we
+ are constructing is anonymous, because in that case we'll
+ already have a number as the class name. */
+ if (! make_nested_class_name (GET_CPC_LIST ())
+ && current_function_decl != NULL_TREE
+ && ! ISDIGIT (IDENTIFIER_POINTER (name)[0]))
+ {
+ char buf[10];
+ sprintf (buf, "%d", anonymous_class_counter);
+ ++anonymous_class_counter;
+ obstack_grow (&temporary_obstack, buf, strlen (buf));
+ obstack_1grow (&temporary_obstack, '$');
+ }
obstack_grow0 (&temporary_obstack,
IDENTIFIER_POINTER (name),
IDENTIFIER_LENGTH (name));
@@ -3863,10 +3884,6 @@ create_interface (flags, id, super)
return decl;
}
-/* Anonymous class counter. Will be reset to 1 every time a non
- anonymous class gets created. */
-static int anonymous_class_counter = 1;
-
/* Patch anonymous class CLASS, by either extending or implementing
DEP. */