1 /* Parser grammar for quick source code scan of Java(TM) language programs.
2 Copyright (C) 1998, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
3 Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
5 This file is part of GCC.
7 GCC 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 GCC 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 GCC; 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. */
42 #include "coretypes.h"
48 #define obstack_chunk_alloc xmalloc
49 #define obstack_chunk_free free
51 extern
char *input_filename
;
52 extern
FILE *finput
, *out
;
54 /* Obstack for the lexer. */
55 struct obstack temporary_obstack
;
57 /* The current parser context. */
58 static struct parser_ctxt
*ctxp
;
60 /* Error and warning counts, current line number, because they're used
63 int java_warning_count
;
66 /* Tweak default rules when necessary. */
68 #define USE_ABSORBER absorber = 0
70 /* Keep track of the current package name. */
71 static const char *package_name
;
73 /* Keep track of whether things have be listed before. */
74 static int previous_output
;
76 /* Record modifier uses */
77 static int modifier_value
;
79 /* Record (almost) cyclomatic complexity. */
80 static int complexity
;
82 /* Keeps track of number of bracket pairs after a variable declarator
84 static int bracket_count
;
86 /* Numbers anonymous classes */
87 static int anonymous_count
;
89 /* This is used to record the current class context. */
93 struct class_context
*next
;
96 /* The global class context. */
97 static struct class_context
*current_class_context
;
99 /* A special constant used to represent an anonymous context. */
100 static const char *anonymous_context
= "ANONYMOUS";
102 /* Count of method depth. */
103 static int method_depth
;
105 /* Record a method declaration */
106 struct method_declarator
{
107 const char *method_name
;
110 #define NEW_METHOD_DECLARATOR(D,N,A) \
113 (struct method_declarator
*)xmalloc
(sizeof
(struct method_declarator
)); \
114 (D
)->method_name
= (N
); \
118 /* Two actions for this grammar */
119 static int make_class_name_recursive PARAMS
((struct obstack
*stack
,
120 struct class_context
*ctx
));
121 static char *get_class_name PARAMS
((void));
122 static void report_class_declaration PARAMS
((const char *));
123 static void report_main_declaration PARAMS
((struct method_declarator
*));
124 static void push_class_context PARAMS
((const char *));
125 static void pop_class_context PARAMS
((void));
127 void report PARAMS
((void));
135 struct method_declarator
*declarator
;
136 int value
; /* For modifiers */
140 extern
int flag_assert
;
147 /* Things defined here have to match the order of what's in the
148 binop_lookup table. */
150 %token PLUS_TK MINUS_TK MULT_TK DIV_TK REM_TK
151 %token LS_TK SRS_TK ZRS_TK
152 %token AND_TK XOR_TK OR_TK
153 %token BOOL_AND_TK BOOL_OR_TK
154 %token EQ_TK NEQ_TK GT_TK GTE_TK LT_TK LTE_TK
156 /* This maps to the same binop_lookup entry than the token above */
158 %token PLUS_ASSIGN_TK MINUS_ASSIGN_TK MULT_ASSIGN_TK DIV_ASSIGN_TK
160 %token LS_ASSIGN_TK SRS_ASSIGN_TK ZRS_ASSIGN_TK
161 %token AND_ASSIGN_TK XOR_ASSIGN_TK OR_ASSIGN_TK
164 /* Modifier TOKEN have to be kept in this order. Don't scramble it */
166 %token PUBLIC_TK PRIVATE_TK PROTECTED_TK
167 %token STATIC_TK FINAL_TK SYNCHRONIZED_TK
168 %token VOLATILE_TK TRANSIENT_TK NATIVE_TK
169 %token PAD_TK ABSTRACT_TK MODIFIER_TK
172 /* Keep those two in order, too */
173 %token DECR_TK INCR_TK
175 /* From now one, things can be in any order */
177 %token DEFAULT_TK IF_TK THROW_TK
178 %token BOOLEAN_TK DO_TK IMPLEMENTS_TK
179 %token THROWS_TK BREAK_TK IMPORT_TK
180 %token ELSE_TK INSTANCEOF_TK RETURN_TK
181 %token VOID_TK CATCH_TK INTERFACE_TK
182 %token CASE_TK EXTENDS_TK FINALLY_TK
183 %token SUPER_TK WHILE_TK CLASS_TK
184 %token SWITCH_TK CONST_TK TRY_TK
185 %token FOR_TK NEW_TK CONTINUE_TK
186 %token GOTO_TK PACKAGE_TK THIS_TK
189 %token BYTE_TK SHORT_TK INT_TK LONG_TK
190 %token CHAR_TK INTEGRAL_TK
192 %token FLOAT_TK DOUBLE_TK FP_TK
196 %token REL_QM_TK REL_CL_TK NOT_TK NEG_TK
198 %token ASSIGN_ANY_TK ASSIGN_TK
199 %token OP_TK CP_TK OCB_TK CCB_TK OSB_TK CSB_TK SC_TK C_TK DOT_TK
201 %token STRING_LIT_TK CHAR_LIT_TK INT_LIT_TK FP_LIT_TK
202 %token TRUE_TK FALSE_TK BOOL_LIT_TK NULL_TK
204 %type
<node
> ID_TK identifier name simple_name qualified_name type
205 primitive_type reference_type array_type formal_parameter_list
206 formal_parameter class_or_interface_type class_type interface_type
207 %type
<declarator
> method_declarator
208 %type
<value
> MODIFIER_TK
211 /* 19.2 Production from 2.3: The Syntactic Grammar */
216 /* 19.3 Productions from 3: Lexical structure */
226 /* 19.4 Productions from 4: Types, Values and Variables */
235 /* use preset global here. FIXME */
236 $$
= xstrdup
("int");
240 /* use preset global here. FIXME */
241 $$
= xstrdup
("double");
245 /* use preset global here. FIXME */
246 $$
= xstrdup
("boolean");
251 class_or_interface_type
255 class_or_interface_type:
260 class_or_interface_type
/* Default rule */
264 class_or_interface_type
270 while
(bracket_count
-- > 0)
271 $$
= concat
("[", $1, NULL
);
275 while
(bracket_count
-- > 0)
276 $$
= concat
("[", $1, NULL
);
280 /* 19.5 Productions from 6: Names */
282 simple_name
/* Default rule */
283 | qualified_name
/* Default rule */
287 identifier
/* Default rule */
291 name DOT_TK identifier
293 $$
= concat
($1, ".", $3, NULL
);
301 /* 19.6: Production from 7: Packages */
303 | package_declaration
304 | import_declarations
306 | package_declaration import_declarations
307 | package_declaration type_declarations
308 | import_declarations type_declarations
309 | package_declaration import_declarations type_declarations
314 | import_declarations import_declaration
319 | type_declarations type_declaration
323 PACKAGE_TK name SC_TK
324 { package_name
= $2; }
328 single_type_import_declaration
329 | type_import_on_demand_declaration
332 single_type_import_declaration:
336 type_import_on_demand_declaration:
337 IMPORT_TK name DOT_TK MULT_TK SC_TK
342 | interface_declaration
346 /* 19.7 Shortened from the original:
347 modifiers: modifier | modifiers modifier
348 modifier: any of public... */
358 | modifiers MODIFIER_TK
368 /* 19.8.1 Production from $8.1: Class Declaration */
370 modifiers CLASS_TK identifier super interfaces
372 report_class_declaration
($3);
376 | CLASS_TK identifier super interfaces
377 { report_class_declaration
($2); }
382 | EXTENDS_TK class_type
386 | IMPLEMENTS_TK interface_type_list
392 | interface_type_list C_TK interface_type
398 { pop_class_context
(); }
399 | OCB_TK class_body_declarations CCB_TK
400 { pop_class_context
(); }
403 class_body_declarations:
404 class_body_declaration
405 | class_body_declarations class_body_declaration
408 class_body_declaration:
409 class_member_declaration
411 | constructor_declaration
412 | block
/* Added, JDK1.1, instance initializer */
415 class_member_declaration:
418 | class_declaration
/* Added, JDK1.1 inner classes */
419 | interface_declaration
/* Added, JDK1.1 inner classes */
423 /* 19.8.2 Productions from 8.3: Field Declarations */
425 type variable_declarators SC_TK
427 | modifiers type variable_declarators SC_TK
428 { modifier_value
= 0; }
431 variable_declarators:
432 /* Should we use build_decl_list () instead ? FIXME */
433 variable_declarator
/* Default rule */
434 | variable_declarators C_TK variable_declarator
438 variable_declarator_id
439 | variable_declarator_id ASSIGN_TK variable_initializer
442 variable_declarator_id:
444 { bracket_count
= 0; USE_ABSORBER
; }
445 | variable_declarator_id OSB_TK CSB_TK
449 variable_initializer:
454 /* 19.8.3 Productions from 8.4: Method Declarations */
463 type method_declarator throws
465 | VOID_TK method_declarator throws
466 | modifiers type method_declarator throws
467 { modifier_value
= 0; }
468 | modifiers VOID_TK method_declarator throws
470 report_main_declaration
($3);
476 identifier OP_TK CP_TK
478 struct method_declarator
*d
;
479 NEW_METHOD_DECLARATOR
(d
, $1, NULL
);
482 | identifier OP_TK formal_parameter_list CP_TK
484 struct method_declarator
*d
;
485 NEW_METHOD_DECLARATOR
(d
, $1, $3);
488 | method_declarator OSB_TK CSB_TK
491 formal_parameter_list:
493 | formal_parameter_list C_TK formal_parameter
495 $$
= concat
($1, ",", $3, NULL
);
500 type variable_declarator_id
506 char *n
= xmalloc
(bracket_count
+ 1 + strlen
($$
));
507 for
(i
= 0; i
< bracket_count
; ++i
)
509 strcpy
(n
+ bracket_count
, $$
);
515 | modifiers type variable_declarator_id
/* Added, JDK1.1 final locals */
520 char *n
= xmalloc
(bracket_count
+ 1 + strlen
($$
));
521 for
(i
= 0; i
< bracket_count
; ++i
)
523 strcpy
(n
+ bracket_count
, $$
);
532 | THROWS_TK class_type_list
538 | class_type_list C_TK class_type
547 /* 19.8.4 Productions from 8.5: Static Initializers */
552 static: /* Test lval.sub_token here */
557 /* 19.8.5 Productions from 8.6: Constructor Declarations */
558 /* NOTE FOR FURTHER WORK ON CONSTRUCTORS:
559 - If a forbidded modifier is found, the the error is either the use of
560 a forbidded modifier for a constructor OR bogus attempt to declare a
561 method without having specified the return type. FIXME */
562 constructor_declaration:
563 constructor_declarator throws constructor_body
564 | modifiers constructor_declarator throws constructor_body
565 { modifier_value
= 0; }
566 /* extra SC_TK, FIXME */
567 | constructor_declarator throws constructor_body SC_TK
568 /* extra SC_TK, FIXME */
569 | modifiers constructor_declarator throws constructor_body SC_TK
570 { modifier_value
= 0; }
571 /* I'm not happy with the SC_TK addition. It isn't in the grammer and should
572 probably be matched by and empty statement. But it doesn't work. FIXME */
575 constructor_declarator:
576 simple_name OP_TK CP_TK
578 | simple_name OP_TK formal_parameter_list CP_TK
584 | OCB_TK explicit_constructor_invocation CCB_TK
585 | OCB_TK block_statements CCB_TK
586 | OCB_TK explicit_constructor_invocation block_statements CCB_TK
589 /* Error recovery for that rule moved down expression_statement: rule. */
590 explicit_constructor_invocation:
591 this_or_super OP_TK CP_TK SC_TK
592 | this_or_super OP_TK argument_list CP_TK SC_TK
593 /* Added, JDK1.1 inner classes. Modified because the rule
594 'primary' couldn't work. */
595 | name DOT_TK SUPER_TK OP_TK argument_list CP_TK SC_TK
597 | name DOT_TK SUPER_TK OP_TK CP_TK SC_TK
601 this_or_super: /* Added, simplifies error diagnostics */
606 /* 19.9 Productions from 9: Interfaces */
607 /* 19.9.1 Productions from 9.1: Interfaces Declarations */
608 interface_declaration:
609 INTERFACE_TK identifier
610 { report_class_declaration
($2); modifier_value
= 0; }
612 | modifiers INTERFACE_TK identifier
613 { report_class_declaration
($3); modifier_value
= 0; }
615 | INTERFACE_TK identifier extends_interfaces
616 { report_class_declaration
($2); modifier_value
= 0; }
618 | modifiers INTERFACE_TK identifier extends_interfaces
619 { report_class_declaration
($3); modifier_value
= 0; }
624 EXTENDS_TK interface_type
625 | extends_interfaces C_TK interface_type
630 { pop_class_context
(); }
631 | OCB_TK interface_member_declarations CCB_TK
632 { pop_class_context
(); }
635 interface_member_declarations:
636 interface_member_declaration
637 | interface_member_declarations interface_member_declaration
640 interface_member_declaration:
642 | abstract_method_declaration
643 | class_declaration
/* Added, JDK1.1 inner classes */
644 | interface_declaration
/* Added, JDK1.1 inner classes */
647 constant_declaration:
651 abstract_method_declaration:
655 /* 19.10 Productions from 10: Arrays */
658 | OCB_TK variable_initializers CCB_TK
660 | OCB_TK variable_initializers C_TK CCB_TK
663 variable_initializers:
665 | variable_initializers C_TK variable_initializer
668 /* 19.11 Production from 14: Blocks and Statements */
671 | OCB_TK block_statements CCB_TK
676 | block_statements block_statement
680 local_variable_declaration_statement
682 | class_declaration
/* Added, JDK1.1 inner classes */
685 local_variable_declaration_statement:
686 local_variable_declaration SC_TK
/* Can't catch missing ';' here */
689 local_variable_declaration:
690 type variable_declarators
692 | modifiers type variable_declarators
/* Added, JDK1.1 final locals */
693 { modifier_value
= 0; }
697 statement_without_trailing_substatement
700 | if_then_else_statement
706 statement_without_trailing_substatement
707 | labeled_statement_nsi
708 | if_then_else_statement_nsi
709 | while_statement_nsi
713 statement_without_trailing_substatement:
716 | expression_statement
722 | synchronized_statement
741 labeled_statement_nsi:
742 label_decl statement_nsi
745 /* We concentrate here a bunch of error handling rules that we couldn't write
746 earlier, because expression_statement catches a missing ';'. */
747 expression_statement:
748 statement_expression SC_TK
751 statement_expression:
753 | pre_increment_expression
754 | pre_decrement_expression
755 | post_increment_expression
756 | post_decrement_expression
758 | class_instance_creation_expression
762 IF_TK OP_TK expression CP_TK statement
{ ++complexity
; }
765 if_then_else_statement:
766 IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement
770 if_then_else_statement_nsi:
771 IF_TK OP_TK expression CP_TK statement_nsi ELSE_TK statement_nsi
776 SWITCH_TK OP_TK expression CP_TK switch_block
781 | OCB_TK switch_labels CCB_TK
782 | OCB_TK switch_block_statement_groups CCB_TK
783 | OCB_TK switch_block_statement_groups switch_labels CCB_TK
786 switch_block_statement_groups:
787 switch_block_statement_group
788 | switch_block_statement_groups switch_block_statement_group
791 switch_block_statement_group:
792 switch_labels block_statements
{ ++complexity
; }
798 | switch_labels switch_label
802 CASE_TK constant_expression REL_CL_TK
803 | DEFAULT_TK REL_CL_TK
807 WHILE_TK OP_TK expression CP_TK
{ ++complexity
; }
811 while_expression statement
815 while_expression statement_nsi
823 do_statement_begin statement WHILE_TK OP_TK expression CP_TK SC_TK
828 for_begin SC_TK expression SC_TK for_update CP_TK statement
829 | for_begin SC_TK SC_TK for_update CP_TK statement
833 for_begin SC_TK expression SC_TK for_update CP_TK statement_nsi
834 | for_begin SC_TK SC_TK for_update CP_TK statement_nsi
842 for_header for_init
{ ++complexity
; }
844 for_init: /* Can be empty */
845 | statement_expression_list
846 | local_variable_declaration
849 for_update: /* Can be empty */
850 | statement_expression_list
853 statement_expression_list:
855 | statement_expression_list C_TK statement_expression
860 | BREAK_TK identifier SC_TK
863 /* `continue' with a label is considered for complexity but ordinary
867 | CONTINUE_TK identifier SC_TK
{ ++complexity
; }
872 | RETURN_TK expression SC_TK
876 THROW_TK expression SC_TK
{ ++complexity
; }
880 ASSERT_TK expression REL_CL_TK expression SC_TK
881 | ASSERT_TK expression SC_TK
883 {yyerror ("Missing term"); RECOVER
;}
884 | ASSERT_TK expression
error
885 {yyerror ("';' expected"); RECOVER
;}
887 synchronized_statement:
888 synchronized OP_TK expression CP_TK block
889 | synchronized OP_TK expression CP_TK
error
892 synchronized: /* Test lval.sub_token here */
899 | TRY_TK block finally
900 | TRY_TK block catches finally
905 | catches catch_clause
909 CATCH_TK OP_TK formal_parameter CP_TK block
{ ++complexity
; }
913 FINALLY_TK block
{ ++complexity
; }
916 /* 19.12 Production from 15: Expressions */
919 | array_creation_expression
922 primary_no_new_array:
925 | OP_TK expression CP_TK
926 | class_instance_creation_expression
931 /* Added, JDK1.1 inner classes. Documentation is wrong
932 refering to a 'ClassName' (class_name) rule that doesn't
933 exist. Used name instead. */
934 | name DOT_TK THIS_TK
941 | array_type DOT_TK CLASS_TK
943 | primitive_type DOT_TK CLASS_TK
945 | VOID_TK DOT_TK CLASS_TK
949 class_instance_creation_expression:
950 NEW_TK class_type OP_TK argument_list CP_TK
951 | NEW_TK class_type OP_TK CP_TK
952 | anonymous_class_creation
953 | something_dot_new identifier OP_TK CP_TK
954 | something_dot_new identifier OP_TK CP_TK class_body
955 | something_dot_new identifier OP_TK argument_list CP_TK
956 | something_dot_new identifier OP_TK argument_list CP_TK class_body
959 anonymous_class_creation:
960 NEW_TK class_type OP_TK CP_TK
961 { report_class_declaration
(anonymous_context
); }
963 | NEW_TK class_type OP_TK argument_list CP_TK
964 { report_class_declaration
(anonymous_context
); }
968 something_dot_new: /* Added, not part of the specs. */
971 | primary DOT_TK NEW_TK
976 | argument_list C_TK expression
977 | argument_list C_TK
error
980 array_creation_expression:
981 NEW_TK primitive_type dim_exprs
982 | NEW_TK class_or_interface_type dim_exprs
983 | NEW_TK primitive_type dim_exprs dims
984 | NEW_TK class_or_interface_type dim_exprs dims
985 /* Added, JDK1.1 anonymous array. Initial documentation rule
987 | NEW_TK class_or_interface_type dims array_initializer
988 | NEW_TK primitive_type dims array_initializer
997 OSB_TK expression CSB_TK
1002 { bracket_count
= 1; }
1003 | dims OSB_TK CSB_TK
1004 { bracket_count
++; }
1008 primary DOT_TK identifier
1009 | SUPER_TK DOT_TK identifier
1012 /* We include method invocation in the complexity measure on the
1013 theory that most method calls are virtual and therefore involve a
1017 { USE_ABSORBER
; ++complexity
; }
1018 | name OP_TK argument_list CP_TK
1019 { USE_ABSORBER
; ++complexity
; }
1020 | primary DOT_TK identifier OP_TK CP_TK
{ ++complexity
; }
1021 | primary DOT_TK identifier OP_TK argument_list CP_TK
{ ++complexity
; }
1022 | SUPER_TK DOT_TK identifier OP_TK CP_TK
{ ++complexity
; }
1023 | SUPER_TK DOT_TK identifier OP_TK argument_list CP_TK
{ ++complexity
; }
1027 name OSB_TK expression CSB_TK
1029 | primary_no_new_array OSB_TK expression CSB_TK
1036 | post_increment_expression
1037 | post_decrement_expression
1040 post_increment_expression:
1041 postfix_expression INCR_TK
1044 post_decrement_expression:
1045 postfix_expression DECR_TK
1049 pre_increment_expression
1050 | pre_decrement_expression
1051 | PLUS_TK unary_expression
1052 | MINUS_TK unary_expression
1053 | unary_expression_not_plus_minus
1056 pre_increment_expression:
1057 INCR_TK unary_expression
1060 pre_decrement_expression:
1061 DECR_TK unary_expression
1064 unary_expression_not_plus_minus:
1066 | NOT_TK unary_expression
1067 | NEG_TK unary_expression
1071 cast_expression: /* Error handling here is potentially weak */
1072 OP_TK primitive_type dims CP_TK unary_expression
1073 | OP_TK primitive_type CP_TK unary_expression
1074 | OP_TK expression CP_TK unary_expression_not_plus_minus
1075 | OP_TK name dims CP_TK unary_expression_not_plus_minus
1078 multiplicative_expression:
1080 | multiplicative_expression MULT_TK unary_expression
1081 | multiplicative_expression DIV_TK unary_expression
1082 | multiplicative_expression REM_TK unary_expression
1085 additive_expression:
1086 multiplicative_expression
1087 | additive_expression PLUS_TK multiplicative_expression
1088 | additive_expression MINUS_TK multiplicative_expression
1093 | shift_expression LS_TK additive_expression
1094 | shift_expression SRS_TK additive_expression
1095 | shift_expression ZRS_TK additive_expression
1098 relational_expression:
1100 | relational_expression LT_TK shift_expression
1101 | relational_expression GT_TK shift_expression
1102 | relational_expression LTE_TK shift_expression
1103 | relational_expression GTE_TK shift_expression
1104 | relational_expression INSTANCEOF_TK reference_type
1107 equality_expression:
1108 relational_expression
1109 | equality_expression EQ_TK relational_expression
1110 | equality_expression NEQ_TK relational_expression
1115 | and_expression AND_TK equality_expression
1118 exclusive_or_expression:
1120 | exclusive_or_expression XOR_TK and_expression
1123 inclusive_or_expression:
1124 exclusive_or_expression
1125 | inclusive_or_expression OR_TK exclusive_or_expression
1128 conditional_and_expression:
1129 inclusive_or_expression
1130 | conditional_and_expression BOOL_AND_TK inclusive_or_expression
1134 conditional_or_expression:
1135 conditional_and_expression
1136 | conditional_or_expression BOOL_OR_TK conditional_and_expression
1140 conditional_expression: /* Error handling here is weak */
1141 conditional_or_expression
1142 | conditional_or_expression REL_QM_TK expression REL_CL_TK conditional_expression
1146 assignment_expression:
1147 conditional_expression
1152 left_hand_side assignment_operator assignment_expression
1162 assignment_operator:
1168 assignment_expression
1171 constant_expression:
1177 /* Create a new parser context */
1180 java_push_parser_context
()
1182 struct parser_ctxt
*new
=
1183 (struct parser_ctxt
*) xcalloc
(1, sizeof
(struct parser_ctxt
));
1190 push_class_context
(name
)
1193 struct class_context
*ctx
;
1195 ctx
= (struct class_context
*) xmalloc
(sizeof
(struct class_context
));
1196 ctx
->name
= (char *) name
;
1197 ctx
->next
= current_class_context
;
1198 current_class_context
= ctx
;
1202 pop_class_context
()
1204 struct class_context
*ctx
;
1206 if
(current_class_context
== NULL
)
1209 ctx
= current_class_context
->next
;
1210 if
(current_class_context
->name
!= anonymous_context
)
1211 free
(current_class_context
->name
);
1212 free
(current_class_context
);
1214 current_class_context
= ctx
;
1215 if
(current_class_context
== NULL
)
1216 anonymous_count
= 0;
1219 /* Recursively construct the class name. This is just a helper
1220 function for get_class_name(). */
1222 make_class_name_recursive
(stack
, ctx
)
1223 struct obstack
*stack
;
1224 struct class_context
*ctx
;
1229 make_class_name_recursive
(stack
, ctx
->next
);
1231 /* Replace an anonymous context with the appropriate counter value. */
1232 if
(ctx
->name
== anonymous_context
)
1236 sprintf
(buf
, "%d", anonymous_count
);
1237 ctx
->name
= xstrdup
(buf
);
1240 obstack_grow
(stack
, ctx
->name
, strlen
(ctx
->name
));
1241 obstack_1grow
(stack
, '$');
1243 return ISDIGIT
(ctx
->name
[0]);
1246 /* Return a newly allocated string holding the name of the class. */
1252 struct obstack name_stack
;
1254 obstack_init
(&name_stack
);
1256 /* Duplicate the logic of parse.y:maybe_make_nested_class_name(). */
1257 last_was_digit
= make_class_name_recursive
(&name_stack
,
1258 current_class_context
->next
);
1260 if
(! last_was_digit
1262 && current_class_context
->name
!= anonymous_context
)
1266 sprintf
(buf
, "%d", anonymous_count
);
1267 obstack_grow
(&name_stack
, buf
, strlen
(buf
));
1268 obstack_1grow
(&name_stack
, '$');
1271 if
(current_class_context
->name
== anonymous_context
)
1275 sprintf
(buf
, "%d", anonymous_count
);
1276 current_class_context
->name
= xstrdup
(buf
);
1277 obstack_grow0
(&name_stack
, buf
, strlen
(buf
));
1280 obstack_grow0
(&name_stack
, current_class_context
->name
,
1281 strlen
(current_class_context
->name
));
1283 result
= xstrdup
(obstack_finish
(&name_stack
));
1284 obstack_free
(&name_stack
, NULL
);
1289 /* Actions defined here */
1292 report_class_declaration
(name
)
1295 extern
int flag_dump_class
, flag_list_filename
;
1297 push_class_context
(name
);
1298 if
(flag_dump_class
)
1300 char *name
= get_class_name
();
1302 if
(!previous_output
)
1304 if
(flag_list_filename
)
1305 fprintf
(out
, "%s: ", input_filename
);
1306 previous_output
= 1;
1310 fprintf
(out
, "%s.%s ", package_name
, name
);
1312 fprintf
(out
, "%s ", name
);
1319 report_main_declaration
(declarator
)
1320 struct method_declarator
*declarator
;
1322 extern
int flag_find_main
;
1325 && modifier_value
== 2
1326 && !strcmp
(declarator
->method_name
, "main")
1328 && declarator
->args
[0] == '['
1329 && (! strcmp
(declarator
->args
+1, "String")
1330 ||
! strcmp
(declarator
->args
+ 1, "java.lang.String"))
1331 && current_class_context
)
1333 if
(!previous_output
)
1335 char *name
= get_class_name
();
1337 fprintf
(out
, "%s.%s ", package_name
, name
);
1339 fprintf
(out
, "%s", name
);
1341 previous_output
= 1;
1349 extern
int flag_complexity
;
1350 if
(flag_complexity
)
1351 fprintf
(out
, "%s %d\n", input_filename
, complexity
);
1354 /* Reset global status used by the report functions. */
1356 void reset_report
()
1358 previous_output
= 0;
1359 package_name
= NULL
;
1360 current_class_context
= NULL
;
1366 const char *msg ATTRIBUTE_UNUSED
;
1368 fprintf
(stderr
, "%s: %d: %s\n", input_filename
, lineno
, msg
);