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