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-2018 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 "c-ada-spec.h"
28 #include "fold-const.h"
30 #include "stringpool.h"
33 /* Local functions, macros and variables. */
34 static int dump_ada_node (pretty_printer
*, tree
, tree
, int, bool, bool);
35 static int dump_ada_declaration (pretty_printer
*, tree
, tree
, int);
36 static void dump_ada_structure (pretty_printer
*, tree
, tree
, bool, int);
37 static char *to_ada_name (const char *, bool *);
39 #define INDENT(SPACE) \
40 do { int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
44 /* Global hook used to perform C++ queries on nodes. */
45 static int (*cpp_check
) (tree
, cpp_operation
) = NULL
;
47 /* Global variables used in macro-related callbacks. */
48 static int max_ada_macros
;
49 static int store_ada_macro_index
;
50 static const char *macro_source_file
;
52 /* Given a cpp MACRO, compute the max length BUFFER_LEN of the macro, as well
53 as max length PARAM_LEN of arguments for fun_like macros, and also set
54 SUPPORTED to 0 if the macro cannot be mapped to an Ada construct. */
57 macro_length (const cpp_macro
*macro
, int *supported
, int *buffer_len
,
70 for (i
= 0; i
< macro
->paramc
; i
++)
72 cpp_hashnode
*param
= macro
->parm
.params
[i
];
74 *param_len
+= NODE_LEN (param
);
76 if (i
+ 1 < macro
->paramc
)
78 *param_len
+= 2; /* ", " */
80 else if (macro
->variadic
)
86 *param_len
+= 2; /* ")\0" */
89 for (j
= 0; j
< macro
->count
; j
++)
91 const cpp_token
*token
= ¯o
->exp
.tokens
[j
];
93 if (token
->flags
& PREV_WHITE
)
96 if (token
->flags
& STRINGIFY_ARG
|| token
->flags
& PASTE_LEFT
)
102 if (token
->type
== CPP_MACRO_ARG
)
104 NODE_LEN (macro
->parm
.params
[token
->val
.macro_arg
.arg_no
- 1]);
106 /* Include enough extra space to handle e.g. special characters. */
107 *buffer_len
+= (cpp_token_len (token
) + 1) * 8;
113 /* Dump all digits/hex chars from NUMBER to BUFFER and return a pointer
114 to the character after the last character written. If FLOAT_P is true,
115 this is a floating-point number. */
117 static unsigned char *
118 dump_number (unsigned char *number
, unsigned char *buffer
, bool float_p
)
120 while (*number
!= '\0'
121 && *number
!= (float_p
? 'F' : 'U')
122 && *number
!= (float_p
? 'f' : 'u')
125 *buffer
++ = *number
++;
130 /* Handle escape character C and convert to an Ada character into BUFFER.
131 Return a pointer to the character after the last character written, or
132 NULL if the escape character is not supported. */
134 static unsigned char *
135 handle_escape_character (unsigned char *buffer
, char c
)
145 strcpy ((char *) buffer
, "\" & ASCII.LF & \"");
150 strcpy ((char *) buffer
, "\" & ASCII.CR & \"");
155 strcpy ((char *) buffer
, "\" & ASCII.HT & \"");
166 /* Callback used to count the number of macros from cpp_forall_identifiers.
167 PFILE and V are not used. NODE is the current macro to consider. */
170 count_ada_macro (cpp_reader
*pfile ATTRIBUTE_UNUSED
, cpp_hashnode
*node
,
171 void *v ATTRIBUTE_UNUSED
)
173 if (cpp_user_macro_p (node
) && *NODE_NAME (node
) != '_')
175 const cpp_macro
*macro
= node
->value
.macro
;
176 if (macro
->count
&& LOCATION_FILE (macro
->line
) == macro_source_file
)
183 /* Callback used to store relevant macros from cpp_forall_identifiers.
184 PFILE is not used. NODE is the current macro to store if relevant.
185 MACROS is an array of cpp_hashnode* used to store NODE. */
188 store_ada_macro (cpp_reader
*pfile ATTRIBUTE_UNUSED
,
189 cpp_hashnode
*node
, void *macros
)
191 if (cpp_user_macro_p (node
) && *NODE_NAME (node
) != '_')
193 const cpp_macro
*macro
= node
->value
.macro
;
195 && LOCATION_FILE (macro
->line
) == macro_source_file
)
196 ((cpp_hashnode
**) macros
)[store_ada_macro_index
++] = node
;
201 /* Callback used to compare (during qsort) macros. NODE1 and NODE2 are the
202 two macro nodes to compare. */
205 compare_macro (const void *node1
, const void *node2
)
207 typedef const cpp_hashnode
*const_hnode
;
209 const_hnode n1
= *(const const_hnode
*) node1
;
210 const_hnode n2
= *(const const_hnode
*) node2
;
212 return n1
->value
.macro
->line
- n2
->value
.macro
->line
;
215 /* Dump in PP all relevant macros appearing in FILE. */
218 dump_ada_macros (pretty_printer
*pp
, const char* file
)
220 int num_macros
= 0, prev_line
= -1;
221 cpp_hashnode
**macros
;
223 /* Initialize file-scope variables. */
225 store_ada_macro_index
= 0;
226 macro_source_file
= file
;
228 /* Count all potentially relevant macros, and then sort them by sloc. */
229 cpp_forall_identifiers (parse_in
, count_ada_macro
, NULL
);
230 macros
= XALLOCAVEC (cpp_hashnode
*, max_ada_macros
);
231 cpp_forall_identifiers (parse_in
, store_ada_macro
, macros
);
232 qsort (macros
, max_ada_macros
, sizeof (cpp_hashnode
*), compare_macro
);
234 for (int j
= 0; j
< max_ada_macros
; j
++)
236 cpp_hashnode
*node
= macros
[j
];
237 const cpp_macro
*macro
= node
->value
.macro
;
239 int supported
= 1, prev_is_one
= 0, buffer_len
, param_len
;
240 int is_string
= 0, is_char
= 0;
242 unsigned char *s
, *params
, *buffer
, *buf_param
, *char_one
= NULL
, *tmp
;
244 macro_length (macro
, &supported
, &buffer_len
, ¶m_len
);
245 s
= buffer
= XALLOCAVEC (unsigned char, buffer_len
);
246 params
= buf_param
= XALLOCAVEC (unsigned char, param_len
);
253 for (i
= 0; i
< macro
->paramc
; i
++)
255 cpp_hashnode
*param
= macro
->parm
.params
[i
];
257 memcpy (buf_param
, NODE_NAME (param
), NODE_LEN (param
));
258 buf_param
+= NODE_LEN (param
);
260 if (i
+ 1 < macro
->paramc
)
265 else if (macro
->variadic
)
275 for (i
= 0; supported
&& i
< macro
->count
; i
++)
277 const cpp_token
*token
= ¯o
->exp
.tokens
[i
];
280 if (token
->flags
& PREV_WHITE
)
283 if (token
->flags
& STRINGIFY_ARG
|| token
->flags
& PASTE_LEFT
)
293 cpp_hashnode
*param
=
294 macro
->parm
.params
[token
->val
.macro_arg
.arg_no
- 1];
295 memcpy (buffer
, NODE_NAME (param
), NODE_LEN (param
));
296 buffer
+= NODE_LEN (param
);
300 case CPP_EQ_EQ
: *buffer
++ = '='; break;
301 case CPP_GREATER
: *buffer
++ = '>'; break;
302 case CPP_LESS
: *buffer
++ = '<'; break;
303 case CPP_PLUS
: *buffer
++ = '+'; break;
304 case CPP_MINUS
: *buffer
++ = '-'; break;
305 case CPP_MULT
: *buffer
++ = '*'; break;
306 case CPP_DIV
: *buffer
++ = '/'; break;
307 case CPP_COMMA
: *buffer
++ = ','; break;
308 case CPP_OPEN_SQUARE
:
309 case CPP_OPEN_PAREN
: *buffer
++ = '('; break;
310 case CPP_CLOSE_SQUARE
: /* fallthrough */
311 case CPP_CLOSE_PAREN
: *buffer
++ = ')'; break;
312 case CPP_DEREF
: /* fallthrough */
313 case CPP_SCOPE
: /* fallthrough */
314 case CPP_DOT
: *buffer
++ = '.'; break;
316 case CPP_EQ
: *buffer
++ = ':'; *buffer
++ = '='; break;
317 case CPP_NOT_EQ
: *buffer
++ = '/'; *buffer
++ = '='; break;
318 case CPP_GREATER_EQ
: *buffer
++ = '>'; *buffer
++ = '='; break;
319 case CPP_LESS_EQ
: *buffer
++ = '<'; *buffer
++ = '='; break;
322 *buffer
++ = 'n'; *buffer
++ = 'o'; *buffer
++ = 't'; break;
324 *buffer
++ = 'm'; *buffer
++ = 'o'; *buffer
++ = 'd'; break;
326 *buffer
++ = 'a'; *buffer
++ = 'n'; *buffer
++ = 'd'; break;
328 *buffer
++ = 'o'; *buffer
++ = 'r'; break;
330 *buffer
++ = 'x'; *buffer
++ = 'o'; *buffer
++ = 'r'; break;
332 strcpy ((char *) buffer
, " and then ");
336 strcpy ((char *) buffer
, " or else ");
342 is_one
= prev_is_one
;
357 if (!macro
->fun_like
)
361 = cpp_spell_token (parse_in
, token
, buffer
, false);
373 const unsigned char *s
= token
->val
.str
.text
;
379 buffer
= handle_escape_character (buffer
, *s
);
398 c
= cpp_interpret_charconst (parse_in
, token
,
399 &chars_seen
, &ignored
);
400 if (c
>= 32 && c
<= 126)
403 *buffer
++ = (char) c
;
409 ((char *) buffer
, "Character'Val (%d)", (int) c
);
410 buffer
+= chars_seen
;
416 tmp
= cpp_token_as_text (parse_in
, token
);
436 buffer
= dump_number (tmp
+ 2, buffer
, false);
444 buffer
= dump_number (tmp
+ 2, buffer
, false);
449 /* Dump floating-point constant unmodified. */
450 if (strchr ((const char *)tmp
, '.'))
451 buffer
= dump_number (tmp
, buffer
, true);
457 = dump_number (tmp
+ 1, buffer
, false);
480 = dump_number (tmp
, buffer
,
481 strchr ((const char *)tmp
, '.'));
489 /* Replace "1 << N" by "2 ** N" */
516 case CPP_CLOSE_BRACE
:
520 case CPP_MINUS_MINUS
:
524 case CPP_HEADER_NAME
:
527 case CPP_OBJC_STRING
:
529 if (!macro
->fun_like
)
532 buffer
= cpp_spell_token (parse_in
, token
, buffer
, false);
536 prev_is_one
= is_one
;
543 if (macro
->fun_like
&& supported
)
545 char *start
= (char *) s
;
548 pp_string (pp
, " -- arg-macro: ");
550 if (*start
== '(' && buffer
[-1] == ')')
555 pp_string (pp
, "function ");
559 pp_string (pp
, "procedure ");
562 pp_string (pp
, (const char *) NODE_NAME (node
));
564 pp_string (pp
, (char *) params
);
566 pp_string (pp
, " -- ");
570 pp_string (pp
, "return ");
571 pp_string (pp
, start
);
575 pp_string (pp
, start
);
581 expanded_location sloc
= expand_location (macro
->line
);
583 if (sloc
.line
!= prev_line
+ 1 && prev_line
> 0)
587 prev_line
= sloc
.line
;
590 ada_name
= to_ada_name ((const char *) NODE_NAME (node
), NULL
);
591 pp_string (pp
, ada_name
);
593 pp_string (pp
, " : ");
596 pp_string (pp
, "aliased constant String");
598 pp_string (pp
, "aliased constant Character");
600 pp_string (pp
, "constant");
602 pp_string (pp
, " := ");
603 pp_string (pp
, (char *) s
);
606 pp_string (pp
, " & ASCII.NUL");
608 pp_string (pp
, "; -- ");
609 pp_string (pp
, sloc
.file
);
611 pp_scalar (pp
, "%d", sloc
.line
);
616 pp_string (pp
, " -- unsupported macro: ");
617 pp_string (pp
, (const char *) cpp_macro_definition (parse_in
, node
));
626 /* Current source file being handled. */
627 static const char *current_source_file
;
629 /* Return sloc of DECL, using sloc of last field if LAST is true. */
632 decl_sloc (const_tree decl
, bool last
)
636 /* Compare the declaration of struct-like types based on the sloc of their
637 last field (if LAST is true), so that more nested types collate before
639 if (TREE_CODE (decl
) == TYPE_DECL
640 && !DECL_ORIGINAL_TYPE (decl
)
641 && RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl
))
642 && (field
= TYPE_FIELDS (TREE_TYPE (decl
))))
645 while (DECL_CHAIN (field
))
646 field
= DECL_CHAIN (field
);
647 return DECL_SOURCE_LOCATION (field
);
650 return DECL_SOURCE_LOCATION (decl
);
653 /* Compare two locations LHS and RHS. */
656 compare_location (location_t lhs
, location_t rhs
)
658 expanded_location xlhs
= expand_location (lhs
);
659 expanded_location xrhs
= expand_location (rhs
);
661 if (xlhs
.file
!= xrhs
.file
)
662 return filename_cmp (xlhs
.file
, xrhs
.file
);
664 if (xlhs
.line
!= xrhs
.line
)
665 return xlhs
.line
- xrhs
.line
;
667 if (xlhs
.column
!= xrhs
.column
)
668 return xlhs
.column
- xrhs
.column
;
673 /* Compare two declarations (LP and RP) by their source location. */
676 compare_node (const void *lp
, const void *rp
)
678 const_tree lhs
= *((const tree
*) lp
);
679 const_tree rhs
= *((const tree
*) rp
);
681 return compare_location (decl_sloc (lhs
, true), decl_sloc (rhs
, true));
684 /* Compare two comments (LP and RP) by their source location. */
687 compare_comment (const void *lp
, const void *rp
)
689 const cpp_comment
*lhs
= (const cpp_comment
*) lp
;
690 const cpp_comment
*rhs
= (const cpp_comment
*) rp
;
692 return compare_location (lhs
->sloc
, rhs
->sloc
);
695 static tree
*to_dump
= NULL
;
696 static int to_dump_count
= 0;
698 /* Collect a list of declarations from T relevant to SOURCE_FILE to be dumped
699 by a subsequent call to dump_ada_nodes. */
702 collect_ada_nodes (tree t
, const char *source_file
)
705 int i
= to_dump_count
;
707 /* Count the likely relevant nodes: do not dump builtins (they are irrelevant
708 in the context of bindings) and namespaces (we do not handle them properly
710 for (n
= t
; n
; n
= TREE_CHAIN (n
))
711 if (!DECL_IS_BUILTIN (n
)
712 && TREE_CODE (n
) != NAMESPACE_DECL
713 && LOCATION_FILE (decl_sloc (n
, false)) == source_file
)
716 /* Allocate sufficient storage for all nodes. */
717 to_dump
= XRESIZEVEC (tree
, to_dump
, to_dump_count
);
719 /* Store the relevant nodes. */
720 for (n
= t
; n
; n
= TREE_CHAIN (n
))
721 if (!DECL_IS_BUILTIN (n
)
722 && TREE_CODE (n
) != NAMESPACE_DECL
723 && LOCATION_FILE (decl_sloc (n
, false)) == source_file
)
727 /* Call back for walk_tree to clear the TREE_VISITED flag of TP. */
730 unmark_visited_r (tree
*tp
, int *walk_subtrees ATTRIBUTE_UNUSED
,
731 void *data ATTRIBUTE_UNUSED
)
733 if (TREE_VISITED (*tp
))
734 TREE_VISITED (*tp
) = 0;
741 /* Print a COMMENT to the output stream PP. */
744 print_comment (pretty_printer
*pp
, const char *comment
)
746 int len
= strlen (comment
);
747 char *str
= XALLOCAVEC (char, len
+ 1);
749 bool extra_newline
= false;
751 memcpy (str
, comment
, len
+ 1);
753 /* Trim C/C++ comment indicators. */
754 if (str
[len
- 2] == '*' && str
[len
- 1] == '/')
761 tok
= strtok (str
, "\n");
763 pp_string (pp
, " --");
766 tok
= strtok (NULL
, "\n");
768 /* Leave a blank line after multi-line comments. */
770 extra_newline
= true;
777 /* Dump nodes into PP relevant to SOURCE_FILE, as collected by previous calls
778 to collect_ada_nodes. */
781 dump_ada_nodes (pretty_printer
*pp
, const char *source_file
)
784 cpp_comment_table
*comments
;
786 /* Sort the table of declarations to dump by sloc. */
787 qsort (to_dump
, to_dump_count
, sizeof (tree
), compare_node
);
789 /* Fetch the table of comments. */
790 comments
= cpp_get_comments (parse_in
);
792 /* Sort the comments table by sloc. */
793 if (comments
->count
> 1)
794 qsort (comments
->entries
, comments
->count
, sizeof (cpp_comment
),
797 /* Interleave comments and declarations in line number order. */
801 /* Advance j until comment j is in this file. */
802 while (j
!= comments
->count
803 && LOCATION_FILE (comments
->entries
[j
].sloc
) != source_file
)
806 /* Advance j until comment j is not a duplicate. */
807 while (j
< comments
->count
- 1
808 && !compare_comment (&comments
->entries
[j
],
809 &comments
->entries
[j
+ 1]))
812 /* Write decls until decl i collates after comment j. */
813 while (i
!= to_dump_count
)
815 if (j
== comments
->count
816 || LOCATION_LINE (decl_sloc (to_dump
[i
], false))
817 < LOCATION_LINE (comments
->entries
[j
].sloc
))
819 current_source_file
= source_file
;
821 if (dump_ada_declaration (pp
, to_dump
[i
++], NULL_TREE
,
832 /* Write comment j, if there is one. */
833 if (j
!= comments
->count
)
834 print_comment (pp
, comments
->entries
[j
++].comment
);
836 } while (i
!= to_dump_count
|| j
!= comments
->count
);
838 /* Clear the TREE_VISITED flag over each subtree we've dumped. */
839 for (i
= 0; i
< to_dump_count
; i
++)
840 walk_tree (&to_dump
[i
], unmark_visited_r
, NULL
, NULL
);
842 /* Finalize the to_dump table. */
851 /* Dump a newline and indent BUFFER by SPC chars. */
854 newline_and_indent (pretty_printer
*buffer
, int spc
)
860 struct with
{ char *s
; const char *in_file
; bool limited
; };
861 static struct with
*withs
= NULL
;
862 static int withs_max
= 4096;
863 static int with_len
= 0;
865 /* Record a "with" clause on package S (a limited with if LIMITED_ACCESS is
866 true), if not already done. */
869 append_withs (const char *s
, bool limited_access
)
874 withs
= XNEWVEC (struct with
, withs_max
);
876 if (with_len
== withs_max
)
879 withs
= XRESIZEVEC (struct with
, withs
, withs_max
);
882 for (i
= 0; i
< with_len
; i
++)
883 if (!strcmp (s
, withs
[i
].s
)
884 && current_source_file
== withs
[i
].in_file
)
886 withs
[i
].limited
&= limited_access
;
890 withs
[with_len
].s
= xstrdup (s
);
891 withs
[with_len
].in_file
= current_source_file
;
892 withs
[with_len
].limited
= limited_access
;
896 /* Reset "with" clauses. */
899 reset_ada_withs (void)
906 for (i
= 0; i
< with_len
; i
++)
914 /* Dump "with" clauses in F. */
917 dump_ada_withs (FILE *f
)
921 fprintf (f
, "with Interfaces.C; use Interfaces.C;\n");
923 for (i
= 0; i
< with_len
; i
++)
925 (f
, "%swith %s;\n", withs
[i
].limited
? "limited " : "", withs
[i
].s
);
928 /* Return suitable Ada package name from FILE. */
931 get_ada_package (const char *file
)
939 s
= strstr (file
, "/include/");
943 base
= lbasename (file
);
945 if (ada_specs_parent
== NULL
)
948 plen
= strlen (ada_specs_parent
) + 1;
950 res
= XNEWVEC (char, plen
+ strlen (base
) + 1);
951 if (ada_specs_parent
!= NULL
) {
952 strcpy (res
, ada_specs_parent
);
956 for (i
= plen
; *base
; base
++, i
++)
968 res
[i
] = (i
== 0 || res
[i
- 1] == '.' || res
[i
- 1] == '_') ? 'u' : '_';
980 static const char *ada_reserved
[] = {
981 "abort", "abs", "abstract", "accept", "access", "aliased", "all", "and",
982 "array", "at", "begin", "body", "case", "constant", "declare", "delay",
983 "delta", "digits", "do", "else", "elsif", "end", "entry", "exception",
984 "exit", "for", "function", "generic", "goto", "if", "in", "interface", "is",
985 "limited", "loop", "mod", "new", "not", "null", "others", "out", "of", "or",
986 "overriding", "package", "pragma", "private", "procedure", "protected",
987 "raise", "range", "record", "rem", "renames", "requeue", "return", "reverse",
988 "select", "separate", "subtype", "synchronized", "tagged", "task",
989 "terminate", "then", "type", "until", "use", "when", "while", "with", "xor",
992 /* ??? would be nice to specify this list via a config file, so that users
993 can create their own dictionary of conflicts. */
994 static const char *c_duplicates
[] = {
995 /* system will cause troubles with System.Address. */
998 /* The following values have other definitions with same name/other
1004 "rl_readline_version",
1010 /* Return a declaration tree corresponding to TYPE. */
1013 get_underlying_decl (tree type
)
1018 /* type is a declaration. */
1022 /* type is a typedef. */
1023 if (TYPE_P (type
) && TYPE_NAME (type
) && DECL_P (TYPE_NAME (type
)))
1024 return TYPE_NAME (type
);
1026 /* TYPE_STUB_DECL has been set for type. */
1027 if (TYPE_P (type
) && TYPE_STUB_DECL (type
))
1028 return TYPE_STUB_DECL (type
);
1033 /* Return whether TYPE has static fields. */
1036 has_static_fields (const_tree type
)
1038 if (!type
|| !RECORD_OR_UNION_TYPE_P (type
))
1041 for (tree fld
= TYPE_FIELDS (type
); fld
; fld
= TREE_CHAIN (fld
))
1042 if (TREE_CODE (fld
) == VAR_DECL
&& DECL_NAME (fld
))
1048 /* Return whether TYPE corresponds to an Ada tagged type (has a dispatch
1052 is_tagged_type (const_tree type
)
1054 if (!type
|| !RECORD_OR_UNION_TYPE_P (type
))
1057 for (tree fld
= TYPE_FIELDS (type
); fld
; fld
= TREE_CHAIN (fld
))
1058 if (TREE_CODE (fld
) == FUNCTION_DECL
&& DECL_VINDEX (fld
))
1064 /* Return whether TYPE has non-trivial methods, i.e. methods that do something
1065 for the objects of TYPE. In C++, all classes have implicit special methods,
1066 e.g. constructors and destructors, but they can be trivial if the type is
1067 sufficiently simple. */
1070 has_nontrivial_methods (tree type
)
1072 if (!type
|| !RECORD_OR_UNION_TYPE_P (type
))
1075 /* Only C++ types can have methods. */
1079 /* A non-trivial type has non-trivial special methods. */
1080 if (!cpp_check (type
, IS_TRIVIAL
))
1083 /* If there are user-defined methods, they are deemed non-trivial. */
1084 for (tree fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
1085 if (TREE_CODE (fld
) == FUNCTION_DECL
&& !DECL_ARTIFICIAL (fld
))
1091 #define INDEX_LENGTH 8
1093 /* Generate a legal Ada name from a C/C++ NAME and return a malloc'ed string.
1094 SPACE_FOUND, if not NULL, is used to indicate whether a space was found in
1098 to_ada_name (const char *name
, bool *space_found
)
1101 const int len
= strlen (name
);
1104 char *s
= XNEWVEC (char, len
* 2 + 5);
1108 *space_found
= false;
1110 /* Add "c_" prefix if name is an Ada reserved word. */
1111 for (names
= ada_reserved
; *names
; names
++)
1112 if (!strcasecmp (name
, *names
))
1121 /* Add "c_" prefix if name is a potential case sensitive duplicate. */
1122 for (names
= c_duplicates
; *names
; names
++)
1123 if (!strcmp (name
, *names
))
1131 for (j
= 0; name
[j
] == '_'; j
++)
1136 else if (*name
== '.' || *name
== '$')
1146 /* Replace unsuitable characters for Ada identifiers. */
1147 for (; j
< len
; j
++)
1152 *space_found
= true;
1156 /* ??? missing some C++ operators. */
1160 if (name
[j
+ 1] == '=')
1175 if (name
[j
+ 1] == '=')
1193 s
[len2
++] = name
[j
] == '&' ? 'a' : name
[j
] == '|' ? 'o' : 'x';
1195 if (name
[j
+ 1] == '=')
1208 if (s
[len2
- 1] != '_')
1211 switch (name
[j
+ 1]) {
1214 switch (name
[j
- 1]) {
1215 case '+': s
[len2
++] = 'p'; break; /* + */
1216 case '-': s
[len2
++] = 'm'; break; /* - */
1217 case '*': s
[len2
++] = 't'; break; /* * */
1218 case '/': s
[len2
++] = 'd'; break; /* / */
1224 switch (name
[j
- 1]) {
1225 case '+': s
[len2
++] = 'p'; break; /* += */
1226 case '-': s
[len2
++] = 'm'; break; /* -= */
1227 case '*': s
[len2
++] = 't'; break; /* *= */
1228 case '/': s
[len2
++] = 'd'; break; /* /= */
1262 c
= name
[j
] == '<' ? 'l' : 'g';
1265 switch (name
[j
+ 1]) {
1291 if (len2
&& s
[len2
- 1] == '_')
1296 s
[len2
++] = name
[j
];
1299 if (s
[len2
- 1] == '_')
1307 /* Return true if DECL refers to a C++ class type for which a
1308 separate enclosing package has been or should be generated. */
1311 separate_class_package (tree decl
)
1313 tree type
= TREE_TYPE (decl
);
1314 return has_nontrivial_methods (type
) || has_static_fields (type
);
1317 static bool package_prefix
= true;
1319 /* Dump in BUFFER the name of an identifier NODE of type TYPE, following Ada
1320 syntax. LIMITED_ACCESS indicates whether NODE can be accessed through a
1321 limited 'with' clause rather than a regular 'with' clause. */
1324 pp_ada_tree_identifier (pretty_printer
*buffer
, tree node
, tree type
,
1325 bool limited_access
)
1327 const char *name
= IDENTIFIER_POINTER (node
);
1328 bool space_found
= false;
1329 char *s
= to_ada_name (name
, &space_found
);
1330 tree decl
= get_underlying_decl (type
);
1332 /* If the entity comes from another file, generate a package prefix. */
1335 expanded_location xloc
= expand_location (decl_sloc (decl
, false));
1337 if (xloc
.file
&& xloc
.line
)
1339 if (xloc
.file
!= current_source_file
)
1341 switch (TREE_CODE (type
))
1346 case FIXED_POINT_TYPE
:
1348 case REFERENCE_TYPE
:
1356 char *s1
= get_ada_package (xloc
.file
);
1357 append_withs (s1
, limited_access
);
1358 pp_string (buffer
, s1
);
1367 /* Generate the additional package prefix for C++ classes. */
1368 if (separate_class_package (decl
))
1370 pp_string (buffer
, "Class_");
1371 pp_string (buffer
, s
);
1379 if (!strcmp (s
, "short_int"))
1380 pp_string (buffer
, "short");
1381 else if (!strcmp (s
, "short_unsigned_int"))
1382 pp_string (buffer
, "unsigned_short");
1383 else if (!strcmp (s
, "unsigned_int"))
1384 pp_string (buffer
, "unsigned");
1385 else if (!strcmp (s
, "long_int"))
1386 pp_string (buffer
, "long");
1387 else if (!strcmp (s
, "long_unsigned_int"))
1388 pp_string (buffer
, "unsigned_long");
1389 else if (!strcmp (s
, "long_long_int"))
1390 pp_string (buffer
, "Long_Long_Integer");
1391 else if (!strcmp (s
, "long_long_unsigned_int"))
1395 append_withs ("Interfaces.C.Extensions", false);
1396 pp_string (buffer
, "Extensions.unsigned_long_long");
1399 pp_string (buffer
, "unsigned_long_long");
1402 pp_string(buffer
, s
);
1404 if (!strcmp (s
, "u_Bool") || !strcmp (s
, "bool"))
1408 append_withs ("Interfaces.C.Extensions", false);
1409 pp_string (buffer
, "Extensions.bool");
1412 pp_string (buffer
, "bool");
1415 pp_string(buffer
, s
);
1420 /* Dump in BUFFER the assembly name of T. */
1423 pp_asm_name (pretty_printer
*buffer
, tree t
)
1425 tree name
= DECL_ASSEMBLER_NAME (t
);
1426 char *ada_name
= XALLOCAVEC (char, IDENTIFIER_LENGTH (name
) + 1), *s
;
1427 const char *ident
= IDENTIFIER_POINTER (name
);
1429 for (s
= ada_name
; *ident
; ident
++)
1433 else if (*ident
!= '*')
1438 pp_string (buffer
, ada_name
);
1441 /* Dump in BUFFER the name of a DECL node if set, in Ada syntax.
1442 LIMITED_ACCESS indicates whether NODE can be accessed via a
1443 limited 'with' clause rather than a regular 'with' clause. */
1446 dump_ada_decl_name (pretty_printer
*buffer
, tree decl
, bool limited_access
)
1448 if (DECL_NAME (decl
))
1449 pp_ada_tree_identifier (buffer
, DECL_NAME (decl
), decl
, limited_access
);
1452 tree type_name
= TYPE_NAME (TREE_TYPE (decl
));
1456 pp_string (buffer
, "anon");
1457 if (TREE_CODE (decl
) == FIELD_DECL
)
1458 pp_scalar (buffer
, "%d", DECL_UID (decl
));
1460 pp_scalar (buffer
, "%d", TYPE_UID (TREE_TYPE (decl
)));
1462 else if (TREE_CODE (type_name
) == IDENTIFIER_NODE
)
1463 pp_ada_tree_identifier (buffer
, type_name
, decl
, limited_access
);
1467 /* Dump in BUFFER a name based on both T1 and T2 followed by a suffix. */
1470 dump_ada_double_name (pretty_printer
*buffer
, tree t1
, tree t2
)
1473 pp_ada_tree_identifier (buffer
, DECL_NAME (t1
), t1
, false);
1476 pp_string (buffer
, "anon");
1477 pp_scalar (buffer
, "%d", TYPE_UID (TREE_TYPE (t1
)));
1480 pp_underscore (buffer
);
1483 pp_ada_tree_identifier (buffer
, DECL_NAME (t2
), t2
, false);
1486 pp_string (buffer
, "anon");
1487 pp_scalar (buffer
, "%d", TYPE_UID (TREE_TYPE (t2
)));
1490 switch (TREE_CODE (TREE_TYPE (t2
)))
1493 pp_string (buffer
, "_array");
1496 pp_string (buffer
, "_enum");
1499 pp_string (buffer
, "_struct");
1502 pp_string (buffer
, "_union");
1505 pp_string (buffer
, "_unknown");
1510 /* Dump in BUFFER aspect Import on a given node T. SPC is the current
1511 indentation level. */
1514 dump_ada_import (pretty_printer
*buffer
, tree t
, int spc
)
1516 const char *name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t
));
1517 const bool is_stdcall
1518 = TREE_CODE (t
) == FUNCTION_DECL
1519 && lookup_attribute ("stdcall", TYPE_ATTRIBUTES (TREE_TYPE (t
)));
1521 pp_string (buffer
, "with Import => True, ");
1523 newline_and_indent (buffer
, spc
+ 5);
1526 pp_string (buffer
, "Convention => Stdcall, ");
1527 else if (name
[0] == '_' && name
[1] == 'Z')
1528 pp_string (buffer
, "Convention => CPP, ");
1530 pp_string (buffer
, "Convention => C, ");
1532 newline_and_indent (buffer
, spc
+ 5);
1534 pp_string (buffer
, "External_Name => \"");
1537 pp_string (buffer
, IDENTIFIER_POINTER (DECL_NAME (t
)));
1539 pp_asm_name (buffer
, t
);
1541 pp_string (buffer
, "\";");
1544 /* Check whether T and its type have different names, and append "the_"
1545 otherwise in BUFFER. */
1548 check_name (pretty_printer
*buffer
, tree t
)
1551 tree tmp
= TREE_TYPE (t
);
1553 while (TREE_CODE (tmp
) == POINTER_TYPE
&& !TYPE_NAME (tmp
))
1554 tmp
= TREE_TYPE (tmp
);
1556 if (TREE_CODE (tmp
) != FUNCTION_TYPE
)
1558 if (TREE_CODE (tmp
) == IDENTIFIER_NODE
)
1559 s
= IDENTIFIER_POINTER (tmp
);
1560 else if (!TYPE_NAME (tmp
))
1562 else if (TREE_CODE (TYPE_NAME (tmp
)) == IDENTIFIER_NODE
)
1563 s
= IDENTIFIER_POINTER (TYPE_NAME (tmp
));
1565 s
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (tmp
)));
1567 if (!strcasecmp (IDENTIFIER_POINTER (DECL_NAME (t
)), s
))
1568 pp_string (buffer
, "the_");
1572 /* Dump in BUFFER a function declaration FUNC in Ada syntax.
1573 IS_METHOD indicates whether FUNC is a C++ method.
1574 IS_CONSTRUCTOR whether FUNC is a C++ constructor.
1575 IS_DESTRUCTOR whether FUNC is a C++ destructor.
1576 SPC is the current indentation level. */
1579 dump_ada_function_declaration (pretty_printer
*buffer
, tree func
,
1580 bool is_method
, bool is_constructor
,
1581 bool is_destructor
, int spc
)
1584 const tree node
= TREE_TYPE (func
);
1586 int num
= 0, num_args
= 0, have_args
= true, have_ellipsis
= false;
1588 /* Compute number of arguments. */
1589 arg
= TYPE_ARG_TYPES (node
);
1593 while (TREE_CHAIN (arg
) && arg
!= error_mark_node
)
1596 arg
= TREE_CHAIN (arg
);
1599 if (TREE_CODE (TREE_VALUE (arg
)) != VOID_TYPE
)
1602 have_ellipsis
= true;
1613 newline_and_indent (buffer
, spc
+ 1);
1618 pp_left_paren (buffer
);
1621 if (TREE_CODE (func
) == FUNCTION_DECL
)
1622 arg
= DECL_ARGUMENTS (func
);
1626 if (arg
== NULL_TREE
)
1629 arg
= TYPE_ARG_TYPES (node
);
1631 if (arg
&& TREE_CODE (TREE_VALUE (arg
)) == VOID_TYPE
)
1636 arg
= TREE_CHAIN (arg
);
1638 /* Print the argument names (if available) & types. */
1640 for (num
= 1; num
<= num_args
; num
++)
1644 if (DECL_NAME (arg
))
1646 check_name (buffer
, arg
);
1647 pp_ada_tree_identifier (buffer
, DECL_NAME (arg
), NULL_TREE
,
1649 pp_string (buffer
, " : ");
1653 sprintf (buf
, "arg%d : ", num
);
1654 pp_string (buffer
, buf
);
1657 dump_ada_node (buffer
, TREE_TYPE (arg
), node
, spc
, false, true);
1661 sprintf (buf
, "arg%d : ", num
);
1662 pp_string (buffer
, buf
);
1663 dump_ada_node (buffer
, TREE_VALUE (arg
), node
, spc
, false, true);
1666 /* If the type is a pointer to a tagged type, we need to differentiate
1667 virtual methods from the rest (non-virtual methods, static member
1668 or regular functions) and import only them as primitive operations,
1669 because they make up the virtual table which is mirrored on the Ada
1670 side by the dispatch table. So we add 'Class to the type of every
1671 parameter that is not the first one of a method which either has a
1672 slot in the virtual table or is a constructor. */
1674 && POINTER_TYPE_P (TREE_TYPE (arg
))
1675 && is_tagged_type (TREE_TYPE (TREE_TYPE (arg
)))
1676 && !(num
== 1 && is_method
&& (DECL_VINDEX (func
) || is_constructor
)))
1677 pp_string (buffer
, "'Class");
1679 arg
= TREE_CHAIN (arg
);
1683 pp_semicolon (buffer
);
1686 newline_and_indent (buffer
, spc
+ INDENT_INCR
);
1694 pp_string (buffer
, " -- , ...");
1695 newline_and_indent (buffer
, spc
+ INDENT_INCR
);
1699 pp_right_paren (buffer
);
1701 if (is_constructor
|| !VOID_TYPE_P (TREE_TYPE (node
)))
1703 pp_string (buffer
, " return ");
1704 tree type
= is_constructor
? DECL_CONTEXT (func
) : TREE_TYPE (node
);
1705 dump_ada_node (buffer
, type
, type
, spc
, false, true);
1709 /* Dump in BUFFER all the domains associated with an array NODE,
1710 in Ada syntax. SPC is the current indentation level. */
1713 dump_ada_array_domains (pretty_printer
*buffer
, tree node
, int spc
)
1716 pp_left_paren (buffer
);
1718 for (; TREE_CODE (node
) == ARRAY_TYPE
; node
= TREE_TYPE (node
))
1720 tree domain
= TYPE_DOMAIN (node
);
1724 tree min
= TYPE_MIN_VALUE (domain
);
1725 tree max
= TYPE_MAX_VALUE (domain
);
1728 pp_string (buffer
, ", ");
1732 dump_ada_node (buffer
, min
, NULL_TREE
, spc
, false, true);
1733 pp_string (buffer
, " .. ");
1735 /* If the upper bound is zero, gcc may generate a NULL_TREE
1736 for TYPE_MAX_VALUE rather than an integer_cst. */
1738 dump_ada_node (buffer
, max
, NULL_TREE
, spc
, false, true);
1740 pp_string (buffer
, "0");
1743 pp_string (buffer
, "size_t");
1745 pp_right_paren (buffer
);
1748 /* Dump in BUFFER file:line information related to NODE. */
1751 dump_sloc (pretty_printer
*buffer
, tree node
)
1753 expanded_location xloc
;
1758 xloc
= expand_location (DECL_SOURCE_LOCATION (node
));
1759 else if (EXPR_HAS_LOCATION (node
))
1760 xloc
= expand_location (EXPR_LOCATION (node
));
1764 pp_string (buffer
, xloc
.file
);
1766 pp_decimal_int (buffer
, xloc
.line
);
1770 /* Return true if type T designates a 1-dimension array of "char". */
1773 is_char_array (tree t
)
1777 while (TREE_CODE (t
) == ARRAY_TYPE
)
1784 && TREE_CODE (t
) == INTEGER_TYPE
1785 && id_equal (DECL_NAME (TYPE_NAME (t
)), "char");
1788 /* Dump in BUFFER an array type NODE of type TYPE in Ada syntax. SPC is the
1789 indentation level. */
1792 dump_ada_array_type (pretty_printer
*buffer
, tree node
, tree type
, int spc
)
1794 const bool char_array
= is_char_array (node
);
1796 /* Special case char arrays. */
1798 pp_string (buffer
, "Interfaces.C.char_array ");
1800 pp_string (buffer
, "array ");
1802 /* Print the dimensions. */
1803 dump_ada_array_domains (buffer
, node
, spc
);
1805 /* Print array's type. */
1808 /* Retrieve the element type. */
1810 while (TREE_CODE (tmp
) == ARRAY_TYPE
)
1811 tmp
= TREE_TYPE (tmp
);
1813 pp_string (buffer
, " of ");
1815 if (TREE_CODE (tmp
) != POINTER_TYPE
)
1816 pp_string (buffer
, "aliased ");
1818 if (TYPE_NAME (tmp
) || !RECORD_OR_UNION_TYPE_P (tmp
))
1819 dump_ada_node (buffer
, tmp
, node
, spc
, false, true);
1821 dump_ada_double_name (buffer
, type
, get_underlying_decl (tmp
));
1825 /* Dump in BUFFER type names associated with a template, each prepended with
1826 '_'. TYPES is the TREE_PURPOSE of a DECL_TEMPLATE_INSTANTIATIONS. SPC is
1827 the indentation level. */
1830 dump_template_types (pretty_printer
*buffer
, tree types
, int spc
)
1832 for (int i
= 0; i
< TREE_VEC_LENGTH (types
); i
++)
1834 tree elem
= TREE_VEC_ELT (types
, i
);
1835 pp_underscore (buffer
);
1837 if (!dump_ada_node (buffer
, elem
, NULL_TREE
, spc
, false, true))
1839 pp_string (buffer
, "unknown");
1840 pp_scalar (buffer
, "%lu", (unsigned long) TREE_HASH (elem
));
1845 /* Dump in BUFFER the contents of all class instantiations associated with
1846 a given template T. SPC is the indentation level. */
1849 dump_ada_template (pretty_printer
*buffer
, tree t
, int spc
)
1851 /* DECL_SIZE_UNIT is DECL_TEMPLATE_INSTANTIATIONS in this context. */
1852 tree inst
= DECL_SIZE_UNIT (t
);
1853 /* This emulates DECL_TEMPLATE_RESULT in this context. */
1854 struct tree_template_decl
{
1855 struct tree_decl_common common
;
1859 tree result
= ((struct tree_template_decl
*) t
)->result
;
1862 /* Don't look at template declarations declaring something coming from
1863 another file. This can occur for template friend declarations. */
1864 if (LOCATION_FILE (decl_sloc (result
, false))
1865 != LOCATION_FILE (decl_sloc (t
, false)))
1868 for (; inst
&& inst
!= error_mark_node
; inst
= TREE_CHAIN (inst
))
1870 tree types
= TREE_PURPOSE (inst
);
1871 tree instance
= TREE_VALUE (inst
);
1873 if (TREE_VEC_LENGTH (types
) == 0)
1876 if (!RECORD_OR_UNION_TYPE_P (instance
))
1879 /* We are interested in concrete template instantiations only: skip
1880 partially specialized nodes. */
1881 if (RECORD_OR_UNION_TYPE_P (instance
)
1883 && cpp_check (instance
, HAS_DEPENDENT_TEMPLATE_ARGS
))
1888 pp_string (buffer
, "package ");
1889 package_prefix
= false;
1890 dump_ada_node (buffer
, instance
, t
, spc
, false, true);
1891 dump_template_types (buffer
, types
, spc
);
1892 pp_string (buffer
, " is");
1894 newline_and_indent (buffer
, spc
);
1896 TREE_VISITED (get_underlying_decl (instance
)) = 1;
1897 pp_string (buffer
, "type ");
1898 dump_ada_node (buffer
, instance
, t
, spc
, false, true);
1899 package_prefix
= true;
1901 if (is_tagged_type (instance
))
1902 pp_string (buffer
, " is tagged limited ");
1904 pp_string (buffer
, " is limited ");
1906 dump_ada_node (buffer
, instance
, t
, spc
, false, false);
1907 pp_newline (buffer
);
1909 newline_and_indent (buffer
, spc
);
1911 pp_string (buffer
, "end;");
1912 newline_and_indent (buffer
, spc
);
1913 pp_string (buffer
, "use ");
1914 package_prefix
= false;
1915 dump_ada_node (buffer
, instance
, t
, spc
, false, true);
1916 dump_template_types (buffer
, types
, spc
);
1917 package_prefix
= true;
1918 pp_semicolon (buffer
);
1919 pp_newline (buffer
);
1920 pp_newline (buffer
);
1923 return num_inst
> 0;
1926 /* Return true if NODE is a simple enum types, that can be mapped to an
1927 Ada enum type directly. */
1930 is_simple_enum (tree node
)
1932 HOST_WIDE_INT count
= 0;
1934 for (tree value
= TYPE_VALUES (node
); value
; value
= TREE_CHAIN (value
))
1936 tree int_val
= TREE_VALUE (value
);
1938 if (TREE_CODE (int_val
) != INTEGER_CST
)
1939 int_val
= DECL_INITIAL (int_val
);
1941 if (!tree_fits_shwi_p (int_val
))
1943 else if (tree_to_shwi (int_val
) != count
)
1952 /* Dump in BUFFER an enumeral type NODE in Ada syntax. SPC is the indentation
1956 dump_ada_enum_type (pretty_printer
*buffer
, tree node
, int spc
)
1958 if (is_simple_enum (node
))
1962 newline_and_indent (buffer
, spc
- 1);
1963 pp_left_paren (buffer
);
1964 for (tree value
= TYPE_VALUES (node
); value
; value
= TREE_CHAIN (value
))
1971 newline_and_indent (buffer
, spc
);
1974 pp_ada_tree_identifier (buffer
, TREE_PURPOSE (value
), node
, false);
1976 pp_string (buffer
, ")");
1978 newline_and_indent (buffer
, spc
);
1979 pp_string (buffer
, "with Convention => C");
1983 if (TYPE_UNSIGNED (node
))
1984 pp_string (buffer
, "unsigned");
1986 pp_string (buffer
, "int");
1987 for (tree value
= TYPE_VALUES (node
); value
; value
= TREE_CHAIN (value
))
1989 pp_semicolon (buffer
);
1990 newline_and_indent (buffer
, spc
);
1992 pp_ada_tree_identifier (buffer
, TREE_PURPOSE (value
), node
, false);
1993 pp_string (buffer
, " : constant ");
1995 if (TYPE_UNSIGNED (node
))
1996 pp_string (buffer
, "unsigned");
1998 pp_string (buffer
, "int");
2000 pp_string (buffer
, " := ");
2001 dump_ada_node (buffer
,
2002 TREE_CODE (TREE_VALUE (value
)) == INTEGER_CST
2003 ? TREE_VALUE (value
)
2004 : DECL_INITIAL (TREE_VALUE (value
)),
2005 node
, spc
, false, true);
2010 static bool bitfield_used
= false;
2012 /* Recursively dump in BUFFER Ada declarations corresponding to NODE of type
2013 TYPE. SPC is the indentation level. LIMITED_ACCESS indicates whether NODE
2014 can be referenced via a "limited with" clause. NAME_ONLY indicates whether
2015 we should only dump the name of NODE, instead of its full declaration. */
2018 dump_ada_node (pretty_printer
*buffer
, tree node
, tree type
, int spc
,
2019 bool limited_access
, bool name_only
)
2021 if (node
== NULL_TREE
)
2024 switch (TREE_CODE (node
))
2027 pp_string (buffer
, "<<< error >>>");
2030 case IDENTIFIER_NODE
:
2031 pp_ada_tree_identifier (buffer
, node
, type
, limited_access
);
2035 pp_string (buffer
, "--- unexpected node: TREE_LIST");
2039 dump_ada_node (buffer
, BINFO_TYPE (node
), type
, spc
, limited_access
,
2044 pp_string (buffer
, "--- unexpected node: TREE_VEC");
2051 append_withs ("System", false);
2052 pp_string (buffer
, "System.Address");
2055 pp_string (buffer
, "address");
2059 pp_string (buffer
, "<vector>");
2063 pp_string (buffer
, "<complex>");
2068 dump_ada_node (buffer
, TYPE_NAME (node
), node
, spc
, false, true);
2070 dump_ada_enum_type (buffer
, node
, spc
);
2074 if (TYPE_NAME (node
)
2075 && TREE_CODE (TYPE_NAME (node
)) == TYPE_DECL
2076 && IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node
))) [0] == '_'
2077 && (id_equal (DECL_NAME (TYPE_NAME (node
)), "_Float128")
2078 || id_equal (DECL_NAME (TYPE_NAME (node
)), "__float128")))
2080 append_withs ("Interfaces.C.Extensions", false);
2081 pp_string (buffer
, "Extensions.Float_128");
2087 case FIXED_POINT_TYPE
:
2089 if (TYPE_NAME (node
))
2091 if (TREE_CODE (TYPE_NAME (node
)) == IDENTIFIER_NODE
)
2092 pp_ada_tree_identifier (buffer
, TYPE_NAME (node
), node
,
2094 else if (TREE_CODE (TYPE_NAME (node
)) == TYPE_DECL
2095 && DECL_NAME (TYPE_NAME (node
)))
2096 dump_ada_decl_name (buffer
, TYPE_NAME (node
), limited_access
);
2098 pp_string (buffer
, "<unnamed type>");
2100 else if (TREE_CODE (node
) == INTEGER_TYPE
)
2102 append_withs ("Interfaces.C.Extensions", false);
2103 bitfield_used
= true;
2105 if (TYPE_PRECISION (node
) == 1)
2106 pp_string (buffer
, "Extensions.Unsigned_1");
2109 pp_string (buffer
, TYPE_UNSIGNED (node
)
2110 ? "Extensions.Unsigned_"
2111 : "Extensions.Signed_");
2112 pp_decimal_int (buffer
, TYPE_PRECISION (node
));
2116 pp_string (buffer
, "<unnamed type>");
2120 case REFERENCE_TYPE
:
2121 if (name_only
&& TYPE_NAME (node
))
2122 dump_ada_node (buffer
, TYPE_NAME (node
), node
, spc
, limited_access
,
2125 else if (TREE_CODE (TREE_TYPE (node
)) == FUNCTION_TYPE
)
2127 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (node
))))
2128 pp_string (buffer
, "access procedure");
2130 pp_string (buffer
, "access function");
2132 dump_ada_function_declaration (buffer
, node
, false, false, false,
2135 /* If we are dumping the full type, it means we are part of a
2136 type definition and need also a Convention C aspect. */
2139 newline_and_indent (buffer
, spc
);
2140 pp_string (buffer
, "with Convention => C");
2145 bool is_access
= false;
2146 unsigned int quals
= TYPE_QUALS (TREE_TYPE (node
));
2148 if (VOID_TYPE_P (TREE_TYPE (node
)))
2151 pp_string (buffer
, "new ");
2154 append_withs ("System", false);
2155 pp_string (buffer
, "System.Address");
2158 pp_string (buffer
, "address");
2162 if (TREE_CODE (node
) == POINTER_TYPE
2163 && TREE_CODE (TREE_TYPE (node
)) == INTEGER_TYPE
2164 && id_equal (DECL_NAME (TYPE_NAME (TREE_TYPE (node
))),
2168 pp_string (buffer
, "new ");
2172 pp_string (buffer
, "Interfaces.C.Strings.chars_ptr");
2173 append_withs ("Interfaces.C.Strings", false);
2176 pp_string (buffer
, "chars_ptr");
2180 tree type_name
= TYPE_NAME (TREE_TYPE (node
));
2182 /* For now, handle access-to-access as System.Address. */
2183 if (TREE_CODE (TREE_TYPE (node
)) == POINTER_TYPE
)
2187 append_withs ("System", false);
2189 pp_string (buffer
, "new ");
2190 pp_string (buffer
, "System.Address");
2193 pp_string (buffer
, "address");
2197 if (!package_prefix
)
2198 pp_string (buffer
, "access");
2199 else if (AGGREGATE_TYPE_P (TREE_TYPE (node
)))
2201 if (!type
|| TREE_CODE (type
) != FUNCTION_DECL
)
2203 pp_string (buffer
, "access ");
2206 if (quals
& TYPE_QUAL_CONST
)
2207 pp_string (buffer
, "constant ");
2208 else if (!name_only
)
2209 pp_string (buffer
, "all ");
2211 else if (quals
& TYPE_QUAL_CONST
)
2212 pp_string (buffer
, "in ");
2216 pp_string (buffer
, "access ");
2217 /* ??? should be configurable: access or in out. */
2223 pp_string (buffer
, "access ");
2226 pp_string (buffer
, "all ");
2229 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node
)) && type_name
)
2230 dump_ada_node (buffer
, type_name
, TREE_TYPE (node
), spc
,
2233 dump_ada_node (buffer
, TREE_TYPE (node
), TREE_TYPE (node
),
2242 dump_ada_node (buffer
, TYPE_NAME (node
), node
, spc
, limited_access
,
2245 dump_ada_array_type (buffer
, node
, type
, spc
);
2251 dump_ada_node (buffer
, TYPE_NAME (node
), node
, spc
, limited_access
,
2254 dump_ada_structure (buffer
, node
, type
, false, spc
);
2258 /* We treat the upper half of the sizetype range as negative. This
2259 is consistent with the internal treatment and makes it possible
2260 to generate the (0 .. -1) range for flexible array members. */
2261 if (TREE_TYPE (node
) == sizetype
)
2262 node
= fold_convert (ssizetype
, node
);
2263 if (tree_fits_shwi_p (node
))
2264 pp_wide_integer (buffer
, tree_to_shwi (node
));
2265 else if (tree_fits_uhwi_p (node
))
2266 pp_unsigned_wide_integer (buffer
, tree_to_uhwi (node
));
2269 wide_int val
= wi::to_wide (node
);
2271 if (wi::neg_p (val
))
2276 sprintf (pp_buffer (buffer
)->digit_buffer
,
2277 "16#%" HOST_WIDE_INT_PRINT
"x",
2278 val
.elt (val
.get_len () - 1));
2279 for (i
= val
.get_len () - 2; i
>= 0; i
--)
2280 sprintf (pp_buffer (buffer
)->digit_buffer
,
2281 HOST_WIDE_INT_PRINT_PADDED_HEX
, val
.elt (i
));
2282 pp_string (buffer
, pp_buffer (buffer
)->digit_buffer
);
2294 if (DECL_IS_BUILTIN (node
))
2296 /* Don't print the declaration of built-in types. */
2299 /* If we're in the middle of a declaration, defaults to
2303 append_withs ("System", false);
2304 pp_string (buffer
, "System.Address");
2307 pp_string (buffer
, "address");
2313 dump_ada_decl_name (buffer
, node
, limited_access
);
2316 if (is_tagged_type (TREE_TYPE (node
)))
2320 /* Look for ancestors. */
2321 for (tree fld
= TYPE_FIELDS (TREE_TYPE (node
));
2323 fld
= TREE_CHAIN (fld
))
2325 if (!DECL_NAME (fld
) && is_tagged_type (TREE_TYPE (fld
)))
2329 pp_string (buffer
, "limited new ");
2333 pp_string (buffer
, " and ");
2335 dump_ada_decl_name (buffer
, TYPE_NAME (TREE_TYPE (fld
)),
2340 pp_string (buffer
, first
? "tagged limited " : " with ");
2342 else if (has_nontrivial_methods (TREE_TYPE (node
)))
2343 pp_string (buffer
, "limited ");
2345 dump_ada_node (buffer
, TREE_TYPE (node
), type
, spc
, false, false);
2354 case NAMESPACE_DECL
:
2355 dump_ada_decl_name (buffer
, node
, false);
2359 /* Ignore other nodes (e.g. expressions). */
2366 /* Dump in BUFFER NODE's methods. SPC is the indentation level. Return 1 if
2367 methods were printed, 0 otherwise. */
2370 dump_ada_methods (pretty_printer
*buffer
, tree node
, int spc
)
2372 if (!has_nontrivial_methods (node
))
2375 pp_semicolon (buffer
);
2378 for (tree fld
= TYPE_FIELDS (node
); fld
; fld
= DECL_CHAIN (fld
))
2379 if (TREE_CODE (fld
) == FUNCTION_DECL
)
2383 pp_newline (buffer
);
2384 pp_newline (buffer
);
2387 res
= dump_ada_declaration (buffer
, fld
, node
, spc
);
2393 /* Dump in BUFFER a forward declaration for TYPE present inside T.
2394 SPC is the indentation level. */
2397 dump_forward_type (pretty_printer
*buffer
, tree type
, tree t
, int spc
)
2399 tree decl
= get_underlying_decl (type
);
2401 /* Anonymous pointer and function types. */
2404 if (TREE_CODE (type
) == POINTER_TYPE
)
2405 dump_forward_type (buffer
, TREE_TYPE (type
), t
, spc
);
2406 else if (TREE_CODE (type
) == FUNCTION_TYPE
)
2408 function_args_iterator args_iter
;
2410 dump_forward_type (buffer
, TREE_TYPE (type
), t
, spc
);
2411 FOREACH_FUNCTION_ARGS (type
, arg
, args_iter
)
2412 dump_forward_type (buffer
, arg
, t
, spc
);
2417 if (DECL_IS_BUILTIN (decl
) || TREE_VISITED (decl
))
2420 /* Forward declarations are only needed within a given file. */
2421 if (DECL_SOURCE_FILE (decl
) != DECL_SOURCE_FILE (t
))
2424 /* Generate an incomplete type declaration. */
2425 pp_string (buffer
, "type ");
2426 dump_ada_node (buffer
, decl
, NULL_TREE
, spc
, false, true);
2427 pp_semicolon (buffer
);
2428 newline_and_indent (buffer
, spc
);
2430 /* Only one incomplete declaration is legal for a given type. */
2431 TREE_VISITED (decl
) = 1;
2434 static void dump_nested_type (pretty_printer
*, tree
, tree
, tree
, int);
2436 /* Dump in BUFFER anonymous types nested inside T's definition.
2437 PARENT is the parent node of T. SPC is the indentation level.
2439 In C anonymous nested tagged types have no name whereas in C++ they have
2440 one. In C their TYPE_DECL is at top level whereas in C++ it is nested.
2441 In both languages untagged types (pointers and arrays) have no name.
2442 In C++ the nested TYPE_DECLs can come after their associated FIELD_DECL.
2444 Therefore, in order to have a common processing for both languages, we
2445 disregard anonymous TYPE_DECLs at top level and here we make a first
2446 pass on the nested TYPE_DECLs and a second pass on the unnamed types. */
2449 dump_nested_types (pretty_printer
*buffer
, tree t
, tree parent
, int spc
)
2453 /* Find possible anonymous pointers/arrays/structs/unions recursively. */
2454 type
= TREE_TYPE (t
);
2455 if (type
== NULL_TREE
)
2458 for (field
= TYPE_FIELDS (type
); field
; field
= TREE_CHAIN (field
))
2459 if (TREE_CODE (field
) == TYPE_DECL
2460 && DECL_NAME (field
) != DECL_NAME (t
)
2461 && !DECL_ORIGINAL_TYPE (field
)
2462 && TYPE_NAME (TREE_TYPE (field
)) != TYPE_NAME (type
))
2463 dump_nested_type (buffer
, field
, t
, parent
, spc
);
2465 for (field
= TYPE_FIELDS (type
); field
; field
= TREE_CHAIN (field
))
2466 if (TREE_CODE (field
) == FIELD_DECL
&& !TYPE_NAME (TREE_TYPE (field
)))
2467 dump_nested_type (buffer
, field
, t
, parent
, spc
);
2470 /* Dump in BUFFER the anonymous type of FIELD inside T.
2471 PARENT is the parent node of T. SPC is the indentation level. */
2474 dump_nested_type (pretty_printer
*buffer
, tree field
, tree t
, tree parent
,
2477 tree field_type
= TREE_TYPE (field
);
2480 switch (TREE_CODE (field_type
))
2483 tmp
= TREE_TYPE (field_type
);
2484 dump_forward_type (buffer
, tmp
, t
, spc
);
2488 tmp
= TREE_TYPE (field_type
);
2489 while (TREE_CODE (tmp
) == ARRAY_TYPE
)
2490 tmp
= TREE_TYPE (tmp
);
2491 decl
= get_underlying_decl (tmp
);
2492 if (decl
&& !DECL_NAME (decl
) && !TREE_VISITED (decl
))
2494 /* Generate full declaration. */
2495 dump_nested_type (buffer
, decl
, t
, parent
, spc
);
2496 TREE_VISITED (decl
) = 1;
2498 else if (!decl
&& TREE_CODE (tmp
) == POINTER_TYPE
)
2499 dump_forward_type (buffer
, TREE_TYPE (tmp
), t
, spc
);
2501 /* Special case char arrays. */
2502 if (is_char_array (field_type
))
2503 pp_string (buffer
, "subtype ");
2505 pp_string (buffer
, "type ");
2507 dump_ada_double_name (buffer
, parent
, field
);
2508 pp_string (buffer
, " is ");
2509 dump_ada_array_type (buffer
, field_type
, parent
, spc
);
2510 pp_semicolon (buffer
);
2511 newline_and_indent (buffer
, spc
);
2515 if (is_simple_enum (field_type
))
2516 pp_string (buffer
, "type ");
2518 pp_string (buffer
, "subtype ");
2520 if (TYPE_NAME (field_type
))
2521 dump_ada_node (buffer
, field_type
, NULL_TREE
, spc
, false, true);
2523 dump_ada_double_name (buffer
, parent
, field
);
2524 pp_string (buffer
, " is ");
2525 dump_ada_enum_type (buffer
, field_type
, spc
);
2526 pp_semicolon (buffer
);
2527 newline_and_indent (buffer
, spc
);
2532 dump_nested_types (buffer
, field
, t
, spc
);
2534 pp_string (buffer
, "type ");
2536 if (TYPE_NAME (field_type
))
2537 dump_ada_node (buffer
, field_type
, NULL_TREE
, spc
, false, true);
2539 dump_ada_double_name (buffer
, parent
, field
);
2541 if (TREE_CODE (field_type
) == UNION_TYPE
)
2542 pp_string (buffer
, " (discr : unsigned := 0)");
2544 pp_string (buffer
, " is ");
2545 dump_ada_structure (buffer
, field_type
, t
, true, spc
);
2547 pp_string (buffer
, "with Convention => C_Pass_By_Copy");
2549 if (TREE_CODE (field_type
) == UNION_TYPE
)
2552 newline_and_indent (buffer
, spc
+ 5);
2553 pp_string (buffer
, "Unchecked_Union => True");
2556 pp_semicolon (buffer
);
2557 newline_and_indent (buffer
, spc
);
2565 /* Dump in BUFFER constructor spec corresponding to T for TYPE. */
2568 print_constructor (pretty_printer
*buffer
, tree t
, tree type
)
2570 tree decl_name
= DECL_NAME (TYPE_NAME (type
));
2572 pp_string (buffer
, "New_");
2573 pp_ada_tree_identifier (buffer
, decl_name
, t
, false);
2576 /* Dump in BUFFER destructor spec corresponding to T. */
2579 print_destructor (pretty_printer
*buffer
, tree t
, tree type
)
2581 tree decl_name
= DECL_NAME (TYPE_NAME (type
));
2583 pp_string (buffer
, "Delete_");
2584 pp_ada_tree_identifier (buffer
, decl_name
, t
, false);
2587 /* Return the name of type T. */
2592 tree n
= TYPE_NAME (t
);
2594 if (TREE_CODE (n
) == IDENTIFIER_NODE
)
2595 return IDENTIFIER_POINTER (n
);
2597 return IDENTIFIER_POINTER (DECL_NAME (n
));
2600 /* Dump in BUFFER the declaration of a variable T of type TYPE in Ada syntax.
2601 SPC is the indentation level. Return 1 if a declaration was printed,
2605 dump_ada_declaration (pretty_printer
*buffer
, tree t
, tree type
, int spc
)
2607 bool is_var
= false;
2608 bool need_indent
= false;
2609 bool is_class
= false;
2610 tree name
= TYPE_NAME (TREE_TYPE (t
));
2611 tree decl_name
= DECL_NAME (t
);
2612 tree orig
= NULL_TREE
;
2614 if (cpp_check
&& cpp_check (t
, IS_TEMPLATE
))
2615 return dump_ada_template (buffer
, t
, spc
);
2617 /* Skip enumeral values: will be handled as part of the type itself. */
2618 if (TREE_CODE (t
) == CONST_DECL
&& TREE_CODE (TREE_TYPE (t
)) == ENUMERAL_TYPE
)
2621 if (TREE_CODE (t
) == TYPE_DECL
)
2623 orig
= DECL_ORIGINAL_TYPE (t
);
2625 if (orig
&& TYPE_STUB_DECL (orig
))
2627 tree stub
= TYPE_STUB_DECL (orig
);
2628 tree typ
= TREE_TYPE (stub
);
2630 if (TYPE_NAME (typ
))
2632 /* If the types have the same name (ignoring casing), then ignore
2633 the second type, but forward declare the first if need be. */
2634 if (type_name (typ
) == type_name (TREE_TYPE (t
))
2635 || !strcasecmp (type_name (typ
), type_name (TREE_TYPE (t
))))
2637 if (RECORD_OR_UNION_TYPE_P (typ
) && !TREE_VISITED (stub
))
2640 dump_forward_type (buffer
, typ
, t
, 0);
2643 TREE_VISITED (t
) = 1;
2649 if (RECORD_OR_UNION_TYPE_P (typ
) && !TREE_VISITED (stub
))
2650 dump_forward_type (buffer
, typ
, t
, spc
);
2652 pp_string (buffer
, "subtype ");
2653 dump_ada_node (buffer
, t
, type
, spc
, false, true);
2654 pp_string (buffer
, " is ");
2655 dump_ada_node (buffer
, typ
, type
, spc
, false, true);
2656 pp_string (buffer
, "; -- ");
2657 dump_sloc (buffer
, t
);
2659 TREE_VISITED (t
) = 1;
2664 /* Skip unnamed or anonymous structs/unions/enum types. */
2665 if (!orig
&& !decl_name
&& !name
2666 && (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t
))
2667 || TREE_CODE (TREE_TYPE (t
)) == ENUMERAL_TYPE
))
2670 /* Skip anonymous enum types (duplicates of real types). */
2672 && TREE_CODE (TREE_TYPE (t
)) == ENUMERAL_TYPE
2674 && (*IDENTIFIER_POINTER (decl_name
) == '.'
2675 || *IDENTIFIER_POINTER (decl_name
) == '$'))
2680 switch (TREE_CODE (TREE_TYPE (t
)))
2684 if (!COMPLETE_TYPE_P (TREE_TYPE (t
)))
2686 pp_string (buffer
, "type ");
2687 dump_ada_node (buffer
, t
, type
, spc
, false, true);
2688 pp_string (buffer
, " is null record; -- incomplete struct");
2689 TREE_VISITED (t
) = 1;
2694 && (*IDENTIFIER_POINTER (decl_name
) == '.'
2695 || *IDENTIFIER_POINTER (decl_name
) == '$'))
2697 pp_string (buffer
, "-- skipped anonymous struct ");
2698 dump_ada_node (buffer
, t
, type
, spc
, false, true);
2699 TREE_VISITED (t
) = 1;
2703 if (orig
&& TYPE_NAME (orig
))
2704 pp_string (buffer
, "subtype ");
2707 dump_nested_types (buffer
, t
, t
, spc
);
2709 if (separate_class_package (t
))
2712 pp_string (buffer
, "package Class_");
2713 dump_ada_node (buffer
, t
, type
, spc
, false, true);
2714 pp_string (buffer
, " is");
2716 newline_and_indent (buffer
, spc
);
2719 pp_string (buffer
, "type ");
2724 case REFERENCE_TYPE
:
2725 dump_forward_type (buffer
, TREE_TYPE (TREE_TYPE (t
)), t
, spc
);
2729 if ((orig
&& TYPE_NAME (orig
)) || is_char_array (TREE_TYPE (t
)))
2730 pp_string (buffer
, "subtype ");
2732 pp_string (buffer
, "type ");
2736 pp_string (buffer
, "-- skipped function type ");
2737 dump_ada_node (buffer
, t
, type
, spc
, false, true);
2741 if ((orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
))
2742 || !is_simple_enum (TREE_TYPE (t
)))
2743 pp_string (buffer
, "subtype ");
2745 pp_string (buffer
, "type ");
2749 pp_string (buffer
, "subtype ");
2751 TREE_VISITED (t
) = 1;
2757 && *IDENTIFIER_POINTER (decl_name
) == '_')
2763 /* Print the type and name. */
2764 if (TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
)
2769 /* Print variable's name. */
2770 dump_ada_node (buffer
, t
, type
, spc
, false, true);
2772 if (TREE_CODE (t
) == TYPE_DECL
)
2774 pp_string (buffer
, " is ");
2776 if (orig
&& TYPE_NAME (orig
))
2777 dump_ada_node (buffer
, TYPE_NAME (orig
), type
, spc
, false, true);
2779 dump_ada_array_type (buffer
, TREE_TYPE (t
), type
, spc
);
2783 tree tmp
= TYPE_NAME (TREE_TYPE (t
));
2785 if (spc
== INDENT_INCR
|| TREE_STATIC (t
))
2788 pp_string (buffer
, " : ");
2790 if (TREE_CODE (TREE_TYPE (TREE_TYPE (t
))) != POINTER_TYPE
)
2791 pp_string (buffer
, "aliased ");
2794 dump_ada_node (buffer
, tmp
, type
, spc
, false, true);
2796 dump_ada_double_name (buffer
, type
, t
);
2798 dump_ada_array_type (buffer
, TREE_TYPE (t
), type
, spc
);
2801 else if (TREE_CODE (t
) == FUNCTION_DECL
)
2803 bool is_abstract_class
= false;
2804 bool is_method
= TREE_CODE (TREE_TYPE (t
)) == METHOD_TYPE
;
2805 tree decl_name
= DECL_NAME (t
);
2806 bool is_abstract
= false;
2807 bool is_constructor
= false;
2808 bool is_destructor
= false;
2809 bool is_copy_constructor
= false;
2810 bool is_move_constructor
= false;
2817 is_abstract
= cpp_check (t
, IS_ABSTRACT
);
2818 is_constructor
= cpp_check (t
, IS_CONSTRUCTOR
);
2819 is_destructor
= cpp_check (t
, IS_DESTRUCTOR
);
2820 is_copy_constructor
= cpp_check (t
, IS_COPY_CONSTRUCTOR
);
2821 is_move_constructor
= cpp_check (t
, IS_MOVE_CONSTRUCTOR
);
2824 /* Skip copy constructors and C++11 move constructors: some are internal
2825 only and those that are not cannot be called easily from Ada. */
2826 if (is_copy_constructor
|| is_move_constructor
)
2829 if (is_constructor
|| is_destructor
)
2831 /* ??? Skip implicit constructors/destructors for now. */
2832 if (DECL_ARTIFICIAL (t
))
2835 /* Only consider constructors/destructors for complete objects. */
2836 if (strncmp (IDENTIFIER_POINTER (decl_name
), "__ct_comp", 9) != 0
2837 && strncmp (IDENTIFIER_POINTER (decl_name
), "__dt_comp", 9) != 0)
2841 /* If this function has an entry in the vtable, we cannot omit it. */
2842 else if (!DECL_VINDEX (t
) && *IDENTIFIER_POINTER (decl_name
) == '_')
2845 pp_string (buffer
, "-- skipped func ");
2846 pp_string (buffer
, IDENTIFIER_POINTER (decl_name
));
2853 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (t
))) && !is_constructor
)
2854 pp_string (buffer
, "procedure ");
2856 pp_string (buffer
, "function ");
2859 print_constructor (buffer
, t
, type
);
2860 else if (is_destructor
)
2861 print_destructor (buffer
, t
, type
);
2863 dump_ada_decl_name (buffer
, t
, false);
2865 dump_ada_function_declaration
2866 (buffer
, t
, is_method
, is_constructor
, is_destructor
, spc
);
2868 if (is_constructor
&& RECORD_OR_UNION_TYPE_P (type
))
2869 for (tree fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
2870 if (TREE_CODE (fld
) == FUNCTION_DECL
&& cpp_check (fld
, IS_ABSTRACT
))
2872 is_abstract_class
= true;
2876 if (is_abstract
|| is_abstract_class
)
2877 pp_string (buffer
, " is abstract");
2879 if (is_abstract
|| !DECL_ASSEMBLER_NAME (t
))
2881 pp_semicolon (buffer
);
2882 pp_string (buffer
, " -- ");
2883 dump_sloc (buffer
, t
);
2885 else if (is_constructor
)
2887 pp_semicolon (buffer
);
2888 pp_string (buffer
, " -- ");
2889 dump_sloc (buffer
, t
);
2891 newline_and_indent (buffer
, spc
);
2892 pp_string (buffer
, "pragma CPP_Constructor (");
2893 print_constructor (buffer
, t
, type
);
2894 pp_string (buffer
, ", \"");
2895 pp_asm_name (buffer
, t
);
2896 pp_string (buffer
, "\");");
2900 pp_string (buffer
, " -- ");
2901 dump_sloc (buffer
, t
);
2903 newline_and_indent (buffer
, spc
);
2904 dump_ada_import (buffer
, t
, spc
);
2909 else if (TREE_CODE (t
) == TYPE_DECL
&& !orig
)
2911 bool is_interface
= false;
2912 bool is_abstract_record
= false;
2917 /* Anonymous structs/unions. */
2918 dump_ada_node (buffer
, TREE_TYPE (t
), t
, spc
, false, true);
2920 if (TREE_CODE (TREE_TYPE (t
)) == UNION_TYPE
)
2921 pp_string (buffer
, " (discr : unsigned := 0)");
2923 pp_string (buffer
, " is ");
2925 /* Check whether we have an Ada interface compatible class.
2926 That is only have a vtable non-static data member and no
2927 non-abstract methods. */
2929 && RECORD_OR_UNION_TYPE_P (TREE_TYPE (t
)))
2931 bool has_fields
= false;
2933 /* Check that there are no fields other than the virtual table. */
2934 for (tree fld
= TYPE_FIELDS (TREE_TYPE (t
));
2936 fld
= TREE_CHAIN (fld
))
2938 if (TREE_CODE (fld
) == FIELD_DECL
)
2940 if (!has_fields
&& DECL_VIRTUAL_P (fld
))
2941 is_interface
= true;
2943 is_interface
= false;
2946 else if (TREE_CODE (fld
) == FUNCTION_DECL
2947 && !DECL_ARTIFICIAL (fld
))
2949 if (cpp_check (fld
, IS_ABSTRACT
))
2950 is_abstract_record
= true;
2952 is_interface
= false;
2957 TREE_VISITED (t
) = 1;
2960 pp_string (buffer
, "limited interface -- ");
2961 dump_sloc (buffer
, t
);
2962 newline_and_indent (buffer
, spc
);
2963 pp_string (buffer
, "with Import => True,");
2964 newline_and_indent (buffer
, spc
+ 5);
2965 pp_string (buffer
, "Convention => CPP");
2967 dump_ada_methods (buffer
, TREE_TYPE (t
), spc
);
2971 if (is_abstract_record
)
2972 pp_string (buffer
, "abstract ");
2973 dump_ada_node (buffer
, t
, t
, spc
, false, false);
2981 if (TREE_CODE (t
) == FIELD_DECL
&& DECL_NAME (t
))
2982 check_name (buffer
, t
);
2984 /* Print variable/type's name. */
2985 dump_ada_node (buffer
, t
, t
, spc
, false, true);
2987 if (TREE_CODE (t
) == TYPE_DECL
)
2989 const bool is_subtype
= TYPE_NAME (orig
);
2991 if (!is_subtype
&& TREE_CODE (TREE_TYPE (t
)) == UNION_TYPE
)
2992 pp_string (buffer
, " (discr : unsigned := 0)");
2994 pp_string (buffer
, " is ");
2996 dump_ada_node (buffer
, orig
, t
, spc
, false, is_subtype
);
3000 if (spc
== INDENT_INCR
|| TREE_STATIC (t
))
3003 pp_string (buffer
, " : ");
3005 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t
))
3006 || TREE_CODE (TREE_TYPE (t
)) == ENUMERAL_TYPE
)
3008 if (TYPE_NAME (TREE_TYPE (t
))
3009 || TREE_CODE (TREE_TYPE (t
)) != ENUMERAL_TYPE
)
3010 pp_string (buffer
, "aliased ");
3012 if (TREE_READONLY (t
) && TREE_CODE (t
) != FIELD_DECL
)
3013 pp_string (buffer
, "constant ");
3015 if (TYPE_NAME (TREE_TYPE (t
)))
3016 dump_ada_node (buffer
, TREE_TYPE (t
), t
, spc
, false, true);
3018 dump_ada_double_name (buffer
, type
, t
);
3022 if (TREE_CODE (TREE_TYPE (t
)) != POINTER_TYPE
3023 && (TYPE_NAME (TREE_TYPE (t
))
3024 || TREE_CODE (TREE_TYPE (t
)) != INTEGER_TYPE
))
3025 pp_string (buffer
, "aliased ");
3027 if (TREE_READONLY (t
) && TREE_CODE (t
) != FIELD_DECL
)
3028 pp_string (buffer
, "constant ");
3030 dump_ada_node (buffer
, TREE_TYPE (t
), t
, spc
, false, true);
3038 newline_and_indent (buffer
, spc
);
3039 pp_string (buffer
, "end;");
3040 newline_and_indent (buffer
, spc
);
3041 pp_string (buffer
, "use Class_");
3042 dump_ada_node (buffer
, t
, type
, spc
, false, true);
3043 pp_semicolon (buffer
);
3044 pp_newline (buffer
);
3046 /* All needed indentation/newline performed already, so return 0. */
3051 pp_string (buffer
, " -- ");
3052 dump_sloc (buffer
, t
);
3053 newline_and_indent (buffer
, spc
);
3054 dump_ada_import (buffer
, t
, spc
);
3059 pp_string (buffer
, "; -- ");
3060 dump_sloc (buffer
, t
);
3066 /* Dump in BUFFER a structure NODE of type TYPE in Ada syntax. If NESTED is
3067 true, it's an anonymous nested type. SPC is the indentation level. */
3070 dump_ada_structure (pretty_printer
*buffer
, tree node
, tree type
, bool nested
,
3073 const bool is_union
= (TREE_CODE (node
) == UNION_TYPE
);
3076 int field_spc
= spc
+ INDENT_INCR
;
3079 bitfield_used
= false;
3081 /* Print the contents of the structure. */
3082 pp_string (buffer
, "record");
3086 newline_and_indent (buffer
, spc
+ INDENT_INCR
);
3087 pp_string (buffer
, "case discr is");
3088 field_spc
= spc
+ INDENT_INCR
* 3;
3091 pp_newline (buffer
);
3093 /* Print the non-static fields of the structure. */
3094 for (tree tmp
= TYPE_FIELDS (node
); tmp
; tmp
= TREE_CHAIN (tmp
))
3096 /* Add parent field if needed. */
3097 if (!DECL_NAME (tmp
))
3099 if (!is_tagged_type (TREE_TYPE (tmp
)))
3101 if (!TYPE_NAME (TREE_TYPE (tmp
)))
3102 dump_ada_declaration (buffer
, tmp
, type
, field_spc
);
3108 pp_string (buffer
, "parent : aliased ");
3111 sprintf (buf
, "field_%d : aliased ", field_num
+ 1);
3112 pp_string (buffer
, buf
);
3114 dump_ada_decl_name (buffer
, TYPE_NAME (TREE_TYPE (tmp
)),
3116 pp_semicolon (buffer
);
3119 pp_newline (buffer
);
3123 else if (TREE_CODE (tmp
) == FIELD_DECL
)
3125 /* Skip internal virtual table field. */
3126 if (!DECL_VIRTUAL_P (tmp
))
3130 if (TREE_CHAIN (tmp
)
3131 && TREE_TYPE (TREE_CHAIN (tmp
)) != node
3132 && TREE_CODE (TREE_CHAIN (tmp
)) != TYPE_DECL
)
3133 sprintf (buf
, "when %d =>", field_num
);
3135 sprintf (buf
, "when others =>");
3137 INDENT (spc
+ INDENT_INCR
* 2);
3138 pp_string (buffer
, buf
);
3139 pp_newline (buffer
);
3142 if (dump_ada_declaration (buffer
, tmp
, type
, field_spc
))
3144 pp_newline (buffer
);
3153 INDENT (spc
+ INDENT_INCR
);
3154 pp_string (buffer
, "end case;");
3155 pp_newline (buffer
);
3160 INDENT (spc
+ INDENT_INCR
);
3161 pp_string (buffer
, "null;");
3162 pp_newline (buffer
);
3166 pp_string (buffer
, "end record");
3168 newline_and_indent (buffer
, spc
);
3170 /* We disregard the methods for anonymous nested types. */
3174 if (has_nontrivial_methods (node
))
3176 pp_string (buffer
, "with Import => True,");
3177 newline_and_indent (buffer
, spc
+ 5);
3178 pp_string (buffer
, "Convention => CPP");
3181 pp_string (buffer
, "with Convention => C_Pass_By_Copy");
3186 newline_and_indent (buffer
, spc
+ 5);
3187 pp_string (buffer
, "Unchecked_Union => True");
3193 newline_and_indent (buffer
, spc
+ 5);
3194 pp_string (buffer
, "Pack => True");
3195 bitfield_used
= false;
3198 need_semicolon
= !dump_ada_methods (buffer
, node
, spc
);
3200 /* Print the static fields of the structure, if any. */
3201 for (tree tmp
= TYPE_FIELDS (node
); tmp
; tmp
= TREE_CHAIN (tmp
))
3203 if (TREE_CODE (tmp
) == VAR_DECL
&& DECL_NAME (tmp
))
3207 need_semicolon
= false;
3208 pp_semicolon (buffer
);
3210 pp_newline (buffer
);
3211 pp_newline (buffer
);
3212 dump_ada_declaration (buffer
, tmp
, type
, spc
);
3217 /* Dump all the declarations in SOURCE_FILE to an Ada spec.
3218 COLLECT_ALL_REFS is a front-end callback used to collect all relevant
3219 nodes for SOURCE_FILE. CHECK is used to perform C++ queries on nodes. */
3222 dump_ads (const char *source_file
,
3223 void (*collect_all_refs
)(const char *),
3224 int (*check
)(tree
, cpp_operation
))
3231 pkg_name
= get_ada_package (source_file
);
3233 /* Construct the .ads filename and package name. */
3234 ads_name
= xstrdup (pkg_name
);
3236 for (s
= ads_name
; *s
; s
++)
3242 ads_name
= reconcat (ads_name
, ads_name
, ".ads", NULL
);
3244 /* Write out the .ads file. */
3245 f
= fopen (ads_name
, "w");
3250 pp_needs_newline (&pp
) = true;
3251 pp
.buffer
->stream
= f
;
3253 /* Dump all relevant macros. */
3254 dump_ada_macros (&pp
, source_file
);
3256 /* Reset the table of withs for this file. */
3259 (*collect_all_refs
) (source_file
);
3261 /* Dump all references. */
3263 dump_ada_nodes (&pp
, source_file
);
3265 /* We require Ada 2012 syntax, so generate corresponding pragma.
3266 Also, disable style checks since this file is auto-generated. */
3267 fprintf (f
, "pragma Ada_2012;\npragma Style_Checks (Off);\n\n");
3272 fprintf (f
, "\npackage %s is\n\n", pkg_name
);
3273 pp_write_text_to_stream (&pp
);
3274 /* ??? need to free pp */
3275 fprintf (f
, "end %s;\n", pkg_name
);
3283 static const char **source_refs
= NULL
;
3284 static int source_refs_used
= 0;
3285 static int source_refs_allocd
= 0;
3287 /* Add an entry for FILENAME to the table SOURCE_REFS. */
3290 collect_source_ref (const char *filename
)
3297 if (source_refs_allocd
== 0)
3299 source_refs_allocd
= 1024;
3300 source_refs
= XNEWVEC (const char *, source_refs_allocd
);
3303 for (i
= 0; i
< source_refs_used
; i
++)
3304 if (filename
== source_refs
[i
])
3307 if (source_refs_used
== source_refs_allocd
)
3309 source_refs_allocd
*= 2;
3310 source_refs
= XRESIZEVEC (const char *, source_refs
, source_refs_allocd
);
3313 source_refs
[source_refs_used
++] = filename
;
3316 /* Main entry point: dump all Ada specs corresponding to SOURCE_REFS
3317 using callbacks COLLECT_ALL_REFS and CHECK.
3318 COLLECT_ALL_REFS is a front-end callback used to collect all relevant
3319 nodes for a given source file.
3320 CHECK is used to perform C++ queries on nodes, or NULL for the C
3324 dump_ada_specs (void (*collect_all_refs
)(const char *),
3325 int (*check
)(tree
, cpp_operation
))
3327 /* Iterate over the list of files to dump specs for. */
3328 for (int i
= 0; i
< source_refs_used
; i
++)
3329 dump_ads (source_refs
[i
], collect_all_refs
, check
);
3331 /* Free various tables. */