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