]>
Commit | Line | Data |
---|---|---|
e04a16fb AG |
1 | /* Process declarations and variables for the GNU compiler for the |
2 | Java(TM) language. | |
3 | ||
df32d2ce | 4 | Copyright (C) 1996, 97-99, 2000 Free Software Foundation, Inc. |
e04a16fb AG |
5 | |
6 | This file is part of GNU CC. | |
7 | ||
8 | GNU CC 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 | GNU CC 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 GNU CC; see the file COPYING. If not, write to | |
20 | the Free Software Foundation, 59 Temple Place - Suite 330, | |
21 | Boston, MA 02111-1307, 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 | /* Hacked by Per Bothner <bothner@cygnus.com> February 1996. */ | |
28 | ||
29 | #include "config.h" | |
1f43f4b4 | 30 | #include "system.h" |
e04a16fb AG |
31 | #include "tree.h" |
32 | #include "java-tree.h" | |
33 | #include "jcf.h" | |
1f43f4b4 | 34 | #include "toplev.h" |
b384405b | 35 | #include "function.h" |
138657ec | 36 | #include "except.h" |
0ae70c6a | 37 | #include "defaults.h" |
e04a16fb | 38 | |
df32d2ce KG |
39 | static tree push_jvm_slot PARAMS ((int, tree)); |
40 | static tree lookup_name_current_level PARAMS ((tree)); | |
41 | static tree push_promoted_type PARAMS ((const char *, tree)); | |
42 | static struct binding_level *make_binding_level PARAMS ((void)); | |
4bcde32e | 43 | |
9d45bec2 PB |
44 | #ifndef INT_TYPE_SIZE |
45 | #define INT_TYPE_SIZE BITS_PER_WORD | |
46 | #endif | |
47 | ||
e04a16fb AG |
48 | /* The DECL_MAP is a mapping from (index, type) to a decl node. |
49 | If index < max_locals, it is the index of a local variable. | |
50 | if index >= max_locals, then index-max_locals is a stack slot. | |
51 | The DECL_MAP mapping is represented as a TREE_VEC whose elements | |
52 | are a list of decls (VAR_DECL or PARM_DECL) chained by | |
53 | DECL_LOCAL_SLOT_CHAIN; the index finds the TREE_VEC element, and then | |
54 | we search the chain for a decl with a matching TREE_TYPE. */ | |
55 | ||
56 | tree decl_map; | |
57 | ||
58 | /* A list of local variables VAR_DECLs for this method that we have seen | |
59 | debug information, but we have not reached their starting (byte) PC yet. */ | |
60 | ||
61 | tree pending_local_decls = NULL_TREE; | |
62 | ||
63 | /* Push a local variable or stack slot into the decl_map, | |
64 | and assign it an rtl. */ | |
65 | ||
4bcde32e | 66 | static tree |
e04a16fb AG |
67 | push_jvm_slot (index, decl) |
68 | int index; | |
69 | tree decl; | |
70 | { | |
71 | struct rtx_def *rtl = NULL; | |
72 | tree type = TREE_TYPE (decl); | |
73 | tree tmp; | |
74 | ||
75 | DECL_CONTEXT (decl) = current_function_decl; | |
76 | layout_decl (decl, 0); | |
77 | ||
78 | /* See if we have an appropriate rtl (i.e. same mode) at this index. | |
79 | If so, we must use it. */ | |
80 | tmp = TREE_VEC_ELT (decl_map, index); | |
81 | while (tmp != NULL_TREE) | |
82 | { | |
83 | if (TYPE_MODE (type) == TYPE_MODE (TREE_TYPE (tmp))) | |
84 | rtl = DECL_RTL (tmp); | |
85 | if (rtl != NULL) | |
86 | break; | |
87 | tmp = DECL_LOCAL_SLOT_CHAIN (tmp); | |
88 | } | |
89 | if (rtl != NULL) | |
90 | DECL_RTL (decl) = rtl; | |
91 | else | |
92 | { | |
93 | if (index >= DECL_MAX_LOCALS (current_function_decl)) | |
94 | DECL_REGISTER (decl) = 1; | |
95 | expand_decl (decl); | |
96 | } | |
97 | ||
98 | /* Now link the decl into the decl_map. */ | |
99 | if (DECL_LANG_SPECIFIC (decl) == NULL) | |
100 | { | |
101 | DECL_LANG_SPECIFIC (decl) | |
102 | = (struct lang_decl *) permalloc (sizeof (struct lang_decl_var)); | |
103 | DECL_LOCAL_START_PC (decl) = 0; | |
104 | DECL_LOCAL_END_PC (decl) = DECL_CODE_LENGTH (current_function_decl); | |
105 | DECL_LOCAL_SLOT_NUMBER (decl) = index; | |
106 | } | |
107 | DECL_LOCAL_SLOT_CHAIN (decl) = TREE_VEC_ELT (decl_map, index); | |
108 | TREE_VEC_ELT (decl_map, index) = decl; | |
109 | return decl; | |
110 | } | |
111 | ||
112 | /* Find a VAR_DECL (or PARM_DECL) at local index INDEX that has type TYPE, | |
113 | that is valid at PC (or -1 if any pc). | |
114 | If there is no existing matching decl, allocate one. | |
115 | If we find a decl with matching modes but different types, | |
116 | we re-use the rtl, but create a new decl. */ | |
117 | ||
118 | tree | |
119 | find_local_variable (index, type, pc) | |
120 | int index; | |
121 | tree type; | |
122 | int pc; | |
123 | { | |
e04a16fb AG |
124 | tree decl = TREE_VEC_ELT (decl_map, index); |
125 | tree best = NULL_TREE; | |
126 | while (decl != NULL_TREE) | |
127 | { | |
128 | int in_range; | |
129 | in_range = pc < 0 | |
130 | || (pc >= DECL_LOCAL_START_PC (decl) | |
131 | && pc < DECL_LOCAL_END_PC (decl)); | |
132 | ||
133 | if ((TREE_TYPE (decl) == type | |
134 | || (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE | |
135 | && type == ptr_type_node)) | |
136 | && in_range) | |
137 | { | |
138 | if (best == NULL_TREE | |
139 | || (TREE_TYPE (decl) == type && TREE_TYPE (best) != type) | |
140 | || DECL_LOCAL_START_PC (decl) > DECL_LOCAL_START_PC (best) | |
141 | || DECL_LOCAL_END_PC (decl) < DECL_LOCAL_START_PC (decl)) | |
142 | best = decl; | |
143 | } | |
144 | decl = DECL_LOCAL_SLOT_CHAIN (decl); | |
145 | } | |
146 | if (best != NULL_TREE) | |
147 | return best; | |
148 | return push_jvm_slot (index, build_decl (VAR_DECL, NULL_TREE, type)); | |
149 | } | |
150 | ||
151 | ||
152 | /* Same as find_local_index, except that INDEX is a stack index. */ | |
153 | ||
154 | tree | |
155 | find_stack_slot (index, type) | |
156 | int index; | |
157 | tree type; | |
158 | { | |
159 | return find_local_variable (index + DECL_MAX_LOCALS (current_function_decl), | |
160 | type, -1); | |
161 | } | |
162 | ||
163 | struct binding_level | |
164 | { | |
165 | /* A chain of _DECL nodes for all variables, constants, functions, | |
166 | * and typedef types. These are in the reverse of the order supplied. | |
167 | */ | |
168 | tree names; | |
169 | ||
170 | /* For each level, a list of shadowed outer-level local definitions | |
171 | to be restored when this level is popped. | |
172 | Each link is a TREE_LIST whose TREE_PURPOSE is an identifier and | |
173 | whose TREE_VALUE is its old definition (a kind of ..._DECL node). */ | |
174 | tree shadowed; | |
175 | ||
176 | /* For each level (except not the global one), | |
177 | a chain of BLOCK nodes for all the levels | |
178 | that were entered and exited one level down. */ | |
179 | tree blocks; | |
180 | ||
181 | /* The BLOCK node for this level, if one has been preallocated. | |
182 | If 0, the BLOCK is allocated (if needed) when the level is popped. */ | |
183 | tree this_block; | |
184 | ||
185 | /* The binding level which this one is contained in (inherits from). */ | |
186 | struct binding_level *level_chain; | |
187 | ||
188 | /* 1 means make a BLOCK for this level regardless of all else. | |
189 | 2 for temporary binding contours created by the compiler. */ | |
190 | char keep; | |
191 | ||
192 | /* Nonzero means make a BLOCK if this level has any subblocks. */ | |
193 | char keep_if_subblocks; | |
194 | ||
195 | /* Nonzero if this level can safely have additional | |
196 | cleanup-needing variables added to it. */ | |
197 | char more_cleanups_ok; | |
198 | char have_cleanups; | |
199 | ||
200 | /* The bytecode PC that marks the end of this level. */ | |
201 | int end_pc; | |
202 | }; | |
203 | ||
204 | #define NULL_BINDING_LEVEL (struct binding_level *) NULL | |
205 | ||
206 | /* The binding level currently in effect. */ | |
207 | ||
208 | static struct binding_level *current_binding_level; | |
209 | ||
210 | /* A chain of binding_level structures awaiting reuse. */ | |
211 | ||
212 | static struct binding_level *free_binding_level; | |
213 | ||
214 | /* The outermost binding level, for names of file scope. | |
215 | This is created when the compiler is started and exists | |
216 | through the entire run. */ | |
217 | ||
218 | static struct binding_level *global_binding_level; | |
219 | ||
220 | /* Binding level structures are initialized by copying this one. */ | |
221 | ||
222 | static struct binding_level clear_binding_level | |
223 | = {NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, | |
224 | NULL_BINDING_LEVEL, 0, 0, 0, 0, 1000000000}; | |
225 | ||
226 | #if 0 | |
227 | /* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function | |
228 | that have names. Here so we can clear out their names' definitions | |
229 | at the end of the function. */ | |
230 | ||
231 | static tree named_labels; | |
232 | ||
233 | /* A list of LABEL_DECLs from outer contexts that are currently shadowed. */ | |
234 | ||
235 | static tree shadowed_labels; | |
236 | #endif | |
237 | ||
238 | int flag_traditional; | |
239 | ||
240 | /* Nonzero means unconditionally make a BLOCK for the next level pushed. */ | |
241 | ||
242 | static int keep_next_level_flag; | |
243 | ||
244 | /* Nonzero means make a BLOCK for the next level pushed | |
245 | if it has subblocks. */ | |
246 | ||
247 | static int keep_next_if_subblocks; | |
248 | ||
249 | /* The FUNCTION_DECL for the function currently being compiled, | |
250 | or 0 if between functions. */ | |
251 | tree current_function_decl; | |
252 | ||
e04a16fb | 253 | tree object_type_node; |
c877974e | 254 | tree unqualified_object_id_node; |
e04a16fb AG |
255 | tree object_ptr_type_node; |
256 | tree string_type_node; | |
cd9643f7 | 257 | tree string_ptr_type_node; |
e04a16fb | 258 | tree throwable_type_node; |
b9f7e36c APB |
259 | tree runtime_exception_type_node; |
260 | tree error_exception_type_node; | |
5423609c APB |
261 | tree *predef_filenames; |
262 | int predef_filenames_size; | |
e04a16fb AG |
263 | |
264 | tree boolean_type_node; | |
265 | ||
e04a16fb AG |
266 | tree return_address_type_node; |
267 | ||
e04a16fb AG |
268 | tree byte_type_node; |
269 | tree short_type_node; | |
270 | tree int_type_node; | |
271 | tree long_type_node; | |
272 | ||
273 | tree promoted_byte_type_node; | |
274 | tree promoted_short_type_node; | |
275 | tree promoted_char_type_node; | |
276 | tree promoted_boolean_type_node; | |
277 | ||
278 | tree unsigned_byte_type_node; | |
279 | tree unsigned_short_type_node; | |
280 | tree unsigned_int_type_node; | |
281 | tree unsigned_long_type_node; | |
282 | ||
283 | /* The type for struct methodtable. */ | |
284 | tree methodtable_type; | |
285 | tree methodtable_ptr_type; | |
286 | ||
287 | tree utf8const_type; | |
288 | tree utf8const_ptr_type; | |
289 | tree class_type_node; | |
290 | tree class_ptr_type; | |
291 | tree field_type_node; | |
292 | tree field_ptr_type_node; | |
293 | tree field_info_union_node; | |
294 | tree jexception_type; | |
295 | tree jexception_ptr_type; | |
296 | tree lineNumberEntry_type; | |
297 | tree lineNumbers_type; | |
298 | tree constants_type_node; | |
299 | tree dtable_type; | |
300 | tree dtable_ptr_type; | |
301 | tree method_type_node; | |
302 | tree method_ptr_type_node; | |
303 | tree nativecode_ptr_array_type_node; | |
304 | tree one_elt_array_domain_type; | |
305 | tree access_flags_type_node; | |
306 | tree class_dtable_decl; | |
307 | ||
81b3411c BS |
308 | /* Expressions that are constants with value zero, of types |
309 | `long', `float' and `double'. */ | |
4a5f66c3 APB |
310 | tree long_zero_node; |
311 | tree float_zero_node; | |
312 | tree double_zero_node; | |
313 | ||
9bbc7d9f | 314 | tree empty_stmt_node; |
e04a16fb AG |
315 | |
316 | /* Nodes for boolean constants TRUE and FALSE. */ | |
317 | tree boolean_true_node, boolean_false_node; | |
318 | ||
319 | tree TYPE_identifier_node; | |
320 | tree init_identifier_node; | |
321 | tree clinit_identifier_node; | |
22eed1e6 | 322 | tree finit_identifier_node; |
e04a16fb AG |
323 | tree void_signature_node; |
324 | tree length_identifier_node; | |
325 | tree this_identifier_node; | |
326 | tree super_identifier_node; | |
f1b0c0d8 | 327 | tree continue_identifier_node; |
e04a16fb | 328 | |
0bd2e6db PB |
329 | tree end_params_node; |
330 | ||
e04a16fb AG |
331 | /* References to internal libjava functions we use. */ |
332 | tree alloc_object_node; | |
333 | tree soft_instanceof_node; | |
334 | tree soft_checkcast_node; | |
335 | tree soft_initclass_node; | |
336 | tree soft_newarray_node; | |
337 | tree soft_anewarray_node; | |
338 | tree soft_multianewarray_node; | |
339 | tree soft_badarrayindex_node; | |
8bbb23b7 | 340 | tree throw_node [2]; |
e04a16fb AG |
341 | tree soft_checkarraystore_node; |
342 | tree soft_monitorenter_node; | |
343 | tree soft_monitorexit_node; | |
344 | tree soft_lookupinterfacemethod_node; | |
345 | tree soft_fmod_node; | |
9d45bec2 | 346 | tree soft_exceptioninfo_call_node; |
aa4759c1 AH |
347 | tree soft_idiv_node; |
348 | tree soft_irem_node; | |
349 | tree soft_ldiv_node; | |
350 | tree soft_lrem_node; | |
351 | ||
e04a16fb AG |
352 | /* Build (and pushdecl) a "promoted type" for all standard |
353 | types shorter than int. */ | |
354 | ||
355 | static tree | |
356 | push_promoted_type (name, actual_type) | |
c8e7d2e6 | 357 | const char *name; |
e04a16fb AG |
358 | tree actual_type; |
359 | { | |
360 | tree type = make_node (TREE_CODE (actual_type)); | |
361 | #if 1 | |
362 | tree in_min = TYPE_MIN_VALUE (int_type_node); | |
363 | tree in_max = TYPE_MAX_VALUE (int_type_node); | |
364 | #else | |
365 | tree in_min = TYPE_MIN_VALUE (actual_type); | |
366 | tree in_max = TYPE_MAX_VALUE (actual_type); | |
367 | #endif | |
368 | TYPE_MIN_VALUE (type) = build_int_2 (TREE_INT_CST_LOW (in_min), | |
369 | TREE_INT_CST_HIGH (in_min)); | |
370 | TREE_TYPE (TYPE_MIN_VALUE (type)) = type; | |
371 | TYPE_MAX_VALUE (type) = build_int_2 (TREE_INT_CST_LOW (in_max), | |
372 | TREE_INT_CST_HIGH (in_max)); | |
373 | TREE_TYPE (TYPE_MAX_VALUE (type)) = type; | |
374 | TYPE_PRECISION (type) = TYPE_PRECISION (int_type_node); | |
375 | layout_type (type); | |
376 | pushdecl (build_decl (TYPE_DECL, get_identifier (name), type)); | |
377 | return type; | |
378 | } | |
379 | ||
380 | /* Nodes for integer constants. */ | |
81b3411c | 381 | tree integer_two_node, integer_four_node; |
e04a16fb AG |
382 | tree integer_negative_one_node; |
383 | ||
384 | /* Return a definition for a builtin function named NAME and whose data type | |
385 | is TYPE. TYPE should be a function type with argument types. | |
386 | FUNCTION_CODE tells later passes how to compile calls to this function. | |
387 | See tree.h for its possible values. | |
388 | ||
389 | If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME, | |
390 | the name to be called if we can't opencode the function. */ | |
391 | ||
26db82d8 BS |
392 | tree |
393 | builtin_function (name, type, function_code, class, library_name) | |
4bcde32e | 394 | const char *name; |
e04a16fb | 395 | tree type; |
26db82d8 BS |
396 | int function_code; |
397 | enum built_in_class class; | |
4bcde32e | 398 | const char *library_name; |
e04a16fb AG |
399 | { |
400 | tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type); | |
401 | DECL_EXTERNAL (decl) = 1; | |
402 | TREE_PUBLIC (decl) = 1; | |
403 | if (library_name) | |
404 | DECL_ASSEMBLER_NAME (decl) = get_identifier (library_name); | |
405 | make_decl_rtl (decl, NULL_PTR, 1); | |
406 | pushdecl (decl); | |
26db82d8 BS |
407 | DECL_BUILT_IN_CLASS (decl) = class; |
408 | DECL_FUNCTION_CODE (decl) = function_code; | |
e04a16fb AG |
409 | return decl; |
410 | } | |
411 | ||
412 | void | |
413 | init_decl_processing () | |
414 | { | |
0bd2e6db | 415 | register tree endlink; |
ab3a6dd6 | 416 | tree field = NULL_TREE; |
e04a16fb AG |
417 | tree t; |
418 | ||
419 | current_function_decl = NULL; | |
420 | current_binding_level = NULL_BINDING_LEVEL; | |
421 | free_binding_level = NULL_BINDING_LEVEL; | |
422 | pushlevel (0); /* make the binding_level structure for global names */ | |
423 | global_binding_level = current_binding_level; | |
424 | ||
425 | error_mark_node = make_node (ERROR_MARK); | |
426 | TREE_TYPE (error_mark_node) = error_mark_node; | |
427 | ||
428 | /* Create sizetype first - needed for other types. */ | |
429 | sizetype = make_unsigned_type (POINTER_SIZE); | |
430 | size_zero_node = build_int_2 (0, 0); | |
431 | TREE_TYPE (size_zero_node) = sizetype; | |
432 | size_one_node = build_int_2 (1, 0); | |
433 | TREE_TYPE (size_one_node) = sizetype; | |
434 | ||
435 | byte_type_node = make_signed_type (8); | |
436 | pushdecl (build_decl (TYPE_DECL, get_identifier ("byte"), byte_type_node)); | |
437 | short_type_node = make_signed_type (16); | |
438 | pushdecl (build_decl (TYPE_DECL, get_identifier ("short"), short_type_node)); | |
439 | int_type_node = make_signed_type (32); | |
440 | pushdecl (build_decl (TYPE_DECL, get_identifier ("int"), int_type_node)); | |
441 | long_type_node = make_signed_type (64); | |
442 | pushdecl (build_decl (TYPE_DECL, get_identifier ("long"), long_type_node)); | |
443 | ||
444 | unsigned_byte_type_node = make_unsigned_type (8); | |
445 | pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned byte"), | |
446 | unsigned_byte_type_node)); | |
447 | unsigned_short_type_node = make_unsigned_type (16); | |
448 | pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned short"), | |
449 | unsigned_short_type_node)); | |
450 | unsigned_int_type_node = make_unsigned_type (32); | |
451 | pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"), | |
452 | unsigned_int_type_node)); | |
453 | unsigned_long_type_node = make_unsigned_type (64); | |
454 | pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned long"), | |
455 | unsigned_long_type_node)); | |
456 | ||
9d45bec2 | 457 | integer_type_node = type_for_size (INT_TYPE_SIZE, 0); |
e04a16fb AG |
458 | |
459 | integer_zero_node = build_int_2 (0, 0); | |
460 | integer_one_node = build_int_2 (1, 0); | |
461 | integer_two_node = build_int_2 (2, 0); | |
462 | integer_four_node = build_int_2 (4, 0); | |
463 | integer_negative_one_node = build_int_2 (-1, 0); | |
464 | ||
4a5f66c3 APB |
465 | long_zero_node = build_int_2 (0, 0); |
466 | TREE_TYPE (long_zero_node) = long_type_node; | |
467 | ||
e04a16fb AG |
468 | void_type_node = make_node (VOID_TYPE); |
469 | pushdecl (build_decl (TYPE_DECL, get_identifier ("void"), void_type_node)); | |
470 | layout_type (void_type_node); /* Uses size_zero_node */ | |
471 | ptr_type_node = build_pointer_type (void_type_node); | |
472 | t = make_node (VOID_TYPE); | |
473 | layout_type (t); /* Uses size_zero_node */ | |
474 | return_address_type_node = build_pointer_type (t); | |
475 | ||
476 | null_pointer_node = build_int_2 (0, 0); | |
477 | TREE_TYPE (null_pointer_node) = ptr_type_node; | |
478 | ||
9bbc7d9f PB |
479 | /* Used by the parser to represent empty statements and blocks. */ |
480 | empty_stmt_node = build1 (NOP_EXPR, void_type_node, size_zero_node); | |
481 | CAN_COMPLETE_NORMALLY (empty_stmt_node) = 1; | |
482 | ||
e04a16fb AG |
483 | #if 0 |
484 | /* Make a type to be the domain of a few array types | |
485 | whose domains don't really matter. | |
486 | 200 is small enough that it always fits in size_t | |
487 | and large enough that it can hold most function names for the | |
488 | initializations of __FUNCTION__ and __PRETTY_FUNCTION__. */ | |
489 | short_array_type_node = build_prim_array_type (short_type_node, 200); | |
490 | #endif | |
491 | char_type_node = make_node (CHAR_TYPE); | |
492 | TYPE_PRECISION (char_type_node) = 16; | |
493 | fixup_unsigned_type (char_type_node); | |
494 | pushdecl (build_decl (TYPE_DECL, get_identifier ("char"), char_type_node)); | |
495 | ||
496 | boolean_type_node = make_node (BOOLEAN_TYPE); | |
497 | TYPE_PRECISION (boolean_type_node) = 1; | |
498 | fixup_unsigned_type (boolean_type_node); | |
499 | pushdecl (build_decl (TYPE_DECL, get_identifier ("boolean"), | |
500 | boolean_type_node)); | |
501 | boolean_false_node = TYPE_MIN_VALUE (boolean_type_node); | |
502 | boolean_true_node = TYPE_MAX_VALUE (boolean_type_node); | |
503 | ||
504 | promoted_byte_type_node | |
505 | = push_promoted_type ("promoted_byte", byte_type_node); | |
506 | promoted_short_type_node | |
507 | = push_promoted_type ("promoted_short", short_type_node); | |
508 | promoted_char_type_node | |
509 | = push_promoted_type ("promoted_char", char_type_node); | |
510 | promoted_boolean_type_node | |
511 | = push_promoted_type ("promoted_boolean", boolean_type_node); | |
512 | ||
513 | float_type_node = make_node (REAL_TYPE); | |
514 | TYPE_PRECISION (float_type_node) = 32; | |
515 | pushdecl (build_decl (TYPE_DECL, get_identifier ("float"), | |
516 | float_type_node)); | |
517 | layout_type (float_type_node); | |
518 | ||
519 | double_type_node = make_node (REAL_TYPE); | |
520 | TYPE_PRECISION (double_type_node) = 64; | |
521 | pushdecl (build_decl (TYPE_DECL, get_identifier ("double"), | |
522 | double_type_node)); | |
523 | layout_type (double_type_node); | |
524 | ||
4a5f66c3 APB |
525 | float_zero_node = build_real (float_type_node, dconst0); |
526 | double_zero_node = build_real (double_type_node, dconst0); | |
527 | ||
5423609c APB |
528 | /* As your adding items here, please update the code right after |
529 | this section, so that the filename containing the source code of | |
530 | the pre-defined class gets registered correctly. */ | |
c877974e | 531 | unqualified_object_id_node = get_identifier ("Object"); |
e04a16fb AG |
532 | object_type_node = lookup_class (get_identifier ("java.lang.Object")); |
533 | object_ptr_type_node = promote_type (object_type_node); | |
534 | string_type_node = lookup_class (get_identifier ("java.lang.String")); | |
cd9643f7 | 535 | string_ptr_type_node = promote_type (string_type_node); |
e04a16fb AG |
536 | class_type_node = lookup_class (get_identifier ("java.lang.Class")); |
537 | throwable_type_node = lookup_class (get_identifier ("java.lang.Throwable")); | |
b9f7e36c APB |
538 | runtime_exception_type_node = |
539 | lookup_class (get_identifier ("java.lang.RuntimeException")); | |
540 | error_exception_type_node = | |
541 | lookup_class (get_identifier ("java.lang.Error")); | |
e04a16fb | 542 | |
5423609c APB |
543 | /* This section has to be updated as items are added to the previous |
544 | section. */ | |
545 | predef_filenames_size = 6; | |
546 | predef_filenames = (tree *)xmalloc (predef_filenames_size * sizeof (tree)); | |
547 | predef_filenames [0] = get_identifier ("java/lang/Class.java"); | |
548 | predef_filenames [1] = get_identifier ("java/lang/Error.java"); | |
549 | predef_filenames [2] = get_identifier ("java/lang/Object.java"); | |
550 | predef_filenames [3] = get_identifier ("java/lang/RuntimeException.java"); | |
551 | predef_filenames [4] = get_identifier ("java/lang/String.java"); | |
552 | predef_filenames [5] = get_identifier ("java/lang/Throwable.java"); | |
553 | ||
e04a16fb AG |
554 | methodtable_type = make_node (RECORD_TYPE); |
555 | layout_type (methodtable_type); | |
5e942c50 | 556 | build_decl (TYPE_DECL, get_identifier ("methodtable"), methodtable_type); |
e04a16fb AG |
557 | methodtable_ptr_type = build_pointer_type (methodtable_type); |
558 | ||
559 | TYPE_identifier_node = get_identifier ("TYPE"); | |
560 | init_identifier_node = get_identifier ("<init>"); | |
561 | clinit_identifier_node = get_identifier ("<clinit>"); | |
157412f5 | 562 | finit_identifier_node = get_identifier ("$finit$"); |
e04a16fb AG |
563 | void_signature_node = get_identifier ("()V"); |
564 | length_identifier_node = get_identifier ("length"); | |
565 | this_identifier_node = get_identifier ("this"); | |
566 | super_identifier_node = get_identifier ("super"); | |
f1b0c0d8 | 567 | continue_identifier_node = get_identifier ("continue"); |
e04a16fb AG |
568 | |
569 | /* for lack of a better place to put this stub call */ | |
570 | init_expr_processing(); | |
571 | ||
572 | utf8const_type = make_node (RECORD_TYPE); | |
573 | PUSH_FIELD (utf8const_type, field, "hash", unsigned_short_type_node); | |
574 | PUSH_FIELD (utf8const_type, field, "length", unsigned_short_type_node); | |
575 | FINISH_RECORD (utf8const_type); | |
576 | utf8const_ptr_type = build_pointer_type (utf8const_type); | |
577 | ||
578 | constants_type_node = make_node (RECORD_TYPE); | |
579 | PUSH_FIELD (constants_type_node, field, "size", unsigned_int_type_node); | |
580 | PUSH_FIELD (constants_type_node, field, "tags", ptr_type_node); | |
581 | PUSH_FIELD (constants_type_node, field, "data", ptr_type_node); | |
582 | FINISH_RECORD (constants_type_node); | |
5e942c50 | 583 | build_decl (TYPE_DECL, get_identifier ("constants"), constants_type_node); |
e04a16fb AG |
584 | |
585 | access_flags_type_node = unsigned_short_type_node; | |
586 | ||
587 | dtable_type = make_node (RECORD_TYPE); | |
588 | dtable_ptr_type = build_pointer_type (dtable_type); | |
589 | ||
78857b4e | 590 | PUSH_FIELD (object_type_node, field, "vtable", dtable_ptr_type); |
e04a16fb AG |
591 | PUSH_FIELD (object_type_node, field, "sync_info", ptr_type_node); |
592 | for (t = TYPE_FIELDS (object_type_node); t != NULL_TREE; t = TREE_CHAIN (t)) | |
593 | FIELD_PRIVATE (t) = 1; | |
594 | FINISH_RECORD (object_type_node); | |
595 | ||
596 | class_dtable_decl = build_dtable_decl (class_type_node); | |
597 | TREE_STATIC (class_dtable_decl) = 1; | |
598 | DECL_ARTIFICIAL (class_dtable_decl) = 1; | |
599 | DECL_IGNORED_P (class_dtable_decl) = 1; | |
600 | rest_of_decl_compilation (class_dtable_decl, (char*) 0, 1, 0); | |
601 | ||
602 | field_type_node = make_node (RECORD_TYPE); | |
603 | field_ptr_type_node = build_pointer_type (field_type_node); | |
604 | method_type_node = make_node (RECORD_TYPE); | |
605 | method_ptr_type_node = build_pointer_type (method_type_node); | |
606 | ||
607 | set_super_info (0, class_type_node, object_type_node, 0); | |
608 | set_super_info (0, string_type_node, object_type_node, 0); | |
609 | class_ptr_type = build_pointer_type (class_type_node); | |
610 | ||
611 | PUSH_FIELD (class_type_node, field, "next", class_ptr_type); | |
612 | PUSH_FIELD (class_type_node, field, "name", utf8const_ptr_type); | |
613 | PUSH_FIELD (class_type_node, field, "accflags", access_flags_type_node); | |
614 | PUSH_FIELD (class_type_node, field, "superclass", class_ptr_type); | |
e04a16fb AG |
615 | PUSH_FIELD (class_type_node, field, "constants", constants_type_node); |
616 | PUSH_FIELD (class_type_node, field, "methods", method_ptr_type_node); | |
571d54d5 | 617 | PUSH_FIELD (class_type_node, field, "method_count", short_type_node); |
78857b4e | 618 | PUSH_FIELD (class_type_node, field, "vtable_method_count", short_type_node); |
e04a16fb | 619 | PUSH_FIELD (class_type_node, field, "fields", field_ptr_type_node); |
571d54d5 TT |
620 | PUSH_FIELD (class_type_node, field, "size_in_bytes", int_type_node); |
621 | PUSH_FIELD (class_type_node, field, "field_count", short_type_node); | |
622 | PUSH_FIELD (class_type_node, field, "static_field_count", short_type_node); | |
78857b4e | 623 | PUSH_FIELD (class_type_node, field, "vtable", dtable_ptr_type); |
e04a16fb AG |
624 | PUSH_FIELD (class_type_node, field, "interfaces", |
625 | build_pointer_type (class_ptr_type)); | |
626 | PUSH_FIELD (class_type_node, field, "loader", ptr_type_node); | |
571d54d5 | 627 | PUSH_FIELD (class_type_node, field, "interface_count", short_type_node); |
e04a16fb | 628 | PUSH_FIELD (class_type_node, field, "state", byte_type_node); |
9d45bec2 | 629 | PUSH_FIELD (class_type_node, field, "thread", ptr_type_node); |
e04a16fb AG |
630 | for (t = TYPE_FIELDS (class_type_node); t != NULL_TREE; t = TREE_CHAIN (t)) |
631 | FIELD_PRIVATE (t) = 1; | |
632 | push_super_field (class_type_node, object_type_node); | |
633 | FINISH_RECORD (class_type_node); | |
5e942c50 | 634 | build_decl (TYPE_DECL, get_identifier ("Class"), class_type_node); |
e04a16fb AG |
635 | |
636 | field_info_union_node = make_node (UNION_TYPE); | |
637 | PUSH_FIELD (field_info_union_node, field, "boffset", int_type_node); | |
638 | PUSH_FIELD (field_info_union_node, field, "addr", ptr_type_node); | |
639 | #if 0 | |
640 | PUSH_FIELD (field_info_union_node, field, "idx", unsigned_short_type_node); | |
641 | #endif | |
642 | layout_type (field_info_union_node); | |
643 | ||
644 | PUSH_FIELD (field_type_node, field, "name", utf8const_ptr_type); | |
645 | PUSH_FIELD (field_type_node, field, "type", class_ptr_type); | |
646 | PUSH_FIELD (field_type_node, field, "accflags", access_flags_type_node); | |
647 | PUSH_FIELD (field_type_node, field, "bsize", unsigned_short_type_node); | |
648 | PUSH_FIELD (field_type_node, field, "info", field_info_union_node); | |
649 | FINISH_RECORD (field_type_node); | |
650 | CLASS_LOADED_P (field_type_node) = 1; | |
5e942c50 | 651 | build_decl (TYPE_DECL, get_identifier ("Field"), field_type_node); |
e04a16fb AG |
652 | |
653 | one_elt_array_domain_type = build_index_type (integer_one_node); | |
654 | nativecode_ptr_array_type_node | |
655 | = build_array_type (nativecode_ptr_type_node, one_elt_array_domain_type); | |
656 | ||
657 | PUSH_FIELD (dtable_type, field, "class", class_ptr_type); | |
658 | PUSH_FIELD (dtable_type, field, "methods", nativecode_ptr_array_type_node); | |
659 | FINISH_RECORD (dtable_type); | |
5e942c50 | 660 | build_decl (TYPE_DECL, get_identifier ("dispatchTable"), dtable_type); |
e04a16fb AG |
661 | |
662 | #define jint_type int_type_node | |
663 | #define jint_ptr_type ptr_type_node | |
664 | ||
665 | jexception_type = make_node (RECORD_TYPE); | |
666 | PUSH_FIELD (jexception_type, field, "start_pc", ptr_type_node); | |
667 | PUSH_FIELD (jexception_type, field, "end_pc", ptr_type_node); | |
668 | PUSH_FIELD (jexception_type, field, "handler_pc", ptr_type_node); | |
669 | PUSH_FIELD (jexception_type, field, "catch_type", class_ptr_type); | |
670 | FINISH_RECORD (jexception_type); | |
5e942c50 | 671 | build_decl (TYPE_DECL, get_identifier ("jexception"), field_type_node); |
e04a16fb AG |
672 | jexception_ptr_type = build_pointer_type (jexception_type); |
673 | ||
674 | lineNumberEntry_type = make_node (RECORD_TYPE); | |
675 | PUSH_FIELD (lineNumberEntry_type, field, "line_nr", unsigned_short_type_node); | |
676 | PUSH_FIELD (lineNumberEntry_type, field, "start_pc", ptr_type_node); | |
677 | FINISH_RECORD (lineNumberEntry_type); | |
678 | ||
679 | lineNumbers_type = make_node (RECORD_TYPE); | |
680 | PUSH_FIELD (lineNumbers_type, field, "length", unsigned_int_type_node); | |
681 | FINISH_RECORD (lineNumbers_type); | |
682 | ||
683 | #define instn_ptr_type_node ptr_type_node /* XXX JH */ | |
684 | ||
685 | #define lineNumbers_ptr_type_node build_pointer_type(lineNumbers_type) | |
686 | ||
687 | PUSH_FIELD (method_type_node, field, "name", utf8const_ptr_type); | |
688 | PUSH_FIELD (method_type_node, field, "signature", utf8const_ptr_type); | |
689 | PUSH_FIELD (method_type_node, field, "accflags", access_flags_type_node); | |
690 | PUSH_FIELD (method_type_node, field, "ncode", nativecode_ptr_type_node); | |
691 | FINISH_RECORD (method_type_node); | |
692 | CLASS_LOADED_P (method_type_node) = 1; | |
5e942c50 | 693 | build_decl (TYPE_DECL, get_identifier ("Method"), method_type_node); |
e04a16fb | 694 | |
0bd2e6db PB |
695 | endlink = end_params_node = tree_cons (NULL_TREE, void_type_node, NULL_TREE); |
696 | ||
e04a16fb | 697 | t = tree_cons (NULL_TREE, class_ptr_type, |
0bd2e6db | 698 | tree_cons (NULL_TREE, int_type_node, endlink)); |
e04a16fb AG |
699 | alloc_object_node = builtin_function ("_Jv_AllocObject", |
700 | build_function_type (ptr_type_node, t), | |
26db82d8 | 701 | 0, NOT_BUILT_IN, NULL_PTR); |
1684f874 | 702 | DECL_IS_MALLOC (alloc_object_node) = 1; |
e04a16fb AG |
703 | soft_initclass_node = builtin_function ("_Jv_InitClass", |
704 | build_function_type (void_type_node, | |
705 | t), | |
26db82d8 BS |
706 | 0, NOT_BUILT_IN, |
707 | NULL_PTR); | |
0bd2e6db | 708 | t = tree_cons (NULL_TREE, ptr_type_node, endlink); |
8bbb23b7 AH |
709 | throw_node[0] = builtin_function ("_Jv_Throw", |
710 | build_function_type (ptr_type_node, t), | |
711 | 0, NOT_BUILT_IN, NULL_PTR); | |
712 | /* Mark throw_nodes as `noreturn' functions with side effects. */ | |
713 | TREE_THIS_VOLATILE (throw_node[0]) = 1; | |
714 | TREE_SIDE_EFFECTS (throw_node[0]) = 1; | |
715 | t = tree_cons (NULL_TREE, ptr_type_node, endlink); | |
716 | throw_node[1] = builtin_function ("_Jv_Sjlj_Throw", | |
717 | build_function_type (ptr_type_node, t), | |
718 | 0, NOT_BUILT_IN, NULL_PTR); | |
719 | TREE_THIS_VOLATILE (throw_node[1]) = 1; | |
720 | TREE_SIDE_EFFECTS (throw_node[1]) = 1; | |
0bd2e6db | 721 | t = build_function_type (int_type_node, endlink); |
e04a16fb | 722 | soft_monitorenter_node |
26db82d8 BS |
723 | = builtin_function ("_Jv_MonitorEnter", t, 0, NOT_BUILT_IN, |
724 | NULL_PTR); | |
e04a16fb | 725 | soft_monitorexit_node |
26db82d8 BS |
726 | = builtin_function ("_Jv_MonitorExit", t, 0, NOT_BUILT_IN, |
727 | NULL_PTR); | |
e04a16fb AG |
728 | |
729 | t = tree_cons (NULL_TREE, int_type_node, | |
0bd2e6db | 730 | tree_cons (NULL_TREE, int_type_node, endlink)); |
e04a16fb AG |
731 | soft_newarray_node |
732 | = builtin_function ("_Jv_NewArray", | |
733 | build_function_type(ptr_type_node, t), | |
26db82d8 | 734 | 0, NOT_BUILT_IN, NULL_PTR); |
1684f874 | 735 | DECL_IS_MALLOC (soft_newarray_node) = 1; |
e04a16fb AG |
736 | |
737 | t = tree_cons (NULL_TREE, int_type_node, | |
738 | tree_cons (NULL_TREE, class_ptr_type, | |
0bd2e6db | 739 | tree_cons (NULL_TREE, object_ptr_type_node, endlink))); |
e04a16fb AG |
740 | soft_anewarray_node |
741 | = builtin_function ("_Jv_NewObjectArray", | |
742 | build_function_type (ptr_type_node, t), | |
26db82d8 | 743 | 0, NOT_BUILT_IN, NULL_PTR); |
1684f874 | 744 | DECL_IS_MALLOC (soft_anewarray_node) = 1; |
e04a16fb AG |
745 | |
746 | t = tree_cons (NULL_TREE, ptr_type_node, | |
0bd2e6db | 747 | tree_cons (NULL_TREE, int_type_node, endlink)); |
e04a16fb AG |
748 | soft_multianewarray_node |
749 | = builtin_function ("_Jv_NewMultiArray", | |
750 | build_function_type (ptr_type_node, t), | |
26db82d8 | 751 | 0, NOT_BUILT_IN, NULL_PTR); |
1684f874 | 752 | DECL_IS_MALLOC (soft_multianewarray_node) = 1; |
e04a16fb | 753 | |
9d45bec2 | 754 | t = build_function_type (void_type_node, |
0bd2e6db | 755 | tree_cons (NULL_TREE, int_type_node, endlink)); |
e04a16fb | 756 | soft_badarrayindex_node |
9d45bec2 | 757 | = builtin_function ("_Jv_ThrowBadArrayIndex", t, |
26db82d8 | 758 | 0, NOT_BUILT_IN, NULL_PTR); |
1684f874 AG |
759 | /* Mark soft_badarrayindex_node as a `noreturn' function with side |
760 | effects. */ | |
e04a16fb AG |
761 | TREE_THIS_VOLATILE (soft_badarrayindex_node) = 1; |
762 | TREE_SIDE_EFFECTS (soft_badarrayindex_node) = 1; | |
763 | ||
764 | t = tree_cons (NULL_TREE, class_ptr_type, | |
0bd2e6db | 765 | tree_cons (NULL_TREE, object_ptr_type_node, endlink)); |
e04a16fb AG |
766 | soft_checkcast_node |
767 | = builtin_function ("_Jv_CheckCast", | |
768 | build_function_type (ptr_type_node, t), | |
26db82d8 | 769 | 0, NOT_BUILT_IN, NULL_PTR); |
e04a16fb | 770 | t = tree_cons (NULL_TREE, object_ptr_type_node, |
0bd2e6db | 771 | tree_cons (NULL_TREE, class_ptr_type, endlink)); |
e04a16fb AG |
772 | soft_instanceof_node |
773 | = builtin_function ("_Jv_IsInstanceOf", | |
774 | build_function_type (promoted_boolean_type_node, t), | |
26db82d8 | 775 | 0, NOT_BUILT_IN, NULL_PTR); |
e04a16fb | 776 | t = tree_cons (NULL_TREE, object_ptr_type_node, |
0bd2e6db | 777 | tree_cons (NULL_TREE, object_ptr_type_node, endlink)); |
e04a16fb AG |
778 | soft_checkarraystore_node |
779 | = builtin_function ("_Jv_CheckArrayStore", | |
780 | build_function_type (void_type_node, t), | |
26db82d8 | 781 | 0, NOT_BUILT_IN, NULL_PTR); |
e04a16fb AG |
782 | t = tree_cons (NULL_TREE, ptr_type_node, |
783 | tree_cons (NULL_TREE, ptr_type_node, | |
0bd2e6db | 784 | tree_cons (NULL_TREE, ptr_type_node, endlink))); |
e04a16fb AG |
785 | soft_lookupinterfacemethod_node |
786 | = builtin_function ("_Jv_LookupInterfaceMethod", | |
9d45bec2 | 787 | build_function_type (ptr_type_node, t), |
26db82d8 | 788 | 0, NOT_BUILT_IN, NULL_PTR); |
e04a16fb | 789 | t = tree_cons (NULL_TREE, double_type_node, |
0bd2e6db | 790 | tree_cons (NULL_TREE, double_type_node, endlink)); |
e04a16fb AG |
791 | soft_fmod_node |
792 | = builtin_function ("__builtin_fmod", | |
793 | build_function_type (double_type_node, t), | |
26db82d8 | 794 | BUILT_IN_FMOD, BUILT_IN_NORMAL, "fmod"); |
9d45bec2 | 795 | |
9d45bec2 PB |
796 | soft_exceptioninfo_call_node |
797 | = build (CALL_EXPR, | |
798 | ptr_type_node, | |
799 | build_address_of | |
800 | (builtin_function ("_Jv_exception_info", | |
0bd2e6db | 801 | build_function_type (ptr_type_node, endlink), |
26db82d8 | 802 | 0, NOT_BUILT_IN, NULL_PTR)), |
9d45bec2 PB |
803 | NULL_TREE, NULL_TREE); |
804 | TREE_SIDE_EFFECTS (soft_exceptioninfo_call_node) = 1; | |
e04a16fb AG |
805 | #if 0 |
806 | t = tree_cons (NULL_TREE, float_type_node, | |
0bd2e6db | 807 | tree_cons (NULL_TREE, float_type_node, endlink)); |
e04a16fb AG |
808 | soft_fmodf_node |
809 | = builtin_function ("__builtin_fmodf", | |
810 | build_function_type (float_type_node, t), | |
26db82d8 | 811 | BUILT_IN_FMOD, BUILT_IN_NORMAL, "fmodf"); |
e04a16fb AG |
812 | #endif |
813 | ||
aa4759c1 AH |
814 | soft_idiv_node |
815 | = builtin_function ("_Jv_divI", | |
816 | build_function_type (int_type_node, t), | |
26db82d8 | 817 | 0, NOT_BUILT_IN, NULL_PTR); |
aa4759c1 AH |
818 | |
819 | soft_irem_node | |
820 | = builtin_function ("_Jv_remI", | |
821 | build_function_type (int_type_node, t), | |
26db82d8 | 822 | 0, NOT_BUILT_IN, NULL_PTR); |
aa4759c1 AH |
823 | |
824 | soft_ldiv_node | |
825 | = builtin_function ("_Jv_divJ", | |
826 | build_function_type (long_type_node, t), | |
26db82d8 | 827 | 0, NOT_BUILT_IN, NULL_PTR); |
aa4759c1 AH |
828 | |
829 | soft_lrem_node | |
830 | = builtin_function ("_Jv_remJ", | |
831 | build_function_type (long_type_node, t), | |
26db82d8 | 832 | 0, NOT_BUILT_IN, NULL_PTR); |
aa4759c1 | 833 | |
e04a16fb AG |
834 | init_class_processing (); |
835 | } | |
836 | ||
837 | ||
838 | /* Look up NAME in the current binding level and its superiors | |
839 | in the namespace of variables, functions and typedefs. | |
840 | Return a ..._DECL node of some kind representing its definition, | |
841 | or return 0 if it is undefined. */ | |
842 | ||
843 | tree | |
844 | lookup_name (name) | |
845 | tree name; | |
846 | { | |
847 | register tree val; | |
848 | if (current_binding_level != global_binding_level | |
849 | && IDENTIFIER_LOCAL_VALUE (name)) | |
850 | val = IDENTIFIER_LOCAL_VALUE (name); | |
851 | else | |
852 | val = IDENTIFIER_GLOBAL_VALUE (name); | |
853 | return val; | |
854 | } | |
855 | ||
856 | /* Similar to `lookup_name' but look only at current binding level and | |
857 | the previous one if its the parameter level. */ | |
858 | ||
4bcde32e | 859 | static tree |
e04a16fb AG |
860 | lookup_name_current_level (name) |
861 | tree name; | |
862 | { | |
863 | register tree t; | |
864 | ||
865 | if (current_binding_level == global_binding_level) | |
866 | return IDENTIFIER_GLOBAL_VALUE (name); | |
867 | ||
868 | if (IDENTIFIER_LOCAL_VALUE (name) == 0) | |
869 | return 0; | |
870 | ||
871 | for (t = current_binding_level->names; t; t = TREE_CHAIN (t)) | |
872 | if (DECL_NAME (t) == name) | |
873 | break; | |
874 | ||
875 | return t; | |
876 | } | |
877 | ||
878 | /* Use a binding level to record a labeled block declaration */ | |
879 | ||
880 | void | |
881 | push_labeled_block (lb) | |
882 | tree lb; | |
883 | { | |
884 | register tree name = DECL_NAME (LABELED_BLOCK_LABEL (lb)); | |
885 | register struct binding_level *b = current_binding_level; | |
886 | tree oldlocal = IDENTIFIER_LOCAL_VALUE (name); | |
887 | if (oldlocal != 0) | |
888 | b->shadowed = tree_cons (name, oldlocal, b->shadowed); | |
889 | TREE_CHAIN (lb) = b->names; | |
890 | b->names = lb; | |
891 | IDENTIFIER_LOCAL_VALUE (name) = lb; | |
892 | } | |
893 | ||
894 | /* Pop the current binding level, reinstalling values for the previous | |
895 | labeled block */ | |
896 | ||
897 | void | |
898 | pop_labeled_block () | |
899 | { | |
900 | struct binding_level *b = current_binding_level; | |
901 | tree label = b->names; | |
902 | IDENTIFIER_LOCAL_VALUE (DECL_NAME (LABELED_BLOCK_LABEL (label))) = | |
903 | NULL_TREE; | |
904 | if (b->shadowed) | |
905 | IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (b->shadowed)) = | |
906 | TREE_VALUE (b->shadowed); | |
907 | ||
908 | /* Pop the current level, and free the structure for reuse. */ | |
909 | current_binding_level = current_binding_level->level_chain; | |
910 | b->level_chain = free_binding_level; | |
911 | free_binding_level = b; | |
912 | } | |
913 | ||
914 | /* Record a decl-node X as belonging to the current lexical scope. | |
915 | Check for errors (such as an incompatible declaration for the same | |
916 | name already seen in the same scope). | |
917 | ||
918 | Returns either X or an old decl for the same name. | |
919 | If an old decl is returned, it may have been smashed | |
920 | to agree with what X says. */ | |
921 | ||
922 | tree | |
923 | pushdecl (x) | |
924 | tree x; | |
925 | { | |
926 | register tree t; | |
927 | register tree name = DECL_NAME (x); | |
928 | register struct binding_level *b = current_binding_level; | |
929 | ||
930 | DECL_CONTEXT (x) = current_function_decl; | |
931 | if (name) | |
932 | { | |
c8e7d2e6 | 933 | const char *file; |
e04a16fb | 934 | int line; |
e04a16fb AG |
935 | |
936 | t = lookup_name_current_level (name); | |
937 | if (t != 0 && t == error_mark_node) | |
938 | /* error_mark_node is 0 for a while during initialization! */ | |
939 | { | |
940 | t = 0; | |
941 | error_with_decl (x, "`%s' used prior to declaration"); | |
942 | } | |
943 | ||
944 | if (t != 0) | |
945 | { | |
946 | file = DECL_SOURCE_FILE (t); | |
947 | line = DECL_SOURCE_LINE (t); | |
948 | } | |
949 | ||
950 | /* If we're naming a hitherto-unnamed type, set its TYPE_NAME | |
951 | to point to the TYPE_DECL. | |
952 | Since Java does not have typedefs, a type can only have | |
953 | one (true) name, given by a class, interface, or builtin. */ | |
954 | if (TREE_CODE (x) == TYPE_DECL | |
955 | && TYPE_NAME (TREE_TYPE (x)) == 0 | |
956 | && TREE_TYPE (x) != error_mark_node) | |
957 | { | |
958 | TYPE_NAME (TREE_TYPE (x)) = x; | |
959 | TYPE_STUB_DECL (TREE_TYPE (x)) = x; | |
960 | } | |
961 | ||
962 | /* This name is new in its binding level. | |
963 | Install the new declaration and return it. */ | |
964 | if (b == global_binding_level) | |
965 | { | |
966 | /* Install a global value. */ | |
967 | ||
968 | IDENTIFIER_GLOBAL_VALUE (name) = x; | |
969 | } | |
970 | else | |
971 | { | |
972 | /* Here to install a non-global value. */ | |
973 | tree oldlocal = IDENTIFIER_LOCAL_VALUE (name); | |
e04a16fb AG |
974 | IDENTIFIER_LOCAL_VALUE (name) = x; |
975 | ||
976 | #if 0 | |
977 | /* Warn if shadowing an argument at the top level of the body. */ | |
978 | if (oldlocal != 0 && !DECL_EXTERNAL (x) | |
979 | /* This warning doesn't apply to the parms of a nested fcn. */ | |
980 | && ! current_binding_level->parm_flag | |
981 | /* Check that this is one level down from the parms. */ | |
982 | && current_binding_level->level_chain->parm_flag | |
983 | /* Check that the decl being shadowed | |
984 | comes from the parm level, one level up. */ | |
985 | && chain_member (oldlocal, current_binding_level->level_chain->names)) | |
986 | { | |
987 | if (TREE_CODE (oldlocal) == PARM_DECL) | |
988 | pedwarn ("declaration of `%s' shadows a parameter", | |
989 | IDENTIFIER_POINTER (name)); | |
990 | else | |
991 | pedwarn ("declaration of `%s' shadows a symbol from the parameter list", | |
992 | IDENTIFIER_POINTER (name)); | |
993 | } | |
994 | ||
995 | /* Maybe warn if shadowing something else. */ | |
996 | else if (warn_shadow && !DECL_EXTERNAL (x) | |
997 | /* No shadow warnings for internally generated vars. */ | |
998 | && DECL_SOURCE_LINE (x) != 0 | |
999 | /* No shadow warnings for vars made for inlining. */ | |
1000 | && ! DECL_FROM_INLINE (x)) | |
1001 | { | |
c8e7d2e6 | 1002 | const char *warnstring = 0; |
e04a16fb AG |
1003 | |
1004 | if (TREE_CODE (x) == PARM_DECL | |
1005 | && current_binding_level->level_chain->parm_flag) | |
1006 | /* Don't warn about the parm names in function declarator | |
1007 | within a function declarator. | |
1008 | It would be nice to avoid warning in any function | |
1009 | declarator in a declaration, as opposed to a definition, | |
1010 | but there is no way to tell it's not a definition. */ | |
1011 | ; | |
1012 | else if (oldlocal != 0 && TREE_CODE (oldlocal) == PARM_DECL) | |
1013 | warnstring = "declaration of `%s' shadows a parameter"; | |
1014 | else if (oldlocal != 0) | |
1015 | warnstring = "declaration of `%s' shadows previous local"; | |
1016 | else if (IDENTIFIER_GLOBAL_VALUE (name) != 0 | |
1017 | && IDENTIFIER_GLOBAL_VALUE (name) != error_mark_node) | |
1018 | warnstring = "declaration of `%s' shadows global declaration"; | |
1019 | ||
1020 | if (warnstring) | |
1021 | warning (warnstring, IDENTIFIER_POINTER (name)); | |
1022 | } | |
1023 | #endif | |
1024 | ||
1025 | /* If storing a local value, there may already be one (inherited). | |
1026 | If so, record it for restoration when this binding level ends. */ | |
1027 | if (oldlocal != 0) | |
1028 | b->shadowed = tree_cons (name, oldlocal, b->shadowed); | |
1029 | } | |
1030 | } | |
1031 | ||
1032 | /* Put decls on list in reverse order. | |
1033 | We will reverse them later if necessary. */ | |
1034 | TREE_CHAIN (x) = b->names; | |
1035 | b->names = x; | |
1036 | ||
1037 | return x; | |
1038 | } | |
1039 | void | |
1040 | pushdecl_force_head (x) | |
1041 | tree x; | |
1042 | { | |
1043 | current_binding_level->names = x; | |
1044 | } | |
1045 | ||
1046 | /* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */ | |
1047 | ||
1048 | tree | |
1049 | pushdecl_top_level (x) | |
1050 | tree x; | |
1051 | { | |
1052 | register tree t; | |
1053 | register struct binding_level *b = current_binding_level; | |
1054 | ||
1055 | current_binding_level = global_binding_level; | |
1056 | t = pushdecl (x); | |
1057 | current_binding_level = b; | |
1058 | return t; | |
1059 | } | |
1060 | ||
1061 | /* Nonzero if we are currently in the global binding level. */ | |
1062 | ||
1063 | int | |
1064 | global_bindings_p () | |
1065 | { | |
1066 | return current_binding_level == global_binding_level; | |
1067 | } | |
1068 | ||
1069 | /* Return the list of declarations of the current level. | |
1070 | Note that this list is in reverse order unless/until | |
1071 | you nreverse it; and when you do nreverse it, you must | |
1072 | store the result back using `storedecls' or you will lose. */ | |
1073 | ||
1074 | tree | |
1075 | getdecls () | |
1076 | { | |
1077 | return current_binding_level->names; | |
1078 | } | |
1079 | ||
1080 | /* Create a new `struct binding_level'. */ | |
1081 | ||
1082 | static | |
1083 | struct binding_level * | |
1084 | make_binding_level () | |
1085 | { | |
1086 | /* NOSTRICT */ | |
1087 | return (struct binding_level *) xmalloc (sizeof (struct binding_level)); | |
1088 | } | |
1089 | ||
1090 | void | |
1091 | pushlevel (unused) | |
d4476be2 | 1092 | int unused ATTRIBUTE_UNUSED; |
e04a16fb AG |
1093 | { |
1094 | register struct binding_level *newlevel = NULL_BINDING_LEVEL; | |
1095 | ||
1096 | #if 0 | |
1097 | /* If this is the top level of a function, | |
1098 | just make sure that NAMED_LABELS is 0. */ | |
1099 | ||
1100 | if (current_binding_level == global_binding_level) | |
1101 | named_labels = 0; | |
1102 | #endif | |
1103 | ||
1104 | /* Reuse or create a struct for this binding level. */ | |
1105 | ||
1106 | if (free_binding_level) | |
1107 | { | |
1108 | newlevel = free_binding_level; | |
1109 | free_binding_level = free_binding_level->level_chain; | |
1110 | } | |
1111 | else | |
1112 | { | |
1113 | newlevel = make_binding_level (); | |
1114 | } | |
1115 | ||
1116 | /* Add this level to the front of the chain (stack) of levels that | |
1117 | are active. */ | |
1118 | ||
1119 | *newlevel = clear_binding_level; | |
1120 | newlevel->level_chain = current_binding_level; | |
1121 | current_binding_level = newlevel; | |
1122 | newlevel->keep = keep_next_level_flag; | |
1123 | keep_next_level_flag = 0; | |
1124 | newlevel->keep_if_subblocks = keep_next_if_subblocks; | |
1125 | keep_next_if_subblocks = 0; | |
1126 | } | |
1127 | ||
1128 | /* Exit a binding level. | |
1129 | Pop the level off, and restore the state of the identifier-decl mappings | |
1130 | that were in effect when this level was entered. | |
1131 | ||
1132 | If KEEP is nonzero, this level had explicit declarations, so | |
1133 | and create a "block" (a BLOCK node) for the level | |
1134 | to record its declarations and subblocks for symbol table output. | |
1135 | ||
1136 | If FUNCTIONBODY is nonzero, this level is the body of a function, | |
1137 | so create a block as if KEEP were set and also clear out all | |
1138 | label names. | |
1139 | ||
1140 | If REVERSE is nonzero, reverse the order of decls before putting | |
1141 | them into the BLOCK. */ | |
1142 | ||
1143 | tree | |
1144 | poplevel (keep, reverse, functionbody) | |
1145 | int keep; | |
1146 | int reverse; | |
1147 | int functionbody; | |
1148 | { | |
1149 | register tree link; | |
1150 | /* The chain of decls was accumulated in reverse order. | |
1151 | Put it into forward order, just for cleanliness. */ | |
1152 | tree decls; | |
1153 | tree subblocks = current_binding_level->blocks; | |
1154 | tree block = 0; | |
1155 | tree decl; | |
1156 | int block_previously_created; | |
1157 | ||
1158 | keep |= current_binding_level->keep; | |
1159 | ||
1160 | /* Get the decls in the order they were written. | |
1161 | Usually current_binding_level->names is in reverse order. | |
1162 | But parameter decls were previously put in forward order. */ | |
1163 | ||
1164 | if (reverse) | |
1165 | current_binding_level->names | |
1166 | = decls = nreverse (current_binding_level->names); | |
1167 | else | |
1168 | decls = current_binding_level->names; | |
1169 | ||
1170 | /* Output any nested inline functions within this block | |
1171 | if they weren't already output. */ | |
1172 | ||
1173 | for (decl = decls; decl; decl = TREE_CHAIN (decl)) | |
1174 | if (TREE_CODE (decl) == FUNCTION_DECL | |
1175 | && ! TREE_ASM_WRITTEN (decl) | |
1176 | && DECL_INITIAL (decl) != 0 | |
1177 | && TREE_ADDRESSABLE (decl)) | |
1178 | { | |
1179 | /* If this decl was copied from a file-scope decl | |
1180 | on account of a block-scope extern decl, | |
1181 | propagate TREE_ADDRESSABLE to the file-scope decl. | |
1182 | ||
1183 | DECL_ABSTRACT_ORIGIN can be set to itself if warn_return_type is | |
1184 | true, since then the decl goes through save_for_inline_copying. */ | |
1185 | if (DECL_ABSTRACT_ORIGIN (decl) != 0 | |
1186 | && DECL_ABSTRACT_ORIGIN (decl) != decl) | |
1187 | TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1; | |
1188 | else | |
1189 | { | |
1190 | push_function_context (); | |
1191 | output_inline_function (decl); | |
1192 | pop_function_context (); | |
1193 | } | |
1194 | } | |
1195 | ||
1196 | /* If there were any declarations in that level, | |
1197 | or if this level is a function body, | |
1198 | create a BLOCK to record them for the life of this function. */ | |
1199 | ||
1200 | block = 0; | |
1201 | block_previously_created = (current_binding_level->this_block != 0); | |
1202 | if (block_previously_created) | |
1203 | block = current_binding_level->this_block; | |
1204 | else if (keep || functionbody | |
1205 | || (current_binding_level->keep_if_subblocks && subblocks != 0)) | |
1206 | block = make_node (BLOCK); | |
1207 | if (block != 0) | |
1208 | { | |
1209 | BLOCK_VARS (block) = decls; | |
e04a16fb | 1210 | BLOCK_SUBBLOCKS (block) = subblocks; |
e04a16fb AG |
1211 | } |
1212 | ||
1213 | /* In each subblock, record that this is its superior. */ | |
1214 | ||
1215 | for (link = subblocks; link; link = TREE_CHAIN (link)) | |
1216 | BLOCK_SUPERCONTEXT (link) = block; | |
1217 | ||
1218 | /* Clear out the meanings of the local variables of this level. */ | |
1219 | ||
1220 | for (link = decls; link; link = TREE_CHAIN (link)) | |
1221 | { | |
1222 | tree name = DECL_NAME (link); | |
1223 | if (name != 0 && IDENTIFIER_LOCAL_VALUE (name) == link) | |
1224 | { | |
1225 | /* If the ident. was used or addressed via a local extern decl, | |
1226 | don't forget that fact. */ | |
1227 | if (DECL_EXTERNAL (link)) | |
1228 | { | |
1229 | if (TREE_USED (link)) | |
1230 | TREE_USED (name) = 1; | |
1231 | if (TREE_ADDRESSABLE (link)) | |
1232 | TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1; | |
1233 | } | |
1234 | IDENTIFIER_LOCAL_VALUE (name) = 0; | |
1235 | } | |
1236 | } | |
1237 | ||
1238 | /* Restore all name-meanings of the outer levels | |
1239 | that were shadowed by this level. */ | |
1240 | ||
1241 | for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link)) | |
1242 | IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link); | |
1243 | ||
1244 | /* If the level being exited is the top level of a function, | |
1245 | check over all the labels, and clear out the current | |
1246 | (function local) meanings of their names. */ | |
1247 | ||
1248 | if (functionbody) | |
1249 | { | |
1250 | /* If this is the top level block of a function, | |
1251 | the vars are the function's parameters. | |
1252 | Don't leave them in the BLOCK because they are | |
1253 | found in the FUNCTION_DECL instead. */ | |
1254 | ||
1255 | BLOCK_VARS (block) = 0; | |
1256 | ||
1257 | /* Clear out the definitions of all label names, | |
1258 | since their scopes end here, | |
1259 | and add them to BLOCK_VARS. */ | |
1260 | ||
1261 | #if 0 | |
1262 | for (link = named_labels; link; link = TREE_CHAIN (link)) | |
1263 | { | |
1264 | register tree label = TREE_VALUE (link); | |
1265 | ||
1266 | if (DECL_INITIAL (label) == 0) | |
1267 | { | |
1268 | error_with_decl (label, "label `%s' used but not defined"); | |
1269 | /* Avoid crashing later. */ | |
1270 | define_label (input_filename, lineno, | |
1271 | DECL_NAME (label)); | |
1272 | } | |
1273 | else if (warn_unused && !TREE_USED (label)) | |
1274 | warning_with_decl (label, "label `%s' defined but not used"); | |
1275 | IDENTIFIER_LABEL_VALUE (DECL_NAME (label)) = 0; | |
1276 | ||
1277 | /* Put the labels into the "variables" of the | |
1278 | top-level block, so debugger can see them. */ | |
1279 | TREE_CHAIN (label) = BLOCK_VARS (block); | |
1280 | BLOCK_VARS (block) = label; | |
1281 | } | |
1282 | #endif | |
1283 | } | |
1284 | ||
1285 | /* Pop the current level, and free the structure for reuse. */ | |
1286 | ||
1287 | { | |
1288 | register struct binding_level *level = current_binding_level; | |
1289 | current_binding_level = current_binding_level->level_chain; | |
1290 | ||
1291 | level->level_chain = free_binding_level; | |
1292 | free_binding_level = level; | |
1293 | } | |
1294 | ||
1295 | /* Dispose of the block that we just made inside some higher level. */ | |
1296 | if (functionbody) | |
1297 | DECL_INITIAL (current_function_decl) = block; | |
1298 | else if (block) | |
1299 | { | |
1300 | if (!block_previously_created) | |
1301 | current_binding_level->blocks | |
1302 | = chainon (current_binding_level->blocks, block); | |
1303 | } | |
1304 | /* If we did not make a block for the level just exited, | |
1305 | any blocks made for inner levels | |
1306 | (since they cannot be recorded as subblocks in that level) | |
1307 | must be carried forward so they will later become subblocks | |
1308 | of something else. */ | |
1309 | else if (subblocks) | |
1310 | current_binding_level->blocks | |
1311 | = chainon (current_binding_level->blocks, subblocks); | |
1312 | ||
1313 | /* Set the TYPE_CONTEXTs for all of the tagged types belonging to this | |
1314 | binding contour so that they point to the appropriate construct, i.e. | |
1315 | either to the current FUNCTION_DECL node, or else to the BLOCK node | |
1316 | we just constructed. | |
1317 | ||
1318 | Note that for tagged types whose scope is just the formal parameter | |
1319 | list for some function type specification, we can't properly set | |
1320 | their TYPE_CONTEXTs here, because we don't have a pointer to the | |
1321 | appropriate FUNCTION_TYPE node readily available to us. For those | |
1322 | cases, the TYPE_CONTEXTs of the relevant tagged type nodes get set | |
1323 | in `grokdeclarator' as soon as we have created the FUNCTION_TYPE | |
1324 | node which will represent the "scope" for these "parameter list local" | |
1325 | tagged types. | |
1326 | */ | |
1327 | ||
1328 | if (block) | |
1329 | TREE_USED (block) = 1; | |
1330 | return block; | |
1331 | } | |
1332 | ||
1333 | void | |
1334 | maybe_pushlevels (pc) | |
1335 | int pc; | |
1336 | { | |
1337 | while (pending_local_decls != NULL_TREE && | |
1338 | DECL_LOCAL_START_PC (pending_local_decls) <= pc) | |
1339 | { | |
1340 | tree *ptr = &pending_local_decls; | |
1341 | tree decl = *ptr; | |
1342 | int end_pc = DECL_LOCAL_END_PC (decl); | |
1343 | ||
1344 | while (*ptr != NULL_TREE | |
1345 | && DECL_LOCAL_START_PC (*ptr) <= pc | |
1346 | && DECL_LOCAL_END_PC (*ptr) == end_pc) | |
1347 | ptr = &TREE_CHAIN (*ptr); | |
1348 | pending_local_decls = *ptr; | |
1349 | *ptr = NULL_TREE; | |
1350 | ||
1351 | /* Force non-nested range to be nested in current range. */ | |
1352 | if (end_pc > current_binding_level->end_pc) | |
1353 | end_pc = current_binding_level->end_pc; | |
1354 | ||
1355 | pushlevel (1); | |
1356 | expand_start_bindings (0); | |
1357 | current_binding_level->end_pc = end_pc; | |
1358 | ||
1359 | current_binding_level->names = decl; | |
1360 | for ( ; decl != NULL_TREE; decl = TREE_CHAIN (decl)) | |
1361 | { | |
1362 | push_jvm_slot (DECL_LOCAL_SLOT_NUMBER (decl), decl); | |
1363 | } | |
1364 | } | |
1365 | } | |
1366 | ||
1367 | void | |
1368 | maybe_poplevels (pc) | |
1369 | int pc; | |
1370 | { | |
1371 | while (current_binding_level->end_pc <= pc) | |
1372 | { | |
1373 | expand_end_bindings (getdecls (), 1, 0); | |
1374 | poplevel (1, 0, 0); | |
1375 | } | |
1376 | } | |
1377 | ||
1378 | /* Insert BLOCK at the end of the list of subblocks of the | |
1379 | current binding level. This is used when a BIND_EXPR is expanded, | |
1380 | to handle the BLOCK node inside the BIND_EXPR. */ | |
1381 | ||
1382 | void | |
1383 | insert_block (block) | |
1384 | tree block; | |
1385 | { | |
1386 | TREE_USED (block) = 1; | |
e04a16fb AG |
1387 | current_binding_level->blocks |
1388 | = chainon (current_binding_level->blocks, block); | |
1389 | } | |
1390 | ||
1391 | /* Set the BLOCK node for the innermost scope | |
1392 | (the one we are currently in). */ | |
1393 | ||
1394 | void | |
1395 | set_block (block) | |
1396 | register tree block; | |
1397 | { | |
1398 | current_binding_level->this_block = block; | |
1399 | } | |
1400 | ||
1401 | /* integrate_decl_tree calls this function. */ | |
1402 | ||
1403 | void | |
1404 | copy_lang_decl (node) | |
1405 | tree node; | |
1406 | { | |
1407 | int lang_decl_size | |
1408 | = TREE_CODE (node) == VAR_DECL ? sizeof (struct lang_decl_var) | |
1409 | : sizeof (struct lang_decl); | |
1410 | struct lang_decl *x = (struct lang_decl *) oballoc (lang_decl_size); | |
4504ead1 | 1411 | bcopy ((PTR) DECL_LANG_SPECIFIC (node), (PTR) x, lang_decl_size); |
e04a16fb AG |
1412 | DECL_LANG_SPECIFIC (node) = x; |
1413 | } | |
1414 | ||
1415 | /* If DECL has a cleanup, build and return that cleanup here. | |
1416 | This is a callback called by expand_expr. */ | |
1417 | ||
1418 | tree | |
1419 | maybe_build_cleanup (decl) | |
d4476be2 | 1420 | tree decl ATTRIBUTE_UNUSED; |
e04a16fb AG |
1421 | { |
1422 | /* There are no cleanups in Java (I think). */ | |
1423 | return NULL_TREE; | |
1424 | } | |
1425 | ||
1426 | void | |
1427 | give_name_to_locals (jcf) | |
1428 | JCF *jcf; | |
1429 | { | |
1430 | int i, n = DECL_LOCALVARIABLES_OFFSET (current_function_decl); | |
1431 | tree parm; | |
1432 | pending_local_decls = NULL_TREE; | |
1433 | if (n == 0) | |
1434 | return; | |
1435 | JCF_SEEK (jcf, n); | |
1436 | n = JCF_readu2 (jcf); | |
1437 | for (i = 0; i < n; i++) | |
1438 | { | |
1439 | int start_pc = JCF_readu2 (jcf); | |
1440 | int length = JCF_readu2 (jcf); | |
1441 | int name_index = JCF_readu2 (jcf); | |
1442 | int signature_index = JCF_readu2 (jcf); | |
1443 | int slot = JCF_readu2 (jcf); | |
1444 | tree name = get_name_constant (jcf, name_index); | |
9d45bec2 | 1445 | tree type = parse_signature (jcf, signature_index); |
e04a16fb AG |
1446 | if (slot < DECL_ARG_SLOT_COUNT (current_function_decl) |
1447 | && start_pc == 0 | |
1448 | && length == DECL_CODE_LENGTH (current_function_decl)) | |
1449 | { | |
1450 | tree decl = TREE_VEC_ELT (decl_map, slot); | |
1451 | DECL_NAME (decl) = name; | |
1452 | DECL_ASSEMBLER_NAME (decl) = name; | |
1453 | if (TREE_CODE (decl) != PARM_DECL || TREE_TYPE (decl) != type) | |
1454 | warning ("bad type in parameter debug info"); | |
1455 | } | |
1456 | else | |
1457 | { | |
1458 | tree *ptr; | |
1459 | int end_pc = start_pc + length; | |
1460 | tree decl = build_decl (VAR_DECL, name, type); | |
1461 | if (end_pc > DECL_CODE_LENGTH (current_function_decl)) | |
1462 | { | |
1463 | warning_with_decl (decl, | |
1464 | "bad PC range for debug info for local `%s'"); | |
1465 | end_pc = DECL_CODE_LENGTH (current_function_decl); | |
1466 | } | |
1467 | DECL_LANG_SPECIFIC (decl) | |
1468 | = (struct lang_decl *) permalloc (sizeof (struct lang_decl_var)); | |
1469 | DECL_LOCAL_SLOT_NUMBER (decl) = slot; | |
1470 | DECL_LOCAL_START_PC (decl) = start_pc; | |
1471 | DECL_LOCAL_END_PC (decl) = end_pc; | |
1472 | ||
1473 | /* Now insert the new decl in the proper place in | |
1474 | pending_local_decls. We are essentially doing an insertion sort, | |
1475 | which works fine, since the list input will normally already | |
1476 | be sorted. */ | |
1477 | ptr = &pending_local_decls; | |
1478 | while (*ptr != NULL_TREE | |
1479 | && (DECL_LOCAL_START_PC (*ptr) > start_pc | |
1480 | || (DECL_LOCAL_START_PC (*ptr) == start_pc | |
1481 | && DECL_LOCAL_END_PC (*ptr) < end_pc))) | |
1482 | ptr = &TREE_CHAIN (*ptr); | |
1483 | TREE_CHAIN (decl) = *ptr; | |
1484 | *ptr = decl; | |
1485 | } | |
1486 | } | |
1487 | ||
1488 | pending_local_decls = nreverse (pending_local_decls); | |
1489 | ||
1490 | /* Fill in default names for the parameters. */ | |
1491 | for (parm = DECL_ARGUMENTS (current_function_decl), i = 0; | |
1492 | parm != NULL_TREE; parm = TREE_CHAIN (parm), i++) | |
1493 | { | |
1494 | if (DECL_NAME (parm) == NULL_TREE) | |
1495 | { | |
1496 | int arg_i = METHOD_STATIC (current_function_decl) ? i+1 : i; | |
1497 | if (arg_i == 0) | |
1498 | DECL_NAME (parm) = get_identifier ("this"); | |
1499 | else | |
1500 | { | |
1501 | char buffer[12]; | |
1502 | sprintf (buffer, "ARG_%d", arg_i); | |
1503 | DECL_NAME (parm) = get_identifier (buffer); | |
1504 | } | |
1505 | DECL_ASSEMBLER_NAME (parm) = DECL_NAME (parm); | |
1506 | } | |
1507 | } | |
1508 | } | |
1509 | ||
939d7216 PB |
1510 | tree |
1511 | build_result_decl (fndecl) | |
e04a16fb AG |
1512 | tree fndecl; |
1513 | { | |
9d45bec2 PB |
1514 | tree restype = TREE_TYPE (TREE_TYPE (fndecl)); |
1515 | /* To be compatible with C_PROMOTING_INTEGER_TYPE_P in cc1/cc1plus. */ | |
1516 | if (INTEGRAL_TYPE_P (restype) | |
1517 | && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node)) | |
1518 | restype = integer_type_node; | |
939d7216 PB |
1519 | return (DECL_RESULT (fndecl) = build_decl (RESULT_DECL, NULL_TREE, restype)); |
1520 | } | |
e04a16fb | 1521 | |
939d7216 PB |
1522 | void |
1523 | complete_start_java_method (fndecl) | |
1524 | tree fndecl; | |
1525 | { | |
e04a16fb AG |
1526 | if (! flag_emit_class_files) |
1527 | { | |
1528 | /* Initialize the RTL code for the function. */ | |
1529 | init_function_start (fndecl, input_filename, lineno); | |
1530 | ||
1531 | /* Set up parameters and prepare for return, for the function. */ | |
1532 | expand_function_start (fndecl, 0); | |
1533 | } | |
1534 | ||
1535 | /* Allocate further tree nodes temporarily during compilation | |
1536 | of this function only. */ | |
1537 | temporary_allocation (); | |
1538 | ||
1539 | #if 0 | |
1540 | /* If this fcn was already referenced via a block-scope `extern' decl (or | |
1541 | an implicit decl), propagate certain information about the usage. */ | |
1542 | if (TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (current_function_decl))) | |
1543 | TREE_ADDRESSABLE (current_function_decl) = 1; | |
1544 | ||
1545 | #endif | |
1546 | ||
d640220c | 1547 | if (METHOD_STATIC (fndecl) && ! METHOD_PRIVATE (fndecl) |
7f1d4866 APB |
1548 | && ! flag_emit_class_files |
1549 | && ! CLASS_INTERFACE (TYPE_NAME (current_class))) | |
9d45bec2 PB |
1550 | { |
1551 | tree clas = DECL_CONTEXT (fndecl); | |
1552 | tree init = build (CALL_EXPR, void_type_node, | |
1553 | build_address_of (soft_initclass_node), | |
1554 | build_tree_list (NULL_TREE, build_class_ref (clas)), | |
1555 | NULL_TREE); | |
1556 | TREE_SIDE_EFFECTS (init) = 1; | |
1557 | expand_expr_stmt (init); | |
1558 | } | |
1559 | ||
37a08adb PB |
1560 | /* Push local variables. Function compiled from source code are |
1561 | using a different local variables management, and for them, | |
1562 | pushlevel shouldn't be called from here. */ | |
1563 | if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (fndecl))) | |
1564 | { | |
1565 | pushlevel (2); | |
1566 | if (! flag_emit_class_files) | |
1567 | expand_start_bindings (1); | |
1568 | } | |
1569 | ||
1570 | if (METHOD_SYNCHRONIZED (fndecl) && ! flag_emit_class_files) | |
e04a16fb | 1571 | { |
939d7216 | 1572 | /* Warp function body with a monitorenter plus monitorexit cleanup. */ |
939d7216 PB |
1573 | tree enter, exit, lock; |
1574 | if (METHOD_STATIC (fndecl)) | |
1575 | lock = build_class_ref (DECL_CONTEXT (fndecl)); | |
1576 | else | |
1577 | lock = DECL_ARGUMENTS (fndecl); | |
1578 | BUILD_MONITOR_ENTER (enter, lock); | |
1579 | BUILD_MONITOR_EXIT (exit, lock); | |
37a08adb PB |
1580 | if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (fndecl))) |
1581 | { | |
1582 | expand_expr_stmt (enter); | |
1583 | expand_decl_cleanup (NULL_TREE, exit); | |
1584 | } | |
1585 | else | |
1586 | { | |
1587 | tree function_body = DECL_FUNCTION_BODY (fndecl); | |
1588 | tree body = BLOCK_EXPR_BODY (function_body); | |
1589 | lock = build (WITH_CLEANUP_EXPR, void_type_node, | |
1590 | enter, NULL_TREE, exit); | |
1591 | TREE_SIDE_EFFECTS (lock) = 1; | |
1592 | lock = build (COMPOUND_EXPR, TREE_TYPE (body), lock, body); | |
1593 | TREE_SIDE_EFFECTS (lock) = 1; | |
1594 | lock = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (body), lock); | |
1595 | TREE_SIDE_EFFECTS (lock) = 1; | |
1596 | BLOCK_EXPR_BODY (function_body) = lock; | |
1597 | } | |
e04a16fb AG |
1598 | } |
1599 | } | |
1600 | ||
1601 | void | |
1602 | start_java_method (fndecl) | |
1603 | tree fndecl; | |
1604 | { | |
1605 | tree tem, *ptr; | |
1606 | int i; | |
1607 | ||
1608 | current_function_decl = fndecl; | |
1609 | announce_function (fndecl); | |
1610 | ||
1611 | i = DECL_MAX_LOCALS(fndecl) + DECL_MAX_STACK(fndecl); | |
1612 | decl_map = make_tree_vec (i); | |
1613 | type_map = (tree *) oballoc (i * sizeof (tree)); | |
1614 | ||
1615 | pushlevel (1); /* Push parameters. */ | |
1616 | ||
1617 | ptr = &DECL_ARGUMENTS (fndecl); | |
1618 | for (tem = TYPE_ARG_TYPES (TREE_TYPE (fndecl)), i = 0; | |
0bd2e6db | 1619 | tem != end_params_node; tem = TREE_CHAIN (tem), i++) |
e04a16fb AG |
1620 | { |
1621 | tree parm_name = NULL_TREE, parm_decl; | |
9d45bec2 | 1622 | tree parm_type = TREE_VALUE (tem); |
e04a16fb AG |
1623 | if (i >= DECL_MAX_LOCALS(fndecl)) |
1624 | fatal ("function has more parameters than local slots"); | |
1625 | ||
9d45bec2 | 1626 | parm_decl = build_decl (PARM_DECL, parm_name, parm_type); |
e04a16fb | 1627 | DECL_CONTEXT (parm_decl) = fndecl; |
e438e1b7 JJ |
1628 | if (PROMOTE_PROTOTYPES |
1629 | && TYPE_PRECISION (parm_type) < TYPE_PRECISION (integer_type_node) | |
9d45bec2 PB |
1630 | && INTEGRAL_TYPE_P (parm_type)) |
1631 | parm_type = integer_type_node; | |
9d45bec2 | 1632 | DECL_ARG_TYPE (parm_decl) = parm_type; |
e04a16fb AG |
1633 | |
1634 | *ptr = parm_decl; | |
1635 | ptr = &TREE_CHAIN (parm_decl); | |
1636 | ||
1637 | /* Add parm_decl to the decl_map. */ | |
1638 | push_jvm_slot (i, parm_decl); | |
1639 | ||
1640 | type_map[i] = TREE_TYPE (parm_decl); | |
1641 | if (TYPE_IS_WIDE (TREE_TYPE (parm_decl))) | |
1642 | { | |
1643 | i++; | |
1644 | type_map[i] = void_type_node; | |
1645 | } | |
1646 | } | |
1647 | *ptr = NULL_TREE; | |
1648 | DECL_ARG_SLOT_COUNT (current_function_decl) = i; | |
1649 | ||
1650 | while (i < DECL_MAX_LOCALS(fndecl)) | |
1651 | type_map[i++] = NULL_TREE; | |
1652 | ||
939d7216 | 1653 | build_result_decl (fndecl); |
e04a16fb AG |
1654 | complete_start_java_method (fndecl); |
1655 | } | |
1656 | ||
1657 | void | |
1658 | end_java_method () | |
1659 | { | |
1660 | tree fndecl = current_function_decl; | |
138657ec | 1661 | int flag_asynchronous_exceptions = asynchronous_exceptions; |
e04a16fb AG |
1662 | |
1663 | expand_end_bindings (getdecls (), 1, 0); | |
1664 | /* pop out of function */ | |
1665 | poplevel (1, 1, 0); | |
1666 | ||
1667 | /* pop out of its parameters */ | |
1668 | poplevel (1, 0, 1); | |
1669 | ||
1670 | BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl; | |
1671 | ||
1672 | emit_handlers (); | |
1673 | ||
1674 | /* Generate rtl for function exit. */ | |
1675 | expand_function_end (input_filename, lineno, 0); | |
1676 | ||
138657ec AH |
1677 | /* FIXME: If the current method contains any exception handlers, |
1678 | force asynchronous_exceptions: this is necessary because signal | |
1679 | handlers in libjava may throw exceptions. This is far from being | |
1680 | a perfect solution, but it's better than doing nothing at all.*/ | |
1681 | if (catch_clauses) | |
1682 | asynchronous_exceptions = 1; | |
1683 | ||
e04a16fb AG |
1684 | /* Run the optimizers and output assembler code for this function. */ |
1685 | rest_of_compilation (fndecl); | |
1686 | ||
1687 | current_function_decl = NULL_TREE; | |
1688 | permanent_allocation (1); | |
138657ec | 1689 | asynchronous_exceptions = flag_asynchronous_exceptions; |
e04a16fb | 1690 | } |