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