* tree.cc (tree_generator::make_block): Complete comment about
[official-gcc.git] / gcc / java / tree.cc
blobbcc4b75ade4d6a3d57052f5dbbceaf2038e78a92
1 // Tree generation.
3 // Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
4 //
5 // This file is part of GCC.
6 //
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)
10 // any later version.
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
20 // 02111-1307, USA.
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),
35 class_wrapper (k),
36 current (NULL_TREE),
37 this_tree (NULL_TREE),
38 method (NULL),
39 method_tree (NULL_TREE),
40 current_block (NULL_TREE),
41 temp_counter (0),
42 labels (NULL),
43 stack_top (0),
44 stack_types (NULL),
45 stack_slots (NULL),
46 local_slots (NULL)
50 tree_generator::~tree_generator ()
52 if (labels)
53 delete[] labels;
54 if (stack_types)
55 delete[] stack_types;
56 if (stack_slots)
57 delete[] stack_slots;
58 if (local_slots)
59 delete[] local_slots;
62 tree
63 tree_generator::generate (model_method *m)
65 m->visit (this);
66 return method_tree;
71 void
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 ());
79 tree
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;
86 return var;
89 tree
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;
96 return var;
99 void
100 tree_generator::emit_type_assertion (model_type *to_type,
101 model_type *from_type)
105 tree
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);
110 return result;
113 tree
114 tree_generator::build_label ()
116 tree result = build0 (LABEL_DECL, NULL_TREE);
117 DECL_CONTEXT (result) = current_block;
118 DECL_ARTIFICIAL (result) = 1;
119 return result;
122 tree
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.
129 TREE_USED (b) = 1;
131 return b;
136 void
137 tree_generator::visit_method (model_method *meth,
138 const std::list<ref_variable_decl> &params,
139 const ref_block &block)
141 method = meth;
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;
148 if (block)
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 ())
167 tree init
168 = gcc_builtins->build_class_init (meth->get_declaring_class ());
169 tsi_link_after (&out, init, TSI_CONTINUE_LINKING);
172 block->visit (this);
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)
187 tree k;
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);
191 else
192 k = this_tree;
193 current = wrap_synchronized (k, current);
196 current = build3 (BIND_EXPR, void_type_node,
197 BLOCK_VARS (current_block),
198 current, current_block);
200 else
202 assert (meth->native_p ());
203 if (flag_jni)
204 current = build_jni_stub ();
205 else
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
215 // from the old gcj.
216 tree
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"),
238 ptr_type_node);
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 ();
256 tree klass
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),
263 NULL_TREE));
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;
270 tree tem;
271 int args_size = 0;
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)));
275 #ifdef PARM_BOUNDARY
276 arg_bits = (((arg_bits + PARM_BOUNDARY - 1) / PARM_BOUNDARY)
277 * PARM_BOUNDARY);
278 #endif
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));
305 tree method_sig
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 ()));
312 lookup_arg
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);
320 #endif
322 tree jni_func_type = build_pointer_type (tem);
324 tree jnifunc = build3 (COND_EXPR, ptr_type_node,
325 meth_var, meth_var,
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
332 // pointer.
333 tree call = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (method_tree)),
334 build1 (NOP_EXPR, jni_func_type, jnifunc),
335 args, NULL_TREE);
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)),
341 res_var, call);
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),
352 NULL_TREE);
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)
361 tree drt;
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
366 // promoted.
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),
379 body, block);
380 return bind;
385 void
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 ();
393 return;
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,
400 NULL_TREE,
401 disabled.get ());
403 first->visit (this);
404 tree first_tree = current;
406 tree args = NULL_TREE;
407 model_type *arg_type = NULL;
408 if (second)
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);
423 // Generate:
424 // if (! $assertionsDisabled && ! FIRST) throw new AssertionError (SECOND)
425 tree throw_node = build3 (CALL_EXPR, void_type_node,
426 builtin_Jv_Throw,
427 build_tree_list (NULL_TREE, new_tree),
428 NULL_TREE);
429 current = build3 (COND_EXPR, void_type_node,
430 build2 (TRUTH_ANDIF_EXPR,
431 type_jboolean,
432 build1 (TRUTH_NOT_EXPR,
433 type_jboolean,
434 disabled_tree),
435 build1 (TRUTH_NOT_EXPR,
436 type_jboolean,
437 first_tree)),
438 throw_node, NULL_TREE);
439 annotate (current, element);
442 tree
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 ();
449 i != vals.end ();
450 ++i)
452 current = NULL_TREE;
453 (*i)->visit (this);
454 if (current != NULL_TREE)
455 tsi_link_after (&out, current, TSI_CONTINUE_LINKING);
457 return result;
460 void
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);
476 void
477 tree_generator::visit_break (model_break *brk,
478 const ref_stmt &target)
480 model_stmt *real_target = target.get ();
481 if (! real_target)
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);
493 void
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
509 // list.
510 tree vtype = gcc_builtins->map_type (vardecl->type ());
511 // FIXME: 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.
518 body->visit (this);
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
527 // -fPIC.
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);
535 void
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);
548 void
549 tree_generator::visit_class_decl_stmt (model_class_decl_stmt *,
550 const ref_class &)
552 // Nothing to do.
555 void
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.
566 expr->visit (this);
567 tree expr_tree = current;
568 body->visit (this);
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
575 // changed.
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,
579 void_type_node,
580 fold (build1 (TRUTH_NOT_EXPR, type_jboolean,
581 expr_tree))),
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);
594 current = outer;
597 void
598 tree_generator::visit_empty (model_empty *)
600 current = build_empty_stmt ();
603 void
604 tree_generator::visit_expression_stmt (model_expression_stmt *,
605 const ref_expression &expr)
607 expr->visit (this);
610 void
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.
652 tree get_len
653 = build3 (COMPONENT_REF, type_jint,
654 build1 (INDIRECT_REF, container_type,
655 // FIXME: there is probably a more optimal
656 // approach here.
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,
681 container_tree),
682 datafield, NULL_TREE),
683 index_tree, NULL_TREE, NULL_TREE);
685 else
687 // Use an iterator.
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,
700 fstmt);
701 model_method *next_meth = find_method ("next", iterator_type, NULL,
702 object_type, fstmt);
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),
710 iter_tree,
711 gcc_builtins->map_method_call (class_wrapper,
712 container_tree,
713 NULL_TREE, iter_meth,
714 false));
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,
722 has_next_meth,
723 false));
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,
729 next_meth, false);
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
737 // loop body.
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),
746 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.
752 body->visit (this);
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);
772 void
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);
789 if (init)
791 init->visit (this);
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);
798 if (cond)
800 cond->visit (this);
801 tsi_link_after (&body_out, build1 (EXIT_EXPR, void_type_node,
802 fold (build1 (TRUTH_NOT_EXPR,
803 type_jboolean,
804 current))),
805 TSI_CONTINUE_LINKING);
807 body->visit (this);
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);
812 if (update)
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
819 // list.
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);
831 void
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)
837 cond->visit (this);
838 tree cond_tree = current;
839 true_branch->visit (this);
840 tree true_tree = current;
841 tree false_tree;
842 if (false_branch)
844 false_branch->visit (this);
845 false_tree = current;
847 else
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);
858 void
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);
874 stmt->visit (this);
875 tsi_link_after (&out, current, TSI_CONTINUE_LINKING);
876 tsi_link_after (&out, wrap_label (brk, label), TSI_CONTINUE_LINKING);
878 current = body_tree;
880 else
881 stmt->visit (this);
884 void
885 tree_generator::visit_return (model_return *rtn,
886 const ref_expression &expr)
888 if (expr)
890 expr->visit (this);
891 current = build2 (MODIFY_EXPR, TREE_TYPE (DECL_RESULT (method_tree)),
892 DECL_RESULT (method_tree),
893 convert (TREE_TYPE (DECL_RESULT (method_tree)),
894 current));
895 TREE_SIDE_EFFECTS (current) = 1;
897 else
898 current = NULL_TREE;
899 current = build1 (RETURN_EXPR, void_type_node, current);
900 TREE_SIDE_EFFECTS (current) = 1;
901 annotate (current, rtn);
904 void
905 tree_generator::visit_switch (model_switch *swstmt,
906 const ref_expression &expr,
907 const std::list<ref_switch_block> &blocks)
909 expr->visit (this);
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 ();
920 i != blocks.end ();
921 ++i)
923 if ((*i).get () == def)
925 tree label = build_label ();
927 tree case_label = build3 (CASE_LABEL_EXPR, NULL_TREE, NULL_TREE,
928 NULL_TREE, label);
929 annotate (case_label, (*i).get ());
930 tsi_link_after (&out, case_label, TSI_CONTINUE_LINKING);
932 (*i)->visit (this);
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);
944 current = body_tree;
947 void
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
952 // without a cast.
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 ();
961 i != labels.end ();
962 ++i)
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),
968 NULL_TREE, label);
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);
976 current = body_tree;
979 tree
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),
989 NULL_TREE);
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),
996 NULL_TREE);
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);
1008 void
1009 tree_generator::visit_synchronized (model_synchronized *sync,
1010 const ref_expression &expr,
1011 const ref_stmt &body)
1013 expr->visit (this);
1014 tree expr_tree = current;
1015 body->visit (this);
1016 tree body_tree = current;
1018 current = wrap_synchronized (expr_tree, body_tree);
1019 annotate (current, sync);
1022 void
1023 tree_generator::visit_throw (model_throw *element,
1024 const ref_expression &expr)
1026 expr->visit (this);
1027 tree expr_tree = current;
1028 current = build3 (CALL_EXPR, void_type_node,
1029 builtin_Jv_Throw,
1030 build_tree_list (NULL_TREE, expr_tree),
1031 NULL_TREE);
1032 TREE_SIDE_EFFECTS (current) = 1;
1033 annotate (current, element);
1036 void
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.
1043 body->visit (this);
1044 tree body_tree = current;
1046 assert (finally || ! catchers.empty ());
1048 // Now generate trees for the catch clauses, but only if there are
1049 // any.
1050 tree result;
1052 if (catchers.empty ())
1053 result = body_tree;
1054 else
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 ();
1060 ++i)
1062 (*i)->visit (this);
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.
1073 if (finally)
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);
1082 current = result;
1083 annotate (current, trystmt);
1086 void
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 ();
1096 i != decls.end ();
1097 ++i)
1099 tree decl = add_var (*i);
1100 if ((*i)->has_initializer_p ())
1102 ref_expression init = (*i)->get_initializer ();
1103 init->visit (this);
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),
1109 decl, current);
1110 TREE_SIDE_EFFECTS (modify) = 1;
1111 tsi_link_after (&out, modify, TSI_CONTINUE_LINKING);
1115 current = result;
1118 void
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);
1133 cond->visit (this);
1134 tsi_link_after (&out, build1 (EXIT_EXPR, void_type_node,
1135 fold (build1 (TRUTH_NOT_EXPR, type_jboolean,
1136 current))),
1137 TSI_CONTINUE_LINKING);
1139 body->visit (this);
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);
1154 void
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);
1164 else
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 ();
1182 i != exprs.rend ();
1183 ++i)
1185 (*i)->visit (this);
1186 tree value = current;
1188 tree idx_tree = build_int_cst (type_jint, index);
1189 tree assign
1190 = build2 (MODIFY_EXPR, elt_tree,
1191 build_array_reference (new_expr, idx_tree,
1192 elt_tree, false),
1193 value);
1194 TREE_SIDE_EFFECTS (assign) = 1;
1195 result = build2 (COMPOUND_EXPR, TREE_TYPE (result), assign, result);
1196 --index;
1199 current = result;
1200 annotate (current, initx);
1203 void
1204 tree_generator::handle_array_ref (model_array_ref *aref,
1205 model_expression *array,
1206 model_expression *index,
1207 tree rhs)
1209 array->visit (this);
1210 tree array_tree = current;
1211 index->visit (this);
1212 tree index_tree = current;
1213 tree component_type
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,
1220 true, rhs);
1221 annotate (current, aref);
1224 void
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 ());
1232 void
1233 tree_generator::binary_operator (model_element *element,
1234 tree_code code,
1235 const ref_expression &lhs,
1236 const ref_expression &rhs,
1237 tree result_type)
1239 lhs->visit (this);
1240 tree lhs_tree = current;
1241 rhs->visit (this);
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);
1253 else
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);
1260 void
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);
1268 void
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);
1276 void
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);
1284 void
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);
1292 void
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);
1300 void
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);
1308 void
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.
1317 model_method *
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 ();
1327 ++i)
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)
1334 result = meth;
1335 break;
1337 if (! argtype || len != 1)
1338 continue;
1339 ref_variable_decl var = params.front ();
1340 if (var->type ()->erasure () == argtype)
1342 result = meth;
1343 break;
1347 if (! result)
1349 throw request->error ("couldn't find method %1 with argument of type "
1350 "%2 in class %3 -- perhaps you have the wrong "
1351 "class library?")
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"
1358 " of %2")
1359 % result % result_type;
1361 return result;
1364 void
1365 tree_generator::stringbuffer_append (model_expression *expr,
1366 tree &buffer_tree,
1367 model_class *sb_class,
1368 tree expr_override)
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);
1381 else
1383 // Generate code for the expression.
1384 tree expr_tree;
1385 if (expr_override)
1386 expr_tree = expr_override;
1387 else
1389 expr->visit (this);
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,
1412 sb_class, expr);
1413 tree ap_tree = gcc_builtins->map_method_call (class_wrapper,
1414 buffer_tree, args,
1415 append, false);
1416 buffer_tree = save_expr (ap_tree);
1420 void
1421 tree_generator::handle_string_plus (model_plus *model,
1422 const ref_expression &lhs,
1423 const ref_expression &rhs,
1424 tree &buffer_tree,
1425 model_class *sb_class)
1427 stringbuffer_append (lhs.get (), buffer_tree, sb_class);
1428 stringbuffer_append (rhs.get (), buffer_tree, sb_class);
1431 tree
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,
1448 init, NULL_TREE);
1449 buffer_tree = save_expr (buffer_tree);
1451 *sb_class_r = sb_class;
1452 return buffer_tree;
1455 tree
1456 tree_generator::finish_stringbuffer (model_class *sb_class,
1457 tree buffer_tree,
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
1462 // String.
1463 model_method *tostring
1464 = find_method ("toString", sb_class, NULL,
1465 global->get_compiler ()->java_lang_String (),
1466 model);
1467 tree result = gcc_builtins->map_method_call (class_wrapper, buffer_tree,
1468 NULL_TREE, tostring, false);
1469 TREE_SIDE_EFFECTS (result) = 1;
1470 return result;
1473 void
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);
1481 return;
1484 // String '+'.
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);
1493 tree
1494 tree_generator::arith_shift (model_element *element,
1495 tree_code kind,
1496 const ref_expression &lhs,
1497 const ref_expression &rhs,
1498 bool is_unsigned)
1500 lhs->visit (this);
1501 tree lhs_tree = current;
1502 tree saved_lhs_type = TREE_TYPE (lhs_tree);
1503 rhs->visit (this);
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);
1514 rhs_tree = conv;
1517 if (is_unsigned)
1519 model_type *lt = lhs->type ();
1520 tree utype;
1521 if (lt == primitive_int_type)
1522 utype = type_juint;
1523 else
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);
1530 lhs_tree = conv;
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);
1539 rhs_tree = folded;
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);
1546 if (is_unsigned)
1548 tree conv = build1 (CONVERT_EXPR, saved_lhs_type, result);
1549 TREE_SIDE_EFFECTS (conv) = TREE_SIDE_EFFECTS (result);
1550 result = conv;
1553 return result;
1556 void
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);
1564 void
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);
1572 void
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);
1580 void
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
1586 // in this class.
1587 rhs->visit (this);
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 ());
1595 if (ref != NULL
1596 && rhs->type () != null_type
1597 && ref->type ()->reference_p ())
1598 handle_array_ref (ref, ref->get_array (), ref->get_index (), rhs_tree);
1599 else
1600 lhs->visit (this);
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);
1609 void
1610 tree_generator::handle_op_assignment (model_element *element,
1611 tree_code op,
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
1616 // in this class.
1617 rhs->visit (this);
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 ());
1625 if (ref != NULL
1626 && rhs->type () != null_type
1627 && ref->type ()->reference_p ())
1628 handle_array_ref (ref, ref->get_array (), ref->get_index (), rhs_tree);
1629 else
1630 lhs->visit (this);
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;
1641 if (! is_shift)
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.
1649 tree operation;
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);
1654 else
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);
1671 void
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);
1679 void
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);
1687 void
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);
1695 void
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);
1703 void
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);
1711 void
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);
1719 void
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);
1727 void
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);
1735 void
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);
1743 void
1744 tree_generator::visit_op_assignment (model_urs_equal *op,
1745 const ref_expression &lhs,
1746 const ref_expression &rhs)
1748 lhs->visit (this);
1749 tree lhs_tree = stabilize_reference (current);
1751 tree utype;
1752 if (lhs->type () == primitive_int_type)
1753 utype = type_juint;
1754 else
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));
1763 rhs->visit (this);
1764 tree rhs_tree = current;
1766 current = build2 (MODIFY_EXPR, gcc_builtins->map_type (lhs->type ()),
1767 lhs_tree,
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);
1775 void
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);
1783 return;
1786 // String '+='.
1787 model_class *sb_class;
1788 tree buffer_tree = create_stringbuffer (&sb_class, elt);
1790 // Wrap the LHS so we only evaluate it once.
1791 lhs->visit (this);
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);
1808 void
1809 tree_generator::visit_cast (model_cast *elt,
1810 const ref_forwarding_type &dest,
1811 const ref_expression &expr)
1813 expr->visit (this);
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 ()
1833 + "Value");
1834 model_method *call
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);
1846 else
1848 // Boxing conversion. We call the static factory method
1849 // valueOf(), which handles the caching required by boxing
1850 // conversion.
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,
1854 elt);
1855 tree args = build_tree_list (NULL_TREE, expr_tree);
1856 current = gcc_builtins->map_method_call (class_wrapper, NULL_TREE,
1857 args, call, false);
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);
1877 else
1879 current = fold_convert (gcc_builtins->map_type (dest_type),
1880 expr_tree);
1881 TREE_SIDE_EFFECTS (current) = TREE_SIDE_EFFECTS (expr_tree);
1884 else
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)),
1895 NULL_TREE);
1896 TREE_SIDE_EFFECTS (current) = 1;
1898 else
1900 emit_type_assertion (dest_type, expr_type);
1901 current = build1 (NOP_EXPR, gcc_builtins->map_type (dest_type),
1902 expr_tree);
1903 TREE_SIDE_EFFECTS (current) = TREE_SIDE_EFFECTS (expr_tree);
1906 // FIXME: might have a constant or DECL here.
1907 // annotate (current, elt);
1910 void
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);
1918 void
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);
1926 void
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);
1934 void
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);
1942 void
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);
1950 void
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);
1958 void
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);
1966 void
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)
1972 cond->visit (this);
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);
1987 void
1988 tree_generator::visit_field_ref (model_field_ref *elt,
1989 const ref_expression &expr,
1990 model_field *field)
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;
1997 if (expr)
1999 expr->visit (this);
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
2004 // 'foo'.
2005 if (should_inline && ! field->static_p ())
2006 expr_tree = gcc_builtins->check_reference (expr_tree, true);
2009 if (should_inline)
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));
2015 init->visit (this);
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.
2023 else
2025 // FIXME: Note that map_field_ref does not handle the case of a
2026 // non-static reference to a static field.
2028 #if 0
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 ());
2033 #endif
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);
2042 void
2043 tree_generator::visit_field_initializer (model_field_initializer *elt,
2044 model_field *field)
2046 if ((field->static_p () && field->constant_p ())
2047 || ! field->has_initializer_p ())
2049 // Ignore constant fields.
2050 return;
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,
2056 field);
2058 field->get_initializer ()->visit (this);
2059 current = build2 (MODIFY_EXPR, TREE_TYPE (field_tree), field_tree, current);
2060 annotate (current, elt);
2063 tree
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)),
2070 NULL_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),
2078 call);
2079 TREE_SIDE_EFFECTS (result) = 1;
2081 return result;
2084 void
2085 tree_generator::visit_instanceof (model_instanceof *stmt,
2086 const ref_expression &expr,
2087 const ref_forwarding_type &klass)
2089 expr->visit (this);
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);
2096 void
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);
2104 void
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);
2112 void
2113 tree_generator::visit_simple_literal (model_literal_base *,
2114 const jboolean &val)
2116 current = val ? boolean_true_node : boolean_false_node;
2119 void
2120 tree_generator::visit_simple_literal (model_literal_base *, const jbyte &val)
2122 current = build_int (val, type_jbyte);
2125 void
2126 tree_generator::visit_simple_literal (model_literal_base *, const jchar &val)
2128 current = build_int (val, type_jchar);
2131 void
2132 tree_generator::visit_simple_literal (model_literal_base *, const jshort &val)
2134 current = build_int (val, type_jshort);
2137 void
2138 tree_generator::visit_simple_literal (model_literal_base *, const jint &val)
2140 current = build_int (val);
2143 void
2144 tree_generator::visit_simple_literal (model_literal_base *, const jlong &val)
2146 current = build_long (val);
2149 tree
2150 tree_generator::handle_float (jfloat val)
2152 jint w = float_to_word (val);
2153 long wl = w;
2154 REAL_VALUE_TYPE f;
2155 real_from_target_fmt (&f, &wl, &ieee_single_format);
2156 return build_real (type_jfloat, f);
2159 void
2160 tree_generator::visit_simple_literal (model_literal_base *, const jfloat &val)
2162 current = handle_float (val);
2165 tree
2166 tree_generator::handle_double (jdouble val)
2168 jint w[2];
2169 double_to_words (w, val);
2170 long wl[2];
2171 #ifdef WORDS_BIGENDIAN
2172 wl[0] = w[0];
2173 wl[1] = w[1];
2174 #else
2175 wl[0] = w[1];
2176 wl[1] = w[0];
2177 #endif // WORDS_BIGENDIAN
2178 REAL_VALUE_TYPE d;
2179 real_from_target_fmt (&d, wl, &ieee_double_format);
2180 return build_real (type_jdouble, d);
2183 void
2184 tree_generator::visit_simple_literal (model_literal_base *, const jdouble &val)
2186 current = handle_double (val);
2189 tree
2190 tree_generator::handle_string_literal (const std::string &val)
2192 int location = class_wrapper->add (val);
2193 tree type
2194 = gcc_builtins->map_type (global->get_compiler ()->java_lang_String ());
2195 return build_ref_from_constant_pool (type, location);
2198 void
2199 tree_generator::visit_string_literal (model_string_literal *,
2200 const std::string &val)
2202 current = handle_string_literal (val);
2205 void
2206 tree_generator::handle_invocation (const model_method *meth,
2207 tree this_expr_tree,
2208 const std::list<ref_expression> &args,
2209 bool is_super)
2211 tree compound;
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.
2216 #if 0
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);
2222 #endif
2224 current = gcc_builtins->map_method_call (class_wrapper,
2225 this_expr_tree, arg_tree,
2226 const_cast<model_method *> (meth),
2227 is_super);
2228 if (compound != NULL_TREE)
2229 current = build2 (COMPOUND_EXPR, TREE_TYPE (current), compound, current);
2232 void
2233 tree_generator::visit_method_invocation (model_method_invocation *elt,
2234 model_method *meth,
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;
2240 if (this_expr)
2242 this_expr->visit (this);
2243 if (! meth->static_p ())
2244 expr_tree = current;
2245 else
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;
2261 void
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,
2266 bool super)
2268 handle_invocation (meth, meth->static_p () ? NULL_TREE : this_tree, args,
2269 super);
2270 annotate (current, elt);
2273 void
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);
2282 if (finit)
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);
2292 void
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);
2301 void
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)
2307 tree compound;
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);
2313 current
2314 = gcc_builtins->map_new (class_wrapper, klassp,
2315 const_cast<model_method *> (constructor),
2316 arg_tree);
2317 if (compound != NULL_TREE)
2318 current = build2 (COMPOUND_EXPR, TREE_TYPE (current), compound, current);
2320 annotate (current, elt);
2323 void
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 ();
2332 ind->visit (this);
2334 tree ind_tree = current;
2335 if (elt_type->type ()->primitive_p ())
2336 current = build_new_array (elt_type->type (), ind_tree, new_elt);
2337 else
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 ();
2344 tree compound;
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),
2350 args);
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,
2356 args, NULL_TREE));
2358 // This is to force evaluation order to be correct.
2359 if (compound != NULL_TREE)
2360 current = build2 (COMPOUND_EXPR, TREE_TYPE (current), compound,
2361 current);
2362 annotate (current, new_elt);
2364 else
2366 assert (init);
2367 init->visit (this);
2371 void
2372 tree_generator::visit_null_literal (model_null_literal *)
2374 current = null_pointer_node;
2377 void
2378 tree_generator::handle_inc_dec (model_element *element, tree_code op,
2379 const ref_expression &expr)
2381 expr->visit (this);
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);
2390 void
2391 tree_generator::visit_prefix_side_effect (model_prefix_plusplus *elt,
2392 const ref_expression &expr)
2394 handle_inc_dec (elt, PREINCREMENT_EXPR, expr);
2397 void
2398 tree_generator::visit_prefix_side_effect (model_prefix_minusminus *elt,
2399 const ref_expression &expr)
2401 handle_inc_dec (elt, PREDECREMENT_EXPR, expr);
2404 void
2405 tree_generator::visit_prefix_simple (model_prefix_plus *,
2406 const ref_expression &expr)
2408 // Nothing special to do here.
2409 expr->visit (this);
2412 void
2413 tree_generator::visit_prefix_simple (model_prefix_minus *elt,
2414 const ref_expression &expr)
2416 expr->visit (this);
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);
2423 void
2424 tree_generator::visit_prefix_simple (model_bitwise_not *elt,
2425 const ref_expression &expr)
2427 expr->visit (this);
2428 tree hold = current;
2429 current = build1 (BIT_NOT_EXPR, gcc_builtins->map_type (expr->type ()),
2430 hold);
2431 TREE_SIDE_EFFECTS (current) = TREE_SIDE_EFFECTS (hold);
2432 annotate (current, elt);
2435 void
2436 tree_generator::visit_prefix_simple (model_logical_not *elt,
2437 const ref_expression &expr)
2439 expr->visit (this);
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);
2446 void
2447 tree_generator::visit_postfix_side_effect (model_postfix_plusplus *elt,
2448 const ref_expression &expr)
2450 handle_inc_dec (elt, POSTINCREMENT_EXPR, expr);
2453 void
2454 tree_generator::visit_postfix_side_effect (model_postfix_minusminus *elt,
2455 const ref_expression &expr)
2457 handle_inc_dec (elt, POSTDECREMENT_EXPR, expr);
2460 void
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 ();
2469 tree expr_tree;
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
2477 // an outer "this".
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);
2482 prev = iter;
2483 iter = iter->get_lexically_enclosing_class ();
2485 else
2486 expr_tree = this_tree;
2488 for (;
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,
2497 th0.get ());
2499 prev = iter;
2502 current = expr_tree;
2503 // Note: can't annotate here as we have a DECL, not an expression.
2506 void
2507 tree_generator::visit_simple_variable_ref (model_simple_variable_ref *elt,
2508 const model_variable_decl *decl)
2510 current
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.
2517 tree
2518 tree_generator::build_int (jint val, tree override)
2520 return build_int_cst (override ? override : type_jint, val);
2523 tree
2524 tree_generator::build_long (jlong val)
2526 unsigned HOST_WIDE_INT low;
2527 HOST_WIDE_INT high;
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),
2533 0, &low, &high);
2534 tree value = build_int_cst_wide (type_jlong, low, high);
2537 tree
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)),
2551 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;
2558 return insn;
2561 tree
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,
2572 NULL_TREE)));
2574 tree insn = build3 (CALL_EXPR, array_type_tree, builtin_Jv_NewObjectArray,
2575 args, NULL_TREE);
2576 TREE_SIDE_EFFECTS (insn) = 1;
2578 return insn;
2581 tree
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.
2593 tree
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);
2603 return obj;
2606 // FIXME: this is (sort of) duplicated in bytecode_generator.
2607 model_field *
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)
2618 return field;
2620 throw request->error ("couldn't find field %1 of type %2 in class %3")
2621 % name % type % klass;
2624 tree
2625 tree_generator::build_class_ref (model_type *t, model_element *request)
2627 tree result;
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
2634 // primitive class?
2635 model_field *field
2636 = find_field ("TYPE", wrapper,
2637 global->get_compiler ()->java_lang_Class (),
2638 request);
2639 result = gcc_builtins->map_field_ref (class_wrapper, NULL_TREE,
2640 field);
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));
2650 else
2652 gcj_abi *abi = gcc_builtins->find_abi ();
2653 result = abi->build_class_reference (gcc_builtins, class_wrapper,
2654 assert_cast<model_class *> (t));
2656 return result;
2659 tree
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);
2666 tree
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)
2671 opcode = RDIV_EXPR;
2672 else
2674 if (flag_use_divide_subroutine)
2676 tree func;
2677 if (result_type == type_jlong)
2678 func = builtin_Jv_divJ;
2679 else
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)),
2684 NULL_TREE);
2686 opcode = TRUNC_DIV_EXPR;
2689 return build2 (opcode, result_type, lhs, rhs);
2692 tree
2693 tree_generator::build_mod (tree result_type, tree lhs, tree rhs)
2695 tree func;
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]);
2700 else
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;
2707 else
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)),
2714 NULL_TREE);
2717 tree
2718 tree_generator::build_array_reference (tree array, tree index,
2719 tree result_type,
2720 bool use_checks,
2721 tree rhs)
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);
2731 tree result
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),
2737 index,
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
2744 // check first.
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)),
2751 NULL_TREE);
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),
2769 field, NULL_TREE);
2770 tree call = build3 (CALL_EXPR, void_type_node,
2771 builtin_Jv_ThrowBadArrayIndex,
2772 build_tree_list (NULL_TREE, index),
2773 NULL_TREE);
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)),
2779 call,
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),
2789 array, index),
2790 result);
2792 return result;
2795 tree
2796 tree_generator::build_arguments (const std::list<ref_expression> &args,
2797 tree &compound)
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 ();
2804 i != args.end ();
2805 ++i)
2807 (*i)->visit (this);
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)
2821 compound = saved;
2822 else
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);
2829 return arg_tree;