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