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