1 /* Parser grammar for quick source code scan of Java(TM) language programs.
2 Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
3 Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
22 Java and all Java-based marks are trademarks or registered trademarks
23 of Sun Microsystems, Inc. in the United States and other countries.
24 The Free Software Foundation is independent of Sun Microsystems, Inc. */
26 /* This file parses Java source code. Action can be further completed
27 to achieve a desired behavior. This file isn't part of the Java
28 language gcc front end.
30 The grammar conforms to the Java grammar described in "The Java(TM)
31 Language Specification. J. Gosling, B. Joy, G. Steele. Addison Wesley
32 1996, ISBN 0-201-63451-1"
34 Some rules have been modified to support JDK1.1 inner classes
35 definitions and other extensions. */
46 #define obstack_chunk_alloc xmalloc
47 #define obstack_chunk_free free
49 extern char *input_filename;
50 extern FILE *finput, *out;
52 /* Obstack for the lexer. */
53 struct obstack temporary_obstack;
55 /* The current parser context. */
56 static struct parser_ctxt *ctxp;
58 /* Error and warning counts, current line number, because they're used
61 int java_warning_count;
64 /* Tweak default rules when necessary. */
66 #define USE_ABSORBER absorber = 0
68 /* Keep track of the current package name. */
69 static const char *package_name;
71 /* Keep track of whether things have be listed before. */
72 static int previous_output;
74 /* Record modifier uses */
75 static int modifier_value;
77 /* Record (almost) cyclomatic complexity. */
78 static int complexity;
80 /* Keeps track of number of bracket pairs after a variable declarator
82 static int bracket_count;
84 /* Numbers anonymous classes */
85 static int anonymous_count;
87 /* This is used to record the current class context. */
91 struct class_context *next;
94 /* The global class context. */
95 static struct class_context *current_class_context;
97 /* A special constant used to represent an anonymous context. */
98 static const char *anonymous_context = "ANONYMOUS";
100 /* Count of method depth. */
101 static int method_depth;
103 /* Record a method declaration */
104 struct method_declarator {
105 const char *method_name;
108 #define NEW_METHOD_DECLARATOR(D,N,A) \
111 (struct method_declarator *)xmalloc (sizeof (struct method_declarator)); \
112 (D)->method_name = (N); \
116 /* Two actions for this grammar */
117 static int make_class_name_recursive PARAMS ((struct obstack *stack,
118 struct class_context *ctx));
119 static char *get_class_name PARAMS ((void));
120 static void report_class_declaration PARAMS ((const char *));
121 static void report_main_declaration PARAMS ((struct method_declarator *));
122 static void push_class_context PARAMS ((const char *));
123 static void pop_class_context PARAMS ((void));
125 void report PARAMS ((void));
133 struct method_declarator *declarator;
134 int value; /* For modifiers */
143 /* Things defined here have to match the order of what's in the
144 binop_lookup table. */
146 %token PLUS_TK MINUS_TK MULT_TK DIV_TK REM_TK
147 %token LS_TK SRS_TK ZRS_TK
148 %token AND_TK XOR_TK OR_TK
149 %token BOOL_AND_TK BOOL_OR_TK
150 %token EQ_TK NEQ_TK GT_TK GTE_TK LT_TK LTE_TK
152 /* This maps to the same binop_lookup entry than the token above */
154 %token PLUS_ASSIGN_TK MINUS_ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
156 %token LS_ASSIGN_TK SRS_ASSIGN_TK ZRS_ASSIGN_TK
157 %token AND_ASSIGN_TK XOR_ASSIGN_TK OR_ASSIGN_TK
160 /* Modifier TOKEN have to be kept in this order. Don't scramble it */
162 %token PUBLIC_TK PRIVATE_TK PROTECTED_TK
163 %token STATIC_TK FINAL_TK SYNCHRONIZED_TK
164 %token VOLATILE_TK TRANSIENT_TK NATIVE_TK
165 %token PAD_TK ABSTRACT_TK MODIFIER_TK
168 /* Keep those two in order, too */
169 %token DECR_TK INCR_TK
171 /* From now one, things can be in any order */
173 %token DEFAULT_TK IF_TK THROW_TK
174 %token BOOLEAN_TK DO_TK IMPLEMENTS_TK
175 %token THROWS_TK BREAK_TK IMPORT_TK
176 %token ELSE_TK INSTANCEOF_TK RETURN_TK
177 %token VOID_TK CATCH_TK INTERFACE_TK
178 %token CASE_TK EXTENDS_TK FINALLY_TK
179 %token SUPER_TK WHILE_TK CLASS_TK
180 %token SWITCH_TK CONST_TK TRY_TK
181 %token FOR_TK NEW_TK CONTINUE_TK
182 %token GOTO_TK PACKAGE_TK THIS_TK
184 %token BYTE_TK SHORT_TK INT_TK LONG_TK
185 %token CHAR_TK INTEGRAL_TK
187 %token FLOAT_TK DOUBLE_TK FP_TK
191 %token REL_QM_TK REL_CL_TK NOT_TK NEG_TK
193 %token ASSIGN_ANY_TK ASSIGN_TK
194 %token OP_TK CP_TK OCB_TK CCB_TK OSB_TK CSB_TK SC_TK C_TK DOT_TK
196 %token STRING_LIT_TK CHAR_LIT_TK INT_LIT_TK FP_LIT_TK
197 %token TRUE_TK FALSE_TK BOOL_LIT_TK NULL_TK
199 %type <node> ID_TK identifier name simple_name qualified_name type
200 primitive_type reference_type array_type formal_parameter_list
201 formal_parameter class_or_interface_type class_type interface_type
202 %type <declarator> method_declarator
203 %type <value> MODIFIER_TK
206 /* 19.2 Production from 2.3: The Syntactic Grammar */
211 /* 19.3 Productions from 3: Lexical structure */
221 /* 19.4 Productions from 4: Types, Values and Variables */
230 /* use preset global here. FIXME */
231 $$ = xstrdup ("int");
235 /* use preset global here. FIXME */
236 $$ = xstrdup ("double");
240 /* use preset global here. FIXME */
241 $$ = xstrdup ("boolean");
246 class_or_interface_type
250 class_or_interface_type:
255 class_or_interface_type /* Default rule */
259 class_or_interface_type
265 while (bracket_count-- > 0)
266 $$ = concat ("[", $1, NULL);
270 while (bracket_count-- > 0)
271 $$ = concat ("[", $1, NULL);
275 /* 19.5 Productions from 6: Names */
277 simple_name /* Default rule */
278 | qualified_name /* Default rule */
282 identifier /* Default rule */
286 name DOT_TK identifier
288 $$ = concat ($1, ".", $3, NULL);
296 /* 19.6: Production from 7: Packages */
298 | package_declaration
299 | import_declarations
301 | package_declaration import_declarations
302 | package_declaration type_declarations
303 | import_declarations type_declarations
304 | package_declaration import_declarations type_declarations
309 | import_declarations import_declaration
314 | type_declarations type_declaration
318 PACKAGE_TK name SC_TK
319 { package_name = $2; }
323 single_type_import_declaration
324 | type_import_on_demand_declaration
327 single_type_import_declaration:
331 type_import_on_demand_declaration:
332 IMPORT_TK name DOT_TK MULT_TK SC_TK
337 | interface_declaration
341 /* 19.7 Shortened from the original:
342 modifiers: modifier | modifiers modifier
343 modifier: any of public... */
353 | modifiers MODIFIER_TK
363 /* 19.8.1 Production from $8.1: Class Declaration */
365 modifiers CLASS_TK identifier super interfaces
367 report_class_declaration($3);
371 | CLASS_TK identifier super interfaces
372 { report_class_declaration($2); }
377 | EXTENDS_TK class_type
381 | IMPLEMENTS_TK interface_type_list
387 | interface_type_list C_TK interface_type
393 { pop_class_context (); }
394 | OCB_TK class_body_declarations CCB_TK
395 { pop_class_context (); }
398 class_body_declarations:
399 class_body_declaration
400 | class_body_declarations class_body_declaration
403 class_body_declaration:
404 class_member_declaration
406 | constructor_declaration
407 | block /* Added, JDK1.1, instance initializer */
410 class_member_declaration:
413 | class_declaration /* Added, JDK1.1 inner classes */
414 | interface_declaration /* Added, JDK1.1 inner classes */
418 /* 19.8.2 Productions from 8.3: Field Declarations */
420 type variable_declarators SC_TK
422 | modifiers type variable_declarators SC_TK
423 { modifier_value = 0; }
426 variable_declarators:
427 /* Should we use build_decl_list () instead ? FIXME */
428 variable_declarator /* Default rule */
429 | variable_declarators C_TK variable_declarator
433 variable_declarator_id
434 | variable_declarator_id ASSIGN_TK variable_initializer
437 variable_declarator_id:
439 { bracket_count = 0; USE_ABSORBER; }
440 | variable_declarator_id OSB_TK CSB_TK
444 variable_initializer:
449 /* 19.8.3 Productions from 8.4: Method Declarations */
458 type method_declarator throws
460 | VOID_TK method_declarator throws
461 | modifiers type method_declarator throws
462 { modifier_value = 0; }
463 | modifiers VOID_TK method_declarator throws
465 report_main_declaration ($3);
471 identifier OP_TK CP_TK
473 struct method_declarator *d;
474 NEW_METHOD_DECLARATOR (d, $1, NULL);
477 | identifier OP_TK formal_parameter_list CP_TK
479 struct method_declarator *d;
480 NEW_METHOD_DECLARATOR (d, $1, $3);
483 | method_declarator OSB_TK CSB_TK
486 formal_parameter_list:
488 | formal_parameter_list C_TK formal_parameter
490 $$ = concat ($1, ",", $3, NULL);
495 type variable_declarator_id
501 char *n = xmalloc (bracket_count + 1 + strlen ($$));
502 for (i = 0; i < bracket_count; ++i)
504 strcpy (n + bracket_count, $$);
510 | modifiers type variable_declarator_id /* Added, JDK1.1 final locals */
515 char *n = xmalloc (bracket_count + 1 + strlen ($$));
516 for (i = 0; i < bracket_count; ++i)
518 strcpy (n + bracket_count, $$);
527 | THROWS_TK class_type_list
533 | class_type_list C_TK class_type
542 /* 19.8.4 Productions from 8.5: Static Initializers */
547 static: /* Test lval.sub_token here */
552 /* 19.8.5 Productions from 8.6: Constructor Declarations */
553 /* NOTE FOR FURTHER WORK ON CONSTRUCTORS:
554 - If a forbidded modifier is found, the the error is either the use of
555 a forbidded modifier for a constructor OR bogus attempt to declare a
556 method without having specified the return type. FIXME */
557 constructor_declaration:
558 constructor_declarator throws constructor_body
559 | modifiers constructor_declarator throws constructor_body
560 { modifier_value = 0; }
561 /* extra SC_TK, FIXME */
562 | constructor_declarator throws constructor_body SC_TK
563 /* extra SC_TK, FIXME */
564 | modifiers constructor_declarator throws constructor_body SC_TK
565 { modifier_value = 0; }
566 /* I'm not happy with the SC_TK addition. It isn't in the grammer and should
567 probably be matched by and empty statement. But it doesn't work. FIXME */
570 constructor_declarator:
571 simple_name OP_TK CP_TK
573 | simple_name OP_TK formal_parameter_list CP_TK
579 | OCB_TK explicit_constructor_invocation CCB_TK
580 | OCB_TK block_statements CCB_TK
581 | OCB_TK explicit_constructor_invocation block_statements CCB_TK
584 /* Error recovery for that rule moved down expression_statement: rule. */
585 explicit_constructor_invocation:
586 this_or_super OP_TK CP_TK SC_TK
587 | this_or_super OP_TK argument_list CP_TK SC_TK
588 /* Added, JDK1.1 inner classes. Modified because the rule
589 'primary' couldn't work. */
590 | name DOT_TK SUPER_TK OP_TK argument_list CP_TK SC_TK
592 | name DOT_TK SUPER_TK OP_TK CP_TK SC_TK
596 this_or_super: /* Added, simplifies error diagnostics */
601 /* 19.9 Productions from 9: Interfaces */
602 /* 19.9.1 Productions from 9.1: Interfaces Declarations */
603 interface_declaration:
604 INTERFACE_TK identifier
605 { report_class_declaration ($2); modifier_value = 0; }
607 | modifiers INTERFACE_TK identifier
608 { report_class_declaration ($3); modifier_value = 0; }
610 | INTERFACE_TK identifier extends_interfaces
611 { report_class_declaration ($2); modifier_value = 0; }
613 | modifiers INTERFACE_TK identifier extends_interfaces
614 { report_class_declaration ($3); modifier_value = 0; }
619 EXTENDS_TK interface_type
620 | extends_interfaces C_TK interface_type
625 { pop_class_context (); }
626 | OCB_TK interface_member_declarations CCB_TK
627 { pop_class_context (); }
630 interface_member_declarations:
631 interface_member_declaration
632 | interface_member_declarations interface_member_declaration
635 interface_member_declaration:
637 | abstract_method_declaration
638 | class_declaration /* Added, JDK1.1 inner classes */
639 | interface_declaration /* Added, JDK1.1 inner classes */
642 constant_declaration:
646 abstract_method_declaration:
650 /* 19.10 Productions from 10: Arrays */
653 | OCB_TK variable_initializers CCB_TK
655 | OCB_TK variable_initializers C_TK CCB_TK
658 variable_initializers:
660 | variable_initializers C_TK variable_initializer
663 /* 19.11 Production from 14: Blocks and Statements */
666 | OCB_TK block_statements CCB_TK
671 | block_statements block_statement
675 local_variable_declaration_statement
677 | class_declaration /* Added, JDK1.1 inner classes */
680 local_variable_declaration_statement:
681 local_variable_declaration SC_TK /* Can't catch missing ';' here */
684 local_variable_declaration:
685 type variable_declarators
687 | modifiers type variable_declarators /* Added, JDK1.1 final locals */
688 { modifier_value = 0; }
692 statement_without_trailing_substatement
695 | if_then_else_statement
701 statement_without_trailing_substatement
702 | labeled_statement_nsi
703 | if_then_else_statement_nsi
704 | while_statement_nsi
708 statement_without_trailing_substatement:
711 | expression_statement
717 | synchronized_statement
735 labeled_statement_nsi:
736 label_decl statement_nsi
739 /* We concentrate here a bunch of error handling rules that we couldn't write
740 earlier, because expression_statement catches a missing ';'. */
741 expression_statement:
742 statement_expression SC_TK
745 statement_expression:
747 | pre_increment_expression
748 | pre_decrement_expression
749 | post_increment_expression
750 | post_decrement_expression
752 | class_instance_creation_expression
756 IF_TK OP_TK expression CP_TK statement { ++complexity; }
759 if_then_else_statement:
760 IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
764 if_then_else_statement_nsi:
765 IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
770 SWITCH_TK OP_TK expression CP_TK switch_block
775 | OCB_TK switch_labels CCB_TK
776 | OCB_TK switch_block_statement_groups CCB_TK
777 | OCB_TK switch_block_statement_groups switch_labels CCB_TK
780 switch_block_statement_groups:
781 switch_block_statement_group
782 | switch_block_statement_groups switch_block_statement_group
785 switch_block_statement_group:
786 switch_labels block_statements { ++complexity; }
792 | switch_labels switch_label
796 CASE_TK constant_expression REL_CL_TK
797 | DEFAULT_TK REL_CL_TK
801 WHILE_TK OP_TK expression CP_TK { ++complexity; }
805 while_expression statement
809 while_expression statement_nsi
817 do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
822 for_begin SC_TK expression SC_TK for_update CP_TK statement
823 | for_begin SC_TK SC_TK for_update CP_TK statement
827 for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
828 | for_begin SC_TK SC_TK for_update CP_TK statement_nsi
836 for_header for_init { ++complexity; }
838 for_init: /* Can be empty */
839 | statement_expression_list
840 | local_variable_declaration
843 for_update: /* Can be empty */
844 | statement_expression_list
847 statement_expression_list:
849 | statement_expression_list C_TK statement_expression
854 | BREAK_TK identifier SC_TK
857 /* `continue' with a label is considered for complexity but ordinary
861 | CONTINUE_TK identifier SC_TK { ++complexity; }
866 | RETURN_TK expression SC_TK
870 THROW_TK expression SC_TK { ++complexity; }
873 synchronized_statement:
874 synchronized OP_TK expression CP_TK block
875 | synchronized OP_TK expression CP_TK error
878 synchronized: /* Test lval.sub_token here */
885 | TRY_TK block finally
886 | TRY_TK block catches finally
891 | catches catch_clause
895 CATCH_TK OP_TK formal_parameter CP_TK block { ++complexity; }
899 FINALLY_TK block { ++complexity; }
902 /* 19.12 Production from 15: Expressions */
905 | array_creation_expression
908 primary_no_new_array:
911 | OP_TK expression CP_TK
912 | class_instance_creation_expression
917 /* Added, JDK1.1 inner classes. Documentation is wrong
918 refering to a 'ClassName' (class_name) rule that doesn't
919 exist. Used name instead. */
920 | name DOT_TK THIS_TK
927 | array_type DOT_TK CLASS_TK
929 | primitive_type DOT_TK CLASS_TK
931 | VOID_TK DOT_TK CLASS_TK
935 class_instance_creation_expression:
936 NEW_TK class_type OP_TK argument_list CP_TK
937 | NEW_TK class_type OP_TK CP_TK
938 | anonymous_class_creation
939 | something_dot_new identifier OP_TK CP_TK
940 | something_dot_new identifier OP_TK CP_TK class_body
941 | something_dot_new identifier OP_TK argument_list CP_TK
942 | something_dot_new identifier OP_TK argument_list CP_TK class_body
945 anonymous_class_creation:
946 NEW_TK class_type OP_TK CP_TK
947 { report_class_declaration (anonymous_context); }
949 | NEW_TK class_type OP_TK argument_list CP_TK
950 { report_class_declaration (anonymous_context); }
954 something_dot_new: /* Added, not part of the specs. */
957 | primary DOT_TK NEW_TK
962 | argument_list C_TK expression
963 | argument_list C_TK error
966 array_creation_expression:
967 NEW_TK primitive_type dim_exprs
968 | NEW_TK class_or_interface_type dim_exprs
969 | NEW_TK primitive_type dim_exprs dims
970 | NEW_TK class_or_interface_type dim_exprs dims
971 /* Added, JDK1.1 anonymous array. Initial documentation rule
973 | NEW_TK class_or_interface_type dims array_initializer
974 | NEW_TK primitive_type dims array_initializer
983 OSB_TK expression CSB_TK
988 { bracket_count = 1; }
994 primary DOT_TK identifier
995 | SUPER_TK DOT_TK identifier
998 /* We include method invocation in the complexity measure on the
999 theory that most method calls are virtual and therefore involve a
1003 { USE_ABSORBER; ++complexity; }
1004 | name OP_TK argument_list CP_TK
1005 { USE_ABSORBER; ++complexity; }
1006 | primary DOT_TK identifier OP_TK CP_TK { ++complexity; }
1007 | primary DOT_TK identifier OP_TK argument_list CP_TK { ++complexity; }
1008 | SUPER_TK DOT_TK identifier OP_TK CP_TK { ++complexity; }
1009 | SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK { ++complexity; }
1013 name OSB_TK expression CSB_TK
1015 | primary_no_new_array OSB_TK expression CSB_TK
1022 | post_increment_expression
1023 | post_decrement_expression
1026 post_increment_expression:
1027 postfix_expression INCR_TK
1030 post_decrement_expression:
1031 postfix_expression DECR_TK
1035 pre_increment_expression
1036 | pre_decrement_expression
1037 | PLUS_TK unary_expression
1038 | MINUS_TK unary_expression
1039 | unary_expression_not_plus_minus
1042 pre_increment_expression:
1043 INCR_TK unary_expression
1046 pre_decrement_expression:
1047 DECR_TK unary_expression
1050 unary_expression_not_plus_minus:
1052 | NOT_TK unary_expression
1053 | NEG_TK unary_expression
1057 cast_expression: /* Error handling here is potentially weak */
1058 OP_TK primitive_type dims CP_TK unary_expression
1059 | OP_TK primitive_type CP_TK unary_expression
1060 | OP_TK expression CP_TK unary_expression_not_plus_minus
1061 | OP_TK name dims CP_TK unary_expression_not_plus_minus
1064 multiplicative_expression:
1066 | multiplicative_expression MULT_TK unary_expression
1067 | multiplicative_expression DIV_TK unary_expression
1068 | multiplicative_expression REM_TK unary_expression
1071 additive_expression:
1072 multiplicative_expression
1073 | additive_expression PLUS_TK multiplicative_expression
1074 | additive_expression MINUS_TK multiplicative_expression
1079 | shift_expression LS_TK additive_expression
1080 | shift_expression SRS_TK additive_expression
1081 | shift_expression ZRS_TK additive_expression
1084 relational_expression:
1086 | relational_expression LT_TK shift_expression
1087 | relational_expression GT_TK shift_expression
1088 | relational_expression LTE_TK shift_expression
1089 | relational_expression GTE_TK shift_expression
1090 | relational_expression INSTANCEOF_TK reference_type
1093 equality_expression:
1094 relational_expression
1095 | equality_expression EQ_TK relational_expression
1096 | equality_expression NEQ_TK relational_expression
1101 | and_expression AND_TK equality_expression
1104 exclusive_or_expression:
1106 | exclusive_or_expression XOR_TK and_expression
1109 inclusive_or_expression:
1110 exclusive_or_expression
1111 | inclusive_or_expression OR_TK exclusive_or_expression
1114 conditional_and_expression:
1115 inclusive_or_expression
1116 | conditional_and_expression BOOL_AND_TK inclusive_or_expression
1120 conditional_or_expression:
1121 conditional_and_expression
1122 | conditional_or_expression BOOL_OR_TK conditional_and_expression
1126 conditional_expression: /* Error handling here is weak */
1127 conditional_or_expression
1128 | conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression
1132 assignment_expression:
1133 conditional_expression
1138 left_hand_side assignment_operator assignment_expression
1148 assignment_operator:
1154 assignment_expression
1157 constant_expression:
1163 /* Create a new parser context */
1166 java_push_parser_context ()
1168 struct parser_ctxt *new =
1169 (struct parser_ctxt *) xcalloc (1, sizeof (struct parser_ctxt));
1176 push_class_context (name)
1179 struct class_context *ctx;
1181 ctx = (struct class_context *) xmalloc (sizeof (struct class_context));
1182 ctx->name = (char *) name;
1183 ctx->next = current_class_context;
1184 current_class_context = ctx;
1188 pop_class_context ()
1190 struct class_context *ctx;
1192 if (current_class_context == NULL)
1195 ctx = current_class_context->next;
1196 if (current_class_context->name != anonymous_context)
1197 free (current_class_context->name);
1198 free (current_class_context);
1200 current_class_context = ctx;
1201 if (current_class_context == NULL)
1202 anonymous_count = 0;
1205 /* Recursively construct the class name. This is just a helper
1206 function for get_class_name(). */
1208 make_class_name_recursive (stack, ctx)
1209 struct obstack *stack;
1210 struct class_context *ctx;
1215 make_class_name_recursive (stack, ctx->next);
1217 /* Replace an anonymous context with the appropriate counter value. */
1218 if (ctx->name == anonymous_context)
1222 sprintf (buf, "%d", anonymous_count);
1223 ctx->name = xstrdup (buf);
1226 obstack_grow (stack, ctx->name, strlen (ctx->name));
1227 obstack_1grow (stack, '$');
1229 return ISDIGIT (ctx->name[0]);
1232 /* Return a newly allocated string holding the name of the class. */
1238 struct obstack name_stack;
1240 obstack_init (&name_stack);
1242 /* Duplicate the logic of parse.y:maybe_make_nested_class_name(). */
1243 last_was_digit = make_class_name_recursive (&name_stack,
1244 current_class_context->next);
1246 if (! last_was_digit
1248 && current_class_context->name != anonymous_context)
1252 sprintf (buf, "%d", anonymous_count);
1253 obstack_grow (&name_stack, buf, strlen (buf));
1254 obstack_1grow (&name_stack, '$');
1257 if (current_class_context->name == anonymous_context)
1261 sprintf (buf, "%d", anonymous_count);
1262 current_class_context->name = xstrdup (buf);
1263 obstack_grow0 (&name_stack, buf, strlen (buf));
1266 obstack_grow0 (&name_stack, current_class_context->name,
1267 strlen (current_class_context->name));
1269 result = xstrdup (obstack_finish (&name_stack));
1270 obstack_free (&name_stack, NULL);
1275 /* Actions defined here */
1278 report_class_declaration (name)
1281 extern int flag_dump_class, flag_list_filename;
1283 push_class_context (name);
1284 if (flag_dump_class)
1286 char *name = get_class_name ();
1288 if (!previous_output)
1290 if (flag_list_filename)
1291 fprintf (out, "%s: ", input_filename);
1292 previous_output = 1;
1296 fprintf (out, "%s.%s ", package_name, name);
1298 fprintf (out, "%s ", name);
1305 report_main_declaration (declarator)
1306 struct method_declarator *declarator;
1308 extern int flag_find_main;
1311 && modifier_value == 2
1312 && !strcmp (declarator->method_name, "main")
1314 && declarator->args [0] == '['
1315 && (! strcmp (declarator->args+1, "String")
1316 || ! strcmp (declarator->args + 1, "java.lang.String"))
1317 && current_class_context)
1319 if (!previous_output)
1321 char *name = get_class_name ();
1323 fprintf (out, "%s.%s ", package_name, name);
1325 fprintf (out, "%s", name);
1327 previous_output = 1;
1335 extern int flag_complexity;
1336 if (flag_complexity)
1337 fprintf (out, "%s %d\n", input_filename, complexity);
1340 /* Reset global status used by the report functions. */
1342 void reset_report ()
1344 previous_output = 0;
1345 package_name = NULL;
1346 current_class_context = NULL;
1352 const char *msg ATTRIBUTE_UNUSED;
1354 fprintf (stderr, "%s: %d: %s\n", input_filename, lineno, msg);