1 /* Print GENERIC declaration (functions, variables, types) trees coming from
2    the C and C++ front-ends as well as macros in Ada syntax.
3    Copyright (C) 2010-2018 Free Software Foundation, Inc.
4    Adapted from tree-pretty-print.c by Arnaud Charlet  <charlet@adacore.com>
5 
6 This file is part of GCC.
7 
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12 
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3.  If not see
20 <http://www.gnu.org/licenses/>.  */
21 
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "c-ada-spec.h"
28 #include "fold-const.h"
29 #include "c-pragma.h"
30 #include "cpp-id-data.h"
31 #include "stringpool.h"
32 #include "attribs.h"
33 
34 /* Local functions, macros and variables.  */
35 static int  dump_ada_node (pretty_printer *, tree, tree, int, bool, bool);
36 static int  dump_ada_declaration (pretty_printer *, tree, tree, int);
37 static void dump_ada_structure (pretty_printer *, tree, tree, int, bool);
38 static char *to_ada_name (const char *, unsigned int, bool *);
39 
40 #define INDENT(SPACE) \
41   do { int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
42 
43 #define INDENT_INCR 3
44 
45 /* Global hook used to perform C++ queries on nodes.  */
46 static int (*cpp_check) (tree, cpp_operation) = NULL;
47 
48 /* Global variables used in macro-related callbacks.  */
49 static int max_ada_macros;
50 static int store_ada_macro_index;
51 static const char *macro_source_file;
52 
53 /* Given a cpp MACRO, compute the max length BUFFER_LEN of the macro, as well
54    as max length PARAM_LEN of arguments for fun_like macros, and also set
55    SUPPORTED to 0 if the macro cannot be mapped to an Ada construct.  */
56 
57 static void
58 macro_length (const cpp_macro *macro, int *supported, int *buffer_len,
59 	      int *param_len)
60 {
61   int i;
62   unsigned j;
63 
64   *supported = 1;
65   *buffer_len = 0;
66   *param_len = 0;
67 
68   if (macro->fun_like)
69     {
70       (*param_len)++;
71       for (i = 0; i < macro->paramc; i++)
72 	{
73 	  cpp_hashnode *param = macro->params[i];
74 
75 	  *param_len += NODE_LEN (param);
76 
77 	  if (i + 1 < macro->paramc)
78 	    {
79 	      *param_len += 2;  /* ", " */
80 	    }
81 	  else if (macro->variadic)
82 	    {
83 	      *supported = 0;
84 	      return;
85 	    }
86 	}
87       *param_len += 2;  /* ")\0" */
88     }
89 
90   for (j = 0; j < macro->count; j++)
91     {
92       cpp_token *token = &macro->exp.tokens[j];
93 
94       if (token->flags & PREV_WHITE)
95 	(*buffer_len)++;
96 
97       if (token->flags & STRINGIFY_ARG || token->flags & PASTE_LEFT)
98 	{
99 	  *supported = 0;
100 	  return;
101 	}
102 
103       if (token->type == CPP_MACRO_ARG)
104 	*buffer_len +=
105 	  NODE_LEN (macro->params[token->val.macro_arg.arg_no - 1]);
106       else
107 	/* Include enough extra space to handle e.g. special characters.  */
108 	*buffer_len += (cpp_token_len (token) + 1) * 8;
109     }
110 
111   (*buffer_len)++;
112 }
113 
114 /* Dump all digits/hex chars from NUMBER to BUFFER and return a pointer
115    to the character after the last character written.  If FLOAT_P is true,
116    this is a floating-point number.  */
117 
118 static unsigned char *
119 dump_number (unsigned char *number, unsigned char *buffer, bool float_p)
120 {
121   while (*number != '\0'
122 	 && *number != (float_p ? 'F' : 'U')
123 	 && *number != (float_p ? 'f' : 'u')
124 	 && *number != 'l'
125 	 && *number != 'L')
126     *buffer++ = *number++;
127 
128   return buffer;
129 }
130 
131 /* Handle escape character C and convert to an Ada character into BUFFER.
132    Return a pointer to the character after the last character written, or
133    NULL if the escape character is not supported.  */
134 
135 static unsigned char *
136 handle_escape_character (unsigned char *buffer, char c)
137 {
138   switch (c)
139     {
140       case '"':
141 	*buffer++ = '"';
142 	*buffer++ = '"';
143 	break;
144 
145       case 'n':
146 	strcpy ((char *) buffer, "\" & ASCII.LF & \"");
147 	buffer += 16;
148 	break;
149 
150       case 'r':
151 	strcpy ((char *) buffer, "\" & ASCII.CR & \"");
152 	buffer += 16;
153 	break;
154 
155       case 't':
156 	strcpy ((char *) buffer, "\" & ASCII.HT & \"");
157 	buffer += 16;
158 	break;
159 
160       default:
161 	return NULL;
162     }
163 
164   return buffer;
165 }
166 
167 /* Callback used to count the number of macros from cpp_forall_identifiers.
168    PFILE and V are not used.  NODE is the current macro to consider.  */
169 
170 static int
171 count_ada_macro (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *node,
172 		 void *v ATTRIBUTE_UNUSED)
173 {
174   const cpp_macro *macro = node->value.macro;
175 
176   if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN)
177       && macro->count
178       && *NODE_NAME (node) != '_'
179       && LOCATION_FILE (macro->line) == macro_source_file)
180     max_ada_macros++;
181 
182   return 1;
183 }
184 
185 /* Callback used to store relevant macros from cpp_forall_identifiers.
186    PFILE is not used.  NODE is the current macro to store if relevant.
187    MACROS is an array of cpp_hashnode* used to store NODE.  */
188 
189 static int
190 store_ada_macro (cpp_reader *pfile ATTRIBUTE_UNUSED,
191 		 cpp_hashnode *node, void *macros)
192 {
193   const cpp_macro *macro = node->value.macro;
194 
195   if (node->type == NT_MACRO
196       && !(node->flags & NODE_BUILTIN)
197       && macro->count
198       && *NODE_NAME (node) != '_'
199       && LOCATION_FILE (macro->line) == macro_source_file)
200     ((cpp_hashnode **) macros)[store_ada_macro_index++] = node;
201 
202   return 1;
203 }
204 
205 /* Callback used to compare (during qsort) macros.  NODE1 and NODE2 are the
206    two macro nodes to compare.  */
207 
208 static int
209 compare_macro (const void *node1, const void *node2)
210 {
211   typedef const cpp_hashnode *const_hnode;
212 
213   const_hnode n1 = *(const const_hnode *) node1;
214   const_hnode n2 = *(const const_hnode *) node2;
215 
216   return n1->value.macro->line - n2->value.macro->line;
217 }
218 
219 /* Dump in PP all relevant macros appearing in FILE.  */
220 
221 static void
222 dump_ada_macros (pretty_printer *pp, const char* file)
223 {
224   int num_macros = 0, prev_line = -1;
225   cpp_hashnode **macros;
226 
227   /* Initialize file-scope variables.  */
228   max_ada_macros = 0;
229   store_ada_macro_index = 0;
230   macro_source_file = file;
231 
232   /* Count all potentially relevant macros, and then sort them by sloc.  */
233   cpp_forall_identifiers (parse_in, count_ada_macro, NULL);
234   macros = XALLOCAVEC (cpp_hashnode *, max_ada_macros);
235   cpp_forall_identifiers (parse_in, store_ada_macro, macros);
236   qsort (macros, max_ada_macros, sizeof (cpp_hashnode *), compare_macro);
237 
238   for (int j = 0; j < max_ada_macros; j++)
239     {
240       cpp_hashnode *node = macros[j];
241       const cpp_macro *macro = node->value.macro;
242       unsigned i;
243       int supported = 1, prev_is_one = 0, buffer_len, param_len;
244       int is_string = 0, is_char = 0;
245       char *ada_name;
246       unsigned char *s, *params, *buffer, *buf_param, *char_one = NULL, *tmp;
247 
248       macro_length (macro, &supported, &buffer_len, &param_len);
249       s = buffer = XALLOCAVEC (unsigned char, buffer_len);
250       params = buf_param = XALLOCAVEC (unsigned char, param_len);
251 
252       if (supported)
253 	{
254 	  if (macro->fun_like)
255 	    {
256 	      *buf_param++ = '(';
257 	      for (i = 0; i < macro->paramc; i++)
258 		{
259 		  cpp_hashnode *param = macro->params[i];
260 
261 		  memcpy (buf_param, NODE_NAME (param), NODE_LEN (param));
262 		  buf_param += NODE_LEN (param);
263 
264 		  if (i + 1 < macro->paramc)
265 		    {
266 		      *buf_param++ = ',';
267 		      *buf_param++ = ' ';
268 		    }
269 		  else if (macro->variadic)
270 		    {
271 		      supported = 0;
272 		      break;
273 		    }
274 		}
275 	      *buf_param++ = ')';
276 	      *buf_param = '\0';
277 	    }
278 
279 	  for (i = 0; supported && i < macro->count; i++)
280 	    {
281 	      cpp_token *token = &macro->exp.tokens[i];
282 	      int is_one = 0;
283 
284 	      if (token->flags & PREV_WHITE)
285 		*buffer++ = ' ';
286 
287 	      if (token->flags & STRINGIFY_ARG || token->flags & PASTE_LEFT)
288 		{
289 		  supported = 0;
290 		  break;
291 		}
292 
293 	      switch (token->type)
294 		{
295 		  case CPP_MACRO_ARG:
296 		    {
297 		      cpp_hashnode *param =
298 			macro->params[token->val.macro_arg.arg_no - 1];
299 		      memcpy (buffer, NODE_NAME (param), NODE_LEN (param));
300 		      buffer += NODE_LEN (param);
301 		    }
302 		    break;
303 
304 		  case CPP_EQ_EQ:       *buffer++ = '='; break;
305 		  case CPP_GREATER:     *buffer++ = '>'; break;
306 		  case CPP_LESS:        *buffer++ = '<'; break;
307 		  case CPP_PLUS:        *buffer++ = '+'; break;
308 		  case CPP_MINUS:       *buffer++ = '-'; break;
309 		  case CPP_MULT:        *buffer++ = '*'; break;
310 		  case CPP_DIV:         *buffer++ = '/'; break;
311 		  case CPP_COMMA:       *buffer++ = ','; break;
312 		  case CPP_OPEN_SQUARE:
313 		  case CPP_OPEN_PAREN:  *buffer++ = '('; break;
314 		  case CPP_CLOSE_SQUARE: /* fallthrough */
315 		  case CPP_CLOSE_PAREN: *buffer++ = ')'; break;
316 		  case CPP_DEREF:       /* fallthrough */
317 		  case CPP_SCOPE:       /* fallthrough */
318 		  case CPP_DOT:         *buffer++ = '.'; break;
319 
320 		  case CPP_EQ:          *buffer++ = ':'; *buffer++ = '='; break;
321 		  case CPP_NOT_EQ:      *buffer++ = '/'; *buffer++ = '='; break;
322 		  case CPP_GREATER_EQ:  *buffer++ = '>'; *buffer++ = '='; break;
323 		  case CPP_LESS_EQ:     *buffer++ = '<'; *buffer++ = '='; break;
324 
325 		  case CPP_NOT:
326 		    *buffer++ = 'n'; *buffer++ = 'o'; *buffer++ = 't'; break;
327 		  case CPP_MOD:
328 		    *buffer++ = 'm'; *buffer++ = 'o'; *buffer++ = 'd'; break;
329 		  case CPP_AND:
330 		    *buffer++ = 'a'; *buffer++ = 'n'; *buffer++ = 'd'; break;
331 		  case CPP_OR:
332 		    *buffer++ = 'o'; *buffer++ = 'r'; break;
333 		  case CPP_XOR:
334 		    *buffer++ = 'x'; *buffer++ = 'o'; *buffer++ = 'r'; break;
335 		  case CPP_AND_AND:
336 		    strcpy ((char *) buffer, " and then ");
337 		    buffer += 10;
338 		    break;
339 		  case CPP_OR_OR:
340 		    strcpy ((char *) buffer, " or else ");
341 		    buffer += 9;
342 		    break;
343 
344 		  case CPP_PADDING:
345 		    *buffer++ = ' ';
346 		    is_one = prev_is_one;
347 		    break;
348 
349 		  case CPP_COMMENT:
350 		    break;
351 
352 		  case CPP_WSTRING:
353 		  case CPP_STRING16:
354 		  case CPP_STRING32:
355 		  case CPP_UTF8STRING:
356 		  case CPP_WCHAR:
357 		  case CPP_CHAR16:
358 		  case CPP_CHAR32:
359 		  case CPP_UTF8CHAR:
360 		  case CPP_NAME:
361 		    if (!macro->fun_like)
362 		      supported = 0;
363 		    else
364 		      buffer
365 			= cpp_spell_token (parse_in, token, buffer, false);
366 		    break;
367 
368 		  case CPP_STRING:
369 		    if (is_string)
370 		      {
371 			*buffer++ = '&';
372 			*buffer++ = ' ';
373 		      }
374 		    else
375 		      is_string = 1;
376 		    {
377 		      const unsigned char *s = token->val.str.text;
378 
379 		      for (; *s; s++)
380 			if (*s == '\\')
381 			  {
382 			    s++;
383 			    buffer = handle_escape_character (buffer, *s);
384 			    if (buffer == NULL)
385 			      {
386 				supported = 0;
387 				break;
388 			      }
389 			  }
390 			else
391 			  *buffer++ = *s;
392 		    }
393 		    break;
394 
395 		  case CPP_CHAR:
396 		    is_char = 1;
397 		    {
398 		      unsigned chars_seen;
399 		      int ignored;
400 		      cppchar_t c;
401 
402 		      c = cpp_interpret_charconst (parse_in, token,
403 						   &chars_seen, &ignored);
404 		      if (c >= 32 && c <= 126)
405 			{
406 			  *buffer++ = '\'';
407 			  *buffer++ = (char) c;
408 			  *buffer++ = '\'';
409 			}
410 		      else
411 			{
412 			  chars_seen = sprintf
413 			    ((char *) buffer, "Character'Val (%d)", (int) c);
414 			  buffer += chars_seen;
415 			}
416 		    }
417 		    break;
418 
419 		  case CPP_NUMBER:
420 		    tmp = cpp_token_as_text (parse_in, token);
421 
422 		    switch (*tmp)
423 		      {
424 			case '0':
425 			  switch (tmp[1])
426 			    {
427 			      case '\0':
428 			      case 'l':
429 			      case 'L':
430 			      case 'u':
431 			      case 'U':
432 				*buffer++ = '0';
433 				break;
434 
435 			      case 'x':
436 			      case 'X':
437 				*buffer++ = '1';
438 				*buffer++ = '6';
439 				*buffer++ = '#';
440 				buffer = dump_number (tmp + 2, buffer, false);
441 				*buffer++ = '#';
442 				break;
443 
444 			      case 'b':
445 			      case 'B':
446 				*buffer++ = '2';
447 				*buffer++ = '#';
448 				buffer = dump_number (tmp + 2, buffer, false);
449 				*buffer++ = '#';
450 				break;
451 
452 			      default:
453 				/* Dump floating-point constant unmodified.  */
454 				if (strchr ((const char *)tmp, '.'))
455 				  buffer = dump_number (tmp, buffer, true);
456 				else
457 				  {
458 				    *buffer++ = '8';
459 				    *buffer++ = '#';
460 				    buffer
461 				      = dump_number (tmp + 1, buffer, false);
462 				    *buffer++ = '#';
463 				  }
464 				break;
465 			    }
466 			  break;
467 
468 			case '1':
469 			  if (tmp[1] == '\0'
470 			      || tmp[1] == 'u'
471 			      || tmp[1] == 'U'
472 			      || tmp[1] == 'l'
473 			      || tmp[1] == 'L')
474 			    {
475 			      is_one = 1;
476 			      char_one = buffer;
477 			      *buffer++ = '1';
478 			      break;
479 			    }
480 			  /* fallthrough */
481 
482 			default:
483 			  buffer
484 			    = dump_number (tmp, buffer,
485 					   strchr ((const char *)tmp, '.'));
486 			  break;
487 		      }
488 		    break;
489 
490 		  case CPP_LSHIFT:
491 		    if (prev_is_one)
492 		      {
493 			/* Replace "1 << N" by "2 ** N" */
494 		        *char_one = '2';
495 		        *buffer++ = '*';
496 		        *buffer++ = '*';
497 		        break;
498 		      }
499 		    /* fallthrough */
500 
501 		  case CPP_RSHIFT:
502 		  case CPP_COMPL:
503 		  case CPP_QUERY:
504 		  case CPP_EOF:
505 		  case CPP_PLUS_EQ:
506 		  case CPP_MINUS_EQ:
507 		  case CPP_MULT_EQ:
508 		  case CPP_DIV_EQ:
509 		  case CPP_MOD_EQ:
510 		  case CPP_AND_EQ:
511 		  case CPP_OR_EQ:
512 		  case CPP_XOR_EQ:
513 		  case CPP_RSHIFT_EQ:
514 		  case CPP_LSHIFT_EQ:
515 		  case CPP_PRAGMA:
516 		  case CPP_PRAGMA_EOL:
517 		  case CPP_HASH:
518 		  case CPP_PASTE:
519 		  case CPP_OPEN_BRACE:
520 		  case CPP_CLOSE_BRACE:
521 		  case CPP_SEMICOLON:
522 		  case CPP_ELLIPSIS:
523 		  case CPP_PLUS_PLUS:
524 		  case CPP_MINUS_MINUS:
525 		  case CPP_DEREF_STAR:
526 		  case CPP_DOT_STAR:
527 		  case CPP_ATSIGN:
528 		  case CPP_HEADER_NAME:
529 		  case CPP_AT_NAME:
530 		  case CPP_OTHER:
531 		  case CPP_OBJC_STRING:
532 		  default:
533 		    if (!macro->fun_like)
534 		      supported = 0;
535 		    else
536 		      buffer = cpp_spell_token (parse_in, token, buffer, false);
537 		    break;
538 		}
539 
540 	      prev_is_one = is_one;
541 	    }
542 
543 	  if (supported)
544 	    *buffer = '\0';
545 	}
546 
547       if (macro->fun_like && supported)
548 	{
549 	  char *start = (char *) s;
550 	  int is_function = 0;
551 
552 	  pp_string (pp, "   --  arg-macro: ");
553 
554 	  if (*start == '(' && buffer[-1] == ')')
555 	    {
556 	      start++;
557 	      buffer[-1] = '\0';
558 	      is_function = 1;
559 	      pp_string (pp, "function ");
560 	    }
561 	  else
562 	    {
563 	      pp_string (pp, "procedure ");
564 	    }
565 
566 	  pp_string (pp, (const char *) NODE_NAME (node));
567 	  pp_space (pp);
568 	  pp_string (pp, (char *) params);
569 	  pp_newline (pp);
570 	  pp_string (pp, "   --    ");
571 
572 	  if (is_function)
573 	    {
574 	      pp_string (pp, "return ");
575 	      pp_string (pp, start);
576 	      pp_semicolon (pp);
577 	    }
578 	  else
579 	    pp_string (pp, start);
580 
581 	  pp_newline (pp);
582 	}
583       else if (supported)
584 	{
585 	  expanded_location sloc = expand_location (macro->line);
586 
587 	  if (sloc.line != prev_line + 1 && prev_line > 0)
588 	    pp_newline (pp);
589 
590 	  num_macros++;
591 	  prev_line = sloc.line;
592 
593 	  pp_string (pp, "   ");
594 	  ada_name = to_ada_name ((const char *) NODE_NAME (node), 0, NULL);
595 	  pp_string (pp, ada_name);
596 	  free (ada_name);
597 	  pp_string (pp, " : ");
598 
599 	  if (is_string)
600 	    pp_string (pp, "aliased constant String");
601 	  else if (is_char)
602 	    pp_string (pp, "aliased constant Character");
603 	  else
604 	    pp_string (pp, "constant");
605 
606 	  pp_string (pp, " := ");
607 	  pp_string (pp, (char *) s);
608 
609 	  if (is_string)
610 	    pp_string (pp, " & ASCII.NUL");
611 
612 	  pp_string (pp, ";  --  ");
613 	  pp_string (pp, sloc.file);
614 	  pp_colon (pp);
615 	  pp_scalar (pp, "%d", sloc.line);
616 	  pp_newline (pp);
617 	}
618       else
619 	{
620 	  pp_string (pp, "   --  unsupported macro: ");
621 	  pp_string (pp, (const char *) cpp_macro_definition (parse_in, node));
622 	  pp_newline (pp);
623 	}
624     }
625 
626   if (num_macros > 0)
627     pp_newline (pp);
628 }
629 
630 /* Current source file being handled.  */
631 static const char *current_source_file;
632 
633 /* Return sloc of DECL, using sloc of last field if LAST is true.  */
634 
635 location_t
636 decl_sloc (const_tree decl, bool last)
637 {
638   tree field;
639 
640   /* Compare the declaration of struct-like types based on the sloc of their
641      last field (if LAST is true), so that more nested types collate before
642      less nested ones.  */
643   if (TREE_CODE (decl) == TYPE_DECL
644       && !DECL_ORIGINAL_TYPE (decl)
645       && RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl))
646       && (field = TYPE_FIELDS (TREE_TYPE (decl))))
647     {
648       if (last)
649 	while (DECL_CHAIN (field))
650 	  field = DECL_CHAIN (field);
651       return DECL_SOURCE_LOCATION (field);
652     }
653 
654   return DECL_SOURCE_LOCATION (decl);
655 }
656 
657 /* Compare two locations LHS and RHS.  */
658 
659 static int
660 compare_location (location_t lhs, location_t rhs)
661 {
662   expanded_location xlhs = expand_location (lhs);
663   expanded_location xrhs = expand_location (rhs);
664 
665   if (xlhs.file != xrhs.file)
666     return filename_cmp (xlhs.file, xrhs.file);
667 
668   if (xlhs.line != xrhs.line)
669     return xlhs.line - xrhs.line;
670 
671   if (xlhs.column != xrhs.column)
672     return xlhs.column - xrhs.column;
673 
674   return 0;
675 }
676 
677 /* Compare two declarations (LP and RP) by their source location.  */
678 
679 static int
680 compare_node (const void *lp, const void *rp)
681 {
682   const_tree lhs = *((const tree *) lp);
683   const_tree rhs = *((const tree *) rp);
684 
685   return compare_location (decl_sloc (lhs, true), decl_sloc (rhs, true));
686 }
687 
688 /* Compare two comments (LP and RP) by their source location.  */
689 
690 static int
691 compare_comment (const void *lp, const void *rp)
692 {
693   const cpp_comment *lhs = (const cpp_comment *) lp;
694   const cpp_comment *rhs = (const cpp_comment *) rp;
695 
696   return compare_location (lhs->sloc, rhs->sloc);
697 }
698 
699 static tree *to_dump = NULL;
700 static int to_dump_count = 0;
701 
702 /* Collect a list of declarations from T relevant to SOURCE_FILE to be dumped
703    by a subsequent call to dump_ada_nodes.  */
704 
705 void
706 collect_ada_nodes (tree t, const char *source_file)
707 {
708   tree n;
709   int i = to_dump_count;
710 
711   /* Count the likely relevant nodes: do not dump builtins (they are irrelevant
712      in the context of bindings) and namespaces (we do not handle them properly
713      yet).  */
714   for (n = t; n; n = TREE_CHAIN (n))
715     if (!DECL_IS_BUILTIN (n)
716 	&& TREE_CODE (n) != NAMESPACE_DECL
717 	&& LOCATION_FILE (decl_sloc (n, false)) == source_file)
718       to_dump_count++;
719 
720   /* Allocate sufficient storage for all nodes.  */
721   to_dump = XRESIZEVEC (tree, to_dump, to_dump_count);
722 
723   /* Store the relevant nodes.  */
724   for (n = t; n; n = TREE_CHAIN (n))
725     if (!DECL_IS_BUILTIN (n)
726 	&& TREE_CODE (n) != NAMESPACE_DECL
727 	&& LOCATION_FILE (decl_sloc (n, false)) == source_file)
728       to_dump[i++] = n;
729 }
730 
731 /* Call back for walk_tree to clear the TREE_VISITED flag of TP.  */
732 
733 static tree
734 unmark_visited_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
735 		  void *data ATTRIBUTE_UNUSED)
736 {
737   if (TREE_VISITED (*tp))
738     TREE_VISITED (*tp) = 0;
739   else
740     *walk_subtrees = 0;
741 
742   return NULL_TREE;
743 }
744 
745 /* Print a COMMENT to the output stream PP.  */
746 
747 static void
748 print_comment (pretty_printer *pp, const char *comment)
749 {
750   int len = strlen (comment);
751   char *str = XALLOCAVEC (char, len + 1);
752   char *tok;
753   bool extra_newline = false;
754 
755   memcpy (str, comment, len + 1);
756 
757   /* Trim C/C++ comment indicators.  */
758   if (str[len - 2] == '*' && str[len - 1] == '/')
759     {
760       str[len - 2] = ' ';
761       str[len - 1] = '\0';
762     }
763   str += 2;
764 
765   tok = strtok (str, "\n");
766   while (tok) {
767     pp_string (pp, "  --");
768     pp_string (pp, tok);
769     pp_newline (pp);
770     tok = strtok (NULL, "\n");
771 
772     /* Leave a blank line after multi-line comments.  */
773     if (tok)
774       extra_newline = true;
775   }
776 
777   if (extra_newline)
778     pp_newline (pp);
779 }
780 
781 /* Dump nodes into PP relevant to SOURCE_FILE, as collected by previous calls
782    to collect_ada_nodes.  */
783 
784 static void
785 dump_ada_nodes (pretty_printer *pp, const char *source_file)
786 {
787   int i, j;
788   cpp_comment_table *comments;
789 
790   /* Sort the table of declarations to dump by sloc.  */
791   qsort (to_dump, to_dump_count, sizeof (tree), compare_node);
792 
793   /* Fetch the table of comments.  */
794   comments = cpp_get_comments (parse_in);
795 
796   /* Sort the comments table by sloc.  */
797   if (comments->count > 1)
798     qsort (comments->entries, comments->count, sizeof (cpp_comment),
799 	   compare_comment);
800 
801   /* Interleave comments and declarations in line number order.  */
802   i = j = 0;
803   do
804     {
805       /* Advance j until comment j is in this file.  */
806       while (j != comments->count
807 	     && LOCATION_FILE (comments->entries[j].sloc) != source_file)
808 	j++;
809 
810       /* Advance j until comment j is not a duplicate.  */
811       while (j < comments->count - 1
812 	     && !compare_comment (&comments->entries[j],
813 				  &comments->entries[j + 1]))
814 	j++;
815 
816       /* Write decls until decl i collates after comment j.  */
817       while (i != to_dump_count)
818 	{
819 	  if (j == comments->count
820 	      || LOCATION_LINE (decl_sloc (to_dump[i], false))
821 	      <  LOCATION_LINE (comments->entries[j].sloc))
822 	    {
823 	      current_source_file = source_file;
824 
825 	      if (dump_ada_declaration (pp, to_dump[i++], NULL_TREE,
826 					 INDENT_INCR))
827 		{
828 		  pp_newline (pp);
829 		  pp_newline (pp);
830 		}
831 	    }
832 	  else
833 	    break;
834 	}
835 
836       /* Write comment j, if there is one.  */
837       if (j != comments->count)
838 	print_comment (pp, comments->entries[j++].comment);
839 
840     } while (i != to_dump_count || j != comments->count);
841 
842   /* Clear the TREE_VISITED flag over each subtree we've dumped.  */
843   for (i = 0; i < to_dump_count; i++)
844     walk_tree (&to_dump[i], unmark_visited_r, NULL, NULL);
845 
846   /* Finalize the to_dump table.  */
847   if (to_dump)
848     {
849       free (to_dump);
850       to_dump = NULL;
851       to_dump_count = 0;
852     }
853 }
854 
855 /* Dump a newline and indent BUFFER by SPC chars.  */
856 
857 static void
858 newline_and_indent (pretty_printer *buffer, int spc)
859 {
860   pp_newline (buffer);
861   INDENT (spc);
862 }
863 
864 struct with { char *s; const char *in_file; bool limited; };
865 static struct with *withs = NULL;
866 static int withs_max = 4096;
867 static int with_len = 0;
868 
869 /* Record a "with" clause on package S (a limited with if LIMITED_ACCESS is
870    true), if not already done.  */
871 
872 static void
873 append_withs (const char *s, bool limited_access)
874 {
875   int i;
876 
877   if (withs == NULL)
878     withs = XNEWVEC (struct with, withs_max);
879 
880   if (with_len == withs_max)
881     {
882       withs_max *= 2;
883       withs = XRESIZEVEC (struct with, withs, withs_max);
884     }
885 
886   for (i = 0; i < with_len; i++)
887     if (!strcmp (s, withs[i].s)
888 	&& current_source_file == withs[i].in_file)
889       {
890 	withs[i].limited &= limited_access;
891 	return;
892       }
893 
894   withs[with_len].s = xstrdup (s);
895   withs[with_len].in_file = current_source_file;
896   withs[with_len].limited = limited_access;
897   with_len++;
898 }
899 
900 /* Reset "with" clauses.  */
901 
902 static void
903 reset_ada_withs (void)
904 {
905   int i;
906 
907   if (!withs)
908     return;
909 
910   for (i = 0; i < with_len; i++)
911     free (withs[i].s);
912   free (withs);
913   withs = NULL;
914   withs_max = 4096;
915   with_len = 0;
916 }
917 
918 /* Dump "with" clauses in F.  */
919 
920 static void
921 dump_ada_withs (FILE *f)
922 {
923   int i;
924 
925   fprintf (f, "with Interfaces.C; use Interfaces.C;\n");
926 
927   for (i = 0; i < with_len; i++)
928     fprintf
929       (f, "%swith %s;\n", withs[i].limited ? "limited " : "", withs[i].s);
930 }
931 
932 /* Return suitable Ada package name from FILE.  */
933 
934 static char *
935 get_ada_package (const char *file)
936 {
937   const char *base;
938   char *res;
939   const char *s;
940   int i;
941   size_t plen;
942 
943   s = strstr (file, "/include/");
944   if (s)
945     base = s + 9;
946   else
947     base = lbasename (file);
948 
949   if (ada_specs_parent == NULL)
950     plen = 0;
951   else
952     plen = strlen (ada_specs_parent) + 1;
953 
954   res = XNEWVEC (char, plen + strlen (base) + 1);
955   if (ada_specs_parent != NULL) {
956     strcpy (res, ada_specs_parent);
957     res[plen - 1] = '.';
958   }
959 
960   for (i = plen; *base; base++, i++)
961     switch (*base)
962       {
963 	case '+':
964 	  res[i] = 'p';
965 	  break;
966 
967 	case '.':
968 	case '-':
969 	case '_':
970 	case '/':
971 	case '\\':
972 	  res[i] = (i == 0 || res[i - 1] == '.' || res[i - 1] == '_') ? 'u' : '_';
973 	  break;
974 
975 	default:
976 	  res[i] = *base;
977 	  break;
978       }
979   res[i] = '\0';
980 
981   return res;
982 }
983 
984 static const char *ada_reserved[] = {
985   "abort", "abs", "abstract", "accept", "access", "aliased", "all", "and",
986   "array", "at", "begin", "body", "case", "constant", "declare", "delay",
987   "delta", "digits", "do", "else", "elsif", "end", "entry", "exception",
988   "exit", "for", "function", "generic", "goto", "if", "in", "interface", "is",
989   "limited", "loop", "mod", "new", "not", "null", "others", "out", "of", "or",
990   "overriding", "package", "pragma", "private", "procedure", "protected",
991   "raise", "range", "record", "rem", "renames", "requeue", "return", "reverse",
992   "select", "separate", "subtype", "synchronized", "tagged", "task",
993   "terminate", "then", "type", "until", "use", "when", "while", "with", "xor",
994   NULL};
995 
996 /* ??? would be nice to specify this list via a config file, so that users
997    can create their own dictionary of conflicts.  */
998 static const char *c_duplicates[] = {
999   /* system will cause troubles with System.Address.  */
1000   "system",
1001 
1002   /* The following values have other definitions with same name/other
1003      casing.  */
1004   "funmap",
1005   "rl_vi_fWord",
1006   "rl_vi_bWord",
1007   "rl_vi_eWord",
1008   "rl_readline_version",
1009   "_Vx_ushort",
1010   "USHORT",
1011   "XLookupKeysym",
1012   NULL};
1013 
1014 /* Return a declaration tree corresponding to TYPE.  */
1015 
1016 static tree
1017 get_underlying_decl (tree type)
1018 {
1019   if (!type)
1020     return NULL_TREE;
1021 
1022   /* type is a declaration.  */
1023   if (DECL_P (type))
1024     return type;
1025 
1026   /* type is a typedef.  */
1027   if (TYPE_P (type) && TYPE_NAME (type) && DECL_P (TYPE_NAME (type)))
1028     return TYPE_NAME (type);
1029 
1030   /* TYPE_STUB_DECL has been set for type.  */
1031   if (TYPE_P (type) && TYPE_STUB_DECL (type))
1032     return TYPE_STUB_DECL (type);
1033 
1034   return NULL_TREE;
1035 }
1036 
1037 /* Return whether TYPE has static fields.  */
1038 
1039 static bool
1040 has_static_fields (const_tree type)
1041 {
1042   if (!type || !RECORD_OR_UNION_TYPE_P (type))
1043     return false;
1044 
1045   for (tree fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld))
1046     if (TREE_CODE (fld) == VAR_DECL && DECL_NAME (fld))
1047       return true;
1048 
1049   return false;
1050 }
1051 
1052 /* Return whether TYPE corresponds to an Ada tagged type (has a dispatch
1053    table).  */
1054 
1055 static bool
1056 is_tagged_type (const_tree type)
1057 {
1058   if (!type || !RECORD_OR_UNION_TYPE_P (type))
1059     return false;
1060 
1061   for (tree fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld))
1062     if (TREE_CODE (fld) == FUNCTION_DECL && DECL_VINDEX (fld))
1063       return true;
1064 
1065   return false;
1066 }
1067 
1068 /* Return whether TYPE has non-trivial methods, i.e. methods that do something
1069    for the objects of TYPE.  In C++, all classes have implicit special methods,
1070    e.g. constructors and destructors, but they can be trivial if the type is
1071    sufficiently simple.  */
1072 
1073 static bool
1074 has_nontrivial_methods (tree type)
1075 {
1076   if (!type || !RECORD_OR_UNION_TYPE_P (type))
1077     return false;
1078 
1079   /* Only C++ types can have methods.  */
1080   if (!cpp_check)
1081     return false;
1082 
1083   /* A non-trivial type has non-trivial special methods.  */
1084   if (!cpp_check (type, IS_TRIVIAL))
1085     return true;
1086 
1087   /* If there are user-defined methods, they are deemed non-trivial.  */
1088   for (tree fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
1089     if (TREE_CODE (fld) == FUNCTION_DECL && !DECL_ARTIFICIAL (fld))
1090       return true;
1091 
1092   return false;
1093 }
1094 
1095 #define INDEX_LENGTH 8
1096 
1097 /* Generate a legal Ada name from a C/C++ NAME and return a malloc'ed string.
1098    INDEX, if non-zero, is used to disambiguate overloaded names.  SPACE_FOUND,
1099    if not NULL, is used to indicate whether a space was found in NAME.  */
1100 
1101 static char *
1102 to_ada_name (const char *name, unsigned int index, bool *space_found)
1103 {
1104   const char **names;
1105   const int len = strlen (name);
1106   int j, len2 = 0;
1107   bool found = false;
1108   char *s = XNEWVEC (char, len * 2 + 5 + (index ? INDEX_LENGTH : 0));
1109   char c;
1110 
1111   if (space_found)
1112     *space_found = false;
1113 
1114   /* Add "c_" prefix if name is an Ada reserved word.  */
1115   for (names = ada_reserved; *names; names++)
1116     if (!strcasecmp (name, *names))
1117       {
1118 	s[len2++] = 'c';
1119 	s[len2++] = '_';
1120 	found = true;
1121 	break;
1122       }
1123 
1124   if (!found)
1125     /* Add "c_" prefix if name is a potential case sensitive duplicate.  */
1126     for (names = c_duplicates; *names; names++)
1127       if (!strcmp (name, *names))
1128 	{
1129 	  s[len2++] = 'c';
1130 	  s[len2++] = '_';
1131 	  found = true;
1132 	  break;
1133 	}
1134 
1135   for (j = 0; name[j] == '_'; j++)
1136     s[len2++] = 'u';
1137 
1138   if (j > 0)
1139     s[len2++] = '_';
1140   else if (*name == '.' || *name == '$')
1141     {
1142       s[0] = 'a';
1143       s[1] = 'n';
1144       s[2] = 'o';
1145       s[3] = 'n';
1146       len2 = 4;
1147       j++;
1148     }
1149 
1150   /* Replace unsuitable characters for Ada identifiers.  */
1151   for (; j < len; j++)
1152     switch (name[j])
1153       {
1154 	case ' ':
1155 	  if (space_found)
1156 	    *space_found = true;
1157 	  s[len2++] = '_';
1158 	  break;
1159 
1160 	/* ??? missing some C++ operators.  */
1161 	case '=':
1162 	  s[len2++] = '_';
1163 
1164 	  if (name[j + 1] == '=')
1165 	    {
1166 	      j++;
1167 	      s[len2++] = 'e';
1168 	      s[len2++] = 'q';
1169 	    }
1170 	  else
1171 	    {
1172 	      s[len2++] = 'a';
1173 	      s[len2++] = 's';
1174 	    }
1175 	  break;
1176 
1177 	case '!':
1178 	  s[len2++] = '_';
1179 	  if (name[j + 1] == '=')
1180 	    {
1181 	      j++;
1182 	      s[len2++] = 'n';
1183 	      s[len2++] = 'e';
1184 	    }
1185 	  break;
1186 
1187 	case '~':
1188 	  s[len2++] = '_';
1189 	  s[len2++] = 't';
1190 	  s[len2++] = 'i';
1191 	  break;
1192 
1193 	case '&':
1194 	case '|':
1195 	case '^':
1196 	  s[len2++] = '_';
1197 	  s[len2++] = name[j] == '&' ? 'a' : name[j] == '|' ? 'o' : 'x';
1198 
1199 	  if (name[j + 1] == '=')
1200 	    {
1201 	      j++;
1202 	      s[len2++] = 'e';
1203 	    }
1204 	  break;
1205 
1206 	case '+':
1207 	case '-':
1208 	case '*':
1209 	case '/':
1210 	case '(':
1211 	case '[':
1212 	  if (s[len2 - 1] != '_')
1213 	    s[len2++] = '_';
1214 
1215 	  switch (name[j + 1]) {
1216 	    case '\0':
1217 	      j++;
1218 	      switch (name[j - 1]) {
1219 		case '+': s[len2++] = 'p'; break;  /* + */
1220 		case '-': s[len2++] = 'm'; break;  /* - */
1221 		case '*': s[len2++] = 't'; break;  /* * */
1222 		case '/': s[len2++] = 'd'; break;  /* / */
1223 	      }
1224 	      break;
1225 
1226 	    case '=':
1227 	      j++;
1228 	      switch (name[j - 1]) {
1229 		case '+': s[len2++] = 'p'; break;  /* += */
1230 		case '-': s[len2++] = 'm'; break;  /* -= */
1231 		case '*': s[len2++] = 't'; break;  /* *= */
1232 		case '/': s[len2++] = 'd'; break;  /* /= */
1233 	      }
1234 	      s[len2++] = 'a';
1235 	      break;
1236 
1237 	    case '-':  /* -- */
1238 	      j++;
1239 	      s[len2++] = 'm';
1240 	      s[len2++] = 'm';
1241 	      break;
1242 
1243 	    case '+':  /* ++ */
1244 	      j++;
1245 	      s[len2++] = 'p';
1246 	      s[len2++] = 'p';
1247 	      break;
1248 
1249 	    case ')':  /* () */
1250 	      j++;
1251 	      s[len2++] = 'o';
1252 	      s[len2++] = 'p';
1253 	      break;
1254 
1255 	    case ']':  /* [] */
1256 	      j++;
1257 	      s[len2++] = 'o';
1258 	      s[len2++] = 'b';
1259 	      break;
1260 	  }
1261 
1262 	  break;
1263 
1264 	case '<':
1265 	case '>':
1266 	  c = name[j] == '<' ? 'l' : 'g';
1267 	  s[len2++] = '_';
1268 
1269 	  switch (name[j + 1]) {
1270 	    case '\0':
1271 	      s[len2++] = c;
1272 	      s[len2++] = 't';
1273 	      break;
1274 	    case '=':
1275 	      j++;
1276 	      s[len2++] = c;
1277 	      s[len2++] = 'e';
1278 	      break;
1279 	    case '>':
1280 	      j++;
1281 	      s[len2++] = 's';
1282 	      s[len2++] = 'r';
1283 	      break;
1284 	    case '<':
1285 	      j++;
1286 	      s[len2++] = 's';
1287 	      s[len2++] = 'l';
1288 	      break;
1289 	    default:
1290 	      break;
1291 	  }
1292 	  break;
1293 
1294 	case '_':
1295 	  if (len2 && s[len2 - 1] == '_')
1296 	    s[len2++] = 'u';
1297 	  /* fall through */
1298 
1299 	default:
1300 	  s[len2++] = name[j];
1301       }
1302 
1303   if (s[len2 - 1] == '_')
1304     s[len2++] = 'u';
1305 
1306   if (index)
1307     snprintf (&s[len2], INDEX_LENGTH, "_u_%d", index + 1);
1308   else
1309     s[len2] = '\0';
1310 
1311   return s;
1312 }
1313 
1314 /* Return true if DECL refers to a C++ class type for which a
1315    separate enclosing package has been or should be generated.  */
1316 
1317 static bool
1318 separate_class_package (tree decl)
1319 {
1320   tree type = TREE_TYPE (decl);
1321   return has_nontrivial_methods (type) || has_static_fields (type);
1322 }
1323 
1324 static bool package_prefix = true;
1325 
1326 /* Dump in BUFFER the name of an identifier NODE of type TYPE, following Ada
1327    syntax.  INDEX, if non-zero, is used to disambiguate overloaded names.
1328    LIMITED_ACCESS indicates whether NODE can be accessed via a limited
1329    'with' clause rather than a regular 'with' clause.  */
1330 
1331 static void
1332 pp_ada_tree_identifier (pretty_printer *buffer, tree node, tree type,
1333 			unsigned int index, bool limited_access)
1334 {
1335   const char *name = IDENTIFIER_POINTER (node);
1336   bool space_found = false;
1337   char *s = to_ada_name (name, index, &space_found);
1338   tree decl = get_underlying_decl (type);
1339 
1340   /* If the entity comes from another file, generate a package prefix.  */
1341   if (decl)
1342     {
1343       expanded_location xloc = expand_location (decl_sloc (decl, false));
1344 
1345       if (xloc.file && xloc.line)
1346 	{
1347 	  if (xloc.file != current_source_file)
1348 	    {
1349 	      switch (TREE_CODE (type))
1350 		{
1351 		  case ENUMERAL_TYPE:
1352 		  case INTEGER_TYPE:
1353 		  case REAL_TYPE:
1354 		  case FIXED_POINT_TYPE:
1355 		  case BOOLEAN_TYPE:
1356 		  case REFERENCE_TYPE:
1357 		  case POINTER_TYPE:
1358 		  case ARRAY_TYPE:
1359 		  case RECORD_TYPE:
1360 		  case UNION_TYPE:
1361 		  case TYPE_DECL:
1362 		    if (package_prefix)
1363 		      {
1364 			char *s1 = get_ada_package (xloc.file);
1365 			append_withs (s1, limited_access);
1366 			pp_string (buffer, s1);
1367 			pp_dot (buffer);
1368 			free (s1);
1369 		      }
1370 		    break;
1371 		  default:
1372 		    break;
1373 		}
1374 
1375 	      /* Generate the additional package prefix for C++ classes.  */
1376 	      if (separate_class_package (decl))
1377 		{
1378 		  pp_string (buffer, "Class_");
1379 		  pp_string (buffer, s);
1380 		  pp_dot (buffer);
1381 		}
1382 	     }
1383 	}
1384     }
1385 
1386   if (space_found)
1387     if (!strcmp (s, "short_int"))
1388       pp_string (buffer, "short");
1389     else if (!strcmp (s, "short_unsigned_int"))
1390       pp_string (buffer, "unsigned_short");
1391     else if (!strcmp (s, "unsigned_int"))
1392       pp_string (buffer, "unsigned");
1393     else if (!strcmp (s, "long_int"))
1394       pp_string (buffer, "long");
1395     else if (!strcmp (s, "long_unsigned_int"))
1396       pp_string (buffer, "unsigned_long");
1397     else if (!strcmp (s, "long_long_int"))
1398       pp_string (buffer, "Long_Long_Integer");
1399     else if (!strcmp (s, "long_long_unsigned_int"))
1400       {
1401 	if (package_prefix)
1402 	  {
1403 	    append_withs ("Interfaces.C.Extensions", false);
1404 	    pp_string (buffer, "Extensions.unsigned_long_long");
1405 	  }
1406 	else
1407 	  pp_string (buffer, "unsigned_long_long");
1408       }
1409     else
1410       pp_string(buffer, s);
1411   else
1412     if (!strcmp (s, "u_Bool") || !strcmp (s, "bool"))
1413       {
1414 	if (package_prefix)
1415 	  {
1416 	    append_withs ("Interfaces.C.Extensions", false);
1417 	    pp_string (buffer, "Extensions.bool");
1418 	  }
1419 	else
1420 	  pp_string (buffer, "bool");
1421       }
1422     else
1423       pp_string(buffer, s);
1424 
1425   free (s);
1426 }
1427 
1428 /* Dump in BUFFER the assembly name of T.  */
1429 
1430 static void
1431 pp_asm_name (pretty_printer *buffer, tree t)
1432 {
1433   tree name = DECL_ASSEMBLER_NAME (t);
1434   char *ada_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (name) + 1), *s;
1435   const char *ident = IDENTIFIER_POINTER (name);
1436 
1437   for (s = ada_name; *ident; ident++)
1438     {
1439       if (*ident == ' ')
1440 	break;
1441       else if (*ident != '*')
1442 	*s++ = *ident;
1443     }
1444 
1445   *s = '\0';
1446   pp_string (buffer, ada_name);
1447 }
1448 
1449 /* Hash table of overloaded names associating identifier nodes with DECL_UIDs.
1450    It is needed in Ada 2005 because we can have at most one import directive
1451    per subprogram name in a given scope, so we have to mangle the subprogram
1452    names on the Ada side to import overloaded subprograms from C++.  */
1453 
1454 struct overloaded_name_hash {
1455   hashval_t hash;
1456   tree name;
1457   tree context;
1458   vec<unsigned int> homonyms;
1459 };
1460 
1461 struct overloaded_name_hasher : delete_ptr_hash<overloaded_name_hash>
1462 {
1463   static inline hashval_t hash (overloaded_name_hash *t)
1464     { return t->hash; }
1465   static inline bool equal (overloaded_name_hash *a, overloaded_name_hash *b)
1466     { return a->name == b->name && a->context == b->context; }
1467 };
1468 
1469 static hash_table<overloaded_name_hasher> *overloaded_names;
1470 
1471 /* Compute the overloading index of function DECL in its context.  */
1472 
1473 static unsigned int
1474 compute_overloading_index (tree decl)
1475 {
1476   const hashval_t hashcode
1477     = iterative_hash_hashval_t (htab_hash_pointer (DECL_NAME (decl)),
1478 			        htab_hash_pointer (DECL_CONTEXT (decl)));
1479   struct overloaded_name_hash in, *h, **slot;
1480   unsigned int index, *iter;
1481 
1482   if (!overloaded_names)
1483     overloaded_names = new hash_table<overloaded_name_hasher> (512);
1484 
1485   /* Look up the list of homonyms in the table.  */
1486   in.hash = hashcode;
1487   in.name = DECL_NAME (decl);
1488   in.context = DECL_CONTEXT (decl);
1489   slot = overloaded_names->find_slot_with_hash (&in, hashcode, INSERT);
1490   if (*slot)
1491     h = *slot;
1492   else
1493     {
1494       h = new overloaded_name_hash;
1495       h->hash = hashcode;
1496       h->name = DECL_NAME (decl);
1497       h->context = DECL_CONTEXT (decl);
1498       h->homonyms.create (0);
1499       *slot = h;
1500     }
1501 
1502   /* Look up the function in the list of homonyms.  */
1503   FOR_EACH_VEC_ELT (h->homonyms, index, iter)
1504     if (*iter == DECL_UID (decl))
1505       break;
1506 
1507   /* If it is not present, push it onto the list.  */
1508   if (!iter)
1509     h->homonyms.safe_push (DECL_UID (decl));
1510 
1511   return index;
1512 }
1513 
1514 /* Dump in BUFFER the name of a DECL node if set, in Ada syntax.
1515    LIMITED_ACCESS indicates whether NODE can be accessed via a
1516    limited 'with' clause rather than a regular 'with' clause.  */
1517 
1518 static void
1519 dump_ada_decl_name (pretty_printer *buffer, tree decl, bool limited_access)
1520 {
1521   if (DECL_NAME (decl))
1522     {
1523       const unsigned int index
1524 	= (TREE_CODE (decl) == FUNCTION_DECL && cpp_check)
1525 	  ? compute_overloading_index (decl) : 0;
1526       pp_ada_tree_identifier (buffer, DECL_NAME (decl), decl, index,
1527 			      limited_access);
1528     }
1529   else
1530     {
1531       tree type_name = TYPE_NAME (TREE_TYPE (decl));
1532 
1533       if (!type_name)
1534 	{
1535 	  pp_string (buffer, "anon");
1536 	  if (TREE_CODE (decl) == FIELD_DECL)
1537 	    pp_scalar (buffer, "%d", DECL_UID (decl));
1538 	  else
1539 	    pp_scalar (buffer, "%d", TYPE_UID (TREE_TYPE (decl)));
1540 	}
1541       else if (TREE_CODE (type_name) == IDENTIFIER_NODE)
1542 	pp_ada_tree_identifier (buffer, type_name, decl, 0, limited_access);
1543     }
1544 }
1545 
1546 /* Dump in BUFFER a name based on both T1 and T2 followed by a suffix.  */
1547 
1548 static void
1549 dump_ada_double_name (pretty_printer *buffer, tree t1, tree t2)
1550 {
1551   if (DECL_NAME (t1))
1552     pp_ada_tree_identifier (buffer, DECL_NAME (t1), t1, 0, false);
1553   else
1554     {
1555       pp_string (buffer, "anon");
1556       pp_scalar (buffer, "%d", TYPE_UID (TREE_TYPE (t1)));
1557     }
1558 
1559   pp_underscore (buffer);
1560 
1561   if (DECL_NAME (t2))
1562     pp_ada_tree_identifier (buffer, DECL_NAME (t2), t2, 0, false);
1563   else
1564     {
1565       pp_string (buffer, "anon");
1566       pp_scalar (buffer, "%d", TYPE_UID (TREE_TYPE (t2)));
1567     }
1568 
1569   switch (TREE_CODE (TREE_TYPE (t2)))
1570     {
1571     case ARRAY_TYPE:
1572       pp_string (buffer, "_array");
1573       break;
1574     case ENUMERAL_TYPE:
1575       pp_string (buffer, "_enum");
1576       break;
1577     case RECORD_TYPE:
1578       pp_string (buffer, "_struct");
1579       break;
1580     case UNION_TYPE:
1581       pp_string (buffer, "_union");
1582       break;
1583     default:
1584       pp_string (buffer, "_unknown");
1585       break;
1586     }
1587 }
1588 
1589 /* Dump in BUFFER pragma Import C/CPP on a given node T.  */
1590 
1591 static void
1592 dump_ada_import (pretty_printer *buffer, tree t)
1593 {
1594   const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t));
1595   const bool is_stdcall
1596     = TREE_CODE (t) == FUNCTION_DECL
1597       && lookup_attribute ("stdcall", TYPE_ATTRIBUTES (TREE_TYPE (t)));
1598 
1599   if (is_stdcall)
1600     pp_string (buffer, "pragma Import (Stdcall, ");
1601   else if (name[0] == '_' && name[1] == 'Z')
1602     pp_string (buffer, "pragma Import (CPP, ");
1603   else
1604     pp_string (buffer, "pragma Import (C, ");
1605 
1606   dump_ada_decl_name (buffer, t, false);
1607   pp_string (buffer, ", \"");
1608 
1609   if (is_stdcall)
1610     pp_string (buffer, IDENTIFIER_POINTER (DECL_NAME (t)));
1611   else
1612     pp_asm_name (buffer, t);
1613 
1614   pp_string (buffer, "\");");
1615 }
1616 
1617 /* Check whether T and its type have different names, and append "the_"
1618    otherwise in BUFFER.  */
1619 
1620 static void
1621 check_name (pretty_printer *buffer, tree t)
1622 {
1623   const char *s;
1624   tree tmp = TREE_TYPE (t);
1625 
1626   while (TREE_CODE (tmp) == POINTER_TYPE && !TYPE_NAME (tmp))
1627     tmp = TREE_TYPE (tmp);
1628 
1629   if (TREE_CODE (tmp) != FUNCTION_TYPE)
1630     {
1631       if (TREE_CODE (tmp) == IDENTIFIER_NODE)
1632 	s = IDENTIFIER_POINTER (tmp);
1633       else if (!TYPE_NAME (tmp))
1634 	s = "";
1635       else if (TREE_CODE (TYPE_NAME (tmp)) == IDENTIFIER_NODE)
1636 	s = IDENTIFIER_POINTER (TYPE_NAME (tmp));
1637       else
1638 	s = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (tmp)));
1639 
1640       if (!strcasecmp (IDENTIFIER_POINTER (DECL_NAME (t)), s))
1641 	pp_string (buffer, "the_");
1642     }
1643 }
1644 
1645 /* Dump in BUFFER a function declaration FUNC in Ada syntax.
1646    IS_METHOD indicates whether FUNC is a C++ method.
1647    IS_CONSTRUCTOR whether FUNC is a C++ constructor.
1648    IS_DESTRUCTOR whether FUNC is a C++ destructor.
1649    SPC is the current indentation level.  */
1650 
1651 static void
1652 dump_ada_function_declaration (pretty_printer *buffer, tree func,
1653 			       bool is_method, bool is_constructor,
1654 			       bool is_destructor, int spc)
1655 {
1656   tree arg;
1657   const tree node = TREE_TYPE (func);
1658   char buf[17];
1659   int num = 0, num_args = 0, have_args = true, have_ellipsis = false;
1660 
1661   /* Compute number of arguments.  */
1662   arg = TYPE_ARG_TYPES (node);
1663 
1664   if (arg)
1665     {
1666       while (TREE_CHAIN (arg) && arg != error_mark_node)
1667 	{
1668 	  num_args++;
1669 	  arg = TREE_CHAIN (arg);
1670 	}
1671 
1672       if (TREE_CODE (TREE_VALUE (arg)) != VOID_TYPE)
1673 	{
1674 	  num_args++;
1675 	  have_ellipsis = true;
1676 	}
1677     }
1678 
1679   if (is_constructor)
1680     num_args--;
1681 
1682   if (is_destructor)
1683     num_args = 1;
1684 
1685   if (num_args > 2)
1686     newline_and_indent (buffer, spc + 1);
1687 
1688   if (num_args > 0)
1689     {
1690       pp_space (buffer);
1691       pp_left_paren (buffer);
1692     }
1693 
1694   if (TREE_CODE (func) == FUNCTION_DECL)
1695     arg = DECL_ARGUMENTS (func);
1696   else
1697     arg = NULL_TREE;
1698 
1699   if (arg == NULL_TREE)
1700     {
1701       have_args = false;
1702       arg = TYPE_ARG_TYPES (node);
1703 
1704       if (arg && TREE_CODE (TREE_VALUE (arg)) == VOID_TYPE)
1705 	arg = NULL_TREE;
1706     }
1707 
1708   if (is_constructor)
1709     arg = TREE_CHAIN (arg);
1710 
1711   /* Print the argument names (if available) & types.  */
1712 
1713   for (num = 1; num <= num_args; num++)
1714     {
1715       if (have_args)
1716 	{
1717 	  if (DECL_NAME (arg))
1718 	    {
1719 	      check_name (buffer, arg);
1720 	      pp_ada_tree_identifier (buffer, DECL_NAME (arg), NULL_TREE, 0,
1721 				      false);
1722 	      pp_string (buffer, " : ");
1723 	    }
1724 	  else
1725 	    {
1726 	      sprintf (buf, "arg%d : ", num);
1727 	      pp_string (buffer, buf);
1728 	    }
1729 
1730 	  dump_ada_node (buffer, TREE_TYPE (arg), node, spc, false, true);
1731 	}
1732       else
1733 	{
1734 	  sprintf (buf, "arg%d : ", num);
1735 	  pp_string (buffer, buf);
1736 	  dump_ada_node (buffer, TREE_VALUE (arg), node, spc, false, true);
1737 	}
1738 
1739       /* If the type is a pointer to a tagged type, we need to differentiate
1740 	 virtual methods from the rest (non-virtual methods, static member
1741 	 or regular functions) and import only them as primitive operations,
1742 	 because they make up the virtual table which is mirrored on the Ada
1743 	 side by the dispatch table.  So we add 'Class to the type of every
1744 	 parameter that is not the first one of a method which either has a
1745 	 slot in the virtual table or is a constructor.  */
1746       if (TREE_TYPE (arg)
1747 	  && POINTER_TYPE_P (TREE_TYPE (arg))
1748 	  && is_tagged_type (TREE_TYPE (TREE_TYPE (arg)))
1749 	  && !(num == 1 && is_method && (DECL_VINDEX (func) || is_constructor)))
1750 	pp_string (buffer, "'Class");
1751 
1752       arg = TREE_CHAIN (arg);
1753 
1754       if (num < num_args)
1755 	{
1756 	  pp_semicolon (buffer);
1757 
1758 	  if (num_args > 2)
1759 	    newline_and_indent (buffer, spc + INDENT_INCR);
1760 	  else
1761 	    pp_space (buffer);
1762 	}
1763     }
1764 
1765   if (have_ellipsis)
1766     {
1767       pp_string (buffer, "  -- , ...");
1768       newline_and_indent (buffer, spc + INDENT_INCR);
1769     }
1770 
1771   if (num_args > 0)
1772     pp_right_paren (buffer);
1773 
1774   if (is_constructor || !VOID_TYPE_P (TREE_TYPE (node)))
1775     {
1776       pp_string (buffer, " return ");
1777       tree type = is_constructor ? DECL_CONTEXT (func) : TREE_TYPE (node);
1778       dump_ada_node (buffer, type, type, spc, false, true);
1779     }
1780 }
1781 
1782 /* Dump in BUFFER all the domains associated with an array NODE,
1783    in Ada syntax.  SPC is the current indentation level.  */
1784 
1785 static void
1786 dump_ada_array_domains (pretty_printer *buffer, tree node, int spc)
1787 {
1788   int first = 1;
1789   pp_left_paren (buffer);
1790 
1791   for (; TREE_CODE (node) == ARRAY_TYPE; node = TREE_TYPE (node))
1792     {
1793       tree domain = TYPE_DOMAIN (node);
1794 
1795       if (domain)
1796 	{
1797 	  tree min = TYPE_MIN_VALUE (domain);
1798 	  tree max = TYPE_MAX_VALUE (domain);
1799 
1800 	  if (!first)
1801 	    pp_string (buffer, ", ");
1802 	  first = 0;
1803 
1804 	  if (min)
1805 	    dump_ada_node (buffer, min, NULL_TREE, spc, false, true);
1806 	  pp_string (buffer, " .. ");
1807 
1808 	  /* If the upper bound is zero, gcc may generate a NULL_TREE
1809 	     for TYPE_MAX_VALUE rather than an integer_cst.  */
1810 	  if (max)
1811 	    dump_ada_node (buffer, max, NULL_TREE, spc, false, true);
1812 	  else
1813 	    pp_string (buffer, "0");
1814 	}
1815       else
1816 	pp_string (buffer, "size_t");
1817     }
1818   pp_right_paren (buffer);
1819 }
1820 
1821 /* Dump in BUFFER file:line information related to NODE.  */
1822 
1823 static void
1824 dump_sloc (pretty_printer *buffer, tree node)
1825 {
1826   expanded_location xloc;
1827 
1828   xloc.file = NULL;
1829 
1830   if (DECL_P (node))
1831     xloc = expand_location (DECL_SOURCE_LOCATION (node));
1832   else if (EXPR_HAS_LOCATION (node))
1833     xloc = expand_location (EXPR_LOCATION (node));
1834 
1835   if (xloc.file)
1836     {
1837       pp_string (buffer, xloc.file);
1838       pp_colon (buffer);
1839       pp_decimal_int (buffer, xloc.line);
1840     }
1841 }
1842 
1843 /* Return true if type T designates a 1-dimension array of "char".  */
1844 
1845 static bool
1846 is_char_array (tree t)
1847 {
1848   int num_dim = 0;
1849 
1850   while (TREE_CODE (t) == ARRAY_TYPE)
1851     {
1852       num_dim++;
1853       t = TREE_TYPE (t);
1854     }
1855 
1856   return num_dim == 1
1857 	 && TREE_CODE (t) == INTEGER_TYPE
1858 	 && id_equal (DECL_NAME (TYPE_NAME (t)), "char");
1859 }
1860 
1861 /* Dump in BUFFER an array type NODE of type TYPE in Ada syntax.  SPC is the
1862    indentation level.  */
1863 
1864 static void
1865 dump_ada_array_type (pretty_printer *buffer, tree node, tree type, int spc)
1866 {
1867   const bool char_array = is_char_array (node);
1868 
1869   /* Special case char arrays.  */
1870   if (char_array)
1871     pp_string (buffer, "Interfaces.C.char_array ");
1872   else
1873     pp_string (buffer, "array ");
1874 
1875   /* Print the dimensions.  */
1876   dump_ada_array_domains (buffer, node, spc);
1877 
1878   /* Print array's type.  */
1879   if (!char_array)
1880     {
1881       /* Retrieve the element type.  */
1882       tree tmp = node;
1883       while (TREE_CODE (tmp) == ARRAY_TYPE)
1884 	tmp = TREE_TYPE (tmp);
1885 
1886       pp_string (buffer, " of ");
1887 
1888       if (TREE_CODE (tmp) != POINTER_TYPE)
1889 	pp_string (buffer, "aliased ");
1890 
1891       if (TYPE_NAME (tmp) || !RECORD_OR_UNION_TYPE_P (tmp))
1892 	dump_ada_node (buffer, tmp, node, spc, false, true);
1893       else
1894 	dump_ada_double_name (buffer, type, get_underlying_decl (tmp));
1895     }
1896 }
1897 
1898 /* Dump in BUFFER type names associated with a template, each prepended with
1899    '_'.  TYPES is the TREE_PURPOSE of a DECL_TEMPLATE_INSTANTIATIONS.  SPC is
1900    the indentation level.  */
1901 
1902 static void
1903 dump_template_types (pretty_printer *buffer, tree types, int spc)
1904 {
1905   for (int i = 0; i < TREE_VEC_LENGTH (types); i++)
1906     {
1907       tree elem = TREE_VEC_ELT (types, i);
1908       pp_underscore (buffer);
1909 
1910       if (!dump_ada_node (buffer, elem, NULL_TREE, spc, false, true))
1911 	{
1912 	  pp_string (buffer, "unknown");
1913 	  pp_scalar (buffer, "%lu", (unsigned long) TREE_HASH (elem));
1914 	}
1915     }
1916 }
1917 
1918 /* Dump in BUFFER the contents of all class instantiations associated with
1919    a given template T.  SPC is the indentation level.  */
1920 
1921 static int
1922 dump_ada_template (pretty_printer *buffer, tree t, int spc)
1923 {
1924   /* DECL_SIZE_UNIT is DECL_TEMPLATE_INSTANTIATIONS in this context.  */
1925   tree inst = DECL_SIZE_UNIT (t);
1926   /* This emulates DECL_TEMPLATE_RESULT in this context.  */
1927   struct tree_template_decl {
1928     struct tree_decl_common common;
1929     tree arguments;
1930     tree result;
1931   };
1932   tree result = ((struct tree_template_decl *) t)->result;
1933   int num_inst = 0;
1934 
1935   /* Don't look at template declarations declaring something coming from
1936      another file.  This can occur for template friend declarations.  */
1937   if (LOCATION_FILE (decl_sloc (result, false))
1938       != LOCATION_FILE (decl_sloc (t, false)))
1939     return 0;
1940 
1941   for (; inst && inst != error_mark_node; inst = TREE_CHAIN (inst))
1942     {
1943       tree types = TREE_PURPOSE (inst);
1944       tree instance = TREE_VALUE (inst);
1945 
1946       if (TREE_VEC_LENGTH (types) == 0)
1947 	break;
1948 
1949       if (!RECORD_OR_UNION_TYPE_P (instance))
1950 	break;
1951 
1952       /* We are interested in concrete template instantiations only: skip
1953 	 partially specialized nodes.  */
1954       if (RECORD_OR_UNION_TYPE_P (instance)
1955 	  && cpp_check
1956 	  && cpp_check (instance, HAS_DEPENDENT_TEMPLATE_ARGS))
1957 	continue;
1958 
1959       num_inst++;
1960       INDENT (spc);
1961       pp_string (buffer, "package ");
1962       package_prefix = false;
1963       dump_ada_node (buffer, instance, t, spc, false, true);
1964       dump_template_types (buffer, types, spc);
1965       pp_string (buffer, " is");
1966       spc += INDENT_INCR;
1967       newline_and_indent (buffer, spc);
1968 
1969       TREE_VISITED (get_underlying_decl (instance)) = 1;
1970       pp_string (buffer, "type ");
1971       dump_ada_node (buffer, instance, t, spc, false, true);
1972       package_prefix = true;
1973 
1974       if (is_tagged_type (instance))
1975 	pp_string (buffer, " is tagged limited ");
1976       else
1977 	pp_string (buffer, " is limited ");
1978 
1979       dump_ada_node (buffer, instance, t, spc, false, false);
1980       pp_newline (buffer);
1981       spc -= INDENT_INCR;
1982       newline_and_indent (buffer, spc);
1983 
1984       pp_string (buffer, "end;");
1985       newline_and_indent (buffer, spc);
1986       pp_string (buffer, "use ");
1987       package_prefix = false;
1988       dump_ada_node (buffer, instance, t, spc, false, true);
1989       dump_template_types (buffer, types, spc);
1990       package_prefix = true;
1991       pp_semicolon (buffer);
1992       pp_newline (buffer);
1993       pp_newline (buffer);
1994     }
1995 
1996   return num_inst > 0;
1997 }
1998 
1999 /* Return true if NODE is a simple enum types, that can be mapped to an
2000    Ada enum type directly.  */
2001 
2002 static bool
2003 is_simple_enum (tree node)
2004 {
2005   HOST_WIDE_INT count = 0;
2006 
2007   for (tree value = TYPE_VALUES (node); value; value = TREE_CHAIN (value))
2008     {
2009       tree int_val = TREE_VALUE (value);
2010 
2011       if (TREE_CODE (int_val) != INTEGER_CST)
2012 	int_val = DECL_INITIAL (int_val);
2013 
2014       if (!tree_fits_shwi_p (int_val))
2015 	return false;
2016       else if (tree_to_shwi (int_val) != count)
2017 	return false;
2018 
2019       count++;
2020     }
2021 
2022   return true;
2023 }
2024 
2025 /* Dump in BUFFER an enumeral type NODE of type TYPE in Ada syntax.  SPC is
2026    the indentation level.  If DISPLAY_CONVENTION is true, also print the
2027    pragma Convention for NODE.  */
2028 
2029 static void
2030 dump_ada_enum_type (pretty_printer *buffer, tree node, tree type, int spc,
2031 		    bool display_convention)
2032 {
2033   if (is_simple_enum (node))
2034     {
2035       bool first = true;
2036       spc += INDENT_INCR;
2037       newline_and_indent (buffer, spc - 1);
2038       pp_left_paren (buffer);
2039       for (tree value = TYPE_VALUES (node); value; value = TREE_CHAIN (value))
2040 	{
2041 	  if (first)
2042 	    first = false;
2043 	  else
2044 	    {
2045 	      pp_comma (buffer);
2046 	      newline_and_indent (buffer, spc);
2047 	    }
2048 
2049 	  pp_ada_tree_identifier (buffer, TREE_PURPOSE (value), node, 0, false);
2050 	}
2051       pp_string (buffer, ");");
2052       spc -= INDENT_INCR;
2053       newline_and_indent (buffer, spc);
2054 
2055       if (display_convention)
2056 	{
2057 	  pp_string (buffer, "pragma Convention (C, ");
2058 	  dump_ada_node (buffer, DECL_NAME (type) ? type : TYPE_NAME (node),
2059 		     type, spc, false, true);
2060 	  pp_right_paren (buffer);
2061 	}
2062     }
2063   else
2064     {
2065       if (TYPE_UNSIGNED (node))
2066 	pp_string (buffer, "unsigned");
2067       else
2068 	pp_string (buffer, "int");
2069       for (tree value = TYPE_VALUES (node); value; value = TREE_CHAIN (value))
2070 	{
2071 	  pp_semicolon (buffer);
2072 	  newline_and_indent (buffer, spc);
2073 
2074 	  pp_ada_tree_identifier (buffer, TREE_PURPOSE (value), node, 0, false);
2075 	  pp_string (buffer, " : constant ");
2076 
2077 	  if (TYPE_UNSIGNED (node))
2078 	    pp_string (buffer, "unsigned");
2079 	  else
2080 	    pp_string (buffer, "int");
2081 
2082 	  pp_string (buffer, " := ");
2083 	  dump_ada_node (buffer,
2084 			 TREE_CODE (TREE_VALUE (value)) == INTEGER_CST
2085 			 ? TREE_VALUE (value)
2086 			 : DECL_INITIAL (TREE_VALUE (value)),
2087 			 node, spc, false, true);
2088 	}
2089     }
2090 }
2091 
2092 static bool bitfield_used = false;
2093 
2094 /* Recursively dump in BUFFER Ada declarations corresponding to NODE of type
2095    TYPE.  SPC is the indentation level.  LIMITED_ACCESS indicates whether NODE
2096    can be referenced via a "limited with" clause.  NAME_ONLY indicates whether
2097    we should only dump the name of NODE, instead of its full declaration.  */
2098 
2099 static int
2100 dump_ada_node (pretty_printer *buffer, tree node, tree type, int spc,
2101 	       bool limited_access, bool name_only)
2102 {
2103   if (node == NULL_TREE)
2104     return 0;
2105 
2106   switch (TREE_CODE (node))
2107     {
2108     case ERROR_MARK:
2109       pp_string (buffer, "<<< error >>>");
2110       return 0;
2111 
2112     case IDENTIFIER_NODE:
2113       pp_ada_tree_identifier (buffer, node, type, 0, limited_access);
2114       break;
2115 
2116     case TREE_LIST:
2117       pp_string (buffer, "--- unexpected node: TREE_LIST");
2118       return 0;
2119 
2120     case TREE_BINFO:
2121       dump_ada_node (buffer, BINFO_TYPE (node), type, spc, limited_access,
2122 		     name_only);
2123       return 0;
2124 
2125     case TREE_VEC:
2126       pp_string (buffer, "--- unexpected node: TREE_VEC");
2127       return 0;
2128 
2129     case NULLPTR_TYPE:
2130     case VOID_TYPE:
2131       if (package_prefix)
2132 	{
2133 	  append_withs ("System", false);
2134 	  pp_string (buffer, "System.Address");
2135 	}
2136       else
2137 	pp_string (buffer, "address");
2138       break;
2139 
2140     case VECTOR_TYPE:
2141       pp_string (buffer, "<vector>");
2142       break;
2143 
2144     case COMPLEX_TYPE:
2145       pp_string (buffer, "<complex>");
2146       break;
2147 
2148     case ENUMERAL_TYPE:
2149       if (name_only)
2150 	dump_ada_node (buffer, TYPE_NAME (node), node, spc, false, true);
2151       else
2152 	dump_ada_enum_type (buffer, node, type, spc, true);
2153       break;
2154 
2155     case REAL_TYPE:
2156       if (TYPE_NAME (node)
2157 	  && TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
2158 	  && IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node))) [0] == '_'
2159 	  && (id_equal (DECL_NAME (TYPE_NAME (node)), "_Float128")
2160 	      || id_equal (DECL_NAME (TYPE_NAME (node)), "__float128")))
2161 	{
2162 	  append_withs ("Interfaces.C.Extensions", false);
2163 	  pp_string (buffer, "Extensions.Float_128");
2164 	  break;
2165 	}
2166       /* fallthrough */
2167 
2168     case INTEGER_TYPE:
2169     case FIXED_POINT_TYPE:
2170     case BOOLEAN_TYPE:
2171       if (TYPE_NAME (node))
2172 	{
2173 	  if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
2174 	    pp_ada_tree_identifier (buffer, TYPE_NAME (node), node, 0,
2175 				    limited_access);
2176 	  else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
2177 		   && DECL_NAME (TYPE_NAME (node)))
2178 	    dump_ada_decl_name (buffer, TYPE_NAME (node), limited_access);
2179 	  else
2180 	    pp_string (buffer, "<unnamed type>");
2181 	}
2182       else if (TREE_CODE (node) == INTEGER_TYPE)
2183 	{
2184 	  append_withs ("Interfaces.C.Extensions", false);
2185 	  bitfield_used = true;
2186 
2187 	  if (TYPE_PRECISION (node) == 1)
2188 	    pp_string (buffer, "Extensions.Unsigned_1");
2189 	  else
2190 	    {
2191 	      pp_string (buffer, TYPE_UNSIGNED (node)
2192 				 ? "Extensions.Unsigned_"
2193 				 : "Extensions.Signed_");
2194 	      pp_decimal_int (buffer, TYPE_PRECISION (node));
2195 	    }
2196 	}
2197       else
2198 	pp_string (buffer, "<unnamed type>");
2199       break;
2200 
2201     case POINTER_TYPE:
2202     case REFERENCE_TYPE:
2203       if (name_only && TYPE_NAME (node))
2204 	dump_ada_node (buffer, TYPE_NAME (node), node, spc, limited_access,
2205 		       true);
2206 
2207       else if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
2208 	{
2209 	  if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (node))))
2210 	    pp_string (buffer, "access procedure");
2211 	  else
2212 	    pp_string (buffer, "access function");
2213 
2214 	  dump_ada_function_declaration (buffer, node, false, false, false,
2215 					 spc + INDENT_INCR);
2216 
2217 	  /* If we are dumping the full type, it means we are part of a
2218 	     type definition and need also a Convention C pragma.  */
2219 	  if (!name_only)
2220 	    {
2221 	      pp_semicolon (buffer);
2222 	      newline_and_indent (buffer, spc);
2223 	      pp_string (buffer, "pragma Convention (C, ");
2224 	      dump_ada_node (buffer, type, NULL_TREE, spc, false, true);
2225 	      pp_right_paren (buffer);
2226 	    }
2227 	}
2228       else
2229 	{
2230 	  bool is_access = false;
2231 	  unsigned int quals = TYPE_QUALS (TREE_TYPE (node));
2232 
2233 	  if (VOID_TYPE_P (TREE_TYPE (node)))
2234 	    {
2235 	      if (!name_only)
2236 		pp_string (buffer, "new ");
2237 	      if (package_prefix)
2238 		{
2239 		  append_withs ("System", false);
2240 		  pp_string (buffer, "System.Address");
2241 		}
2242 	      else
2243 		pp_string (buffer, "address");
2244 	    }
2245 	  else
2246 	    {
2247 	      if (TREE_CODE (node) == POINTER_TYPE
2248 		  && TREE_CODE (TREE_TYPE (node)) == INTEGER_TYPE
2249 		  && id_equal (DECL_NAME (TYPE_NAME (TREE_TYPE (node))),
2250 			       "char"))
2251 		{
2252 		  if (!name_only)
2253 		    pp_string (buffer, "new ");
2254 
2255 		  if (package_prefix)
2256 		    {
2257 		      pp_string (buffer, "Interfaces.C.Strings.chars_ptr");
2258 		      append_withs ("Interfaces.C.Strings", false);
2259 		    }
2260 		  else
2261 		    pp_string (buffer, "chars_ptr");
2262 		}
2263 	      else
2264 		{
2265 		  tree type_name = TYPE_NAME (TREE_TYPE (node));
2266 
2267 		  /* For now, handle access-to-access as System.Address.  */
2268 		  if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
2269 		    {
2270 		      if (package_prefix)
2271 			{
2272 			  append_withs ("System", false);
2273 			  if (!name_only)
2274 			    pp_string (buffer, "new ");
2275 			  pp_string (buffer, "System.Address");
2276 			}
2277 		      else
2278 			pp_string (buffer, "address");
2279 		      return spc;
2280 		    }
2281 
2282 		  if (!package_prefix)
2283 		    pp_string (buffer, "access");
2284 		  else if (AGGREGATE_TYPE_P (TREE_TYPE (node)))
2285 		    {
2286 		      if (!type || TREE_CODE (type) != FUNCTION_DECL)
2287 			{
2288 			  pp_string (buffer, "access ");
2289 			  is_access = true;
2290 
2291 			  if (quals & TYPE_QUAL_CONST)
2292 			    pp_string (buffer, "constant ");
2293 			  else if (!name_only)
2294 			    pp_string (buffer, "all ");
2295 			}
2296 		      else if (quals & TYPE_QUAL_CONST)
2297 			pp_string (buffer, "in ");
2298 		      else
2299 			{
2300 			  is_access = true;
2301 			  pp_string (buffer, "access ");
2302 			  /* ??? should be configurable: access or in out.  */
2303 			}
2304 		    }
2305 		  else
2306 		    {
2307 		      is_access = true;
2308 		      pp_string (buffer, "access ");
2309 
2310 		      if (!name_only)
2311 			pp_string (buffer, "all ");
2312 		    }
2313 
2314 		  if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node)) && type_name)
2315 		    dump_ada_node (buffer, type_name, TREE_TYPE (node), spc,
2316 				   is_access, true);
2317 		  else
2318 		    dump_ada_node (buffer, TREE_TYPE (node), TREE_TYPE (node),
2319 				   spc, false, true);
2320 		}
2321 	    }
2322 	}
2323       break;
2324 
2325     case ARRAY_TYPE:
2326       if (name_only)
2327 	dump_ada_node (buffer, TYPE_NAME (node), node, spc, limited_access,
2328 		       true);
2329       else
2330 	dump_ada_array_type (buffer, node, type, spc);
2331       break;
2332 
2333     case RECORD_TYPE:
2334     case UNION_TYPE:
2335       if (name_only)
2336 	dump_ada_node (buffer, TYPE_NAME (node), node, spc, limited_access,
2337 		       true);
2338       else
2339 	dump_ada_structure (buffer, node, type, spc, true);
2340       break;
2341 
2342     case INTEGER_CST:
2343       /* We treat the upper half of the sizetype range as negative.  This
2344 	 is consistent with the internal treatment and makes it possible
2345 	 to generate the (0 .. -1) range for flexible array members.  */
2346       if (TREE_TYPE (node) == sizetype)
2347 	node = fold_convert (ssizetype, node);
2348       if (tree_fits_shwi_p (node))
2349 	pp_wide_integer (buffer, tree_to_shwi (node));
2350       else if (tree_fits_uhwi_p (node))
2351 	pp_unsigned_wide_integer (buffer, tree_to_uhwi (node));
2352       else
2353 	{
2354 	  wide_int val = wi::to_wide (node);
2355 	  int i;
2356 	  if (wi::neg_p (val))
2357 	    {
2358 	      pp_minus (buffer);
2359 	      val = -val;
2360 	    }
2361 	  sprintf (pp_buffer (buffer)->digit_buffer,
2362 		   "16#%" HOST_WIDE_INT_PRINT "x",
2363 		   val.elt (val.get_len () - 1));
2364 	  for (i = val.get_len () - 2; i >= 0; i--)
2365 	    sprintf (pp_buffer (buffer)->digit_buffer,
2366 		     HOST_WIDE_INT_PRINT_PADDED_HEX, val.elt (i));
2367 	  pp_string (buffer, pp_buffer (buffer)->digit_buffer);
2368 	}
2369       break;
2370 
2371     case REAL_CST:
2372     case FIXED_CST:
2373     case COMPLEX_CST:
2374     case STRING_CST:
2375     case VECTOR_CST:
2376       return 0;
2377 
2378     case TYPE_DECL:
2379       if (DECL_IS_BUILTIN (node))
2380 	{
2381 	  /* Don't print the declaration of built-in types.  */
2382 	  if (name_only)
2383 	    {
2384 	      /* If we're in the middle of a declaration, defaults to
2385 		 System.Address.  */
2386 	      if (package_prefix)
2387 		{
2388 		  append_withs ("System", false);
2389 		  pp_string (buffer, "System.Address");
2390 		}
2391 	      else
2392 		pp_string (buffer, "address");
2393 	    }
2394 	  break;
2395 	}
2396 
2397       if (name_only)
2398 	dump_ada_decl_name (buffer, node, limited_access);
2399       else
2400 	{
2401 	  if (is_tagged_type (TREE_TYPE (node)))
2402 	    {
2403 	      int first = true;
2404 
2405 	      /* Look for ancestors.  */
2406 	      for (tree fld = TYPE_FIELDS (TREE_TYPE (node));
2407 		   fld;
2408 		   fld = TREE_CHAIN (fld))
2409 		{
2410 		  if (!DECL_NAME (fld) && is_tagged_type (TREE_TYPE (fld)))
2411 		    {
2412 		      if (first)
2413 			{
2414 			  pp_string (buffer, "limited new ");
2415 			  first = false;
2416 			}
2417 		      else
2418 			pp_string (buffer, " and ");
2419 
2420 		      dump_ada_decl_name (buffer, TYPE_NAME (TREE_TYPE (fld)),
2421 					  false);
2422 		    }
2423 		}
2424 
2425 	      pp_string (buffer, first ? "tagged limited " : " with ");
2426 	    }
2427 	  else if (has_nontrivial_methods (TREE_TYPE (node)))
2428 	    pp_string (buffer, "limited ");
2429 
2430 	  dump_ada_node (buffer, TREE_TYPE (node), type, spc, false, false);
2431 	}
2432       break;
2433 
2434     case FUNCTION_DECL:
2435     case CONST_DECL:
2436     case VAR_DECL:
2437     case PARM_DECL:
2438     case FIELD_DECL:
2439     case NAMESPACE_DECL:
2440       dump_ada_decl_name (buffer, node, false);
2441       break;
2442 
2443     default:
2444       /* Ignore other nodes (e.g. expressions).  */
2445       return 0;
2446     }
2447 
2448   return 1;
2449 }
2450 
2451 /* Dump in BUFFER NODE's methods.  SPC is the indentation level.  Return 1 if
2452    methods were printed, 0 otherwise.  */
2453 
2454 static int
2455 dump_ada_methods (pretty_printer *buffer, tree node, int spc)
2456 {
2457   if (!has_nontrivial_methods (node))
2458     return 0;
2459 
2460   pp_semicolon (buffer);
2461 
2462   int res = 1;
2463   for (tree fld = TYPE_FIELDS (node); fld; fld = DECL_CHAIN (fld))
2464     if (TREE_CODE (fld) == FUNCTION_DECL)
2465       {
2466 	if (res)
2467 	  {
2468 	    pp_newline (buffer);
2469 	    pp_newline (buffer);
2470 	  }
2471 
2472 	res = dump_ada_declaration (buffer, fld, node, spc);
2473       }
2474 
2475   return 1;
2476 }
2477 
2478 /* Dump in BUFFER a forward declaration for TYPE present inside T.
2479    SPC is the indentation level.  */
2480 
2481 static void
2482 dump_forward_type (pretty_printer *buffer, tree type, tree t, int spc)
2483 {
2484   tree decl = get_underlying_decl (type);
2485 
2486   /* Anonymous pointer and function types.  */
2487   if (!decl)
2488     {
2489       if (TREE_CODE (type) == POINTER_TYPE)
2490 	dump_forward_type (buffer, TREE_TYPE (type), t, spc);
2491       else if (TREE_CODE (type) == FUNCTION_TYPE)
2492 	{
2493 	  function_args_iterator args_iter;
2494 	  tree arg;
2495 	  dump_forward_type (buffer, TREE_TYPE (type), t, spc);
2496 	  FOREACH_FUNCTION_ARGS (type, arg, args_iter)
2497 	    dump_forward_type (buffer, arg, t, spc);
2498 	}
2499       return;
2500     }
2501 
2502   if (DECL_IS_BUILTIN (decl) || TREE_VISITED (decl))
2503     return;
2504 
2505   /* Forward declarations are only needed within a given file.  */
2506   if (DECL_SOURCE_FILE (decl) != DECL_SOURCE_FILE (t))
2507     return;
2508 
2509   /* Generate an incomplete type declaration.  */
2510   pp_string (buffer, "type ");
2511   dump_ada_node (buffer, decl, NULL_TREE, spc, false, true);
2512   pp_semicolon (buffer);
2513   newline_and_indent (buffer, spc);
2514 
2515   /* Only one incomplete declaration is legal for a given type.  */
2516   TREE_VISITED (decl) = 1;
2517 }
2518 
2519 static void dump_nested_type (pretty_printer *, tree, tree, tree, int);
2520 
2521 /* Dump in BUFFER anonymous types nested inside T's definition.
2522    PARENT is the parent node of T.  SPC is the indentation level.
2523 
2524    In C anonymous nested tagged types have no name whereas in C++ they have
2525    one.  In C their TYPE_DECL is at top level whereas in C++ it is nested.
2526    In both languages untagged types (pointers and arrays) have no name.
2527    In C++ the nested TYPE_DECLs can come after their associated FIELD_DECL.
2528 
2529    Therefore, in order to have a common processing for both languages, we
2530    disregard anonymous TYPE_DECLs at top level and here we make a first
2531    pass on the nested TYPE_DECLs and a second pass on the unnamed types.  */
2532 
2533 static void
2534 dump_nested_types (pretty_printer *buffer, tree t, tree parent, int spc)
2535 {
2536   tree type, field;
2537 
2538   /* Find possible anonymous pointers/arrays/structs/unions recursively.  */
2539   type = TREE_TYPE (t);
2540   if (type == NULL_TREE)
2541     return;
2542 
2543   for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
2544     if (TREE_CODE (field) == TYPE_DECL
2545 	&& DECL_NAME (field) != DECL_NAME (t)
2546 	&& !DECL_ORIGINAL_TYPE (field)
2547 	&& TYPE_NAME (TREE_TYPE (field)) != TYPE_NAME (type))
2548       dump_nested_type (buffer, field, t, parent, spc);
2549 
2550   for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
2551     if (TREE_CODE (field) == FIELD_DECL && !TYPE_NAME (TREE_TYPE (field)))
2552       dump_nested_type (buffer, field, t, parent, spc);
2553 }
2554 
2555 /* Dump in BUFFER the anonymous type of FIELD inside T.
2556    PARENT is the parent node of T.  SPC is the indentation level.  */
2557 
2558 static void
2559 dump_nested_type (pretty_printer *buffer, tree field, tree t, tree parent,
2560 		  int spc)
2561 {
2562   tree field_type = TREE_TYPE (field);
2563   tree decl, tmp;
2564 
2565   switch (TREE_CODE (field_type))
2566     {
2567     case POINTER_TYPE:
2568       tmp = TREE_TYPE (field_type);
2569       dump_forward_type (buffer, tmp, t, spc);
2570       break;
2571 
2572     case ARRAY_TYPE:
2573       tmp = TREE_TYPE (field_type);
2574       while (TREE_CODE (tmp) == ARRAY_TYPE)
2575 	tmp = TREE_TYPE (tmp);
2576       decl = get_underlying_decl (tmp);
2577       if (decl && !DECL_NAME (decl) && !TREE_VISITED (decl))
2578 	{
2579 	  /* Generate full declaration.  */
2580 	  dump_nested_type (buffer, decl, t, parent, spc);
2581 	  TREE_VISITED (decl) = 1;
2582 	}
2583       else if (!decl && TREE_CODE (tmp) == POINTER_TYPE)
2584 	dump_forward_type (buffer, TREE_TYPE (tmp), t, spc);
2585 
2586       /* Special case char arrays.  */
2587       if (is_char_array (field_type))
2588 	pp_string (buffer, "subtype ");
2589       else
2590 	pp_string (buffer, "type ");
2591 
2592       dump_ada_double_name (buffer, parent, field);
2593       pp_string (buffer, " is ");
2594       dump_ada_array_type (buffer, field_type, parent, spc);
2595       pp_semicolon (buffer);
2596       newline_and_indent (buffer, spc);
2597       break;
2598 
2599     case ENUMERAL_TYPE:
2600       if (is_simple_enum (field_type))
2601 	pp_string (buffer, "type ");
2602       else
2603 	pp_string (buffer, "subtype ");
2604 
2605       if (TYPE_NAME (field_type))
2606 	dump_ada_node (buffer, field_type, NULL_TREE, spc, false, true);
2607       else
2608 	dump_ada_double_name (buffer, parent, field);
2609       pp_string (buffer, " is ");
2610       dump_ada_enum_type (buffer, field_type, t, spc, false);
2611 
2612       if (is_simple_enum (field_type))
2613 	{
2614 	  pp_string (buffer, "pragma Convention (C, ");
2615 	  if (TYPE_NAME (field_type))
2616 	    dump_ada_node (buffer, field_type, NULL_TREE, spc, false, true);
2617 	  else
2618 	    dump_ada_double_name (buffer, parent, field);
2619 	  pp_string (buffer, ");");
2620 	  newline_and_indent (buffer, spc);
2621 	}
2622       else
2623 	{
2624 	  pp_semicolon (buffer);
2625 	  newline_and_indent (buffer, spc);
2626 	}
2627       break;
2628 
2629     case RECORD_TYPE:
2630     case UNION_TYPE:
2631       dump_nested_types (buffer, field, t, spc);
2632 
2633       pp_string (buffer, "type ");
2634 
2635       if (TYPE_NAME (field_type))
2636 	dump_ada_node (buffer, field_type, NULL_TREE, spc, false, true);
2637       else
2638 	dump_ada_double_name (buffer, parent, field);
2639 
2640       if (TREE_CODE (field_type) == UNION_TYPE)
2641 	pp_string (buffer, " (discr : unsigned := 0)");
2642 
2643       pp_string (buffer, " is ");
2644       dump_ada_structure (buffer, field_type, t, spc, false);
2645 
2646       pp_string (buffer, "pragma Convention (C_Pass_By_Copy, ");
2647       if (TYPE_NAME (field_type))
2648 	dump_ada_node (buffer, field_type, NULL_TREE, spc, false, true);
2649       else
2650 	dump_ada_double_name (buffer, parent, field);
2651       pp_string (buffer, ");");
2652       newline_and_indent (buffer, spc);
2653 
2654       if (TREE_CODE (field_type) == UNION_TYPE)
2655 	{
2656 	  pp_string (buffer, "pragma Unchecked_Union (");
2657 	  if (TYPE_NAME (field_type))
2658 	    dump_ada_node (buffer, field_type, NULL_TREE, spc, false, true);
2659 	  else
2660 	    dump_ada_double_name (buffer, parent, field);
2661 	  pp_string (buffer, ");");
2662 	}
2663       break;
2664 
2665     default:
2666       break;
2667     }
2668 }
2669 
2670 /* Dump in BUFFER constructor spec corresponding to T for TYPE.  */
2671 
2672 static void
2673 print_constructor (pretty_printer *buffer, tree t, tree type)
2674 {
2675   tree decl_name = DECL_NAME (TYPE_NAME (type));
2676 
2677   pp_string (buffer, "New_");
2678   pp_ada_tree_identifier (buffer, decl_name, t, 0, false);
2679 }
2680 
2681 /* Dump in BUFFER destructor spec corresponding to T.  */
2682 
2683 static void
2684 print_destructor (pretty_printer *buffer, tree t, tree type)
2685 {
2686   tree decl_name = DECL_NAME (TYPE_NAME (type));
2687 
2688   pp_string (buffer, "Delete_");
2689   if (strncmp (IDENTIFIER_POINTER (DECL_NAME (t)), "__dt_del", 8) == 0)
2690     pp_string (buffer, "And_Free_");
2691   pp_ada_tree_identifier (buffer, decl_name, t, 0, false);
2692 }
2693 
2694 /* Return the name of type T.  */
2695 
2696 static const char *
2697 type_name (tree t)
2698 {
2699   tree n = TYPE_NAME (t);
2700 
2701   if (TREE_CODE (n) == IDENTIFIER_NODE)
2702     return IDENTIFIER_POINTER (n);
2703   else
2704     return IDENTIFIER_POINTER (DECL_NAME (n));
2705 }
2706 
2707 /* Dump in BUFFER the declaration of a variable T of type TYPE in Ada syntax.
2708    SPC is the indentation level.  Return 1 if a declaration was printed,
2709    0 otherwise.  */
2710 
2711 static int
2712 dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
2713 {
2714   bool is_var = false;
2715   bool need_indent = false;
2716   bool is_class = false;
2717   tree name = TYPE_NAME (TREE_TYPE (t));
2718   tree decl_name = DECL_NAME (t);
2719   tree orig = NULL_TREE;
2720 
2721   if (cpp_check && cpp_check (t, IS_TEMPLATE))
2722     return dump_ada_template (buffer, t, spc);
2723 
2724   /* Skip enumeral values: will be handled as part of the type itself.  */
2725   if (TREE_CODE (t) == CONST_DECL && TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE)
2726     return 0;
2727 
2728   if (TREE_CODE (t) == TYPE_DECL)
2729     {
2730       orig = DECL_ORIGINAL_TYPE (t);
2731 
2732       if (orig && TYPE_STUB_DECL (orig))
2733 	{
2734 	  tree stub = TYPE_STUB_DECL (orig);
2735 	  tree typ = TREE_TYPE (stub);
2736 
2737 	  if (TYPE_NAME (typ))
2738 	    {
2739 	      /* If the types have the same name (ignoring casing), then ignore
2740 		 the second type, but forward declare the first if need be.  */
2741 	      if (type_name (typ) == type_name (TREE_TYPE (t))
2742 		  || !strcasecmp (type_name (typ), type_name (TREE_TYPE (t))))
2743 		{
2744 		  if (RECORD_OR_UNION_TYPE_P (typ) && !TREE_VISITED (stub))
2745 		    {
2746 		      INDENT (spc);
2747 		      dump_forward_type (buffer, typ, t, 0);
2748 		    }
2749 
2750 		  TREE_VISITED (t) = 1;
2751 		  return 0;
2752 		}
2753 
2754 	      INDENT (spc);
2755 
2756 	      if (RECORD_OR_UNION_TYPE_P (typ) && !TREE_VISITED (stub))
2757 		dump_forward_type (buffer, typ, t, spc);
2758 
2759 	      pp_string (buffer, "subtype ");
2760 	      dump_ada_node (buffer, t, type, spc, false, true);
2761 	      pp_string (buffer, " is ");
2762 	      dump_ada_node (buffer, typ, type, spc, false, true);
2763 	      pp_string (buffer, ";  -- ");
2764 	      dump_sloc (buffer, t);
2765 
2766 	      TREE_VISITED (t) = 1;
2767 	      return 1;
2768 	    }
2769 	}
2770 
2771       /* Skip unnamed or anonymous structs/unions/enum types.  */
2772       if (!orig && !decl_name && !name
2773 	  && (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t))
2774 	      || TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE))
2775 	return 0;
2776 
2777 	/* Skip anonymous enum types (duplicates of real types).  */
2778       if (!orig
2779 	  && TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE
2780 	  && decl_name
2781 	  && (*IDENTIFIER_POINTER (decl_name) == '.'
2782 	      || *IDENTIFIER_POINTER (decl_name) == '$'))
2783 	return 0;
2784 
2785       INDENT (spc);
2786 
2787       switch (TREE_CODE (TREE_TYPE (t)))
2788 	{
2789 	  case RECORD_TYPE:
2790 	  case UNION_TYPE:
2791 	    if (!COMPLETE_TYPE_P (TREE_TYPE (t)))
2792 	      {
2793 		pp_string (buffer, "type ");
2794 		dump_ada_node (buffer, t, type, spc, false, true);
2795 		pp_string (buffer, " is null record;   -- incomplete struct");
2796 		TREE_VISITED (t) = 1;
2797 		return 1;
2798 	      }
2799 
2800 	    if (decl_name
2801 		&& (*IDENTIFIER_POINTER (decl_name) == '.'
2802 		    || *IDENTIFIER_POINTER (decl_name) == '$'))
2803 	      {
2804 		pp_string (buffer, "--  skipped anonymous struct ");
2805 		dump_ada_node (buffer, t, type, spc, false, true);
2806 		TREE_VISITED (t) = 1;
2807 		return 1;
2808 	      }
2809 
2810 	    if (orig && TYPE_NAME (orig))
2811 	      pp_string (buffer, "subtype ");
2812 	    else
2813 	      {
2814 		dump_nested_types (buffer, t, t, spc);
2815 
2816                 if (separate_class_package (t))
2817 		  {
2818 		    is_class = true;
2819 		    pp_string (buffer, "package Class_");
2820 		    dump_ada_node (buffer, t, type, spc, false, true);
2821 		    pp_string (buffer, " is");
2822 		    spc += INDENT_INCR;
2823 		    newline_and_indent (buffer, spc);
2824 		  }
2825 
2826 		pp_string (buffer, "type ");
2827 	      }
2828 	    break;
2829 
2830 	  case POINTER_TYPE:
2831 	  case REFERENCE_TYPE:
2832 	    dump_forward_type (buffer, TREE_TYPE (TREE_TYPE (t)), t, spc);
2833 	    /* fallthrough */
2834 
2835 	  case ARRAY_TYPE:
2836 	    if ((orig && TYPE_NAME (orig)) || is_char_array (TREE_TYPE (t)))
2837 	      pp_string (buffer, "subtype ");
2838 	    else
2839 	      pp_string (buffer, "type ");
2840 	    break;
2841 
2842 	  case FUNCTION_TYPE:
2843 	    pp_string (buffer, "--  skipped function type ");
2844 	    dump_ada_node (buffer, t, type, spc, false, true);
2845 	    return 1;
2846 
2847 	  case ENUMERAL_TYPE:
2848 	    if ((orig && TYPE_NAME (orig) && orig != TREE_TYPE (t))
2849 		|| !is_simple_enum (TREE_TYPE (t)))
2850 	      pp_string (buffer, "subtype ");
2851 	    else
2852 	      pp_string (buffer, "type ");
2853 	    break;
2854 
2855 	  default:
2856 	    pp_string (buffer, "subtype ");
2857 	}
2858       TREE_VISITED (t) = 1;
2859     }
2860   else
2861     {
2862       if (VAR_P (t)
2863 	  && decl_name
2864 	  && *IDENTIFIER_POINTER (decl_name) == '_')
2865 	return 0;
2866 
2867       need_indent = true;
2868     }
2869 
2870   /* Print the type and name.  */
2871   if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
2872     {
2873       if (need_indent)
2874 	INDENT (spc);
2875 
2876       /* Print variable's name.  */
2877       dump_ada_node (buffer, t, type, spc, false, true);
2878 
2879       if (TREE_CODE (t) == TYPE_DECL)
2880 	{
2881 	  pp_string (buffer, " is ");
2882 
2883 	  if (orig && TYPE_NAME (orig))
2884 	    dump_ada_node (buffer, TYPE_NAME (orig), type, spc, false, true);
2885 	  else
2886 	    dump_ada_array_type (buffer, TREE_TYPE (t), type, spc);
2887 	}
2888       else
2889 	{
2890 	  tree tmp = TYPE_NAME (TREE_TYPE (t));
2891 
2892 	  if (spc == INDENT_INCR || TREE_STATIC (t))
2893 	    is_var = true;
2894 
2895 	  pp_string (buffer, " : ");
2896 
2897 	  if (TREE_CODE (TREE_TYPE (TREE_TYPE (t))) != POINTER_TYPE)
2898 	    pp_string (buffer, "aliased ");
2899 
2900 	  if (tmp)
2901 	    dump_ada_node (buffer, tmp, type, spc, false, true);
2902 	  else if (type)
2903 	    dump_ada_double_name (buffer, type, t);
2904 	  else
2905 	    dump_ada_array_type (buffer, TREE_TYPE (t), type, spc);
2906 	}
2907     }
2908   else if (TREE_CODE (t) == FUNCTION_DECL)
2909     {
2910       bool is_abstract_class = false;
2911       bool is_method = TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE;
2912       tree decl_name = DECL_NAME (t);
2913       bool is_abstract = false;
2914       bool is_constructor = false;
2915       bool is_destructor = false;
2916       bool is_copy_constructor = false;
2917       bool is_move_constructor = false;
2918 
2919       if (!decl_name)
2920 	return 0;
2921 
2922       if (cpp_check)
2923 	{
2924 	  is_abstract = cpp_check (t, IS_ABSTRACT);
2925 	  is_constructor = cpp_check (t, IS_CONSTRUCTOR);
2926 	  is_destructor = cpp_check (t, IS_DESTRUCTOR);
2927 	  is_copy_constructor = cpp_check (t, IS_COPY_CONSTRUCTOR);
2928 	  is_move_constructor = cpp_check (t, IS_MOVE_CONSTRUCTOR);
2929 	}
2930 
2931       /* Skip copy constructors and C++11 move constructors: some are internal
2932 	 only and those that are not cannot be called easily from Ada.  */
2933       if (is_copy_constructor || is_move_constructor)
2934 	return 0;
2935 
2936       if (is_constructor || is_destructor)
2937 	{
2938 	  /* ??? Skip implicit constructors/destructors for now.  */
2939 	  if (DECL_ARTIFICIAL (t))
2940 	    return 0;
2941 
2942 	  /* Only consider complete constructors and deleting destructors.  */
2943 	  if (strncmp (IDENTIFIER_POINTER (decl_name), "__ct_comp", 9) != 0
2944 	      && strncmp (IDENTIFIER_POINTER (decl_name), "__dt_comp", 9) != 0
2945 	      && strncmp (IDENTIFIER_POINTER (decl_name), "__dt_del", 8) != 0)
2946 	    return 0;
2947 	}
2948 
2949       /* If this function has an entry in the vtable, we cannot omit it.  */
2950       else if (!DECL_VINDEX (t) && *IDENTIFIER_POINTER (decl_name) == '_')
2951 	{
2952 	  INDENT (spc);
2953 	  pp_string (buffer, "--  skipped func ");
2954 	  pp_string (buffer, IDENTIFIER_POINTER (decl_name));
2955 	  return 1;
2956 	}
2957 
2958       if (need_indent)
2959 	INDENT (spc);
2960 
2961       if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (t))) && !is_constructor)
2962 	pp_string (buffer, "procedure ");
2963       else
2964 	pp_string (buffer, "function ");
2965 
2966       if (is_constructor)
2967 	print_constructor (buffer, t, type);
2968       else if (is_destructor)
2969 	print_destructor (buffer, t, type);
2970       else
2971 	dump_ada_decl_name (buffer, t, false);
2972 
2973       dump_ada_function_declaration
2974 	(buffer, t, is_method, is_constructor, is_destructor, spc);
2975 
2976       if (is_constructor && RECORD_OR_UNION_TYPE_P (type))
2977 	for (tree fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
2978 	  if (TREE_CODE (fld) == FUNCTION_DECL && cpp_check (fld, IS_ABSTRACT))
2979 	    {
2980 	      is_abstract_class = true;
2981 	      break;
2982 	    }
2983 
2984       if (is_abstract || is_abstract_class)
2985 	pp_string (buffer, " is abstract");
2986 
2987       pp_semicolon (buffer);
2988       pp_string (buffer, "  -- ");
2989       dump_sloc (buffer, t);
2990 
2991       if (is_abstract || !DECL_ASSEMBLER_NAME (t))
2992 	return 1;
2993 
2994       newline_and_indent (buffer, spc);
2995 
2996       if (is_constructor)
2997 	{
2998 	  pp_string (buffer, "pragma CPP_Constructor (");
2999 	  print_constructor (buffer, t, type);
3000 	  pp_string (buffer, ", \"");
3001 	  pp_asm_name (buffer, t);
3002 	  pp_string (buffer, "\");");
3003 	}
3004       else if (is_destructor)
3005 	{
3006 	  pp_string (buffer, "pragma Import (CPP, ");
3007 	  print_destructor (buffer, t, type);
3008 	  pp_string (buffer, ", \"");
3009 	  pp_asm_name (buffer, t);
3010 	  pp_string (buffer, "\");");
3011 	}
3012       else
3013 	dump_ada_import (buffer, t);
3014 
3015       return 1;
3016     }
3017   else if (TREE_CODE (t) == TYPE_DECL && !orig)
3018     {
3019       bool is_interface = false;
3020       bool is_abstract_record = false;
3021 
3022       if (need_indent)
3023 	INDENT (spc);
3024 
3025       /* Anonymous structs/unions.  */
3026       dump_ada_node (buffer, TREE_TYPE (t), t, spc, false, true);
3027 
3028       if (TREE_CODE (TREE_TYPE (t)) == UNION_TYPE)
3029 	pp_string (buffer, " (discr : unsigned := 0)");
3030 
3031       pp_string (buffer, " is ");
3032 
3033       /* Check whether we have an Ada interface compatible class.
3034 	 That is only have a vtable non-static data member and no
3035 	 non-abstract methods.  */
3036       if (cpp_check
3037 	  && RECORD_OR_UNION_TYPE_P (TREE_TYPE (t)))
3038 	{
3039 	  bool has_fields = false;
3040 
3041 	  /* Check that there are no fields other than the virtual table.  */
3042 	  for (tree fld = TYPE_FIELDS (TREE_TYPE (t));
3043 	       fld;
3044 	       fld = TREE_CHAIN (fld))
3045 	    {
3046 	      if (TREE_CODE (fld) == FIELD_DECL)
3047 		{
3048 		  if (!has_fields && DECL_VIRTUAL_P (fld))
3049 		    is_interface = true;
3050 		  else
3051 		    is_interface = false;
3052 		  has_fields = true;
3053 		}
3054 	      else if (TREE_CODE (fld) == FUNCTION_DECL
3055 		       && !DECL_ARTIFICIAL (fld))
3056 		{
3057 		  if (cpp_check (fld, IS_ABSTRACT))
3058 		    is_abstract_record = true;
3059 		  else
3060 		    is_interface = false;
3061 		}
3062 	    }
3063 	}
3064 
3065       TREE_VISITED (t) = 1;
3066       if (is_interface)
3067 	{
3068 	  pp_string (buffer, "limited interface;  -- ");
3069 	  dump_sloc (buffer, t);
3070 	  newline_and_indent (buffer, spc);
3071 	  pp_string (buffer, "pragma Import (CPP, ");
3072 	  dump_ada_node (buffer, TYPE_NAME (TREE_TYPE (t)), type, spc, false,
3073 			 true);
3074 	  pp_right_paren (buffer);
3075 
3076 	  dump_ada_methods (buffer, TREE_TYPE (t), spc);
3077 	}
3078       else
3079 	{
3080 	  if (is_abstract_record)
3081 	    pp_string (buffer, "abstract ");
3082 	  dump_ada_node (buffer, t, t, spc, false, false);
3083 	}
3084     }
3085   else
3086     {
3087       if (need_indent)
3088 	INDENT (spc);
3089 
3090       if (TREE_CODE (t) == FIELD_DECL && DECL_NAME (t))
3091 	check_name (buffer, t);
3092 
3093       /* Print variable/type's name.  */
3094       dump_ada_node (buffer, t, t, spc, false, true);
3095 
3096       if (TREE_CODE (t) == TYPE_DECL)
3097 	{
3098 	  const bool is_subtype = TYPE_NAME (orig);
3099 
3100 	  if (!is_subtype && TREE_CODE (TREE_TYPE (t)) == UNION_TYPE)
3101 	    pp_string (buffer, " (discr : unsigned := 0)");
3102 
3103 	  pp_string (buffer, " is ");
3104 
3105 	  dump_ada_node (buffer, orig, t, spc, false, is_subtype);
3106 	}
3107       else
3108 	{
3109 	  if (spc == INDENT_INCR || TREE_STATIC (t))
3110 	    is_var = true;
3111 
3112 	  pp_string (buffer, " : ");
3113 
3114 	  if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t))
3115 	      || TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE)
3116 	    {
3117 	      if (TYPE_NAME (TREE_TYPE (t))
3118 		  || TREE_CODE (TREE_TYPE (t)) != ENUMERAL_TYPE)
3119 		pp_string (buffer, "aliased ");
3120 
3121 	      if (TREE_READONLY (t) && TREE_CODE (t) != FIELD_DECL)
3122 		pp_string (buffer, "constant ");
3123 
3124 	      if (TYPE_NAME (TREE_TYPE (t)))
3125 		dump_ada_node (buffer, TREE_TYPE (t), t, spc, false, true);
3126 	      else if (type)
3127 		dump_ada_double_name (buffer, type, t);
3128 	    }
3129 	  else
3130 	    {
3131 	      if (TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE
3132 		  && (TYPE_NAME (TREE_TYPE (t))
3133 		      || TREE_CODE (TREE_TYPE (t)) != INTEGER_TYPE))
3134 		pp_string (buffer, "aliased ");
3135 
3136 	      if (TREE_READONLY (t) && TREE_CODE (t) != FIELD_DECL)
3137 		pp_string (buffer, "constant ");
3138 
3139 	      dump_ada_node (buffer, TREE_TYPE (t), t, spc, false, true);
3140 	    }
3141 	}
3142     }
3143 
3144   if (is_class)
3145     {
3146       spc -= INDENT_INCR;
3147       newline_and_indent (buffer, spc);
3148       pp_string (buffer, "end;");
3149       newline_and_indent (buffer, spc);
3150       pp_string (buffer, "use Class_");
3151       dump_ada_node (buffer, t, type, spc, false, true);
3152       pp_semicolon (buffer);
3153       pp_newline (buffer);
3154 
3155       /* All needed indentation/newline performed already, so return 0.  */
3156       return 0;
3157     }
3158   else
3159     {
3160       pp_string (buffer, ";  -- ");
3161       dump_sloc (buffer, t);
3162     }
3163 
3164   if (is_var)
3165     {
3166       newline_and_indent (buffer, spc);
3167       dump_ada_import (buffer, t);
3168     }
3169 
3170   return 1;
3171 }
3172 
3173 /* Dump in BUFFER a structure NODE of type TYPE: name, fields, and methods
3174    in Ada syntax.  SPC is the indentation level.  If DISPLAY_CONVENTION is
3175    true, also print the pragma Convention for NODE.  */
3176 
3177 static void
3178 dump_ada_structure (pretty_printer *buffer, tree node, tree type, int spc,
3179 		    bool display_convention)
3180 {
3181   const bool is_union = (TREE_CODE (node) == UNION_TYPE);
3182   char buf[32];
3183   int field_num = 0;
3184   int field_spc = spc + INDENT_INCR;
3185   int need_semicolon;
3186 
3187   bitfield_used = false;
3188 
3189   /* Print the contents of the structure.  */
3190   pp_string (buffer, "record");
3191 
3192   if (is_union)
3193     {
3194       newline_and_indent (buffer, spc + INDENT_INCR);
3195       pp_string (buffer, "case discr is");
3196       field_spc = spc + INDENT_INCR * 3;
3197     }
3198 
3199   pp_newline (buffer);
3200 
3201   /* Print the non-static fields of the structure.  */
3202   for (tree tmp = TYPE_FIELDS (node); tmp; tmp = TREE_CHAIN (tmp))
3203     {
3204       /* Add parent field if needed.  */
3205       if (!DECL_NAME (tmp))
3206 	{
3207 	  if (!is_tagged_type (TREE_TYPE (tmp)))
3208 	    {
3209 	      if (!TYPE_NAME (TREE_TYPE (tmp)))
3210 		dump_ada_declaration (buffer, tmp, type, field_spc);
3211 	      else
3212 		{
3213 		  INDENT (field_spc);
3214 
3215 		  if (field_num == 0)
3216 		    pp_string (buffer, "parent : aliased ");
3217 		  else
3218 		    {
3219 		      sprintf (buf, "field_%d : aliased ", field_num + 1);
3220 		      pp_string (buffer, buf);
3221 		    }
3222 		  dump_ada_decl_name (buffer, TYPE_NAME (TREE_TYPE (tmp)),
3223 				      false);
3224 		  pp_semicolon (buffer);
3225 		}
3226 
3227 	      pp_newline (buffer);
3228 	      field_num++;
3229 	    }
3230 	}
3231       else if (TREE_CODE (tmp) == FIELD_DECL)
3232 	{
3233 	  /* Skip internal virtual table field.  */
3234 	  if (!DECL_VIRTUAL_P (tmp))
3235 	    {
3236 	      if (is_union)
3237 		{
3238 		  if (TREE_CHAIN (tmp)
3239 		      && TREE_TYPE (TREE_CHAIN (tmp)) != node
3240 		      && TREE_CODE (TREE_CHAIN (tmp)) != TYPE_DECL)
3241 		    sprintf (buf, "when %d =>", field_num);
3242 		  else
3243 		    sprintf (buf, "when others =>");
3244 
3245 		  INDENT (spc + INDENT_INCR * 2);
3246 		  pp_string (buffer, buf);
3247 		  pp_newline (buffer);
3248 		}
3249 
3250 	      if (dump_ada_declaration (buffer, tmp, type, field_spc))
3251 		{
3252 		  pp_newline (buffer);
3253 		  field_num++;
3254 		}
3255 	    }
3256 	}
3257     }
3258 
3259   if (is_union)
3260     {
3261       INDENT (spc + INDENT_INCR);
3262       pp_string (buffer, "end case;");
3263       pp_newline (buffer);
3264     }
3265 
3266   if (field_num == 0)
3267     {
3268       INDENT (spc + INDENT_INCR);
3269       pp_string (buffer, "null;");
3270       pp_newline (buffer);
3271     }
3272 
3273   INDENT (spc);
3274   pp_string (buffer, "end record;");
3275 
3276   newline_and_indent (buffer, spc);
3277 
3278   if (!display_convention)
3279     return;
3280 
3281   if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type)))
3282     {
3283       if (has_nontrivial_methods (TREE_TYPE (type)))
3284 	pp_string (buffer, "pragma Import (CPP, ");
3285       else
3286 	pp_string (buffer, "pragma Convention (C_Pass_By_Copy, ");
3287     }
3288   else
3289     pp_string (buffer, "pragma Convention (C, ");
3290 
3291   package_prefix = false;
3292   dump_ada_node (buffer, TREE_TYPE (type), type, spc, false, true);
3293   package_prefix = true;
3294   pp_right_paren (buffer);
3295 
3296   if (is_union)
3297     {
3298       pp_semicolon (buffer);
3299       newline_and_indent (buffer, spc);
3300       pp_string (buffer, "pragma Unchecked_Union (");
3301 
3302       dump_ada_node (buffer, TREE_TYPE (type), type, spc, false, true);
3303       pp_right_paren (buffer);
3304     }
3305 
3306   if (bitfield_used)
3307     {
3308       pp_semicolon (buffer);
3309       newline_and_indent (buffer, spc);
3310       pp_string (buffer, "pragma Pack (");
3311       dump_ada_node (buffer, TREE_TYPE (type), type, spc, false, true);
3312       pp_right_paren (buffer);
3313       bitfield_used = false;
3314     }
3315 
3316   need_semicolon = !dump_ada_methods (buffer, node, spc);
3317 
3318   /* Print the static fields of the structure, if any.  */
3319   for (tree tmp = TYPE_FIELDS (node); tmp; tmp = TREE_CHAIN (tmp))
3320     {
3321       if (TREE_CODE (tmp) == VAR_DECL && DECL_NAME (tmp))
3322 	{
3323 	  if (need_semicolon)
3324 	    {
3325 	      need_semicolon = false;
3326 	      pp_semicolon (buffer);
3327 	    }
3328 	  pp_newline (buffer);
3329 	  pp_newline (buffer);
3330 	  dump_ada_declaration (buffer, tmp, type, spc);
3331 	}
3332     }
3333 }
3334 
3335 /* Dump all the declarations in SOURCE_FILE to an Ada spec.
3336    COLLECT_ALL_REFS is a front-end callback used to collect all relevant
3337    nodes for SOURCE_FILE.  CHECK is used to perform C++ queries on nodes.  */
3338 
3339 static void
3340 dump_ads (const char *source_file,
3341 	  void (*collect_all_refs)(const char *),
3342 	  int (*check)(tree, cpp_operation))
3343 {
3344   char *ads_name;
3345   char *pkg_name;
3346   char *s;
3347   FILE *f;
3348 
3349   pkg_name = get_ada_package (source_file);
3350 
3351   /* Construct the .ads filename and package name.  */
3352   ads_name = xstrdup (pkg_name);
3353 
3354   for (s = ads_name; *s; s++)
3355     if (*s == '.')
3356       *s = '-';
3357     else
3358       *s = TOLOWER (*s);
3359 
3360   ads_name = reconcat (ads_name, ads_name, ".ads", NULL);
3361 
3362   /* Write out the .ads file.  */
3363   f = fopen (ads_name, "w");
3364   if (f)
3365     {
3366       pretty_printer pp;
3367 
3368       pp_needs_newline (&pp) = true;
3369       pp.buffer->stream = f;
3370 
3371       /* Dump all relevant macros.  */
3372       dump_ada_macros (&pp, source_file);
3373 
3374       /* Reset the table of withs for this file.  */
3375       reset_ada_withs ();
3376 
3377       (*collect_all_refs) (source_file);
3378 
3379       /* Dump all references.  */
3380       cpp_check = check;
3381       dump_ada_nodes (&pp, source_file);
3382 
3383       /* Requires Ada 2005 syntax, so generate corresponding pragma.
3384          Also, disable style checks since this file is auto-generated.  */
3385       fprintf (f, "pragma Ada_2005;\npragma Style_Checks (Off);\n\n");
3386 
3387       /* Dump withs.  */
3388       dump_ada_withs (f);
3389 
3390       fprintf (f, "\npackage %s is\n\n", pkg_name);
3391       pp_write_text_to_stream (&pp);
3392       /* ??? need to free pp */
3393       fprintf (f, "end %s;\n", pkg_name);
3394       fclose (f);
3395     }
3396 
3397   free (ads_name);
3398   free (pkg_name);
3399 }
3400 
3401 static const char **source_refs = NULL;
3402 static int source_refs_used = 0;
3403 static int source_refs_allocd = 0;
3404 
3405 /* Add an entry for FILENAME to the table SOURCE_REFS.  */
3406 
3407 void
3408 collect_source_ref (const char *filename)
3409 {
3410   int i;
3411 
3412   if (!filename)
3413     return;
3414 
3415   if (source_refs_allocd == 0)
3416     {
3417       source_refs_allocd = 1024;
3418       source_refs = XNEWVEC (const char *, source_refs_allocd);
3419     }
3420 
3421   for (i = 0; i < source_refs_used; i++)
3422     if (filename == source_refs[i])
3423       return;
3424 
3425   if (source_refs_used == source_refs_allocd)
3426     {
3427       source_refs_allocd *= 2;
3428       source_refs = XRESIZEVEC (const char *, source_refs, source_refs_allocd);
3429     }
3430 
3431   source_refs[source_refs_used++] = filename;
3432 }
3433 
3434 /* Main entry point: dump all Ada specs corresponding to SOURCE_REFS
3435    using callbacks COLLECT_ALL_REFS and CHECK.
3436    COLLECT_ALL_REFS is a front-end callback used to collect all relevant
3437    nodes for a given source file.
3438    CHECK is used to perform C++ queries on nodes, or NULL for the C
3439    front-end.  */
3440 
3441 void
3442 dump_ada_specs (void (*collect_all_refs)(const char *),
3443 		int (*check)(tree, cpp_operation))
3444 {
3445   /* Iterate over the list of files to dump specs for.  */
3446   for (int i = 0; i < source_refs_used; i++)
3447     dump_ads (source_refs[i], collect_all_refs, check);
3448 
3449   /* Free various tables.  */
3450   free (source_refs);
3451   delete overloaded_names;
3452 }
3453