1 |
12 |
jlechner |
/* Language parser definitions for the GNU compiler for the Java(TM) language.
|
2 |
|
|
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
3 |
|
|
Free Software Foundation, Inc.
|
4 |
|
|
Contributed by Alexandre Petit-Bianco (apbianco@cygnus.com)
|
5 |
|
|
|
6 |
|
|
This file is part of GCC.
|
7 |
|
|
|
8 |
|
|
GCC is free software; you can redistribute it and/or modify
|
9 |
|
|
it under the terms of the GNU General Public License as published by
|
10 |
|
|
the Free Software Foundation; either version 2, or (at your option)
|
11 |
|
|
any later version.
|
12 |
|
|
|
13 |
|
|
GCC is distributed in the hope that it will be useful,
|
14 |
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15 |
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16 |
|
|
GNU General Public License for more details.
|
17 |
|
|
|
18 |
|
|
You should have received a copy of the GNU General Public License
|
19 |
|
|
along with GCC; see the file COPYING. If not, write to
|
20 |
|
|
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
21 |
|
|
Boston, MA 02110-1301, USA.
|
22 |
|
|
|
23 |
|
|
Java and all Java-based marks are trademarks or registered trademarks
|
24 |
|
|
of Sun Microsystems, Inc. in the United States and other countries.
|
25 |
|
|
The Free Software Foundation is independent of Sun Microsystems, Inc. */
|
26 |
|
|
|
27 |
|
|
#ifndef GCC_JAVA_PARSE_H
|
28 |
|
|
#define GCC_JAVA_PARSE_H
|
29 |
|
|
|
30 |
|
|
#include "lex.h"
|
31 |
|
|
|
32 |
|
|
/* Extern global variable declarations */
|
33 |
|
|
extern int java_error_count;
|
34 |
|
|
extern struct obstack temporary_obstack;
|
35 |
|
|
extern int quiet_flag;
|
36 |
|
|
|
37 |
|
|
#ifndef JC1_LITE
|
38 |
|
|
/* Function extern to java/ */
|
39 |
|
|
extern int int_fits_type_p (tree, tree);
|
40 |
|
|
extern tree stabilize_reference (tree);
|
41 |
|
|
#endif
|
42 |
|
|
|
43 |
|
|
/* Macros for verbose debug info */
|
44 |
|
|
#ifdef VERBOSE_SKELETON
|
45 |
|
|
#define RULE( rule ) printf ( "jv_yacc:%d: rule %s\n", lineno, rule )
|
46 |
|
|
#else
|
47 |
|
|
#define RULE( rule )
|
48 |
|
|
#endif
|
49 |
|
|
|
50 |
|
|
#ifdef VERBOSE_SKELETON
|
51 |
|
|
#undef SOURCE_FRONTEND_DEBUG
|
52 |
|
|
#define SOURCE_FRONTEND_DEBUG(X) \
|
53 |
|
|
{if (!quiet_flag) {printf ("* "); printf X; putchar ('\n');} }
|
54 |
|
|
#else
|
55 |
|
|
#define SOURCE_FRONTEND_DEBUG(X)
|
56 |
|
|
#endif
|
57 |
|
|
|
58 |
|
|
/* Macro for error recovering */
|
59 |
|
|
#ifdef YYDEBUG
|
60 |
|
|
#define RECOVERED \
|
61 |
|
|
{ if (!quiet_flag) {printf ("** Recovered\n");} }
|
62 |
|
|
#define DRECOVERED(s) \
|
63 |
|
|
{ if (!quiet_flag) {printf ("** Recovered (%s)\n", #s);}}
|
64 |
|
|
#else
|
65 |
|
|
#define RECOVERED
|
66 |
|
|
#define DRECOVERED(s)
|
67 |
|
|
#endif
|
68 |
|
|
|
69 |
|
|
#define DRECOVER(s) {yyerrok; DRECOVERED(s);}
|
70 |
|
|
#define RECOVER {yyerrok; RECOVERED;}
|
71 |
|
|
|
72 |
|
|
#define YYERROR_NOW ctxp->java_error_flag = 1
|
73 |
|
|
#define YYNOT_TWICE if (ctxp->prevent_ese != input_line)
|
74 |
|
|
|
75 |
|
|
/* Accepted modifiers */
|
76 |
|
|
#define CLASS_MODIFIERS ACC_PUBLIC|ACC_ABSTRACT|ACC_FINAL|ACC_STRICT
|
77 |
|
|
#define FIELD_MODIFIERS ACC_PUBLIC|ACC_PROTECTED|ACC_PRIVATE|ACC_FINAL| \
|
78 |
|
|
ACC_STATIC|ACC_TRANSIENT|ACC_VOLATILE
|
79 |
|
|
#define METHOD_MODIFIERS ACC_PUBLIC|ACC_PROTECTED|ACC_PRIVATE|ACC_ABSTRACT| \
|
80 |
|
|
ACC_STATIC|ACC_FINAL|ACC_SYNCHRONIZED|ACC_NATIVE| \
|
81 |
|
|
ACC_STRICT
|
82 |
|
|
#define INTERFACE_MODIFIERS ACC_PUBLIC|ACC_ABSTRACT|ACC_STRICT
|
83 |
|
|
#define INTERFACE_INNER_MODIFIERS ACC_PUBLIC|ACC_PROTECTED|ACC_ABSTRACT| \
|
84 |
|
|
ACC_STATIC|ACC_PRIVATE
|
85 |
|
|
#define INTERFACE_METHOD_MODIFIERS ACC_PUBLIC|ACC_ABSTRACT
|
86 |
|
|
#define INTERFACE_FIELD_MODIFIERS ACC_PUBLIC|ACC_STATIC|ACC_FINAL
|
87 |
|
|
|
88 |
|
|
/* Getting a modifier WFL */
|
89 |
|
|
#define MODIFIER_WFL(M) (ctxp->modifier_ctx [(M) - PUBLIC_TK])
|
90 |
|
|
|
91 |
|
|
/* Check on modifiers */
|
92 |
|
|
#ifdef USE_MAPPED_LOCATION
|
93 |
|
|
#define THIS_MODIFIER_ONLY(f, m, v, count, l) \
|
94 |
|
|
if ((f) & (m)) \
|
95 |
|
|
{ \
|
96 |
|
|
tree node = MODIFIER_WFL (v); \
|
97 |
|
|
if (!l) \
|
98 |
|
|
l = node; \
|
99 |
|
|
else \
|
100 |
|
|
{ \
|
101 |
|
|
expanded_location lloc = expand_location (EXPR_LOCATION (l)); \
|
102 |
|
|
expanded_location nloc = expand_location (EXPR_LOCATION (node)); \
|
103 |
|
|
if (nloc.column > lloc.column || nloc.line > lloc.line) \
|
104 |
|
|
l = node; \
|
105 |
|
|
} \
|
106 |
|
|
count++; \
|
107 |
|
|
}
|
108 |
|
|
#else
|
109 |
|
|
#define THIS_MODIFIER_ONLY(f, m, v, count, l) \
|
110 |
|
|
if ((f) & (m)) \
|
111 |
|
|
{ \
|
112 |
|
|
tree node = MODIFIER_WFL (v); \
|
113 |
|
|
if ((l) \
|
114 |
|
|
&& ((EXPR_WFL_COLNO (node) > EXPR_WFL_COLNO (l)) \
|
115 |
|
|
|| (EXPR_WFL_LINENO (node) > EXPR_WFL_LINENO (l)))) \
|
116 |
|
|
l = node; \
|
117 |
|
|
else if (!(l)) \
|
118 |
|
|
l = node; \
|
119 |
|
|
count++; \
|
120 |
|
|
}
|
121 |
|
|
#endif
|
122 |
|
|
|
123 |
|
|
#ifdef ATTRIBUTE_GCC_DIAG
|
124 |
|
|
extern void parse_error_context (tree cl, const char *gmsgid, ...) ATTRIBUTE_GCC_DIAG(2,3);
|
125 |
|
|
#endif
|
126 |
|
|
|
127 |
|
|
#define ABSTRACT_CHECK(FLAG, V, CL, S) \
|
128 |
|
|
if ((FLAG) & (V)) \
|
129 |
|
|
parse_error_context ((CL), "%s method can't be abstract", (S));
|
130 |
|
|
|
131 |
|
|
#define JCONSTRUCTOR_CHECK(FLAG, V, CL, S) \
|
132 |
|
|
if ((FLAG) & (V)) \
|
133 |
|
|
parse_error_context ((CL), "Constructor can't be %s", (S)); \
|
134 |
|
|
|
135 |
|
|
/* Misc. */
|
136 |
|
|
#define exit_java_complete_class() \
|
137 |
|
|
{ \
|
138 |
|
|
return; \
|
139 |
|
|
}
|
140 |
|
|
|
141 |
|
|
#define CLASS_OR_INTERFACE(decl, s1, s2) \
|
142 |
|
|
(decl ? \
|
143 |
|
|
((get_access_flags_from_decl (TYPE_NAME (TREE_TYPE (decl))) \
|
144 |
|
|
& ACC_INTERFACE) ? \
|
145 |
|
|
s2 : s1) : ((s1 [0]=='S'|| s1 [0]=='s') ? \
|
146 |
|
|
(s1 [0]=='S' ? "Supertype" : "supertype") : \
|
147 |
|
|
(s1 [0] > 'A' ? "Type" : "type")))
|
148 |
|
|
|
149 |
|
|
#define GET_REAL_TYPE(TYPE) \
|
150 |
|
|
(TREE_CODE (TYPE) == TREE_LIST ? TREE_PURPOSE (TYPE) : TYPE)
|
151 |
|
|
|
152 |
|
|
/* Get TYPE name string, regardless whether TYPE is a class or an
|
153 |
|
|
array. */
|
154 |
|
|
#define GET_TYPE_NAME(TYPE) \
|
155 |
|
|
(TREE_CODE (TYPE_NAME (TYPE)) == IDENTIFIER_NODE ? \
|
156 |
|
|
IDENTIFIER_POINTER (TYPE_NAME (TYPE)) : \
|
157 |
|
|
IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (TYPE))))
|
158 |
|
|
|
159 |
|
|
/* Pedantic warning on obsolete modifiers. Note: when cl is NULL,
|
160 |
|
|
flags was set artificially, such as for an interface method. */
|
161 |
|
|
#define OBSOLETE_MODIFIER_WARNING(cl, flags, __modifier, arg) \
|
162 |
|
|
{ \
|
163 |
|
|
if (flag_redundant && (cl) && ((flags) & (__modifier))) \
|
164 |
|
|
parse_warning_context (cl, \
|
165 |
|
|
"Discouraged redundant use of %qs modifier in declaration of %s", \
|
166 |
|
|
java_accstring_lookup (__modifier), arg); \
|
167 |
|
|
}
|
168 |
|
|
#define OBSOLETE_MODIFIER_WARNING2(cl, flags, __modifier, arg1, arg2) \
|
169 |
|
|
{ \
|
170 |
|
|
if (flag_redundant && (cl) && ((flags) & (__modifier))) \
|
171 |
|
|
parse_warning_context (cl, \
|
172 |
|
|
"Discouraged redundant use of %qs modifier in declaration of %s %qs", \
|
173 |
|
|
java_accstring_lookup (__modifier), arg1, arg2);\
|
174 |
|
|
}
|
175 |
|
|
|
176 |
|
|
/* Quickly build a temporary pointer on hypothetical type NAME. */
|
177 |
|
|
#define BUILD_PTR_FROM_NAME(ptr, name) \
|
178 |
|
|
do { \
|
179 |
|
|
ptr = make_node (POINTER_TYPE); \
|
180 |
|
|
TYPE_NAME (ptr) = name; \
|
181 |
|
|
} while (0)
|
182 |
|
|
|
183 |
|
|
#define INCOMPLETE_TYPE_P(NODE) \
|
184 |
|
|
((TREE_CODE (NODE) == POINTER_TYPE) \
|
185 |
|
|
&& !TREE_TYPE (NODE) \
|
186 |
|
|
&& TREE_CODE (TYPE_NAME (NODE)) == IDENTIFIER_NODE)
|
187 |
|
|
|
188 |
|
|
#ifndef USE_MAPPED_LOCATION
|
189 |
|
|
/* Set the EMIT_LINE_NOTE flag of a EXPR_WLF to 1 if debug information
|
190 |
|
|
are requested. Works in the context of a parser rule. */
|
191 |
|
|
#define JAVA_MAYBE_GENERATE_DEBUG_INFO(node) \
|
192 |
|
|
do {if (debug_info_level != DINFO_LEVEL_NONE) \
|
193 |
|
|
EXPR_WFL_EMIT_LINE_NOTE (node) = 1; } while (0)
|
194 |
|
|
#endif
|
195 |
|
|
|
196 |
|
|
/* Types classification, according to the JLS, section 4.2 */
|
197 |
|
|
#define JFLOAT_TYPE_P(TYPE) (TYPE && TREE_CODE ((TYPE)) == REAL_TYPE)
|
198 |
|
|
#define JINTEGRAL_TYPE_P(TYPE) ((TYPE) \
|
199 |
|
|
&& (TREE_CODE ((TYPE)) == INTEGER_TYPE \
|
200 |
|
|
|| TREE_CODE ((TYPE)) == CHAR_TYPE))
|
201 |
|
|
#define JNUMERIC_TYPE_P(TYPE) ((TYPE) \
|
202 |
|
|
&& (JFLOAT_TYPE_P ((TYPE)) \
|
203 |
|
|
|| JINTEGRAL_TYPE_P ((TYPE))))
|
204 |
|
|
#define JPRIMITIVE_TYPE_P(TYPE) ((TYPE) \
|
205 |
|
|
&& (JNUMERIC_TYPE_P ((TYPE)) \
|
206 |
|
|
|| TREE_CODE ((TYPE)) == BOOLEAN_TYPE))
|
207 |
|
|
|
208 |
|
|
#define JBSC_TYPE_P(TYPE) ((TYPE) && (((TYPE) == byte_type_node) \
|
209 |
|
|
|| ((TYPE) == short_type_node) \
|
210 |
|
|
|| ((TYPE) == char_type_node)))
|
211 |
|
|
|
212 |
|
|
/* Not defined in the LRM */
|
213 |
|
|
#define JSTRING_TYPE_P(TYPE) ((TYPE) \
|
214 |
|
|
&& ((TYPE) == string_type_node || \
|
215 |
|
|
(TREE_CODE (TYPE) == POINTER_TYPE && \
|
216 |
|
|
TREE_TYPE (TYPE) == string_type_node)))
|
217 |
|
|
#define JSTRING_P(NODE) ((NODE) \
|
218 |
|
|
&& (TREE_CODE (NODE) == STRING_CST \
|
219 |
|
|
|| IS_CRAFTED_STRING_BUFFER_P (NODE) \
|
220 |
|
|
|| JSTRING_TYPE_P (TREE_TYPE (NODE))))
|
221 |
|
|
|
222 |
|
|
#define JREFERENCE_TYPE_P(TYPE) ((TYPE) \
|
223 |
|
|
&& (TREE_CODE (TYPE) == RECORD_TYPE \
|
224 |
|
|
|| (TREE_CODE (TYPE) == POINTER_TYPE \
|
225 |
|
|
&& TREE_CODE (TREE_TYPE (TYPE)) == \
|
226 |
|
|
RECORD_TYPE)))
|
227 |
|
|
#define JNULLP_TYPE_P(TYPE) ((TYPE) && (TREE_CODE (TYPE) == POINTER_TYPE) \
|
228 |
|
|
&& (TYPE) == TREE_TYPE (null_pointer_node))
|
229 |
|
|
|
230 |
|
|
/* Other predicates */
|
231 |
|
|
#define JDECL_P(NODE) (NODE && (TREE_CODE (NODE) == PARM_DECL \
|
232 |
|
|
|| TREE_CODE (NODE) == VAR_DECL \
|
233 |
|
|
|| TREE_CODE (NODE) == FIELD_DECL))
|
234 |
|
|
|
235 |
|
|
#define TYPE_INTERFACE_P(TYPE) \
|
236 |
|
|
(CLASS_P (TYPE) && CLASS_INTERFACE (TYPE_NAME (TYPE)))
|
237 |
|
|
|
238 |
|
|
#define TYPE_CLASS_P(TYPE) (CLASS_P (TYPE) \
|
239 |
|
|
&& !CLASS_INTERFACE (TYPE_NAME (TYPE)))
|
240 |
|
|
|
241 |
|
|
/* Identifier business related to 1.1 language extensions. */
|
242 |
|
|
|
243 |
|
|
#define IDENTIFIER_INNER_CLASS_OUTER_FIELD_ACCESS(NODE) \
|
244 |
|
|
(TREE_CODE (NODE) == IDENTIFIER_NODE && \
|
245 |
|
|
IDENTIFIER_LENGTH (NODE) >= 8 && \
|
246 |
|
|
IDENTIFIER_POINTER (NODE)[7] != '0')
|
247 |
|
|
|
248 |
|
|
/* Build the string val$<O> and store it into N. The is used to
|
249 |
|
|
construct the name of inner class hidden fields used to alias outer
|
250 |
|
|
scope local variables. */
|
251 |
|
|
#define MANGLE_OUTER_LOCAL_VARIABLE_NAME(N, O) \
|
252 |
|
|
{ \
|
253 |
|
|
char *mangled_name; \
|
254 |
|
|
obstack_grow (&temporary_obstack, "val$", 4); \
|
255 |
|
|
obstack_grow (&temporary_obstack, \
|
256 |
|
|
IDENTIFIER_POINTER ((O)), IDENTIFIER_LENGTH ((O))); \
|
257 |
|
|
obstack_1grow (&temporary_obstack, '\0'); \
|
258 |
|
|
mangled_name = obstack_finish (&temporary_obstack); \
|
259 |
|
|
(N) = get_identifier (mangled_name); \
|
260 |
|
|
obstack_free (&temporary_obstack, mangled_name); \
|
261 |
|
|
}
|
262 |
|
|
|
263 |
|
|
/* Build the string parm$<O> and store in into the identifier N. This
|
264 |
|
|
is used to construct the name of hidden parameters used to
|
265 |
|
|
initialize outer scope aliases. */
|
266 |
|
|
#define MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_ID(N, O) \
|
267 |
|
|
{ \
|
268 |
|
|
char *mangled_name; \
|
269 |
|
|
obstack_grow (&temporary_obstack, "parm$", 5); \
|
270 |
|
|
obstack_grow (&temporary_obstack, \
|
271 |
|
|
IDENTIFIER_POINTER ((O)), IDENTIFIER_LENGTH ((O))); \
|
272 |
|
|
obstack_1grow (&temporary_obstack, '\0'); \
|
273 |
|
|
mangled_name = obstack_finish (&temporary_obstack); \
|
274 |
|
|
(N) = get_identifier (mangled_name); \
|
275 |
|
|
obstack_free (&temporary_obstack, mangled_name); \
|
276 |
|
|
}
|
277 |
|
|
|
278 |
|
|
#define MANGLE_ALIAS_INITIALIZER_PARAMETER_NAME_STR(N, S) \
|
279 |
|
|
{ \
|
280 |
|
|
char *mangled_name; \
|
281 |
|
|
obstack_grow (&temporary_obstack, "parm$", 5); \
|
282 |
|
|
obstack_grow (&temporary_obstack, (S), strlen ((S))); \
|
283 |
|
|
obstack_1grow (&temporary_obstack, '\0'); \
|
284 |
|
|
mangled_name = obstack_finish (&temporary_obstack); \
|
285 |
|
|
(N) = get_identifier (mangled_name); \
|
286 |
|
|
obstack_free (&temporary_obstack, mangled_name); \
|
287 |
|
|
}
|
288 |
|
|
|
289 |
|
|
/* Skip THIS and artificial parameters found in function decl M and
|
290 |
|
|
assign the result to C. We don't do that for $finit$, since it's
|
291 |
|
|
knowingly called with artificial parms. */
|
292 |
|
|
#define SKIP_THIS_AND_ARTIFICIAL_PARMS(C,M) \
|
293 |
|
|
{ \
|
294 |
|
|
int i; \
|
295 |
|
|
(C) = TYPE_ARG_TYPES (TREE_TYPE ((M))); \
|
296 |
|
|
if (!METHOD_STATIC ((M))) \
|
297 |
|
|
(C) = TREE_CHAIN (C); \
|
298 |
|
|
if (DECL_CONSTRUCTOR_P ((M)) \
|
299 |
|
|
&& PURE_INNER_CLASS_TYPE_P (DECL_CONTEXT ((M)))) \
|
300 |
|
|
(C) = TREE_CHAIN (C); \
|
301 |
|
|
if (!DECL_FINIT_P ((M))) \
|
302 |
|
|
for (i = DECL_FUNCTION_NAP ((M)); i; i--) \
|
303 |
|
|
(C) = TREE_CHAIN (C); \
|
304 |
|
|
}
|
305 |
|
|
|
306 |
|
|
/* Mark final parameters in method M, by comparison of the argument
|
307 |
|
|
list L. This macro is used to set the flag once the method has been
|
308 |
|
|
build. */
|
309 |
|
|
#define MARK_FINAL_PARMS(M, L) \
|
310 |
|
|
{ \
|
311 |
|
|
tree current = TYPE_ARG_TYPES (TREE_TYPE ((M))); \
|
312 |
|
|
tree list = (L); \
|
313 |
|
|
if (!METHOD_STATIC ((M))) \
|
314 |
|
|
current = TREE_CHAIN (current); \
|
315 |
|
|
for (; current != end_params_node; \
|
316 |
|
|
current = TREE_CHAIN (current), list = TREE_CHAIN (list)) \
|
317 |
|
|
ARG_FINAL_P (current) = ARG_FINAL_P (list); \
|
318 |
|
|
if (current != list) \
|
319 |
|
|
abort (); \
|
320 |
|
|
}
|
321 |
|
|
|
322 |
|
|
/* Reset the ARG_FINAL_P that might have been set in method M args. */
|
323 |
|
|
#define UNMARK_FINAL_PARMS(M) \
|
324 |
|
|
{ \
|
325 |
|
|
tree current; \
|
326 |
|
|
for (current = TYPE_ARG_TYPES (TREE_TYPE ((M))); \
|
327 |
|
|
current != end_params_node; current = TREE_CHAIN (current)) \
|
328 |
|
|
ARG_FINAL_P (current) = 0; \
|
329 |
|
|
}
|
330 |
|
|
|
331 |
|
|
/* Reverse a crafted parameter list as required. */
|
332 |
|
|
#define CRAFTED_PARAM_LIST_FIXUP(P) \
|
333 |
|
|
{ \
|
334 |
|
|
if ((P)) \
|
335 |
|
|
{ \
|
336 |
|
|
tree last = (P); \
|
337 |
|
|
(P) = nreverse (P); \
|
338 |
|
|
TREE_CHAIN (last) = end_params_node; \
|
339 |
|
|
} \
|
340 |
|
|
else \
|
341 |
|
|
(P) = end_params_node; \
|
342 |
|
|
}
|
343 |
|
|
|
344 |
|
|
/* Modes governing the creation of a alias initializer parameter
|
345 |
|
|
lists. AIPL stands for Alias Initializer Parameter List. */
|
346 |
|
|
enum {
|
347 |
|
|
AIPL_FUNCTION_CREATION, /* Suitable for artificial method creation */
|
348 |
|
|
AIPL_FUNCTION_DECLARATION, /* Suitable for declared methods */
|
349 |
|
|
AIPL_FUNCTION_CTOR_INVOCATION, /* Invocation of constructors */
|
350 |
|
|
AIPL_FUNCTION_FINIT_INVOCATION /* Invocation of $finit$ */
|
351 |
|
|
};
|
352 |
|
|
|
353 |
|
|
/* Standard error messages */
|
354 |
|
|
#define ERROR_CANT_CONVERT_TO_BOOLEAN(OPERATOR, NODE, TYPE) \
|
355 |
|
|
parse_error_context ((OPERATOR), \
|
356 |
|
|
"Incompatible type for %qs. Can't convert %qs to boolean", \
|
357 |
|
|
operator_string ((NODE)), lang_printable_name ((TYPE),0))
|
358 |
|
|
|
359 |
|
|
#define ERROR_CANT_CONVERT_TO_NUMERIC(OPERATOR, NODE, TYPE) \
|
360 |
|
|
parse_error_context ((OPERATOR), \
|
361 |
|
|
"Incompatible type for %qs. Can't convert %qs to numeric type", \
|
362 |
|
|
operator_string ((NODE)), lang_printable_name ((TYPE), 0))
|
363 |
|
|
|
364 |
|
|
#define ERROR_CAST_NEEDED_TO_INTEGRAL(OPERATOR, NODE, TYPE) \
|
365 |
|
|
do { \
|
366 |
|
|
tree _operator = (OPERATOR), _node = (NODE), _type = (TYPE); \
|
367 |
|
|
if (JPRIMITIVE_TYPE_P (_type)) \
|
368 |
|
|
parse_error_context (_operator, \
|
369 |
|
|
"Incompatible type for %qs. Explicit cast needed to convert %qs to integral",\
|
370 |
|
|
operator_string(_node), \
|
371 |
|
|
lang_printable_name (_type, 0)); \
|
372 |
|
|
else \
|
373 |
|
|
parse_error_context (_operator, \
|
374 |
|
|
"Incompatible type for %qs. Can't convert %qs to integral", \
|
375 |
|
|
operator_string(_node), \
|
376 |
|
|
lang_printable_name (_type, 0)); \
|
377 |
|
|
} while (0)
|
378 |
|
|
|
379 |
|
|
#define ERROR_VARIABLE_NOT_INITIALIZED(WFL, V) \
|
380 |
|
|
parse_error_context \
|
381 |
|
|
((WFL), "Variable %qs may not have been initialized", \
|
382 |
|
|
IDENTIFIER_POINTER (V))
|
383 |
|
|
|
384 |
|
|
/* Definition for loop handling. This is Java's own definition of a
|
385 |
|
|
loop body. See parse.y for documentation. It's valid once you hold
|
386 |
|
|
a loop's body (LOOP_EXPR_BODY) */
|
387 |
|
|
|
388 |
|
|
/* The loop main block is the one hold the condition and the loop body */
|
389 |
|
|
#define LOOP_EXPR_BODY_MAIN_BLOCK(NODE) TREE_OPERAND (NODE, 0)
|
390 |
|
|
/* And then there is the loop update block */
|
391 |
|
|
#define LOOP_EXPR_BODY_UPDATE_BLOCK(NODE) TREE_OPERAND (NODE, 1)
|
392 |
|
|
|
393 |
|
|
/* Inside the loop main block, there is the loop condition and the
|
394 |
|
|
loop body. They may be reversed if the loop being described is a
|
395 |
|
|
do-while loop. NOTE: if you use a WFL around the EXIT_EXPR so you
|
396 |
|
|
can issue debug info for it, the EXIT_EXPR will be one operand
|
397 |
|
|
further. */
|
398 |
|
|
#define LOOP_EXPR_BODY_CONDITION_EXPR(NODE, R) \
|
399 |
|
|
TREE_OPERAND (LOOP_EXPR_BODY_MAIN_BLOCK (NODE), (R ? 1 : 0))
|
400 |
|
|
|
401 |
|
|
/* Here is the labeled block the loop real body is encapsulated in */
|
402 |
|
|
#define LOOP_EXPR_BODY_LABELED_BODY(NODE, R) \
|
403 |
|
|
TREE_OPERAND (LOOP_EXPR_BODY_MAIN_BLOCK (NODE), (R ? 0 : 1))
|
404 |
|
|
/* And here is the loop's real body */
|
405 |
|
|
#define LOOP_EXPR_BODY_BODY_EXPR(NODE, R) \
|
406 |
|
|
LABELED_BLOCK_BODY (LOOP_EXPR_BODY_LABELED_BODY(NODE, R))
|
407 |
|
|
|
408 |
|
|
#define PUSH_LABELED_BLOCK(B) \
|
409 |
|
|
{ \
|
410 |
|
|
TREE_CHAIN (B) = ctxp->current_labeled_block; \
|
411 |
|
|
ctxp->current_labeled_block = (B); \
|
412 |
|
|
}
|
413 |
|
|
#define POP_LABELED_BLOCK() \
|
414 |
|
|
ctxp->current_labeled_block = TREE_CHAIN (ctxp->current_labeled_block)
|
415 |
|
|
|
416 |
|
|
#define PUSH_LOOP(L) \
|
417 |
|
|
{ \
|
418 |
|
|
TREE_CHAIN (L) = ctxp->current_loop; \
|
419 |
|
|
ctxp->current_loop = (L); \
|
420 |
|
|
}
|
421 |
|
|
#define POP_LOOP() ctxp->current_loop = TREE_CHAIN (ctxp->current_loop)
|
422 |
|
|
|
423 |
|
|
#define PUSH_EXCEPTIONS(E) \
|
424 |
|
|
currently_caught_type_list = \
|
425 |
|
|
tree_cons (NULL_TREE, (E), currently_caught_type_list);
|
426 |
|
|
|
427 |
|
|
#define POP_EXCEPTIONS() \
|
428 |
|
|
currently_caught_type_list = TREE_CHAIN (currently_caught_type_list)
|
429 |
|
|
|
430 |
|
|
/* Check that we're inside a try block. */
|
431 |
|
|
#define IN_TRY_BLOCK_P() \
|
432 |
|
|
(currently_caught_type_list \
|
433 |
|
|
&& ((TREE_VALUE (currently_caught_type_list) != \
|
434 |
|
|
DECL_FUNCTION_THROWS (current_function_decl)) \
|
435 |
|
|
|| TREE_CHAIN (currently_caught_type_list)))
|
436 |
|
|
|
437 |
|
|
/* Check that we have exceptions in E. */
|
438 |
|
|
#define EXCEPTIONS_P(E) ((E) ? TREE_VALUE (E) : NULL_TREE)
|
439 |
|
|
|
440 |
|
|
/* Anonymous array access */
|
441 |
|
|
#define ANONYMOUS_ARRAY_BASE_TYPE(N) TREE_OPERAND ((N), 0)
|
442 |
|
|
#define ANONYMOUS_ARRAY_DIMS_SIG(N) TREE_OPERAND ((N), 1)
|
443 |
|
|
#define ANONYMOUS_ARRAY_INITIALIZER(N) TREE_OPERAND ((N), 2)
|
444 |
|
|
|
445 |
|
|
/* Invocation modes, as returned by invocation_mode (). */
|
446 |
|
|
enum {
|
447 |
|
|
INVOKE_STATIC,
|
448 |
|
|
INVOKE_NONVIRTUAL,
|
449 |
|
|
INVOKE_SUPER,
|
450 |
|
|
INVOKE_INTERFACE,
|
451 |
|
|
INVOKE_VIRTUAL
|
452 |
|
|
};
|
453 |
|
|
|
454 |
|
|
/* Unresolved type identifiers handling. When we process the source
|
455 |
|
|
code, we blindly accept an unknown type identifier and try to
|
456 |
|
|
resolve it later. When an unknown type identifier is encountered
|
457 |
|
|
and used, we record in a struct jdep element what the incomplete
|
458 |
|
|
type is and what it should patch. Later, java_complete_class will
|
459 |
|
|
process all classes known to have unresolved type
|
460 |
|
|
dependencies. Within each of these classes, this routine will
|
461 |
|
|
process unresolved type dependencies (JDEP_TO_RESOLVE), patch what
|
462 |
|
|
needs to be patched in the dependent tree node (JDEP_GET_PATCH,
|
463 |
|
|
JDEP_APPLY_PATCH) and perform other actions dictated by the context
|
464 |
|
|
of the patch (JDEP_KIND). The ideas are: we patch only what needs
|
465 |
|
|
to be patched, and with java_complete_class called at the right
|
466 |
|
|
time, we will start processing incomplete function bodies tree
|
467 |
|
|
nodes with everything external to function's bodies already
|
468 |
|
|
completed, it makes things much simpler. */
|
469 |
|
|
|
470 |
|
|
enum jdep_code {
|
471 |
|
|
JDEP_NO_PATCH, /* Must be first */
|
472 |
|
|
JDEP_SUPER, /* Patch the type of one type
|
473 |
|
|
supertype. Requires some check
|
474 |
|
|
before it's done */
|
475 |
|
|
JDEP_FIELD, /* Patch the type of a class field */
|
476 |
|
|
|
477 |
|
|
/* JDEP_{METHOD,METHOD_RETURN,METHOD_END} to be kept in order */
|
478 |
|
|
JDEP_METHOD, /* Mark the beginning of the patching
|
479 |
|
|
of a method declaration, including
|
480 |
|
|
it's arguments */
|
481 |
|
|
JDEP_METHOD_RETURN, /* Mark the beginning of the patching
|
482 |
|
|
of a method declaration. Arguments
|
483 |
|
|
aren't patched, only the returned
|
484 |
|
|
type is */
|
485 |
|
|
JDEP_METHOD_END, /* Mark the end of the patching of a
|
486 |
|
|
method declaration. It indicates
|
487 |
|
|
that it's time to compute and
|
488 |
|
|
install a new signature */
|
489 |
|
|
|
490 |
|
|
JDEP_INTERFACE, /* Patch the type of a Class/interface
|
491 |
|
|
extension */
|
492 |
|
|
JDEP_VARIABLE, /* Patch the type of a variable declaration */
|
493 |
|
|
JDEP_PARM, /* Patch the type of a parm declaration */
|
494 |
|
|
JDEP_TYPE, /* Patch a random tree node type,
|
495 |
|
|
without the need for any specific
|
496 |
|
|
actions */
|
497 |
|
|
JDEP_EXCEPTION, /* Patch exceptions specified by `throws' */
|
498 |
|
|
JDEP_ANONYMOUS /* Patch anonymous classes
|
499 |
|
|
(implementation or extension.) */
|
500 |
|
|
|
501 |
|
|
};
|
502 |
|
|
|
503 |
|
|
typedef struct _jdep {
|
504 |
|
|
ENUM_BITFIELD(jdep_code) kind : 8; /* Type of patch */
|
505 |
|
|
|
506 |
|
|
unsigned int flag0 : 1; /* Some flags */
|
507 |
|
|
tree decl; /* Tied decl/or WFL */
|
508 |
|
|
tree solv; /* What to solve */
|
509 |
|
|
tree wfl; /* Where thing to resolve where found */
|
510 |
|
|
tree misc; /* Miscellaneous info (optional). */
|
511 |
|
|
tree enclosing; /* The enclosing (current) class */
|
512 |
|
|
tree *patch; /* Address of a location to patch */
|
513 |
|
|
struct _jdep *next; /* Linked list */
|
514 |
|
|
} jdep;
|
515 |
|
|
|
516 |
|
|
|
517 |
|
|
#define JDEP_DECL(J) ((J)->decl)
|
518 |
|
|
#define JDEP_DECL_WFL(J) ((J)->decl)
|
519 |
|
|
#define JDEP_KIND(J) ((J)->kind)
|
520 |
|
|
#define JDEP_WFL(J) ((J)->wfl)
|
521 |
|
|
#define JDEP_MISC(J) ((J)->misc)
|
522 |
|
|
#define JDEP_ENCLOSING(J) ((J)->enclosing)
|
523 |
|
|
#define JDEP_CLASS(J) ((J)->class)
|
524 |
|
|
#define JDEP_APPLY_PATCH(J,P) (*(J)->patch = (P))
|
525 |
|
|
#define JDEP_GET_PATCH(J) ((J)->patch)
|
526 |
|
|
#define JDEP_CHAIN(J) ((J)->next)
|
527 |
|
|
#define JDEP_TO_RESOLVE(J) ((J)->solv)
|
528 |
|
|
#define JDEP_RESOLVED_DECL(J) ((J)->solv)
|
529 |
|
|
#define JDEP_RESOLVED(J, D) ((J)->solv = D)
|
530 |
|
|
#define JDEP_RESOLVED_P(J) \
|
531 |
|
|
(!(J)->solv || TREE_CODE ((J)->solv) != POINTER_TYPE)
|
532 |
|
|
|
533 |
|
|
struct jdeplist_s {
|
534 |
|
|
jdep *first;
|
535 |
|
|
jdep *last;
|
536 |
|
|
struct jdeplist_s *next;
|
537 |
|
|
};
|
538 |
|
|
typedef struct jdeplist_s jdeplist;
|
539 |
|
|
|
540 |
|
|
#define CLASSD_FIRST(CD) ((CD)->first)
|
541 |
|
|
#define CLASSD_LAST(CD) ((CD)->last)
|
542 |
|
|
#define CLASSD_CHAIN(CD) ((CD)->next)
|
543 |
|
|
|
544 |
|
|
#define JDEP_INSERT(L,J) \
|
545 |
|
|
{ \
|
546 |
|
|
if (!(L)->first) \
|
547 |
|
|
(L)->last = (L)->first = (J); \
|
548 |
|
|
else \
|
549 |
|
|
{ \
|
550 |
|
|
JDEP_CHAIN ((L)->last) = (J); \
|
551 |
|
|
(L)->last = (J); \
|
552 |
|
|
} \
|
553 |
|
|
}
|
554 |
|
|
|
555 |
|
|
/* if TYPE can't be resolved, obtain something suitable for its
|
556 |
|
|
resolution (TYPE is saved in SAVE before being changed). and set
|
557 |
|
|
CHAIN to 1. Otherwise, type is set to something usable. CHAIN is
|
558 |
|
|
usually used to determine that a new DEP must be installed on TYPE.
|
559 |
|
|
Note that when compiling java.lang.Object, references to Object are
|
560 |
|
|
java.lang.Object. */
|
561 |
|
|
#define SET_TYPE_FOR_RESOLUTION(TYPE, SAVE, CHAIN) \
|
562 |
|
|
{ \
|
563 |
|
|
tree _returned_type; \
|
564 |
|
|
(CHAIN) = 0; \
|
565 |
|
|
if (TREE_TYPE (GET_CPC ()) == object_type_node \
|
566 |
|
|
&& TREE_CODE (TYPE) == EXPR_WITH_FILE_LOCATION \
|
567 |
|
|
&& EXPR_WFL_NODE (TYPE) == unqualified_object_id_node) \
|
568 |
|
|
(TYPE) = object_type_node; \
|
569 |
|
|
else \
|
570 |
|
|
{ \
|
571 |
|
|
if (unresolved_type_p (type, &_returned_type)) \
|
572 |
|
|
{ \
|
573 |
|
|
if (_returned_type) \
|
574 |
|
|
(TYPE) = _returned_type; \
|
575 |
|
|
else \
|
576 |
|
|
{ \
|
577 |
|
|
tree _type; \
|
578 |
|
|
WFL_STRIP_BRACKET (_type, TYPE); \
|
579 |
|
|
(SAVE) = (_type); \
|
580 |
|
|
(TYPE) = obtain_incomplete_type (TYPE); \
|
581 |
|
|
CHAIN = 1; \
|
582 |
|
|
} \
|
583 |
|
|
} \
|
584 |
|
|
} \
|
585 |
|
|
}
|
586 |
|
|
|
587 |
|
|
#define WFL_STRIP_BRACKET(TARGET, TYPE) \
|
588 |
|
|
{ \
|
589 |
|
|
tree __type = (TYPE); \
|
590 |
|
|
if (TYPE && TREE_CODE (TYPE) == EXPR_WITH_FILE_LOCATION) \
|
591 |
|
|
{ \
|
592 |
|
|
tree _node; \
|
593 |
|
|
if (build_type_name_from_array_name (EXPR_WFL_NODE (TYPE), &_node)) \
|
594 |
|
|
{ \
|
595 |
|
|
tree _new = copy_node (TYPE); \
|
596 |
|
|
EXPR_WFL_NODE (_new) = _node; \
|
597 |
|
|
__type = _new; \
|
598 |
|
|
} \
|
599 |
|
|
} \
|
600 |
|
|
(TARGET) = __type; \
|
601 |
|
|
}
|
602 |
|
|
|
603 |
|
|
/* If NAME contains one or more trailing []s, NAMELEN will be the
|
604 |
|
|
adjusted to be the index of the last non bracket character in
|
605 |
|
|
NAME. ARRAY_DIMS will contain the number of []s found. */
|
606 |
|
|
|
607 |
|
|
#define STRING_STRIP_BRACKETS(NAME, NAMELEN, ARRAY_DIMS) \
|
608 |
|
|
{ \
|
609 |
|
|
ARRAY_DIMS = 0; \
|
610 |
|
|
while (NAMELEN >= 2 && (NAME)[NAMELEN - 1] == ']') \
|
611 |
|
|
{ \
|
612 |
|
|
NAMELEN -= 2; \
|
613 |
|
|
(ARRAY_DIMS)++; \
|
614 |
|
|
} \
|
615 |
|
|
}
|
616 |
|
|
|
617 |
|
|
/* Promote a type if it won't be registered as a patch */
|
618 |
|
|
#define PROMOTE_RECORD_IF_COMPLETE(TYPE, IS_INCOMPLETE) \
|
619 |
|
|
{ \
|
620 |
|
|
if (!(IS_INCOMPLETE) && TREE_CODE (TYPE) == RECORD_TYPE) \
|
621 |
|
|
(TYPE) = promote_type (TYPE); \
|
622 |
|
|
}
|
623 |
|
|
|
624 |
|
|
/* Insert a DECL in the current block */
|
625 |
|
|
#define BLOCK_CHAIN_DECL(NODE) \
|
626 |
|
|
{ \
|
627 |
|
|
TREE_CHAIN ((NODE)) = \
|
628 |
|
|
BLOCK_EXPR_DECLS (GET_CURRENT_BLOCK (current_function_decl)); \
|
629 |
|
|
BLOCK_EXPR_DECLS (GET_CURRENT_BLOCK (current_function_decl)) = (NODE); \
|
630 |
|
|
}
|
631 |
|
|
|
632 |
|
|
/* Return the current block, either found in the body of the currently
|
633 |
|
|
declared function or in the current static block being defined. */
|
634 |
|
|
#define GET_CURRENT_BLOCK(F) ((F) ? DECL_FUNCTION_BODY ((F)) : \
|
635 |
|
|
current_static_block)
|
636 |
|
|
|
637 |
|
|
#ifndef USE_MAPPED_LOCATION
|
638 |
|
|
/* Retrieve line/column from a WFL. */
|
639 |
|
|
#define EXPR_WFL_GET_LINECOL(V,LINE,COL) \
|
640 |
|
|
{ \
|
641 |
|
|
(LINE) = (V) >> 12; \
|
642 |
|
|
(COL) = (V) & 0xfff; \
|
643 |
|
|
}
|
644 |
|
|
#endif
|
645 |
|
|
|
646 |
|
|
#define EXPR_WFL_QUALIFICATION(WFL) TREE_OPERAND ((WFL), 1)
|
647 |
|
|
#define QUAL_WFL(NODE) TREE_PURPOSE (NODE)
|
648 |
|
|
#define QUAL_RESOLUTION(NODE) TREE_VALUE (NODE)
|
649 |
|
|
#define QUAL_DECL_TYPE(NODE) GET_SKIP_TYPE (NODE)
|
650 |
|
|
|
651 |
|
|
#define GET_SKIP_TYPE(NODE) \
|
652 |
|
|
(TREE_CODE (TREE_TYPE (NODE)) == POINTER_TYPE ? \
|
653 |
|
|
TREE_TYPE (TREE_TYPE (NODE)): TREE_TYPE (NODE))
|
654 |
|
|
|
655 |
|
|
/* Handy macros for the walk operation */
|
656 |
|
|
#define COMPLETE_CHECK_OP(NODE, N) \
|
657 |
|
|
{ \
|
658 |
|
|
TREE_OPERAND ((NODE), (N)) = \
|
659 |
|
|
java_complete_tree (TREE_OPERAND ((NODE), (N))); \
|
660 |
|
|
if (TREE_OPERAND ((NODE), (N)) == error_mark_node) \
|
661 |
|
|
return error_mark_node; \
|
662 |
|
|
}
|
663 |
|
|
#define COMPLETE_CHECK_OP_0(NODE) COMPLETE_CHECK_OP(NODE, 0)
|
664 |
|
|
#define COMPLETE_CHECK_OP_1(NODE) COMPLETE_CHECK_OP(NODE, 1)
|
665 |
|
|
#define COMPLETE_CHECK_OP_2(NODE) COMPLETE_CHECK_OP(NODE, 2)
|
666 |
|
|
|
667 |
|
|
/* Building invocations: append(ARG) and StringBuffer(ARG) */
|
668 |
|
|
#define BUILD_APPEND(ARG) \
|
669 |
|
|
((JSTRING_TYPE_P (TREE_TYPE (ARG)) || JPRIMITIVE_TYPE_P (TREE_TYPE (ARG))) \
|
670 |
|
|
? build_method_invocation (wfl_append, \
|
671 |
|
|
ARG ? build_tree_list (NULL, (ARG)) : NULL_TREE)\
|
672 |
|
|
: build_method_invocation (wfl_append, \
|
673 |
|
|
ARG ? build_tree_list (NULL, \
|
674 |
|
|
build1 (CONVERT_EXPR, \
|
675 |
|
|
object_type_node,\
|
676 |
|
|
(ARG))) \
|
677 |
|
|
: NULL_TREE))
|
678 |
|
|
#define BUILD_STRING_BUFFER(ARG) \
|
679 |
|
|
build_new_invocation (wfl_string_buffer, \
|
680 |
|
|
(ARG ? build_tree_list (NULL, (ARG)) : NULL_TREE))
|
681 |
|
|
|
682 |
|
|
#define BUILD_THROW(WHERE, WHAT) \
|
683 |
|
|
{ \
|
684 |
|
|
(WHERE) = \
|
685 |
|
|
build3 (CALL_EXPR, void_type_node, \
|
686 |
|
|
build_address_of (throw_node), \
|
687 |
|
|
build_tree_list (NULL_TREE, (WHAT)), NULL_TREE); \
|
688 |
|
|
TREE_SIDE_EFFECTS ((WHERE)) = 1; \
|
689 |
|
|
}
|
690 |
|
|
|
691 |
|
|
/* Set wfl_operator for the most accurate error location */
|
692 |
|
|
#ifdef USE_MAPPED_LOCATION
|
693 |
|
|
#define SET_WFL_OPERATOR(WHICH, NODE, WFL) \
|
694 |
|
|
SET_EXPR_LOCATION (WHICH, \
|
695 |
|
|
(TREE_CODE (WFL) == EXPR_WITH_FILE_LOCATION ? \
|
696 |
|
|
EXPR_LOCATION (WFL) : EXPR_LOCATION (NODE)))
|
697 |
|
|
#else
|
698 |
|
|
#define SET_WFL_OPERATOR(WHICH, NODE, WFL) \
|
699 |
|
|
EXPR_WFL_LINECOL (WHICH) = \
|
700 |
|
|
(TREE_CODE (WFL) == EXPR_WITH_FILE_LOCATION ? \
|
701 |
|
|
EXPR_WFL_LINECOL (WFL) : EXPR_WFL_LINECOL (NODE))
|
702 |
|
|
#endif
|
703 |
|
|
|
704 |
|
|
#define PATCH_METHOD_RETURN_ERROR() \
|
705 |
|
|
{ \
|
706 |
|
|
if (ret_decl) \
|
707 |
|
|
*ret_decl = NULL_TREE; \
|
708 |
|
|
return error_mark_node; \
|
709 |
|
|
}
|
710 |
|
|
|
711 |
|
|
/* Convenient macro to check. Assumes that CLASS is a CLASS_DECL. */
|
712 |
|
|
#define CHECK_METHODS(CLASS) \
|
713 |
|
|
{ \
|
714 |
|
|
if (CLASS_INTERFACE ((CLASS))) \
|
715 |
|
|
java_check_abstract_methods ((CLASS)); \
|
716 |
|
|
else \
|
717 |
|
|
java_check_regular_methods ((CLASS)); \
|
718 |
|
|
}
|
719 |
|
|
|
720 |
|
|
#define CLEAR_DEPRECATED ctxp->deprecated = 0
|
721 |
|
|
|
722 |
|
|
#define CHECK_DEPRECATED_NO_RESET(DECL) \
|
723 |
|
|
{ \
|
724 |
|
|
if (ctxp->deprecated) \
|
725 |
|
|
DECL_DEPRECATED (DECL) = 1; \
|
726 |
|
|
}
|
727 |
|
|
|
728 |
|
|
/* Using and reseting the @deprecated tag flag */
|
729 |
|
|
#define CHECK_DEPRECATED(DECL) \
|
730 |
|
|
{ \
|
731 |
|
|
if (ctxp->deprecated) \
|
732 |
|
|
DECL_DEPRECATED (DECL) = 1; \
|
733 |
|
|
ctxp->deprecated = 0; \
|
734 |
|
|
}
|
735 |
|
|
|
736 |
|
|
/* Register an import */
|
737 |
|
|
#define REGISTER_IMPORT(WHOLE, NAME) \
|
738 |
|
|
{ \
|
739 |
|
|
IS_A_SINGLE_IMPORT_CLASSFILE_NAME_P ((NAME)) = 1; \
|
740 |
|
|
ctxp->import_list = tree_cons ((WHOLE), (NAME), ctxp->import_list); \
|
741 |
|
|
}
|
742 |
|
|
|
743 |
|
|
/* Macro to access the osb (opening square bracket) count */
|
744 |
|
|
#define CURRENT_OSB(C) (C)->osb_number [(C)->osb_depth]
|
745 |
|
|
|
746 |
|
|
/* Parser context data structure. */
|
747 |
|
|
struct parser_ctxt GTY(()) {
|
748 |
|
|
const char *filename; /* Current filename */
|
749 |
|
|
location_t file_start_location;
|
750 |
|
|
location_t save_location;
|
751 |
|
|
struct parser_ctxt *next;
|
752 |
|
|
|
753 |
|
|
java_lexer * GTY((skip)) lexer; /* Current lexer state */
|
754 |
|
|
char marker_begining; /* Marker. Should be a sub-struct */
|
755 |
|
|
int ccb_indent; /* Number of unmatched { seen. */
|
756 |
|
|
/* The next two fields are only source_location if USE_MAPPED_LOCATION.
|
757 |
|
|
Otherwise, they are integer line number, but we can't have #ifdefs
|
758 |
|
|
in GTY structures. */
|
759 |
|
|
source_location first_ccb_indent1; /* First { at ident level 1 */
|
760 |
|
|
source_location last_ccb_indent1; /* Last } at ident level 1 */
|
761 |
|
|
int parser_ccb_indent; /* Keep track of {} indent, parser */
|
762 |
|
|
int osb_depth; /* Current depth of [ in an expression */
|
763 |
|
|
int osb_limit; /* Limit of this depth */
|
764 |
|
|
int * GTY ((skip)) osb_number; /* Keep track of ['s */
|
765 |
|
|
char marker_end; /* End marker. Should be a sub-struct */
|
766 |
|
|
|
767 |
|
|
/* The flags section */
|
768 |
|
|
|
769 |
|
|
/* Indicates a context used for saving the parser status. The
|
770 |
|
|
context must be popped when the status is restored. */
|
771 |
|
|
unsigned saved_data_ctx:1;
|
772 |
|
|
/* Indicates that a context already contains saved data and that the
|
773 |
|
|
next save operation will require a new context to be created. */
|
774 |
|
|
unsigned saved_data:1;
|
775 |
|
|
/* Report error when true */
|
776 |
|
|
unsigned java_error_flag:1;
|
777 |
|
|
/* @deprecated tag seen */
|
778 |
|
|
unsigned deprecated:1;
|
779 |
|
|
/* Flag to report certain errors (fix this documentation. FIXME) */
|
780 |
|
|
unsigned class_err:1;
|
781 |
|
|
|
782 |
|
|
/* This section is used only if we compile jc1 */
|
783 |
|
|
tree modifier_ctx [12]; /* WFL of modifiers */
|
784 |
|
|
tree class_type; /* Current class */
|
785 |
|
|
tree function_decl; /* Current function decl, save/restore */
|
786 |
|
|
|
787 |
|
|
int prevent_ese; /* Prevent expression statement error */
|
788 |
|
|
|
789 |
|
|
int formal_parameter_number; /* Number of parameters found */
|
790 |
|
|
int interface_number; /* # itfs declared to extend an itf def */
|
791 |
|
|
|
792 |
|
|
tree package; /* Defined package ID */
|
793 |
|
|
|
794 |
|
|
/* These two lists won't survive file traversal */
|
795 |
|
|
tree class_list; /* List of classes in a CU */
|
796 |
|
|
jdeplist * GTY((skip)) classd_list; /* Classe dependencies in a CU */
|
797 |
|
|
|
798 |
|
|
tree current_parsed_class; /* Class currently parsed */
|
799 |
|
|
tree current_parsed_class_un; /* Curr. parsed class unqualified name */
|
800 |
|
|
|
801 |
|
|
tree non_static_initialized; /* List of non static initialized fields */
|
802 |
|
|
tree static_initialized; /* List of static non final initialized */
|
803 |
|
|
tree instance_initializers; /* List of instance initializers stmts */
|
804 |
|
|
|
805 |
|
|
tree import_list; /* List of import */
|
806 |
|
|
tree import_demand_list; /* List of import on demand */
|
807 |
|
|
|
808 |
|
|
tree current_loop; /* List of the currently nested
|
809 |
|
|
loops/switches */
|
810 |
|
|
tree current_labeled_block; /* List of currently nested
|
811 |
|
|
labeled blocks. */
|
812 |
|
|
|
813 |
|
|
int pending_block; /* Pending block to close */
|
814 |
|
|
|
815 |
|
|
int explicit_constructor_p; /* >0 when processing an explicit
|
816 |
|
|
constructor. This flag is used to trap
|
817 |
|
|
illegal argument usage during an
|
818 |
|
|
explicit constructor invocation. */
|
819 |
|
|
};
|
820 |
|
|
|
821 |
|
|
/* A set of macros to push/pop/access the currently parsed class. */
|
822 |
|
|
#define GET_CPC_LIST() ctxp->current_parsed_class
|
823 |
|
|
|
824 |
|
|
/* Currently class being parsed is an inner class if an enclosing
|
825 |
|
|
class has been already pushed. This truth value is only valid prior
|
826 |
|
|
an inner class is pushed. After, use FIXME. */
|
827 |
|
|
#define CPC_INNER_P() GET_CPC_LIST ()
|
828 |
|
|
|
829 |
|
|
/* The TYPE_DECL node of the class currently being parsed. */
|
830 |
|
|
#define GET_CPC() TREE_VALUE (GET_CPC_LIST ())
|
831 |
|
|
|
832 |
|
|
/* Get the currently parsed class unqualified IDENTIFIER_NODE. */
|
833 |
|
|
#define GET_CPC_UN() TREE_PURPOSE (GET_CPC_LIST ())
|
834 |
|
|
|
835 |
|
|
/* Get a parsed class unqualified IDENTIFIER_NODE from its CPC node. */
|
836 |
|
|
#define GET_CPC_UN_NODE(N) TREE_PURPOSE (N)
|
837 |
|
|
|
838 |
|
|
/* Get the currently parsed class DECL_TYPE from its CPC node. */
|
839 |
|
|
#define GET_CPC_DECL_NODE(N) TREE_VALUE (N)
|
840 |
|
|
|
841 |
|
|
/* The currently parsed enclosing currently parsed TREE_LIST node. */
|
842 |
|
|
#define GET_ENCLOSING_CPC() TREE_CHAIN (GET_CPC_LIST ())
|
843 |
|
|
|
844 |
|
|
/* Get the next enclosing context. */
|
845 |
|
|
#define GET_NEXT_ENCLOSING_CPC(C) TREE_CHAIN (C)
|
846 |
|
|
|
847 |
|
|
/* The DECL_TYPE node of the enclosing currently parsed
|
848 |
|
|
class. NULL_TREE if the currently parsed class isn't an inner
|
849 |
|
|
class. */
|
850 |
|
|
#define GET_ENCLOSING_CPC_CONTEXT() (GET_ENCLOSING_CPC () ? \
|
851 |
|
|
TREE_VALUE (GET_ENCLOSING_CPC ()) : \
|
852 |
|
|
NULL_TREE)
|
853 |
|
|
|
854 |
|
|
/* Make sure that innerclass T sits in an appropriate enclosing
|
855 |
|
|
context. */
|
856 |
|
|
#define INNER_ENCLOSING_SCOPE_CHECK(T) \
|
857 |
|
|
(INNER_CLASS_TYPE_P ((T)) && !ANONYMOUS_CLASS_P ((T)) \
|
858 |
|
|
&& ((current_this \
|
859 |
|
|
/* We have a this and it's not the right one */ \
|
860 |
|
|
&& (DECL_CONTEXT (TYPE_NAME ((T))) \
|
861 |
|
|
!= TYPE_NAME (TREE_TYPE (TREE_TYPE (current_this)))) \
|
862 |
|
|
&& !inherits_from_p (TREE_TYPE (TREE_TYPE (current_this)), \
|
863 |
|
|
TREE_TYPE (DECL_CONTEXT (TYPE_NAME (T)))) \
|
864 |
|
|
&& !common_enclosing_instance_p (TREE_TYPE (TREE_TYPE (current_this)),\
|
865 |
|
|
(T)) \
|
866 |
|
|
&& INNER_CLASS_TYPE_P (TREE_TYPE (TREE_TYPE (current_this))) \
|
867 |
|
|
&& !inherits_from_p \
|
868 |
|
|
(TREE_TYPE (DECL_CONTEXT \
|
869 |
|
|
(TYPE_NAME (TREE_TYPE (TREE_TYPE (current_this))))),\
|
870 |
|
|
TREE_TYPE (DECL_CONTEXT (TYPE_NAME (T))))) \
|
871 |
|
|
/* We don't have a this, which is OK if the current function is \
|
872 |
|
|
static. */ \
|
873 |
|
|
|| (!current_this \
|
874 |
|
|
&& current_function_decl \
|
875 |
|
|
&& ! METHOD_STATIC (current_function_decl))))
|
876 |
|
|
|
877 |
|
|
/* Push macro. First argument to PUSH_CPC is a DECL_TYPE, second
|
878 |
|
|
argument is the unqualified currently parsed class name. */
|
879 |
|
|
#define PUSH_CPC(C,R) { \
|
880 |
|
|
ctxp->current_parsed_class = \
|
881 |
|
|
tree_cons ((R), (C), GET_CPC_LIST ()); \
|
882 |
|
|
}
|
883 |
|
|
|
884 |
|
|
/* In case of an error, push an error. */
|
885 |
|
|
#define PUSH_ERROR() PUSH_CPC (error_mark_node, error_mark_node)
|
886 |
|
|
|
887 |
|
|
/* Pop macro. Before we pop, we link the current inner class decl (if any)
|
888 |
|
|
to its enclosing class. */
|
889 |
|
|
#define POP_CPC() { \
|
890 |
|
|
link_nested_class_to_enclosing (); \
|
891 |
|
|
ctxp->current_parsed_class = \
|
892 |
|
|
TREE_CHAIN (GET_CPC_LIST ()); \
|
893 |
|
|
}
|
894 |
|
|
|
895 |
|
|
#define DEBUG_CPC() \
|
896 |
|
|
do \
|
897 |
|
|
{ \
|
898 |
|
|
tree tmp = ctxp->current_parsed_class; \
|
899 |
|
|
while (tmp) \
|
900 |
|
|
{ \
|
901 |
|
|
fprintf (stderr, "%s ", \
|
902 |
|
|
IDENTIFIER_POINTER (TREE_PURPOSE (tmp))); \
|
903 |
|
|
tmp = TREE_CHAIN (tmp); \
|
904 |
|
|
} \
|
905 |
|
|
} \
|
906 |
|
|
while (0);
|
907 |
|
|
|
908 |
|
|
/* Access to the various initializer statement lists */
|
909 |
|
|
#define CPC_INITIALIZER_LIST(C) ((C)->non_static_initialized)
|
910 |
|
|
#define CPC_STATIC_INITIALIZER_LIST(C) ((C)->static_initialized)
|
911 |
|
|
#define CPC_INSTANCE_INITIALIZER_LIST(C) ((C)->instance_initializers)
|
912 |
|
|
|
913 |
|
|
/* Access to the various initializer statements */
|
914 |
|
|
#define CPC_INITIALIZER_STMT(C) (TREE_PURPOSE (CPC_INITIALIZER_LIST (C)))
|
915 |
|
|
#define CPC_STATIC_INITIALIZER_STMT(C) \
|
916 |
|
|
(TREE_PURPOSE (CPC_STATIC_INITIALIZER_LIST (C)))
|
917 |
|
|
#define CPC_INSTANCE_INITIALIZER_STMT(C) \
|
918 |
|
|
(TREE_PURPOSE (CPC_INSTANCE_INITIALIZER_LIST (C)))
|
919 |
|
|
|
920 |
|
|
/* Set various initializer statements */
|
921 |
|
|
#define SET_CPC_INITIALIZER_STMT(C,S) \
|
922 |
|
|
if (CPC_INITIALIZER_LIST (C)) \
|
923 |
|
|
TREE_PURPOSE (CPC_INITIALIZER_LIST (C)) = (S);
|
924 |
|
|
#define SET_CPC_STATIC_INITIALIZER_STMT(C,S) \
|
925 |
|
|
if (CPC_STATIC_INITIALIZER_LIST (C)) \
|
926 |
|
|
TREE_PURPOSE (CPC_STATIC_INITIALIZER_LIST (C)) = (S);
|
927 |
|
|
#define SET_CPC_INSTANCE_INITIALIZER_STMT(C,S) \
|
928 |
|
|
if (CPC_INSTANCE_INITIALIZER_LIST(C)) \
|
929 |
|
|
TREE_PURPOSE (CPC_INSTANCE_INITIALIZER_LIST (C)) = (S);
|
930 |
|
|
|
931 |
|
|
/* This is used by the lexer to communicate with the parser. It is
|
932 |
|
|
set on an integer constant if the radix is NOT 10, so that the parser
|
933 |
|
|
can correctly diagnose a numeric overflow. */
|
934 |
|
|
#define JAVA_NOT_RADIX10_FLAG(NODE) TREE_LANG_FLAG_0(NODE)
|
935 |
|
|
|
936 |
|
|
#ifndef JC1_LITE
|
937 |
|
|
void java_complete_class (void);
|
938 |
|
|
void java_check_circular_reference (void);
|
939 |
|
|
void java_fix_constructors (void);
|
940 |
|
|
void java_layout_classes (void);
|
941 |
|
|
void java_reorder_fields (void);
|
942 |
|
|
tree java_method_add_stmt (tree, tree);
|
943 |
|
|
int java_report_errors (void);
|
944 |
|
|
extern tree do_resolve_class (tree, tree, tree, tree, tree);
|
945 |
|
|
#endif
|
946 |
|
|
char *java_get_line_col (const char *, int, int);
|
947 |
|
|
extern void reset_report (void);
|
948 |
|
|
|
949 |
|
|
/* Always in use, no matter what you compile */
|
950 |
|
|
void java_push_parser_context (void);
|
951 |
|
|
void java_pop_parser_context (int);
|
952 |
|
|
void java_init_lex (FILE *, const char *);
|
953 |
|
|
extern void java_parser_context_save_global (void);
|
954 |
|
|
extern void java_parser_context_restore_global (void);
|
955 |
|
|
int yyparse (void);
|
956 |
|
|
extern int java_parse (void);
|
957 |
|
|
extern void yyerror (const char *)
|
958 |
|
|
#ifdef JC1_LITE
|
959 |
|
|
ATTRIBUTE_NORETURN
|
960 |
|
|
#endif
|
961 |
|
|
;
|
962 |
|
|
extern void java_expand_classes (void);
|
963 |
|
|
extern void java_finish_classes (void);
|
964 |
|
|
|
965 |
|
|
extern GTY(()) struct parser_ctxt *ctxp;
|
966 |
|
|
extern GTY(()) struct parser_ctxt *ctxp_for_generation;
|
967 |
|
|
extern GTY(()) struct parser_ctxt *ctxp_for_generation_last;
|
968 |
|
|
|
969 |
|
|
#endif /* ! GCC_JAVA_PARSE_H */
|