* c-ada-spec.c (has_static_fields): Look only into variables.
[official-gcc.git] / gcc / c-family / c-ada-spec.c
blobdac437d9bf63c2165160d8edc6bd6fd4d4888dee
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-2017 Free Software Foundation, Inc.
4 Adapted from tree-pretty-print.c by Arnaud Charlet <charlet@adacore.com>
6 This file is part of GCC.
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.
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.
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/>. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "c-ada-spec.h"
28 #include "fold-const.h"
29 #include "c-pragma.h"
30 #include "cpp-id-data.h"
32 /* Local functions, macros and variables. */
33 static int dump_generic_ada_node (pretty_printer *, tree, tree, int, int,
34 bool);
35 static int print_ada_declaration (pretty_printer *, tree, tree, int);
36 static void print_ada_struct_decl (pretty_printer *, tree, tree, int, bool);
37 static void dump_sloc (pretty_printer *buffer, tree node);
38 static void print_comment (pretty_printer *, const char *);
39 static void print_generic_ada_decl (pretty_printer *, tree, const char *);
40 static char *get_ada_package (const char *);
41 static void dump_ada_nodes (pretty_printer *, const char *);
42 static void reset_ada_withs (void);
43 static void dump_ada_withs (FILE *);
44 static void dump_ads (const char *, void (*)(const char *),
45 int (*)(tree, cpp_operation));
46 static char *to_ada_name (const char *, int *);
47 static bool separate_class_package (tree);
49 #define INDENT(SPACE) \
50 do { int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
52 #define INDENT_INCR 3
54 /* Global hook used to perform C++ queries on nodes. */
55 static int (*cpp_check) (tree, cpp_operation) = NULL;
58 /* Given a cpp MACRO, compute the max length BUFFER_LEN of the macro, as well
59 as max length PARAM_LEN of arguments for fun_like macros, and also set
60 SUPPORTED to 0 if the macro cannot be mapped to an Ada construct. */
62 static void
63 macro_length (const cpp_macro *macro, int *supported, int *buffer_len,
64 int *param_len)
66 int i;
67 unsigned j;
69 *supported = 1;
70 *buffer_len = 0;
71 *param_len = 0;
73 if (macro->fun_like)
75 (*param_len)++;
76 for (i = 0; i < macro->paramc; i++)
78 cpp_hashnode *param = macro->params[i];
80 *param_len += NODE_LEN (param);
82 if (i + 1 < macro->paramc)
84 *param_len += 2; /* ", " */
86 else if (macro->variadic)
88 *supported = 0;
89 return;
92 *param_len += 2; /* ")\0" */
95 for (j = 0; j < macro->count; j++)
97 cpp_token *token = &macro->exp.tokens[j];
99 if (token->flags & PREV_WHITE)
100 (*buffer_len)++;
102 if (token->flags & STRINGIFY_ARG || token->flags & PASTE_LEFT)
104 *supported = 0;
105 return;
108 if (token->type == CPP_MACRO_ARG)
109 *buffer_len +=
110 NODE_LEN (macro->params[token->val.macro_arg.arg_no - 1]);
111 else
112 /* Include enough extra space to handle e.g. special characters. */
113 *buffer_len += (cpp_token_len (token) + 1) * 8;
116 (*buffer_len)++;
119 /* Dump all digits/hex chars from NUMBER to BUFFER and return a pointer
120 to the character after the last character written. */
122 static unsigned char *
123 dump_number (unsigned char *number, unsigned char *buffer)
125 while (*number != '\0'
126 && *number != 'U'
127 && *number != 'u'
128 && *number != 'l'
129 && *number != 'L')
130 *buffer++ = *number++;
132 return buffer;
135 /* Handle escape character C and convert to an Ada character into BUFFER.
136 Return a pointer to the character after the last character written, or
137 NULL if the escape character is not supported. */
139 static unsigned char *
140 handle_escape_character (unsigned char *buffer, char c)
142 switch (c)
144 case '"':
145 *buffer++ = '"';
146 *buffer++ = '"';
147 break;
149 case 'n':
150 strcpy ((char *) buffer, "\" & ASCII.LF & \"");
151 buffer += 16;
152 break;
154 case 'r':
155 strcpy ((char *) buffer, "\" & ASCII.CR & \"");
156 buffer += 16;
157 break;
159 case 't':
160 strcpy ((char *) buffer, "\" & ASCII.HT & \"");
161 buffer += 16;
162 break;
164 default:
165 return NULL;
168 return buffer;
171 /* Dump into PP a set of MAX_ADA_MACROS MACROS (C/C++) as Ada constants when
172 possible. */
174 static void
175 print_ada_macros (pretty_printer *pp, cpp_hashnode **macros, int max_ada_macros)
177 int j, num_macros = 0, prev_line = -1;
179 for (j = 0; j < max_ada_macros; j++)
181 cpp_hashnode *node = macros[j];
182 const cpp_macro *macro = node->value.macro;
183 unsigned i;
184 int supported = 1, prev_is_one = 0, buffer_len, param_len;
185 int is_string = 0, is_char = 0;
186 char *ada_name;
187 unsigned char *s, *params, *buffer, *buf_param, *char_one = NULL, *tmp;
189 macro_length (macro, &supported, &buffer_len, &param_len);
190 s = buffer = XALLOCAVEC (unsigned char, buffer_len);
191 params = buf_param = XALLOCAVEC (unsigned char, param_len);
193 if (supported)
195 if (macro->fun_like)
197 *buf_param++ = '(';
198 for (i = 0; i < macro->paramc; i++)
200 cpp_hashnode *param = macro->params[i];
202 memcpy (buf_param, NODE_NAME (param), NODE_LEN (param));
203 buf_param += NODE_LEN (param);
205 if (i + 1 < macro->paramc)
207 *buf_param++ = ',';
208 *buf_param++ = ' ';
210 else if (macro->variadic)
212 supported = 0;
213 break;
216 *buf_param++ = ')';
217 *buf_param = '\0';
220 for (i = 0; supported && i < macro->count; i++)
222 cpp_token *token = &macro->exp.tokens[i];
223 int is_one = 0;
225 if (token->flags & PREV_WHITE)
226 *buffer++ = ' ';
228 if (token->flags & STRINGIFY_ARG || token->flags & PASTE_LEFT)
230 supported = 0;
231 break;
234 switch (token->type)
236 case CPP_MACRO_ARG:
238 cpp_hashnode *param =
239 macro->params[token->val.macro_arg.arg_no - 1];
240 memcpy (buffer, NODE_NAME (param), NODE_LEN (param));
241 buffer += NODE_LEN (param);
243 break;
245 case CPP_EQ_EQ: *buffer++ = '='; break;
246 case CPP_GREATER: *buffer++ = '>'; break;
247 case CPP_LESS: *buffer++ = '<'; break;
248 case CPP_PLUS: *buffer++ = '+'; break;
249 case CPP_MINUS: *buffer++ = '-'; break;
250 case CPP_MULT: *buffer++ = '*'; break;
251 case CPP_DIV: *buffer++ = '/'; break;
252 case CPP_COMMA: *buffer++ = ','; break;
253 case CPP_OPEN_SQUARE:
254 case CPP_OPEN_PAREN: *buffer++ = '('; break;
255 case CPP_CLOSE_SQUARE: /* fallthrough */
256 case CPP_CLOSE_PAREN: *buffer++ = ')'; break;
257 case CPP_DEREF: /* fallthrough */
258 case CPP_SCOPE: /* fallthrough */
259 case CPP_DOT: *buffer++ = '.'; break;
261 case CPP_EQ: *buffer++ = ':'; *buffer++ = '='; break;
262 case CPP_NOT_EQ: *buffer++ = '/'; *buffer++ = '='; break;
263 case CPP_GREATER_EQ: *buffer++ = '>'; *buffer++ = '='; break;
264 case CPP_LESS_EQ: *buffer++ = '<'; *buffer++ = '='; break;
266 case CPP_NOT:
267 *buffer++ = 'n'; *buffer++ = 'o'; *buffer++ = 't'; break;
268 case CPP_MOD:
269 *buffer++ = 'm'; *buffer++ = 'o'; *buffer++ = 'd'; break;
270 case CPP_AND:
271 *buffer++ = 'a'; *buffer++ = 'n'; *buffer++ = 'd'; break;
272 case CPP_OR:
273 *buffer++ = 'o'; *buffer++ = 'r'; break;
274 case CPP_XOR:
275 *buffer++ = 'x'; *buffer++ = 'o'; *buffer++ = 'r'; break;
276 case CPP_AND_AND:
277 strcpy ((char *) buffer, " and then ");
278 buffer += 10;
279 break;
280 case CPP_OR_OR:
281 strcpy ((char *) buffer, " or else ");
282 buffer += 9;
283 break;
285 case CPP_PADDING:
286 *buffer++ = ' ';
287 is_one = prev_is_one;
288 break;
290 case CPP_COMMENT: break;
292 case CPP_WSTRING:
293 case CPP_STRING16:
294 case CPP_STRING32:
295 case CPP_UTF8STRING:
296 case CPP_WCHAR:
297 case CPP_CHAR16:
298 case CPP_CHAR32:
299 case CPP_UTF8CHAR:
300 case CPP_NAME:
301 if (!macro->fun_like)
302 supported = 0;
303 else
304 buffer = cpp_spell_token (parse_in, token, buffer, false);
305 break;
307 case CPP_STRING:
308 is_string = 1;
310 const unsigned char *s = token->val.str.text;
312 for (; *s; s++)
313 if (*s == '\\')
315 s++;
316 buffer = handle_escape_character (buffer, *s);
317 if (buffer == NULL)
319 supported = 0;
320 break;
323 else
324 *buffer++ = *s;
326 break;
328 case CPP_CHAR:
329 is_char = 1;
331 unsigned chars_seen;
332 int ignored;
333 cppchar_t c;
335 c = cpp_interpret_charconst (parse_in, token,
336 &chars_seen, &ignored);
337 if (c >= 32 && c <= 126)
339 *buffer++ = '\'';
340 *buffer++ = (char) c;
341 *buffer++ = '\'';
343 else
345 chars_seen = sprintf
346 ((char *) buffer, "Character'Val (%d)", (int) c);
347 buffer += chars_seen;
350 break;
352 case CPP_NUMBER:
353 tmp = cpp_token_as_text (parse_in, token);
355 switch (*tmp)
357 case '0':
358 switch (tmp[1])
360 case '\0':
361 case 'l':
362 case 'L':
363 case 'u':
364 case 'U':
365 *buffer++ = '0';
366 break;
368 case 'x':
369 case 'X':
370 *buffer++ = '1';
371 *buffer++ = '6';
372 *buffer++ = '#';
373 buffer = dump_number (tmp + 2, buffer);
374 *buffer++ = '#';
375 break;
377 case 'b':
378 case 'B':
379 *buffer++ = '2';
380 *buffer++ = '#';
381 buffer = dump_number (tmp + 2, buffer);
382 *buffer++ = '#';
383 break;
385 default:
386 /* Dump floating constants unmodified. */
387 if (strchr ((const char *)tmp, '.'))
388 buffer = dump_number (tmp, buffer);
389 else
391 *buffer++ = '8';
392 *buffer++ = '#';
393 buffer = dump_number (tmp + 1, buffer);
394 *buffer++ = '#';
396 break;
398 break;
400 case '1':
401 if (tmp[1] == '\0' || tmp[1] == 'l' || tmp[1] == 'u'
402 || tmp[1] == 'L' || tmp[1] == 'U')
404 is_one = 1;
405 char_one = buffer;
406 *buffer++ = '1';
408 else
409 buffer = dump_number (tmp, buffer);
410 break;
412 default:
413 buffer = dump_number (tmp, buffer);
414 break;
416 break;
418 case CPP_LSHIFT:
419 if (prev_is_one)
421 /* Replace "1 << N" by "2 ** N" */
422 *char_one = '2';
423 *buffer++ = '*';
424 *buffer++ = '*';
425 break;
427 /* fallthrough */
429 case CPP_RSHIFT:
430 case CPP_COMPL:
431 case CPP_QUERY:
432 case CPP_EOF:
433 case CPP_PLUS_EQ:
434 case CPP_MINUS_EQ:
435 case CPP_MULT_EQ:
436 case CPP_DIV_EQ:
437 case CPP_MOD_EQ:
438 case CPP_AND_EQ:
439 case CPP_OR_EQ:
440 case CPP_XOR_EQ:
441 case CPP_RSHIFT_EQ:
442 case CPP_LSHIFT_EQ:
443 case CPP_PRAGMA:
444 case CPP_PRAGMA_EOL:
445 case CPP_HASH:
446 case CPP_PASTE:
447 case CPP_OPEN_BRACE:
448 case CPP_CLOSE_BRACE:
449 case CPP_SEMICOLON:
450 case CPP_ELLIPSIS:
451 case CPP_PLUS_PLUS:
452 case CPP_MINUS_MINUS:
453 case CPP_DEREF_STAR:
454 case CPP_DOT_STAR:
455 case CPP_ATSIGN:
456 case CPP_HEADER_NAME:
457 case CPP_AT_NAME:
458 case CPP_OTHER:
459 case CPP_OBJC_STRING:
460 default:
461 if (!macro->fun_like)
462 supported = 0;
463 else
464 buffer = cpp_spell_token (parse_in, token, buffer, false);
465 break;
468 prev_is_one = is_one;
471 if (supported)
472 *buffer = '\0';
475 if (macro->fun_like && supported)
477 char *start = (char *) s;
478 int is_function = 0;
480 pp_string (pp, " -- arg-macro: ");
482 if (*start == '(' && buffer[-1] == ')')
484 start++;
485 buffer[-1] = '\0';
486 is_function = 1;
487 pp_string (pp, "function ");
489 else
491 pp_string (pp, "procedure ");
494 pp_string (pp, (const char *) NODE_NAME (node));
495 pp_space (pp);
496 pp_string (pp, (char *) params);
497 pp_newline (pp);
498 pp_string (pp, " -- ");
500 if (is_function)
502 pp_string (pp, "return ");
503 pp_string (pp, start);
504 pp_semicolon (pp);
506 else
507 pp_string (pp, start);
509 pp_newline (pp);
511 else if (supported)
513 expanded_location sloc = expand_location (macro->line);
515 if (sloc.line != prev_line + 1 && prev_line > 0)
516 pp_newline (pp);
518 num_macros++;
519 prev_line = sloc.line;
521 pp_string (pp, " ");
522 ada_name = to_ada_name ((const char *) NODE_NAME (node), NULL);
523 pp_string (pp, ada_name);
524 free (ada_name);
525 pp_string (pp, " : ");
527 if (is_string)
528 pp_string (pp, "aliased constant String");
529 else if (is_char)
530 pp_string (pp, "aliased constant Character");
531 else
532 pp_string (pp, "constant");
534 pp_string (pp, " := ");
535 pp_string (pp, (char *) s);
537 if (is_string)
538 pp_string (pp, " & ASCII.NUL");
540 pp_string (pp, "; -- ");
541 pp_string (pp, sloc.file);
542 pp_colon (pp);
543 pp_scalar (pp, "%d", sloc.line);
544 pp_newline (pp);
546 else
548 pp_string (pp, " -- unsupported macro: ");
549 pp_string (pp, (const char *) cpp_macro_definition (parse_in, node));
550 pp_newline (pp);
554 if (num_macros > 0)
555 pp_newline (pp);
558 static const char *source_file;
559 static int max_ada_macros;
561 /* Callback used to count the number of relevant macros from
562 cpp_forall_identifiers. PFILE and V are not used. NODE is the current macro
563 to consider. */
565 static int
566 count_ada_macro (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *node,
567 void *v ATTRIBUTE_UNUSED)
569 const cpp_macro *macro = node->value.macro;
571 if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN)
572 && macro->count
573 && *NODE_NAME (node) != '_'
574 && LOCATION_FILE (macro->line) == source_file)
575 max_ada_macros++;
577 return 1;
580 static int store_ada_macro_index;
582 /* Callback used to store relevant macros from cpp_forall_identifiers.
583 PFILE is not used. NODE is the current macro to store if relevant.
584 MACROS is an array of cpp_hashnode* used to store NODE. */
586 static int
587 store_ada_macro (cpp_reader *pfile ATTRIBUTE_UNUSED,
588 cpp_hashnode *node, void *macros)
590 const cpp_macro *macro = node->value.macro;
592 if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN)
593 && macro->count
594 && *NODE_NAME (node) != '_'
595 && LOCATION_FILE (macro->line) == source_file)
596 ((cpp_hashnode **) macros)[store_ada_macro_index++] = node;
598 return 1;
601 /* Callback used to compare (during qsort) macros. NODE1 and NODE2 are the
602 two macro nodes to compare. */
604 static int
605 compare_macro (const void *node1, const void *node2)
607 typedef const cpp_hashnode *const_hnode;
609 const_hnode n1 = *(const const_hnode *) node1;
610 const_hnode n2 = *(const const_hnode *) node2;
612 return n1->value.macro->line - n2->value.macro->line;
615 /* Dump in PP all relevant macros appearing in FILE. */
617 static void
618 dump_ada_macros (pretty_printer *pp, const char* file)
620 cpp_hashnode **macros;
622 /* Initialize file-scope variables. */
623 max_ada_macros = 0;
624 store_ada_macro_index = 0;
625 source_file = file;
627 /* Count all potentially relevant macros, and then sort them by sloc. */
628 cpp_forall_identifiers (parse_in, count_ada_macro, NULL);
629 macros = XALLOCAVEC (cpp_hashnode *, max_ada_macros);
630 cpp_forall_identifiers (parse_in, store_ada_macro, macros);
631 qsort (macros, max_ada_macros, sizeof (cpp_hashnode *), compare_macro);
633 print_ada_macros (pp, macros, max_ada_macros);
636 /* Current source file being handled. */
638 static const char *source_file_base;
640 /* Return sloc of DECL, using sloc of last field if LAST is true. */
642 location_t
643 decl_sloc (const_tree decl, bool last)
645 tree field;
647 /* Compare the declaration of struct-like types based on the sloc of their
648 last field (if LAST is true), so that more nested types collate before
649 less nested ones. */
650 if (TREE_CODE (decl) == TYPE_DECL
651 && !DECL_ORIGINAL_TYPE (decl)
652 && RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl))
653 && (field = TYPE_FIELDS (TREE_TYPE (decl))))
655 if (last)
656 while (DECL_CHAIN (field))
657 field = DECL_CHAIN (field);
658 return DECL_SOURCE_LOCATION (field);
661 return DECL_SOURCE_LOCATION (decl);
664 /* Compare two locations LHS and RHS. */
666 static int
667 compare_location (location_t lhs, location_t rhs)
669 expanded_location xlhs = expand_location (lhs);
670 expanded_location xrhs = expand_location (rhs);
672 if (xlhs.file != xrhs.file)
673 return filename_cmp (xlhs.file, xrhs.file);
675 if (xlhs.line != xrhs.line)
676 return xlhs.line - xrhs.line;
678 if (xlhs.column != xrhs.column)
679 return xlhs.column - xrhs.column;
681 return 0;
684 /* Compare two declarations (LP and RP) by their source location. */
686 static int
687 compare_node (const void *lp, const void *rp)
689 const_tree lhs = *((const tree *) lp);
690 const_tree rhs = *((const tree *) rp);
692 return compare_location (decl_sloc (lhs, true), decl_sloc (rhs, true));
695 /* Compare two comments (LP and RP) by their source location. */
697 static int
698 compare_comment (const void *lp, const void *rp)
700 const cpp_comment *lhs = (const cpp_comment *) lp;
701 const cpp_comment *rhs = (const cpp_comment *) rp;
703 return compare_location (lhs->sloc, rhs->sloc);
706 static tree *to_dump = NULL;
707 static int to_dump_count = 0;
709 /* Collect a list of declarations from T relevant to SOURCE_FILE to be dumped
710 by a subsequent call to dump_ada_nodes. */
712 void
713 collect_ada_nodes (tree t, const char *source_file)
715 tree n;
716 int i = to_dump_count;
718 /* Count the likely relevant nodes: do not dump builtins (they are irrelevant
719 in the context of bindings) and namespaces (we do not handle them properly
720 yet). */
721 for (n = t; n; n = TREE_CHAIN (n))
722 if (!DECL_IS_BUILTIN (n)
723 && TREE_CODE (n) != NAMESPACE_DECL
724 && LOCATION_FILE (decl_sloc (n, false)) == source_file)
725 to_dump_count++;
727 /* Allocate sufficient storage for all nodes. */
728 to_dump = XRESIZEVEC (tree, to_dump, to_dump_count);
730 /* Store the relevant nodes. */
731 for (n = t; n; n = TREE_CHAIN (n))
732 if (!DECL_IS_BUILTIN (n)
733 && TREE_CODE (n) != NAMESPACE_DECL
734 && LOCATION_FILE (decl_sloc (n, false)) == source_file)
735 to_dump[i++] = n;
738 /* Call back for walk_tree to clear the TREE_VISITED flag of TP. */
740 static tree
741 unmark_visited_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
742 void *data ATTRIBUTE_UNUSED)
744 if (TREE_VISITED (*tp))
745 TREE_VISITED (*tp) = 0;
746 else
747 *walk_subtrees = 0;
749 return NULL_TREE;
752 /* Dump nodes into PP relevant to SOURCE_FILE, as collected by previous calls
753 to collect_ada_nodes. */
755 static void
756 dump_ada_nodes (pretty_printer *pp, const char *source_file)
758 int i, j;
759 cpp_comment_table *comments;
761 /* Sort the table of declarations to dump by sloc. */
762 qsort (to_dump, to_dump_count, sizeof (tree), compare_node);
764 /* Fetch the table of comments. */
765 comments = cpp_get_comments (parse_in);
767 /* Sort the comments table by sloc. */
768 if (comments->count > 1)
769 qsort (comments->entries, comments->count, sizeof (cpp_comment),
770 compare_comment);
772 /* Interleave comments and declarations in line number order. */
773 i = j = 0;
776 /* Advance j until comment j is in this file. */
777 while (j != comments->count
778 && LOCATION_FILE (comments->entries[j].sloc) != source_file)
779 j++;
781 /* Advance j until comment j is not a duplicate. */
782 while (j < comments->count - 1
783 && !compare_comment (&comments->entries[j],
784 &comments->entries[j + 1]))
785 j++;
787 /* Write decls until decl i collates after comment j. */
788 while (i != to_dump_count)
790 if (j == comments->count
791 || LOCATION_LINE (decl_sloc (to_dump[i], false))
792 < LOCATION_LINE (comments->entries[j].sloc))
793 print_generic_ada_decl (pp, to_dump[i++], source_file);
794 else
795 break;
798 /* Write comment j, if there is one. */
799 if (j != comments->count)
800 print_comment (pp, comments->entries[j++].comment);
802 } while (i != to_dump_count || j != comments->count);
804 /* Clear the TREE_VISITED flag over each subtree we've dumped. */
805 for (i = 0; i < to_dump_count; i++)
806 walk_tree (&to_dump[i], unmark_visited_r, NULL, NULL);
808 /* Finalize the to_dump table. */
809 if (to_dump)
811 free (to_dump);
812 to_dump = NULL;
813 to_dump_count = 0;
817 /* Print a COMMENT to the output stream PP. */
819 static void
820 print_comment (pretty_printer *pp, const char *comment)
822 int len = strlen (comment);
823 char *str = XALLOCAVEC (char, len + 1);
824 char *tok;
825 bool extra_newline = false;
827 memcpy (str, comment, len + 1);
829 /* Trim C/C++ comment indicators. */
830 if (str[len - 2] == '*' && str[len - 1] == '/')
832 str[len - 2] = ' ';
833 str[len - 1] = '\0';
835 str += 2;
837 tok = strtok (str, "\n");
838 while (tok) {
839 pp_string (pp, " --");
840 pp_string (pp, tok);
841 pp_newline (pp);
842 tok = strtok (NULL, "\n");
844 /* Leave a blank line after multi-line comments. */
845 if (tok)
846 extra_newline = true;
849 if (extra_newline)
850 pp_newline (pp);
853 /* Print declaration DECL to PP in Ada syntax. The current source file being
854 handled is SOURCE_FILE. */
856 static void
857 print_generic_ada_decl (pretty_printer *pp, tree decl, const char *source_file)
859 source_file_base = source_file;
861 if (print_ada_declaration (pp, decl, NULL_TREE, INDENT_INCR))
863 pp_newline (pp);
864 pp_newline (pp);
868 /* Dump a newline and indent BUFFER by SPC chars. */
870 static void
871 newline_and_indent (pretty_printer *buffer, int spc)
873 pp_newline (buffer);
874 INDENT (spc);
877 struct with { char *s; const char *in_file; int limited; };
878 static struct with *withs = NULL;
879 static int withs_max = 4096;
880 static int with_len = 0;
882 /* Record a "with" clause on package S (a limited with if LIMITED_ACCESS is
883 true), if not already done. */
885 static void
886 append_withs (const char *s, int limited_access)
888 int i;
890 if (withs == NULL)
891 withs = XNEWVEC (struct with, withs_max);
893 if (with_len == withs_max)
895 withs_max *= 2;
896 withs = XRESIZEVEC (struct with, withs, withs_max);
899 for (i = 0; i < with_len; i++)
900 if (!strcmp (s, withs[i].s)
901 && source_file_base == withs[i].in_file)
903 withs[i].limited &= limited_access;
904 return;
907 withs[with_len].s = xstrdup (s);
908 withs[with_len].in_file = source_file_base;
909 withs[with_len].limited = limited_access;
910 with_len++;
913 /* Reset "with" clauses. */
915 static void
916 reset_ada_withs (void)
918 int i;
920 if (!withs)
921 return;
923 for (i = 0; i < with_len; i++)
924 free (withs[i].s);
925 free (withs);
926 withs = NULL;
927 withs_max = 4096;
928 with_len = 0;
931 /* Dump "with" clauses in F. */
933 static void
934 dump_ada_withs (FILE *f)
936 int i;
938 fprintf (f, "with Interfaces.C; use Interfaces.C;\n");
940 for (i = 0; i < with_len; i++)
941 fprintf
942 (f, "%swith %s;\n", withs[i].limited ? "limited " : "", withs[i].s);
945 /* Return suitable Ada package name from FILE. */
947 static char *
948 get_ada_package (const char *file)
950 const char *base;
951 char *res;
952 const char *s;
953 int i;
954 size_t plen;
956 s = strstr (file, "/include/");
957 if (s)
958 base = s + 9;
959 else
960 base = lbasename (file);
962 if (ada_specs_parent == NULL)
963 plen = 0;
964 else
965 plen = strlen (ada_specs_parent) + 1;
967 res = XNEWVEC (char, plen + strlen (base) + 1);
968 if (ada_specs_parent != NULL) {
969 strcpy (res, ada_specs_parent);
970 res[plen - 1] = '.';
973 for (i = plen; *base; base++, i++)
974 switch (*base)
976 case '+':
977 res[i] = 'p';
978 break;
980 case '.':
981 case '-':
982 case '_':
983 case '/':
984 case '\\':
985 res[i] = (i == 0 || res[i - 1] == '.' || res[i - 1] == '_') ? 'u' : '_';
986 break;
988 default:
989 res[i] = *base;
990 break;
992 res[i] = '\0';
994 return res;
997 static const char *ada_reserved[] = {
998 "abort", "abs", "abstract", "accept", "access", "aliased", "all", "and",
999 "array", "at", "begin", "body", "case", "constant", "declare", "delay",
1000 "delta", "digits", "do", "else", "elsif", "end", "entry", "exception",
1001 "exit", "for", "function", "generic", "goto", "if", "in", "interface", "is",
1002 "limited", "loop", "mod", "new", "not", "null", "others", "out", "of", "or",
1003 "overriding", "package", "pragma", "private", "procedure", "protected",
1004 "raise", "range", "record", "rem", "renames", "requeue", "return", "reverse",
1005 "select", "separate", "subtype", "synchronized", "tagged", "task",
1006 "terminate", "then", "type", "until", "use", "when", "while", "with", "xor",
1007 NULL};
1009 /* ??? would be nice to specify this list via a config file, so that users
1010 can create their own dictionary of conflicts. */
1011 static const char *c_duplicates[] = {
1012 /* system will cause troubles with System.Address. */
1013 "system",
1015 /* The following values have other definitions with same name/other
1016 casing. */
1017 "funmap",
1018 "rl_vi_fWord",
1019 "rl_vi_bWord",
1020 "rl_vi_eWord",
1021 "rl_readline_version",
1022 "_Vx_ushort",
1023 "USHORT",
1024 "XLookupKeysym",
1025 NULL};
1027 /* Return a declaration tree corresponding to TYPE. */
1029 static tree
1030 get_underlying_decl (tree type)
1032 if (!type)
1033 return NULL_TREE;
1035 /* type is a declaration. */
1036 if (DECL_P (type))
1037 return type;
1039 /* type is a typedef. */
1040 if (TYPE_P (type) && TYPE_NAME (type) && DECL_P (TYPE_NAME (type)))
1041 return TYPE_NAME (type);
1043 /* TYPE_STUB_DECL has been set for type. */
1044 if (TYPE_P (type) && TYPE_STUB_DECL (type))
1045 return TYPE_STUB_DECL (type);
1047 return NULL_TREE;
1050 /* Return whether TYPE has static fields. */
1052 static bool
1053 has_static_fields (const_tree type)
1055 if (!type || !RECORD_OR_UNION_TYPE_P (type))
1056 return false;
1058 for (tree fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld))
1059 if (TREE_CODE (fld) == VAR_DECL && DECL_NAME (fld))
1060 return true;
1062 return false;
1065 /* Return whether TYPE corresponds to an Ada tagged type (has a dispatch
1066 table). */
1068 static bool
1069 is_tagged_type (const_tree type)
1071 if (!type || !RECORD_OR_UNION_TYPE_P (type))
1072 return false;
1074 for (tree fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld))
1075 if (TREE_CODE (fld) == FUNCTION_DECL && DECL_VINDEX (fld))
1076 return true;
1078 return false;
1081 /* Return whether TYPE has non-trivial methods, i.e. methods that do something
1082 for the objects of TYPE. In C++, all classes have implicit special methods,
1083 e.g. constructors and destructors, but they can be trivial if the type is
1084 sufficiently simple. */
1086 static bool
1087 has_nontrivial_methods (tree type)
1089 if (!type || !RECORD_OR_UNION_TYPE_P (type))
1090 return false;
1092 /* Only C++ types can have methods. */
1093 if (!cpp_check)
1094 return false;
1096 /* A non-trivial type has non-trivial special methods. */
1097 if (!cpp_check (type, IS_TRIVIAL))
1098 return true;
1100 /* If there are user-defined methods, they are deemed non-trivial. */
1101 for (tree fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
1102 if (TREE_CODE (TREE_TYPE (fld)) == METHOD_TYPE && !DECL_ARTIFICIAL (fld))
1103 return true;
1105 return false;
1108 /* Generate a legal Ada name from a C NAME, returning a malloc'd string.
1109 SPACE_FOUND, if not NULL, is used to indicate whether a space was found in
1110 NAME. */
1112 static char *
1113 to_ada_name (const char *name, int *space_found)
1115 const char **names;
1116 int len = strlen (name);
1117 int j, len2 = 0;
1118 int found = false;
1119 char *s = XNEWVEC (char, len * 2 + 5);
1120 char c;
1122 if (space_found)
1123 *space_found = false;
1125 /* Add trailing "c_" if name is an Ada reserved word. */
1126 for (names = ada_reserved; *names; names++)
1127 if (!strcasecmp (name, *names))
1129 s[len2++] = 'c';
1130 s[len2++] = '_';
1131 found = true;
1132 break;
1135 if (!found)
1136 /* Add trailing "c_" if name is an potential case sensitive duplicate. */
1137 for (names = c_duplicates; *names; names++)
1138 if (!strcmp (name, *names))
1140 s[len2++] = 'c';
1141 s[len2++] = '_';
1142 found = true;
1143 break;
1146 for (j = 0; name[j] == '_'; j++)
1147 s[len2++] = 'u';
1149 if (j > 0)
1150 s[len2++] = '_';
1151 else if (*name == '.' || *name == '$')
1153 s[0] = 'a';
1154 s[1] = 'n';
1155 s[2] = 'o';
1156 s[3] = 'n';
1157 len2 = 4;
1158 j++;
1161 /* Replace unsuitable characters for Ada identifiers. */
1163 for (; j < len; j++)
1164 switch (name[j])
1166 case ' ':
1167 if (space_found)
1168 *space_found = true;
1169 s[len2++] = '_';
1170 break;
1172 /* ??? missing some C++ operators. */
1173 case '=':
1174 s[len2++] = '_';
1176 if (name[j + 1] == '=')
1178 j++;
1179 s[len2++] = 'e';
1180 s[len2++] = 'q';
1182 else
1184 s[len2++] = 'a';
1185 s[len2++] = 's';
1187 break;
1189 case '!':
1190 s[len2++] = '_';
1191 if (name[j + 1] == '=')
1193 j++;
1194 s[len2++] = 'n';
1195 s[len2++] = 'e';
1197 break;
1199 case '~':
1200 s[len2++] = '_';
1201 s[len2++] = 't';
1202 s[len2++] = 'i';
1203 break;
1205 case '&':
1206 case '|':
1207 case '^':
1208 s[len2++] = '_';
1209 s[len2++] = name[j] == '&' ? 'a' : name[j] == '|' ? 'o' : 'x';
1211 if (name[j + 1] == '=')
1213 j++;
1214 s[len2++] = 'e';
1216 break;
1218 case '+':
1219 case '-':
1220 case '*':
1221 case '/':
1222 case '(':
1223 case '[':
1224 if (s[len2 - 1] != '_')
1225 s[len2++] = '_';
1227 switch (name[j + 1]) {
1228 case '\0':
1229 j++;
1230 switch (name[j - 1]) {
1231 case '+': s[len2++] = 'p'; break; /* + */
1232 case '-': s[len2++] = 'm'; break; /* - */
1233 case '*': s[len2++] = 't'; break; /* * */
1234 case '/': s[len2++] = 'd'; break; /* / */
1236 break;
1238 case '=':
1239 j++;
1240 switch (name[j - 1]) {
1241 case '+': s[len2++] = 'p'; break; /* += */
1242 case '-': s[len2++] = 'm'; break; /* -= */
1243 case '*': s[len2++] = 't'; break; /* *= */
1244 case '/': s[len2++] = 'd'; break; /* /= */
1246 s[len2++] = 'a';
1247 break;
1249 case '-': /* -- */
1250 j++;
1251 s[len2++] = 'm';
1252 s[len2++] = 'm';
1253 break;
1255 case '+': /* ++ */
1256 j++;
1257 s[len2++] = 'p';
1258 s[len2++] = 'p';
1259 break;
1261 case ')': /* () */
1262 j++;
1263 s[len2++] = 'o';
1264 s[len2++] = 'p';
1265 break;
1267 case ']': /* [] */
1268 j++;
1269 s[len2++] = 'o';
1270 s[len2++] = 'b';
1271 break;
1274 break;
1276 case '<':
1277 case '>':
1278 c = name[j] == '<' ? 'l' : 'g';
1279 s[len2++] = '_';
1281 switch (name[j + 1]) {
1282 case '\0':
1283 s[len2++] = c;
1284 s[len2++] = 't';
1285 break;
1286 case '=':
1287 j++;
1288 s[len2++] = c;
1289 s[len2++] = 'e';
1290 break;
1291 case '>':
1292 j++;
1293 s[len2++] = 's';
1294 s[len2++] = 'r';
1295 break;
1296 case '<':
1297 j++;
1298 s[len2++] = 's';
1299 s[len2++] = 'l';
1300 break;
1301 default:
1302 break;
1304 break;
1306 case '_':
1307 if (len2 && s[len2 - 1] == '_')
1308 s[len2++] = 'u';
1309 /* fall through */
1311 default:
1312 s[len2++] = name[j];
1315 if (s[len2 - 1] == '_')
1316 s[len2++] = 'u';
1318 s[len2] = '\0';
1320 return s;
1323 /* Return true if DECL refers to a C++ class type for which a
1324 separate enclosing package has been or should be generated. */
1326 static bool
1327 separate_class_package (tree decl)
1329 tree type = TREE_TYPE (decl);
1330 return has_nontrivial_methods (type) || has_static_fields (type);
1333 static bool package_prefix = true;
1335 /* Dump in BUFFER the name of an identifier NODE of type TYPE, following Ada
1336 syntax. LIMITED_ACCESS indicates whether NODE can be accessed via a limited
1337 'with' clause rather than a regular 'with' clause. */
1339 static void
1340 pp_ada_tree_identifier (pretty_printer *buffer, tree node, tree type,
1341 int limited_access)
1343 const char *name = IDENTIFIER_POINTER (node);
1344 int space_found = false;
1345 char *s = to_ada_name (name, &space_found);
1346 tree decl;
1348 /* If the entity is a type and comes from another file, generate "package"
1349 prefix. */
1350 decl = get_underlying_decl (type);
1352 if (decl)
1354 expanded_location xloc = expand_location (decl_sloc (decl, false));
1356 if (xloc.file && xloc.line)
1358 if (xloc.file != source_file_base)
1360 switch (TREE_CODE (type))
1362 case ENUMERAL_TYPE:
1363 case INTEGER_TYPE:
1364 case REAL_TYPE:
1365 case FIXED_POINT_TYPE:
1366 case BOOLEAN_TYPE:
1367 case REFERENCE_TYPE:
1368 case POINTER_TYPE:
1369 case ARRAY_TYPE:
1370 case RECORD_TYPE:
1371 case UNION_TYPE:
1372 case TYPE_DECL:
1373 if (package_prefix)
1375 char *s1 = get_ada_package (xloc.file);
1376 append_withs (s1, limited_access);
1377 pp_string (buffer, s1);
1378 pp_dot (buffer);
1379 free (s1);
1381 break;
1382 default:
1383 break;
1386 /* Generate the additional package prefix for C++ classes. */
1387 if (separate_class_package (decl))
1389 pp_string (buffer, "Class_");
1390 pp_string (buffer, s);
1391 pp_dot (buffer);
1397 if (space_found)
1398 if (!strcmp (s, "short_int"))
1399 pp_string (buffer, "short");
1400 else if (!strcmp (s, "short_unsigned_int"))
1401 pp_string (buffer, "unsigned_short");
1402 else if (!strcmp (s, "unsigned_int"))
1403 pp_string (buffer, "unsigned");
1404 else if (!strcmp (s, "long_int"))
1405 pp_string (buffer, "long");
1406 else if (!strcmp (s, "long_unsigned_int"))
1407 pp_string (buffer, "unsigned_long");
1408 else if (!strcmp (s, "long_long_int"))
1409 pp_string (buffer, "Long_Long_Integer");
1410 else if (!strcmp (s, "long_long_unsigned_int"))
1412 if (package_prefix)
1414 append_withs ("Interfaces.C.Extensions", false);
1415 pp_string (buffer, "Extensions.unsigned_long_long");
1417 else
1418 pp_string (buffer, "unsigned_long_long");
1420 else
1421 pp_string(buffer, s);
1422 else
1423 if (!strcmp (s, "bool"))
1425 if (package_prefix)
1427 append_withs ("Interfaces.C.Extensions", false);
1428 pp_string (buffer, "Extensions.bool");
1430 else
1431 pp_string (buffer, "bool");
1433 else
1434 pp_string(buffer, s);
1436 free (s);
1439 /* Dump in BUFFER the assembly name of T. */
1441 static void
1442 pp_asm_name (pretty_printer *buffer, tree t)
1444 tree name = DECL_ASSEMBLER_NAME (t);
1445 char *ada_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (name) + 1), *s;
1446 const char *ident = IDENTIFIER_POINTER (name);
1448 for (s = ada_name; *ident; ident++)
1450 if (*ident == ' ')
1451 break;
1452 else if (*ident != '*')
1453 *s++ = *ident;
1456 *s = '\0';
1457 pp_string (buffer, ada_name);
1460 /* Dump in BUFFER the name of a DECL node if set, following Ada syntax.
1461 LIMITED_ACCESS indicates whether NODE can be accessed via a limited
1462 'with' clause rather than a regular 'with' clause. */
1464 static void
1465 dump_ada_decl_name (pretty_printer *buffer, tree decl, int limited_access)
1467 if (DECL_NAME (decl))
1468 pp_ada_tree_identifier (buffer, DECL_NAME (decl), decl, limited_access);
1469 else
1471 tree type_name = TYPE_NAME (TREE_TYPE (decl));
1473 if (!type_name)
1475 pp_string (buffer, "anon");
1476 if (TREE_CODE (decl) == FIELD_DECL)
1477 pp_scalar (buffer, "%d", DECL_UID (decl));
1478 else
1479 pp_scalar (buffer, "%d", TYPE_UID (TREE_TYPE (decl)));
1481 else if (TREE_CODE (type_name) == IDENTIFIER_NODE)
1482 pp_ada_tree_identifier (buffer, type_name, decl, limited_access);
1486 /* Dump in BUFFER a name based on both T1 and T2 followed by a suffix. */
1488 static void
1489 dump_ada_double_name (pretty_printer *buffer, tree t1, tree t2)
1491 if (DECL_NAME (t1))
1492 pp_ada_tree_identifier (buffer, DECL_NAME (t1), t1, false);
1493 else
1495 pp_string (buffer, "anon");
1496 pp_scalar (buffer, "%d", TYPE_UID (TREE_TYPE (t1)));
1499 pp_underscore (buffer);
1501 if (DECL_NAME (t2))
1502 pp_ada_tree_identifier (buffer, DECL_NAME (t2), t2, false);
1503 else
1505 pp_string (buffer, "anon");
1506 pp_scalar (buffer, "%d", TYPE_UID (TREE_TYPE (t2)));
1509 switch (TREE_CODE (TREE_TYPE (t2)))
1511 case ARRAY_TYPE:
1512 pp_string (buffer, "_array");
1513 break;
1514 case RECORD_TYPE:
1515 pp_string (buffer, "_struct");
1516 break;
1517 case UNION_TYPE:
1518 pp_string (buffer, "_union");
1519 break;
1520 default:
1521 pp_string (buffer, "_unknown");
1522 break;
1526 /* Dump in BUFFER pragma Import C/CPP on a given node T. */
1528 static void
1529 dump_ada_import (pretty_printer *buffer, tree t)
1531 const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t));
1532 int is_stdcall = TREE_CODE (t) == FUNCTION_DECL &&
1533 lookup_attribute ("stdcall", TYPE_ATTRIBUTES (TREE_TYPE (t)));
1535 if (is_stdcall)
1536 pp_string (buffer, "pragma Import (Stdcall, ");
1537 else if (name[0] == '_' && name[1] == 'Z')
1538 pp_string (buffer, "pragma Import (CPP, ");
1539 else
1540 pp_string (buffer, "pragma Import (C, ");
1542 dump_ada_decl_name (buffer, t, false);
1543 pp_string (buffer, ", \"");
1545 if (is_stdcall)
1546 pp_string (buffer, IDENTIFIER_POINTER (DECL_NAME (t)));
1547 else
1548 pp_asm_name (buffer, t);
1550 pp_string (buffer, "\");");
1553 /* Check whether T and its type have different names, and append "the_"
1554 otherwise in BUFFER. */
1556 static void
1557 check_name (pretty_printer *buffer, tree t)
1559 const char *s;
1560 tree tmp = TREE_TYPE (t);
1562 while (TREE_CODE (tmp) == POINTER_TYPE && !TYPE_NAME (tmp))
1563 tmp = TREE_TYPE (tmp);
1565 if (TREE_CODE (tmp) != FUNCTION_TYPE)
1567 if (TREE_CODE (tmp) == IDENTIFIER_NODE)
1568 s = IDENTIFIER_POINTER (tmp);
1569 else if (!TYPE_NAME (tmp))
1570 s = "";
1571 else if (TREE_CODE (TYPE_NAME (tmp)) == IDENTIFIER_NODE)
1572 s = IDENTIFIER_POINTER (TYPE_NAME (tmp));
1573 else
1574 s = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (tmp)));
1576 if (!strcasecmp (IDENTIFIER_POINTER (DECL_NAME (t)), s))
1577 pp_string (buffer, "the_");
1581 /* Dump in BUFFER a function declaration FUNC with Ada syntax.
1582 IS_METHOD indicates whether FUNC is a C++ method.
1583 IS_CONSTRUCTOR whether FUNC is a C++ constructor.
1584 IS_DESTRUCTOR whether FUNC is a C++ destructor.
1585 SPC is the current indentation level. */
1587 static int
1588 dump_ada_function_declaration (pretty_printer *buffer, tree func,
1589 int is_method, int is_constructor,
1590 int is_destructor, int spc)
1592 tree arg;
1593 const tree node = TREE_TYPE (func);
1594 char buf[17];
1595 int num = 0, num_args = 0, have_args = true, have_ellipsis = false;
1597 /* Compute number of arguments. */
1598 arg = TYPE_ARG_TYPES (node);
1600 if (arg)
1602 while (TREE_CHAIN (arg) && arg != error_mark_node)
1604 num_args++;
1605 arg = TREE_CHAIN (arg);
1608 if (TREE_CODE (TREE_VALUE (arg)) != VOID_TYPE)
1610 num_args++;
1611 have_ellipsis = true;
1615 if (is_constructor)
1616 num_args--;
1618 if (is_destructor)
1619 num_args = 1;
1621 if (num_args > 2)
1622 newline_and_indent (buffer, spc + 1);
1624 if (num_args > 0)
1626 pp_space (buffer);
1627 pp_left_paren (buffer);
1630 if (TREE_CODE (func) == FUNCTION_DECL)
1631 arg = DECL_ARGUMENTS (func);
1632 else
1633 arg = NULL_TREE;
1635 if (arg == NULL_TREE)
1637 have_args = false;
1638 arg = TYPE_ARG_TYPES (node);
1640 if (arg && TREE_CODE (TREE_VALUE (arg)) == VOID_TYPE)
1641 arg = NULL_TREE;
1644 if (is_constructor)
1645 arg = TREE_CHAIN (arg);
1647 /* Print the argument names (if available) & types. */
1649 for (num = 1; num <= num_args; num++)
1651 if (have_args)
1653 if (DECL_NAME (arg))
1655 check_name (buffer, arg);
1656 pp_ada_tree_identifier (buffer, DECL_NAME (arg), NULL_TREE,
1657 false);
1658 pp_string (buffer, " : ");
1660 else
1662 sprintf (buf, "arg%d : ", num);
1663 pp_string (buffer, buf);
1666 dump_generic_ada_node (buffer, TREE_TYPE (arg), node, spc, 0, true);
1668 else
1670 sprintf (buf, "arg%d : ", num);
1671 pp_string (buffer, buf);
1672 dump_generic_ada_node (buffer, TREE_VALUE (arg), node, spc, 0, true);
1675 /* If the type is a pointer to a tagged type, we need to differentiate
1676 virtual methods from the rest (non-virtual methods, static member
1677 or regular functions) and import only them as primitive operations,
1678 because they make up the virtual table which is mirrored on the Ada
1679 side by the dispatch table. So we add 'Class to the type of every
1680 parameter that is not the first one of a method which either has a
1681 slot in the virtual table or is a constructor. */
1682 if (TREE_TYPE (arg)
1683 && POINTER_TYPE_P (TREE_TYPE (arg))
1684 && is_tagged_type (TREE_TYPE (TREE_TYPE (arg)))
1685 && !(num == 1 && is_method && (DECL_VINDEX (func) || is_constructor)))
1686 pp_string (buffer, "'Class");
1688 arg = TREE_CHAIN (arg);
1690 if (num < num_args)
1692 pp_semicolon (buffer);
1694 if (num_args > 2)
1695 newline_and_indent (buffer, spc + INDENT_INCR);
1696 else
1697 pp_space (buffer);
1701 if (have_ellipsis)
1703 pp_string (buffer, " -- , ...");
1704 newline_and_indent (buffer, spc + INDENT_INCR);
1707 if (num_args > 0)
1708 pp_right_paren (buffer);
1709 return num_args;
1712 /* Dump in BUFFER all the domains associated with an array NODE,
1713 using Ada syntax. SPC is the current indentation level. */
1715 static void
1716 dump_ada_array_domains (pretty_printer *buffer, tree node, int spc)
1718 int first = 1;
1719 pp_left_paren (buffer);
1721 for (; TREE_CODE (node) == ARRAY_TYPE; node = TREE_TYPE (node))
1723 tree domain = TYPE_DOMAIN (node);
1725 if (domain)
1727 tree min = TYPE_MIN_VALUE (domain);
1728 tree max = TYPE_MAX_VALUE (domain);
1730 if (!first)
1731 pp_string (buffer, ", ");
1732 first = 0;
1734 if (min)
1735 dump_generic_ada_node (buffer, min, NULL_TREE, spc, 0, true);
1736 pp_string (buffer, " .. ");
1738 /* If the upper bound is zero, gcc may generate a NULL_TREE
1739 for TYPE_MAX_VALUE rather than an integer_cst. */
1740 if (max)
1741 dump_generic_ada_node (buffer, max, NULL_TREE, spc, 0, true);
1742 else
1743 pp_string (buffer, "0");
1745 else
1746 pp_string (buffer, "size_t");
1748 pp_right_paren (buffer);
1751 /* Dump in BUFFER file:line information related to NODE. */
1753 static void
1754 dump_sloc (pretty_printer *buffer, tree node)
1756 expanded_location xloc;
1758 xloc.file = NULL;
1760 if (DECL_P (node))
1761 xloc = expand_location (DECL_SOURCE_LOCATION (node));
1762 else if (EXPR_HAS_LOCATION (node))
1763 xloc = expand_location (EXPR_LOCATION (node));
1765 if (xloc.file)
1767 pp_string (buffer, xloc.file);
1768 pp_colon (buffer);
1769 pp_decimal_int (buffer, xloc.line);
1773 /* Return true if T designates a one dimension array of "char". */
1775 static bool
1776 is_char_array (tree t)
1778 tree tmp;
1779 int num_dim = 0;
1781 /* Retrieve array's type. */
1782 tmp = t;
1783 while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1785 num_dim++;
1786 tmp = TREE_TYPE (tmp);
1789 tmp = TREE_TYPE (tmp);
1790 return num_dim == 1 && TREE_CODE (tmp) == INTEGER_TYPE
1791 && id_equal (DECL_NAME (TYPE_NAME (tmp)), "char");
1794 /* Dump in BUFFER an array type T in Ada syntax. Assume that the "type"
1795 keyword and name have already been printed. PARENT is the parent node of T.
1796 SPC is the indentation level. */
1798 static void
1799 dump_ada_array_type (pretty_printer *buffer, tree t, tree parent, int spc)
1801 const bool char_array = is_char_array (t);
1802 tree tmp;
1804 /* Special case char arrays. */
1805 if (char_array)
1807 pp_string (buffer, "Interfaces.C.char_array ");
1809 else
1810 pp_string (buffer, "array ");
1812 /* Print the dimensions. */
1813 dump_ada_array_domains (buffer, TREE_TYPE (t), spc);
1815 /* Retrieve the element type. */
1816 tmp = TREE_TYPE (t);
1817 while (TREE_CODE (tmp) == ARRAY_TYPE)
1818 tmp = TREE_TYPE (tmp);
1820 /* Print array's type. */
1821 if (!char_array)
1823 pp_string (buffer, " of ");
1825 if (TREE_CODE (tmp) != POINTER_TYPE)
1826 pp_string (buffer, "aliased ");
1828 if (TYPE_NAME (tmp) || !RECORD_OR_UNION_TYPE_P (tmp))
1829 dump_generic_ada_node (buffer, tmp, TREE_TYPE (t), spc, false, true);
1830 else
1831 dump_ada_double_name (buffer, parent, get_underlying_decl (tmp));
1835 /* Dump in BUFFER type names associated with a template, each prepended with
1836 '_'. TYPES is the TREE_PURPOSE of a DECL_TEMPLATE_INSTANTIATIONS. SPC is
1837 the indentation level. */
1839 static void
1840 dump_template_types (pretty_printer *buffer, tree types, int spc)
1842 size_t i;
1843 size_t len = TREE_VEC_LENGTH (types);
1845 for (i = 0; i < len; i++)
1847 tree elem = TREE_VEC_ELT (types, i);
1848 pp_underscore (buffer);
1849 if (!dump_generic_ada_node (buffer, elem, 0, spc, false, true))
1851 pp_string (buffer, "unknown");
1852 pp_scalar (buffer, "%lu", (unsigned long) TREE_HASH (elem));
1857 /* Dump in BUFFER the contents of all class instantiations associated with
1858 a given template T. SPC is the indentation level. */
1860 static int
1861 dump_ada_template (pretty_printer *buffer, tree t, int spc)
1863 /* DECL_SIZE_UNIT is DECL_TEMPLATE_INSTANTIATIONS in this context. */
1864 tree inst = DECL_SIZE_UNIT (t);
1865 /* This emulates DECL_TEMPLATE_RESULT in this context. */
1866 struct tree_template_decl {
1867 struct tree_decl_common common;
1868 tree arguments;
1869 tree result;
1871 tree result = ((struct tree_template_decl *) t)->result;
1872 int num_inst = 0;
1874 /* Don't look at template declarations declaring something coming from
1875 another file. This can occur for template friend declarations. */
1876 if (LOCATION_FILE (decl_sloc (result, false))
1877 != LOCATION_FILE (decl_sloc (t, false)))
1878 return 0;
1880 for (; inst && inst != error_mark_node; inst = TREE_CHAIN (inst))
1882 tree types = TREE_PURPOSE (inst);
1883 tree instance = TREE_VALUE (inst);
1885 if (TREE_VEC_LENGTH (types) == 0)
1886 break;
1888 if (!RECORD_OR_UNION_TYPE_P (instance))
1889 break;
1891 /* We are interested in concrete template instantiations only: skip
1892 partially specialized nodes. */
1893 if (RECORD_OR_UNION_TYPE_P (instance)
1894 && cpp_check
1895 && cpp_check (instance, HAS_DEPENDENT_TEMPLATE_ARGS))
1896 continue;
1898 num_inst++;
1899 INDENT (spc);
1900 pp_string (buffer, "package ");
1901 package_prefix = false;
1902 dump_generic_ada_node (buffer, instance, t, spc, false, true);
1903 dump_template_types (buffer, types, spc);
1904 pp_string (buffer, " is");
1905 spc += INDENT_INCR;
1906 newline_and_indent (buffer, spc);
1908 TREE_VISITED (get_underlying_decl (instance)) = 1;
1909 pp_string (buffer, "type ");
1910 dump_generic_ada_node (buffer, instance, t, spc, false, true);
1911 package_prefix = true;
1913 if (is_tagged_type (instance))
1914 pp_string (buffer, " is tagged limited ");
1915 else
1916 pp_string (buffer, " is limited ");
1918 dump_generic_ada_node (buffer, instance, t, spc, false, false);
1919 pp_newline (buffer);
1920 spc -= INDENT_INCR;
1921 newline_and_indent (buffer, spc);
1923 pp_string (buffer, "end;");
1924 newline_and_indent (buffer, spc);
1925 pp_string (buffer, "use ");
1926 package_prefix = false;
1927 dump_generic_ada_node (buffer, instance, t, spc, false, true);
1928 dump_template_types (buffer, types, spc);
1929 package_prefix = true;
1930 pp_semicolon (buffer);
1931 pp_newline (buffer);
1932 pp_newline (buffer);
1935 return num_inst > 0;
1938 /* Return true if NODE is a simple enum types, that can be mapped to an
1939 Ada enum type directly. */
1941 static bool
1942 is_simple_enum (tree node)
1944 HOST_WIDE_INT count = 0;
1945 tree value;
1947 for (value = TYPE_VALUES (node); value; value = TREE_CHAIN (value))
1949 tree int_val = TREE_VALUE (value);
1951 if (TREE_CODE (int_val) != INTEGER_CST)
1952 int_val = DECL_INITIAL (int_val);
1954 if (!tree_fits_shwi_p (int_val))
1955 return false;
1956 else if (tree_to_shwi (int_val) != count)
1957 return false;
1959 count++;
1962 return true;
1965 static bool bitfield_used = false;
1967 /* Recursively dump in BUFFER Ada declarations corresponding to NODE of type
1968 TYPE. SPC is the indentation level. LIMITED_ACCESS indicates whether NODE
1969 can be referenced via a "limited with" clause. NAME_ONLY indicates whether
1970 we should only dump the name of NODE, instead of its full declaration. */
1972 static int
1973 dump_generic_ada_node (pretty_printer *buffer, tree node, tree type, int spc,
1974 int limited_access, bool name_only)
1976 if (node == NULL_TREE)
1977 return 0;
1979 switch (TREE_CODE (node))
1981 case ERROR_MARK:
1982 pp_string (buffer, "<<< error >>>");
1983 return 0;
1985 case IDENTIFIER_NODE:
1986 pp_ada_tree_identifier (buffer, node, type, limited_access);
1987 break;
1989 case TREE_LIST:
1990 pp_string (buffer, "--- unexpected node: TREE_LIST");
1991 return 0;
1993 case TREE_BINFO:
1994 dump_generic_ada_node
1995 (buffer, BINFO_TYPE (node), type, spc, limited_access, name_only);
1996 return 0;
1998 case TREE_VEC:
1999 pp_string (buffer, "--- unexpected node: TREE_VEC");
2000 return 0;
2002 case VOID_TYPE:
2003 if (package_prefix)
2005 append_withs ("System", false);
2006 pp_string (buffer, "System.Address");
2008 else
2009 pp_string (buffer, "address");
2010 break;
2012 case VECTOR_TYPE:
2013 pp_string (buffer, "<vector>");
2014 break;
2016 case COMPLEX_TYPE:
2017 pp_string (buffer, "<complex>");
2018 break;
2020 case ENUMERAL_TYPE:
2021 if (name_only)
2022 dump_generic_ada_node (buffer, TYPE_NAME (node), node, spc, 0, true);
2023 else
2025 tree value = TYPE_VALUES (node);
2027 if (is_simple_enum (node))
2029 bool first = true;
2030 spc += INDENT_INCR;
2031 newline_and_indent (buffer, spc - 1);
2032 pp_left_paren (buffer);
2033 for (; value; value = TREE_CHAIN (value))
2035 if (first)
2036 first = false;
2037 else
2039 pp_comma (buffer);
2040 newline_and_indent (buffer, spc);
2043 pp_ada_tree_identifier
2044 (buffer, TREE_PURPOSE (value), node, false);
2046 pp_string (buffer, ");");
2047 spc -= INDENT_INCR;
2048 newline_and_indent (buffer, spc);
2049 pp_string (buffer, "pragma Convention (C, ");
2050 dump_generic_ada_node
2051 (buffer, DECL_NAME (type) ? type : TYPE_NAME (node), type,
2052 spc, 0, true);
2053 pp_right_paren (buffer);
2055 else
2057 if (TYPE_UNSIGNED (node))
2058 pp_string (buffer, "unsigned");
2059 else
2060 pp_string (buffer, "int");
2061 for (; value; value = TREE_CHAIN (value))
2063 pp_semicolon (buffer);
2064 newline_and_indent (buffer, spc);
2066 pp_ada_tree_identifier
2067 (buffer, TREE_PURPOSE (value), node, false);
2068 pp_string (buffer, " : constant ");
2070 dump_generic_ada_node
2071 (buffer, DECL_NAME (type) ? type : TYPE_NAME (node), type,
2072 spc, 0, true);
2074 pp_string (buffer, " := ");
2075 dump_generic_ada_node
2076 (buffer,
2077 TREE_CODE (TREE_VALUE (value)) == INTEGER_CST ?
2078 TREE_VALUE (value) : DECL_INITIAL (TREE_VALUE (value)),
2079 node, spc, false, true);
2083 break;
2085 case INTEGER_TYPE:
2086 case REAL_TYPE:
2087 case FIXED_POINT_TYPE:
2088 case BOOLEAN_TYPE:
2090 enum tree_code_class tclass;
2092 tclass = TREE_CODE_CLASS (TREE_CODE (node));
2094 if (tclass == tcc_declaration)
2096 if (DECL_NAME (node))
2097 pp_ada_tree_identifier
2098 (buffer, DECL_NAME (node), NULL_TREE, limited_access);
2099 else
2100 pp_string (buffer, "<unnamed type decl>");
2102 else if (tclass == tcc_type)
2104 if (TYPE_NAME (node))
2106 if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
2107 pp_ada_tree_identifier (buffer, TYPE_NAME (node),
2108 node, limited_access);
2109 else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
2110 && DECL_NAME (TYPE_NAME (node)))
2111 dump_ada_decl_name (buffer, TYPE_NAME (node), limited_access);
2112 else
2113 pp_string (buffer, "<unnamed type>");
2115 else if (TREE_CODE (node) == INTEGER_TYPE)
2117 append_withs ("Interfaces.C.Extensions", false);
2118 bitfield_used = true;
2120 if (TYPE_PRECISION (node) == 1)
2121 pp_string (buffer, "Extensions.Unsigned_1");
2122 else
2124 pp_string (buffer, (TYPE_UNSIGNED (node)
2125 ? "Extensions.Unsigned_"
2126 : "Extensions.Signed_"));
2127 pp_decimal_int (buffer, TYPE_PRECISION (node));
2130 else
2131 pp_string (buffer, "<unnamed type>");
2133 break;
2136 case POINTER_TYPE:
2137 case REFERENCE_TYPE:
2138 if (name_only && TYPE_NAME (node))
2139 dump_generic_ada_node
2140 (buffer, TYPE_NAME (node), node, spc, limited_access, true);
2142 else if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
2144 tree fnode = TREE_TYPE (node);
2145 bool is_function;
2147 if (VOID_TYPE_P (TREE_TYPE (fnode)))
2149 is_function = false;
2150 pp_string (buffer, "access procedure");
2152 else
2154 is_function = true;
2155 pp_string (buffer, "access function");
2158 dump_ada_function_declaration
2159 (buffer, node, false, false, false, spc + INDENT_INCR);
2161 if (is_function)
2163 pp_string (buffer, " return ");
2164 dump_generic_ada_node
2165 (buffer, TREE_TYPE (fnode), type, spc, 0, true);
2168 /* If we are dumping the full type, it means we are part of a
2169 type definition and need also a Convention C pragma. */
2170 if (!name_only)
2172 pp_semicolon (buffer);
2173 newline_and_indent (buffer, spc);
2174 pp_string (buffer, "pragma Convention (C, ");
2175 dump_generic_ada_node
2176 (buffer, type, 0, spc, false, true);
2177 pp_right_paren (buffer);
2180 else
2182 int is_access = false;
2183 unsigned int quals = TYPE_QUALS (TREE_TYPE (node));
2185 if (VOID_TYPE_P (TREE_TYPE (node)))
2187 if (!name_only)
2188 pp_string (buffer, "new ");
2189 if (package_prefix)
2191 append_withs ("System", false);
2192 pp_string (buffer, "System.Address");
2194 else
2195 pp_string (buffer, "address");
2197 else
2199 if (TREE_CODE (node) == POINTER_TYPE
2200 && TREE_CODE (TREE_TYPE (node)) == INTEGER_TYPE
2201 && !strcmp
2202 (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME
2203 (TREE_TYPE (node)))), "char"))
2205 if (!name_only)
2206 pp_string (buffer, "new ");
2208 if (package_prefix)
2210 pp_string (buffer, "Interfaces.C.Strings.chars_ptr");
2211 append_withs ("Interfaces.C.Strings", false);
2213 else
2214 pp_string (buffer, "chars_ptr");
2216 else
2218 tree type_name = TYPE_NAME (TREE_TYPE (node));
2219 tree decl = get_underlying_decl (TREE_TYPE (node));
2220 tree enclosing_decl = get_underlying_decl (type);
2222 /* For now, handle access-to-access, access-to-empty-struct
2223 or access-to-incomplete as opaque system.address. */
2224 if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE
2225 || (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node))
2226 && !TYPE_FIELDS (TREE_TYPE (node)))
2227 || !decl
2228 || (!enclosing_decl
2229 && !TREE_VISITED (decl)
2230 && DECL_SOURCE_FILE (decl) == source_file_base)
2231 || (enclosing_decl
2232 && !TREE_VISITED (decl)
2233 && DECL_SOURCE_FILE (decl)
2234 == DECL_SOURCE_FILE (enclosing_decl)
2235 && decl_sloc (decl, true)
2236 > decl_sloc (enclosing_decl, true)))
2238 if (package_prefix)
2240 append_withs ("System", false);
2241 if (!name_only)
2242 pp_string (buffer, "new ");
2243 pp_string (buffer, "System.Address");
2245 else
2246 pp_string (buffer, "address");
2247 return spc;
2250 if (!package_prefix)
2251 pp_string (buffer, "access");
2252 else if (AGGREGATE_TYPE_P (TREE_TYPE (node)))
2254 if (!type || TREE_CODE (type) != FUNCTION_DECL)
2256 pp_string (buffer, "access ");
2257 is_access = true;
2259 if (quals & TYPE_QUAL_CONST)
2260 pp_string (buffer, "constant ");
2261 else if (!name_only)
2262 pp_string (buffer, "all ");
2264 else if (quals & TYPE_QUAL_CONST)
2265 pp_string (buffer, "in ");
2266 else
2268 is_access = true;
2269 pp_string (buffer, "access ");
2270 /* ??? should be configurable: access or in out. */
2273 else
2275 is_access = true;
2276 pp_string (buffer, "access ");
2278 if (!name_only)
2279 pp_string (buffer, "all ");
2282 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node)) && type_name)
2283 dump_generic_ada_node (buffer, type_name, TREE_TYPE (node),
2284 spc, is_access, true);
2285 else
2286 dump_generic_ada_node (buffer, TREE_TYPE (node),
2287 TREE_TYPE (node), spc, 0, true);
2291 break;
2293 case ARRAY_TYPE:
2294 if (name_only)
2295 dump_generic_ada_node
2296 (buffer, TYPE_NAME (node), node, spc, limited_access, true);
2297 else
2298 dump_ada_array_type (buffer, node, type, spc);
2299 break;
2301 case RECORD_TYPE:
2302 case UNION_TYPE:
2303 if (name_only)
2305 if (TYPE_NAME (node))
2306 dump_generic_ada_node
2307 (buffer, TYPE_NAME (node), node, spc, limited_access, true);
2308 else
2310 pp_string (buffer, "anon_");
2311 pp_scalar (buffer, "%d", TYPE_UID (node));
2314 else
2315 print_ada_struct_decl (buffer, node, type, spc, true);
2316 break;
2318 case INTEGER_CST:
2319 /* We treat the upper half of the sizetype range as negative. This
2320 is consistent with the internal treatment and makes it possible
2321 to generate the (0 .. -1) range for flexible array members. */
2322 if (TREE_TYPE (node) == sizetype)
2323 node = fold_convert (ssizetype, node);
2324 if (tree_fits_shwi_p (node))
2325 pp_wide_integer (buffer, tree_to_shwi (node));
2326 else if (tree_fits_uhwi_p (node))
2327 pp_unsigned_wide_integer (buffer, tree_to_uhwi (node));
2328 else
2330 wide_int val = node;
2331 int i;
2332 if (wi::neg_p (val))
2334 pp_minus (buffer);
2335 val = -val;
2337 sprintf (pp_buffer (buffer)->digit_buffer,
2338 "16#%" HOST_WIDE_INT_PRINT "x",
2339 val.elt (val.get_len () - 1));
2340 for (i = val.get_len () - 2; i >= 0; i--)
2341 sprintf (pp_buffer (buffer)->digit_buffer,
2342 HOST_WIDE_INT_PRINT_PADDED_HEX, val.elt (i));
2343 pp_string (buffer, pp_buffer (buffer)->digit_buffer);
2345 break;
2347 case REAL_CST:
2348 case FIXED_CST:
2349 case COMPLEX_CST:
2350 case STRING_CST:
2351 case VECTOR_CST:
2352 return 0;
2354 case FUNCTION_DECL:
2355 case CONST_DECL:
2356 dump_ada_decl_name (buffer, node, limited_access);
2357 break;
2359 case TYPE_DECL:
2360 if (DECL_IS_BUILTIN (node))
2362 /* Don't print the declaration of built-in types. */
2364 if (name_only)
2366 /* If we're in the middle of a declaration, defaults to
2367 System.Address. */
2368 if (package_prefix)
2370 append_withs ("System", false);
2371 pp_string (buffer, "System.Address");
2373 else
2374 pp_string (buffer, "address");
2376 break;
2379 if (name_only)
2380 dump_ada_decl_name (buffer, node, limited_access);
2381 else
2383 if (is_tagged_type (TREE_TYPE (node)))
2385 int first = 1;
2387 /* Look for ancestors. */
2388 for (tree fld = TYPE_FIELDS (TREE_TYPE (node));
2389 fld;
2390 fld = TREE_CHAIN (fld))
2392 if (!DECL_NAME (fld) && is_tagged_type (TREE_TYPE (fld)))
2394 if (first)
2396 pp_string (buffer, "limited new ");
2397 first = 0;
2399 else
2400 pp_string (buffer, " and ");
2402 dump_ada_decl_name (buffer, TYPE_NAME (TREE_TYPE (fld)),
2403 false);
2407 pp_string (buffer, first ? "tagged limited " : " with ");
2409 else if (has_nontrivial_methods (TREE_TYPE (node)))
2410 pp_string (buffer, "limited ");
2412 dump_generic_ada_node
2413 (buffer, TREE_TYPE (node), type, spc, false, false);
2415 break;
2417 case VAR_DECL:
2418 case PARM_DECL:
2419 case FIELD_DECL:
2420 case NAMESPACE_DECL:
2421 dump_ada_decl_name (buffer, node, false);
2422 break;
2424 default:
2425 /* Ignore other nodes (e.g. expressions). */
2426 return 0;
2429 return 1;
2432 /* Dump in BUFFER NODE's methods. SPC is the indentation level. Return 1 if
2433 methods were printed, 0 otherwise. */
2435 static int
2436 print_ada_methods (pretty_printer *buffer, tree node, int spc)
2438 if (!has_nontrivial_methods (node))
2439 return 0;
2441 pp_semicolon (buffer);
2443 int res = 1;
2444 for (tree fld = TYPE_FIELDS (node); fld; fld = DECL_CHAIN (fld))
2445 if (TREE_CODE (TREE_TYPE (fld)) == METHOD_TYPE)
2447 if (res)
2449 pp_newline (buffer);
2450 pp_newline (buffer);
2453 res = print_ada_declaration (buffer, fld, node, spc);
2456 return 1;
2459 static void dump_nested_type (pretty_printer *, tree, tree, tree, int);
2461 /* Dump in BUFFER anonymous types nested inside T's definition.
2462 PARENT is the parent node of T.
2463 FORWARD indicates whether a forward declaration of T should be generated.
2464 SPC is the indentation level.
2466 In C anonymous nested tagged types have no name whereas in C++ they have
2467 one. In C their TYPE_DECL is at top level whereas in C++ it is nested.
2468 In both languages untagged types (pointers and arrays) have no name.
2469 In C++ the nested TYPE_DECLs can come after their associated FIELD_DECL.
2471 Therefore, in order to have a common processing for both languages, we
2472 disregard anonymous TYPE_DECLs at top level and here we make a first
2473 pass on the nested TYPE_DECLs and a second pass on the unnamed types. */
2475 static void
2476 dump_nested_types (pretty_printer *buffer, tree t, tree parent, bool forward,
2477 int spc)
2479 tree type, field;
2481 /* Avoid recursing over the same tree. */
2482 if (TREE_VISITED (t))
2483 return;
2485 /* Find possible anonymous pointers/arrays/structs/unions recursively. */
2486 type = TREE_TYPE (t);
2487 if (type == NULL_TREE)
2488 return;
2490 if (forward)
2492 pp_string (buffer, "type ");
2493 dump_generic_ada_node (buffer, t, t, spc, false, true);
2494 pp_semicolon (buffer);
2495 newline_and_indent (buffer, spc);
2496 TREE_VISITED (t) = 1;
2499 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
2500 if (TREE_CODE (field) == TYPE_DECL
2501 && DECL_NAME (field) != DECL_NAME (t)
2502 && TYPE_NAME (TREE_TYPE (field)) != TYPE_NAME (type))
2503 dump_nested_type (buffer, field, t, parent, spc);
2505 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
2506 if (TREE_CODE (field) == FIELD_DECL && !TYPE_NAME (TREE_TYPE (field)))
2507 dump_nested_type (buffer, field, t, parent, spc);
2509 TREE_VISITED (t) = 1;
2512 /* Dump in BUFFER the anonymous type of FIELD inside T.
2513 PARENT is the parent node of T.
2514 FORWARD indicates whether a forward declaration of T should be generated.
2515 SPC is the indentation level. */
2517 static void
2518 dump_nested_type (pretty_printer *buffer, tree field, tree t, tree parent,
2519 int spc)
2521 tree field_type = TREE_TYPE (field);
2522 tree decl, tmp;
2524 switch (TREE_CODE (field_type))
2526 case POINTER_TYPE:
2527 tmp = TREE_TYPE (field_type);
2529 if (TREE_CODE (tmp) == FUNCTION_TYPE)
2530 for (tmp = TREE_TYPE (tmp);
2531 tmp && TREE_CODE (tmp) == POINTER_TYPE;
2532 tmp = TREE_TYPE (tmp))
2535 decl = get_underlying_decl (tmp);
2536 if (decl
2537 && !DECL_IS_BUILTIN (decl)
2538 && (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl))
2539 || TYPE_FIELDS (TREE_TYPE (decl)))
2540 && !TREE_VISITED (decl)
2541 && DECL_SOURCE_FILE (decl) == DECL_SOURCE_FILE (t)
2542 && decl_sloc (decl, true) > decl_sloc (t, true))
2544 /* Generate forward declaration. */
2545 pp_string (buffer, "type ");
2546 dump_generic_ada_node (buffer, decl, 0, spc, false, true);
2547 pp_semicolon (buffer);
2548 newline_and_indent (buffer, spc);
2549 TREE_VISITED (decl) = 1;
2551 break;
2553 case ARRAY_TYPE:
2554 tmp = TREE_TYPE (field_type);
2555 while (TREE_CODE (tmp) == ARRAY_TYPE)
2556 tmp = TREE_TYPE (tmp);
2557 decl = get_underlying_decl (tmp);
2558 if (decl && !DECL_NAME (decl) && !TREE_VISITED (decl))
2560 /* Generate full declaration. */
2561 dump_nested_type (buffer, decl, t, parent, spc);
2562 TREE_VISITED (decl) = 1;
2565 /* Special case char arrays. */
2566 if (is_char_array (field))
2567 pp_string (buffer, "sub");
2569 pp_string (buffer, "type ");
2570 dump_ada_double_name (buffer, parent, field);
2571 pp_string (buffer, " is ");
2572 dump_ada_array_type (buffer, field, parent, spc);
2573 pp_semicolon (buffer);
2574 newline_and_indent (buffer, spc);
2575 break;
2577 case RECORD_TYPE:
2578 case UNION_TYPE:
2579 if (TYPE_NAME (TREE_TYPE (t)) && !TREE_VISITED (t))
2581 pp_string (buffer, "type ");
2582 dump_generic_ada_node (buffer, t, parent, spc, false, true);
2583 pp_semicolon (buffer);
2584 newline_and_indent (buffer, spc);
2587 TREE_VISITED (t) = 1;
2588 dump_nested_types (buffer, field, t, false, spc);
2590 pp_string (buffer, "type ");
2592 if (TYPE_NAME (field_type))
2594 dump_generic_ada_node (buffer, field_type, 0, spc, false, true);
2595 if (TREE_CODE (field_type) == UNION_TYPE)
2596 pp_string (buffer, " (discr : unsigned := 0)");
2597 pp_string (buffer, " is ");
2598 print_ada_struct_decl (buffer, field_type, t, spc, false);
2600 pp_string (buffer, "pragma Convention (C_Pass_By_Copy, ");
2601 dump_generic_ada_node (buffer, field_type, 0, spc, false, true);
2602 pp_string (buffer, ");");
2603 newline_and_indent (buffer, spc);
2605 if (TREE_CODE (field_type) == UNION_TYPE)
2607 pp_string (buffer, "pragma Unchecked_Union (");
2608 dump_generic_ada_node (buffer, field_type, 0, spc, false, true);
2609 pp_string (buffer, ");");
2612 else
2614 dump_ada_double_name (buffer, parent, field);
2615 if (TREE_CODE (field_type) == UNION_TYPE)
2616 pp_string (buffer, " (discr : unsigned := 0)");
2617 pp_string (buffer, " is ");
2618 print_ada_struct_decl (buffer, field_type, t, spc, false);
2620 pp_string (buffer, "pragma Convention (C_Pass_By_Copy, ");
2621 dump_ada_double_name (buffer, parent, field);
2622 pp_string (buffer, ");");
2623 newline_and_indent (buffer, spc);
2625 if (TREE_CODE (field_type) == UNION_TYPE)
2627 pp_string (buffer, "pragma Unchecked_Union (");
2628 dump_ada_double_name (buffer, parent, field);
2629 pp_string (buffer, ");");
2633 default:
2634 break;
2638 /* Dump in BUFFER constructor spec corresponding to T for TYPE. */
2640 static void
2641 print_constructor (pretty_printer *buffer, tree t, tree type)
2643 tree decl_name = DECL_NAME (TYPE_NAME (type));
2645 pp_string (buffer, "New_");
2646 pp_ada_tree_identifier (buffer, decl_name, t, false);
2649 /* Dump in BUFFER destructor spec corresponding to T. */
2651 static void
2652 print_destructor (pretty_printer *buffer, tree t, tree type)
2654 tree decl_name = DECL_NAME (TYPE_NAME (type));
2656 pp_string (buffer, "Delete_");
2657 pp_ada_tree_identifier (buffer, decl_name, t, false);
2660 /* Return the name of type T. */
2662 static const char *
2663 type_name (tree t)
2665 tree n = TYPE_NAME (t);
2667 if (TREE_CODE (n) == IDENTIFIER_NODE)
2668 return IDENTIFIER_POINTER (n);
2669 else
2670 return IDENTIFIER_POINTER (DECL_NAME (n));
2673 /* Print in BUFFER the declaration of a variable T of type TYPE in Ada syntax.
2674 SPC is the indentation level. Return 1 if a declaration was printed,
2675 0 otherwise. */
2677 static int
2678 print_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc)
2680 int is_var = 0, need_indent = 0;
2681 int is_class = false;
2682 tree name = TYPE_NAME (TREE_TYPE (t));
2683 tree decl_name = DECL_NAME (t);
2684 tree orig = NULL_TREE;
2686 if (cpp_check && cpp_check (t, IS_TEMPLATE))
2687 return dump_ada_template (buffer, t, spc);
2689 if (TREE_CODE (t) == CONST_DECL && TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE)
2690 /* Skip enumeral values: will be handled as part of the type itself. */
2691 return 0;
2693 if (TREE_CODE (t) == TYPE_DECL)
2695 orig = DECL_ORIGINAL_TYPE (t);
2697 if (orig && TYPE_STUB_DECL (orig))
2699 tree stub = TYPE_STUB_DECL (orig);
2700 tree typ = TREE_TYPE (stub);
2702 if (TYPE_NAME (typ))
2704 /* If types have same representation, and same name (ignoring
2705 casing), then ignore the second type. */
2706 if (type_name (typ) == type_name (TREE_TYPE (t))
2707 || !strcasecmp (type_name (typ), type_name (TREE_TYPE (t))))
2709 TREE_VISITED (t) = 1;
2710 return 0;
2713 INDENT (spc);
2715 if (RECORD_OR_UNION_TYPE_P (typ) && !TYPE_FIELDS (typ))
2717 pp_string (buffer, "-- skipped empty struct ");
2718 dump_generic_ada_node (buffer, t, type, spc, false, true);
2720 else
2722 if (RECORD_OR_UNION_TYPE_P (typ)
2723 && DECL_SOURCE_FILE (stub) == source_file_base)
2724 dump_nested_types (buffer, stub, stub, true, spc);
2726 pp_string (buffer, "subtype ");
2727 dump_generic_ada_node (buffer, t, type, spc, false, true);
2728 pp_string (buffer, " is ");
2729 dump_generic_ada_node (buffer, typ, type, spc, false, true);
2730 pp_string (buffer, "; -- ");
2731 dump_sloc (buffer, t);
2734 TREE_VISITED (t) = 1;
2735 return 1;
2739 /* Skip unnamed or anonymous structs/unions/enum types. */
2740 if (!orig && !decl_name && !name
2741 && (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t))
2742 || TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE))
2743 return 0;
2745 /* Skip anonymous enum types (duplicates of real types). */
2746 if (!orig
2747 && TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE
2748 && decl_name
2749 && (*IDENTIFIER_POINTER (decl_name) == '.'
2750 || *IDENTIFIER_POINTER (decl_name) == '$'))
2751 return 0;
2753 INDENT (spc);
2755 switch (TREE_CODE (TREE_TYPE (t)))
2757 case RECORD_TYPE:
2758 case UNION_TYPE:
2759 /* Skip empty structs (typically forward references to real
2760 structs). */
2761 if (!TYPE_FIELDS (TREE_TYPE (t)))
2763 pp_string (buffer, "-- skipped empty struct ");
2764 dump_generic_ada_node (buffer, t, type, spc, false, true);
2765 return 1;
2768 if (decl_name
2769 && (*IDENTIFIER_POINTER (decl_name) == '.'
2770 || *IDENTIFIER_POINTER (decl_name) == '$'))
2772 pp_string (buffer, "-- skipped anonymous struct ");
2773 dump_generic_ada_node (buffer, t, type, spc, false, true);
2774 TREE_VISITED (t) = 1;
2775 return 1;
2778 if (orig && TYPE_NAME (orig) && orig != TREE_TYPE (t))
2779 pp_string (buffer, "subtype ");
2780 else
2782 dump_nested_types (buffer, t, t, false, spc);
2784 if (separate_class_package (t))
2786 is_class = true;
2787 pp_string (buffer, "package Class_");
2788 dump_generic_ada_node (buffer, t, type, spc, false, true);
2789 pp_string (buffer, " is");
2790 spc += INDENT_INCR;
2791 newline_and_indent (buffer, spc);
2794 pp_string (buffer, "type ");
2796 break;
2798 case ARRAY_TYPE:
2799 case POINTER_TYPE:
2800 case REFERENCE_TYPE:
2801 if ((orig && TYPE_NAME (orig) && orig != TREE_TYPE (t))
2802 || is_char_array (t))
2803 pp_string (buffer, "subtype ");
2804 else
2805 pp_string (buffer, "type ");
2806 break;
2808 case FUNCTION_TYPE:
2809 pp_string (buffer, "-- skipped function type ");
2810 dump_generic_ada_node (buffer, t, type, spc, false, true);
2811 return 1;
2813 case ENUMERAL_TYPE:
2814 if ((orig && TYPE_NAME (orig) && orig != TREE_TYPE (t))
2815 || !is_simple_enum (TREE_TYPE (t)))
2816 pp_string (buffer, "subtype ");
2817 else
2818 pp_string (buffer, "type ");
2819 break;
2821 default:
2822 pp_string (buffer, "subtype ");
2824 TREE_VISITED (t) = 1;
2826 else
2828 if (VAR_P (t)
2829 && decl_name
2830 && *IDENTIFIER_POINTER (decl_name) == '_')
2831 return 0;
2833 need_indent = 1;
2836 /* Print the type and name. */
2837 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
2839 if (need_indent)
2840 INDENT (spc);
2842 /* Print variable's name. */
2843 dump_generic_ada_node (buffer, t, type, spc, false, true);
2845 if (TREE_CODE (t) == TYPE_DECL)
2847 pp_string (buffer, " is ");
2849 if (orig && TYPE_NAME (orig) && orig != TREE_TYPE (t))
2850 dump_generic_ada_node
2851 (buffer, TYPE_NAME (orig), type, spc, false, true);
2852 else
2853 dump_ada_array_type (buffer, t, type, spc);
2855 else
2857 tree tmp = TYPE_NAME (TREE_TYPE (t));
2859 if (spc == INDENT_INCR || TREE_STATIC (t))
2860 is_var = 1;
2862 pp_string (buffer, " : ");
2864 if (TREE_CODE (TREE_TYPE (TREE_TYPE (t))) != POINTER_TYPE)
2865 pp_string (buffer, "aliased ");
2867 if (tmp)
2868 dump_generic_ada_node (buffer, tmp, type, spc, false, true);
2869 else if (type)
2870 dump_ada_double_name (buffer, type, t);
2871 else
2872 dump_ada_array_type (buffer, t, type, spc);
2875 else if (TREE_CODE (t) == FUNCTION_DECL)
2877 bool is_function, is_abstract_class = false;
2878 bool is_method = TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE;
2879 tree decl_name = DECL_NAME (t);
2880 bool is_abstract = false;
2881 bool is_constructor = false;
2882 bool is_destructor = false;
2883 bool is_copy_constructor = false;
2884 bool is_move_constructor = false;
2886 if (!decl_name)
2887 return 0;
2889 if (cpp_check)
2891 is_abstract = cpp_check (t, IS_ABSTRACT);
2892 is_constructor = cpp_check (t, IS_CONSTRUCTOR);
2893 is_destructor = cpp_check (t, IS_DESTRUCTOR);
2894 is_copy_constructor = cpp_check (t, IS_COPY_CONSTRUCTOR);
2895 is_move_constructor = cpp_check (t, IS_MOVE_CONSTRUCTOR);
2898 /* Skip copy constructors and C++11 move constructors: some are internal
2899 only and those that are not cannot be called easily from Ada. */
2900 if (is_copy_constructor || is_move_constructor)
2901 return 0;
2903 if (is_constructor || is_destructor)
2905 /* ??? Skip implicit constructors/destructors for now. */
2906 if (DECL_ARTIFICIAL (t))
2907 return 0;
2909 /* Only consider constructors/destructors for complete objects. */
2910 if (strncmp (IDENTIFIER_POINTER (decl_name), "__ct_comp", 9) != 0
2911 && strncmp (IDENTIFIER_POINTER (decl_name), "__dt_comp", 9) != 0)
2912 return 0;
2915 /* If this function has an entry in the vtable, we cannot omit it. */
2916 else if (!DECL_VINDEX (t) && *IDENTIFIER_POINTER (decl_name) == '_')
2918 INDENT (spc);
2919 pp_string (buffer, "-- skipped func ");
2920 pp_string (buffer, IDENTIFIER_POINTER (decl_name));
2921 return 1;
2924 if (need_indent)
2925 INDENT (spc);
2927 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (t))) && !is_constructor)
2929 pp_string (buffer, "procedure ");
2930 is_function = false;
2932 else
2934 pp_string (buffer, "function ");
2935 is_function = true;
2938 if (is_constructor)
2939 print_constructor (buffer, t, type);
2940 else if (is_destructor)
2941 print_destructor (buffer, t, type);
2942 else
2943 dump_ada_decl_name (buffer, t, false);
2945 dump_ada_function_declaration
2946 (buffer, t, is_method, is_constructor, is_destructor, spc);
2948 if (is_function)
2950 pp_string (buffer, " return ");
2951 tree ret_type
2952 = is_constructor ? DECL_CONTEXT (t) : TREE_TYPE (TREE_TYPE (t));
2953 dump_generic_ada_node (buffer, ret_type, type, spc, false, true);
2956 if (is_constructor && RECORD_OR_UNION_TYPE_P (type))
2957 for (tree fld = TYPE_FIELDS (type); fld; fld = DECL_CHAIN (fld))
2958 if (TREE_CODE (TREE_TYPE (fld)) == METHOD_TYPE
2959 && cpp_check (fld, IS_ABSTRACT))
2961 is_abstract_class = true;
2962 break;
2965 if (is_abstract || is_abstract_class)
2966 pp_string (buffer, " is abstract");
2968 pp_semicolon (buffer);
2969 pp_string (buffer, " -- ");
2970 dump_sloc (buffer, t);
2972 if (is_abstract || !DECL_ASSEMBLER_NAME (t))
2973 return 1;
2975 newline_and_indent (buffer, spc);
2977 if (is_constructor)
2979 pp_string (buffer, "pragma CPP_Constructor (");
2980 print_constructor (buffer, t, type);
2981 pp_string (buffer, ", \"");
2982 pp_asm_name (buffer, t);
2983 pp_string (buffer, "\");");
2985 else if (is_destructor)
2987 pp_string (buffer, "pragma Import (CPP, ");
2988 print_destructor (buffer, t, type);
2989 pp_string (buffer, ", \"");
2990 pp_asm_name (buffer, t);
2991 pp_string (buffer, "\");");
2993 else
2995 dump_ada_import (buffer, t);
2998 return 1;
3000 else if (TREE_CODE (t) == TYPE_DECL && !DECL_ORIGINAL_TYPE (t))
3002 int is_interface = 0;
3003 int is_abstract_record = 0;
3005 if (need_indent)
3006 INDENT (spc);
3008 /* Anonymous structs/unions */
3009 dump_generic_ada_node (buffer, TREE_TYPE (t), t, spc, false, true);
3011 if (TREE_CODE (TREE_TYPE (t)) == UNION_TYPE)
3013 pp_string (buffer, " (discr : unsigned := 0)");
3016 pp_string (buffer, " is ");
3018 /* Check whether we have an Ada interface compatible class.
3019 That is only have a vtable non-static data member and no
3020 non-abstract methods. */
3021 if (cpp_check
3022 && RECORD_OR_UNION_TYPE_P (TREE_TYPE (t)))
3024 bool has_fields = false;
3026 /* Check that there are no fields other than the virtual table. */
3027 for (tree fld = TYPE_FIELDS (TREE_TYPE (t));
3028 fld;
3029 fld = TREE_CHAIN (fld))
3031 if (TREE_CODE (fld) == FIELD_DECL)
3033 if (!has_fields && DECL_VIRTUAL_P (fld))
3034 is_interface = 1;
3035 else
3036 is_interface = 0;
3037 has_fields = true;
3039 else if (TREE_CODE (TREE_TYPE (fld)) == METHOD_TYPE
3040 && !DECL_ARTIFICIAL (fld))
3042 if (cpp_check (fld, IS_ABSTRACT))
3043 is_abstract_record = 1;
3044 else
3045 is_interface = 0;
3050 TREE_VISITED (t) = 1;
3051 if (is_interface)
3053 pp_string (buffer, "limited interface; -- ");
3054 dump_sloc (buffer, t);
3055 newline_and_indent (buffer, spc);
3056 pp_string (buffer, "pragma Import (CPP, ");
3057 dump_generic_ada_node
3058 (buffer, TYPE_NAME (TREE_TYPE (t)), type, spc, false, true);
3059 pp_right_paren (buffer);
3061 print_ada_methods (buffer, TREE_TYPE (t), spc);
3063 else
3065 if (is_abstract_record)
3066 pp_string (buffer, "abstract ");
3067 dump_generic_ada_node (buffer, t, t, spc, false, false);
3070 else
3072 if (need_indent)
3073 INDENT (spc);
3075 if (TREE_CODE (t) == FIELD_DECL && DECL_NAME (t))
3076 check_name (buffer, t);
3078 /* Print variable/type's name. */
3079 dump_generic_ada_node (buffer, t, t, spc, false, true);
3081 if (TREE_CODE (t) == TYPE_DECL)
3083 tree orig = DECL_ORIGINAL_TYPE (t);
3084 int is_subtype = orig && TYPE_NAME (orig) && orig != TREE_TYPE (t);
3086 if (!is_subtype && TREE_CODE (TREE_TYPE (t)) == UNION_TYPE)
3087 pp_string (buffer, " (discr : unsigned := 0)");
3089 pp_string (buffer, " is ");
3091 dump_generic_ada_node (buffer, orig, t, spc, false, is_subtype);
3093 else
3095 if (spc == INDENT_INCR || TREE_STATIC (t))
3096 is_var = 1;
3098 pp_string (buffer, " : ");
3100 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t)))
3102 pp_string (buffer, "aliased ");
3104 if (TREE_READONLY (t))
3105 pp_string (buffer, "constant ");
3107 if (TYPE_NAME (TREE_TYPE (t)))
3108 dump_generic_ada_node
3109 (buffer, TREE_TYPE (t), t, spc, false, true);
3110 else if (type)
3111 dump_ada_double_name (buffer, type, t);
3113 else
3115 if (TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE
3116 && (TYPE_NAME (TREE_TYPE (t))
3117 || TREE_CODE (TREE_TYPE (t)) != INTEGER_TYPE))
3118 pp_string (buffer, "aliased ");
3120 if (TREE_READONLY (t))
3121 pp_string (buffer, "constant ");
3123 dump_generic_ada_node
3124 (buffer, TREE_TYPE (t), TREE_TYPE (t), spc, false, true);
3129 if (is_class)
3131 spc -= INDENT_INCR;
3132 newline_and_indent (buffer, spc);
3133 pp_string (buffer, "end;");
3134 newline_and_indent (buffer, spc);
3135 pp_string (buffer, "use Class_");
3136 dump_generic_ada_node (buffer, t, type, spc, false, true);
3137 pp_semicolon (buffer);
3138 pp_newline (buffer);
3140 /* All needed indentation/newline performed already, so return 0. */
3141 return 0;
3143 else
3145 pp_string (buffer, "; -- ");
3146 dump_sloc (buffer, t);
3149 if (is_var)
3151 newline_and_indent (buffer, spc);
3152 dump_ada_import (buffer, t);
3155 return 1;
3158 /* Prints in BUFFER a structure NODE of type TYPE: name, fields, and methods
3159 with Ada syntax. SPC is the indentation level. If DISPLAY_CONVENTION is
3160 true, also print the pragma Convention for NODE. */
3162 static void
3163 print_ada_struct_decl (pretty_printer *buffer, tree node, tree type, int spc,
3164 bool display_convention)
3166 tree tmp;
3167 const bool is_union = (TREE_CODE (node) == UNION_TYPE);
3168 char buf[32];
3169 int field_num = 0;
3170 int field_spc = spc + INDENT_INCR;
3171 int need_semicolon;
3173 bitfield_used = false;
3175 if (TYPE_FIELDS (node))
3177 /* Print the contents of the structure. */
3178 pp_string (buffer, "record");
3180 if (is_union)
3182 newline_and_indent (buffer, spc + INDENT_INCR);
3183 pp_string (buffer, "case discr is");
3184 field_spc = spc + INDENT_INCR * 3;
3187 pp_newline (buffer);
3189 /* Print the non-static fields of the structure. */
3190 for (tmp = TYPE_FIELDS (node); tmp; tmp = TREE_CHAIN (tmp))
3192 /* Add parent field if needed. */
3193 if (!DECL_NAME (tmp))
3195 if (!is_tagged_type (TREE_TYPE (tmp)))
3197 if (!TYPE_NAME (TREE_TYPE (tmp)))
3198 print_ada_declaration (buffer, tmp, type, field_spc);
3199 else
3201 INDENT (field_spc);
3203 if (field_num == 0)
3204 pp_string (buffer, "parent : aliased ");
3205 else
3207 sprintf (buf, "field_%d : aliased ", field_num + 1);
3208 pp_string (buffer, buf);
3210 dump_ada_decl_name
3211 (buffer, TYPE_NAME (TREE_TYPE (tmp)), false);
3212 pp_semicolon (buffer);
3214 pp_newline (buffer);
3215 field_num++;
3218 else if (TREE_CODE (tmp) == FIELD_DECL)
3220 /* Skip internal virtual table field. */
3221 if (!DECL_VIRTUAL_P (tmp))
3223 if (is_union)
3225 if (TREE_CHAIN (tmp)
3226 && TREE_TYPE (TREE_CHAIN (tmp)) != node
3227 && TREE_CODE (TREE_CHAIN (tmp)) != TYPE_DECL)
3228 sprintf (buf, "when %d =>", field_num);
3229 else
3230 sprintf (buf, "when others =>");
3232 INDENT (spc + INDENT_INCR * 2);
3233 pp_string (buffer, buf);
3234 pp_newline (buffer);
3237 if (print_ada_declaration (buffer, tmp, type, field_spc))
3239 pp_newline (buffer);
3240 field_num++;
3246 if (is_union)
3248 INDENT (spc + INDENT_INCR);
3249 pp_string (buffer, "end case;");
3250 pp_newline (buffer);
3253 if (field_num == 0)
3255 INDENT (spc + INDENT_INCR);
3256 pp_string (buffer, "null;");
3257 pp_newline (buffer);
3260 INDENT (spc);
3261 pp_string (buffer, "end record;");
3263 else
3264 pp_string (buffer, "null record;");
3266 newline_and_indent (buffer, spc);
3268 if (!display_convention)
3269 return;
3271 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type)))
3273 if (has_nontrivial_methods (TREE_TYPE (type)))
3274 pp_string (buffer, "pragma Import (CPP, ");
3275 else
3276 pp_string (buffer, "pragma Convention (C_Pass_By_Copy, ");
3278 else
3279 pp_string (buffer, "pragma Convention (C, ");
3281 package_prefix = false;
3282 dump_generic_ada_node (buffer, TREE_TYPE (type), type, spc, false, true);
3283 package_prefix = true;
3284 pp_right_paren (buffer);
3286 if (is_union)
3288 pp_semicolon (buffer);
3289 newline_and_indent (buffer, spc);
3290 pp_string (buffer, "pragma Unchecked_Union (");
3292 dump_generic_ada_node (buffer, TREE_TYPE (type), type, spc, false, true);
3293 pp_right_paren (buffer);
3296 if (bitfield_used)
3298 pp_semicolon (buffer);
3299 newline_and_indent (buffer, spc);
3300 pp_string (buffer, "pragma Pack (");
3301 dump_generic_ada_node
3302 (buffer, TREE_TYPE (type), type, spc, false, true);
3303 pp_right_paren (buffer);
3304 bitfield_used = false;
3307 need_semicolon = !print_ada_methods (buffer, node, spc);
3309 /* Print the static fields of the structure, if any. */
3310 for (tmp = TYPE_FIELDS (node); tmp; tmp = TREE_CHAIN (tmp))
3312 if (TREE_CODE (tmp) == VAR_DECL && DECL_NAME (tmp))
3314 if (need_semicolon)
3316 need_semicolon = false;
3317 pp_semicolon (buffer);
3319 pp_newline (buffer);
3320 pp_newline (buffer);
3321 print_ada_declaration (buffer, tmp, type, spc);
3326 /* Dump all the declarations in SOURCE_FILE to an Ada spec.
3327 COLLECT_ALL_REFS is a front-end callback used to collect all relevant
3328 nodes for SOURCE_FILE. CHECK is used to perform C++ queries on nodes. */
3330 static void
3331 dump_ads (const char *source_file,
3332 void (*collect_all_refs)(const char *),
3333 int (*check)(tree, cpp_operation))
3335 char *ads_name;
3336 char *pkg_name;
3337 char *s;
3338 FILE *f;
3340 pkg_name = get_ada_package (source_file);
3342 /* Construct the .ads filename and package name. */
3343 ads_name = xstrdup (pkg_name);
3345 for (s = ads_name; *s; s++)
3346 if (*s == '.')
3347 *s = '-';
3348 else
3349 *s = TOLOWER (*s);
3351 ads_name = reconcat (ads_name, ads_name, ".ads", NULL);
3353 /* Write out the .ads file. */
3354 f = fopen (ads_name, "w");
3355 if (f)
3357 pretty_printer pp;
3359 pp_needs_newline (&pp) = true;
3360 pp.buffer->stream = f;
3362 /* Dump all relevant macros. */
3363 dump_ada_macros (&pp, source_file);
3365 /* Reset the table of withs for this file. */
3366 reset_ada_withs ();
3368 (*collect_all_refs) (source_file);
3370 /* Dump all references. */
3371 cpp_check = check;
3372 dump_ada_nodes (&pp, source_file);
3374 /* Requires Ada 2005 syntax, so generate corresponding pragma.
3375 Also, disable style checks since this file is auto-generated. */
3376 fprintf (f, "pragma Ada_2005;\npragma Style_Checks (Off);\n\n");
3378 /* Dump withs. */
3379 dump_ada_withs (f);
3381 fprintf (f, "\npackage %s is\n\n", pkg_name);
3382 pp_write_text_to_stream (&pp);
3383 /* ??? need to free pp */
3384 fprintf (f, "end %s;\n", pkg_name);
3385 fclose (f);
3388 free (ads_name);
3389 free (pkg_name);
3392 static const char **source_refs = NULL;
3393 static int source_refs_used = 0;
3394 static int source_refs_allocd = 0;
3396 /* Add an entry for FILENAME to the table SOURCE_REFS. */
3398 void
3399 collect_source_ref (const char *filename)
3401 int i;
3403 if (!filename)
3404 return;
3406 if (source_refs_allocd == 0)
3408 source_refs_allocd = 1024;
3409 source_refs = XNEWVEC (const char *, source_refs_allocd);
3412 for (i = 0; i < source_refs_used; i++)
3413 if (filename == source_refs[i])
3414 return;
3416 if (source_refs_used == source_refs_allocd)
3418 source_refs_allocd *= 2;
3419 source_refs = XRESIZEVEC (const char *, source_refs, source_refs_allocd);
3422 source_refs[source_refs_used++] = filename;
3425 /* Main entry point: dump all Ada specs corresponding to SOURCE_REFS
3426 using callbacks COLLECT_ALL_REFS and CHECK.
3427 COLLECT_ALL_REFS is a front-end callback used to collect all relevant
3428 nodes for a given source file.
3429 CHECK is used to perform C++ queries on nodes, or NULL for the C
3430 front-end. */
3432 void
3433 dump_ada_specs (void (*collect_all_refs)(const char *),
3434 int (*check)(tree, cpp_operation))
3436 int i;
3438 /* Iterate over the list of files to dump specs for */
3439 for (i = 0; i < source_refs_used; i++)
3440 dump_ads (source_refs[i], collect_all_refs, check);
3442 /* Free files table. */
3443 free (source_refs);