3 // Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
5 // This file is part of GCC.
7 // GCC is free software; you can redistribute it and/or modify it
8 // under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2, or (at your option)
12 // GCC is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with GCC; see the file COPYING. If not, write to the Free
19 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 // This include must come first.
23 #include "java/glue.hh"
25 #include "bytecode/cpool.hh"
26 #include "java/tree.hh"
28 /// This is a code generator that generates GCC 'GENERIC' trees.
29 /// This is a language-independent tree representation. Currently
30 /// the documentation is here:
31 /// http://gcc.gnu.org/ml/gcc/2002-08/msg01397.html
33 tree_generator::tree_generator (tree_builtins
*builtins
, aot_class
*k
)
34 : gcc_builtins (builtins
),
37 this_tree (NULL_TREE
),
39 method_tree (NULL_TREE
),
40 current_block (NULL_TREE
),
50 tree_generator::~tree_generator ()
63 tree_generator::generate (model_method
*m
)
72 tree_generator::annotate (tree val
, model_element
*element
)
74 location where
= element
->get_location ();
75 if (where
.get_line () >= 0)
76 annotate_with_file_line (val
, where
.get_file (), where
.get_line ());
80 tree_generator::add_var (const ref_variable_decl
&vardecl
)
82 tree var
= gcc_builtins
->map_variable (method_tree
, vardecl
.get ());
83 assert (TREE_CHAIN (var
) == NULL_TREE
);
84 TREE_CHAIN (var
) = BLOCK_VARS (current_block
);
85 BLOCK_VARS (current_block
) = var
;
90 tree_generator::add_temporary (tree name
, tree type
)
92 tree var
= build_decl (VAR_DECL
, name
, type
);
93 DECL_CONTEXT (var
) = method_tree
;
94 TREE_CHAIN (var
) = BLOCK_VARS (current_block
);
95 BLOCK_VARS (current_block
) = var
;
100 tree_generator::emit_type_assertion (model_type
*to_type
,
101 model_type
*from_type
)
106 tree_generator::wrap_label (tree label_decl
, model_element
*request
)
108 tree result
= build1 (LABEL_EXPR
, void_type_node
, label_decl
);
109 annotate (result
, request
);
114 tree_generator::build_label ()
116 tree result
= build0 (LABEL_DECL
, NULL_TREE
);
117 DECL_CONTEXT (result
) = current_block
;
118 DECL_ARTIFICIAL (result
) = 1;
123 tree_generator::make_block ()
125 tree b
= make_node (BLOCK
);
127 // This determines whether the debug output routines generate
128 // information for the variables in that block.
137 tree_generator::visit_method (model_method
*meth
,
138 const std::list
<ref_variable_decl
> ¶ms
,
139 const ref_block
&block
)
142 gcc_builtins
->lay_out_class (meth
->get_declaring_class ());
143 method_tree
= gcc_builtins
->map_method (meth
);
145 if (block
|| flag_jni
)
146 DECL_EXTERNAL (method_tree
) = 0;
150 assert (this_tree
== NULL_TREE
);
151 if (! meth
->static_p ())
152 this_tree
= DECL_ARGUMENTS (method_tree
);
154 current_block
= make_block ();
155 BLOCK_SUPERCONTEXT (current_block
) = method_tree
;
156 DECL_INITIAL (method_tree
) = current_block
;
158 tree statements
= alloc_stmt_list ();
159 tree_stmt_iterator out
= tsi_start (statements
);
161 if (meth
->static_p () && ! meth
->static_initializer_p ()
162 // Don't emit check for methods declared here. FIXME: this
163 // should be an ABI decision. FIXME: also possibly doesn't
164 // work well with generics.
165 && class_wrapper
->get () != meth
->get_declaring_class ())
168 = gcc_builtins
->build_class_init (meth
->get_declaring_class ());
169 tsi_link_after (&out
, init
, TSI_CONTINUE_LINKING
);
173 tsi_link_after (&out
, current
, TSI_CONTINUE_LINKING
);
175 // Emit an explicit 'return' for GCC's sake.
176 if (meth
->get_return_type () == primitive_void_type
177 && block
->can_complete_normally ())
178 tsi_link_after (&out
, build1 (RETURN_EXPR
, void_type_node
, NULL_TREE
),
179 TSI_CONTINUE_LINKING
);
181 current
= statements
;
183 // Handle synchronized methods. This isn't done for JNI
184 // methods, since such synchronization is handled by the VM.
185 if ((meth
->get_modifiers () & ACC_SYNCHRONIZED
) != 0)
188 if (meth
->static_p ())
189 // FIXME: this is kind of wrong for new ABI code.
190 k
= build_class_ref (meth
->get_declaring_class (), meth
);
193 current
= wrap_synchronized (k
, current
);
196 current
= build3 (BIND_EXPR
, void_type_node
,
197 BLOCK_VARS (current_block
),
198 current
, current_block
);
202 assert (meth
->native_p ());
204 current
= build_jni_stub ();
207 // For CNI (old ABI) just generate an external reference.
211 DECL_SAVED_TREE (method_tree
) = current
;
214 // Build a stub to call a JNI method. This code comes almost verbatim
217 tree_generator::build_jni_stub ()
219 current_block
= make_block ();
220 BLOCK_SUPERCONTEXT (current_block
) = method_tree
;
221 DECL_INITIAL (method_tree
) = current_block
;
223 DECL_ARTIFICIAL (method_tree
) = 1;
225 tree env_var
= build_decl (VAR_DECL
, get_identifier ("env"), ptr_type_node
);
226 DECL_CONTEXT (env_var
) = method_tree
;
228 tree res_var
= NULL_TREE
;
229 if (TREE_TYPE (TREE_TYPE (method_tree
)) != void_type_node
)
231 res_var
= build_decl (VAR_DECL
, get_identifier ("res"),
232 TREE_TYPE (TREE_TYPE (method_tree
)));
233 DECL_CONTEXT (res_var
) = method_tree
;
234 TREE_CHAIN (env_var
) = res_var
;
237 tree meth_var
= build_decl (VAR_DECL
, get_identifier ("meth"),
239 TREE_STATIC (meth_var
) = 1;
240 TREE_PUBLIC (meth_var
) = 0;
241 DECL_EXTERNAL (meth_var
) = 0;
242 DECL_CONTEXT (meth_var
) = method_tree
;
243 DECL_ARTIFICIAL (meth_var
) = 1;
244 DECL_INITIAL (meth_var
) = null_pointer_node
;
245 TREE_USED (meth_var
) = 1;
246 chainon (env_var
, meth_var
);
248 tree method_args
= DECL_ARGUMENTS (method_tree
);
249 tree block
= build_block (env_var
, NULL_TREE
, NULL_TREE
,
250 method_args
, NULL_TREE
);
251 TREE_SIDE_EFFECTS (block
) = 1;
252 TREE_TYPE (block
) = TREE_TYPE (TREE_TYPE (method_tree
));
254 // Compute the local 'env' by calling _Jv_GetJNIEnvNewFrame.
255 gcj_abi
*abi
= gcc_builtins
->find_abi ();
257 = abi
->build_direct_class_reference (gcc_builtins
, class_wrapper
,
258 class_wrapper
->get ());
259 tree body
= build2 (MODIFY_EXPR
, ptr_type_node
, env_var
,
260 build3 (CALL_EXPR
, ptr_type_node
,
261 builtin_Jv_GetJNIEnvNewFrame
,
262 build_tree_list (NULL_TREE
, klass
),
264 TREE_SIDE_EFFECTS (body
) = 1;
266 // All the arguments to this method become arguments to the
267 // underlying JNI function. If we had to wrap object arguments in a
268 // special way, we would do that here.
269 tree args
= NULL_TREE
;
272 for (tem
= method_args
; tem
!= NULL_TREE
; tem
= TREE_CHAIN (tem
))
274 int arg_bits
= TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (tem
)));
276 arg_bits
= (((arg_bits
+ PARM_BOUNDARY
- 1) / PARM_BOUNDARY
)
279 args_size
+= (arg_bits
/ BITS_PER_UNIT
);
281 args
= tree_cons (NULL_TREE
, tem
, args
);
283 args
= nreverse (args
);
284 tree arg_types
= TYPE_ARG_TYPES (TREE_TYPE (method_tree
));
286 // For a static method the second argument is the class. For a
287 // non-static method the second argument is 'this'; that is already
288 // available in the argument list.
289 if (method
->static_p ())
291 args_size
+= int_size_in_bytes (TREE_TYPE (klass
));
292 args
= tree_cons (NULL_TREE
, klass
, args
);
293 arg_types
= tree_cons (NULL_TREE
, type_object
, arg_types
);
296 // The JNIEnv structure is the first argument to the JNI function.
297 args_size
+= int_size_in_bytes (TREE_TYPE (env_var
));
298 args
= tree_cons (NULL_TREE
, env_var
, args
);
299 arg_types
= tree_cons (NULL_TREE
, ptr_type_node
, arg_types
);
301 // We call _Jv_LookupJNIMethod to find the actual underlying
302 // function pointer. _Jv_LookupJNIMethod will throw the appropriate
303 // exception if this function is not found at runtime.
304 tem
= build_tree_list (NULL_TREE
, build_int_cst (NULL_TREE
, args_size
));
306 = build_ref_from_constant_pool (type_utf8const_ptr
,
307 class_wrapper
->add_utf (method
->get_descriptor ()));
308 tree lookup_arg
= tree_cons (NULL_TREE
, method_sig
, tem
);
310 tem
= build_ref_from_constant_pool (type_utf8const_ptr
,
311 class_wrapper
->add_utf (method
->get_name ()));
313 = tree_cons (NULL_TREE
, klass
,
314 tree_cons (NULL_TREE
, tem
, lookup_arg
));
316 tem
= build_function_type (TREE_TYPE (TREE_TYPE (method_tree
)), arg_types
);
318 #ifdef MODIFY_JNI_METHOD_CALL
319 tem
= MODIFY_JNI_METHOD_CALL (tem
);
322 tree jni_func_type
= build_pointer_type (tem
);
324 tree jnifunc
= build3 (COND_EXPR
, ptr_type_node
,
326 build2 (MODIFY_EXPR
, ptr_type_node
, meth_var
,
327 build3 (CALL_EXPR
, ptr_type_node
,
328 builtin_Jv_LookupJNIMethod
,
329 lookup_arg
, NULL_TREE
)));
331 // Now we make the actual JNI call via the resulting function
333 tree call
= build3 (CALL_EXPR
, TREE_TYPE (TREE_TYPE (method_tree
)),
334 build1 (NOP_EXPR
, jni_func_type
, jnifunc
),
337 // If the JNI call returned a result, capture it here. If we had to
338 // unwrap JNI object results, we would do that here.
339 if (res_var
!= NULL_TREE
)
340 call
= build2 (MODIFY_EXPR
, TREE_TYPE (TREE_TYPE (method_tree
)),
343 TREE_SIDE_EFFECTS (call
) = 1;
345 body
= build2 (COMPOUND_EXPR
, void_type_node
, body
, call
);
346 TREE_SIDE_EFFECTS (body
) = 1;
348 // Now free the environment we allocated.
349 call
= build3 (CALL_EXPR
, ptr_type_node
,
350 builtin_Jv_JNI_PopSystemFrame
,
351 build_tree_list (NULL_TREE
, env_var
),
353 TREE_SIDE_EFFECTS (call
) = 1;
354 body
= build2 (COMPOUND_EXPR
, void_type_node
, body
, call
);
355 TREE_SIDE_EFFECTS (body
) = 1;
357 // Finally, do the return.
358 tree res_type
= void_type_node
;
359 if (res_var
!= NULL_TREE
)
362 assert (DECL_RESULT (method_tree
));
363 // Make sure we copy the result variable to the actual result.
364 // We use the type of the DECL_RESULT because it might be
365 // different from the return type of the function: it might be
367 drt
= TREE_TYPE (DECL_RESULT (method_tree
));
368 if (drt
!= TREE_TYPE (res_var
))
369 res_var
= build1 (CONVERT_EXPR
, drt
, res_var
);
370 res_var
= build2 (MODIFY_EXPR
, drt
, DECL_RESULT (method_tree
), res_var
);
371 TREE_SIDE_EFFECTS (res_var
) = 1;
374 body
= build2 (COMPOUND_EXPR
, void_type_node
, body
,
375 build1 (RETURN_EXPR
, res_type
, res_var
));
376 TREE_SIDE_EFFECTS (body
) = 1;
378 tree bind
= build3 (BIND_EXPR
, void_type_node
, BLOCK_VARS (block
),
386 tree_generator::visit_assert (model_assert
*element
,
387 const ref_expression
&first
,
388 const ref_expression
&second
)
390 if (! global
->get_compiler ()->target_assert ())
392 current
= build_empty_stmt ();
396 // Add assertion-related members.
397 ref_field disabled
= method
->get_declaring_class ()->add_assert_members ();
398 gcc_builtins
->lay_out_class (disabled
->get_declaring_class ());
399 tree disabled_tree
= gcc_builtins
->map_field_ref (class_wrapper
,
404 tree first_tree
= current
;
406 tree args
= NULL_TREE
;
407 model_type
*arg_type
= NULL
;
410 arg_type
= second
->type ();
411 second
->visit (this);
412 args
= build_tree_list (NULL_TREE
, current
);
415 model_class
*errclass
= global
->get_compiler ()->java_lang_AssertionError ();
416 gcc_builtins
->lay_out_class (errclass
);
418 model_method
*init
= find_method ("<init>", errclass
, arg_type
,
419 primitive_void_type
, element
);
421 tree new_tree
= gcc_builtins
->map_new (class_wrapper
, errclass
, init
, args
);
424 // if (! $assertionsDisabled && ! FIRST) throw new AssertionError (SECOND)
425 tree throw_node
= build3 (CALL_EXPR
, void_type_node
,
427 build_tree_list (NULL_TREE
, new_tree
),
429 current
= build3 (COND_EXPR
, void_type_node
,
430 build2 (TRUTH_ANDIF_EXPR
,
432 build1 (TRUTH_NOT_EXPR
,
435 build1 (TRUTH_NOT_EXPR
,
438 throw_node
, NULL_TREE
);
439 annotate (current
, element
);
443 tree_generator::transform_list (const std::list
<ref_stmt
> &vals
)
445 tree result
= alloc_stmt_list ();
446 tree_stmt_iterator out
= tsi_start (result
);
448 for (std::list
<ref_stmt
>::const_iterator i
= vals
.begin ();
454 if (current
!= NULL_TREE
)
455 tsi_link_after (&out
, current
, TSI_CONTINUE_LINKING
);
461 tree_generator::visit_block (model_block
*block
,
462 const std::list
<ref_stmt
> &statements
)
464 // Create a new block for the body.
465 save_tree
saver (current_block
, make_block ());
466 BLOCK_SUPERCONTEXT (current_block
) = saver
.get ();
468 tree body
= transform_list (statements
);
470 current
= build3 (BIND_EXPR
, void_type_node
,
471 BLOCK_VARS (current_block
),
472 body
, current_block
);
473 annotate (current
, block
);
477 tree_generator::visit_break (model_break
*brk
,
478 const ref_stmt
&target
)
480 model_stmt
*real_target
= target
.get ();
482 real_target
= brk
->get_target ();
483 // Find the target statement.
484 target_map_type::iterator iter
= target_map
.find (real_target
);
485 assert (iter
!= target_map
.end ());
487 current
= build1 (GOTO_EXPR
, void_type_node
,
488 (*iter
).second
.second
);
489 TREE_SIDE_EFFECTS (current
) = 1;
490 annotate (current
, brk
);
494 tree_generator::visit_catch (model_catch
*stmt
,
495 const ref_variable_decl
&vardecl
,
496 const ref_block
&body
)
498 // Create a new block for the body.
499 save_tree
saver (current_block
, make_block ());
500 BLOCK_SUPERCONTEXT (current_block
) = saver
.get ();
502 // Make a new variable and link it in.
503 tree var
= add_var (vardecl
);
505 tree body_tree
= alloc_stmt_list ();
506 tree_stmt_iterator out
= tsi_start (body_tree
);
508 // Create an assignment to the variable and put it in the statement
510 tree vtype
= gcc_builtins
->map_type (vardecl
->type ());
512 tree assign
= build2 (MODIFY_EXPR
, ptr_type_node
,
513 var
, build_exception_object_ref (vtype
));
515 tsi_link_after (&out
, assign
, TSI_CONTINUE_LINKING
);
517 // Generate code for the body and link it in.
519 tsi_link_after (&out
, current
, TSI_CONTINUE_LINKING
);
521 tree bind
= build3 (BIND_EXPR
, void_type_node
,
522 BLOCK_VARS (current_block
),
523 body_tree
, current_block
);
525 // It would be nice to emit this as a pointer into the constant
526 // pool, but GCC apparently crashes when this is compiled with
528 model_class
*vklass
= assert_cast
<model_class
*> (vardecl
->type ());
529 tree decl
= gcc_builtins
->map_catch_class (class_wrapper
->get (), vklass
);
531 current
= build2 (CATCH_EXPR
, void_type_node
, build_address_of (decl
), bind
);
532 annotate (current
, stmt
);
536 tree_generator::visit_continue (model_continue
*element
,
537 const ref_stmt
&target
)
539 // Find the target statement.
540 target_map_type::iterator iter
= target_map
.find (target
.get ());
541 assert (iter
!= target_map
.end ());
542 current
= build1 (GOTO_EXPR
, void_type_node
,
543 (*iter
).second
.first
);
544 TREE_SIDE_EFFECTS (current
) = 1;
545 annotate (current
, element
);
549 tree_generator::visit_class_decl_stmt (model_class_decl_stmt
*,
556 tree_generator::visit_do (model_do
*dstmt
,
557 const ref_expression
&expr
,
558 const ref_stmt
&body
)
560 // Some labels which we'll use later.
561 tree test
= build_label ();
562 tree done
= build_label ();
563 target_map
[dstmt
] = std::make_pair (test
, done
);
565 // Generate code for the expression and the body.
567 tree expr_tree
= current
;
569 tree stmt_tree
= current
;
571 tree body_tree
= alloc_stmt_list ();
572 tree_stmt_iterator out
= tsi_start (body_tree
);
574 // Set up the loop body and arrange to exit once the condition has
576 tsi_link_after (&out
, stmt_tree
, TSI_CONTINUE_LINKING
);
577 tsi_link_after (&out
, wrap_label (test
, expr
.get ()), TSI_CONTINUE_LINKING
);
578 tsi_link_after (&out
, build1 (EXIT_EXPR
,
580 fold (build1 (TRUTH_NOT_EXPR
, type_jboolean
,
582 TSI_CONTINUE_LINKING
);
584 // Wrap the body in a loop.
585 body_tree
= build1 (LOOP_EXPR
, void_type_node
, body_tree
);
586 annotate (current
, dstmt
);
588 // Now make an outer statement list with the remaining label.
589 tree outer
= alloc_stmt_list ();
590 out
= tsi_start (outer
);
591 tsi_link_after (&out
, body_tree
, TSI_CONTINUE_LINKING
);
592 // FIXME: location should be end of do statement, not beginning.
593 tsi_link_after (&out
, wrap_label (done
, dstmt
), TSI_CONTINUE_LINKING
);
598 tree_generator::visit_empty (model_empty
*)
600 current
= build_empty_stmt ();
604 tree_generator::visit_expression_stmt (model_expression_stmt
*,
605 const ref_expression
&expr
)
611 tree_generator::visit_for_enhanced (model_for_enhanced
*fstmt
,
612 const ref_stmt
&body
,
613 const ref_expression
&container
,
614 const ref_variable_decl
&var
)
616 tree update_tree
= build_label ();
617 tree done_tree
= build_label ();
618 target_map
[fstmt
] = std::make_pair (update_tree
, done_tree
);
620 // Push a new block around the loop.
621 save_tree
saver (current_block
, make_block ());
622 BLOCK_SUPERCONTEXT (current_block
) = saver
.get ();
624 tree body_tree
= alloc_stmt_list ();
625 tree_stmt_iterator out
= tsi_start (body_tree
);
627 // Generate code to find the container.
628 container
->visit (this);
629 tree container_tree
= save_expr (current
);
630 tree container_ptr_type
= TREE_TYPE (current
);
632 model_type
*ctype
= container
->type ();
633 gcc_builtins
->lay_out_class (assert_cast
<model_class
*> (ctype
));
635 // The user's variable.
636 tree var_decl
= add_var (var
);
638 tree exit_expr
, update_expr
, assign_rhs
;
640 if (container
->type ()->array_p ())
642 // Make some temporaries: one to hold the index and one to hold
643 // the length of the array.
644 tree index_tree
= add_temporary (gcc_builtins
->get_symbol (), type_jint
);
645 tree len_tree
= add_temporary (gcc_builtins
->get_symbol (), type_jint
);
647 tree container_type
= TREE_TYPE (container_ptr_type
);
648 tree lenfield
= gcc_builtins
->find_decl (container_type
, "length");
649 tree datafield
= gcc_builtins
->find_decl (container_type
, "data");
651 // Compute and save the length of the array.
653 = build3 (COMPONENT_REF
, type_jint
,
654 build1 (INDIRECT_REF
, container_type
,
655 // FIXME: there is probably a more optimal
657 gcc_builtins
->check_reference (container_tree
)),
658 lenfield
, NULL_TREE
);
659 get_len
= build2 (MODIFY_EXPR
, type_jint
, len_tree
, get_len
);
660 TREE_SIDE_EFFECTS (get_len
) = 1;
661 tsi_link_after (&out
, get_len
, TSI_CONTINUE_LINKING
);
663 // Initialize the index.
664 tree init
= build2 (MODIFY_EXPR
, type_jint
, index_tree
,
665 fold (convert (type_jint
, integer_zero_node
)));
666 TREE_SIDE_EFFECTS (init
) = 1;
667 tsi_link_after (&out
, init
, TSI_CONTINUE_LINKING
);
669 // Code for the exit expression.
670 exit_expr
= build2 (EQ_EXPR
, type_jboolean
, index_tree
, len_tree
);
672 // Code for the update expression.
673 update_expr
= build2 (PREINCREMENT_EXPR
, type_jint
, index_tree
,
674 fold (convert (type_jint
, integer_one_node
)));
675 TREE_SIDE_EFFECTS (update_expr
) = 1;
677 // Code to compute the new user variable value.
678 assign_rhs
= build4 (ARRAY_REF
, TREE_TYPE (TREE_TYPE (datafield
)),
679 build3 (COMPONENT_REF
, TREE_TYPE (datafield
),
680 build1 (INDIRECT_REF
, container_type
,
682 datafield
, NULL_TREE
),
683 index_tree
, NULL_TREE
, NULL_TREE
);
689 model_class
*iterator_type
690 = global
->get_compiler ()->java_util_Iterator ();
691 model_class
*object_type
692 = global
->get_compiler ()->java_lang_Object ();
693 model_class
*iterable_type
694 = global
->get_compiler ()->java_lang_Iterable ();
696 model_method
*iter_meth
= find_method ("iterator", iterable_type
, NULL
,
697 iterator_type
, fstmt
);
698 model_method
*has_next_meth
= find_method ("hasNext", iterator_type
,
699 NULL
, primitive_boolean_type
,
701 model_method
*next_meth
= find_method ("next", iterator_type
, NULL
,
704 // Introduce a new variable that holds the iterator.
705 tree iter_tree
= add_temporary (gcc_builtins
->get_symbol (),
706 gcc_builtins
->map_type (iterator_type
));
708 // Initialize the iterator and link it in.
709 tree init
= build2 (MODIFY_EXPR
, TREE_TYPE (iter_tree
),
711 gcc_builtins
->map_method_call (class_wrapper
,
713 NULL_TREE
, iter_meth
,
715 TREE_SIDE_EFFECTS (init
) = 1;
716 tsi_link_after (&out
, init
, TSI_CONTINUE_LINKING
);
718 // Compute the exit expression.
719 exit_expr
= build1 (TRUTH_NOT_EXPR
, type_jboolean
,
720 gcc_builtins
->map_method_call (class_wrapper
,
721 iter_tree
, NULL_TREE
,
724 TREE_SIDE_EFFECTS (exit_expr
) = 1;
726 // Code for the update expression.
727 assign_rhs
= gcc_builtins
->map_method_call (class_wrapper
,
728 iter_tree
, NULL_TREE
,
730 TREE_SIDE_EFFECTS (assign_rhs
) = 1;
732 // We don't need a different update expression.
733 update_expr
= build_empty_stmt ();
736 // We've already linked in the initialization code. Now start the
738 tree loop_tree
= alloc_stmt_list ();
739 tree_stmt_iterator loop_out
= tsi_start (loop_tree
);
741 // Link in the exit expression.
742 tsi_link_after (&loop_out
, build1 (EXIT_EXPR
, void_type_node
, exit_expr
),
743 TSI_CONTINUE_LINKING
);
744 // Link in the user variable assignment.
745 tree user_assign
= build2 (MODIFY_EXPR
, TREE_TYPE (var_decl
),
747 convert (TREE_TYPE (var_decl
), assign_rhs
));
748 TREE_SIDE_EFFECTS (user_assign
) = 1;
749 tsi_link_after (&loop_out
, user_assign
, TSI_CONTINUE_LINKING
);
751 // Compute and link in the body of the loop.
753 tsi_link_after (&loop_out
, current
, TSI_CONTINUE_LINKING
);
755 // Link in the update label and the update expression.
756 tsi_link_after (&loop_out
, wrap_label (update_tree
, fstmt
),
757 TSI_CONTINUE_LINKING
);
758 tsi_link_after (&loop_out
, update_expr
, TSI_CONTINUE_LINKING
);
760 // Wrap up the loop body and link it into the outer statement list.
761 tree loop_contents
= build1 (LOOP_EXPR
, void_type_node
, loop_tree
);
762 TREE_SIDE_EFFECTS (loop_contents
) = 1;
763 annotate (loop_contents
, fstmt
);
764 tsi_link_after (&out
, loop_contents
, TSI_CONTINUE_LINKING
);
766 tsi_link_after (&out
, wrap_label (done_tree
, fstmt
), TSI_CONTINUE_LINKING
);
768 current
= build3 (BIND_EXPR
, void_type_node
, BLOCK_VARS (current_block
),
769 body_tree
, current_block
);
773 tree_generator::visit_for (model_for
*fstmt
,
774 const ref_stmt
&init
,
775 const ref_expression
&cond
,
776 const ref_stmt
&update
,
777 const ref_stmt
&body
)
779 tree update_tree
= build_label ();
780 tree done_tree
= build_label ();
781 target_map
[fstmt
] = std::make_pair (update_tree
, done_tree
);
783 save_tree
saver (current_block
, make_block ());
784 BLOCK_SUPERCONTEXT (current_block
) = saver
.get ();
786 tree result
= alloc_stmt_list ();
787 tree_stmt_iterator result_out
= tsi_start (result
);
792 tsi_link_after (&result_out
, current
, TSI_CONTINUE_LINKING
);
795 // The body of the loop, including the condition and the update.
796 tree body_tree
= alloc_stmt_list ();
797 tree_stmt_iterator body_out
= tsi_start (body_tree
);
801 tsi_link_after (&body_out
, build1 (EXIT_EXPR
, void_type_node
,
802 fold (build1 (TRUTH_NOT_EXPR
,
805 TSI_CONTINUE_LINKING
);
808 tsi_link_after (&body_out
, current
, TSI_CONTINUE_LINKING
);
810 tsi_link_after (&body_out
, wrap_label (update_tree
, fstmt
),
811 TSI_CONTINUE_LINKING
);
814 update
->visit (this);
815 tsi_link_after (&body_out
, current
, TSI_CONTINUE_LINKING
);
818 // Now wrap the body in a loop and link it into the outer statement
820 body_tree
= build1 (LOOP_EXPR
, void_type_node
, body_tree
);
821 annotate (body_tree
, fstmt
);
822 tsi_link_after (&result_out
, body_tree
, TSI_CONTINUE_LINKING
);
824 tsi_link_after (&result_out
, wrap_label (done_tree
, fstmt
),
825 TSI_CONTINUE_LINKING
);
827 current
= build3 (BIND_EXPR
, void_type_node
, BLOCK_VARS (current_block
),
828 result
, current_block
);
832 tree_generator::visit_if (model_if
*element
,
833 const ref_expression
&cond
,
834 const ref_stmt
&true_branch
,
835 const ref_stmt
&false_branch
)
838 tree cond_tree
= current
;
839 true_branch
->visit (this);
840 tree true_tree
= current
;
844 false_branch
->visit (this);
845 false_tree
= current
;
848 false_tree
= build_empty_stmt ();
850 current
= build3 (COND_EXPR
, void_type_node
, cond_tree
,
851 true_tree
, false_tree
);
852 TREE_SIDE_EFFECTS (current
) = (TREE_SIDE_EFFECTS (cond_tree
)
853 || TREE_SIDE_EFFECTS (true_tree
)
854 || TREE_SIDE_EFFECTS (false_tree
));
855 annotate (current
, element
);
859 tree_generator::visit_label (model_label
*label
, const ref_stmt
&stmt
)
861 // We might not know the target of a break statement at semantic
862 // analysis time, so we compute it here.
863 if (label
->get_break_target () == NULL
)
865 // Note that we don't use build_label() here since this is not
866 // an artificial label.
867 tree brk
= build0 (LABEL_DECL
, NULL_TREE
);
868 DECL_CONTEXT (brk
) = current_block
;
869 target_map
[label
] = std::make_pair (NULL_TREE
, brk
);
871 tree body_tree
= alloc_stmt_list ();
872 tree_stmt_iterator out
= tsi_start (body_tree
);
875 tsi_link_after (&out
, current
, TSI_CONTINUE_LINKING
);
876 tsi_link_after (&out
, wrap_label (brk
, label
), TSI_CONTINUE_LINKING
);
885 tree_generator::visit_return (model_return
*rtn
,
886 const ref_expression
&expr
)
891 current
= build2 (MODIFY_EXPR
, TREE_TYPE (DECL_RESULT (method_tree
)),
892 DECL_RESULT (method_tree
),
893 convert (TREE_TYPE (DECL_RESULT (method_tree
)),
895 TREE_SIDE_EFFECTS (current
) = 1;
899 current
= build1 (RETURN_EXPR
, void_type_node
, current
);
900 TREE_SIDE_EFFECTS (current
) = 1;
901 annotate (current
, rtn
);
905 tree_generator::visit_switch (model_switch
*swstmt
,
906 const ref_expression
&expr
,
907 const std::list
<ref_switch_block
> &blocks
)
910 tree expr_tree
= current
;
912 tree done
= build_label ();
913 target_map
[swstmt
] = std::make_pair (NULL_TREE
, done
);
915 tree body_tree
= alloc_stmt_list ();
916 tree_stmt_iterator out
= tsi_start (body_tree
);
918 model_switch_block
*def
= swstmt
->get_default ();
919 for (std::list
<ref_switch_block
>::const_iterator i
= blocks
.begin ();
923 if ((*i
).get () == def
)
925 tree label
= build_label ();
927 tree case_label
= build3 (CASE_LABEL_EXPR
, NULL_TREE
, NULL_TREE
,
929 annotate (case_label
, (*i
).get ());
930 tsi_link_after (&out
, case_label
, TSI_CONTINUE_LINKING
);
933 tsi_link_after (&out
, current
, TSI_CONTINUE_LINKING
);
936 current
= build3 (SWITCH_EXPR
, TREE_TYPE (expr_tree
), expr_tree
,
937 body_tree
, NULL_TREE
);
938 annotate (current
, swstmt
);
940 body_tree
= alloc_stmt_list ();
941 out
= tsi_start (body_tree
);
942 tsi_link_after (&out
, current
, TSI_CONTINUE_LINKING
);
943 tsi_link_after (&out
, wrap_label (done
, swstmt
), TSI_CONTINUE_LINKING
);
948 tree_generator::visit_switch_block (model_switch_block
*swblock
,
949 const std::list
<ref_stmt
> &statements
)
951 // FIXME: redeclare primitive types so we can do this
953 model_primitive_base
*intb
954 = assert_cast
<model_primitive_base
*> (primitive_int_type
);
956 tree body_tree
= alloc_stmt_list ();
957 tree_stmt_iterator out
= tsi_start (body_tree
);
959 std::list
<ref_expression
> labels
= swblock
->get_labels ();
960 for (std::list
<ref_expression
>::const_iterator i
= labels
.begin ();
964 tree label
= build_label ();
966 jint value
= jint (intb
->convert ((*i
)->type (), (*i
)->value ()));
967 tree new_label
= build3 (CASE_LABEL_EXPR
, NULL_TREE
, build_int (value
),
969 annotate (new_label
, swblock
);
970 tsi_link_after (&out
, new_label
, TSI_CONTINUE_LINKING
);
973 tree stmt_tree
= transform_list (statements
);
974 tsi_link_after (&out
, stmt_tree
, TSI_CONTINUE_LINKING
);
980 tree_generator::wrap_synchronized (tree expr
, tree body
)
982 // Make sure we only evaluate the expression once.
983 expr
= save_expr (expr
);
985 // Emit a call to enter the monitor.
986 tree enter
= build3 (CALL_EXPR
, void_type_node
,
987 builtin_Jv_MonitorEnter
,
988 build_tree_list (NULL_TREE
, expr
),
990 TREE_SIDE_EFFECTS (enter
) = 1;
992 // Build a call to leave the monitor, we use it shortly.
993 tree exit_tree
= build3 (CALL_EXPR
, void_type_node
,
994 builtin_Jv_MonitorExit
,
995 build_tree_list (NULL_TREE
, expr
),
997 TREE_SIDE_EFFECTS (exit_tree
) = 1;
999 tree body_tree
= alloc_stmt_list ();
1000 tree_stmt_iterator out
= tsi_start (body_tree
);
1001 tsi_link_after (&out
, enter
, TSI_CONTINUE_LINKING
);
1003 tsi_link_after (&out
, body
, TSI_CONTINUE_LINKING
);
1005 return build2 (TRY_FINALLY_EXPR
, NULL_TREE
, body_tree
, exit_tree
);
1009 tree_generator::visit_synchronized (model_synchronized
*sync
,
1010 const ref_expression
&expr
,
1011 const ref_stmt
&body
)
1014 tree expr_tree
= current
;
1016 tree body_tree
= current
;
1018 current
= wrap_synchronized (expr_tree
, body_tree
);
1019 annotate (current
, sync
);
1023 tree_generator::visit_throw (model_throw
*element
,
1024 const ref_expression
&expr
)
1027 tree expr_tree
= current
;
1028 current
= build3 (CALL_EXPR
, void_type_node
,
1030 build_tree_list (NULL_TREE
, expr_tree
),
1032 TREE_SIDE_EFFECTS (current
) = 1;
1033 annotate (current
, element
);
1037 tree_generator::visit_try (model_try
*trystmt
,
1038 const ref_block
&body
,
1039 const std::list
<ref_catch
> &catchers
,
1040 const ref_block
&finally
)
1042 // First generate trees for the body.
1044 tree body_tree
= current
;
1046 assert (finally
|| ! catchers
.empty ());
1048 // Now generate trees for the catch clauses, but only if there are
1052 if (catchers
.empty ())
1056 tree catch_tree
= alloc_stmt_list ();
1057 tree_stmt_iterator out
= tsi_start (catch_tree
);
1058 for (std::list
<ref_catch
>::const_iterator i
= catchers
.begin ();
1059 i
!= catchers
.end ();
1063 // It is fine to simply link in CURRENT here, since we know
1064 // that each catcher will just generate a CATCH_EXPR.
1065 tsi_link_after (&out
, current
, TSI_CONTINUE_LINKING
);
1068 // Generate the internal try-catch.
1069 result
= build2 (TRY_CATCH_EXPR
, NULL_TREE
, body_tree
, catch_tree
);
1072 // Generate code for 'finally' if needed.
1075 finally
->visit (this);
1076 tree finally_tree
= current
;
1077 // In this case we need an outer try-finally, which encloses all
1078 // the catch clauses.
1079 result
= build2 (TRY_FINALLY_EXPR
, NULL_TREE
, result
, finally_tree
);
1083 annotate (current
, trystmt
);
1087 tree_generator::visit_variable_stmt (model_variable_stmt
*,
1088 const std::list
<ref_variable_decl
> &decls
)
1090 // The result here is a statement list that initializes all the
1091 // variables, as needed. The statement list might be empty.
1092 tree result
= alloc_stmt_list ();
1093 tree_stmt_iterator out
= tsi_start (result
);
1095 for (std::list
<ref_variable_decl
>::const_iterator i
= decls
.begin ();
1099 tree decl
= add_var (*i
);
1100 if ((*i
)->has_initializer_p ())
1102 ref_expression init
= (*i
)->get_initializer ();
1105 // Apparently setting DECL_INITIAL is not enough for locals
1106 // -- instead we must emit explicit initializations.
1107 // DECL_INITIAL (decl) = current; -- does not work.
1108 tree modify
= build2 (MODIFY_EXPR
, TREE_TYPE (decl
),
1110 TREE_SIDE_EFFECTS (modify
) = 1;
1111 tsi_link_after (&out
, modify
, TSI_CONTINUE_LINKING
);
1119 tree_generator::visit_while (model_while
*wstmt
,
1120 const ref_expression
&cond
,
1121 const ref_stmt
&body
)
1123 tree again
= build_label ();
1124 tree done
= build_label ();
1125 target_map
[wstmt
] = std::make_pair (again
, done
);
1127 // Create the body of the loop: first the 'again' label, then the
1128 // exit expression, then the actual body.
1129 tree body_tree
= alloc_stmt_list ();
1130 tree_stmt_iterator out
= tsi_start (body_tree
);
1131 tsi_link_after (&out
, wrap_label (again
, wstmt
), TSI_CONTINUE_LINKING
);
1134 tsi_link_after (&out
, build1 (EXIT_EXPR
, void_type_node
,
1135 fold (build1 (TRUTH_NOT_EXPR
, type_jboolean
,
1137 TSI_CONTINUE_LINKING
);
1140 tsi_link_after (&out
, current
, TSI_CONTINUE_LINKING
);
1142 // Now wrap the body in a loop, and add the "done" label.
1143 body_tree
= build1 (LOOP_EXPR
, void_type_node
, body_tree
);
1144 annotate (body_tree
, wstmt
);
1146 current
= alloc_stmt_list ();
1147 out
= tsi_start (current
);
1148 tsi_link_after (&out
, body_tree
, TSI_CONTINUE_LINKING
);
1149 tsi_link_after (&out
, wrap_label (done
, wstmt
), TSI_CONTINUE_LINKING
);
1155 tree_generator::visit_array_initializer (model_array_initializer
*initx
,
1156 const ref_forwarding_type
&elt_type
,
1157 const std::list
<ref_expression
> &exprs
)
1159 // FIXME: constant array initialization optimization... ?
1161 tree ind_tree
= build_int_cst (type_jint
, exprs
.size ());
1162 if (elt_type
->type ()->primitive_p ())
1163 current
= build_new_array (elt_type
->type (), ind_tree
, initx
);
1165 current
= build_new_object_array (elt_type
->type (), ind_tree
);
1167 // Ensure array class is laid out.
1168 gcc_builtins
->lay_out_class (elt_type
->type ()->array ());
1170 // At this point, 'current' is the 'new' expression for the array.
1171 tree new_expr
= save_expr (current
);
1173 // Yield 'new_expr'.
1174 tree result
= new_expr
;
1176 tree elt_tree
= gcc_builtins
->map_type (elt_type
->type ());
1178 // Build in reverse order so that the result ends up on the right
1179 // hand side of the last compound expression.
1180 int index
= exprs
.size () - 1;
1181 for (std::list
<ref_expression
>::const_reverse_iterator i
= exprs
.rbegin ();
1186 tree value
= current
;
1188 tree idx_tree
= build_int_cst (type_jint
, index
);
1190 = build2 (MODIFY_EXPR
, elt_tree
,
1191 build_array_reference (new_expr
, idx_tree
,
1194 TREE_SIDE_EFFECTS (assign
) = 1;
1195 result
= build2 (COMPOUND_EXPR
, TREE_TYPE (result
), assign
, result
);
1200 annotate (current
, initx
);
1204 tree_generator::handle_array_ref (model_array_ref
*aref
,
1205 model_expression
*array
,
1206 model_expression
*index
,
1209 array
->visit (this);
1210 tree array_tree
= current
;
1211 index
->visit (this);
1212 tree index_tree
= current
;
1214 = gcc_builtins
->map_type (array
->type ()->element_type ());
1215 // We need the array type laid out before we can use it.
1216 // FIXME: this should be handled more generically.
1217 gcc_builtins
->lay_out_class (assert_cast
<model_class
*> (array
->type ()));
1219 current
= build_array_reference (array_tree
, index_tree
, component_type
,
1221 annotate (current
, aref
);
1225 tree_generator::visit_array_ref (model_array_ref
*aref
,
1226 const ref_expression
&array
,
1227 const ref_expression
&index
)
1229 handle_array_ref (aref
, array
.get (), index
.get ());
1233 tree_generator::binary_operator (model_element
*element
,
1235 const ref_expression
&lhs
,
1236 const ref_expression
&rhs
,
1240 tree lhs_tree
= current
;
1242 tree rhs_tree
= current
;
1243 if (result_type
== NULL_TREE
)
1244 result_type
= gcc_builtins
->map_type (lhs
->type ());
1246 // A trick to force evaluation order to be correct.
1247 lhs_tree
= save_expr (lhs_tree
);
1249 if (code
== TRUNC_MOD_EXPR
)
1250 current
= build_mod (result_type
, lhs_tree
, rhs_tree
);
1251 else if (code
== RDIV_EXPR
)
1252 current
= build_divide (result_type
, lhs_tree
, rhs_tree
);
1254 current
= build2 (code
, result_type
, lhs_tree
, rhs_tree
);
1255 TREE_SIDE_EFFECTS (current
) = (TREE_SIDE_EFFECTS (lhs_tree
)
1256 || TREE_SIDE_EFFECTS (rhs_tree
));
1257 annotate (current
, element
);
1261 tree_generator::visit_arith_binary (model_minus
*elt
,
1262 const ref_expression
&lhs
,
1263 const ref_expression
&rhs
)
1265 binary_operator (elt
, MINUS_EXPR
, lhs
, rhs
);
1269 tree_generator::visit_arith_binary (model_mult
*elt
,
1270 const ref_expression
&lhs
,
1271 const ref_expression
&rhs
)
1273 binary_operator (elt
, MULT_EXPR
, lhs
, rhs
);
1277 tree_generator::visit_arith_binary (model_div
*op
,
1278 const ref_expression
&lhs
,
1279 const ref_expression
&rhs
)
1281 binary_operator (op
, RDIV_EXPR
, lhs
, rhs
);
1285 tree_generator::visit_arith_binary (model_mod
*op
,
1286 const ref_expression
&lhs
,
1287 const ref_expression
&rhs
)
1289 binary_operator (op
, TRUNC_MOD_EXPR
, lhs
, rhs
);
1293 tree_generator::visit_arith_binary (model_and
*elt
,
1294 const ref_expression
&lhs
,
1295 const ref_expression
&rhs
)
1297 binary_operator (elt
, BIT_AND_EXPR
, lhs
, rhs
);
1301 tree_generator::visit_arith_binary (model_or
*elt
,
1302 const ref_expression
&lhs
,
1303 const ref_expression
&rhs
)
1305 binary_operator (elt
, BIT_IOR_EXPR
, lhs
, rhs
);
1309 tree_generator::visit_arith_binary (model_xor
*elt
,
1310 const ref_expression
&lhs
,
1311 const ref_expression
&rhs
)
1313 binary_operator (elt
, BIT_XOR_EXPR
, lhs
, rhs
);
1316 // FIXME: this is copied from bytecode_generator.
1318 tree_generator::find_method (const char *mname
, model_class
*klass
,
1319 model_type
*argtype
, model_type
*result_type
,
1320 model_element
*request
)
1322 std::set
<model_method
*> methods
;
1323 klass
->find_members (mname
, methods
, method
->get_declaring_class (), klass
);
1324 model_method
*result
= NULL
;
1325 for (std::set
<model_method
*>::const_iterator i
= methods
.begin ();
1326 i
!= methods
.end ();
1329 model_method
*meth
= *i
;
1330 std::list
<ref_variable_decl
> params
= meth
->get_parameters ();
1331 int len
= params
.size ();
1332 if (! argtype
&& len
== 0)
1337 if (! argtype
|| len
!= 1)
1339 ref_variable_decl var
= params
.front ();
1340 if (var
->type ()->erasure () == argtype
)
1349 throw request
->error ("couldn't find method %1 with argument of type "
1350 "%2 in class %3 -- perhaps you have the wrong "
1352 % mname
% (argtype
? argtype
: primitive_void_type
) % klass
;
1355 if (result
->get_return_type ()->erasure () != result_type
)
1357 throw request
->error ("method %1 doesn't have expected return type"
1359 % result
% result_type
;
1365 tree_generator::stringbuffer_append (model_expression
*expr
,
1367 model_class
*sb_class
,
1370 if (! expr
->type ()->primitive_p () && dynamic_cast<model_plus
*> (expr
))
1372 assert (! expr_override
);
1373 // We have another String '+'. So recurse, using the same
1374 // StringBuffer. Note that it is simpler to handle this
1375 // recursion explicitly here than it is to do more bookkeeping
1376 // so we can reuse visitor.
1377 model_plus
*plus
= assert_cast
<model_plus
*> (expr
);
1378 handle_string_plus (plus
, plus
->get_lhs (), plus
->get_rhs (),
1379 buffer_tree
, sb_class
);
1383 // Generate code for the expression.
1386 expr_tree
= expr_override
;
1390 expr_tree
= current
;
1393 // Maybe promote the expression -- StringBuffer doesn't have
1394 // every possible overload.
1395 model_type
*expr_type
= expr
->type ();
1396 if (expr_type
== primitive_byte_type
1397 || expr_type
== primitive_short_type
)
1399 expr_type
= primitive_int_type
;
1400 expr_tree
= convert (type_jint
, expr_tree
);
1402 else if (! expr_type
->primitive_p ()
1403 && expr_type
!= global
->get_compiler ()->java_lang_String ())
1405 expr_type
= global
->get_compiler ()->java_lang_Object ();
1406 expr_tree
= convert (type_object_ptr
, expr_tree
);
1409 tree args
= build_tree_list (NULL_TREE
, expr_tree
);
1411 model_method
*append
= find_method ("append", sb_class
, expr_type
,
1413 tree ap_tree
= gcc_builtins
->map_method_call (class_wrapper
,
1416 buffer_tree
= save_expr (ap_tree
);
1421 tree_generator::handle_string_plus (model_plus
*model
,
1422 const ref_expression
&lhs
,
1423 const ref_expression
&rhs
,
1425 model_class
*sb_class
)
1427 stringbuffer_append (lhs
.get (), buffer_tree
, sb_class
);
1428 stringbuffer_append (rhs
.get (), buffer_tree
, sb_class
);
1432 tree_generator::create_stringbuffer (model_class
**sb_class_r
,
1433 model_element
*model
)
1435 // Our StringBuffer is unsynchronized, but unlike StringBuilder does
1436 // not allocate any garbage.
1437 model_class
*sb_class
1438 = global
->get_compiler ()->gnu_gcj_runtime_StringBuffer ();
1439 gcc_builtins
->lay_out_class (sb_class
);
1441 // Create the StringBuffer.
1442 // FIXME: could optimize ""+foo if we wanted ...
1443 // FIXME: could call a different constructor if the LHS is a String.
1444 model_method
*init
= find_method ("<init>", sb_class
, NULL
,
1445 primitive_void_type
, model
);
1447 tree buffer_tree
= gcc_builtins
->map_new (class_wrapper
, sb_class
,
1449 buffer_tree
= save_expr (buffer_tree
);
1451 *sb_class_r
= sb_class
;
1456 tree_generator::finish_stringbuffer (model_class
*sb_class
,
1458 model_element
*model
)
1460 // At this point we have a big expression to create a StringBuffer
1461 // and append all the contents. So now we just convert it into a
1463 model_method
*tostring
1464 = find_method ("toString", sb_class
, NULL
,
1465 global
->get_compiler ()->java_lang_String (),
1467 tree result
= gcc_builtins
->map_method_call (class_wrapper
, buffer_tree
,
1468 NULL_TREE
, tostring
, false);
1469 TREE_SIDE_EFFECTS (result
) = 1;
1474 tree_generator::visit_arith_binary (model_plus
*model
,
1475 const ref_expression
&lhs
,
1476 const ref_expression
&rhs
)
1478 if (model
->type ()->primitive_p ())
1480 binary_operator (model
, PLUS_EXPR
, lhs
, rhs
);
1485 model_class
*sb_class
;
1486 tree buffer_tree
= create_stringbuffer (&sb_class
, model
);
1487 handle_string_plus (model
, lhs
, rhs
, buffer_tree
, sb_class
);
1488 current
= finish_stringbuffer (sb_class
, buffer_tree
, model
);
1489 TREE_SIDE_EFFECTS (current
) = 1;
1490 annotate (current
, model
);
1494 tree_generator::arith_shift (model_element
*element
,
1496 const ref_expression
&lhs
,
1497 const ref_expression
&rhs
,
1501 tree lhs_tree
= current
;
1502 tree saved_lhs_type
= TREE_TYPE (lhs_tree
);
1504 tree rhs_tree
= current
;
1506 // A trick to force evaluation order to be correct.
1507 lhs_tree
= save_expr (lhs_tree
);
1509 // Convert right hand side to 'int' if required.
1510 if (rhs
->type () == primitive_long_type
)
1512 tree conv
= build1 (CONVERT_EXPR
, type_jint
, rhs_tree
);
1513 TREE_SIDE_EFFECTS (conv
) = TREE_SIDE_EFFECTS (rhs_tree
);
1519 model_type
*lt
= lhs
->type ();
1521 if (lt
== primitive_int_type
)
1525 assert (lt
== primitive_long_type
);
1526 utype
= type_julong
;
1528 tree conv
= build1 (CONVERT_EXPR
, utype
, lhs_tree
);
1529 TREE_SIDE_EFFECTS (conv
) = TREE_SIDE_EFFECTS (lhs_tree
);
1533 // Mask off relevant bits of shift count.
1534 model_type
*t
= lhs
->type ();
1535 int bits
= t
== primitive_long_type
? 0x3f : 0x1f;
1536 tree folded
= fold (build2 (BIT_AND_EXPR
, type_jint
,
1537 rhs_tree
, build_int (bits
)));
1538 TREE_SIDE_EFFECTS (folded
) = TREE_SIDE_EFFECTS (rhs_tree
);
1541 tree result
= build2 (kind
, TREE_TYPE (lhs_tree
), lhs_tree
, rhs_tree
);
1542 TREE_SIDE_EFFECTS (result
) = (TREE_SIDE_EFFECTS (lhs_tree
)
1543 | TREE_SIDE_EFFECTS (rhs_tree
));
1544 annotate (result
, element
);
1548 tree conv
= build1 (CONVERT_EXPR
, saved_lhs_type
, result
);
1549 TREE_SIDE_EFFECTS (conv
) = TREE_SIDE_EFFECTS (result
);
1557 tree_generator::visit_arith_shift (model_left_shift
*elt
,
1558 const ref_expression
&lhs
,
1559 const ref_expression
&rhs
)
1561 current
= arith_shift (elt
, LSHIFT_EXPR
, lhs
, rhs
, false);
1565 tree_generator::visit_arith_shift (model_right_shift
*elt
,
1566 const ref_expression
&lhs
,
1567 const ref_expression
&rhs
)
1569 current
= arith_shift (elt
, RSHIFT_EXPR
, lhs
, rhs
, false);
1573 tree_generator::visit_arith_shift (model_unsigned_right_shift
*elt
,
1574 const ref_expression
&lhs
,
1575 const ref_expression
&rhs
)
1577 current
= arith_shift (elt
, RSHIFT_EXPR
, lhs
, rhs
, true);
1581 tree_generator::visit_assignment (model_assignment
*elt
,
1582 const ref_expression
&lhs
,
1583 const ref_expression
&rhs
)
1585 // It is ok to visit the RHS first, since we don't keep much state
1588 tree rhs_tree
= current
;
1590 // This is pretty ugly, but it is reasonably simple to do this as a
1591 // special case here. If we see an array reference on the LHS, we
1592 // must emit a check as well. Note that we don't need a check if
1593 // the RHS is 'null' or if the array has primitive type.
1594 model_array_ref
*ref
= dynamic_cast<model_array_ref
*> (lhs
.get ());
1596 && rhs
->type () != null_type
1597 && ref
->type ()->reference_p ())
1598 handle_array_ref (ref
, ref
->get_array (), ref
->get_index (), rhs_tree
);
1601 tree lhs_tree
= current
;
1603 current
= build2 (MODIFY_EXPR
, TREE_TYPE (lhs_tree
),
1604 lhs_tree
, convert (TREE_TYPE (lhs_tree
), rhs_tree
));
1605 TREE_SIDE_EFFECTS (current
) = 1;
1606 annotate (current
, elt
);
1610 tree_generator::handle_op_assignment (model_element
*element
,
1612 const ref_expression
&lhs
,
1613 const ref_expression
&rhs
)
1615 // It is ok to visit the RHS first, since we don't keep much state
1618 tree rhs_tree
= current
;
1620 // This is pretty ugly, but it is reasonably simple to do this as a
1621 // special case here. If we see an array reference on the LHS, we
1622 // must emit a check as well. Note that we don't need a check if
1623 // the RHS is 'null' or if the array has primitive type.
1624 model_array_ref
*ref
= dynamic_cast<model_array_ref
*> (lhs
.get ());
1626 && rhs
->type () != null_type
1627 && ref
->type ()->reference_p ())
1628 handle_array_ref (ref
, ref
->get_array (), ref
->get_index (), rhs_tree
);
1631 tree lhs_tree
= current
;
1633 bool is_shift
= (op
== LSHIFT_EXPR
|| op
== RSHIFT_EXPR
);
1635 // Note that we convert the LHS to the type of the RHS, because the
1636 // RHS might have been promoted. However, we don't do this for
1637 // shift operators, as they don't undergo binary numeric promotion.
1638 // FIXME: probably the model should be more clear on this point.
1639 tree rhs_type
= TREE_TYPE (rhs_tree
);
1640 tree lhs_dup_tree
= lhs_tree
;
1642 lhs_dup_tree
= fold (convert (rhs_type
, lhs_dup_tree
));
1644 // A trick to force evaluation order to be correct.
1645 lhs_dup_tree
= save_expr (lhs_dup_tree
);
1647 // The 'mod' operation requires a special case as it may expand to a
1648 // builtin or a function call.
1650 if (op
== TRUNC_MOD_EXPR
)
1651 operation
= build_mod (rhs_type
, lhs_dup_tree
, rhs_tree
);
1652 else if (op
== RDIV_EXPR
)
1653 operation
= build_divide (rhs_type
, lhs_dup_tree
, rhs_tree
);
1655 operation
= build2 (op
, rhs_type
, lhs_dup_tree
, rhs_tree
);
1656 TREE_SIDE_EFFECTS (operation
) = (TREE_SIDE_EFFECTS (lhs_tree
)
1657 | TREE_SIDE_EFFECTS (rhs_tree
));
1659 current
= build2 (MODIFY_EXPR
, TREE_TYPE (lhs_tree
), lhs_tree
,
1660 fold (convert (TREE_TYPE (lhs_tree
), operation
)));
1661 TREE_SIDE_EFFECTS (current
) = 1;
1662 annotate (current
, element
);
1664 model_type
*lhs_mtype
= lhs
->type ();
1665 model_type
*rhs_mtype
= rhs
->type ();
1666 if (! lhs_mtype
->primitive_p () && lhs_mtype
!= null_type
1667 && ! rhs_mtype
->primitive_p () && rhs_mtype
!= null_type
)
1668 emit_type_assertion (lhs_mtype
, rhs_mtype
);
1672 tree_generator::visit_op_assignment (model_minus_equal
*elt
,
1673 const ref_expression
&lhs
,
1674 const ref_expression
&rhs
)
1676 handle_op_assignment (elt
, MINUS_EXPR
, lhs
, rhs
);
1680 tree_generator::visit_op_assignment (model_mult_equal
*elt
,
1681 const ref_expression
&lhs
,
1682 const ref_expression
&rhs
)
1684 handle_op_assignment (elt
, MULT_EXPR
, lhs
, rhs
);
1688 tree_generator::visit_op_assignment (model_div_equal
*op
,
1689 const ref_expression
&lhs
,
1690 const ref_expression
&rhs
)
1692 handle_op_assignment (op
, RDIV_EXPR
, lhs
, rhs
);
1696 tree_generator::visit_op_assignment (model_and_equal
*elt
,
1697 const ref_expression
&lhs
,
1698 const ref_expression
&rhs
)
1700 handle_op_assignment (elt
, BIT_AND_EXPR
, lhs
, rhs
);
1704 tree_generator::visit_op_assignment (model_or_equal
*elt
,
1705 const ref_expression
&lhs
,
1706 const ref_expression
&rhs
)
1708 handle_op_assignment (elt
, BIT_IOR_EXPR
, lhs
, rhs
);
1712 tree_generator::visit_op_assignment (model_xor_equal
*elt
,
1713 const ref_expression
&lhs
,
1714 const ref_expression
&rhs
)
1716 handle_op_assignment (elt
, BIT_XOR_EXPR
, lhs
, rhs
);
1720 tree_generator::visit_op_assignment (model_mod_equal
*op
,
1721 const ref_expression
&lhs
,
1722 const ref_expression
&rhs
)
1724 handle_op_assignment (op
, TRUNC_MOD_EXPR
, lhs
, rhs
);
1728 tree_generator::visit_op_assignment (model_ls_equal
*op
,
1729 const ref_expression
&lhs
,
1730 const ref_expression
&rhs
)
1732 handle_op_assignment (op
, LSHIFT_EXPR
, lhs
, rhs
);
1736 tree_generator::visit_op_assignment (model_rs_equal
*op
,
1737 const ref_expression
&lhs
,
1738 const ref_expression
&rhs
)
1740 handle_op_assignment (op
, RSHIFT_EXPR
, lhs
, rhs
);
1744 tree_generator::visit_op_assignment (model_urs_equal
*op
,
1745 const ref_expression
&lhs
,
1746 const ref_expression
&rhs
)
1749 tree lhs_tree
= stabilize_reference (current
);
1752 if (lhs
->type () == primitive_int_type
)
1756 assert (lhs
->type () == primitive_long_type
);
1757 utype
= type_julong
;
1760 // We save_expr() here as a trick to force evaluation order.
1761 tree ulhs_tree
= convert (utype
, save_expr (lhs_tree
));
1764 tree rhs_tree
= current
;
1766 current
= build2 (MODIFY_EXPR
, gcc_builtins
->map_type (lhs
->type ()),
1768 build2 (RSHIFT_EXPR
,
1769 gcc_builtins
->map_type (lhs
->type ()),
1770 ulhs_tree
, rhs_tree
));
1771 TREE_SIDE_EFFECTS (current
) = 1;
1772 annotate (current
, op
);
1776 tree_generator::visit_op_assignment (model_plus_equal
*elt
,
1777 const ref_expression
&lhs
,
1778 const ref_expression
&rhs
)
1780 if (elt
->type ()->primitive_p ())
1782 handle_op_assignment (elt
, PLUS_EXPR
, lhs
, rhs
);
1787 model_class
*sb_class
;
1788 tree buffer_tree
= create_stringbuffer (&sb_class
, elt
);
1790 // Wrap the LHS so we only evaluate it once.
1792 tree lhs_tree
= stabilize_reference (current
);
1794 // Add the LHS and RHS to the StringBuffer.
1795 stringbuffer_append (lhs
.get (), buffer_tree
, sb_class
, lhs_tree
);
1796 stringbuffer_append (rhs
.get (), buffer_tree
, sb_class
);
1798 tree result
= finish_stringbuffer (sb_class
, buffer_tree
, elt
);
1800 // Note that the LHS might not have String type. So, we make sure
1801 // to cast everything to the actual type.
1802 current
= build2 (MODIFY_EXPR
, TREE_TYPE (lhs_tree
), lhs_tree
,
1803 convert (TREE_TYPE (lhs_tree
), result
));
1804 TREE_SIDE_EFFECTS (current
) = 1;
1805 annotate (current
, elt
);
1809 tree_generator::visit_cast (model_cast
*elt
,
1810 const ref_forwarding_type
&dest
,
1811 const ref_expression
&expr
)
1814 tree expr_tree
= current
;
1816 model_type
*dest_type
= dest
->type ();
1817 model_type
*expr_type
= expr
->type ();
1818 if (dest_type
->primitive_p () != expr_type
->primitive_p ())
1820 if (dest_type
->primitive_p ())
1822 // Unboxing conversion. Call <type>Value() on the wrapper
1823 // object, e.g. for Integer we call intValue(). Using
1824 // get_pretty_name here is a bit of an abuse. Note that
1825 // Character doesn't have all the methods from Number, so we
1826 // need a special case here.
1827 // FIXME: for the C++ ABI we could reference fields directly
1828 // in some situations.
1829 model_type
*tmp_dest_type
= dest_type
;
1830 if (expr_type
== global
->get_compiler ()->java_lang_Character ())
1831 tmp_dest_type
= primitive_char_type
;
1832 std::string method_name
= (tmp_dest_type
->get_pretty_name ()
1835 = find_method (method_name
.c_str (),
1836 assert_cast
<model_class
*> (expr_type
),
1837 NULL
, tmp_dest_type
, elt
);
1838 current
= gcc_builtins
->map_method_call (class_wrapper
, expr_tree
,
1839 NULL_TREE
, call
, false);
1840 if (tmp_dest_type
!= dest_type
)
1842 assert (tmp_dest_type
== primitive_char_type
);
1843 current
= convert (gcc_builtins
->map_type (dest_type
), current
);
1848 // Boxing conversion. We call the static factory method
1849 // valueOf(), which handles the caching required by boxing
1851 model_class
*dest_class
= assert_cast
<model_class
*> (dest_type
);
1852 model_method
*call
= find_method ("valueOf", dest_class
,
1853 expr_type
, dest_class
,
1855 tree args
= build_tree_list (NULL_TREE
, expr_tree
);
1856 current
= gcc_builtins
->map_method_call (class_wrapper
, NULL_TREE
,
1858 TREE_SIDE_EFFECTS (current
) = 1;
1861 else if (dest_type
->primitive_p ())
1863 if (dest_type
->integral_p () && (expr_type
== primitive_float_type
1864 || expr_type
== primitive_double_type
))
1866 // We have to use 'int' as an intermediate type in cases
1867 // like float->byte.
1868 model_type
*inter
= dest_type
;
1869 if (dest_type
!= primitive_int_type
1870 && dest_type
!= primitive_long_type
)
1871 inter
= primitive_int_type
;
1872 current
= handle_convert (inter
, expr_tree
);
1873 if (inter
!= dest_type
)
1874 current
= convert (gcc_builtins
->map_type (dest_type
), current
);
1875 TREE_SIDE_EFFECTS (current
) = TREE_SIDE_EFFECTS (expr_tree
);
1879 current
= fold_convert (gcc_builtins
->map_type (dest_type
),
1881 TREE_SIDE_EFFECTS (current
) = TREE_SIDE_EFFECTS (expr_tree
);
1886 // Reference types. We only need to emit a cast check if the
1887 // types are known to be incompatible.
1888 if (! dest_type
->assignable_from_p (expr_type
))
1890 current
= build3 (CALL_EXPR
, gcc_builtins
->map_type (dest_type
),
1891 builtin_Jv_CheckCast
,
1892 tree_cons (NULL_TREE
,
1893 build_class_ref (dest_type
, elt
),
1894 build_tree_list (NULL_TREE
, expr_tree
)),
1896 TREE_SIDE_EFFECTS (current
) = 1;
1900 emit_type_assertion (dest_type
, expr_type
);
1901 current
= build1 (NOP_EXPR
, gcc_builtins
->map_type (dest_type
),
1903 TREE_SIDE_EFFECTS (current
) = TREE_SIDE_EFFECTS (expr_tree
);
1906 // FIXME: might have a constant or DECL here.
1907 // annotate (current, elt);
1911 tree_generator::visit_class_ref (model_class_ref
*ref
,
1912 const ref_forwarding_type
&req
)
1914 current
= build_class_ref (req
->type (), ref
);
1915 annotate (current
, ref
);
1919 tree_generator::visit_comparison (model_equal
*elt
,
1920 const ref_expression
&lhs
,
1921 const ref_expression
&rhs
)
1923 binary_operator (elt
, EQ_EXPR
, lhs
, rhs
, type_jboolean
);
1927 tree_generator::visit_comparison (model_notequal
*elt
,
1928 const ref_expression
&lhs
,
1929 const ref_expression
&rhs
)
1931 binary_operator (elt
, NE_EXPR
, lhs
, rhs
, type_jboolean
);
1935 tree_generator::visit_comparison (model_lessthan
*elt
,
1936 const ref_expression
&lhs
,
1937 const ref_expression
&rhs
)
1939 binary_operator (elt
, LT_EXPR
, lhs
, rhs
, type_jboolean
);
1943 tree_generator::visit_comparison (model_greaterthan
*elt
,
1944 const ref_expression
&lhs
,
1945 const ref_expression
&rhs
)
1947 binary_operator (elt
, GT_EXPR
, lhs
, rhs
, type_jboolean
);
1951 tree_generator::visit_comparison (model_lessthanequal
*elt
,
1952 const ref_expression
&lhs
,
1953 const ref_expression
&rhs
)
1955 binary_operator (elt
, LE_EXPR
, lhs
, rhs
, type_jboolean
);
1959 tree_generator::visit_comparison (model_greaterthanequal
*elt
,
1960 const ref_expression
&lhs
,
1961 const ref_expression
&rhs
)
1963 binary_operator (elt
, GE_EXPR
, lhs
, rhs
, type_jboolean
);
1967 tree_generator::visit_conditional (model_conditional
*m_cond
,
1968 const ref_expression
&cond
,
1969 const ref_expression
&true_branch
,
1970 const ref_expression
&false_branch
)
1973 tree cond_tree
= current
;
1974 true_branch
->visit (this);
1975 tree true_tree
= current
;
1976 false_branch
->visit (this);
1977 tree false_tree
= current
;
1979 current
= build3 (COND_EXPR
, gcc_builtins
->map_type (m_cond
->type ()),
1980 cond_tree
, true_tree
, false_tree
);
1981 TREE_SIDE_EFFECTS (current
) = (TREE_SIDE_EFFECTS (cond_tree
)
1982 || TREE_SIDE_EFFECTS (true_tree
)
1983 || TREE_SIDE_EFFECTS (false_tree
));
1984 annotate (current
, m_cond
);
1988 tree_generator::visit_field_ref (model_field_ref
*elt
,
1989 const ref_expression
&expr
,
1992 bool should_inline
= field
->inlineable_p ();
1994 // Note that we don't need any special handling for 'array.length'
1995 // -- the generic code here works fine.
1996 tree expr_tree
= NULL_TREE
;
2000 expr_tree
= current
;
2002 // A very obscure case: if we have 'foo.bar', and bar is
2003 // inlineable, we must inline it but we must also null-check
2005 if (should_inline
&& ! field
->static_p ())
2006 expr_tree
= gcc_builtins
->check_reference (expr_tree
, true);
2011 model_expression
*init
= field
->get_initializer ().get ();
2012 // This assertion should be true due to constant folding when
2013 // resolving the field.
2014 assert (dynamic_cast<model_literal_base
*> (init
));
2017 if (expr_tree
!= NULL_TREE
)
2018 current
= build2 (COMPOUND_EXPR
, TREE_TYPE (current
),
2019 expr_tree
, current
);
2021 // FIXME: should annotate() here if possible.
2025 // FIXME: Note that map_field_ref does not handle the case of a
2026 // non-static reference to a static field.
2029 // FIXME: where should this go? [ In the ABI ]
2030 if (expr
->type () != field
->get_declaring_class ())
2031 // FIXME: is this right?
2032 emit_type_assertion (field
->get_declaring_class (), expr
->type ());
2035 gcc_builtins
->lay_out_class (field
->get_declaring_class ());
2036 current
= gcc_builtins
->map_field_ref (class_wrapper
, expr_tree
, field
);
2037 // FIXME: should annotate here, but we might have a var_decl
2038 // annotate (current, elt);
2043 tree_generator::visit_field_initializer (model_field_initializer
*elt
,
2046 if ((field
->static_p () && field
->constant_p ())
2047 || ! field
->has_initializer_p ())
2049 // Ignore constant fields.
2053 // FIXME: perhaps ABI should lay out class.
2054 gcc_builtins
->lay_out_class (field
->get_declaring_class ());
2055 tree field_tree
= gcc_builtins
->map_field_ref (class_wrapper
, this_tree
,
2058 field
->get_initializer ()->visit (this);
2059 current
= build2 (MODIFY_EXPR
, TREE_TYPE (field_tree
), field_tree
, current
);
2060 annotate (current
, elt
);
2064 tree_generator::handle_instanceof (tree expr_tree
, tree class_tree
)
2066 tree call
= build3 (CALL_EXPR
, type_jboolean
,
2067 builtin_Jv_IsInstanceOf
,
2068 tree_cons (NULL_TREE
, expr_tree
,
2069 build_tree_list (NULL_TREE
, class_tree
)),
2071 TREE_SIDE_EFFECTS (call
) = 1;
2073 // It is better to have an explicit null check here, as this enables
2074 // VRP-based optimizations.
2075 tree result
= build2 (TRUTH_AND_EXPR
, type_jboolean
,
2076 build2 (NE_EXPR
, type_jboolean
,
2077 expr_tree
, null_pointer_node
),
2079 TREE_SIDE_EFFECTS (result
) = 1;
2085 tree_generator::visit_instanceof (model_instanceof
*stmt
,
2086 const ref_expression
&expr
,
2087 const ref_forwarding_type
&klass
)
2090 tree expr_tree
= save_expr (current
);
2091 tree class_tree
= build_class_ref (klass
->type (), stmt
);
2092 current
= handle_instanceof (expr_tree
, class_tree
);
2093 annotate (current
, stmt
);
2097 tree_generator::visit_logical_binary (model_lor
*elt
,
2098 const ref_expression
&lhs
,
2099 const ref_expression
&rhs
)
2101 binary_operator (elt
, TRUTH_ORIF_EXPR
, lhs
, rhs
);
2105 tree_generator::visit_logical_binary (model_land
*elt
,
2106 const ref_expression
&lhs
,
2107 const ref_expression
&rhs
)
2109 binary_operator (elt
, TRUTH_ANDIF_EXPR
, lhs
, rhs
);
2113 tree_generator::visit_simple_literal (model_literal_base
*,
2114 const jboolean
&val
)
2116 current
= val
? boolean_true_node
: boolean_false_node
;
2120 tree_generator::visit_simple_literal (model_literal_base
*, const jbyte
&val
)
2122 current
= build_int (val
, type_jbyte
);
2126 tree_generator::visit_simple_literal (model_literal_base
*, const jchar
&val
)
2128 current
= build_int (val
, type_jchar
);
2132 tree_generator::visit_simple_literal (model_literal_base
*, const jshort
&val
)
2134 current
= build_int (val
, type_jshort
);
2138 tree_generator::visit_simple_literal (model_literal_base
*, const jint
&val
)
2140 current
= build_int (val
);
2144 tree_generator::visit_simple_literal (model_literal_base
*, const jlong
&val
)
2146 current
= build_long (val
);
2150 tree_generator::handle_float (jfloat val
)
2152 jint w
= float_to_word (val
);
2155 real_from_target_fmt (&f
, &wl
, &ieee_single_format
);
2156 return build_real (type_jfloat
, f
);
2160 tree_generator::visit_simple_literal (model_literal_base
*, const jfloat
&val
)
2162 current
= handle_float (val
);
2166 tree_generator::handle_double (jdouble val
)
2169 double_to_words (w
, val
);
2171 #ifdef WORDS_BIGENDIAN
2177 #endif // WORDS_BIGENDIAN
2179 real_from_target_fmt (&d
, wl
, &ieee_double_format
);
2180 return build_real (type_jdouble
, d
);
2184 tree_generator::visit_simple_literal (model_literal_base
*, const jdouble
&val
)
2186 current
= handle_double (val
);
2190 tree_generator::handle_string_literal (const std::string
&val
)
2192 int location
= class_wrapper
->add (val
);
2194 = gcc_builtins
->map_type (global
->get_compiler ()->java_lang_String ());
2195 return build_ref_from_constant_pool (type
, location
);
2199 tree_generator::visit_string_literal (model_string_literal
*,
2200 const std::string
&val
)
2202 current
= handle_string_literal (val
);
2206 tree_generator::handle_invocation (const model_method
*meth
,
2207 tree this_expr_tree
,
2208 const std::list
<ref_expression
> &args
,
2212 tree arg_tree
= build_arguments (args
, compound
);
2214 // Handle the reference-checking part of a non-static reference to a
2215 // static method here. The rest is handled by map_method_call.
2217 // FIXME: wrong! we must evaluate for side effects, not nullity.
2218 if (this_expr_tree
!= NULL_TREE
2219 && ! meth
->static_p ()
2220 && this_expr_tree
!= this_tree
)
2221 this_expr_tree
= gcc_builtins
->check_reference (this_expr_tree
);
2224 current
= gcc_builtins
->map_method_call (class_wrapper
,
2225 this_expr_tree
, arg_tree
,
2226 const_cast<model_method
*> (meth
),
2228 if (compound
!= NULL_TREE
)
2229 current
= build2 (COMPOUND_EXPR
, TREE_TYPE (current
), compound
, current
);
2233 tree_generator::visit_method_invocation (model_method_invocation
*elt
,
2235 const ref_expression
&this_expr
,
2236 const std::list
<ref_expression
> &args
)
2238 tree expr_tree
= NULL_TREE
;
2239 tree side_effect
= NULL_TREE
;
2242 this_expr
->visit (this);
2243 if (! meth
->static_p ())
2244 expr_tree
= current
;
2246 side_effect
= current
;
2248 handle_invocation (meth
, expr_tree
, args
);
2249 annotate (current
, elt
);
2251 // Handle the case where we evaluate the expression for side effects
2252 // but discard its value.
2253 if (side_effect
!= NULL_TREE
)
2255 current
= build2 (COMPOUND_EXPR
, TREE_TYPE (current
),
2256 side_effect
, current
);
2257 TREE_SIDE_EFFECTS (current
) = 1;
2262 tree_generator::visit_type_qualified_invocation
2263 (model_type_qualified_invocation
*elt
,
2264 const model_method
*meth
,
2265 const std::list
<ref_expression
> &args
,
2268 handle_invocation (meth
, meth
->static_p () ? NULL_TREE
: this_tree
, args
,
2270 annotate (current
, elt
);
2274 tree_generator::visit_super_invocation (model_super_invocation
*elt
,
2275 const model_method
*meth
,
2276 const std::list
<ref_expression
> &args
,
2277 const ref_expression
&finit
)
2279 handle_invocation (meth
, this_tree
, args
, true);
2280 annotate (current
, elt
);
2284 tree save
= current
;
2285 finit
->visit (this);
2286 current
= build2 (COMPOUND_EXPR
, TREE_TYPE (current
), save
, current
);
2287 TREE_SIDE_EFFECTS (current
) = 1;
2288 annotate (current
, elt
);
2293 tree_generator::visit_this_invocation (model_this_invocation
*elt
,
2294 const model_method
*meth
,
2295 const std::list
<ref_expression
> &args
)
2297 handle_invocation (meth
, this_tree
, args
);
2298 annotate (current
, elt
);
2302 tree_generator::visit_new (model_new
*elt
,
2303 const model_method
*constructor
,
2304 const ref_forwarding_type
&klass
,
2305 const std::list
<ref_expression
> &args
)
2308 tree arg_tree
= build_arguments (args
, compound
);
2310 // FIXME: layout should be done by the ABI, not us.
2311 model_class
*klassp
= assert_cast
<model_class
*> (klass
->type ());
2312 gcc_builtins
->lay_out_class (klassp
);
2314 = gcc_builtins
->map_new (class_wrapper
, klassp
,
2315 const_cast<model_method
*> (constructor
),
2317 if (compound
!= NULL_TREE
)
2318 current
= build2 (COMPOUND_EXPR
, TREE_TYPE (current
), compound
, current
);
2320 annotate (current
, elt
);
2324 tree_generator::visit_new_array (model_new_array
*new_elt
,
2325 const ref_forwarding_type
&elt_type
,
2326 const std::list
<ref_expression
> &indices
,
2327 const ref_expression
&init
)
2329 if (indices
.size () == 1)
2331 ref_expression ind
= indices
.front ();
2334 tree ind_tree
= current
;
2335 if (elt_type
->type ()->primitive_p ())
2336 current
= build_new_array (elt_type
->type (), ind_tree
, new_elt
);
2338 current
= build_new_object_array (elt_type
->type (), ind_tree
);
2339 annotate (current
, new_elt
);
2341 else if (indices
.size () != 0)
2343 int num
= indices
.size ();
2345 tree args
= build_arguments (indices
, compound
);
2347 args
= tree_cons (NULL_TREE
, build_int (num
), args
);
2348 args
= tree_cons (NULL_TREE
,
2349 build_class_ref (new_elt
->type (), new_elt
),
2352 tree array_type_tree
= gcc_builtins
->map_type (new_elt
->type ());
2353 current
= convert (array_type_tree
,
2354 build3 (CALL_EXPR
, ptr_type_node
,
2355 builtin_Jv_NewMultiArray
,
2358 // This is to force evaluation order to be correct.
2359 if (compound
!= NULL_TREE
)
2360 current
= build2 (COMPOUND_EXPR
, TREE_TYPE (current
), compound
,
2362 annotate (current
, new_elt
);
2372 tree_generator::visit_null_literal (model_null_literal
*)
2374 current
= null_pointer_node
;
2378 tree_generator::handle_inc_dec (model_element
*element
, tree_code op
,
2379 const ref_expression
&expr
)
2382 tree expr_tree
= current
;
2383 tree expr_type
= gcc_builtins
->map_type (expr
->type ());
2384 current
= build2 (op
, expr_type
, expr_tree
,
2385 fold (convert (expr_type
, integer_one_node
)));
2386 TREE_SIDE_EFFECTS (current
) = 1;
2387 annotate (current
, element
);
2391 tree_generator::visit_prefix_side_effect (model_prefix_plusplus
*elt
,
2392 const ref_expression
&expr
)
2394 handle_inc_dec (elt
, PREINCREMENT_EXPR
, expr
);
2398 tree_generator::visit_prefix_side_effect (model_prefix_minusminus
*elt
,
2399 const ref_expression
&expr
)
2401 handle_inc_dec (elt
, PREDECREMENT_EXPR
, expr
);
2405 tree_generator::visit_prefix_simple (model_prefix_plus
*,
2406 const ref_expression
&expr
)
2408 // Nothing special to do here.
2413 tree_generator::visit_prefix_simple (model_prefix_minus
*elt
,
2414 const ref_expression
&expr
)
2417 tree hold
= current
;
2418 current
= build1 (NEGATE_EXPR
, gcc_builtins
->map_type (expr
->type ()), hold
);
2419 TREE_SIDE_EFFECTS (current
) = TREE_SIDE_EFFECTS (hold
);
2420 annotate (current
, elt
);
2424 tree_generator::visit_prefix_simple (model_bitwise_not
*elt
,
2425 const ref_expression
&expr
)
2428 tree hold
= current
;
2429 current
= build1 (BIT_NOT_EXPR
, gcc_builtins
->map_type (expr
->type ()),
2431 TREE_SIDE_EFFECTS (current
) = TREE_SIDE_EFFECTS (hold
);
2432 annotate (current
, elt
);
2436 tree_generator::visit_prefix_simple (model_logical_not
*elt
,
2437 const ref_expression
&expr
)
2440 tree hold
= current
;
2441 current
= build1 (TRUTH_NOT_EXPR
, type_jboolean
, hold
);
2442 TREE_SIDE_EFFECTS (current
) = TREE_SIDE_EFFECTS (hold
);
2443 annotate (current
, elt
);
2447 tree_generator::visit_postfix_side_effect (model_postfix_plusplus
*elt
,
2448 const ref_expression
&expr
)
2450 handle_inc_dec (elt
, POSTINCREMENT_EXPR
, expr
);
2454 tree_generator::visit_postfix_side_effect (model_postfix_minusminus
*elt
,
2455 const ref_expression
&expr
)
2457 handle_inc_dec (elt
, POSTDECREMENT_EXPR
, expr
);
2461 tree_generator::visit_this (model_this
*this_expr
)
2463 assert (this_tree
!= NULL_TREE
);
2465 model_class
*rtype
= assert_cast
<model_class
*> (this_expr
->type ());
2466 model_class
*prev
= rtype
;
2467 model_class
*iter
= method
->get_declaring_class ();
2470 if (method
->constructor_p () && ! this_expr
->check_match (rtype
, iter
))
2472 // In <init>, we want to reference the argument
2473 // corresponding to this$0, not the field. This is more
2474 // efficient, and also without it we can create unverifiable
2475 // bytecode before invoking the superclass constructor.
2476 // Obviously this doesn't make sense for a pure "this", only
2478 model_constructor
*cons
2479 = assert_cast
<model_constructor
*> (method
);
2480 model_variable_decl
*th0
= cons
->get_this0_parameter ();
2481 expr_tree
= gcc_builtins
->map_variable (method_tree
, th0
);
2483 iter
= iter
->get_lexically_enclosing_class ();
2486 expr_tree
= this_tree
;
2489 ! this_expr
->check_match (rtype
, iter
);
2490 iter
= iter
->get_lexically_enclosing_class ())
2492 assert (iter
!= NULL
);
2494 ref_field th0
= iter
->get_this_0 ();
2495 gcc_builtins
->lay_out_class (iter
);
2496 expr_tree
= gcc_builtins
->map_field_ref (class_wrapper
, expr_tree
,
2502 current
= expr_tree
;
2503 // Note: can't annotate here as we have a DECL, not an expression.
2507 tree_generator::visit_simple_variable_ref (model_simple_variable_ref
*elt
,
2508 const model_variable_decl
*decl
)
2511 = gcc_builtins
->map_variable (method_tree
,
2512 const_cast<model_variable_decl
*> (decl
));
2513 // We don't have to set TREE_SIDE_EFFECTS here, as a variable cannot
2514 // be volatile and this would be handled by map_variable anyway.
2518 tree_generator::build_int (jint val
, tree override
)
2520 return build_int_cst (override
? override
: type_jint
, val
);
2524 tree_generator::build_long (jlong val
)
2526 unsigned HOST_WIDE_INT low
;
2528 unsigned HOST_WIDE_INT v2
;
2530 v2
= (unsigned HOST_WIDE_INT
) ((val
>> 32) & 0xffffffffLL
);
2531 lshift_double (v2
, 0, 32, 64, &low
, &high
, 0);
2532 add_double (low
, high
, (unsigned HOST_WIDE_INT
) (val
& 0xffffffffLL
),
2534 tree value
= build_int_cst_wide (type_jlong
, low
, high
);
2538 tree_generator::build_new_array (model_type
*elt_type
, tree size
,
2539 model_element
*request
)
2541 assert (elt_type
->primitive_p ());
2542 model_type
*array_type
= elt_type
->array ();
2544 tree array_type_tree
= gcc_builtins
->map_type (array_type
);
2546 tree insn
= build3 (CALL_EXPR
, ptr_type_node
,
2547 builtin_Jv_NewPrimArray
,
2548 tree_cons (NULL_TREE
,
2549 build_class_ref (elt_type
, request
),
2550 tree_cons (NULL_TREE
, size
, NULL_TREE
)),
2552 TREE_SIDE_EFFECTS (insn
) = 1;
2554 // Now cast to correct type.
2555 insn
= build1 (NOP_EXPR
, array_type_tree
, insn
);
2556 TREE_SIDE_EFFECTS (insn
) = 1;
2562 tree_generator::build_new_object_array (model_type
*elt_type
, tree size
)
2564 model_class
*array_type
= assert_cast
<model_class
*> (elt_type
->array ());
2566 tree elt_type_tree
= build_class_ref (elt_type
, elt_type
);
2567 tree array_type_tree
= gcc_builtins
->lay_out_class (array_type
);
2569 tree args
= tree_cons (NULL_TREE
, size
,
2570 tree_cons (NULL_TREE
, elt_type_tree
,
2571 tree_cons (NULL_TREE
, null_pointer_node
,
2574 tree insn
= build3 (CALL_EXPR
, array_type_tree
, builtin_Jv_NewObjectArray
,
2576 TREE_SIDE_EFFECTS (insn
) = 1;
2582 tree_generator::build_ref_from_constant_pool (tree type
, int index
)
2584 tree cpool
= gcc_builtins
->get_constant_pool_decl (class_wrapper
->get ());
2585 tree result
= build4 (ARRAY_REF
, ptr_type_node
,
2586 cpool
, build_int_cst (type_jint
, index
),
2587 NULL_TREE
, NULL_TREE
);
2588 TREE_CONSTANT (result
) = 1;
2589 return build1 (NOP_EXPR
, type
, result
);
2592 // This comes directly from gcj.
2594 tree_generator::build_exception_object_ref (tree type
)
2596 // Java only passes object via pointer and doesn't require
2597 // adjusting. The java object is immediately before the generic
2598 // exception header.
2599 tree obj
= build0 (EXC_PTR_EXPR
, build_pointer_type (type
));
2600 obj
= build2 (MINUS_EXPR
, TREE_TYPE (obj
), obj
,
2601 TYPE_SIZE_UNIT (TREE_TYPE (obj
)));
2602 obj
= build1 (INDIRECT_REF
, type
, obj
);
2606 // FIXME: this is (sort of) duplicated in bytecode_generator.
2608 tree_generator::find_field (const std::string
&name
,
2609 model_class
*klass
, model_type
*type
,
2610 model_element
*request
)
2612 std::set
<model_field
*> result
;
2613 klass
->find_members (name
, result
, klass
, NULL
);
2614 if (result
.size () == 1)
2616 model_field
*field
= *(result
.begin ());
2617 if (field
->type ()->erasure () == type
)
2620 throw request
->error ("couldn't find field %1 of type %2 in class %3")
2621 % name
% type
% klass
;
2625 tree_generator::build_class_ref (model_type
*t
, model_element
*request
)
2629 assert (t
!= null_type
);
2630 if (t
->primitive_p () || t
== primitive_void_type
)
2632 model_class
*wrapper
= box_primitive_type (t
);
2633 // Maybe for BC we could still emit a direct reference to the
2636 = find_field ("TYPE", wrapper
,
2637 global
->get_compiler ()->java_lang_Class (),
2639 result
= gcc_builtins
->map_field_ref (class_wrapper
, NULL_TREE
,
2642 else if (t
->array_p ())
2644 // We can't refer to array types directly, so we emit a
2645 // reference via the constant pool.
2646 model_class
*klass
= assert_cast
<model_class
*> (t
);
2647 result
= build_ref_from_constant_pool (type_class_ptr
,
2648 class_wrapper
->add (klass
));
2652 gcj_abi
*abi
= gcc_builtins
->find_abi ();
2653 result
= abi
->build_class_reference (gcc_builtins
, class_wrapper
,
2654 assert_cast
<model_class
*> (t
));
2660 tree_generator::build_class_ref (const std::string
&classname
)
2662 gcj_abi
*abi
= gcc_builtins
->find_abi ();
2663 return abi
->build_class_reference (gcc_builtins
, class_wrapper
, classname
);
2667 tree_generator::build_divide (tree result_type
, tree lhs
, tree rhs
)
2669 enum tree_code opcode
;
2670 if (result_type
== type_jfloat
|| result_type
== type_jdouble
)
2674 if (flag_use_divide_subroutine
)
2677 if (result_type
== type_jlong
)
2678 func
= builtin_Jv_divJ
;
2680 func
= builtin_Jv_divI
;
2681 return build3 (CALL_EXPR
, result_type
, func
,
2682 tree_cons (NULL_TREE
, lhs
,
2683 build_tree_list (NULL_TREE
, rhs
)),
2686 opcode
= TRUNC_DIV_EXPR
;
2689 return build2 (opcode
, result_type
, lhs
, rhs
);
2693 tree_generator::build_mod (tree result_type
, tree lhs
, tree rhs
)
2696 if (result_type
== type_jfloat
)
2697 func
= build_address_of (built_in_decls
[BUILT_IN_FMODF
]);
2698 else if (result_type
== type_jdouble
)
2699 func
= build_address_of (built_in_decls
[BUILT_IN_FMOD
]);
2702 if (! flag_use_divide_subroutine
)
2703 return build2 (TRUNC_MOD_EXPR
, result_type
, lhs
, rhs
);
2705 if (result_type
== type_jlong
)
2706 func
= builtin_Jv_remJ
;
2708 func
= builtin_Jv_remI
;
2711 return build3 (CALL_EXPR
, result_type
, func
,
2712 tree_cons (NULL_TREE
, lhs
,
2713 build_tree_list (NULL_TREE
, rhs
)),
2718 tree_generator::build_array_reference (tree array
, tree index
,
2723 tree array_type
= TREE_TYPE (TREE_TYPE (array
));
2724 // Note that the 'data' field is a back-end invention; it does not
2725 // exist in the model, so we can't look for it there.
2726 tree datafield
= gcc_builtins
->find_decl (array_type
, "data");
2728 array
= save_expr (array
);
2729 index
= save_expr (index
);
2732 = build4 (ARRAY_REF
, result_type
,
2733 build3 (COMPONENT_REF
, TREE_TYPE (datafield
),
2734 build1 (INDIRECT_REF
, array_type
,
2735 gcc_builtins
->check_reference (array
)),
2736 datafield
, NULL_TREE
),
2738 NULL_TREE
, NULL_TREE
);
2739 TREE_SIDE_EFFECTS (result
) = (TREE_SIDE_EFFECTS (array
)
2740 || TREE_SIDE_EFFECTS (index
));
2742 // The bounds check takes precedence over the array store check, but
2743 // we are building things bottom-up, so we construct the array store
2745 if (rhs
!= NULL_TREE
)
2747 tree call
= build3 (CALL_EXPR
, void_type_node
,
2748 builtin_Jv_CheckArrayStore
,
2749 tree_cons (NULL_TREE
, array
,
2750 build_tree_list (NULL_TREE
, rhs
)),
2752 TREE_SIDE_EFFECTS (call
) = 1;
2754 result
= build2 (COMPOUND_EXPR
, result_type
, call
, result
);
2755 TREE_SIDE_EFFECTS (result
) = 1;
2758 if (use_checks
&& flag_bounds_check
)
2760 tree field
= gcc_builtins
->find_decl (array_type
, "length");
2762 // First: if ((unsigned) index >= (unsigned) length) throw
2763 // ArrayIndexOutOfBoundsException. Note that this unsigned
2764 // comparison also takes care of checking for INDEX < 0.
2765 tree length
= build3 (COMPONENT_REF
, type_jint
,
2766 // Note we don't use check_reference here,
2767 // as it would be redundant.
2768 build1 (INDIRECT_REF
, array_type
, array
),
2770 tree call
= build3 (CALL_EXPR
, void_type_node
,
2771 builtin_Jv_ThrowBadArrayIndex
,
2772 build_tree_list (NULL_TREE
, index
),
2774 TREE_SIDE_EFFECTS (call
) = 1;
2775 tree check
= build3 (COND_EXPR
, void_type_node
,
2776 build2 (GE_EXPR
, type_jboolean
,
2777 build1 (NOP_EXPR
, type_juint
, index
),
2778 build1 (NOP_EXPR
, type_juint
, length
)),
2780 build_empty_stmt ());
2781 result
= build2 (COMPOUND_EXPR
, result_type
, check
, result
);
2782 TREE_SIDE_EFFECTS (result
) = (TREE_SIDE_EFFECTS (array
)
2783 || TREE_SIDE_EFFECTS (index
));
2786 // This is a trick to force evaluation order to be correct.
2787 result
= build2 (COMPOUND_EXPR
, result_type
,
2788 build2 (COMPOUND_EXPR
, TREE_TYPE (index
),
2796 tree_generator::build_arguments (const std::list
<ref_expression
> &args
,
2799 // Build the argument list, and also build a COMPOUND_EXPR which is
2800 // used to force evaluation order.
2801 tree arg_tree
= NULL_TREE
;
2802 compound
= NULL_TREE
;
2803 for (std::list
<ref_expression
>::const_iterator i
= args
.begin ();
2809 // Promote the argument if required.
2810 tree type
= TREE_TYPE (current
);
2811 if (targetm
.calls
.promote_prototypes (type
)
2812 && (*i
)->type ()->integral_p ())
2814 model_type
*type
= (*i
)->type ();
2815 if (type
!= primitive_int_type
&& type
!= primitive_long_type
)
2816 current
= fold_convert (type_jint
, current
);
2819 tree saved
= save_expr (current
);
2820 if (compound
== NULL_TREE
)
2823 compound
= build2 (COMPOUND_EXPR
, void_type_node
, compound
, saved
);
2825 arg_tree
= tree_cons (NULL_TREE
, saved
, arg_tree
);
2827 arg_tree
= nreverse (arg_tree
);