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