1 /* GCC back-end for ortho
2 Copyright (C) 2002-1014 Tristan Gingold and al.
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <gnu.org/licenses>.
16 */
17
18 #include "config.h"
19 #include "system.h"
20 #include "coretypes.h"
21 #include "tm.h"
22 #include "hash-set.h"
23 #include "machmode.h"
24 #include "vec.h"
25 #include "double-int.h"
26 #include "input.h"
27 #include "alias.h"
28 #include "symtab.h"
29 #include "wide-int.h"
30 #include "inchash.h"
31 #include "real.h"
32 #include "tree.h"
33
34 #include "bitmap.h"
35 #include "hash-map.h"
36 #include "is-a.h"
37 #include "plugin-api.h"
38 #include "hard-reg-set.h"
39 #include "input.h"
40 #include "function.h"
41 #include "ipa-ref.h"
42 #include "cgraph.h"
43
44 #include "fold-const.h"
45
46 #include <stddef.h>
47 #include <math.h>
48
49 #include "tm_p.h"
50 #include "defaults.h"
51 #include "ggc.h"
52 #include "diagnostic.h"
53 #include "langhooks.h"
54 #include "langhooks-def.h"
55 #include "toplev.h"
56 #include "opts.h"
57 #include "options.h"
58 #include "tree-iterator.h"
59 #include "target.h"
60 #include "convert.h"
61 #include "tree-pass.h"
62 #include "tree-dump.h"
63
64 #include "print-tree.h"
65 #include "stringpool.h"
66 #include "stor-layout.h"
67 #include "varasm.h"
68
69 /* Returns the number of FIELD_DECLs in TYPE.
70 Copied here from expr.c in gcc4.9 as it is no longer exported by tree.h. */
71
72 static int
fields_length(const_tree type)73 fields_length (const_tree type)
74 {
75 tree t = TYPE_FIELDS (type);
76 int count = 0;
77
78 for (; t; t = DECL_CHAIN (t))
79 if (TREE_CODE (t) == FIELD_DECL)
80 ++count;
81
82 return count;
83 }
84
85 /* TODO:
86 * remove stmt_list_stack, save in if/case/loop block
87 * Re-add -v (if necessary)
88 */
89
90 static tree type_for_size (unsigned int precision, int unsignedp);
91
92 const int tree_identifier_size = sizeof (struct tree_identifier);
93
94 struct GTY(()) binding_level
95 {
96 /* The BIND_EXPR node for this binding. */
97 tree bind;
98
99 /* The BLOCK node for this binding. */
100 tree block;
101
102 /* If true, stack must be saved (alloca is used). */
103 int save_stack;
104
105 /* Parent binding level. */
106 struct binding_level *prev;
107
108 /* Decls in this binding. */
109 tree first_decl;
110 tree last_decl;
111
112 /* Blocks in this binding. */
113 tree first_block;
114 tree last_block;
115
116 /* Statements list containing the binding. */
117 tree prev_stmts;
118 };
119
120 /* The current binding level. */
121 static GTY(()) struct binding_level *cur_binding_level = NULL;
122
123 /* Chain of unused binding levels. */
124 static GTY(()) struct binding_level *old_binding_levels = NULL;
125
126 /* Chain of statements currently generated. */
127 static GTY(()) tree cur_stmts = NULL_TREE;
128
129 enum binding_kind { GLOBAL_BINDING, FUNCTION_BINDING, LOCAL_BINDING };
130
131 static void
push_binding(enum binding_kind kind)132 push_binding (enum binding_kind kind)
133 {
134 struct binding_level *res;
135
136 /* Get a binding level (old ones are recycled). */
137 if (old_binding_levels == NULL)
138 res = ggc_alloc<binding_level> ();
139 else
140 {
141 res = old_binding_levels;
142 old_binding_levels = res->prev;
143 }
144
145 /* Init. */
146 res->first_decl = NULL_TREE;
147 res->last_decl = NULL_TREE;
148
149 res->first_block = NULL_TREE;
150 res->last_block = NULL_TREE;
151
152 res->save_stack = 0;
153
154 switch (kind)
155 {
156 case GLOBAL_BINDING:
157 res->bind = NULL_TREE;
158 res->block = NULL_TREE;
159 res->prev = NULL;
160 res->prev_stmts = NULL;
161 break;
162 case FUNCTION_BINDING:
163 case LOCAL_BINDING:
164 res->block = make_node (BLOCK);
165 TREE_USED (res->block) = true;
166 res->bind = build3 (BIND_EXPR, void_type_node,
167 NULL_TREE, NULL_TREE, res->block);
168 TREE_SIDE_EFFECTS (res->bind) = true;
169 res->prev_stmts = cur_stmts;
170 cur_stmts = alloc_stmt_list ();
171 break;
172 }
173
174 switch (kind)
175 {
176 case GLOBAL_BINDING:
177 /* No supercontext for the global binding. */
178 break;
179 case FUNCTION_BINDING:
180 /* No containing block. */
181 BLOCK_SUPERCONTEXT (res->block) = current_function_decl;
182 break;
183 case LOCAL_BINDING:
184 /* Append the block created. */
185 if (cur_binding_level->first_block == NULL)
186 cur_binding_level->first_block = res->block;
187 else
188 BLOCK_CHAIN (cur_binding_level->last_block) = res->block;
189 cur_binding_level->last_block = res->block;
190
191 BLOCK_SUPERCONTEXT (res->block) = cur_binding_level->block;
192 break;
193 }
194
195 /* Chain previous binding, set current binding. */
196 res->prev = cur_binding_level;
197 cur_binding_level = res;
198 }
199
200 static tree
pushdecl(tree decl)201 pushdecl (tree decl)
202 {
203 /* Set context (always a function or NULL if top-level). */
204 DECL_CONTEXT (decl) = current_function_decl;
205
206 /* Chain the declaration. */
207 if (cur_binding_level->first_decl == NULL)
208 cur_binding_level->first_decl = decl;
209 else
210 TREE_CHAIN (cur_binding_level->last_decl) = decl;
211 cur_binding_level->last_decl = decl;
212
213 return decl;
214 }
215
216 static tree
pop_binding(void)217 pop_binding (void)
218 {
219 tree res;
220 struct binding_level *cur;
221
222 cur = cur_binding_level;
223 res = cur->bind;
224
225 if (cur->save_stack)
226 {
227 tree tmp_var;
228 tree save;
229 tree save_call;
230 tree restore;
231 tree t;
232
233 /* Create an artificial var to save the stack pointer. */
234 tmp_var = build_decl (input_location, VAR_DECL, NULL, ptr_type_node);
235 DECL_ARTIFICIAL (tmp_var) = true;
236 DECL_IGNORED_P (tmp_var) = true;
237 TREE_USED (tmp_var) = true;
238 pushdecl (tmp_var);
239
240 /* Create the save stmt. */
241 save_call = build_call_expr
242 (builtin_decl_implicit (BUILT_IN_STACK_SAVE), 0);
243 save = build2 (MODIFY_EXPR, ptr_type_node, tmp_var, save_call);
244 TREE_SIDE_EFFECTS (save) = true;
245
246 /* Create the restore stmt. */
247 restore = build_call_expr
248 (builtin_decl_implicit (BUILT_IN_STACK_RESTORE), 1, tmp_var);
249
250 /* Build a try-finally block.
251 The statement list is the block of current statements. */
252 t = build2 (TRY_FINALLY_EXPR, void_type_node, cur_stmts, NULL_TREE);
253 TREE_SIDE_EFFECTS (t) = true;
254
255 /* The finally block is the restore stmt. */
256 append_to_statement_list (restore, &TREE_OPERAND (t, 1));
257
258 /* The body of the BIND_BLOCK is the save stmt, followed by the
259 try block. */
260 BIND_EXPR_BODY (res) = NULL_TREE;
261 append_to_statement_list (save, &BIND_EXPR_BODY (res));
262 append_to_statement_list (t, &BIND_EXPR_BODY (res));
263 }
264 else
265 {
266 /* The body of the BIND_BLOCK is the statement block. */
267 BIND_EXPR_BODY (res) = cur_stmts;
268 }
269 BIND_EXPR_VARS (res) = cur->first_decl;
270
271 BLOCK_SUBBLOCKS (cur->block) = cur->first_block;
272 BLOCK_VARS (cur->block) = cur->first_decl;
273
274 /* Set current statements list and current binding. */
275 cur_stmts = cur->prev_stmts;
276 cur_binding_level = cur->prev;
277
278 /* Put removed binding to the recycle list. */
279 cur->prev = old_binding_levels;
280 old_binding_levels = cur;
281
282 return res;
283 }
284
285 static void
append_stmt(tree stmt)286 append_stmt (tree stmt)
287 {
288 /* Set location (if not done). */
289 if (!EXPR_HAS_LOCATION (stmt))
290 SET_EXPR_LOCATION (stmt, input_location);
291
292 TREE_SIDE_EFFECTS (stmt) = true;
293 append_to_statement_list (stmt, &cur_stmts);
294 }
295
296 static GTY(()) tree stack_alloc_function_ptr;
297
298 static bool
global_bindings_p(void)299 global_bindings_p (void)
300 {
301 return cur_binding_level->prev == NULL;
302 }
303
304 /* Return a definition for a builtin function named NAME and whose data type
305 is TYPE. TYPE should be a function type with argument types.
306 FUNCTION_CODE tells later passes how to compile calls to this function.
307 See tree.h for its possible values. */
308 static void
define_builtin(const char * name,tree type,enum built_in_function code,const char * library_name,int attr)309 define_builtin (const char *name,
310 tree type,
311 enum built_in_function code,
312 const char *library_name,
313 int attr)
314 {
315 tree decl;
316
317 decl = add_builtin_function (name, type, code, BUILT_IN_NORMAL,
318 library_name, NULL_TREE);
319 set_call_expr_flags (decl, attr);
320
321 set_builtin_decl (code, decl, true);
322 }
323
324 static REAL_VALUE_TYPE fp_const_m_p5; /* -0.5 */
325
326 static bool
ortho_init(void)327 ortho_init (void)
328 {
329 tree n;
330
331 input_location = BUILTINS_LOCATION;
332
333 /* Create a global binding. Don't use push_binding, as neither a BLOCK nor
334 a BIND_EXPR are needed. */
335 push_binding (GLOBAL_BINDING);
336
337 build_common_tree_nodes (false);
338
339 n = build_decl (input_location,
340 TYPE_DECL, get_identifier ("int"), integer_type_node);
341 pushdecl (n);
342 n = build_decl (input_location,
343 TYPE_DECL, get_identifier ("char"), char_type_node);
344 pushdecl (n);
345
346 /* Create alloca builtin. */
347 {
348 tree args_type = tree_cons (NULL_TREE, size_type_node, void_list_node);
349 tree func_type = build_function_type (ptr_type_node, args_type);
350
351 define_builtin ("__builtin_alloca", func_type,
352 BUILT_IN_ALLOCA, NULL, 0);
353
354 stack_alloc_function_ptr = build1
355 (ADDR_EXPR,
356 build_pointer_type (func_type),
357 builtin_decl_implicit (BUILT_IN_ALLOCA));
358 }
359
360 {
361 tree ptr_ftype = build_function_type (ptr_type_node, NULL_TREE);
362
363 define_builtin ("__builtin_stack_save", ptr_ftype,
364 BUILT_IN_STACK_SAVE, NULL, 0);
365 }
366
367 {
368 tree ftype_ptr = build_function_type_list (void_type_node,
369 ptr_type_node, NULL_TREE);
370
371 define_builtin ("__builtin_stack_restore", ftype_ptr,
372 BUILT_IN_STACK_RESTORE, NULL, 0);
373 }
374
375 {
376 tree ftype_ptr = build_function_type_list (void_type_node, NULL_TREE);
377
378 define_builtin ("__builtin_trap", ftype_ptr,
379 BUILT_IN_TRAP, NULL, ECF_NOTHROW | ECF_LEAF);
380 TREE_THIS_VOLATILE (builtin_decl_explicit (BUILT_IN_TRAP)) = 1;
381 }
382
383 fp_const_m_p5 = real_value_negate (&dconsthalf);
384
385 build_common_builtin_nodes ();
386 // FIXME: this MAY remove the need for creating the builtins above...
387 // Evaluate tree.c / build_common_builtin_nodes (); for each in turn.
388
389 return true;
390 }
391
392 static void
ortho_finish(void)393 ortho_finish (void)
394 {
395 }
396
397 static unsigned int
ortho_option_lang_mask(void)398 ortho_option_lang_mask (void)
399 {
400 return CL_vhdl;
401 }
402
403 static bool
ortho_post_options(const char ** pfilename)404 ortho_post_options (const char **pfilename)
405 {
406 if (*pfilename == NULL || strcmp (*pfilename, "-") == 0)
407 *pfilename = "*stdin*";
408
409 /* Default hook. */
410 lhd_post_options (pfilename);
411
412 /* Run the back-end. */
413 return false;
414 }
415
416 extern "C" int lang_handle_option (const char *opt, const char *arg);
417
418 static bool
ortho_handle_option(size_t code,const char * arg,HOST_WIDE_INT value ATTRIBUTE_UNUSED,int kind ATTRIBUTE_UNUSED,location_t loc ATTRIBUTE_UNUSED,const struct cl_option_handlers * handlers ATTRIBUTE_UNUSED)419 ortho_handle_option (size_t code, const char *arg,
420 HOST_WIDE_INT value ATTRIBUTE_UNUSED,
421 int kind ATTRIBUTE_UNUSED,
422 location_t loc ATTRIBUTE_UNUSED,
423 const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
424 {
425 const char *opt;
426
427 opt = cl_options[code].opt_text;
428
429 switch (code)
430 {
431 case OPT__elab:
432 case OPT_l:
433 case OPT_c:
434 case OPT__anaelab:
435 /* Only a few options have a real arguments. */
436 return lang_handle_option (opt, arg) != 0;
437 default:
438 /* The other options must have a joint argument. */
439 if (arg != NULL)
440 {
441 size_t len1;
442 size_t len2;
443 char *nopt;
444
445 len1 = strlen (opt);
446 len2 = strlen (arg);
447 nopt = (char *) alloca (len1 + len2 + 1);
448 memcpy (nopt, opt, len1);
449 memcpy (nopt + len1, arg, len2);
450 nopt[len1 + len2] = 0;
451 opt = nopt;
452 }
453 return lang_handle_option (opt, NULL) != 0;
454 }
455 }
456
457 extern "C" int lang_parse_file (const char *filename);
458
459 static void
ortho_parse_file(void)460 ortho_parse_file (void)
461 {
462 const char *filename;
463 const char *dbg_filename;
464
465 if (num_in_fnames == 0)
466 filename = NULL;
467 else
468 filename = in_fnames[0];
469
470 /* Use absolute filenames for debug info. Works better than relative
471 filenames with some debuggers/tools. */
472 if (filename == NULL)
473 dbg_filename = "*stdin*";
474 else if (IS_ABSOLUTE_PATH (filename))
475 dbg_filename = filename;
476 else
477 dbg_filename = concat (getpwd (), "/", filename, NULL);
478
479 linemap_add (line_table, LC_ENTER, 0, dbg_filename, 1);
480 input_location = linemap_line_start (line_table, 1, 252);
481
482 if (!lang_parse_file (filename))
483 errorcount++;
484 linemap_add (line_table, LC_LEAVE, 0, NULL, 1);
485 }
486
487 /* Called by the back-end or by the front-end when the address of EXP
488 must be taken.
489 This function should found the base object (if any), and mark it as
490 addressable (via TREE_ADDRESSABLE). It may emit a warning if this
491 object cannot be addressable (front-end restriction).
492 Returns TRUE in case of success, FALSE in case of failure.
493 Note that the status is never checked by the back-end. */
494 static bool
ortho_mark_addressable(tree exp)495 ortho_mark_addressable (tree exp)
496 {
497 tree n;
498
499 n = exp;
500
501 while (1)
502 switch (TREE_CODE (n))
503 {
504 case VAR_DECL:
505 case CONST_DECL:
506 case PARM_DECL:
507 case RESULT_DECL:
508 TREE_ADDRESSABLE (n) = true;
509 return true;
510
511 case COMPONENT_REF:
512 case ARRAY_REF:
513 case ARRAY_RANGE_REF:
514 n = TREE_OPERAND (n, 0);
515 break;
516
517 case FUNCTION_DECL:
518 case CONSTRUCTOR:
519 TREE_ADDRESSABLE (n) = true;
520 return true;
521
522 case INDIRECT_REF:
523 return true;
524
525 default:
526 gcc_unreachable ();
527 }
528 }
529
530 static tree
ortho_truthvalue_conversion(tree expr)531 ortho_truthvalue_conversion (tree expr)
532 {
533 tree expr_type;
534 tree t;
535 tree f;
536
537 expr_type = TREE_TYPE (expr);
538 if (TREE_CODE (expr_type) != BOOLEAN_TYPE)
539 {
540 t = integer_one_node;
541 f = integer_zero_node;
542 }
543 else
544 {
545 f = TYPE_MIN_VALUE (expr_type);
546 t = TYPE_MAX_VALUE (expr_type);
547 }
548
549
550 switch (TREE_CODE (expr))
551 {
552 case EQ_EXPR:
553 case NE_EXPR:
554 case LE_EXPR:
555 case GE_EXPR:
556 case LT_EXPR:
557 case GT_EXPR:
558 case TRUTH_ANDIF_EXPR:
559 case TRUTH_ORIF_EXPR:
560 case TRUTH_AND_EXPR:
561 case TRUTH_OR_EXPR:
562 case ERROR_MARK:
563 return expr;
564
565 case INTEGER_CST:
566 /* Not 0 is true. */
567 return integer_zerop (expr) ? f : t;
568
569 case REAL_CST:
570 return real_zerop (expr) ? f : t;
571
572 default:
573 gcc_unreachable ();
574 }
575 }
576
577 /* Do not deal with alias set. In particular, it doesn't work well with
578 incomplete type, and universal pointers are not expressed in ortho. */
579
580 static alias_set_type
ortho_get_alias_set(tree)581 ortho_get_alias_set (tree)
582 {
583 return 0;
584 }
585
586 /* The following function has been copied and modified from c-convert.c. */
587
588 /* Change of width--truncation and extension of integers or reals--
589 is represented with NOP_EXPR. Proper functioning of many things
590 assumes that no other conversions can be NOP_EXPRs.
591
592 Conversion between integer and pointer is represented with CONVERT_EXPR.
593 Converting integer to real uses FLOAT_EXPR
594 and real to integer uses FIX_TRUNC_EXPR.
595
596 Here is a list of all the functions that assume that widening and
597 narrowing is always done with a NOP_EXPR:
598 In convert.c, convert_to_integer.
599 In c-typeck.c, build_binary_op (boolean ops), and
600 c_common_truthvalue_conversion.
601 In expr.c: expand_expr, for operands of a MULT_EXPR.
602 In fold-const.c: fold.
603 In tree.c: get_narrower and get_unwidened. */
604
605 /* Subroutines of `convert'. */
606
607
608
609 /* Create an expression whose value is that of EXPR,
610 converted to type TYPE. The TREE_TYPE of the value
611 is always TYPE. This function implements all reasonable
612 conversions; callers should filter out those that are
613 not permitted by the language being compiled. */
614
615 tree
convert(tree type,tree expr)616 convert (tree type, tree expr)
617 {
618 tree e = expr;
619 enum tree_code code = TREE_CODE (type);
620 const char *invalid_conv_diag;
621
622 if (type == error_mark_node
623 || expr == error_mark_node
624 || TREE_TYPE (expr) == error_mark_node)
625 return error_mark_node;
626
627 if ((invalid_conv_diag
628 = targetm.invalid_conversion (TREE_TYPE (expr), type)))
629 {
630 error (invalid_conv_diag);
631 return error_mark_node;
632 }
633
634 if (type == TREE_TYPE (expr))
635 return expr;
636
637 if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
638 return fold_build1 (NOP_EXPR, type, expr);
639 if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK)
640 return error_mark_node;
641 if (TREE_CODE (TREE_TYPE (expr)) == VOID_TYPE || code == VOID_TYPE)
642 {
643 gcc_unreachable ();
644 }
645 if (code == INTEGER_TYPE || code == ENUMERAL_TYPE)
646 return fold (convert_to_integer (type, e));
647 if (code == BOOLEAN_TYPE)
648 {
649 tree t = ortho_truthvalue_conversion (expr);
650 if (TREE_CODE (t) == ERROR_MARK)
651 return t;
652
653 /* If it returns a NOP_EXPR, we must fold it here to avoid
654 infinite recursion between fold () and convert (). */
655 if (TREE_CODE (t) == NOP_EXPR)
656 return fold_build1 (NOP_EXPR, type, TREE_OPERAND (t, 0));
657 else
658 return fold_build1 (NOP_EXPR, type, t);
659 }
660 if (code == POINTER_TYPE || code == REFERENCE_TYPE)
661 return fold (convert_to_pointer (type, e));
662 if (code == REAL_TYPE)
663 return fold (convert_to_real (type, e));
664
665 gcc_unreachable ();
666 }
667
668 #ifndef MAX_BITS_PER_WORD
669 #define MAX_BITS_PER_WORD BITS_PER_WORD
670 #endif
671
672 /* This variable keeps a table for types for each precision so that we only
673 allocate each of them once. Signed and unsigned types are kept separate.
674 */
675 static GTY(()) tree signed_and_unsigned_types[MAX_BITS_PER_WORD + 1][2];
676
677 /* Return an integer type with the number of bits of precision given by
678 PRECISION. UNSIGNEDP is nonzero if the type is unsigned; otherwise
679 it is a signed type. */
680 static tree
type_for_size(unsigned int precision,int unsignedp)681 type_for_size (unsigned int precision, int unsignedp)
682 {
683 tree t;
684
685 if (precision <= MAX_BITS_PER_WORD
686 && signed_and_unsigned_types[precision][unsignedp] != NULL_TREE)
687 return signed_and_unsigned_types[precision][unsignedp];
688
689 if (unsignedp)
690 t = make_unsigned_type (precision);
691 else
692 t = make_signed_type (precision);
693
694 if (precision <= MAX_BITS_PER_WORD)
695 signed_and_unsigned_types[precision][unsignedp] = t;
696
697 return t;
698 }
699
700 /* Return a data type that has machine mode MODE. UNSIGNEDP selects
701 an unsigned type; otherwise a signed type is returned. */
702 static tree
type_for_mode(enum machine_mode mode,int unsignedp)703 type_for_mode (enum machine_mode mode, int unsignedp)
704 {
705 scalar_int_mode int_mode;
706 if (is_a <scalar_int_mode> (mode, &int_mode))
707 return type_for_size (GET_MODE_BITSIZE (int_mode), unsignedp);
708
709 if (mode == TYPE_MODE (void_type_node))
710 return void_type_node;
711
712 if (mode == TYPE_MODE (float_type_node))
713 return float_type_node;
714
715 if (mode == TYPE_MODE (double_type_node))
716 return double_type_node;
717
718 if (mode == TYPE_MODE (long_double_type_node))
719 return long_double_type_node;
720
721 if (VECTOR_MODE_P (mode))
722 {
723 machine_mode inner_mode = GET_MODE_INNER (mode);
724 tree inner_type = type_for_mode (inner_mode, unsignedp);
725 if (inner_type)
726 return build_vector_type_for_mode (inner_type, mode);
727 }
728
729 return NULL_TREE;
730 }
731
732 #undef LANG_HOOKS_NAME
733 #define LANG_HOOKS_NAME "vhdl"
734 #undef LANG_HOOKS_IDENTIFIER_SIZE
735 #define LANG_HOOKS_IDENTIFIER_SIZE sizeof (struct tree_identifier)
736 #undef LANG_HOOKS_INIT
737 #define LANG_HOOKS_INIT ortho_init
738 #undef LANG_HOOKS_FINISH
739 #define LANG_HOOKS_FINISH ortho_finish
740 #undef LANG_HOOKS_OPTION_LANG_MASK
741 #define LANG_HOOKS_OPTION_LANG_MASK ortho_option_lang_mask
742 #undef LANG_HOOKS_HANDLE_OPTION
743 #define LANG_HOOKS_HANDLE_OPTION ortho_handle_option
744 #undef LANG_HOOKS_POST_OPTIONS
745 #define LANG_HOOKS_POST_OPTIONS ortho_post_options
746 #undef LANG_HOOKS_HONOR_READONLY
747 #define LANG_HOOKS_HONOR_READONLY true
748 #undef LANG_HOOKS_MARK_ADDRESSABLE
749 #define LANG_HOOKS_MARK_ADDRESSABLE ortho_mark_addressable
750 #undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
751 #define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION ortho_expand_function
752
753 #undef LANG_HOOKS_TYPE_FOR_MODE
754 #define LANG_HOOKS_TYPE_FOR_MODE type_for_mode
755 #undef LANG_HOOKS_TYPE_FOR_SIZE
756 #define LANG_HOOKS_TYPE_FOR_SIZE type_for_size
757 #undef LANG_HOOKS_PARSE_FILE
758 #define LANG_HOOKS_PARSE_FILE ortho_parse_file
759
760 #define pushlevel lhd_do_nothing_i
761 #define poplevel lhd_do_nothing_iii_return_null_tree
762 #define set_block lhd_do_nothing_t
763 #undef LANG_HOOKS_GETDECLS
764 #define LANG_HOOKS_GETDECLS hook_tree_void_null
765
766 #undef LANG_HOOKS_GET_ALIAS_SET
767 #define LANG_HOOKS_GET_ALIAS_SET ortho_get_alias_set
768
769 struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
770
771 union GTY((desc ("0"),
772 chain_next ("CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL")))
773 lang_tree_node
774 {
775 union tree_node GTY((tag ("0"),
776 desc ("tree_node_structure (&%h)"))) generic;
777 };
778
779 /* GHDL does not use the lang_decl and lang_type.
780
781 FIXME: the variable_size annotation here is needed because these types are
782 variable-sized in some other front-ends. Due to gengtype deficiency, the
783 GTY options of such types have to agree across all front-ends. */
784
785 struct GTY((variable_size)) lang_type { char dummy; };
786 struct GTY((variable_size)) lang_decl { char dummy; };
787
788 struct GTY(()) language_function
789 {
790 char dummy;
791 };
792
793
794 extern "C" {
795
796 struct GTY(()) chain_constr_type
797 {
798 tree first;
799 tree last;
800 };
801
802 static void
chain_init(struct chain_constr_type * constr)803 chain_init (struct chain_constr_type *constr)
804 {
805 constr->first = NULL_TREE;
806 constr->last = NULL_TREE;
807 }
808
809 static void
chain_append(struct chain_constr_type * constr,tree el)810 chain_append (struct chain_constr_type *constr, tree el)
811 {
812 if (constr->first == NULL_TREE)
813 {
814 gcc_assert (constr->last == NULL_TREE);
815 constr->first = el;
816 }
817 else
818 TREE_CHAIN (constr->last) = el;
819 constr->last = el;
820 }
821
822 struct GTY(()) list_constr_type
823 {
824 tree first;
825 tree last;
826 };
827
828 static void
list_init(struct list_constr_type * constr)829 list_init (struct list_constr_type *constr)
830 {
831 constr->first = NULL_TREE;
832 constr->last = NULL_TREE;
833 }
834
835 static void
ortho_list_append(struct list_constr_type * constr,tree el)836 ortho_list_append (struct list_constr_type *constr, tree el)
837 {
838 tree res;
839
840 res = tree_cons (NULL_TREE, el, NULL_TREE);
841 if (constr->first == NULL_TREE)
842 constr->first = res;
843 else
844 TREE_CHAIN (constr->last) = res;
845 constr->last = res;
846 }
847
848 enum ON_op_kind {
849 /* Not an operation; invalid. */
850 ON_Nil,
851
852 /* Dyadic operations. */
853 ON_Add_Ov,
854 ON_Sub_Ov,
855 ON_Mul_Ov,
856 ON_Div_Ov,
857 ON_Rem_Ov,
858 ON_Mod_Ov,
859
860 /* Binary operations. */
861 ON_And,
862 ON_Or,
863 ON_Xor,
864
865 /* Monadic operations. */
866 ON_Not,
867 ON_Neg_Ov,
868 ON_Abs_Ov,
869
870 /* Comparaisons */
871 ON_Eq,
872 ON_Neq,
873 ON_Le,
874 ON_Lt,
875 ON_Ge,
876 ON_Gt,
877
878 ON_LAST
879 };
880
881 static enum tree_code ON_op_to_TREE_CODE[ON_LAST] = {
882 ERROR_MARK,
883
884 PLUS_EXPR,
885 MINUS_EXPR,
886 MULT_EXPR,
887 ERROR_MARK,
888 TRUNC_MOD_EXPR,
889 FLOOR_MOD_EXPR,
890
891 BIT_AND_EXPR,
892 BIT_IOR_EXPR,
893 BIT_XOR_EXPR,
894
895 BIT_NOT_EXPR,
896 NEGATE_EXPR,
897 ABS_EXPR,
898
899 EQ_EXPR,
900 NE_EXPR,
901 LE_EXPR,
902 LT_EXPR,
903 GE_EXPR,
904 GT_EXPR,
905 };
906
907 tree
new_dyadic_op(enum ON_op_kind kind,tree left,tree right)908 new_dyadic_op (enum ON_op_kind kind, tree left, tree right)
909 {
910 tree left_type;
911 enum tree_code code;
912
913 /* Truncate to avoid representations issue. */
914 kind = (enum ON_op_kind)((unsigned)kind & 0xff);
915
916 left_type = TREE_TYPE (left);
917 gcc_assert (left_type == TREE_TYPE (right));
918
919 switch (kind)
920 {
921 case ON_Div_Ov:
922 if (TREE_CODE (left_type) == REAL_TYPE)
923 code = RDIV_EXPR;
924 else
925 code = TRUNC_DIV_EXPR;
926 break;
927 default:
928 code = ON_op_to_TREE_CODE[kind];
929 break;
930 }
931 return build2 (code, left_type, left, right);
932 }
933
934 tree
new_monadic_op(enum ON_op_kind kind,tree operand)935 new_monadic_op (enum ON_op_kind kind, tree operand)
936 {
937 /* Truncate to avoid representations issue. */
938 kind = (enum ON_op_kind)((unsigned)kind & 0xff);
939
940 return build1 (ON_op_to_TREE_CODE[kind], TREE_TYPE (operand), operand);
941 }
942
943 tree
new_compare_op(enum ON_op_kind kind,tree left,tree right,tree ntype)944 new_compare_op (enum ON_op_kind kind, tree left, tree right, tree ntype)
945 {
946 gcc_assert (TREE_CODE (ntype) == BOOLEAN_TYPE);
947 gcc_assert (TREE_TYPE (left) == TREE_TYPE (right));
948
949 /* Truncate to avoid representations issue. */
950 kind = (enum ON_op_kind)((unsigned)kind & 0xff);
951
952 return build2 (ON_op_to_TREE_CODE[kind], ntype, left, right);
953 }
954
955 tree
new_convert(tree val,tree rtype)956 new_convert (tree val, tree rtype)
957 {
958 tree val_type;
959 enum tree_code val_code;
960 enum tree_code rtype_code;
961 enum tree_code code;
962
963 val_type = TREE_TYPE (val);
964 if (val_type == rtype)
965 return val;
966
967 /* FIXME: check conversions. */
968 val_code = TREE_CODE (val_type);
969 rtype_code = TREE_CODE (rtype);
970 if (val_code == POINTER_TYPE && rtype_code == POINTER_TYPE)
971 code = NOP_EXPR;
972 else if (val_code == INTEGER_TYPE && rtype_code == INTEGER_TYPE)
973 code = CONVERT_EXPR;
974 else if (val_code == REAL_TYPE && rtype_code == INTEGER_TYPE)
975 {
976 /* REAL to INTEGER
977 Gcc only handles FIX_TRUNC_EXPR, but we need rounding. */
978 tree m_p5;
979 tree p5;
980 tree zero;
981 tree saved;
982 tree comp;
983 tree adj;
984 tree res;
985
986 m_p5 = build_real (val_type, fp_const_m_p5);
987 p5 = build_real (val_type, dconsthalf);
988 zero = build_real (val_type, dconst0);
989 saved = save_expr (val);
990 comp = build2 (GE_EXPR, integer_type_node, saved, zero);
991 /* FIXME: instead of res = res + (comp ? .5 : -.5)
992 do: res = res (comp ? + : -) .5 */
993 adj = build3 (COND_EXPR, val_type, comp, p5, m_p5);
994 res = build2 (PLUS_EXPR, val_type, saved, adj);
995 res = build1 (FIX_TRUNC_EXPR, rtype, res);
996 return res;
997 }
998 else if (val_code == INTEGER_TYPE && rtype_code == ENUMERAL_TYPE)
999 code = CONVERT_EXPR;
1000 else if (val_code == ENUMERAL_TYPE && rtype_code == INTEGER_TYPE)
1001 code = CONVERT_EXPR;
1002 else if (val_code == INTEGER_TYPE && rtype_code == REAL_TYPE)
1003 code = FLOAT_EXPR;
1004 else if (val_code == BOOLEAN_TYPE && rtype_code == BOOLEAN_TYPE)
1005 code = NOP_EXPR;
1006 else if (val_code == BOOLEAN_TYPE && rtype_code == INTEGER_TYPE)
1007 code = CONVERT_EXPR;
1008 else if (val_code == INTEGER_TYPE && rtype_code == BOOLEAN_TYPE)
1009 code = NOP_EXPR;
1010 else if (val_code == REAL_TYPE && rtype_code == REAL_TYPE)
1011 code = NOP_EXPR;
1012 else
1013 gcc_unreachable ();
1014
1015 return build1 (code, rtype, val);
1016 }
1017
1018 tree
new_convert_ov(tree val,tree rtype)1019 new_convert_ov (tree val, tree rtype)
1020 {
1021 return new_convert (val, rtype);
1022 }
1023
1024 tree
new_alloca(tree rtype,tree size)1025 new_alloca (tree rtype, tree size)
1026 {
1027 tree res;
1028
1029 /* Must save stack except when at function level. */
1030 if (cur_binding_level->prev != NULL
1031 && cur_binding_level->prev->prev != NULL)
1032 cur_binding_level->save_stack = 1;
1033
1034 res = build_call_nary (ptr_type_node, stack_alloc_function_ptr,
1035 1, fold_convert (size_type_node, size));
1036 return fold_convert (rtype, res);
1037 }
1038
1039 tree
new_signed_literal(tree ltype,long long value)1040 new_signed_literal (tree ltype, long long value)
1041 {
1042 tree res;
1043 HOST_WIDE_INT lo;
1044 HOST_WIDE_INT hi;
1045
1046 lo = value;
1047 hi = (value >> 1) >> (8 * sizeof (HOST_WIDE_INT) - 1);
1048 res = double_int_to_tree (ltype, double_int::from_pair (hi, lo));
1049 return res;
1050 }
1051
1052 tree
new_unsigned_literal(tree ltype,unsigned long long value)1053 new_unsigned_literal (tree ltype, unsigned long long value)
1054 {
1055 tree res;
1056 unsigned HOST_WIDE_INT lo;
1057 unsigned HOST_WIDE_INT hi;
1058
1059 lo = value;
1060 hi = (value >> 1) >> (8 * sizeof (HOST_WIDE_INT) - 1);
1061 res = double_int_to_tree (ltype, double_int::from_pair (hi, lo));
1062 return res;
1063 }
1064
1065 tree
new_null_access(tree ltype)1066 new_null_access (tree ltype)
1067 {
1068 tree res;
1069
1070 res = build_int_cst (ltype, 0);
1071 return res;
1072 }
1073
1074 tree
new_float_literal(tree ltype,double value)1075 new_float_literal (tree ltype, double value)
1076 {
1077 signed long long s;
1078 double frac;
1079 int ex;
1080 REAL_VALUE_TYPE r_sign;
1081 REAL_VALUE_TYPE r_exp;
1082 REAL_VALUE_TYPE r;
1083 tree res;
1084 HOST_WIDE_INT lo;
1085 HOST_WIDE_INT hi;
1086
1087 frac = frexp (value, &ex);
1088
1089 s = ldexp (frac, 60);
1090 lo = s;
1091 hi = (s >> 1) >> (8 * sizeof (HOST_WIDE_INT) - 1);
1092 real_from_integer (&r_sign, DFmode, double_int::from_pair (hi, lo), SIGNED);
1093 real_2expN (&r_exp, ex - 60, DFmode);
1094 real_arithmetic (&r, MULT_EXPR, &r_sign, &r_exp);
1095 res = build_real (ltype, r);
1096 return res;
1097 }
1098
1099 struct GTY(()) o_element_list
1100 {
1101 tree res;
1102 struct chain_constr_type chain;
1103 };
1104
1105 struct GTY(()) o_element_sublist
1106 {
1107 tree base;
1108 tree field;
1109 tree res;
1110 struct chain_constr_type chain;
1111 };
1112
1113 void
new_uncomplete_record_type(tree * res)1114 new_uncomplete_record_type (tree *res)
1115 {
1116 *res = make_node (RECORD_TYPE);
1117 }
1118
1119 void
start_record_type(struct o_element_list * elements)1120 start_record_type (struct o_element_list *elements)
1121 {
1122 elements->res = make_node (RECORD_TYPE);
1123 chain_init (&elements->chain);
1124 }
1125
1126 void
start_uncomplete_record_type(tree res,struct o_element_list * elements)1127 start_uncomplete_record_type (tree res, struct o_element_list *elements)
1128 {
1129 elements->res = res;
1130 chain_init (&elements->chain);
1131 }
1132
1133 static void
new_record_union_field(struct o_element_list * list,tree * el,tree ident,tree etype)1134 new_record_union_field (struct o_element_list *list,
1135 tree *el,
1136 tree ident,
1137 tree etype)
1138 {
1139 tree res;
1140
1141 res = build_decl (input_location, FIELD_DECL, ident, etype);
1142 DECL_CONTEXT (res) = list->res;
1143 chain_append (&list->chain, res);
1144 *el = res;
1145 }
1146
1147 void
new_record_field(struct o_element_list * list,tree * el,tree ident,tree etype)1148 new_record_field (struct o_element_list *list,
1149 tree *el,
1150 tree ident,
1151 tree etype)
1152 {
1153 return new_record_union_field (list, el, ident, etype);
1154 }
1155
1156 void
finish_record_type(struct o_element_list * elements,tree * res)1157 finish_record_type (struct o_element_list *elements, tree *res)
1158 {
1159 TYPE_FIELDS (elements->res) = elements->chain.first;
1160 layout_type (elements->res);
1161 *res = elements->res;
1162
1163 if (TYPE_NAME (elements->res) != NULL_TREE)
1164 {
1165 /* The type was completed. */
1166 rest_of_type_compilation (elements->res, 1);
1167 }
1168 }
1169
1170 void
start_record_subtype(tree rtype,struct o_element_sublist * elements)1171 start_record_subtype (tree rtype, struct o_element_sublist *elements)
1172 {
1173 elements->base = rtype;
1174 elements->field = TYPE_FIELDS (rtype);
1175 elements->res = make_node (RECORD_TYPE);
1176 chain_init (&elements->chain);
1177 }
1178
1179 void
new_subrecord_field(struct o_element_sublist * list,tree * el,tree etype)1180 new_subrecord_field (struct o_element_sublist *list,
1181 tree *el,
1182 tree etype)
1183 {
1184 tree res;
1185
1186 res = build_decl (input_location, FIELD_DECL, DECL_NAME(list->field), etype);
1187 DECL_CONTEXT (res) = list->res;
1188 chain_append (&list->chain, res);
1189 list->field = TREE_CHAIN(list->field);
1190 *el = res;
1191 }
1192
1193 void
finish_record_subtype(struct o_element_sublist * elements,tree * res)1194 finish_record_subtype (struct o_element_sublist *elements, tree *res)
1195 {
1196 TYPE_FIELDS (elements->res) = elements->chain.first;
1197 layout_type (elements->res);
1198 *res = elements->res;
1199 }
1200
1201 void
start_union_type(struct o_element_list * elements)1202 start_union_type (struct o_element_list *elements)
1203 {
1204 elements->res = make_node (UNION_TYPE);
1205 chain_init (&elements->chain);
1206 }
1207
1208 void
new_union_field(struct o_element_list * elements,tree * el,tree ident,tree etype)1209 new_union_field (struct o_element_list *elements,
1210 tree *el,
1211 tree ident,
1212 tree etype)
1213 {
1214 return new_record_union_field (elements, el, ident, etype);
1215 }
1216
1217 void
finish_union_type(struct o_element_list * elements,tree * res)1218 finish_union_type (struct o_element_list *elements, tree *res)
1219 {
1220 TYPE_FIELDS (elements->res) = elements->chain.first;
1221 layout_type (elements->res);
1222 *res = elements->res;
1223 }
1224
1225 tree
new_unsigned_type(int size)1226 new_unsigned_type (int size)
1227 {
1228 return make_unsigned_type (size);
1229 }
1230
1231 tree
new_signed_type(int size)1232 new_signed_type (int size)
1233 {
1234 return make_signed_type (size);
1235 }
1236
1237 tree
new_float_type(void)1238 new_float_type (void)
1239 {
1240 tree res;
1241
1242 res = make_node (REAL_TYPE);
1243 TYPE_PRECISION (res) = DOUBLE_TYPE_SIZE;
1244 layout_type (res);
1245 return res;
1246 }
1247
1248 tree
new_access_type(tree dtype)1249 new_access_type (tree dtype)
1250 {
1251 tree res;
1252
1253 if (dtype == NULL_TREE)
1254 {
1255 res = make_node (POINTER_TYPE);
1256 TREE_TYPE (res) = NULL_TREE;
1257 /* Seems necessary. */
1258 SET_TYPE_MODE (res, Pmode);
1259 layout_type (res);
1260 return res;
1261 }
1262 else
1263 return build_pointer_type (dtype);
1264 }
1265
1266 void
finish_access_type(tree atype,tree dtype)1267 finish_access_type (tree atype, tree dtype)
1268 {
1269 gcc_assert (TREE_CODE (atype) == POINTER_TYPE
1270 && TREE_TYPE (atype) == NULL_TREE);
1271
1272 TREE_TYPE (atype) = dtype;
1273 }
1274
1275 /* Create a range type from INDEX_TYPE of length LENGTH. */
1276 static tree
ortho_build_array_range(tree index_type,tree length)1277 ortho_build_array_range(tree index_type, tree length)
1278 {
1279 tree len;
1280
1281 if (integer_zerop (length))
1282 {
1283 /* Handle null array, by creating a one-length array... */
1284 len = size_zero_node;
1285 }
1286 else
1287 {
1288 len = fold_build2 (MINUS_EXPR, index_type,
1289 convert (index_type, length),
1290 convert (index_type, size_one_node));
1291 }
1292 return build_range_type (index_type, size_zero_node, len);
1293 }
1294
1295 tree
new_array_type(tree el_type,tree index_type)1296 new_array_type (tree el_type, tree index_type)
1297 {
1298 /* Incomplete array. */
1299 tree range_type;
1300 tree res;
1301
1302 /* Build an incomplete array. */
1303 range_type = build_range_type (index_type, size_zero_node, NULL_TREE);
1304 res = build_array_type (el_type, range_type);
1305 return res;
1306 }
1307
1308 tree
new_array_subtype(tree atype,tree eltype,tree length)1309 new_array_subtype (tree atype, tree eltype, tree length)
1310 {
1311 tree range_type;
1312 tree index_type;
1313 tree res;
1314
1315 index_type = TYPE_DOMAIN (atype);
1316
1317 range_type = ortho_build_array_range(index_type, length);
1318 res = build_array_type (eltype, range_type);
1319
1320 /* Constrained arrays are *always* a subtype of its array type.
1321 Just copy alias set. */
1322 TYPE_ALIAS_SET (res) = get_alias_set (atype);
1323
1324 return res;
1325 }
1326
1327 void
new_boolean_type(tree * res,tree false_id ATTRIBUTE_UNUSED,tree * false_e,tree true_id ATTRIBUTE_UNUSED,tree * true_e)1328 new_boolean_type (tree *res,
1329 tree false_id ATTRIBUTE_UNUSED, tree *false_e,
1330 tree true_id ATTRIBUTE_UNUSED, tree *true_e)
1331 {
1332 *res = make_node (BOOLEAN_TYPE);
1333 TYPE_PRECISION (*res) = 1;
1334 fixup_unsigned_type (*res);
1335 *false_e = TYPE_MIN_VALUE (*res);
1336 *true_e = TYPE_MAX_VALUE (*res);
1337 }
1338
1339 struct o_enum_list
1340 {
1341 tree res;
1342 struct chain_constr_type chain;
1343 int num;
1344 int size;
1345 };
1346
1347 void
start_enum_type(struct o_enum_list * list,int size)1348 start_enum_type (struct o_enum_list *list, int size)
1349 {
1350 list->res = make_node (ENUMERAL_TYPE);
1351 /* Set precision and sign now, as this is used to normalize literals. */
1352 TYPE_PRECISION (list->res) = size;
1353 TYPE_UNSIGNED (list->res) = 1;
1354 chain_init (&list->chain);
1355 list->num = 0;
1356 list->size = size;
1357 }
1358
1359 void
new_enum_literal(struct o_enum_list * list,tree ident,tree * res)1360 new_enum_literal (struct o_enum_list *list, tree ident, tree *res)
1361 {
1362 *res = build_int_cstu (list->res, (HOST_WIDE_INT)(list->num));
1363 chain_append (&list->chain, tree_cons (ident, *res, NULL_TREE));
1364 list->num++;
1365 }
1366
1367 void
finish_enum_type(struct o_enum_list * list,tree * res)1368 finish_enum_type (struct o_enum_list *list, tree *res)
1369 {
1370 *res = list->res;
1371 TYPE_VALUES (*res) = list->chain.first;
1372 set_min_and_max_values_for_integral_type (*res, list->size, UNSIGNED);
1373 layout_type (*res);
1374 }
1375
1376 struct GTY(()) o_record_aggr_list
1377 {
1378 /* Type of the record. */
1379 tree atype;
1380 /* Type of the next field to be added. */
1381 tree field;
1382 /* Vector of elements. */
1383 // VEC(constructor_elt,gc) *elts;
1384 vec<constructor_elt,va_gc> *elts;
1385 };
1386
1387 void
start_record_aggr(struct o_record_aggr_list * list,tree atype)1388 start_record_aggr (struct o_record_aggr_list *list, tree atype)
1389 {
1390 list->atype = atype;
1391 list->field = TYPE_FIELDS (atype);
1392 //list->elts = VEC_alloc (constructor_elt, gc, fields_length (atype));
1393 vec_alloc(list->elts, fields_length (atype));
1394 }
1395
1396 void
new_record_aggr_el(struct o_record_aggr_list * list,tree value)1397 new_record_aggr_el (struct o_record_aggr_list *list, tree value)
1398 {
1399 CONSTRUCTOR_APPEND_ELT (list->elts, list->field, value);
1400 list->field = TREE_CHAIN (list->field);
1401 }
1402
1403 void
finish_record_aggr(struct o_record_aggr_list * list,tree * res)1404 finish_record_aggr (struct o_record_aggr_list *list, tree *res)
1405 {
1406 *res = build_constructor (list->atype, list->elts);
1407 }
1408
1409 struct GTY(()) o_array_aggr_list
1410 {
1411 tree atype;
1412 /* Vector of elements. */
1413 vec<constructor_elt,va_gc> *elts;
1414 };
1415
1416 void
start_array_aggr(struct o_array_aggr_list * list,tree atype,unsigned len)1417 start_array_aggr (struct o_array_aggr_list *list, tree atype, unsigned len)
1418 {
1419 tree length;
1420
1421 length = new_unsigned_literal (sizetype, len);
1422 list->atype = new_array_subtype (atype, TREE_TYPE (atype), length);
1423 vec_alloc(list->elts, len);
1424 }
1425
1426 void
new_array_aggr_el(struct o_array_aggr_list * list,tree value)1427 new_array_aggr_el (struct o_array_aggr_list *list, tree value)
1428 {
1429 CONSTRUCTOR_APPEND_ELT (list->elts, NULL_TREE, value);
1430 }
1431
1432 void
finish_array_aggr(struct o_array_aggr_list * list,tree * res)1433 finish_array_aggr (struct o_array_aggr_list *list, tree *res)
1434 {
1435 *res = build_constructor (list->atype, list->elts);
1436 }
1437
1438 tree
new_union_aggr(tree atype,tree field,tree value)1439 new_union_aggr (tree atype, tree field, tree value)
1440 {
1441 tree res;
1442
1443 res = build_constructor_single (atype, field, value);
1444 TREE_CONSTANT (res) = 1;
1445 return res;
1446 }
1447
1448 tree
new_default_value(tree atype)1449 new_default_value (tree atype)
1450 {
1451 return build_constructor (atype, NULL);
1452 }
1453
1454 tree
new_indexed_element(tree arr,tree index)1455 new_indexed_element (tree arr, tree index)
1456 {
1457 ortho_mark_addressable (arr);
1458 return build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (arr)),
1459 arr, index, NULL_TREE, NULL_TREE);
1460 }
1461
1462 tree
new_slice(tree arr,tree res_type,tree index)1463 new_slice (tree arr, tree res_type, tree index)
1464 {
1465 gcc_assert (TREE_CODE (res_type) == ARRAY_TYPE);
1466
1467 /* gcc needs a complete array type, so create the biggest one if it is
1468 not. */
1469 if (TYPE_MAX_VALUE (TYPE_DOMAIN (res_type)) == NULL_TREE)
1470 {
1471 res_type = build_array_type (TREE_TYPE (res_type),
1472 TREE_TYPE (TYPE_DOMAIN (res_type)));
1473 }
1474
1475 ortho_mark_addressable (arr);
1476 return build4 (ARRAY_RANGE_REF, res_type, arr, index, NULL_TREE, NULL_TREE);
1477 }
1478
1479 tree
new_selected_element(tree rec,tree el)1480 new_selected_element (tree rec, tree el)
1481 {
1482 tree res;
1483
1484 gcc_assert (RECORD_OR_UNION_TYPE_P (TREE_TYPE (rec)));
1485
1486 res = build3 (COMPONENT_REF, TREE_TYPE (el), rec, el, NULL_TREE);
1487 return res;
1488 }
1489
1490 tree
new_access_element(tree acc)1491 new_access_element (tree acc)
1492 {
1493 tree acc_type;
1494
1495 acc_type = TREE_TYPE (acc);
1496 gcc_assert (TREE_CODE (acc_type) == POINTER_TYPE);
1497
1498 return build1 (INDIRECT_REF, TREE_TYPE (acc_type), acc);
1499 }
1500
1501 tree
new_offsetof(tree rec_type,tree field,tree rtype)1502 new_offsetof (tree rec_type, tree field, tree rtype)
1503 {
1504 tree off;
1505 tree bit_off;
1506 HOST_WIDE_INT pos;
1507 tree res;
1508
1509 gcc_assert (DECL_CONTEXT (field) == rec_type);
1510
1511 off = DECL_FIELD_OFFSET (field);
1512
1513 /* The offset must be a constant. */
1514 gcc_assert (tree_fits_uhwi_p (off));
1515
1516 bit_off = DECL_FIELD_BIT_OFFSET (field);
1517
1518 /* The offset must be a constant. */
1519 gcc_assert (tree_fits_uhwi_p (bit_off));
1520
1521 pos = TREE_INT_CST_LOW (off)
1522 + (TREE_INT_CST_LOW (bit_off) / BITS_PER_UNIT);
1523 res = build_int_cstu (rtype, pos);
1524 return res;
1525 }
1526
1527 tree
new_sizeof(tree atype,tree rtype)1528 new_sizeof (tree atype, tree rtype)
1529 {
1530 tree size;
1531
1532 size = TYPE_SIZE_UNIT (atype);
1533
1534 return fold (build1 (NOP_EXPR, rtype, size));
1535 }
1536
1537 tree
new_record_sizeof(tree atype,tree rtype)1538 new_record_sizeof (tree atype, tree rtype)
1539 {
1540 return new_sizeof (atype, rtype);
1541 }
1542
1543 tree
new_alignof(tree atype,tree rtype)1544 new_alignof (tree atype, tree rtype)
1545 {
1546 return build_int_cstu (rtype, TYPE_ALIGN_UNIT (atype));
1547 }
1548
1549 static tree
ortho_build_addr(tree lvalue,tree atype)1550 ortho_build_addr (tree lvalue, tree atype)
1551 {
1552 tree res;
1553
1554 if (TREE_CODE (lvalue) == INDIRECT_REF)
1555 {
1556 /* ADDR_REF(INDIRECT_REF(x)) -> x. */
1557 res = TREE_OPERAND (lvalue, 0);
1558 }
1559 else
1560 {
1561 tree ptr_type;
1562
1563 /* &base[off] -> base+off. */
1564 ortho_mark_addressable (lvalue);
1565
1566 if (TREE_TYPE (lvalue) != TREE_TYPE (atype))
1567 ptr_type = build_pointer_type (TREE_TYPE (lvalue));
1568 else
1569 ptr_type = atype;
1570 res = fold_build1 (ADDR_EXPR, ptr_type, lvalue);
1571 }
1572
1573 if (TREE_TYPE (res) != atype)
1574 res = fold_build1 (NOP_EXPR, atype, res);
1575
1576 return res;
1577 }
1578
1579 tree
new_unchecked_address(tree lvalue,tree atype)1580 new_unchecked_address (tree lvalue, tree atype)
1581 {
1582 return ortho_build_addr (lvalue, atype);
1583 }
1584
1585 tree
new_address(tree lvalue,tree atype)1586 new_address (tree lvalue, tree atype)
1587 {
1588 return ortho_build_addr (lvalue, atype);
1589 }
1590
1591 tree
new_global_address(tree lvalue,tree atype)1592 new_global_address (tree lvalue, tree atype)
1593 {
1594 return ortho_build_addr (lvalue, atype);
1595 }
1596
1597 tree
new_global_unchecked_address(tree lvalue,tree atype)1598 new_global_unchecked_address (tree lvalue, tree atype)
1599 {
1600 return ortho_build_addr (lvalue, atype);
1601 }
1602
1603 /* Return a pointer to function FUNC. */
1604 static tree
build_function_ptr(tree func)1605 build_function_ptr (tree func)
1606 {
1607 return build1 (ADDR_EXPR,
1608 build_pointer_type (TREE_TYPE (func)), func);
1609 }
1610
1611 tree
new_subprogram_address(tree subprg,tree atype)1612 new_subprogram_address (tree subprg, tree atype)
1613 {
1614 return fold (build1 (NOP_EXPR, atype, build_function_ptr (subprg)));
1615 }
1616
1617 tree
new_value(tree lvalue)1618 new_value (tree lvalue)
1619 {
1620 return lvalue;
1621 }
1622
1623 void
new_debug_line_decl(int line)1624 new_debug_line_decl (int line)
1625 {
1626 input_location = linemap_line_start (line_table, line, 252);
1627 }
1628
1629 void
new_type_decl(tree ident,tree atype)1630 new_type_decl (tree ident, tree atype)
1631 {
1632 tree decl;
1633
1634 TYPE_NAME (atype) = ident;
1635 decl = build_decl (input_location, TYPE_DECL, ident, atype);
1636 TYPE_STUB_DECL (atype) = decl;
1637 pushdecl (decl);
1638 /*
1639 if Get_TYPE_SIZE (Ttype) /= NULL_TREE then
1640 -- Do not generate debug info for uncompleted types.
1641 Rest_Of_Type_Compilation (Ttype, C_True);
1642 end if;
1643 */
1644 }
1645
1646 enum o_storage { o_storage_external,
1647 o_storage_public,
1648 o_storage_private,
1649 o_storage_local };
1650
1651 static void
set_storage(tree Node,enum o_storage storage)1652 set_storage (tree Node, enum o_storage storage)
1653 {
1654 switch (storage)
1655 {
1656 case o_storage_external:
1657 DECL_EXTERNAL (Node) = 1;
1658 TREE_PUBLIC (Node) = 1;
1659 TREE_STATIC (Node) = 0;
1660 break;
1661 case o_storage_public:
1662 DECL_EXTERNAL (Node) = 0;
1663 TREE_PUBLIC (Node) = 1;
1664 TREE_STATIC (Node) = 1;
1665 break;
1666 case o_storage_private:
1667 DECL_EXTERNAL (Node) = 0;
1668 TREE_PUBLIC (Node) = 0;
1669 TREE_STATIC (Node) = 1;
1670 break;
1671 case o_storage_local:
1672 DECL_EXTERNAL (Node) = 0;
1673 TREE_PUBLIC (Node) = 0;
1674 TREE_STATIC (Node) = 0;
1675 break;
1676 }
1677 }
1678
1679 void
new_const_decl(tree * res,tree ident,enum o_storage storage,tree atype)1680 new_const_decl (tree *res, tree ident, enum o_storage storage, tree atype)
1681 {
1682 tree cst;
1683
1684 cst = build_decl (input_location, VAR_DECL, ident, atype);
1685 set_storage (cst, storage);
1686 TREE_READONLY (cst) = 1;
1687 pushdecl (cst);
1688 switch (storage)
1689 {
1690 case o_storage_local:
1691 gcc_unreachable ();
1692 case o_storage_external:
1693 /* We are at top level if Current_Function_Decl is null. */
1694 rest_of_decl_compilation (cst, current_function_decl == NULL_TREE, 0);
1695 break;
1696 case o_storage_public:
1697 case o_storage_private:
1698 break;
1699 }
1700 *res = cst;
1701 }
1702
1703 void
start_init_value(tree * decl ATTRIBUTE_UNUSED)1704 start_init_value (tree *decl ATTRIBUTE_UNUSED)
1705 {
1706 }
1707
1708 void
finish_init_value(tree * decl,tree val)1709 finish_init_value (tree *decl, tree val)
1710 {
1711 DECL_INITIAL (*decl) = val;
1712 TREE_CONSTANT (val) = 1;
1713 TREE_STATIC (*decl) = 1;
1714
1715 /* The variable may be declared with an incomplete array, so be sure it
1716 has a completed type.
1717 Force re-layout by clearing the size. */
1718 DECL_SIZE (*decl) = NULL_TREE;
1719 TREE_TYPE (*decl) = TREE_TYPE (val);
1720 layout_decl (*decl, 0);
1721
1722 rest_of_decl_compilation (*decl, current_function_decl == NULL_TREE, 0);
1723 }
1724
1725 void
new_var_decl(tree * res,tree ident,enum o_storage storage,tree atype)1726 new_var_decl (tree *res, tree ident, enum o_storage storage, tree atype)
1727 {
1728 tree var;
1729
1730 var = build_decl (input_location, VAR_DECL, ident, atype);
1731 if (current_function_decl != NULL_TREE)
1732 {
1733 /* Local variable. */
1734 TREE_STATIC (var) = 0;
1735 DECL_EXTERNAL (var) = 0;
1736 TREE_PUBLIC (var) = 0;
1737 }
1738 else
1739 set_storage (var, storage);
1740
1741 pushdecl (var);
1742
1743 if (current_function_decl == NULL_TREE)
1744 rest_of_decl_compilation (var, 1, 0);
1745
1746 *res = var;
1747 }
1748
1749 struct GTY(()) o_inter_list
1750 {
1751 tree ident;
1752 enum o_storage storage;
1753
1754 /* Return type. */
1755 tree rtype;
1756
1757 /* List of parameter types. */
1758 struct list_constr_type param_list;
1759
1760 /* Chain of parameters declarations. */
1761 struct chain_constr_type param_chain;
1762 };
1763
1764 void
start_function_decl(struct o_inter_list * interfaces,tree ident,enum o_storage storage,tree rtype)1765 start_function_decl (struct o_inter_list *interfaces,
1766 tree ident,
1767 enum o_storage storage,
1768 tree rtype)
1769 {
1770 interfaces->ident = ident;
1771 interfaces->storage = storage;
1772 interfaces->rtype = rtype;
1773 chain_init (&interfaces->param_chain);
1774 list_init (&interfaces->param_list);
1775 }
1776
1777 void
start_procedure_decl(struct o_inter_list * interfaces,tree ident,enum o_storage storage)1778 start_procedure_decl (struct o_inter_list *interfaces,
1779 tree ident,
1780 enum o_storage storage)
1781 {
1782 start_function_decl (interfaces, ident, storage, void_type_node);
1783 }
1784
1785 void
new_interface_decl(struct o_inter_list * interfaces,tree * res,tree ident,tree atype)1786 new_interface_decl (struct o_inter_list *interfaces,
1787 tree *res,
1788 tree ident,
1789 tree atype)
1790 {
1791 tree r;
1792
1793 r = build_decl (input_location, PARM_DECL, ident, atype);
1794 /* DECL_CONTEXT (Res, Xxx); */
1795
1796 /* Do type conversion: convert boolean and enums to int */
1797 switch (TREE_CODE (atype))
1798 {
1799 case ENUMERAL_TYPE:
1800 case BOOLEAN_TYPE:
1801 DECL_ARG_TYPE (r) = integer_type_node;
1802 break;
1803 default:
1804 DECL_ARG_TYPE (r) = atype;
1805 break;
1806 }
1807
1808 layout_decl (r, 0);
1809
1810 chain_append (&interfaces->param_chain, r);
1811 ortho_list_append (&interfaces->param_list, atype);
1812 *res = r;
1813 }
1814
1815 void
finish_subprogram_decl(struct o_inter_list * interfaces,tree * res)1816 finish_subprogram_decl (struct o_inter_list *interfaces, tree *res)
1817 {
1818 tree decl;
1819 tree result;
1820 tree parm;
1821 int is_global;
1822
1823 /* Append a void type in the parameter types chain, so that the function
1824 is known not be have variables arguments. */
1825 ortho_list_append (&interfaces->param_list, void_type_node);
1826
1827 decl = build_decl (input_location, FUNCTION_DECL, interfaces->ident,
1828 build_function_type (interfaces->rtype,
1829 interfaces->param_list.first));
1830 DECL_SOURCE_LOCATION (decl) = input_location;
1831
1832 is_global = current_function_decl == NULL_TREE
1833 || interfaces->storage == o_storage_external;
1834 if (is_global)
1835 set_storage (decl, interfaces->storage);
1836 else
1837 {
1838 /* A nested subprogram. */
1839 DECL_EXTERNAL (decl) = 0;
1840 TREE_PUBLIC (decl) = 0;
1841 }
1842 /* The function exist in static storage. */
1843 TREE_STATIC (decl) = 1;
1844 DECL_INITIAL (decl) = error_mark_node;
1845 TREE_ADDRESSABLE (decl) = 1;
1846
1847 /* Declare the result.
1848 FIXME: should be moved in start_function_body. */
1849 result = build_decl (input_location,
1850 RESULT_DECL, NULL_TREE, interfaces->rtype);
1851 DECL_RESULT (decl) = result;
1852 DECL_CONTEXT (result) = decl;
1853
1854 DECL_ARGUMENTS (decl) = interfaces->param_chain.first;
1855 /* Set DECL_CONTEXT of parameters. */
1856 for (parm = interfaces->param_chain.first;
1857 parm != NULL_TREE;
1858 parm = TREE_CHAIN (parm))
1859 DECL_CONTEXT (parm) = decl;
1860
1861 pushdecl (decl);
1862
1863 /* External functions are never nested.
1864 Remove their context, which is set by pushdecl. */
1865 if (interfaces->storage == o_storage_external)
1866 DECL_CONTEXT (decl) = NULL_TREE;
1867
1868 if (is_global)
1869 rest_of_decl_compilation (decl, 1, 0);
1870
1871 *res = decl;
1872 }
1873
1874 void
start_subprogram_body(tree func)1875 start_subprogram_body (tree func)
1876 {
1877 gcc_assert (current_function_decl == DECL_CONTEXT (func));
1878 current_function_decl = func;
1879
1880 /* The function is not anymore external. */
1881 DECL_EXTERNAL (func) = 0;
1882
1883 push_binding (FUNCTION_BINDING);
1884 }
1885
1886 void
finish_subprogram_body(void)1887 finish_subprogram_body (void)
1888 {
1889 tree bind;
1890 tree func;
1891 tree parent;
1892
1893 bind = pop_binding ();
1894
1895 func = current_function_decl;
1896
1897 /* Decl initial contains the BLOCK for the function. */
1898 DECL_INITIAL (func) = BIND_EXPR_BLOCK (bind);
1899
1900 /* The saved tree is the BIND_EXPR. */
1901 DECL_SAVED_TREE (func) = bind;
1902
1903 /* Initialize the RTL code for the function. */
1904 allocate_struct_function (func, false);
1905
1906 /* Store the end of the function. */
1907 cfun->function_end_locus = input_location;
1908
1909 parent = DECL_CONTEXT (func);
1910
1911 if (parent != NULL)
1912 cgraph_node::get_create (func);
1913 else
1914 cgraph_node::finalize_function (func, false);
1915
1916 current_function_decl = parent;
1917 set_cfun (NULL);
1918 }
1919
1920
1921 void
new_debug_line_stmt(int line)1922 new_debug_line_stmt (int line)
1923 {
1924 input_location = linemap_line_start (line_table, line, 252);
1925 }
1926
1927 void
start_declare_stmt(void)1928 start_declare_stmt (void)
1929 {
1930 push_binding (LOCAL_BINDING);
1931 }
1932
1933 void
finish_declare_stmt(void)1934 finish_declare_stmt (void)
1935 {
1936 tree bind;
1937
1938 bind = pop_binding ();
1939 append_stmt (bind);
1940 }
1941
1942
1943 struct GTY(()) o_assoc_list
1944 {
1945 tree subprg;
1946 vec<tree, va_gc> *vecptr;
1947 };
1948
1949 void
start_association(struct o_assoc_list * assocs,tree subprg)1950 start_association (struct o_assoc_list *assocs, tree subprg)
1951 {
1952 assocs->subprg = subprg;
1953 assocs->vecptr = NULL;
1954 }
1955
1956 void
new_association(struct o_assoc_list * assocs,tree val)1957 new_association (struct o_assoc_list *assocs, tree val)
1958 {
1959 vec_safe_push(assocs->vecptr, val);
1960 }
1961
1962 tree
new_function_call(struct o_assoc_list * assocs)1963 new_function_call (struct o_assoc_list *assocs)
1964 {
1965 return build_call_vec (TREE_TYPE (TREE_TYPE (assocs->subprg)),
1966 build_function_ptr (assocs->subprg),
1967 assocs->vecptr);
1968 }
1969
1970 void
new_procedure_call(struct o_assoc_list * assocs)1971 new_procedure_call (struct o_assoc_list *assocs)
1972 {
1973 tree res;
1974
1975 res = build_call_vec (TREE_TYPE (TREE_TYPE (assocs->subprg)),
1976 build_function_ptr (assocs->subprg),
1977 assocs->vecptr);
1978 TREE_SIDE_EFFECTS (res) = 1;
1979 append_stmt (res);
1980 }
1981
1982 void
new_assign_stmt(tree target,tree value)1983 new_assign_stmt (tree target, tree value)
1984 {
1985 tree n;
1986
1987 n = build2 (MODIFY_EXPR, TREE_TYPE (target), target, value);
1988 TREE_SIDE_EFFECTS (n) = 1;
1989 append_stmt (n);
1990 }
1991
1992 void
new_func_return_stmt(tree value)1993 new_func_return_stmt (tree value)
1994 {
1995 tree assign;
1996 tree stmt;
1997 tree res;
1998
1999 res = DECL_RESULT (current_function_decl);
2000 assign = build2 (MODIFY_EXPR, TREE_TYPE (value), res, value);
2001 TREE_SIDE_EFFECTS (assign) = 1;
2002 stmt = build1 (RETURN_EXPR, void_type_node, assign);
2003 TREE_SIDE_EFFECTS (stmt) = 1;
2004 append_stmt (stmt);
2005 }
2006
2007 void
new_proc_return_stmt(void)2008 new_proc_return_stmt (void)
2009 {
2010 tree stmt;
2011
2012 stmt = build1 (RETURN_EXPR, void_type_node, NULL_TREE);
2013 TREE_SIDE_EFFECTS (stmt) = 1;
2014 append_stmt (stmt);
2015 }
2016
2017
2018 struct GTY(()) o_if_block
2019 {
2020 /* STATEMENT_LIST containing the if. */
2021 tree prev_stmts;
2022
2023 /* The COND_EXPR. */
2024 tree if_stmt;
2025 };
2026
2027 void
start_if_stmt(struct o_if_block * block,tree cond)2028 start_if_stmt (struct o_if_block *block, tree cond)
2029 {
2030 tree stmt;
2031 tree stmts;
2032
2033 stmts = alloc_stmt_list ();
2034 stmt = build3 (COND_EXPR, void_type_node, cond, stmts, NULL_TREE);
2035 append_stmt (stmt);
2036 block->prev_stmts = cur_stmts;
2037 block->if_stmt = stmt;
2038 cur_stmts = stmts;
2039 }
2040
2041 void
new_else_stmt(struct o_if_block * block)2042 new_else_stmt (struct o_if_block *block)
2043 {
2044 cur_stmts = alloc_stmt_list ();
2045 COND_EXPR_ELSE (block->if_stmt) = cur_stmts;
2046 }
2047
2048 void
finish_if_stmt(struct o_if_block * block)2049 finish_if_stmt (struct o_if_block *block)
2050 {
2051 cur_stmts = block->prev_stmts;
2052 }
2053
2054 struct GTY(()) o_snode
2055 {
2056 tree beg_label;
2057 tree end_label;
2058 };
2059
2060 /* Create an artificial label. */
2061 static tree
build_label(void)2062 build_label (void)
2063 {
2064 tree res;
2065
2066 res = build_decl (input_location, LABEL_DECL, NULL_TREE, void_type_node);
2067 DECL_CONTEXT (res) = current_function_decl;
2068 DECL_ARTIFICIAL (res) = 1;
2069 return res;
2070 }
2071
2072 void
start_loop_stmt(struct o_snode * label)2073 start_loop_stmt (struct o_snode *label)
2074 {
2075 tree stmt;
2076
2077 label->beg_label = build_label ();
2078
2079 stmt = build1 (LABEL_EXPR, void_type_node, label->beg_label);
2080 append_stmt (stmt);
2081
2082 label->end_label = build_label ();
2083 }
2084
2085 void
finish_loop_stmt(struct o_snode * label)2086 finish_loop_stmt (struct o_snode *label)
2087 {
2088 tree stmt;
2089
2090 stmt = build1 (GOTO_EXPR, void_type_node, label->beg_label);
2091 TREE_USED (label->beg_label) = 1;
2092 append_stmt (stmt);
2093 /* Emit the end label only if there is a goto to it.
2094 (Return may be used to exit from the loop). */
2095 if (TREE_USED (label->end_label))
2096 {
2097 stmt = build1 (LABEL_EXPR, void_type_node, label->end_label);
2098 append_stmt (stmt);
2099 }
2100 }
2101
2102 void
new_exit_stmt(struct o_snode * l)2103 new_exit_stmt (struct o_snode *l)
2104 {
2105 tree stmt;
2106
2107 stmt = build1 (GOTO_EXPR, void_type_node, l->end_label);
2108 append_stmt (stmt);
2109 TREE_USED (l->end_label) = 1;
2110 }
2111
2112 void
new_next_stmt(struct o_snode * l)2113 new_next_stmt (struct o_snode *l)
2114 {
2115 tree stmt;
2116
2117 stmt = build1 (GOTO_EXPR, void_type_node, l->beg_label);
2118 TREE_USED (l->beg_label) = 1;
2119 append_stmt (stmt);
2120 }
2121
2122 struct GTY(()) o_case_block
2123 {
2124 tree prev_stmts;
2125 tree case_type;
2126 tree end_label;
2127 int add_break;
2128 };
2129
2130 void
start_case_stmt(struct o_case_block * block,tree value)2131 start_case_stmt (struct o_case_block *block, tree value)
2132 {
2133 tree stmt;
2134 tree stmts;
2135
2136 block->prev_stmts = cur_stmts;
2137 block->case_type = TREE_TYPE (value);
2138 block->end_label = build_label ();
2139 block->add_break = 0;
2140
2141 stmts = alloc_stmt_list ();
2142 stmt = build2 (SWITCH_EXPR, block->case_type, value, stmts);
2143 append_stmt (stmt);
2144 cur_stmts = stmts;
2145 }
2146
2147 void
start_choice(struct o_case_block * block)2148 start_choice (struct o_case_block *block)
2149 {
2150 tree stmt;
2151
2152 if (block->add_break)
2153 {
2154 stmt = build1 (GOTO_EXPR, block->case_type, block->end_label);
2155 append_stmt (stmt);
2156
2157 block->add_break = 0;
2158 }
2159 }
2160
2161 void
new_expr_choice(struct o_case_block * block ATTRIBUTE_UNUSED,tree expr)2162 new_expr_choice (struct o_case_block *block ATTRIBUTE_UNUSED, tree expr)
2163 {
2164 tree stmt;
2165
2166 stmt = build_case_label
2167 (expr, NULL_TREE, create_artificial_label (input_location));
2168 append_stmt (stmt);
2169 }
2170
2171 void
new_range_choice(struct o_case_block * block ATTRIBUTE_UNUSED,tree low,tree high)2172 new_range_choice (struct o_case_block *block ATTRIBUTE_UNUSED,
2173 tree low, tree high)
2174 {
2175 tree stmt;
2176
2177 stmt = build_case_label
2178 (low, high, create_artificial_label (input_location));
2179 append_stmt (stmt);
2180 }
2181
2182 void
new_default_choice(struct o_case_block * block ATTRIBUTE_UNUSED)2183 new_default_choice (struct o_case_block *block ATTRIBUTE_UNUSED)
2184 {
2185 tree stmt;
2186
2187 stmt = build_case_label
2188 (NULL_TREE, NULL_TREE, create_artificial_label (input_location));
2189 append_stmt (stmt);
2190 }
2191
2192 void
finish_choice(struct o_case_block * block)2193 finish_choice (struct o_case_block *block)
2194 {
2195 block->add_break = 1;
2196 }
2197
2198 void
finish_case_stmt(struct o_case_block * block)2199 finish_case_stmt (struct o_case_block *block)
2200 {
2201 tree stmt;
2202
2203 cur_stmts = block->prev_stmts;
2204 stmt = build1 (LABEL_EXPR, void_type_node, block->end_label);
2205 append_stmt (stmt);
2206 }
2207
2208 bool
compare_identifier_string(tree id,const char * str,size_t len)2209 compare_identifier_string (tree id, const char *str, size_t len)
2210 {
2211 if (IDENTIFIER_LENGTH (id) != len)
2212 return false;
2213 if (!memcmp (IDENTIFIER_POINTER (id), str, len))
2214 return true;
2215 else
2216 return false;
2217 }
2218
2219 void
get_identifier_string(tree id,const char ** str,int * len)2220 get_identifier_string (tree id, const char **str, int *len)
2221 {
2222 *len = IDENTIFIER_LENGTH (id);
2223 *str = IDENTIFIER_POINTER (id);
2224 }
2225
2226 // C linkage wrappers for two (now C++) functions so that
2227 // Ada code can call them without name mangling
get_identifier_with_length_c(const char * c,size_t s)2228 tree get_identifier_with_length_c (const char *c, size_t s)
2229 {
2230 return get_identifier_with_length(c, s);
2231 }
2232
toplev_main_c(int argc,char ** argv)2233 int toplev_main_c (int argc, char **argv)
2234 {
2235 toplev toplev (NULL, true);
2236 return toplev.main(argc, argv);
2237 }
2238
2239 void
debug_tree_c(tree expr)2240 debug_tree_c (tree expr)
2241 {
2242 warning (OPT_Wall, "Debug tree");
2243 debug_tree (expr);
2244 }
2245
2246 } // end extern "C"
2247
2248 #include "debug.h"
2249 #include "gt-vhdl-ortho-lang.h"
2250 #include "gtype-vhdl.h"
2251