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>
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
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
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/>. */
24 #include "coretypes.h"
27 #include "tree-pass.h" /* For TDI_ada and friends. */
29 #include "c-ada-spec.h"
32 #include "cpp-id-data.h"
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,
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);
56 #define LOCATION_COL(LOC) ((expand_location (LOC)).column)
58 #define INDENT(SPACE) do { \
59 int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
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. */
68 macro_length (const cpp_macro *macro, int *supported, int *buffer_len,
81 for (i = 0; i < macro->paramc; i++)
83 cpp_hashnode *param = macro->params[i];
85 *param_len += NODE_LEN (param);
87 if (i + 1 < macro->paramc)
89 *param_len += 2; /* ", " */
91 else if (macro->variadic)
97 *param_len += 2; /* ")\0" */
100 for (j = 0; j < macro->count; j++)
102 cpp_token *token = ¯o->exp.tokens[j];
104 if (token->flags & PREV_WHITE)
107 if (token->flags & STRINGIFY_ARG || token->flags & PASTE_LEFT)
113 if (token->type == CPP_MACRO_ARG)
115 NODE_LEN (macro->params[token->val.macro_arg.arg_no - 1]);
117 /* Include enough extra space to handle e.g. special characters. */
118 *buffer_len += (cpp_token_len (token) + 1) * 8;
124 /* Dump into PP a set of MAX_ADA_MACROS MACROS (C/C++) as Ada constants when
128 print_ada_macros (pretty_printer *pp, cpp_hashnode **macros, int max_ada_macros)
130 int j, num_macros = 0, prev_line = -1;
132 for (j = 0; j < max_ada_macros; j++)
134 cpp_hashnode *node = macros [j];
135 const cpp_macro *macro = node->value.macro;
137 int supported = 1, prev_is_one = 0, buffer_len, param_len;
138 int is_string = 0, is_char = 0;
140 unsigned char *s, *params, *buffer, *buf_param, *char_one = NULL;
142 macro_length (macro, &supported, &buffer_len, ¶m_len);
143 s = buffer = XALLOCAVEC (unsigned char, buffer_len);
144 params = buf_param = XALLOCAVEC (unsigned char, param_len);
151 for (i = 0; i < macro->paramc; i++)
153 cpp_hashnode *param = macro->params[i];
155 memcpy (buf_param, NODE_NAME (param), NODE_LEN (param));
156 buf_param += NODE_LEN (param);
158 if (i + 1 < macro->paramc)
163 else if (macro->variadic)
173 for (i = 0; supported && i < macro->count; i++)
175 cpp_token *token = ¯o->exp.tokens[i];
178 if (token->flags & PREV_WHITE)
181 if (token->flags & STRINGIFY_ARG || token->flags & PASTE_LEFT)
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);
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;
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;
220 *buffer++ = 'n'; *buffer++ = 'o'; *buffer++ = 't'; break;
222 *buffer++ = 'm'; *buffer++ = 'o'; *buffer++ = 'd'; break;
224 *buffer++ = 'a'; *buffer++ = 'n'; *buffer++ = 'd'; break;
226 *buffer++ = 'o'; *buffer++ = 'r'; break;
228 *buffer++ = 'x'; *buffer++ = 'o'; *buffer++ = 'r'; break;
230 strcpy ((char *) buffer, " and then ");
234 strcpy ((char *) buffer, " or else ");
240 is_one = prev_is_one;
243 case CPP_COMMENT: break;
255 if (!macro->fun_like)
258 buffer = cpp_spell_token (parse_in, token, buffer, false);
268 c = cpp_interpret_charconst (parse_in, token,
269 &chars_seen, &ignored);
270 if (c >= 32 && c <= 126)
273 *buffer++ = (char) c;
279 ((char *) buffer, "Character'Val (%d)", (int) c);
280 buffer += chars_seen;
288 /* Replace "1 << N" by "2 ** N" */
315 case CPP_CLOSE_BRACE:
319 case CPP_MINUS_MINUS:
323 case CPP_HEADER_NAME:
326 case CPP_OBJC_STRING:
328 if (!macro->fun_like)
331 buffer = cpp_spell_token (parse_in, token, buffer, false);
335 prev_is_one = is_one;
342 if (macro->fun_like && supported)
344 char *start = (char *) s;
347 pp_string (pp, " -- arg-macro: ");
349 if (*start == '(' && buffer [-1] == ')')
354 pp_string (pp, "function ");
358 pp_string (pp, "procedure ");
361 pp_string (pp, (const char *) NODE_NAME (node));
363 pp_string (pp, (char *) params);
365 pp_string (pp, " -- ");
369 pp_string (pp, "return ");
370 pp_string (pp, start);
374 pp_string (pp, start);
380 expanded_location sloc = expand_location (macro->line);
382 if (sloc.line != prev_line + 1)
386 prev_line = sloc.line;
389 ada_name = to_ada_name ((const char *) NODE_NAME (node), NULL);
390 pp_string (pp, ada_name);
392 pp_string (pp, " : ");
395 pp_string (pp, "aliased constant String");
397 pp_string (pp, "aliased constant Character");
399 pp_string (pp, "constant");
401 pp_string (pp, " := ");
402 pp_string (pp, (char *) s);
405 pp_string (pp, " & ASCII.NUL");
407 pp_string (pp, "; -- ");
408 pp_string (pp, sloc.file);
409 pp_character (pp, ':');
410 pp_scalar (pp, "%d", sloc.line);
415 pp_string (pp, " -- unsupported macro: ");
416 pp_string (pp, (const char *) cpp_macro_definition (parse_in, node));
425 static const char *source_file;
426 static int max_ada_macros;
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
433 count_ada_macro (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *node,
434 void *v ATTRIBUTE_UNUSED)
436 const cpp_macro *macro = node->value.macro;
438 if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN)
440 && *NODE_NAME (node) != '_'
441 && LOCATION_FILE (macro->line) == source_file)
447 static int store_ada_macro_index;
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. */
454 store_ada_macro (cpp_reader *pfile ATTRIBUTE_UNUSED,
455 cpp_hashnode *node, void *macros)
457 const cpp_macro *macro = node->value.macro;
459 if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN)
461 && *NODE_NAME (node) != '_'
462 && LOCATION_FILE (macro->line) == source_file)
463 ((cpp_hashnode **) macros)[store_ada_macro_index++] = node;
468 /* Callback used to compare (during qsort) macros. NODE1 and NODE2 are the
469 two macro nodes to compare. */
472 compare_macro (const void *node1, const void *node2)
474 typedef const cpp_hashnode *const_hnode;
476 const_hnode n1 = *(const const_hnode *) node1;
477 const_hnode n2 = *(const const_hnode *) node2;
479 return n1->value.macro->line - n2->value.macro->line;
482 /* Dump in PP all relevant macros appearing in FILE. */
485 dump_ada_macros (pretty_printer *pp, const char* file)
487 cpp_hashnode **macros;
489 /* Initialize file-scope variables. */
491 store_ada_macro_index = 0;
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);
500 print_ada_macros (pp, macros, max_ada_macros);
503 /* Current source file being handled. */
505 static const char *source_file_base;
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
510 If ORIG_TYPE is true, also consider struct with a DECL_ORIGINAL_TYPE. */
513 decl_sloc_common (const_tree decl, bool last, bool orig_type)
515 tree type = TREE_TYPE (decl);
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))
522 tree f = TYPE_FIELDS (type);
525 while (TREE_CHAIN (f))
528 return DECL_SOURCE_LOCATION (f);
531 return DECL_SOURCE_LOCATION (decl);
534 /* Return sloc of DECL, using sloc of last field if LAST is true. */
537 decl_sloc (const_tree decl, bool last)
539 return decl_sloc_common (decl, last, false);
542 /* Compare two declarations (LP and RP) by their source location. */
545 compare_node (const void *lp, const void *rp)
547 const_tree lhs = *((const tree *) lp);
548 const_tree rhs = *((const tree *) rp);
550 return decl_sloc (lhs, true) - decl_sloc (rhs, true);
553 /* Compare two comments (LP and RP) by their source location. */
556 compare_comment (const void *lp, const void *rp)
558 const cpp_comment *lhs = (const cpp_comment *) lp;
559 const cpp_comment *rhs = (const cpp_comment *) rp;
561 if (LOCATION_FILE (lhs->sloc) != LOCATION_FILE (rhs->sloc))
562 return filename_cmp (LOCATION_FILE (lhs->sloc),
563 LOCATION_FILE (rhs->sloc));
565 if (LOCATION_LINE (lhs->sloc) != LOCATION_LINE (rhs->sloc))
566 return LOCATION_LINE (lhs->sloc) - LOCATION_LINE (rhs->sloc);
568 if (LOCATION_COL (lhs->sloc) != LOCATION_COL (rhs->sloc))
569 return LOCATION_COL (lhs->sloc) - LOCATION_COL (rhs->sloc);
574 static tree *to_dump = NULL;
575 static int to_dump_count = 0;
577 /* Collect a list of declarations from T relevant to SOURCE_FILE to be dumped
578 by a subsequent call to dump_ada_nodes. */
581 collect_ada_nodes (tree t, const char *source_file)
584 int i = to_dump_count;
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)
592 /* Allocate sufficient storage for all nodes. */
593 to_dump = XRESIZEVEC (tree, to_dump, to_dump_count);
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)
602 /* Call back for walk_tree to clear the TREE_VISITED flag of TP. */
605 unmark_visited_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
606 void *data ATTRIBUTE_UNUSED)
608 if (TREE_VISITED (*tp))
609 TREE_VISITED (*tp) = 0;
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. */
620 dump_ada_nodes (pretty_printer *pp, const char *source_file,
621 int (*cpp_check)(tree, cpp_operation))
624 cpp_comment_table *comments;
626 /* Sort the table of declarations to dump by sloc. */
627 qsort (to_dump, to_dump_count, sizeof (tree), compare_node);
629 /* Fetch the table of comments. */
630 comments = cpp_get_comments (parse_in);
632 /* Sort the comments table by sloc. */
633 qsort (comments->entries, comments->count, sizeof (cpp_comment),
636 /* Interleave comments and declarations in line number order. */
640 /* Advance j until comment j is in this file. */
641 while (j != comments->count
642 && LOCATION_FILE (comments->entries[j].sloc) != source_file)
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]))
651 /* Write decls until decl i collates after comment j. */
652 while (i != to_dump_count)
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);
662 /* Write comment j, if there is one. */
663 if (j != comments->count)
664 print_comment (pp, comments->entries[j++].comment);
666 } while (i != to_dump_count || j != comments->count);
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);
672 /* Finalize the to_dump table. */
681 /* Print a COMMENT to the output stream PP. */
684 print_comment (pretty_printer *pp, const char *comment)
686 int len = strlen (comment);
687 char *str = XALLOCAVEC (char, len + 1);
689 bool extra_newline = false;
691 memcpy (str, comment, len + 1);
693 /* Trim C/C++ comment indicators. */
694 if (str[len - 2] == '*' && str[len - 1] == '/')
701 tok = strtok (str, "\n");
703 pp_string (pp, " --");
706 tok = strtok (NULL, "\n");
708 /* Leave a blank line after multi-line comments. */
710 extra_newline = true;
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
722 print_generic_ada_decl (pretty_printer *pp, tree decl,
723 int (*cpp_check)(tree, cpp_operation),
724 const char* source_file)
726 source_file_base = source_file;
728 if (print_ada_declaration (pp, decl, 0, cpp_check, INDENT_INCR))
735 /* Dump a newline and indent BUFFER by SPC chars. */
738 newline_and_indent (pretty_printer *buffer, int spc)
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;
749 /* Record a "with" clause on package S (a limited with if LIMITED_ACCESS is
750 true), if not already done. */
753 append_withs (const char *s, int limited_access)
758 withs = XNEWVEC (struct with, withs_max);
760 if (with_len == withs_max)
763 withs = XRESIZEVEC (struct with, withs, withs_max);
766 for (i = 0; i < with_len; i++)
767 if (!strcmp (s, withs [i].s)
768 && source_file_base == withs [i].in_file)
770 withs [i].limited &= limited_access;
774 withs [with_len].s = xstrdup (s);
775 withs [with_len].in_file = source_file_base;
776 withs [with_len].limited = limited_access;
780 /* Reset "with" clauses. */
783 reset_ada_withs (void)
790 for (i = 0; i < with_len; i++)
798 /* Dump "with" clauses in F. */
801 dump_ada_withs (FILE *f)
805 fprintf (f, "with Interfaces.C; use Interfaces.C;\n");
807 for (i = 0; i < with_len; i++)
809 (f, "%swith %s;\n", withs [i].limited ? "limited " : "", withs [i].s);
812 /* Return suitable Ada package name from FILE. */
815 get_ada_package (const char *file)
822 s = strstr (file, "/include/");
826 base = lbasename (file);
827 res = XNEWVEC (char, strlen (base) + 1);
829 for (i = 0; *base; base++, i++)
841 res [i] = (i == 0 || res [i - 1] == '_') ? 'u' : '_';
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",
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. */
871 /* The following values have other definitions with same name/other
877 "rl_readline_version",
883 /* Return a declaration tree corresponding to TYPE. */
886 get_underlying_decl (tree type)
888 tree decl = NULL_TREE;
890 if (type == NULL_TREE)
893 /* type is a declaration. */
897 /* type is a typedef. */
898 if (TYPE_P (type) && TYPE_NAME (type) && DECL_P (TYPE_NAME (type)))
899 decl = TYPE_NAME (type);
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);
909 /* Return whether TYPE has static fields. */
912 has_static_fields (const_tree type)
916 for (tmp = TYPE_FIELDS (type); tmp; tmp = TREE_CHAIN (tmp))
918 if (DECL_NAME (tmp) && TREE_STATIC (tmp))
924 /* Return whether TYPE corresponds to an Ada tagged type (has a dispatch
928 is_tagged_type (const_tree type)
932 if (!type || !RECORD_OR_UNION_TYPE_P (type))
935 for (tmp = TYPE_METHODS (type); tmp; tmp = TREE_CHAIN (tmp))
936 if (DECL_VINDEX (tmp))
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
947 to_ada_name (const char *name, int *space_found)
950 int len = strlen (name);
953 char *s = XNEWVEC (char, len * 2 + 5);
957 *space_found = false;
959 /* Add trailing "c_" if name is an Ada reserved word. */
960 for (names = ada_reserved; *names; names++)
961 if (!strcasecmp (name, *names))
970 /* Add trailing "c_" if name is an potential case sensitive duplicate. */
971 for (names = c_duplicates; *names; names++)
972 if (!strcmp (name, *names))
980 for (j = 0; name [j] == '_'; j++)
985 else if (*name == '.' || *name == '$')
995 /* Replace unsuitable characters for Ada identifiers. */
1002 *space_found = true;
1006 /* ??? missing some C++ operators. */
1010 if (name [j + 1] == '=')
1025 if (name [j + 1] == '=')
1043 s [len2++] = name [j] == '&' ? 'a' : name [j] == '|' ? 'o' : 'x';
1045 if (name [j + 1] == '=')
1058 if (s [len2 - 1] != '_')
1061 switch (name [j + 1]) {
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; /* / */
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; /* /= */
1112 c = name [j] == '<' ? 'l' : 'g';
1115 switch (name [j + 1]) {
1141 if (len2 && s [len2 - 1] == '_')
1146 s [len2++] = name [j];
1149 if (s [len2 - 1] == '_')
1157 /* Return true if DECL refers to a C++ class type for which a
1158 separate enclosing package has been or should be generated. */
1161 separate_class_package (tree decl)
1165 tree type = TREE_TYPE (decl);
1167 && TREE_CODE (type) == RECORD_TYPE
1168 && (TYPE_METHODS (type) || has_static_fields (type));
1174 static bool package_prefix = true;
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. */
1181 pp_ada_tree_identifier (pretty_printer *buffer, tree node, tree type,
1184 const char *name = IDENTIFIER_POINTER (node);
1185 int space_found = false;
1186 char *s = to_ada_name (name, &space_found);
1189 /* If the entity is a type and comes from another file, generate "package"
1192 decl = get_underlying_decl (type);
1196 expanded_location xloc = expand_location (decl_sloc (decl, false));
1198 if (xloc.file && xloc.line)
1200 if (xloc.file != source_file_base)
1202 switch (TREE_CODE (type))
1207 case FIXED_POINT_TYPE:
1209 case REFERENCE_TYPE:
1214 case QUAL_UNION_TYPE:
1217 char *s1 = get_ada_package (xloc.file);
1221 append_withs (s1, limited_access);
1222 pp_string (buffer, s1);
1223 pp_character (buffer, '.');
1232 if (separate_class_package (decl))
1234 pp_string (buffer, "Class_");
1235 pp_string (buffer, s);
1236 pp_string (buffer, ".");
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"))
1260 append_withs ("Interfaces.C.Extensions", false);
1261 pp_string (buffer, "Extensions.unsigned_long_long");
1264 pp_string (buffer, "unsigned_long_long");
1267 pp_string(buffer, s);
1269 if (!strcmp (s, "bool"))
1273 append_withs ("Interfaces.C.Extensions", false);
1274 pp_string (buffer, "Extensions.bool");
1277 pp_string (buffer, "bool");
1280 pp_string(buffer, s);
1285 /* Dump in BUFFER the assembly name of T. */
1288 pp_asm_name (pretty_printer *buffer, tree t)
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);
1294 for (s = ada_name; *ident; ident++)
1298 else if (*ident != '*')
1303 pp_string (buffer, ada_name);
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. */
1311 dump_ada_decl_name (pretty_printer *buffer, tree decl, int limited_access)
1313 if (DECL_NAME (decl))
1314 pp_ada_tree_identifier (buffer, DECL_NAME (decl), decl, limited_access);
1317 tree type_name = TYPE_NAME (TREE_TYPE (decl));
1321 pp_string (buffer, "anon");
1322 if (TREE_CODE (decl) == FIELD_DECL)
1323 pp_scalar (buffer, "%d", DECL_UID (decl));
1325 pp_scalar (buffer, "%d", TYPE_UID (TREE_TYPE (decl)));
1327 else if (TREE_CODE (type_name) == IDENTIFIER_NODE)
1328 pp_ada_tree_identifier (buffer, type_name, decl, limited_access);
1332 /* Dump in BUFFER a name based on both T1 and T2, followed by S. */
1335 dump_ada_double_name (pretty_printer *buffer, tree t1, tree t2, const char *s)
1338 pp_ada_tree_identifier (buffer, DECL_NAME (t1), t1, false);
1341 pp_string (buffer, "anon");
1342 pp_scalar (buffer, "%d", TYPE_UID (TREE_TYPE (t1)));
1345 pp_character (buffer, '_');
1348 pp_ada_tree_identifier (buffer, DECL_NAME (t2), t2, false);
1351 pp_string (buffer, "anon");
1352 pp_scalar (buffer, "%d", TYPE_UID (TREE_TYPE (t2)));
1355 pp_string (buffer, s);
1358 /* Dump in BUFFER pragma Import C/CPP on a given node T. */
1361 dump_ada_import (pretty_printer *buffer, tree t)
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)));
1368 pp_string (buffer, "pragma Import (Stdcall, ");
1369 else if (name [0] == '_' && name [1] == 'Z')
1370 pp_string (buffer, "pragma Import (CPP, ");
1372 pp_string (buffer, "pragma Import (C, ");
1374 dump_ada_decl_name (buffer, t, false);
1375 pp_string (buffer, ", \"");
1378 pp_string (buffer, IDENTIFIER_POINTER (DECL_NAME (t)));
1380 pp_asm_name (buffer, t);
1382 pp_string (buffer, "\");");
1385 /* Check whether T and its type have different names, and append "the_"
1386 otherwise in BUFFER. */
1389 check_name (pretty_printer *buffer, tree t)
1392 tree tmp = TREE_TYPE (t);
1394 while (TREE_CODE (tmp) == POINTER_TYPE && !TYPE_NAME (tmp))
1395 tmp = TREE_TYPE (tmp);
1397 if (TREE_CODE (tmp) != FUNCTION_TYPE)
1399 if (TREE_CODE (tmp) == IDENTIFIER_NODE)
1400 s = IDENTIFIER_POINTER (tmp);
1401 else if (!TYPE_NAME (tmp))
1403 else if (TREE_CODE (TYPE_NAME (tmp)) == IDENTIFIER_NODE)
1404 s = IDENTIFIER_POINTER (TYPE_NAME (tmp));
1406 s = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (tmp)));
1408 if (!strcasecmp (IDENTIFIER_POINTER (DECL_NAME (t)), s))
1409 pp_string (buffer, "the_");
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. */
1420 dump_ada_function_declaration (pretty_printer *buffer, tree func,
1421 int is_method, int is_constructor,
1422 int is_destructor, int spc)
1425 const tree node = TREE_TYPE (func);
1427 int num = 0, num_args = 0, have_args = true, have_ellipsis = false;
1429 /* Compute number of arguments. */
1430 arg = TYPE_ARG_TYPES (node);
1434 while (TREE_CHAIN (arg) && arg != error_mark_node)
1437 arg = TREE_CHAIN (arg);
1440 if (TREE_CODE (TREE_VALUE (arg)) != VOID_TYPE)
1443 have_ellipsis = true;
1454 newline_and_indent (buffer, spc + 1);
1459 pp_character (buffer, '(');
1462 if (TREE_CODE (func) == FUNCTION_DECL)
1463 arg = DECL_ARGUMENTS (func);
1467 if (arg == NULL_TREE)
1470 arg = TYPE_ARG_TYPES (node);
1472 if (arg && TREE_CODE (TREE_VALUE (arg)) == VOID_TYPE)
1477 arg = TREE_CHAIN (arg);
1479 /* Print the argument names (if available) & types. */
1481 for (num = 1; num <= num_args; num++)
1485 if (DECL_NAME (arg))
1487 check_name (buffer, arg);
1488 pp_ada_tree_identifier (buffer, DECL_NAME (arg), 0, false);
1489 pp_string (buffer, " : ");
1493 sprintf (buf, "arg%d : ", num);
1494 pp_string (buffer, buf);
1497 dump_generic_ada_node
1498 (buffer, TREE_TYPE (arg), node, NULL, spc, 0, true);
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);
1508 if (TREE_TYPE (arg) && TREE_TYPE (TREE_TYPE (arg))
1509 && is_tagged_type (TREE_TYPE (TREE_TYPE (arg))))
1512 || (num != 1 || (!DECL_VINDEX (func) && !is_constructor)))
1513 pp_string (buffer, "'Class");
1516 arg = TREE_CHAIN (arg);
1520 pp_character (buffer, ';');
1523 newline_and_indent (buffer, spc + INDENT_INCR);
1531 pp_string (buffer, " -- , ...");
1532 newline_and_indent (buffer, spc + INDENT_INCR);
1536 pp_character (buffer, ')');
1540 /* Dump in BUFFER all the domains associated with an array NODE,
1541 using Ada syntax. SPC is the current indentation level. */
1544 dump_ada_array_domains (pretty_printer *buffer, tree node, int spc)
1547 pp_character (buffer, '(');
1549 for (; TREE_CODE (node) == ARRAY_TYPE; node = TREE_TYPE (node))
1551 tree domain = TYPE_DOMAIN (node);
1555 tree min = TYPE_MIN_VALUE (domain);
1556 tree max = TYPE_MAX_VALUE (domain);
1559 pp_string (buffer, ", ");
1563 dump_generic_ada_node (buffer, min, NULL_TREE, NULL, spc, 0, true);
1564 pp_string (buffer, " .. ");
1566 /* If the upper bound is zero, gcc may generate a NULL_TREE
1567 for TYPE_MAX_VALUE rather than an integer_cst. */
1569 dump_generic_ada_node (buffer, max, NULL_TREE, NULL, spc, 0, true);
1571 pp_string (buffer, "0");
1574 pp_string (buffer, "size_t");
1576 pp_character (buffer, ')');
1579 /* Dump in BUFFER file:line information related to NODE. */
1582 dump_sloc (pretty_printer *buffer, tree node)
1584 expanded_location xloc;
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));
1595 pp_string (buffer, xloc.file);
1596 pp_string (buffer, ":");
1597 pp_decimal_int (buffer, xloc.line);
1601 /* Return true if T designates a one dimension array of "char". */
1604 is_char_array (tree t)
1609 /* Retrieve array's type. */
1611 while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1614 tmp = TREE_TYPE (tmp);
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");
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
1627 dump_ada_array_type (pretty_printer *buffer, tree t, int spc)
1630 bool char_array = is_char_array (t);
1632 /* Special case char arrays. */
1635 pp_string (buffer, "Interfaces.C.char_array ");
1638 pp_string (buffer, "array ");
1640 /* Print the dimensions. */
1641 dump_ada_array_domains (buffer, TREE_TYPE (t), spc);
1643 /* Retrieve array's type. */
1644 tmp = TREE_TYPE (t);
1645 while (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE)
1646 tmp = TREE_TYPE (tmp);
1648 /* Print array's type. */
1651 pp_string (buffer, " of ");
1653 if (TREE_CODE (TREE_TYPE (tmp)) != POINTER_TYPE)
1654 pp_string (buffer, "aliased ");
1656 dump_generic_ada_node
1657 (buffer, TREE_TYPE (tmp), TREE_TYPE (t), NULL, spc, false, true);
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. */
1667 dump_template_types (pretty_printer *buffer, tree types,
1668 int (*cpp_check)(tree, cpp_operation), int spc)
1671 size_t len = TREE_VEC_LENGTH (types);
1673 for (i = 0; i < len; i++)
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))
1679 pp_string (buffer, "unknown");
1680 pp_scalar (buffer, "%lu", (unsigned long) TREE_HASH (elem));
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. */
1690 dump_ada_template (pretty_printer *buffer, tree t,
1691 int (*cpp_check)(tree, cpp_operation), int spc)
1693 tree inst = DECL_VINDEX (t);
1694 /* DECL_VINDEX is DECL_TEMPLATE_INSTANTIATIONS in this context. */
1697 while (inst && inst != error_mark_node)
1699 tree types = TREE_PURPOSE (inst);
1700 tree instance = TREE_VALUE (inst);
1702 if (TREE_VEC_LENGTH (types) == 0)
1705 if (!TYPE_P (instance) || !TYPE_METHODS (instance))
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");
1716 newline_and_indent (buffer, spc);
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;
1723 if (is_tagged_type (instance))
1724 pp_string (buffer, " is tagged limited ");
1726 pp_string (buffer, " is limited ");
1728 dump_generic_ada_node (buffer, instance, t, cpp_check, spc, false, false);
1729 pp_newline (buffer);
1731 newline_and_indent (buffer, spc);
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);
1744 inst = TREE_CHAIN (inst);
1747 return num_inst > 0;
1750 /* Return true if NODE is a simple enum types, that can be mapped to an
1751 Ada enum type directly. */
1754 is_simple_enum (tree node)
1756 unsigned HOST_WIDE_INT count = 0;
1759 for (value = TYPE_VALUES (node); value; value = TREE_CHAIN (value))
1761 tree int_val = TREE_VALUE (value);
1763 if (TREE_CODE (int_val) != INTEGER_CST)
1764 int_val = DECL_INITIAL (int_val);
1766 if (!host_integerp (int_val, 0))
1768 else if (TREE_INT_CST_LOW (int_val) != count)
1777 static bool in_function = true;
1778 static bool bitfield_used = false;
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. */
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)
1791 if (node == NULL_TREE)
1794 switch (TREE_CODE (node))
1797 pp_string (buffer, "<<< error >>>");
1800 case IDENTIFIER_NODE:
1801 pp_ada_tree_identifier (buffer, node, type, limited_access);
1805 pp_string (buffer, "--- unexpected node: TREE_LIST");
1809 dump_generic_ada_node
1810 (buffer, BINFO_TYPE (node), type, cpp_check,
1811 spc, limited_access, name_only);
1814 pp_string (buffer, "--- unexpected node: TREE_VEC");
1820 append_withs ("System", false);
1821 pp_string (buffer, "System.Address");
1824 pp_string (buffer, "address");
1828 pp_string (buffer, "<vector>");
1832 pp_string (buffer, "<complex>");
1837 dump_generic_ada_node
1838 (buffer, TYPE_NAME (node), node, cpp_check, spc, 0, true);
1841 tree value = TYPE_VALUES (node);
1843 if (is_simple_enum (node))
1847 newline_and_indent (buffer, spc - 1);
1848 pp_string (buffer, "(");
1849 for (; value; value = TREE_CHAIN (value))
1855 pp_string (buffer, ",");
1856 newline_and_indent (buffer, spc);
1859 pp_ada_tree_identifier
1860 (buffer, TREE_PURPOSE (value), node, false);
1862 pp_string (buffer, ");");
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, ")");
1873 pp_string (buffer, "unsigned");
1874 for (; value; value = TREE_CHAIN (value))
1876 pp_semicolon (buffer);
1877 newline_and_indent (buffer, spc);
1879 pp_ada_tree_identifier
1880 (buffer, TREE_PURPOSE (value), node, false);
1881 pp_string (buffer, " : constant ");
1883 dump_generic_ada_node
1884 (buffer, DECL_NAME (type) ? type : TYPE_NAME (node), type,
1885 cpp_check, spc, 0, true);
1887 pp_string (buffer, " := ");
1888 dump_generic_ada_node
1890 TREE_CODE (TREE_VALUE (value)) == INTEGER_CST ?
1891 TREE_VALUE (value) : DECL_INITIAL (TREE_VALUE (value)),
1892 node, cpp_check, spc, false, true);
1900 case FIXED_POINT_TYPE:
1903 enum tree_code_class tclass;
1905 tclass = TREE_CODE_CLASS (TREE_CODE (node));
1907 if (tclass == tcc_declaration)
1909 if (DECL_NAME (node))
1910 pp_ada_tree_identifier
1911 (buffer, DECL_NAME (node), 0, limited_access);
1913 pp_string (buffer, "<unnamed type decl>");
1915 else if (tclass == tcc_type)
1917 if (TYPE_NAME (node))
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);
1926 pp_string (buffer, "<unnamed type>");
1928 else if (TREE_CODE (node) == INTEGER_TYPE)
1930 append_withs ("Interfaces.C.Extensions", false);
1931 bitfield_used = true;
1933 if (TYPE_PRECISION (node) == 1)
1934 pp_string (buffer, "Extensions.Unsigned_1");
1937 pp_string (buffer, (TYPE_UNSIGNED (node)
1938 ? "Extensions.Unsigned_"
1939 : "Extensions.Signed_"));
1940 pp_decimal_int (buffer, TYPE_PRECISION (node));
1944 pp_string (buffer, "<unnamed type>");
1950 case REFERENCE_TYPE:
1951 if (TREE_CODE (TREE_TYPE (node)) == FUNCTION_TYPE)
1953 tree fnode = TREE_TYPE (node);
1955 bool prev_in_function = in_function;
1957 if (VOID_TYPE_P (TREE_TYPE (fnode)))
1959 is_function = false;
1960 pp_string (buffer, "access procedure");
1965 pp_string (buffer, "access function");
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;
1975 pp_string (buffer, " return ");
1976 dump_generic_ada_node
1977 (buffer, TREE_TYPE (fnode), type, cpp_check, spc, 0, true);
1982 int is_access = false;
1983 unsigned int quals = TYPE_QUALS (TREE_TYPE (node));
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)))
1992 pp_string (buffer, "new ");
1995 append_withs ("System", false);
1996 pp_string (buffer, "System.Address");
1999 pp_string (buffer, "address");
2003 if (TREE_CODE (node) == POINTER_TYPE
2004 && TREE_CODE (TREE_TYPE (node)) == INTEGER_TYPE
2006 (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME
2007 (TREE_TYPE (node)))), "char"))
2010 pp_string (buffer, "new ");
2014 pp_string (buffer, "Interfaces.C.Strings.chars_ptr");
2015 append_withs ("Interfaces.C.Strings", false);
2018 pp_string (buffer, "chars_ptr");
2022 /* For now, handle all access-to-access or
2023 access-to-unknown-structs as opaque system.address. */
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));
2031 if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE
2032 /* Pointer to pointer. */
2034 || (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node))
2035 && (!underlying_type
2036 || !TYPE_FIELDS (TREE_TYPE (underlying_type))))
2037 /* Pointer to opaque structure. */
2039 || underlying_type == NULL_TREE
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)
2049 && decl_sloc (underlying_type, true)
2050 > decl_sloc (typ2, true)
2051 && DECL_SOURCE_FILE (underlying_type)
2052 == DECL_SOURCE_FILE (typ2)))
2056 append_withs ("System", false);
2058 pp_string (buffer, "new ");
2059 pp_string (buffer, "System.Address");
2062 pp_string (buffer, "address");
2066 if (!package_prefix)
2067 pp_string (buffer, "access");
2068 else if (AGGREGATE_TYPE_P (TREE_TYPE (node)))
2070 if (!type || TREE_CODE (type) != FUNCTION_DECL)
2072 pp_string (buffer, "access ");
2075 if (quals & TYPE_QUAL_CONST)
2076 pp_string (buffer, "constant ");
2077 else if (!name_only)
2078 pp_string (buffer, "all ");
2080 else if (quals & TYPE_QUAL_CONST)
2081 pp_string (buffer, "in ");
2082 else if (in_function)
2085 pp_string (buffer, "access ");
2090 pp_string (buffer, "access ");
2091 /* ??? should be configurable: access or in out. */
2097 pp_string (buffer, "access ");
2100 pp_string (buffer, "all ");
2103 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node))
2104 && type_name != NULL_TREE)
2105 dump_generic_ada_node
2107 TREE_TYPE (node), cpp_check, spc, is_access, true);
2109 dump_generic_ada_node
2110 (buffer, TREE_TYPE (node), TREE_TYPE (node),
2111 cpp_check, spc, 0, true);
2119 dump_generic_ada_node
2120 (buffer, TYPE_NAME (node), node, cpp_check,
2121 spc, limited_access, true);
2123 dump_ada_array_type (buffer, node, spc);
2128 case QUAL_UNION_TYPE:
2131 if (TYPE_NAME (node))
2132 dump_generic_ada_node
2133 (buffer, TYPE_NAME (node), node, cpp_check,
2134 spc, limited_access, true);
2137 pp_string (buffer, "anon_");
2138 pp_scalar (buffer, "%d", TYPE_UID (node));
2142 print_ada_struct_decl
2143 (buffer, node, type, cpp_check, spc, true);
2147 if (TREE_CODE (TREE_TYPE (node)) == POINTER_TYPE)
2149 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
2150 pp_string (buffer, "B"); /* pseudo-unit */
2152 else if (!host_integerp (node, 0))
2155 unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (val);
2156 HOST_WIDE_INT high = TREE_INT_CST_HIGH (val);
2158 if (tree_int_cst_sgn (val) < 0)
2160 pp_character (buffer, '-');
2161 high = ~high + !low;
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);
2170 pp_wide_integer (buffer, TREE_INT_CST_LOW (node));
2182 dump_ada_decl_name (buffer, node, limited_access);
2186 if (DECL_IS_BUILTIN (node))
2188 /* Don't print the declaration of built-in types. */
2192 /* If we're in the middle of a declaration, defaults to
2196 append_withs ("System", false);
2197 pp_string (buffer, "System.Address");
2200 pp_string (buffer, "address");
2206 dump_ada_decl_name (buffer, node, limited_access);
2209 if (is_tagged_type (TREE_TYPE (node)))
2211 tree tmp = TYPE_FIELDS (TREE_TYPE (node));
2214 /* Look for ancestors. */
2215 for (; tmp; tmp = TREE_CHAIN (tmp))
2217 if (!DECL_NAME (tmp) && is_tagged_type (TREE_TYPE (tmp)))
2221 pp_string (buffer, "limited new ");
2225 pp_string (buffer, " and ");
2228 (buffer, TYPE_NAME (TREE_TYPE (tmp)), false);
2232 pp_string (buffer, first ? "tagged limited " : " with ");
2234 else if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node))
2235 && TYPE_METHODS (TREE_TYPE (node)))
2236 pp_string (buffer, "limited ");
2238 dump_generic_ada_node
2239 (buffer, TREE_TYPE (node), type, cpp_check, spc, false, false);
2246 case NAMESPACE_DECL:
2247 dump_ada_decl_name (buffer, node, false);
2251 /* Ignore other nodes (e.g. expressions). */
2258 /* Dump in BUFFER NODE's methods. CPP_CHECK is used to perform C++ queries on
2259 nodes. SPC is the indentation level. */
2262 print_ada_methods (pretty_printer *buffer, tree node,
2263 int (*cpp_check)(tree, cpp_operation), int spc)
2265 tree tmp = TYPE_METHODS (node);
2270 pp_semicolon (buffer);
2272 for (; tmp; tmp = TREE_CHAIN (tmp))
2276 pp_newline (buffer);
2277 pp_newline (buffer);
2279 res = print_ada_declaration (buffer, tmp, node, cpp_check, spc);
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. */
2291 dump_nested_types (pretty_printer *buffer, tree t, tree parent, bool forward,
2292 int (*cpp_check)(tree, cpp_operation), int spc)
2294 tree field, outer, decl;
2296 /* Avoid recursing over the same tree. */
2297 if (TREE_VISITED (t))
2300 /* Find possible anonymous arrays/unions/structs recursively. */
2302 outer = TREE_TYPE (t);
2304 if (outer == NULL_TREE)
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;
2317 field = TYPE_FIELDS (outer);
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))))
2328 switch (TREE_CODE (TREE_TYPE (field)))
2331 decl = TREE_TYPE (TREE_TYPE (field));
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))
2339 decl = get_underlying_decl (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))))
2350 /* Generate forward declaration. */
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);
2358 /* Ensure we do not generate duplicate forward
2359 declarations for this type. */
2360 TREE_VISITED (decl) = 1;
2365 /* Special case char arrays. */
2366 if (is_char_array (field))
2367 pp_string (buffer, "sub");
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);
2377 TREE_VISITED (t) = 1;
2378 dump_nested_types (buffer, field, t, false, cpp_check, spc);
2380 pp_string (buffer, "type ");
2382 if (TYPE_NAME (TREE_TYPE (field)))
2384 dump_generic_ada_node
2385 (buffer, TYPE_NAME (TREE_TYPE (field)), 0, cpp_check,
2387 pp_string (buffer, " (discr : unsigned := 0) is ");
2388 print_ada_struct_decl
2389 (buffer, TREE_TYPE (field), t, cpp_check, spc, false);
2391 pp_string (buffer, "pragma Convention (C_Pass_By_Copy, ");
2392 dump_generic_ada_node
2393 (buffer, TREE_TYPE (field), 0, cpp_check,
2395 pp_string (buffer, ");");
2396 newline_and_indent (buffer, spc);
2398 pp_string (buffer, "pragma Unchecked_Union (");
2399 dump_generic_ada_node
2400 (buffer, TREE_TYPE (field), 0, cpp_check,
2402 pp_string (buffer, ");");
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);
2415 pp_string (buffer, "pragma Unchecked_Union (");
2416 dump_ada_double_name (buffer, parent, field, "_union);");
2419 newline_and_indent (buffer, spc);
2423 if (TYPE_NAME (TREE_TYPE (t)) && !TREE_VISITED (t))
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);
2432 TREE_VISITED (t) = 1;
2433 dump_nested_types (buffer, field, t, false, cpp_check, spc);
2434 pp_string (buffer, "type ");
2436 if (TYPE_NAME (TREE_TYPE (field)))
2438 dump_generic_ada_node
2439 (buffer, TREE_TYPE (field), 0, cpp_check,
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,
2448 pp_string (buffer, ");");
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);");
2460 newline_and_indent (buffer, spc);
2467 field = TREE_CHAIN (field);
2470 TREE_VISITED (t) = 1;
2473 /* Dump in BUFFER destructor spec corresponding to T. */
2476 print_destructor (pretty_printer *buffer, tree t)
2478 const char *s = IDENTIFIER_POINTER (DECL_NAME (t));
2481 for (s += 2; *s != ' '; s++)
2482 pp_character (buffer, *s);
2485 pp_string (buffer, "Delete_");
2486 pp_ada_tree_identifier (buffer, DECL_NAME (t), t, false);
2490 /* Return the name of type T. */
2495 tree n = TYPE_NAME (t);
2497 if (TREE_CODE (n) == IDENTIFIER_NODE)
2498 return IDENTIFIER_POINTER (n);
2500 return IDENTIFIER_POINTER (DECL_NAME (n));
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. */
2508 print_ada_declaration (pretty_printer *buffer, tree t, tree type,
2509 int (*cpp_check)(tree, cpp_operation), int spc)
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;
2518 if (cpp_check && cpp_check (t, IS_TEMPLATE))
2519 return dump_ada_template (buffer, t, cpp_check, spc);
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. */
2525 if (TREE_CODE (t) == TYPE_DECL)
2527 orig = DECL_ORIGINAL_TYPE (t);
2529 if (orig && TYPE_STUB_DECL (orig))
2531 tree stub = TYPE_STUB_DECL (orig);
2532 tree typ = TREE_TYPE (stub);
2534 if (TYPE_NAME (typ))
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))))
2544 if (RECORD_OR_UNION_TYPE_P (typ) && !TYPE_FIELDS (typ))
2546 pp_string (buffer, "-- skipped empty struct ");
2547 dump_generic_ada_node (buffer, t, type, 0, spc, false, true);
2551 if (!TREE_VISITED (stub)
2552 && DECL_SOURCE_FILE (stub) == source_file_base)
2554 (buffer, stub, stub, true, cpp_check, spc);
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);
2567 /* Skip unnamed or anonymous structs/unions/enum types. */
2568 if (!orig && !decl_name && !name)
2573 if (cpp_check || TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE)
2576 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t)))
2578 /* Search next items until finding a named type decl. */
2579 sloc = decl_sloc_common (t, true, true);
2581 for (tmp = TREE_CHAIN (t); tmp; tmp = TREE_CHAIN (tmp))
2583 if (TREE_CODE (tmp) == TYPE_DECL
2584 && (DECL_NAME (tmp) || TYPE_NAME (TREE_TYPE (tmp))))
2586 /* If same sloc, it means we can ignore the anonymous
2588 if (decl_sloc_common (tmp, true, true) == sloc)
2600 && TREE_CODE (TREE_TYPE (t)) == ENUMERAL_TYPE
2602 && (*IDENTIFIER_POINTER (decl_name) == '.'
2603 || *IDENTIFIER_POINTER (decl_name) == '$'))
2604 /* Skip anonymous enum types (duplicates of real types). */
2609 switch (TREE_CODE (TREE_TYPE (t)))
2613 case QUAL_UNION_TYPE:
2614 /* Skip empty structs (typically forward references to real
2616 if (!TYPE_FIELDS (TREE_TYPE (t)))
2618 pp_string (buffer, "-- skipped empty struct ");
2619 dump_generic_ada_node (buffer, t, type, 0, spc, false, true);
2624 && (*IDENTIFIER_POINTER (decl_name) == '.'
2625 || *IDENTIFIER_POINTER (decl_name) == '$'))
2627 pp_string (buffer, "-- skipped anonymous struct ");
2628 dump_generic_ada_node (buffer, t, type, 0, spc, false, true);
2629 TREE_VISITED (t) = 1;
2633 if (orig && TYPE_NAME (orig) && orig != TREE_TYPE (t))
2634 pp_string (buffer, "subtype ");
2637 dump_nested_types (buffer, t, t, false, cpp_check, spc);
2639 if (separate_class_package (t))
2642 pp_string (buffer, "package Class_");
2643 dump_generic_ada_node
2644 (buffer, t, type, 0, spc, false, true);
2645 pp_string (buffer, " is");
2647 newline_and_indent (buffer, spc);
2650 pp_string (buffer, "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 ");
2661 pp_string (buffer, "type ");
2665 pp_string (buffer, "-- skipped function type ");
2666 dump_generic_ada_node (buffer, t, type, 0, spc, false, true);
2671 if ((orig && TYPE_NAME (orig) && orig != TREE_TYPE (t))
2672 || !is_simple_enum (TREE_TYPE (t)))
2673 pp_string (buffer, "subtype ");
2675 pp_string (buffer, "type ");
2679 pp_string (buffer, "subtype ");
2681 TREE_VISITED (t) = 1;
2686 && TREE_CODE (t) == VAR_DECL
2688 && *IDENTIFIER_POINTER (decl_name) == '_')
2694 /* Print the type and name. */
2695 if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
2700 /* Print variable's name. */
2701 dump_generic_ada_node (buffer, t, type, cpp_check, spc, false, true);
2703 if (TREE_CODE (t) == TYPE_DECL)
2705 pp_string (buffer, " is ");
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);
2712 dump_ada_array_type (buffer, t, spc);
2716 tree tmp = TYPE_NAME (TREE_TYPE (t));
2718 if (spc == INDENT_INCR || TREE_STATIC (t))
2721 pp_string (buffer, " : ");
2725 if (TREE_CODE (TREE_TYPE (tmp)) != POINTER_TYPE
2726 && TREE_CODE (tmp) != INTEGER_TYPE)
2727 pp_string (buffer, "aliased ");
2729 dump_generic_ada_node (buffer, tmp, type, 0, spc, false, true);
2733 pp_string (buffer, "aliased ");
2736 dump_ada_array_type (buffer, t, spc);
2738 dump_ada_double_name (buffer, type, t, "_array");
2742 else if (TREE_CODE (t) == FUNCTION_DECL)
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;
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);
2763 /* Skip __comp_dtor destructor which is redundant with the '~class()'
2766 && !strncmp (IDENTIFIER_POINTER (decl_name), "__comp", 6))
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)
2774 /* If this function has an entry in the dispatch table, we cannot
2776 if (!dump_internal && !DECL_VINDEX (t)
2777 && *IDENTIFIER_POINTER (decl_name) == '_')
2779 if (IDENTIFIER_POINTER (decl_name)[1] == '_')
2783 pp_string (buffer, "-- skipped func ");
2784 pp_string (buffer, IDENTIFIER_POINTER (decl_name));
2792 pp_string (buffer, "function New_");
2793 else if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (t))))
2795 is_function = false;
2796 pp_string (buffer, "procedure ");
2799 pp_string (buffer, "function ");
2801 in_function = is_function;
2802 is_method = TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE;
2805 print_destructor (buffer, t);
2807 dump_ada_decl_name (buffer, t, false);
2809 dump_ada_function_declaration
2810 (buffer, t, is_method, is_constructor, is_destructor, spc);
2811 in_function = prev_in_function;
2815 pp_string (buffer, " return ");
2819 dump_ada_decl_name (buffer, t, false);
2823 dump_generic_ada_node
2824 (buffer, TREE_TYPE (TREE_TYPE (t)), type, cpp_check,
2829 if (is_constructor && cpp_check && type
2830 && AGGREGATE_TYPE_P (type)
2831 && TYPE_METHODS (type))
2833 tree tmp = TYPE_METHODS (type);
2835 for (; tmp; tmp = TREE_CHAIN (tmp))
2836 if (cpp_check (tmp, IS_ABSTRACT))
2838 is_abstract_class = 1;
2843 if (is_abstract || is_abstract_class)
2844 pp_string (buffer, " is abstract");
2846 pp_semicolon (buffer);
2847 pp_string (buffer, " -- ");
2848 dump_sloc (buffer, t);
2853 newline_and_indent (buffer, spc);
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, "\");");
2863 else if (is_destructor)
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, "\");");
2873 dump_ada_import (buffer, t);
2878 else if (TREE_CODE (t) == TYPE_DECL && !DECL_ORIGINAL_TYPE (t))
2880 int is_interface = 0;
2881 int is_abstract_record = 0;
2886 /* Anonymous structs/unions */
2887 dump_generic_ada_node
2888 (buffer, TREE_TYPE (t), t, cpp_check, spc, false, true);
2890 if (TREE_CODE (TREE_TYPE (t)) == UNION_TYPE
2891 || TREE_CODE (TREE_TYPE (t)) == QUAL_UNION_TYPE)
2893 pp_string (buffer, " (discr : unsigned := 0)");
2896 pp_string (buffer, " is ");
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)))
2903 tree tmp = TYPE_FIELDS (TREE_TYPE (t));
2905 /* Check that there are no fields other than the virtual table. */
2906 for (; tmp; tmp = TREE_CHAIN (tmp))
2908 if (TREE_CODE (tmp) == TYPE_DECL)
2913 if (num_fields == 1)
2916 /* Also check that there are only virtual methods. */
2917 for (tmp = TYPE_METHODS (TREE_TYPE (t)); tmp; tmp = TREE_CHAIN (tmp))
2919 if (cpp_check (tmp, IS_ABSTRACT))
2920 is_abstract_record = 1;
2926 TREE_VISITED (t) = 1;
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,
2936 pp_character (buffer, ')');
2938 print_ada_methods (buffer, TREE_TYPE (t), cpp_check, spc);
2942 if (is_abstract_record)
2943 pp_string (buffer, "abstract ");
2944 dump_generic_ada_node (buffer, t, t, cpp_check, spc, false, false);
2952 if (TREE_CODE (t) == FIELD_DECL && DECL_NAME (t))
2953 check_name (buffer, t);
2955 /* Print variable/type's name. */
2956 dump_generic_ada_node (buffer, t, t, cpp_check, spc, false, true);
2958 if (TREE_CODE (t) == TYPE_DECL)
2960 tree orig = DECL_ORIGINAL_TYPE (t);
2961 int is_subtype = orig && TYPE_NAME (orig) && orig != TREE_TYPE (t);
2964 && (TREE_CODE (TREE_TYPE (t)) == UNION_TYPE
2965 || TREE_CODE (TREE_TYPE (t)) == QUAL_UNION_TYPE))
2966 pp_string (buffer, " (discr : unsigned := 0)");
2968 pp_string (buffer, " is ");
2970 dump_generic_ada_node
2971 (buffer, orig, t, cpp_check, spc, false, is_subtype);
2975 if (spc == INDENT_INCR || TREE_STATIC (t))
2978 pp_string (buffer, " : ");
2980 /* Print type declaration. */
2982 if (TREE_CODE (TREE_TYPE (t)) == UNION_TYPE
2983 && !TYPE_NAME (TREE_TYPE (t)))
2985 dump_ada_double_name (buffer, type, t, "_union");
2987 else if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t)))
2989 if (TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE)
2990 pp_string (buffer, "aliased ");
2992 dump_generic_ada_node
2993 (buffer, TREE_TYPE (t), t, cpp_check, spc, false, true);
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 ");
3002 dump_generic_ada_node
3003 (buffer, TREE_TYPE (t), TREE_TYPE (t), cpp_check,
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);
3020 /* All needed indentation/newline performed already, so return 0. */
3025 pp_string (buffer, "; -- ");
3026 dump_sloc (buffer, t);
3031 newline_and_indent (buffer, spc);
3032 dump_ada_import (buffer, t);
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. */
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)
3050 TREE_CODE (node) == UNION_TYPE || TREE_CODE (node) == QUAL_UNION_TYPE;
3053 int field_spc = spc + INDENT_INCR;
3056 bitfield_used = false;
3058 if (!TYPE_FIELDS (node))
3059 pp_string (buffer, "null record;");
3062 pp_string (buffer, "record");
3064 /* Print the contents of the structure. */
3068 newline_and_indent (buffer, spc + INDENT_INCR);
3069 pp_string (buffer, "case discr is");
3070 field_spc = spc + INDENT_INCR * 3;
3073 pp_newline (buffer);
3075 /* Print the non-static fields of the structure. */
3076 for (tmp = TYPE_FIELDS (node); tmp; tmp = TREE_CHAIN (tmp))
3078 /* Add parent field if needed. */
3079 if (!DECL_NAME (tmp))
3081 if (!is_tagged_type (TREE_TYPE (tmp)))
3083 if (!TYPE_NAME (TREE_TYPE (tmp)))
3084 print_ada_declaration
3085 (buffer, tmp, type, cpp_check, field_spc);
3091 pp_string (buffer, "parent : ");
3094 sprintf (buf, "field_%d : ", field_num + 1);
3095 pp_string (buffer, buf);
3098 (buffer, TYPE_NAME (TREE_TYPE (tmp)), false);
3099 pp_semicolon (buffer);
3101 pp_newline (buffer);
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))
3112 /* Skip internal virtual table field. */
3113 if (strncmp (IDENTIFIER_POINTER (DECL_NAME (tmp)), "_vptr", 5))
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);
3122 sprintf (buf, "when others =>");
3124 INDENT (spc + INDENT_INCR * 2);
3125 pp_string (buffer, buf);
3126 pp_newline (buffer);
3129 if (print_ada_declaration (buffer,
3130 tmp, type, cpp_check, field_spc))
3132 pp_newline (buffer);
3141 INDENT (spc + INDENT_INCR);
3142 pp_string (buffer, "end case;");
3143 pp_newline (buffer);
3148 INDENT (spc + INDENT_INCR);
3149 pp_string (buffer, "null;");
3150 pp_newline (buffer);
3154 pp_string (buffer, "end record;");
3157 newline_and_indent (buffer, spc);
3159 if (!display_convention)
3162 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type)))
3164 if (TYPE_METHODS (TREE_TYPE (type)))
3165 pp_string (buffer, "pragma Import (CPP, ");
3167 pp_string (buffer, "pragma Convention (C_Pass_By_Copy, ");
3170 pp_string (buffer, "pragma Convention (C, ");
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, ')');
3180 pp_semicolon (buffer);
3181 newline_and_indent (buffer, spc);
3182 pp_string (buffer, "pragma Unchecked_Union (");
3184 dump_generic_ada_node
3185 (buffer, TREE_TYPE (type), type, cpp_check, spc, false, true);
3186 pp_character (buffer, ')');
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;
3200 print_ada_methods (buffer, node, cpp_check, spc);
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))
3206 if (DECL_NAME (tmp) && TREE_STATIC (tmp))
3210 need_semicolon = false;
3211 pp_semicolon (buffer);
3213 pp_newline (buffer);
3214 pp_newline (buffer);
3215 print_ada_declaration (buffer, tmp, type, cpp_check, spc);
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
3226 dump_ads (const char *source_file,
3227 void (*collect_all_refs)(const char *),
3228 int (*cpp_check)(tree, cpp_operation))
3235 pkg_name = get_ada_package (source_file);
3237 /* Construct the .ads filename and package name. */
3238 ads_name = xstrdup (pkg_name);
3240 for (s = ads_name; *s; s++)
3243 ads_name = reconcat (ads_name, ads_name, ".ads", NULL);
3245 /* Write out the .ads file. */
3246 f = fopen (ads_name, "w");
3251 pp_construct (&pp, NULL, 0);
3252 pp_needs_newline (&pp) = true;
3253 pp.buffer->stream = f;
3255 /* Dump all relevant macros. */
3256 dump_ada_macros (&pp, source_file);
3258 /* Reset the table of withs for this file. */
3261 (*collect_all_refs) (source_file);
3263 /* Dump all references. */
3264 dump_ada_nodes (&pp, source_file, cpp_check);
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);
3280 static const char **source_refs = NULL;
3281 static int source_refs_used = 0;
3282 static int source_refs_allocd = 0;
3284 /* Add an entry for FILENAME to the table SOURCE_REFS. */
3287 collect_source_ref (const char *filename)
3294 if (source_refs_allocd == 0)
3296 source_refs_allocd = 1024;
3297 source_refs = XNEWVEC (const char *, source_refs_allocd);
3300 for (i = 0; i < source_refs_used; i++)
3301 if (filename == source_refs [i])
3304 if (source_refs_used == source_refs_allocd)
3306 source_refs_allocd *= 2;
3307 source_refs = XRESIZEVEC (const char *, source_refs, source_refs_allocd);
3310 source_refs [source_refs_used++] = filename;
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
3321 dump_ada_specs (void (*collect_all_refs)(const char *),
3322 int (*cpp_check)(tree, cpp_operation))
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);
3330 /* Free files table. */