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 "cpp-id-data.h"
31 #include "stringpool.h"
34 /* Local functions, macros and variables. */
35 static int dump_generic_ada_node (pretty_printer
*, tree
, tree
, int, bool,
37 static int dump_ada_declaration (pretty_printer
*, tree
, tree
, int);
38 static void dump_ada_struct_decl (pretty_printer
*, tree
, tree
, int, bool);
39 static char *to_ada_name (const char *, unsigned int, bool *);
41 #define INDENT(SPACE) \
42 do { int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
46 /* Global hook used to perform C++ queries on nodes. */
47 static int (*cpp_check
) (tree
, cpp_operation
) = NULL
;
49 /* Global variables used in macro-related callbacks. */
50 static int max_ada_macros
;
51 static int store_ada_macro_index
;
52 static const char *macro_source_file
;
54 /* Given a cpp MACRO, compute the max length BUFFER_LEN of the macro, as well
55 as max length PARAM_LEN of arguments for fun_like macros, and also set
56 SUPPORTED to 0 if the macro cannot be mapped to an Ada construct. */
59 macro_length (const cpp_macro
*macro
, int *supported
, int *buffer_len
,
72 for (i
= 0; i
< macro
->paramc
; i
++)
74 cpp_hashnode
*param
= macro
->params
[i
];
76 *param_len
+= NODE_LEN (param
);
78 if (i
+ 1 < macro
->paramc
)
80 *param_len
+= 2; /* ", " */
82 else if (macro
->variadic
)
88 *param_len
+= 2; /* ")\0" */
91 for (j
= 0; j
< macro
->count
; j
++)
93 cpp_token
*token
= ¯o
->exp
.tokens
[j
];
95 if (token
->flags
& PREV_WHITE
)
98 if (token
->flags
& STRINGIFY_ARG
|| token
->flags
& PASTE_LEFT
)
104 if (token
->type
== CPP_MACRO_ARG
)
106 NODE_LEN (macro
->params
[token
->val
.macro_arg
.arg_no
- 1]);
108 /* Include enough extra space to handle e.g. special characters. */
109 *buffer_len
+= (cpp_token_len (token
) + 1) * 8;
115 /* Dump all digits/hex chars from NUMBER to BUFFER and return a pointer
116 to the character after the last character written. If FLOAT_P is true,
117 this is a floating-point number. */
119 static unsigned char *
120 dump_number (unsigned char *number
, unsigned char *buffer
, bool float_p
)
122 while (*number
!= '\0'
123 && *number
!= (float_p
? 'F' : 'U')
124 && *number
!= (float_p
? 'f' : 'u')
127 *buffer
++ = *number
++;
132 /* Handle escape character C and convert to an Ada character into BUFFER.
133 Return a pointer to the character after the last character written, or
134 NULL if the escape character is not supported. */
136 static unsigned char *
137 handle_escape_character (unsigned char *buffer
, char c
)
147 strcpy ((char *) buffer
, "\" & ASCII.LF & \"");
152 strcpy ((char *) buffer
, "\" & ASCII.CR & \"");
157 strcpy ((char *) buffer
, "\" & ASCII.HT & \"");
168 /* Callback used to count the number of macros from cpp_forall_identifiers.
169 PFILE and V are not used. NODE is the current macro to consider. */
172 count_ada_macro (cpp_reader
*pfile ATTRIBUTE_UNUSED
, cpp_hashnode
*node
,
173 void *v ATTRIBUTE_UNUSED
)
175 const cpp_macro
*macro
= node
->value
.macro
;
177 if (node
->type
== NT_MACRO
&& !(node
->flags
& NODE_BUILTIN
)
179 && *NODE_NAME (node
) != '_'
180 && LOCATION_FILE (macro
->line
) == macro_source_file
)
186 /* Callback used to store relevant macros from cpp_forall_identifiers.
187 PFILE is not used. NODE is the current macro to store if relevant.
188 MACROS is an array of cpp_hashnode* used to store NODE. */
191 store_ada_macro (cpp_reader
*pfile ATTRIBUTE_UNUSED
,
192 cpp_hashnode
*node
, void *macros
)
194 const cpp_macro
*macro
= node
->value
.macro
;
196 if (node
->type
== NT_MACRO
197 && !(node
->flags
& NODE_BUILTIN
)
199 && *NODE_NAME (node
) != '_'
200 && LOCATION_FILE (macro
->line
) == macro_source_file
)
201 ((cpp_hashnode
**) macros
)[store_ada_macro_index
++] = node
;
206 /* Callback used to compare (during qsort) macros. NODE1 and NODE2 are the
207 two macro nodes to compare. */
210 compare_macro (const void *node1
, const void *node2
)
212 typedef const cpp_hashnode
*const_hnode
;
214 const_hnode n1
= *(const const_hnode
*) node1
;
215 const_hnode n2
= *(const const_hnode
*) node2
;
217 return n1
->value
.macro
->line
- n2
->value
.macro
->line
;
220 /* Dump in PP all relevant macros appearing in FILE. */
223 dump_ada_macros (pretty_printer
*pp
, const char* file
)
225 int num_macros
= 0, prev_line
= -1;
226 cpp_hashnode
**macros
;
228 /* Initialize file-scope variables. */
230 store_ada_macro_index
= 0;
231 macro_source_file
= file
;
233 /* Count all potentially relevant macros, and then sort them by sloc. */
234 cpp_forall_identifiers (parse_in
, count_ada_macro
, NULL
);
235 macros
= XALLOCAVEC (cpp_hashnode
*, max_ada_macros
);
236 cpp_forall_identifiers (parse_in
, store_ada_macro
, macros
);
237 qsort (macros
, max_ada_macros
, sizeof (cpp_hashnode
*), compare_macro
);
239 for (int j
= 0; j
< max_ada_macros
; j
++)
241 cpp_hashnode
*node
= macros
[j
];
242 const cpp_macro
*macro
= node
->value
.macro
;
244 int supported
= 1, prev_is_one
= 0, buffer_len
, param_len
;
245 int is_string
= 0, is_char
= 0;
247 unsigned char *s
, *params
, *buffer
, *buf_param
, *char_one
= NULL
, *tmp
;
249 macro_length (macro
, &supported
, &buffer_len
, ¶m_len
);
250 s
= buffer
= XALLOCAVEC (unsigned char, buffer_len
);
251 params
= buf_param
= XALLOCAVEC (unsigned char, param_len
);
258 for (i
= 0; i
< macro
->paramc
; i
++)
260 cpp_hashnode
*param
= macro
->params
[i
];
262 memcpy (buf_param
, NODE_NAME (param
), NODE_LEN (param
));
263 buf_param
+= NODE_LEN (param
);
265 if (i
+ 1 < macro
->paramc
)
270 else if (macro
->variadic
)
280 for (i
= 0; supported
&& i
< macro
->count
; i
++)
282 cpp_token
*token
= ¯o
->exp
.tokens
[i
];
285 if (token
->flags
& PREV_WHITE
)
288 if (token
->flags
& STRINGIFY_ARG
|| token
->flags
& PASTE_LEFT
)
298 cpp_hashnode
*param
=
299 macro
->params
[token
->val
.macro_arg
.arg_no
- 1];
300 memcpy (buffer
, NODE_NAME (param
), NODE_LEN (param
));
301 buffer
+= NODE_LEN (param
);
305 case CPP_EQ_EQ
: *buffer
++ = '='; break;
306 case CPP_GREATER
: *buffer
++ = '>'; break;
307 case CPP_LESS
: *buffer
++ = '<'; break;
308 case CPP_PLUS
: *buffer
++ = '+'; break;
309 case CPP_MINUS
: *buffer
++ = '-'; break;
310 case CPP_MULT
: *buffer
++ = '*'; break;
311 case CPP_DIV
: *buffer
++ = '/'; break;
312 case CPP_COMMA
: *buffer
++ = ','; break;
313 case CPP_OPEN_SQUARE
:
314 case CPP_OPEN_PAREN
: *buffer
++ = '('; break;
315 case CPP_CLOSE_SQUARE
: /* fallthrough */
316 case CPP_CLOSE_PAREN
: *buffer
++ = ')'; break;
317 case CPP_DEREF
: /* fallthrough */
318 case CPP_SCOPE
: /* fallthrough */
319 case CPP_DOT
: *buffer
++ = '.'; break;
321 case CPP_EQ
: *buffer
++ = ':'; *buffer
++ = '='; break;
322 case CPP_NOT_EQ
: *buffer
++ = '/'; *buffer
++ = '='; break;
323 case CPP_GREATER_EQ
: *buffer
++ = '>'; *buffer
++ = '='; break;
324 case CPP_LESS_EQ
: *buffer
++ = '<'; *buffer
++ = '='; break;
327 *buffer
++ = 'n'; *buffer
++ = 'o'; *buffer
++ = 't'; break;
329 *buffer
++ = 'm'; *buffer
++ = 'o'; *buffer
++ = 'd'; break;
331 *buffer
++ = 'a'; *buffer
++ = 'n'; *buffer
++ = 'd'; break;
333 *buffer
++ = 'o'; *buffer
++ = 'r'; break;
335 *buffer
++ = 'x'; *buffer
++ = 'o'; *buffer
++ = 'r'; break;
337 strcpy ((char *) buffer
, " and then ");
341 strcpy ((char *) buffer
, " or else ");
347 is_one
= prev_is_one
;
362 if (!macro
->fun_like
)
366 = cpp_spell_token (parse_in
, token
, buffer
, false);
378 const unsigned char *s
= token
->val
.str
.text
;
384 buffer
= handle_escape_character (buffer
, *s
);
403 c
= cpp_interpret_charconst (parse_in
, token
,
404 &chars_seen
, &ignored
);
405 if (c
>= 32 && c
<= 126)
408 *buffer
++ = (char) c
;
414 ((char *) buffer
, "Character'Val (%d)", (int) c
);
415 buffer
+= chars_seen
;
421 tmp
= cpp_token_as_text (parse_in
, token
);
441 buffer
= dump_number (tmp
+ 2, buffer
, false);
449 buffer
= dump_number (tmp
+ 2, buffer
, false);
454 /* Dump floating-point constant unmodified. */
455 if (strchr ((const char *)tmp
, '.'))
456 buffer
= dump_number (tmp
, buffer
, true);
462 = dump_number (tmp
+ 1, buffer
, false);
485 = dump_number (tmp
, buffer
,
486 strchr ((const char *)tmp
, '.'));
494 /* Replace "1 << N" by "2 ** N" */
521 case CPP_CLOSE_BRACE
:
525 case CPP_MINUS_MINUS
:
529 case CPP_HEADER_NAME
:
532 case CPP_OBJC_STRING
:
534 if (!macro
->fun_like
)
537 buffer
= cpp_spell_token (parse_in
, token
, buffer
, false);
541 prev_is_one
= is_one
;
548 if (macro
->fun_like
&& supported
)
550 char *start
= (char *) s
;
553 pp_string (pp
, " -- arg-macro: ");
555 if (*start
== '(' && buffer
[-1] == ')')
560 pp_string (pp
, "function ");
564 pp_string (pp
, "procedure ");
567 pp_string (pp
, (const char *) NODE_NAME (node
));
569 pp_string (pp
, (char *) params
);
571 pp_string (pp
, " -- ");
575 pp_string (pp
, "return ");
576 pp_string (pp
, start
);
580 pp_string (pp
, start
);
586 expanded_location sloc
= expand_location (macro
->line
);
588 if (sloc
.line
!= prev_line
+ 1 && prev_line
> 0)
592 prev_line
= sloc
.line
;
595 ada_name
= to_ada_name ((const char *) NODE_NAME (node
), 0, NULL
);
596 pp_string (pp
, ada_name
);
598 pp_string (pp
, " : ");
601 pp_string (pp
, "aliased constant String");
603 pp_string (pp
, "aliased constant Character");
605 pp_string (pp
, "constant");
607 pp_string (pp
, " := ");
608 pp_string (pp
, (char *) s
);
611 pp_string (pp
, " & ASCII.NUL");
613 pp_string (pp
, "; -- ");
614 pp_string (pp
, sloc
.file
);
616 pp_scalar (pp
, "%d", sloc
.line
);
621 pp_string (pp
, " -- unsupported macro: ");
622 pp_string (pp
, (const char *) cpp_macro_definition (parse_in
, node
));
631 /* Current source file being handled. */
632 static const char *current_source_file
;
634 /* Return sloc of DECL, using sloc of last field if LAST is true. */
637 decl_sloc (const_tree decl
, bool last
)
641 /* Compare the declaration of struct-like types based on the sloc of their
642 last field (if LAST is true), so that more nested types collate before
644 if (TREE_CODE (decl
) == TYPE_DECL
645 && !DECL_ORIGINAL_TYPE (decl
)
646 && RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl
))
647 && (field
= TYPE_FIELDS (TREE_TYPE (decl
))))
650 while (DECL_CHAIN (field
))
651 field
= DECL_CHAIN (field
);
652 return DECL_SOURCE_LOCATION (field
);
655 return DECL_SOURCE_LOCATION (decl
);
658 /* Compare two locations LHS and RHS. */
661 compare_location (location_t lhs
, location_t rhs
)
663 expanded_location xlhs
= expand_location (lhs
);
664 expanded_location xrhs
= expand_location (rhs
);
666 if (xlhs
.file
!= xrhs
.file
)
667 return filename_cmp (xlhs
.file
, xrhs
.file
);
669 if (xlhs
.line
!= xrhs
.line
)
670 return xlhs
.line
- xrhs
.line
;
672 if (xlhs
.column
!= xrhs
.column
)
673 return xlhs
.column
- xrhs
.column
;
678 /* Compare two declarations (LP and RP) by their source location. */
681 compare_node (const void *lp
, const void *rp
)
683 const_tree lhs
= *((const tree
*) lp
);
684 const_tree rhs
= *((const tree
*) rp
);
686 return compare_location (decl_sloc (lhs
, true), decl_sloc (rhs
, true));
689 /* Compare two comments (LP and RP) by their source location. */
692 compare_comment (const void *lp
, const void *rp
)
694 const cpp_comment
*lhs
= (const cpp_comment
*) lp
;
695 const cpp_comment
*rhs
= (const cpp_comment
*) rp
;
697 return compare_location (lhs
->sloc
, rhs
->sloc
);
700 static tree
*to_dump
= NULL
;
701 static int to_dump_count
= 0;
703 /* Collect a list of declarations from T relevant to SOURCE_FILE to be dumped
704 by a subsequent call to dump_ada_nodes. */
707 collect_ada_nodes (tree t
, const char *source_file
)
710 int i
= to_dump_count
;
712 /* Count the likely relevant nodes: do not dump builtins (they are irrelevant
713 in the context of bindings) and namespaces (we do not handle them properly
715 for (n
= t
; n
; n
= TREE_CHAIN (n
))
716 if (!DECL_IS_BUILTIN (n
)
717 && TREE_CODE (n
) != NAMESPACE_DECL
718 && LOCATION_FILE (decl_sloc (n
, false)) == source_file
)
721 /* Allocate sufficient storage for all nodes. */
722 to_dump
= XRESIZEVEC (tree
, to_dump
, to_dump_count
);
724 /* Store the relevant nodes. */
725 for (n
= t
; n
; n
= TREE_CHAIN (n
))
726 if (!DECL_IS_BUILTIN (n
)
727 && TREE_CODE (n
) != NAMESPACE_DECL
728 && LOCATION_FILE (decl_sloc (n
, false)) == source_file
)
732 /* Call back for walk_tree to clear the TREE_VISITED flag of TP. */
735 unmark_visited_r (tree
*tp
, int *walk_subtrees ATTRIBUTE_UNUSED
,
736 void *data ATTRIBUTE_UNUSED
)
738 if (TREE_VISITED (*tp
))
739 TREE_VISITED (*tp
) = 0;
746 /* Print a COMMENT to the output stream PP. */
749 print_comment (pretty_printer
*pp
, const char *comment
)
751 int len
= strlen (comment
);
752 char *str
= XALLOCAVEC (char, len
+ 1);
754 bool extra_newline
= false;
756 memcpy (str
, comment
, len
+ 1);
758 /* Trim C/C++ comment indicators. */
759 if (str
[len
- 2] == '*' && str
[len
- 1] == '/')
766 tok
= strtok (str
, "\n");
768 pp_string (pp
, " --");
771 tok
= strtok (NULL
, "\n");
773 /* Leave a blank line after multi-line comments. */
775 extra_newline
= true;
782 /* Dump nodes into PP relevant to SOURCE_FILE, as collected by previous calls
783 to collect_ada_nodes. */
786 dump_ada_nodes (pretty_printer
*pp
, const char *source_file
)
789 cpp_comment_table
*comments
;
791 /* Sort the table of declarations to dump by sloc. */
792 qsort (to_dump
, to_dump_count
, sizeof (tree
), compare_node
);
794 /* Fetch the table of comments. */
795 comments
= cpp_get_comments (parse_in
);
797 /* Sort the comments table by sloc. */
798 if (comments
->count
> 1)
799 qsort (comments
->entries
, comments
->count
, sizeof (cpp_comment
),
802 /* Interleave comments and declarations in line number order. */
806 /* Advance j until comment j is in this file. */
807 while (j
!= comments
->count
808 && LOCATION_FILE (comments
->entries
[j
].sloc
) != source_file
)
811 /* Advance j until comment j is not a duplicate. */
812 while (j
< comments
->count
- 1
813 && !compare_comment (&comments
->entries
[j
],
814 &comments
->entries
[j
+ 1]))
817 /* Write decls until decl i collates after comment j. */
818 while (i
!= to_dump_count
)
820 if (j
== comments
->count
821 || LOCATION_LINE (decl_sloc (to_dump
[i
], false))
822 < LOCATION_LINE (comments
->entries
[j
].sloc
))
824 current_source_file
= source_file
;
826 if (dump_ada_declaration (pp
, to_dump
[i
++], NULL_TREE
,
837 /* Write comment j, if there is one. */
838 if (j
!= comments
->count
)
839 print_comment (pp
, comments
->entries
[j
++].comment
);
841 } while (i
!= to_dump_count
|| j
!= comments
->count
);
843 /* Clear the TREE_VISITED flag over each subtree we've dumped. */
844 for (i
= 0; i
< to_dump_count
; i
++)
845 walk_tree (&to_dump
[i
], unmark_visited_r
, NULL
, NULL
);
847 /* Finalize the to_dump table. */
856 /* Dump a newline and indent BUFFER by SPC chars. */
859 newline_and_indent (pretty_printer
*buffer
, int spc
)
865 struct with
{ char *s
; const char *in_file
; bool limited
; };
866 static struct with
*withs
= NULL
;
867 static int withs_max
= 4096;
868 static int with_len
= 0;
870 /* Record a "with" clause on package S (a limited with if LIMITED_ACCESS is
871 true), if not already done. */
874 append_withs (const char *s
, bool limited_access
)
879 withs
= XNEWVEC (struct with
, withs_max
);
881 if (with_len
== withs_max
)
884 withs
= XRESIZEVEC (struct with
, withs
, withs_max
);
887 for (i
= 0; i
< with_len
; i
++)
888 if (!strcmp (s
, withs
[i
].s
)
889 && current_source_file
== withs
[i
].in_file
)
891 withs
[i
].limited
&= limited_access
;
895 withs
[with_len
].s
= xstrdup (s
);
896 withs
[with_len
].in_file
= current_source_file
;
897 withs
[with_len
].limited
= limited_access
;
901 /* Reset "with" clauses. */
904 reset_ada_withs (void)
911 for (i
= 0; i
< with_len
; i
++)
919 /* Dump "with" clauses in F. */
922 dump_ada_withs (FILE *f
)
926 fprintf (f
, "with Interfaces.C; use Interfaces.C;\n");
928 for (i
= 0; i
< with_len
; i
++)
930 (f
, "%swith %s;\n", withs
[i
].limited
? "limited " : "", withs
[i
].s
);
933 /* Return suitable Ada package name from FILE. */
936 get_ada_package (const char *file
)
944 s
= strstr (file
, "/include/");
948 base
= lbasename (file
);
950 if (ada_specs_parent
== NULL
)
953 plen
= strlen (ada_specs_parent
) + 1;
955 res
= XNEWVEC (char, plen
+ strlen (base
) + 1);
956 if (ada_specs_parent
!= NULL
) {
957 strcpy (res
, ada_specs_parent
);
961 for (i
= plen
; *base
; base
++, i
++)
973 res
[i
] = (i
== 0 || res
[i
- 1] == '.' || res
[i
- 1] == '_') ? 'u' : '_';
985 static const char *ada_reserved
[] = {
986 "abort", "abs", "abstract", "accept", "access", "aliased", "all", "and",
987 "array", "at", "begin", "body", "case", "constant", "declare", "delay",
988 "delta", "digits", "do", "else", "elsif", "end", "entry", "exception",
989 "exit", "for", "function", "generic", "goto", "if", "in", "interface", "is",
990 "limited", "loop", "mod", "new", "not", "null", "others", "out", "of", "or",
991 "overriding", "package", "pragma", "private", "procedure", "protected",
992 "raise", "range", "record", "rem", "renames", "requeue", "return", "reverse",
993 "select", "separate", "subtype", "synchronized", "tagged", "task",
994 "terminate", "then", "type", "until", "use", "when", "while", "with", "xor",
997 /* ??? would be nice to specify this list via a config file, so that users
998 can create their own dictionary of conflicts. */
999 static const char *c_duplicates
[] = {
1000 /* system will cause troubles with System.Address. */
1003 /* The following values have other definitions with same name/other
1009 "rl_readline_version",
1015 /* Return a declaration tree corresponding to TYPE. */
1018 get_underlying_decl (tree type
)
1023 /* type is a declaration. */
1027 /* type is a typedef. */
1028 if (TYPE_P (type
) && TYPE_NAME (type
) && DECL_P (TYPE_NAME (type
)))
1029 return TYPE_NAME (type
);
1031 /* TYPE_STUB_DECL has been set for type. */
1032 if (TYPE_P (type
) && TYPE_STUB_DECL (type
))
1033 return TYPE_STUB_DECL (type
);
1038 /* Return whether TYPE has static fields. */
1041 has_static_fields (const_tree type
)
1043 if (!type
|| !RECORD_OR_UNION_TYPE_P (type
))
1046 for (tree fld
= TYPE_FIELDS (type
); fld
; fld
= TREE_CHAIN (fld
))
1047 if (TREE_CODE (fld
) == VAR_DECL
&& DECL_NAME (fld
))
1053 /* Return whether TYPE corresponds to an Ada tagged type (has a dispatch
1057 is_tagged_type (const_tree type
)
1059 if (!type
|| !RECORD_OR_UNION_TYPE_P (type
))
1062 for (tree fld
= TYPE_FIELDS (type
); fld
; fld
= TREE_CHAIN (fld
))
1063 if (TREE_CODE (fld
) == FUNCTION_DECL
&& DECL_VINDEX (fld
))
1069 /* Return whether TYPE has non-trivial methods, i.e. methods that do something
1070 for the objects of TYPE. In C++, all classes have implicit special methods,
1071 e.g. constructors and destructors, but they can be trivial if the type is
1072 sufficiently simple. */
1075 has_nontrivial_methods (tree type
)
1077 if (!type
|| !RECORD_OR_UNION_TYPE_P (type
))
1080 /* Only C++ types can have methods. */
1084 /* A non-trivial type has non-trivial special methods. */
1085 if (!cpp_check (type
, IS_TRIVIAL
))
1088 /* If there are user-defined methods, they are deemed non-trivial. */
1089 for (tree fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
1090 if (TREE_CODE (fld
) == FUNCTION_DECL
&& !DECL_ARTIFICIAL (fld
))
1096 #define INDEX_LENGTH 8
1098 /* Generate a legal Ada name from a C/C++ NAME and return a malloc'ed string.
1099 INDEX, if non-zero, is used to disambiguate overloaded names. SPACE_FOUND,
1100 if not NULL, is used to indicate whether a space was found in NAME. */
1103 to_ada_name (const char *name
, unsigned int index
, bool *space_found
)
1106 const int len
= strlen (name
);
1109 char *s
= XNEWVEC (char, len
* 2 + 5 + (index
? INDEX_LENGTH
: 0));
1113 *space_found
= false;
1115 /* Add "c_" prefix if name is an Ada reserved word. */
1116 for (names
= ada_reserved
; *names
; names
++)
1117 if (!strcasecmp (name
, *names
))
1126 /* Add "c_" prefix if name is a potential case sensitive duplicate. */
1127 for (names
= c_duplicates
; *names
; names
++)
1128 if (!strcmp (name
, *names
))
1136 for (j
= 0; name
[j
] == '_'; j
++)
1141 else if (*name
== '.' || *name
== '$')
1151 /* Replace unsuitable characters for Ada identifiers. */
1152 for (; j
< len
; j
++)
1157 *space_found
= true;
1161 /* ??? missing some C++ operators. */
1165 if (name
[j
+ 1] == '=')
1180 if (name
[j
+ 1] == '=')
1198 s
[len2
++] = name
[j
] == '&' ? 'a' : name
[j
] == '|' ? 'o' : 'x';
1200 if (name
[j
+ 1] == '=')
1213 if (s
[len2
- 1] != '_')
1216 switch (name
[j
+ 1]) {
1219 switch (name
[j
- 1]) {
1220 case '+': s
[len2
++] = 'p'; break; /* + */
1221 case '-': s
[len2
++] = 'm'; break; /* - */
1222 case '*': s
[len2
++] = 't'; break; /* * */
1223 case '/': s
[len2
++] = 'd'; break; /* / */
1229 switch (name
[j
- 1]) {
1230 case '+': s
[len2
++] = 'p'; break; /* += */
1231 case '-': s
[len2
++] = 'm'; break; /* -= */
1232 case '*': s
[len2
++] = 't'; break; /* *= */
1233 case '/': s
[len2
++] = 'd'; break; /* /= */
1267 c
= name
[j
] == '<' ? 'l' : 'g';
1270 switch (name
[j
+ 1]) {
1296 if (len2
&& s
[len2
- 1] == '_')
1301 s
[len2
++] = name
[j
];
1304 if (s
[len2
- 1] == '_')
1308 snprintf (&s
[len2
], INDEX_LENGTH
, "_u_%d", index
+ 1);
1315 /* Return true if DECL refers to a C++ class type for which a
1316 separate enclosing package has been or should be generated. */
1319 separate_class_package (tree decl
)
1321 tree type
= TREE_TYPE (decl
);
1322 return has_nontrivial_methods (type
) || has_static_fields (type
);
1325 static bool package_prefix
= true;
1327 /* Dump in BUFFER the name of an identifier NODE of type TYPE, following Ada
1328 syntax. INDEX, if non-zero, is used to disambiguate overloaded names.
1329 LIMITED_ACCESS indicates whether NODE can be accessed via a limited
1330 'with' clause rather than a regular 'with' clause. */
1333 pp_ada_tree_identifier (pretty_printer
*buffer
, tree node
, tree type
,
1334 unsigned int index
, bool limited_access
)
1336 const char *name
= IDENTIFIER_POINTER (node
);
1337 bool space_found
= false;
1338 char *s
= to_ada_name (name
, index
, &space_found
);
1339 tree decl
= get_underlying_decl (type
);
1341 /* If the entity comes from another file, generate a package prefix. */
1344 expanded_location xloc
= expand_location (decl_sloc (decl
, false));
1346 if (xloc
.file
&& xloc
.line
)
1348 if (xloc
.file
!= current_source_file
)
1350 switch (TREE_CODE (type
))
1355 case FIXED_POINT_TYPE
:
1357 case REFERENCE_TYPE
:
1365 char *s1
= get_ada_package (xloc
.file
);
1366 append_withs (s1
, limited_access
);
1367 pp_string (buffer
, s1
);
1376 /* Generate the additional package prefix for C++ classes. */
1377 if (separate_class_package (decl
))
1379 pp_string (buffer
, "Class_");
1380 pp_string (buffer
, s
);
1388 if (!strcmp (s
, "short_int"))
1389 pp_string (buffer
, "short");
1390 else if (!strcmp (s
, "short_unsigned_int"))
1391 pp_string (buffer
, "unsigned_short");
1392 else if (!strcmp (s
, "unsigned_int"))
1393 pp_string (buffer
, "unsigned");
1394 else if (!strcmp (s
, "long_int"))
1395 pp_string (buffer
, "long");
1396 else if (!strcmp (s
, "long_unsigned_int"))
1397 pp_string (buffer
, "unsigned_long");
1398 else if (!strcmp (s
, "long_long_int"))
1399 pp_string (buffer
, "Long_Long_Integer");
1400 else if (!strcmp (s
, "long_long_unsigned_int"))
1404 append_withs ("Interfaces.C.Extensions", false);
1405 pp_string (buffer
, "Extensions.unsigned_long_long");
1408 pp_string (buffer
, "unsigned_long_long");
1411 pp_string(buffer
, s
);
1413 if (!strcmp (s
, "bool"))
1417 append_withs ("Interfaces.C.Extensions", false);
1418 pp_string (buffer
, "Extensions.bool");
1421 pp_string (buffer
, "bool");
1424 pp_string(buffer
, s
);
1429 /* Dump in BUFFER the assembly name of T. */
1432 pp_asm_name (pretty_printer
*buffer
, tree t
)
1434 tree name
= DECL_ASSEMBLER_NAME (t
);
1435 char *ada_name
= XALLOCAVEC (char, IDENTIFIER_LENGTH (name
) + 1), *s
;
1436 const char *ident
= IDENTIFIER_POINTER (name
);
1438 for (s
= ada_name
; *ident
; ident
++)
1442 else if (*ident
!= '*')
1447 pp_string (buffer
, ada_name
);
1450 /* Hash table of overloaded names associating identifier nodes with DECL_UIDs.
1451 It is needed in Ada 2005 because we can have at most one import directive
1452 per subprogram name in a given scope, so we have to mangle the subprogram
1453 names on the Ada side to import overloaded subprograms from C++. */
1455 struct overloaded_name_hash
{
1459 vec
<unsigned int> homonyms
;
1462 struct overloaded_name_hasher
: delete_ptr_hash
<overloaded_name_hash
>
1464 static inline hashval_t
hash (overloaded_name_hash
*t
)
1466 static inline bool equal (overloaded_name_hash
*a
, overloaded_name_hash
*b
)
1467 { return a
->name
== b
->name
&& a
->context
== b
->context
; }
1470 static hash_table
<overloaded_name_hasher
> *overloaded_names
;
1472 /* Compute the overloading index of function DECL in its context. */
1475 compute_overloading_index (tree decl
)
1477 const hashval_t hashcode
1478 = iterative_hash_hashval_t (htab_hash_pointer (DECL_NAME (decl
)),
1479 htab_hash_pointer (DECL_CONTEXT (decl
)));
1480 struct overloaded_name_hash in
, *h
, **slot
;
1481 unsigned int index
, *iter
;
1483 if (!overloaded_names
)
1484 overloaded_names
= new hash_table
<overloaded_name_hasher
> (512);
1486 /* Look up the list of homonyms in the table. */
1488 in
.name
= DECL_NAME (decl
);
1489 in
.context
= DECL_CONTEXT (decl
);
1490 slot
= overloaded_names
->find_slot_with_hash (&in
, hashcode
, INSERT
);
1495 h
= new overloaded_name_hash
;
1497 h
->name
= DECL_NAME (decl
);
1498 h
->context
= DECL_CONTEXT (decl
);
1499 h
->homonyms
.create (0);
1503 /* Look up the function in the list of homonyms. */
1504 FOR_EACH_VEC_ELT (h
->homonyms
, index
, iter
)
1505 if (*iter
== DECL_UID (decl
))
1508 /* If it is not present, push it onto the list. */
1510 h
->homonyms
.safe_push (DECL_UID (decl
));
1515 /* Dump in BUFFER the name of a DECL node if set, following Ada syntax.
1516 LIMITED_ACCESS indicates whether NODE can be accessed via a limited
1517 'with' clause rather than a regular 'with' clause. */
1520 dump_ada_decl_name (pretty_printer
*buffer
, tree decl
, bool limited_access
)
1522 if (DECL_NAME (decl
))
1524 const unsigned int index
1525 = (TREE_CODE (decl
) == FUNCTION_DECL
&& cpp_check
)
1526 ? compute_overloading_index (decl
) : 0;
1527 pp_ada_tree_identifier (buffer
, DECL_NAME (decl
), decl
, index
,
1532 tree type_name
= TYPE_NAME (TREE_TYPE (decl
));
1536 pp_string (buffer
, "anon");
1537 if (TREE_CODE (decl
) == FIELD_DECL
)
1538 pp_scalar (buffer
, "%d", DECL_UID (decl
));
1540 pp_scalar (buffer
, "%d", TYPE_UID (TREE_TYPE (decl
)));
1542 else if (TREE_CODE (type_name
) == IDENTIFIER_NODE
)
1543 pp_ada_tree_identifier (buffer
, type_name
, decl
, 0, limited_access
);
1547 /* Dump in BUFFER a name based on both T1 and T2 followed by a suffix. */
1550 dump_ada_double_name (pretty_printer
*buffer
, tree t1
, tree t2
)
1553 pp_ada_tree_identifier (buffer
, DECL_NAME (t1
), t1
, 0, false);
1556 pp_string (buffer
, "anon");
1557 pp_scalar (buffer
, "%d", TYPE_UID (TREE_TYPE (t1
)));
1560 pp_underscore (buffer
);
1563 pp_ada_tree_identifier (buffer
, DECL_NAME (t2
), t2
, 0, false);
1566 pp_string (buffer
, "anon");
1567 pp_scalar (buffer
, "%d", TYPE_UID (TREE_TYPE (t2
)));
1570 switch (TREE_CODE (TREE_TYPE (t2
)))
1573 pp_string (buffer
, "_array");
1576 pp_string (buffer
, "_struct");
1579 pp_string (buffer
, "_union");
1582 pp_string (buffer
, "_unknown");
1587 /* Dump in BUFFER pragma Import C/CPP on a given node T. */
1590 dump_ada_import (pretty_printer
*buffer
, tree t
)
1592 const char *name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t
));
1593 int is_stdcall
= TREE_CODE (t
) == FUNCTION_DECL
&&
1594 lookup_attribute ("stdcall", TYPE_ATTRIBUTES (TREE_TYPE (t
)));
1597 pp_string (buffer
, "pragma Import (Stdcall, ");
1598 else if (name
[0] == '_' && name
[1] == 'Z')
1599 pp_string (buffer
, "pragma Import (CPP, ");
1601 pp_string (buffer
, "pragma Import (C, ");
1603 dump_ada_decl_name (buffer
, t
, false);
1604 pp_string (buffer
, ", \"");
1607 pp_string (buffer
, IDENTIFIER_POINTER (DECL_NAME (t
)));
1609 pp_asm_name (buffer
, t
);
1611 pp_string (buffer
, "\");");
1614 /* Check whether T and its type have different names, and append "the_"
1615 otherwise in BUFFER. */
1618 check_name (pretty_printer
*buffer
, tree t
)
1621 tree tmp
= TREE_TYPE (t
);
1623 while (TREE_CODE (tmp
) == POINTER_TYPE
&& !TYPE_NAME (tmp
))
1624 tmp
= TREE_TYPE (tmp
);
1626 if (TREE_CODE (tmp
) != FUNCTION_TYPE
)
1628 if (TREE_CODE (tmp
) == IDENTIFIER_NODE
)
1629 s
= IDENTIFIER_POINTER (tmp
);
1630 else if (!TYPE_NAME (tmp
))
1632 else if (TREE_CODE (TYPE_NAME (tmp
)) == IDENTIFIER_NODE
)
1633 s
= IDENTIFIER_POINTER (TYPE_NAME (tmp
));
1635 s
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (tmp
)));
1637 if (!strcasecmp (IDENTIFIER_POINTER (DECL_NAME (t
)), s
))
1638 pp_string (buffer
, "the_");
1642 /* Dump in BUFFER a function declaration FUNC with Ada syntax.
1643 IS_METHOD indicates whether FUNC is a C++ method.
1644 IS_CONSTRUCTOR whether FUNC is a C++ constructor.
1645 IS_DESTRUCTOR whether FUNC is a C++ destructor.
1646 SPC is the current indentation level. */
1649 dump_ada_function_declaration (pretty_printer
*buffer
, tree func
,
1650 bool is_method
, bool is_constructor
,
1651 bool is_destructor
, int spc
)
1654 const tree node
= TREE_TYPE (func
);
1656 int num
= 0, num_args
= 0, have_args
= true, have_ellipsis
= false;
1658 /* Compute number of arguments. */
1659 arg
= TYPE_ARG_TYPES (node
);
1663 while (TREE_CHAIN (arg
) && arg
!= error_mark_node
)
1666 arg
= TREE_CHAIN (arg
);
1669 if (TREE_CODE (TREE_VALUE (arg
)) != VOID_TYPE
)
1672 have_ellipsis
= true;
1683 newline_and_indent (buffer
, spc
+ 1);
1688 pp_left_paren (buffer
);
1691 if (TREE_CODE (func
) == FUNCTION_DECL
)
1692 arg
= DECL_ARGUMENTS (func
);
1696 if (arg
== NULL_TREE
)
1699 arg
= TYPE_ARG_TYPES (node
);
1701 if (arg
&& TREE_CODE (TREE_VALUE (arg
)) == VOID_TYPE
)
1706 arg
= TREE_CHAIN (arg
);
1708 /* Print the argument names (if available) & types. */
1710 for (num
= 1; num
<= num_args
; num
++)
1714 if (DECL_NAME (arg
))
1716 check_name (buffer
, arg
);
1717 pp_ada_tree_identifier (buffer
, DECL_NAME (arg
), NULL_TREE
, 0,
1719 pp_string (buffer
, " : ");
1723 sprintf (buf
, "arg%d : ", num
);
1724 pp_string (buffer
, buf
);
1727 dump_generic_ada_node (buffer
, TREE_TYPE (arg
), node
, spc
, 0, true);
1731 sprintf (buf
, "arg%d : ", num
);
1732 pp_string (buffer
, buf
);
1733 dump_generic_ada_node (buffer
, TREE_VALUE (arg
), node
, spc
, 0, true);
1736 /* If the type is a pointer to a tagged type, we need to differentiate
1737 virtual methods from the rest (non-virtual methods, static member
1738 or regular functions) and import only them as primitive operations,
1739 because they make up the virtual table which is mirrored on the Ada
1740 side by the dispatch table. So we add 'Class to the type of every
1741 parameter that is not the first one of a method which either has a
1742 slot in the virtual table or is a constructor. */
1744 && POINTER_TYPE_P (TREE_TYPE (arg
))
1745 && is_tagged_type (TREE_TYPE (TREE_TYPE (arg
)))
1746 && !(num
== 1 && is_method
&& (DECL_VINDEX (func
) || is_constructor
)))
1747 pp_string (buffer
, "'Class");
1749 arg
= TREE_CHAIN (arg
);
1753 pp_semicolon (buffer
);
1756 newline_and_indent (buffer
, spc
+ INDENT_INCR
);
1764 pp_string (buffer
, " -- , ...");
1765 newline_and_indent (buffer
, spc
+ INDENT_INCR
);
1769 pp_right_paren (buffer
);
1771 if (is_constructor
|| !VOID_TYPE_P (TREE_TYPE (node
)))
1773 pp_string (buffer
, " return ");
1774 tree type
= is_constructor
? DECL_CONTEXT (func
) : TREE_TYPE (node
);
1775 dump_generic_ada_node (buffer
, type
, type
, spc
, false, true);
1779 /* Dump in BUFFER all the domains associated with an array NODE,
1780 using Ada syntax. SPC is the current indentation level. */
1783 dump_ada_array_domains (pretty_printer
*buffer
, tree node
, int spc
)
1786 pp_left_paren (buffer
);
1788 for (; TREE_CODE (node
) == ARRAY_TYPE
; node
= TREE_TYPE (node
))
1790 tree domain
= TYPE_DOMAIN (node
);
1794 tree min
= TYPE_MIN_VALUE (domain
);
1795 tree max
= TYPE_MAX_VALUE (domain
);
1798 pp_string (buffer
, ", ");
1802 dump_generic_ada_node (buffer
, min
, NULL_TREE
, spc
, 0, true);
1803 pp_string (buffer
, " .. ");
1805 /* If the upper bound is zero, gcc may generate a NULL_TREE
1806 for TYPE_MAX_VALUE rather than an integer_cst. */
1808 dump_generic_ada_node (buffer
, max
, NULL_TREE
, spc
, 0, true);
1810 pp_string (buffer
, "0");
1813 pp_string (buffer
, "size_t");
1815 pp_right_paren (buffer
);
1818 /* Dump in BUFFER file:line information related to NODE. */
1821 dump_sloc (pretty_printer
*buffer
, tree node
)
1823 expanded_location xloc
;
1828 xloc
= expand_location (DECL_SOURCE_LOCATION (node
));
1829 else if (EXPR_HAS_LOCATION (node
))
1830 xloc
= expand_location (EXPR_LOCATION (node
));
1834 pp_string (buffer
, xloc
.file
);
1836 pp_decimal_int (buffer
, xloc
.line
);
1840 /* Return true if T designates a one dimension array of "char". */
1843 is_char_array (tree t
)
1848 /* Retrieve array's type. */
1850 while (TREE_CODE (TREE_TYPE (tmp
)) == ARRAY_TYPE
)
1853 tmp
= TREE_TYPE (tmp
);
1856 tmp
= TREE_TYPE (tmp
);
1857 return num_dim
== 1 && TREE_CODE (tmp
) == INTEGER_TYPE
1858 && id_equal (DECL_NAME (TYPE_NAME (tmp
)), "char");
1861 /* Dump in BUFFER an array type T in Ada syntax. Assume that the "type"
1862 keyword and name have already been printed. PARENT is the parent node of T.
1863 SPC is the indentation level. */
1866 dump_ada_array_type (pretty_printer
*buffer
, tree t
, tree parent
, int spc
)
1868 const bool char_array
= is_char_array (t
);
1871 /* Special case char arrays. */
1874 pp_string (buffer
, "Interfaces.C.char_array ");
1877 pp_string (buffer
, "array ");
1879 /* Print the dimensions. */
1880 dump_ada_array_domains (buffer
, TREE_TYPE (t
), spc
);
1882 /* Retrieve the element type. */
1883 tmp
= TREE_TYPE (t
);
1884 while (TREE_CODE (tmp
) == ARRAY_TYPE
)
1885 tmp
= TREE_TYPE (tmp
);
1887 /* Print array's type. */
1890 pp_string (buffer
, " of ");
1892 if (TREE_CODE (tmp
) != POINTER_TYPE
)
1893 pp_string (buffer
, "aliased ");
1895 if (TYPE_NAME (tmp
) || !RECORD_OR_UNION_TYPE_P (tmp
))
1896 dump_generic_ada_node (buffer
, tmp
, TREE_TYPE (t
), spc
, false, true);
1898 dump_ada_double_name (buffer
, parent
, get_underlying_decl (tmp
));
1902 /* Dump in BUFFER type names associated with a template, each prepended with
1903 '_'. TYPES is the TREE_PURPOSE of a DECL_TEMPLATE_INSTANTIATIONS. SPC is
1904 the indentation level. */
1907 dump_template_types (pretty_printer
*buffer
, tree types
, int spc
)
1910 size_t len
= TREE_VEC_LENGTH (types
);
1912 for (i
= 0; i
< len
; i
++)
1914 tree elem
= TREE_VEC_ELT (types
, i
);
1915 pp_underscore (buffer
);
1916 if (!dump_generic_ada_node (buffer
, elem
, 0, spc
, false, true))
1918 pp_string (buffer
, "unknown");
1919 pp_scalar (buffer
, "%lu", (unsigned long) TREE_HASH (elem
));
1924 /* Dump in BUFFER the contents of all class instantiations associated with
1925 a given template T. SPC is the indentation level. */
1928 dump_ada_template (pretty_printer
*buffer
, tree t
, int spc
)
1930 /* DECL_SIZE_UNIT is DECL_TEMPLATE_INSTANTIATIONS in this context. */
1931 tree inst
= DECL_SIZE_UNIT (t
);
1932 /* This emulates DECL_TEMPLATE_RESULT in this context. */
1933 struct tree_template_decl
{
1934 struct tree_decl_common common
;
1938 tree result
= ((struct tree_template_decl
*) t
)->result
;
1941 /* Don't look at template declarations declaring something coming from
1942 another file. This can occur for template friend declarations. */
1943 if (LOCATION_FILE (decl_sloc (result
, false))
1944 != LOCATION_FILE (decl_sloc (t
, false)))
1947 for (; inst
&& inst
!= error_mark_node
; inst
= TREE_CHAIN (inst
))
1949 tree types
= TREE_PURPOSE (inst
);
1950 tree instance
= TREE_VALUE (inst
);
1952 if (TREE_VEC_LENGTH (types
) == 0)
1955 if (!RECORD_OR_UNION_TYPE_P (instance
))
1958 /* We are interested in concrete template instantiations only: skip
1959 partially specialized nodes. */
1960 if (RECORD_OR_UNION_TYPE_P (instance
)
1962 && cpp_check (instance
, HAS_DEPENDENT_TEMPLATE_ARGS
))
1967 pp_string (buffer
, "package ");
1968 package_prefix
= false;
1969 dump_generic_ada_node (buffer
, instance
, t
, spc
, false, true);
1970 dump_template_types (buffer
, types
, spc
);
1971 pp_string (buffer
, " is");
1973 newline_and_indent (buffer
, spc
);
1975 TREE_VISITED (get_underlying_decl (instance
)) = 1;
1976 pp_string (buffer
, "type ");
1977 dump_generic_ada_node (buffer
, instance
, t
, spc
, false, true);
1978 package_prefix
= true;
1980 if (is_tagged_type (instance
))
1981 pp_string (buffer
, " is tagged limited ");
1983 pp_string (buffer
, " is limited ");
1985 dump_generic_ada_node (buffer
, instance
, t
, spc
, false, false);
1986 pp_newline (buffer
);
1988 newline_and_indent (buffer
, spc
);
1990 pp_string (buffer
, "end;");
1991 newline_and_indent (buffer
, spc
);
1992 pp_string (buffer
, "use ");
1993 package_prefix
= false;
1994 dump_generic_ada_node (buffer
, instance
, t
, spc
, false, true);
1995 dump_template_types (buffer
, types
, spc
);
1996 package_prefix
= true;
1997 pp_semicolon (buffer
);
1998 pp_newline (buffer
);
1999 pp_newline (buffer
);
2002 return num_inst
> 0;
2005 /* Return true if NODE is a simple enum types, that can be mapped to an
2006 Ada enum type directly. */
2009 is_simple_enum (tree node
)
2011 HOST_WIDE_INT count
= 0;
2014 for (value
= TYPE_VALUES (node
); value
; value
= TREE_CHAIN (value
))
2016 tree int_val
= TREE_VALUE (value
);
2018 if (TREE_CODE (int_val
) != INTEGER_CST
)
2019 int_val
= DECL_INITIAL (int_val
);
2021 if (!tree_fits_shwi_p (int_val
))
2023 else if (tree_to_shwi (int_val
) != count
)
2032 static bool bitfield_used
= false;
2034 /* Recursively dump in BUFFER Ada declarations corresponding to NODE of type
2035 TYPE. SPC is the indentation level. LIMITED_ACCESS indicates whether NODE
2036 can be referenced via a "limited with" clause. NAME_ONLY indicates whether
2037 we should only dump the name of NODE, instead of its full declaration. */
2040 dump_generic_ada_node (pretty_printer
*buffer
, tree node
, tree type
, int spc
,
2041 bool limited_access
, bool name_only
)
2043 if (node
== NULL_TREE
)
2046 switch (TREE_CODE (node
))
2049 pp_string (buffer
, "<<< error >>>");
2052 case IDENTIFIER_NODE
:
2053 pp_ada_tree_identifier (buffer
, node
, type
, 0, limited_access
);
2057 pp_string (buffer
, "--- unexpected node: TREE_LIST");
2061 dump_generic_ada_node
2062 (buffer
, BINFO_TYPE (node
), type
, spc
, limited_access
, name_only
);
2066 pp_string (buffer
, "--- unexpected node: TREE_VEC");
2072 append_withs ("System", false);
2073 pp_string (buffer
, "System.Address");
2076 pp_string (buffer
, "address");
2080 pp_string (buffer
, "<vector>");
2084 pp_string (buffer
, "<complex>");
2089 dump_generic_ada_node (buffer
, TYPE_NAME (node
), node
, spc
, 0, true);
2092 tree value
= TYPE_VALUES (node
);
2094 if (is_simple_enum (node
))
2098 newline_and_indent (buffer
, spc
- 1);
2099 pp_left_paren (buffer
);
2100 for (; value
; value
= TREE_CHAIN (value
))
2107 newline_and_indent (buffer
, spc
);
2110 pp_ada_tree_identifier (buffer
, TREE_PURPOSE (value
), node
,
2113 pp_string (buffer
, ");");
2115 newline_and_indent (buffer
, spc
);
2116 pp_string (buffer
, "pragma Convention (C, ");
2117 dump_generic_ada_node
2118 (buffer
, DECL_NAME (type
) ? type
: TYPE_NAME (node
), type
,
2120 pp_right_paren (buffer
);
2124 if (TYPE_UNSIGNED (node
))
2125 pp_string (buffer
, "unsigned");
2127 pp_string (buffer
, "int");
2128 for (; value
; value
= TREE_CHAIN (value
))
2130 pp_semicolon (buffer
);
2131 newline_and_indent (buffer
, spc
);
2133 pp_ada_tree_identifier (buffer
, TREE_PURPOSE (value
), node
,
2135 pp_string (buffer
, " : constant ");
2137 dump_generic_ada_node
2138 (buffer
, DECL_NAME (type
) ? type
: TYPE_NAME (node
), type
,
2141 pp_string (buffer
, " := ");
2142 dump_generic_ada_node
2144 TREE_CODE (TREE_VALUE (value
)) == INTEGER_CST
?
2145 TREE_VALUE (value
) : DECL_INITIAL (TREE_VALUE (value
)),
2146 node
, spc
, false, true);
2154 case FIXED_POINT_TYPE
:
2157 enum tree_code_class tclass
;
2159 tclass
= TREE_CODE_CLASS (TREE_CODE (node
));
2161 if (tclass
== tcc_declaration
)
2163 if (DECL_NAME (node
))
2164 pp_ada_tree_identifier (buffer
, DECL_NAME (node
), NULL_TREE
, 0,
2167 pp_string (buffer
, "<unnamed type decl>");
2169 else if (tclass
== tcc_type
)
2171 if (TYPE_NAME (node
))
2173 if (TREE_CODE (TYPE_NAME (node
)) == IDENTIFIER_NODE
)
2174 pp_ada_tree_identifier (buffer
, TYPE_NAME (node
), node
, 0,
2176 else if (TREE_CODE (TYPE_NAME (node
)) == TYPE_DECL
2177 && DECL_NAME (TYPE_NAME (node
)))
2178 dump_ada_decl_name (buffer
, TYPE_NAME (node
), limited_access
);
2180 pp_string (buffer
, "<unnamed type>");
2182 else if (TREE_CODE (node
) == INTEGER_TYPE
)
2184 append_withs ("Interfaces.C.Extensions", false);
2185 bitfield_used
= true;
2187 if (TYPE_PRECISION (node
) == 1)
2188 pp_string (buffer
, "Extensions.Unsigned_1");
2191 pp_string (buffer
, (TYPE_UNSIGNED (node
)
2192 ? "Extensions.Unsigned_"
2193 : "Extensions.Signed_"));
2194 pp_decimal_int (buffer
, TYPE_PRECISION (node
));
2198 pp_string (buffer
, "<unnamed type>");
2204 case REFERENCE_TYPE
:
2205 if (name_only
&& TYPE_NAME (node
))
2206 dump_generic_ada_node
2207 (buffer
, TYPE_NAME (node
), node
, spc
, limited_access
, true);
2209 else if (TREE_CODE (TREE_TYPE (node
)) == FUNCTION_TYPE
)
2211 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (node
))))
2212 pp_string (buffer
, "access procedure ");
2214 pp_string (buffer
, "access function ");
2216 dump_ada_function_declaration
2217 (buffer
, node
, false, false, false, spc
+ INDENT_INCR
);
2219 /* If we are dumping the full type, it means we are part of a
2220 type definition and need also a Convention C pragma. */
2223 pp_semicolon (buffer
);
2224 newline_and_indent (buffer
, spc
);
2225 pp_string (buffer
, "pragma Convention (C, ");
2226 dump_generic_ada_node (buffer
, type
, 0, spc
, false, true);
2227 pp_right_paren (buffer
);
2232 int is_access
= false;
2233 unsigned int quals
= TYPE_QUALS (TREE_TYPE (node
));
2235 if (VOID_TYPE_P (TREE_TYPE (node
)))
2238 pp_string (buffer
, "new ");
2241 append_withs ("System", false);
2242 pp_string (buffer
, "System.Address");
2245 pp_string (buffer
, "address");
2249 if (TREE_CODE (node
) == POINTER_TYPE
2250 && TREE_CODE (TREE_TYPE (node
)) == INTEGER_TYPE
2252 (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME
2253 (TREE_TYPE (node
)))), "char"))
2256 pp_string (buffer
, "new ");
2260 pp_string (buffer
, "Interfaces.C.Strings.chars_ptr");
2261 append_withs ("Interfaces.C.Strings", false);
2264 pp_string (buffer
, "chars_ptr");
2268 tree type_name
= TYPE_NAME (TREE_TYPE (node
));
2269 tree decl
= get_underlying_decl (TREE_TYPE (node
));
2270 tree enclosing_decl
= get_underlying_decl (type
);
2272 /* For now, handle access-to-access, access-to-empty-struct
2273 or access-to-incomplete as opaque system.address. */
2274 if (TREE_CODE (TREE_TYPE (node
)) == POINTER_TYPE
2275 || (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node
))
2276 && !TYPE_FIELDS (TREE_TYPE (node
)))
2279 && !TREE_VISITED (decl
)
2280 && DECL_SOURCE_FILE (decl
) == current_source_file
)
2282 && !TREE_VISITED (decl
)
2283 && DECL_SOURCE_FILE (decl
)
2284 == DECL_SOURCE_FILE (enclosing_decl
)
2285 && decl_sloc (decl
, true)
2286 > decl_sloc (enclosing_decl
, true)))
2290 append_withs ("System", false);
2292 pp_string (buffer
, "new ");
2293 pp_string (buffer
, "System.Address");
2296 pp_string (buffer
, "address");
2300 if (!package_prefix
)
2301 pp_string (buffer
, "access");
2302 else if (AGGREGATE_TYPE_P (TREE_TYPE (node
)))
2304 if (!type
|| TREE_CODE (type
) != FUNCTION_DECL
)
2306 pp_string (buffer
, "access ");
2309 if (quals
& TYPE_QUAL_CONST
)
2310 pp_string (buffer
, "constant ");
2311 else if (!name_only
)
2312 pp_string (buffer
, "all ");
2314 else if (quals
& TYPE_QUAL_CONST
)
2315 pp_string (buffer
, "in ");
2319 pp_string (buffer
, "access ");
2320 /* ??? should be configurable: access or in out. */
2326 pp_string (buffer
, "access ");
2329 pp_string (buffer
, "all ");
2332 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node
)) && type_name
)
2333 dump_generic_ada_node (buffer
, type_name
, TREE_TYPE (node
),
2334 spc
, is_access
, true);
2336 dump_generic_ada_node (buffer
, TREE_TYPE (node
),
2337 TREE_TYPE (node
), spc
, 0, true);
2345 dump_generic_ada_node
2346 (buffer
, TYPE_NAME (node
), node
, spc
, limited_access
, true);
2348 dump_ada_array_type (buffer
, node
, type
, spc
);
2355 if (TYPE_NAME (node
))
2356 dump_generic_ada_node
2357 (buffer
, TYPE_NAME (node
), node
, spc
, limited_access
, true);
2360 pp_string (buffer
, "anon_");
2361 pp_scalar (buffer
, "%d", TYPE_UID (node
));
2365 dump_ada_struct_decl (buffer
, node
, type
, spc
, true);
2369 /* We treat the upper half of the sizetype range as negative. This
2370 is consistent with the internal treatment and makes it possible
2371 to generate the (0 .. -1) range for flexible array members. */
2372 if (TREE_TYPE (node
) == sizetype
)
2373 node
= fold_convert (ssizetype
, node
);
2374 if (tree_fits_shwi_p (node
))
2375 pp_wide_integer (buffer
, tree_to_shwi (node
));
2376 else if (tree_fits_uhwi_p (node
))
2377 pp_unsigned_wide_integer (buffer
, tree_to_uhwi (node
));
2380 wide_int val
= wi::to_wide (node
);
2382 if (wi::neg_p (val
))
2387 sprintf (pp_buffer (buffer
)->digit_buffer
,
2388 "16#%" HOST_WIDE_INT_PRINT
"x",
2389 val
.elt (val
.get_len () - 1));
2390 for (i
= val
.get_len () - 2; i
>= 0; i
--)
2391 sprintf (pp_buffer (buffer
)->digit_buffer
,
2392 HOST_WIDE_INT_PRINT_PADDED_HEX
, val
.elt (i
));
2393 pp_string (buffer
, pp_buffer (buffer
)->digit_buffer
);
2405 if (DECL_IS_BUILTIN (node
))
2407 /* Don't print the declaration of built-in types. */
2411 /* If we're in the middle of a declaration, defaults to
2415 append_withs ("System", false);
2416 pp_string (buffer
, "System.Address");
2419 pp_string (buffer
, "address");
2425 dump_ada_decl_name (buffer
, node
, limited_access
);
2428 if (is_tagged_type (TREE_TYPE (node
)))
2432 /* Look for ancestors. */
2433 for (tree fld
= TYPE_FIELDS (TREE_TYPE (node
));
2435 fld
= TREE_CHAIN (fld
))
2437 if (!DECL_NAME (fld
) && is_tagged_type (TREE_TYPE (fld
)))
2441 pp_string (buffer
, "limited new ");
2445 pp_string (buffer
, " and ");
2447 dump_ada_decl_name (buffer
, TYPE_NAME (TREE_TYPE (fld
)),
2452 pp_string (buffer
, first
? "tagged limited " : " with ");
2454 else if (has_nontrivial_methods (TREE_TYPE (node
)))
2455 pp_string (buffer
, "limited ");
2457 dump_generic_ada_node
2458 (buffer
, TREE_TYPE (node
), type
, spc
, false, false);
2467 case NAMESPACE_DECL
:
2468 dump_ada_decl_name (buffer
, node
, false);
2472 /* Ignore other nodes (e.g. expressions). */
2479 /* Dump in BUFFER NODE's methods. SPC is the indentation level. Return 1 if
2480 methods were printed, 0 otherwise. */
2483 dump_ada_methods (pretty_printer
*buffer
, tree node
, int spc
)
2485 if (!has_nontrivial_methods (node
))
2488 pp_semicolon (buffer
);
2491 for (tree fld
= TYPE_FIELDS (node
); fld
; fld
= DECL_CHAIN (fld
))
2492 if (TREE_CODE (fld
) == FUNCTION_DECL
)
2496 pp_newline (buffer
);
2497 pp_newline (buffer
);
2500 res
= dump_ada_declaration (buffer
, fld
, node
, spc
);
2506 static void dump_nested_type (pretty_printer
*, tree
, tree
, tree
, int);
2508 /* Dump in BUFFER anonymous types nested inside T's definition.
2509 PARENT is the parent node of T.
2510 FORWARD indicates whether a forward declaration of T should be generated.
2511 SPC is the indentation level.
2513 In C anonymous nested tagged types have no name whereas in C++ they have
2514 one. In C their TYPE_DECL is at top level whereas in C++ it is nested.
2515 In both languages untagged types (pointers and arrays) have no name.
2516 In C++ the nested TYPE_DECLs can come after their associated FIELD_DECL.
2518 Therefore, in order to have a common processing for both languages, we
2519 disregard anonymous TYPE_DECLs at top level and here we make a first
2520 pass on the nested TYPE_DECLs and a second pass on the unnamed types. */
2523 dump_nested_types (pretty_printer
*buffer
, tree t
, tree parent
, bool forward
,
2528 /* Avoid recursing over the same tree. */
2529 if (TREE_VISITED (t
))
2532 /* Find possible anonymous pointers/arrays/structs/unions recursively. */
2533 type
= TREE_TYPE (t
);
2534 if (type
== NULL_TREE
)
2539 pp_string (buffer
, "type ");
2540 dump_generic_ada_node (buffer
, t
, t
, spc
, false, true);
2541 pp_semicolon (buffer
);
2542 newline_and_indent (buffer
, spc
);
2543 TREE_VISITED (t
) = 1;
2546 for (field
= TYPE_FIELDS (type
); field
; field
= TREE_CHAIN (field
))
2547 if (TREE_CODE (field
) == TYPE_DECL
2548 && DECL_NAME (field
) != DECL_NAME (t
)
2549 && TYPE_NAME (TREE_TYPE (field
)) != TYPE_NAME (type
))
2550 dump_nested_type (buffer
, field
, t
, parent
, spc
);
2552 for (field
= TYPE_FIELDS (type
); field
; field
= TREE_CHAIN (field
))
2553 if (TREE_CODE (field
) == FIELD_DECL
&& !TYPE_NAME (TREE_TYPE (field
)))
2554 dump_nested_type (buffer
, field
, t
, parent
, spc
);
2556 TREE_VISITED (t
) = 1;
2559 /* Dump in BUFFER the anonymous type of FIELD inside T.
2560 PARENT is the parent node of T.
2561 FORWARD indicates whether a forward declaration of T should be generated.
2562 SPC is the indentation level. */
2565 dump_nested_type (pretty_printer
*buffer
, tree field
, tree t
, tree parent
,
2568 tree field_type
= TREE_TYPE (field
);
2571 switch (TREE_CODE (field_type
))
2574 tmp
= TREE_TYPE (field_type
);
2576 if (TREE_CODE (tmp
) == FUNCTION_TYPE
)
2577 for (tmp
= TREE_TYPE (tmp
);
2578 tmp
&& TREE_CODE (tmp
) == POINTER_TYPE
;
2579 tmp
= TREE_TYPE (tmp
))
2582 decl
= get_underlying_decl (tmp
);
2584 && !DECL_IS_BUILTIN (decl
)
2585 && (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl
))
2586 || TYPE_FIELDS (TREE_TYPE (decl
)))
2587 && !TREE_VISITED (decl
)
2588 && DECL_SOURCE_FILE (decl
) == DECL_SOURCE_FILE (t
)
2589 && decl_sloc (decl
, true) > decl_sloc (t
, true))
2591 /* Generate forward declaration. */
2592 pp_string (buffer
, "type ");
2593 dump_generic_ada_node (buffer
, decl
, 0, spc
, false, true);
2594 pp_semicolon (buffer
);
2595 newline_and_indent (buffer
, spc
);
2596 TREE_VISITED (decl
) = 1;
2601 tmp
= TREE_TYPE (field_type
);
2602 while (TREE_CODE (tmp
) == ARRAY_TYPE
)
2603 tmp
= TREE_TYPE (tmp
);
2604 decl
= get_underlying_decl (tmp
);
2605 if (decl
&& !DECL_NAME (decl
) && !TREE_VISITED (decl
))
2607 /* Generate full declaration. */
2608 dump_nested_type (buffer
, decl
, t
, parent
, spc
);
2609 TREE_VISITED (decl
) = 1;
2612 /* Special case char arrays. */
2613 if (is_char_array (field
))
2614 pp_string (buffer
, "sub");
2616 pp_string (buffer
, "type ");
2617 dump_ada_double_name (buffer
, parent
, field
);
2618 pp_string (buffer
, " is ");
2619 dump_ada_array_type (buffer
, field
, parent
, spc
);
2620 pp_semicolon (buffer
);
2621 newline_and_indent (buffer
, spc
);
2626 if (TYPE_NAME (TREE_TYPE (t
)) && !TREE_VISITED (t
))
2628 pp_string (buffer
, "type ");
2629 dump_generic_ada_node (buffer
, t
, parent
, spc
, false, true);
2630 pp_semicolon (buffer
);
2631 newline_and_indent (buffer
, spc
);
2634 TREE_VISITED (t
) = 1;
2635 dump_nested_types (buffer
, field
, t
, false, spc
);
2637 pp_string (buffer
, "type ");
2639 if (TYPE_NAME (field_type
))
2641 dump_generic_ada_node (buffer
, field_type
, 0, spc
, false, true);
2642 if (TREE_CODE (field_type
) == UNION_TYPE
)
2643 pp_string (buffer
, " (discr : unsigned := 0)");
2644 pp_string (buffer
, " is ");
2645 dump_ada_struct_decl (buffer
, field_type
, t
, spc
, false);
2647 pp_string (buffer
, "pragma Convention (C_Pass_By_Copy, ");
2648 dump_generic_ada_node (buffer
, field_type
, 0, spc
, false, true);
2649 pp_string (buffer
, ");");
2650 newline_and_indent (buffer
, spc
);
2652 if (TREE_CODE (field_type
) == UNION_TYPE
)
2654 pp_string (buffer
, "pragma Unchecked_Union (");
2655 dump_generic_ada_node (buffer
, field_type
, 0, spc
, false, true);
2656 pp_string (buffer
, ");");
2661 dump_ada_double_name (buffer
, parent
, field
);
2662 if (TREE_CODE (field_type
) == UNION_TYPE
)
2663 pp_string (buffer
, " (discr : unsigned := 0)");
2664 pp_string (buffer
, " is ");
2665 dump_ada_struct_decl (buffer
, field_type
, t
, spc
, false);
2667 pp_string (buffer
, "pragma Convention (C_Pass_By_Copy, ");
2668 dump_ada_double_name (buffer
, parent
, field
);
2669 pp_string (buffer
, ");");
2670 newline_and_indent (buffer
, spc
);
2672 if (TREE_CODE (field_type
) == UNION_TYPE
)
2674 pp_string (buffer
, "pragma Unchecked_Union (");
2675 dump_ada_double_name (buffer
, parent
, field
);
2676 pp_string (buffer
, ");");
2685 /* Dump in BUFFER constructor spec corresponding to T for TYPE. */
2688 print_constructor (pretty_printer
*buffer
, tree t
, tree type
)
2690 tree decl_name
= DECL_NAME (TYPE_NAME (type
));
2692 pp_string (buffer
, "New_");
2693 pp_ada_tree_identifier (buffer
, decl_name
, t
, 0, false);
2696 /* Dump in BUFFER destructor spec corresponding to T. */
2699 print_destructor (pretty_printer
*buffer
, tree t
, tree type
)
2701 tree decl_name
= DECL_NAME (TYPE_NAME (type
));
2703 pp_string (buffer
, "Delete_");
2704 pp_ada_tree_identifier (buffer
, decl_name
, t
, 0, false);
2707 /* Return the name of type T. */
2712 tree n
= TYPE_NAME (t
);
2714 if (TREE_CODE (n
) == IDENTIFIER_NODE
)
2715 return IDENTIFIER_POINTER (n
);
2717 return IDENTIFIER_POINTER (DECL_NAME (n
));
2720 /* Dump in BUFFER the declaration of a variable T of type TYPE in Ada syntax.
2721 SPC is the indentation level. Return 1 if a declaration was printed,
2725 dump_ada_declaration (pretty_printer
*buffer
, tree t
, tree type
, int spc
)
2727 int is_var
= 0, need_indent
= 0;
2728 int is_class
= false;
2729 tree name
= TYPE_NAME (TREE_TYPE (t
));
2730 tree decl_name
= DECL_NAME (t
);
2731 tree orig
= NULL_TREE
;
2733 if (cpp_check
&& cpp_check (t
, IS_TEMPLATE
))
2734 return dump_ada_template (buffer
, t
, spc
);
2736 if (TREE_CODE (t
) == CONST_DECL
&& TREE_CODE (TREE_TYPE (t
)) == ENUMERAL_TYPE
)
2737 /* Skip enumeral values: will be handled as part of the type itself. */
2740 if (TREE_CODE (t
) == TYPE_DECL
)
2742 orig
= DECL_ORIGINAL_TYPE (t
);
2744 if (orig
&& TYPE_STUB_DECL (orig
))
2746 tree stub
= TYPE_STUB_DECL (orig
);
2747 tree typ
= TREE_TYPE (stub
);
2749 if (TYPE_NAME (typ
))
2751 /* If types have same representation, and same name (ignoring
2752 casing), then ignore the second type. */
2753 if (type_name (typ
) == type_name (TREE_TYPE (t
))
2754 || !strcasecmp (type_name (typ
), type_name (TREE_TYPE (t
))))
2756 TREE_VISITED (t
) = 1;
2762 if (RECORD_OR_UNION_TYPE_P (typ
) && !TYPE_FIELDS (typ
))
2764 pp_string (buffer
, "-- skipped empty struct ");
2765 dump_generic_ada_node (buffer
, t
, type
, spc
, false, true);
2769 if (RECORD_OR_UNION_TYPE_P (typ
)
2770 && DECL_SOURCE_FILE (stub
) == current_source_file
)
2771 dump_nested_types (buffer
, stub
, stub
, true, spc
);
2773 pp_string (buffer
, "subtype ");
2774 dump_generic_ada_node (buffer
, t
, type
, spc
, false, true);
2775 pp_string (buffer
, " is ");
2776 dump_generic_ada_node (buffer
, typ
, type
, spc
, false, true);
2777 pp_string (buffer
, "; -- ");
2778 dump_sloc (buffer
, t
);
2781 TREE_VISITED (t
) = 1;
2786 /* Skip unnamed or anonymous structs/unions/enum types. */
2787 if (!orig
&& !decl_name
&& !name
2788 && (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t
))
2789 || TREE_CODE (TREE_TYPE (t
)) == ENUMERAL_TYPE
))
2792 /* Skip anonymous enum types (duplicates of real types). */
2794 && TREE_CODE (TREE_TYPE (t
)) == ENUMERAL_TYPE
2796 && (*IDENTIFIER_POINTER (decl_name
) == '.'
2797 || *IDENTIFIER_POINTER (decl_name
) == '$'))
2802 switch (TREE_CODE (TREE_TYPE (t
)))
2806 /* Skip empty structs (typically forward references to real
2808 if (!TYPE_FIELDS (TREE_TYPE (t
)))
2810 pp_string (buffer
, "-- skipped empty struct ");
2811 dump_generic_ada_node (buffer
, t
, type
, spc
, false, true);
2816 && (*IDENTIFIER_POINTER (decl_name
) == '.'
2817 || *IDENTIFIER_POINTER (decl_name
) == '$'))
2819 pp_string (buffer
, "-- skipped anonymous struct ");
2820 dump_generic_ada_node (buffer
, t
, type
, spc
, false, true);
2821 TREE_VISITED (t
) = 1;
2825 if (orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
))
2826 pp_string (buffer
, "subtype ");
2829 dump_nested_types (buffer
, t
, t
, false, spc
);
2831 if (separate_class_package (t
))
2834 pp_string (buffer
, "package Class_");
2835 dump_generic_ada_node (buffer
, t
, type
, spc
, false, true);
2836 pp_string (buffer
, " is");
2838 newline_and_indent (buffer
, spc
);
2841 pp_string (buffer
, "type ");
2847 case REFERENCE_TYPE
:
2848 if ((orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
))
2849 || is_char_array (t
))
2850 pp_string (buffer
, "subtype ");
2852 pp_string (buffer
, "type ");
2856 pp_string (buffer
, "-- skipped function type ");
2857 dump_generic_ada_node (buffer
, t
, type
, spc
, false, true);
2861 if ((orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
))
2862 || !is_simple_enum (TREE_TYPE (t
)))
2863 pp_string (buffer
, "subtype ");
2865 pp_string (buffer
, "type ");
2869 pp_string (buffer
, "subtype ");
2871 TREE_VISITED (t
) = 1;
2877 && *IDENTIFIER_POINTER (decl_name
) == '_')
2883 /* Print the type and name. */
2884 if (TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
)
2889 /* Print variable's name. */
2890 dump_generic_ada_node (buffer
, t
, type
, spc
, false, true);
2892 if (TREE_CODE (t
) == TYPE_DECL
)
2894 pp_string (buffer
, " is ");
2896 if (orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
))
2897 dump_generic_ada_node
2898 (buffer
, TYPE_NAME (orig
), type
, spc
, false, true);
2900 dump_ada_array_type (buffer
, t
, type
, spc
);
2904 tree tmp
= TYPE_NAME (TREE_TYPE (t
));
2906 if (spc
== INDENT_INCR
|| TREE_STATIC (t
))
2909 pp_string (buffer
, " : ");
2911 if (TREE_CODE (TREE_TYPE (TREE_TYPE (t
))) != POINTER_TYPE
)
2912 pp_string (buffer
, "aliased ");
2915 dump_generic_ada_node (buffer
, tmp
, type
, spc
, false, true);
2917 dump_ada_double_name (buffer
, type
, t
);
2919 dump_ada_array_type (buffer
, t
, type
, spc
);
2922 else if (TREE_CODE (t
) == FUNCTION_DECL
)
2924 bool is_abstract_class
= false;
2925 bool is_method
= TREE_CODE (TREE_TYPE (t
)) == METHOD_TYPE
;
2926 tree decl_name
= DECL_NAME (t
);
2927 bool is_abstract
= false;
2928 bool is_constructor
= false;
2929 bool is_destructor
= false;
2930 bool is_copy_constructor
= false;
2931 bool is_move_constructor
= false;
2938 is_abstract
= cpp_check (t
, IS_ABSTRACT
);
2939 is_constructor
= cpp_check (t
, IS_CONSTRUCTOR
);
2940 is_destructor
= cpp_check (t
, IS_DESTRUCTOR
);
2941 is_copy_constructor
= cpp_check (t
, IS_COPY_CONSTRUCTOR
);
2942 is_move_constructor
= cpp_check (t
, IS_MOVE_CONSTRUCTOR
);
2945 /* Skip copy constructors and C++11 move constructors: some are internal
2946 only and those that are not cannot be called easily from Ada. */
2947 if (is_copy_constructor
|| is_move_constructor
)
2950 if (is_constructor
|| is_destructor
)
2952 /* ??? Skip implicit constructors/destructors for now. */
2953 if (DECL_ARTIFICIAL (t
))
2956 /* Only consider constructors/destructors for complete objects. */
2957 if (strncmp (IDENTIFIER_POINTER (decl_name
), "__ct_comp", 9) != 0
2958 && strncmp (IDENTIFIER_POINTER (decl_name
), "__dt_comp", 9) != 0)
2962 /* If this function has an entry in the vtable, we cannot omit it. */
2963 else if (!DECL_VINDEX (t
) && *IDENTIFIER_POINTER (decl_name
) == '_')
2966 pp_string (buffer
, "-- skipped func ");
2967 pp_string (buffer
, IDENTIFIER_POINTER (decl_name
));
2974 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (t
))) && !is_constructor
)
2975 pp_string (buffer
, "procedure ");
2977 pp_string (buffer
, "function ");
2980 print_constructor (buffer
, t
, type
);
2981 else if (is_destructor
)
2982 print_destructor (buffer
, t
, type
);
2984 dump_ada_decl_name (buffer
, t
, false);
2986 dump_ada_function_declaration
2987 (buffer
, t
, is_method
, is_constructor
, is_destructor
, spc
);
2989 if (is_constructor
&& RECORD_OR_UNION_TYPE_P (type
))
2990 for (tree fld
= TYPE_FIELDS (type
); fld
; fld
= DECL_CHAIN (fld
))
2991 if (TREE_CODE (fld
) == FUNCTION_DECL
&& cpp_check (fld
, IS_ABSTRACT
))
2993 is_abstract_class
= true;
2997 if (is_abstract
|| is_abstract_class
)
2998 pp_string (buffer
, " is abstract");
3000 pp_semicolon (buffer
);
3001 pp_string (buffer
, " -- ");
3002 dump_sloc (buffer
, t
);
3004 if (is_abstract
|| !DECL_ASSEMBLER_NAME (t
))
3007 newline_and_indent (buffer
, spc
);
3011 pp_string (buffer
, "pragma CPP_Constructor (");
3012 print_constructor (buffer
, t
, type
);
3013 pp_string (buffer
, ", \"");
3014 pp_asm_name (buffer
, t
);
3015 pp_string (buffer
, "\");");
3017 else if (is_destructor
)
3019 pp_string (buffer
, "pragma Import (CPP, ");
3020 print_destructor (buffer
, t
, type
);
3021 pp_string (buffer
, ", \"");
3022 pp_asm_name (buffer
, t
);
3023 pp_string (buffer
, "\");");
3026 dump_ada_import (buffer
, t
);
3030 else if (TREE_CODE (t
) == TYPE_DECL
&& !DECL_ORIGINAL_TYPE (t
))
3032 int is_interface
= 0;
3033 int is_abstract_record
= 0;
3038 /* Anonymous structs/unions */
3039 dump_generic_ada_node (buffer
, TREE_TYPE (t
), t
, spc
, false, true);
3041 if (TREE_CODE (TREE_TYPE (t
)) == UNION_TYPE
)
3043 pp_string (buffer
, " (discr : unsigned := 0)");
3046 pp_string (buffer
, " is ");
3048 /* Check whether we have an Ada interface compatible class.
3049 That is only have a vtable non-static data member and no
3050 non-abstract methods. */
3052 && RECORD_OR_UNION_TYPE_P (TREE_TYPE (t
)))
3054 bool has_fields
= false;
3056 /* Check that there are no fields other than the virtual table. */
3057 for (tree fld
= TYPE_FIELDS (TREE_TYPE (t
));
3059 fld
= TREE_CHAIN (fld
))
3061 if (TREE_CODE (fld
) == FIELD_DECL
)
3063 if (!has_fields
&& DECL_VIRTUAL_P (fld
))
3069 else if (TREE_CODE (fld
) == FUNCTION_DECL
3070 && !DECL_ARTIFICIAL (fld
))
3072 if (cpp_check (fld
, IS_ABSTRACT
))
3073 is_abstract_record
= 1;
3080 TREE_VISITED (t
) = 1;
3083 pp_string (buffer
, "limited interface; -- ");
3084 dump_sloc (buffer
, t
);
3085 newline_and_indent (buffer
, spc
);
3086 pp_string (buffer
, "pragma Import (CPP, ");
3087 dump_generic_ada_node
3088 (buffer
, TYPE_NAME (TREE_TYPE (t
)), type
, spc
, false, true);
3089 pp_right_paren (buffer
);
3091 dump_ada_methods (buffer
, TREE_TYPE (t
), spc
);
3095 if (is_abstract_record
)
3096 pp_string (buffer
, "abstract ");
3097 dump_generic_ada_node (buffer
, t
, t
, spc
, false, false);
3105 if (TREE_CODE (t
) == FIELD_DECL
&& DECL_NAME (t
))
3106 check_name (buffer
, t
);
3108 /* Print variable/type's name. */
3109 dump_generic_ada_node (buffer
, t
, t
, spc
, false, true);
3111 if (TREE_CODE (t
) == TYPE_DECL
)
3113 tree orig
= DECL_ORIGINAL_TYPE (t
);
3114 int is_subtype
= orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
);
3116 if (!is_subtype
&& TREE_CODE (TREE_TYPE (t
)) == UNION_TYPE
)
3117 pp_string (buffer
, " (discr : unsigned := 0)");
3119 pp_string (buffer
, " is ");
3121 dump_generic_ada_node (buffer
, orig
, t
, spc
, false, is_subtype
);
3125 if (spc
== INDENT_INCR
|| TREE_STATIC (t
))
3128 pp_string (buffer
, " : ");
3130 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t
)))
3132 pp_string (buffer
, "aliased ");
3134 if (TREE_READONLY (t
))
3135 pp_string (buffer
, "constant ");
3137 if (TYPE_NAME (TREE_TYPE (t
)))
3138 dump_generic_ada_node
3139 (buffer
, TREE_TYPE (t
), t
, spc
, false, true);
3141 dump_ada_double_name (buffer
, type
, t
);
3145 if (TREE_CODE (TREE_TYPE (t
)) != POINTER_TYPE
3146 && (TYPE_NAME (TREE_TYPE (t
))
3147 || TREE_CODE (TREE_TYPE (t
)) != INTEGER_TYPE
))
3148 pp_string (buffer
, "aliased ");
3150 if (TREE_READONLY (t
))
3151 pp_string (buffer
, "constant ");
3153 dump_generic_ada_node
3154 (buffer
, TREE_TYPE (t
), TREE_TYPE (t
), spc
, false, true);
3162 newline_and_indent (buffer
, spc
);
3163 pp_string (buffer
, "end;");
3164 newline_and_indent (buffer
, spc
);
3165 pp_string (buffer
, "use Class_");
3166 dump_generic_ada_node (buffer
, t
, type
, spc
, false, true);
3167 pp_semicolon (buffer
);
3168 pp_newline (buffer
);
3170 /* All needed indentation/newline performed already, so return 0. */
3175 pp_string (buffer
, "; -- ");
3176 dump_sloc (buffer
, t
);
3181 newline_and_indent (buffer
, spc
);
3182 dump_ada_import (buffer
, t
);
3188 /* Dump in BUFFER a structure NODE of type TYPE: name, fields, and methods
3189 with Ada syntax. SPC is the indentation level. If DISPLAY_CONVENTION is
3190 true, also print the pragma Convention for NODE. */
3193 dump_ada_struct_decl (pretty_printer
*buffer
, tree node
, tree type
, int spc
,
3194 bool display_convention
)
3197 const bool is_union
= (TREE_CODE (node
) == UNION_TYPE
);
3200 int field_spc
= spc
+ INDENT_INCR
;
3203 bitfield_used
= false;
3205 if (TYPE_FIELDS (node
))
3207 /* Print the contents of the structure. */
3208 pp_string (buffer
, "record");
3212 newline_and_indent (buffer
, spc
+ INDENT_INCR
);
3213 pp_string (buffer
, "case discr is");
3214 field_spc
= spc
+ INDENT_INCR
* 3;
3217 pp_newline (buffer
);
3219 /* Print the non-static fields of the structure. */
3220 for (tmp
= TYPE_FIELDS (node
); tmp
; tmp
= TREE_CHAIN (tmp
))
3222 /* Add parent field if needed. */
3223 if (!DECL_NAME (tmp
))
3225 if (!is_tagged_type (TREE_TYPE (tmp
)))
3227 if (!TYPE_NAME (TREE_TYPE (tmp
)))
3228 dump_ada_declaration (buffer
, tmp
, type
, field_spc
);
3234 pp_string (buffer
, "parent : aliased ");
3237 sprintf (buf
, "field_%d : aliased ", field_num
+ 1);
3238 pp_string (buffer
, buf
);
3241 (buffer
, TYPE_NAME (TREE_TYPE (tmp
)), false);
3242 pp_semicolon (buffer
);
3244 pp_newline (buffer
);
3248 else if (TREE_CODE (tmp
) == FIELD_DECL
)
3250 /* Skip internal virtual table field. */
3251 if (!DECL_VIRTUAL_P (tmp
))
3255 if (TREE_CHAIN (tmp
)
3256 && TREE_TYPE (TREE_CHAIN (tmp
)) != node
3257 && TREE_CODE (TREE_CHAIN (tmp
)) != TYPE_DECL
)
3258 sprintf (buf
, "when %d =>", field_num
);
3260 sprintf (buf
, "when others =>");
3262 INDENT (spc
+ INDENT_INCR
* 2);
3263 pp_string (buffer
, buf
);
3264 pp_newline (buffer
);
3267 if (dump_ada_declaration (buffer
, tmp
, type
, field_spc
))
3269 pp_newline (buffer
);
3278 INDENT (spc
+ INDENT_INCR
);
3279 pp_string (buffer
, "end case;");
3280 pp_newline (buffer
);
3285 INDENT (spc
+ INDENT_INCR
);
3286 pp_string (buffer
, "null;");
3287 pp_newline (buffer
);
3291 pp_string (buffer
, "end record;");
3294 pp_string (buffer
, "null record;");
3296 newline_and_indent (buffer
, spc
);
3298 if (!display_convention
)
3301 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type
)))
3303 if (has_nontrivial_methods (TREE_TYPE (type
)))
3304 pp_string (buffer
, "pragma Import (CPP, ");
3306 pp_string (buffer
, "pragma Convention (C_Pass_By_Copy, ");
3309 pp_string (buffer
, "pragma Convention (C, ");
3311 package_prefix
= false;
3312 dump_generic_ada_node (buffer
, TREE_TYPE (type
), type
, spc
, false, true);
3313 package_prefix
= true;
3314 pp_right_paren (buffer
);
3318 pp_semicolon (buffer
);
3319 newline_and_indent (buffer
, spc
);
3320 pp_string (buffer
, "pragma Unchecked_Union (");
3322 dump_generic_ada_node (buffer
, TREE_TYPE (type
), type
, spc
, false, true);
3323 pp_right_paren (buffer
);
3328 pp_semicolon (buffer
);
3329 newline_and_indent (buffer
, spc
);
3330 pp_string (buffer
, "pragma Pack (");
3331 dump_generic_ada_node
3332 (buffer
, TREE_TYPE (type
), type
, spc
, false, true);
3333 pp_right_paren (buffer
);
3334 bitfield_used
= false;
3337 need_semicolon
= !dump_ada_methods (buffer
, node
, spc
);
3339 /* Print the static fields of the structure, if any. */
3340 for (tmp
= TYPE_FIELDS (node
); tmp
; tmp
= TREE_CHAIN (tmp
))
3342 if (TREE_CODE (tmp
) == VAR_DECL
&& DECL_NAME (tmp
))
3346 need_semicolon
= false;
3347 pp_semicolon (buffer
);
3349 pp_newline (buffer
);
3350 pp_newline (buffer
);
3351 dump_ada_declaration (buffer
, tmp
, type
, spc
);
3356 /* Dump all the declarations in SOURCE_FILE to an Ada spec.
3357 COLLECT_ALL_REFS is a front-end callback used to collect all relevant
3358 nodes for SOURCE_FILE. CHECK is used to perform C++ queries on nodes. */
3361 dump_ads (const char *source_file
,
3362 void (*collect_all_refs
)(const char *),
3363 int (*check
)(tree
, cpp_operation
))
3370 pkg_name
= get_ada_package (source_file
);
3372 /* Construct the .ads filename and package name. */
3373 ads_name
= xstrdup (pkg_name
);
3375 for (s
= ads_name
; *s
; s
++)
3381 ads_name
= reconcat (ads_name
, ads_name
, ".ads", NULL
);
3383 /* Write out the .ads file. */
3384 f
= fopen (ads_name
, "w");
3389 pp_needs_newline (&pp
) = true;
3390 pp
.buffer
->stream
= f
;
3392 /* Dump all relevant macros. */
3393 dump_ada_macros (&pp
, source_file
);
3395 /* Reset the table of withs for this file. */
3398 (*collect_all_refs
) (source_file
);
3400 /* Dump all references. */
3402 dump_ada_nodes (&pp
, source_file
);
3404 /* Requires Ada 2005 syntax, so generate corresponding pragma.
3405 Also, disable style checks since this file is auto-generated. */
3406 fprintf (f
, "pragma Ada_2005;\npragma Style_Checks (Off);\n\n");
3411 fprintf (f
, "\npackage %s is\n\n", pkg_name
);
3412 pp_write_text_to_stream (&pp
);
3413 /* ??? need to free pp */
3414 fprintf (f
, "end %s;\n", pkg_name
);
3422 static const char **source_refs
= NULL
;
3423 static int source_refs_used
= 0;
3424 static int source_refs_allocd
= 0;
3426 /* Add an entry for FILENAME to the table SOURCE_REFS. */
3429 collect_source_ref (const char *filename
)
3436 if (source_refs_allocd
== 0)
3438 source_refs_allocd
= 1024;
3439 source_refs
= XNEWVEC (const char *, source_refs_allocd
);
3442 for (i
= 0; i
< source_refs_used
; i
++)
3443 if (filename
== source_refs
[i
])
3446 if (source_refs_used
== source_refs_allocd
)
3448 source_refs_allocd
*= 2;
3449 source_refs
= XRESIZEVEC (const char *, source_refs
, source_refs_allocd
);
3452 source_refs
[source_refs_used
++] = filename
;
3455 /* Main entry point: dump all Ada specs corresponding to SOURCE_REFS
3456 using callbacks COLLECT_ALL_REFS and CHECK.
3457 COLLECT_ALL_REFS is a front-end callback used to collect all relevant
3458 nodes for a given source file.
3459 CHECK is used to perform C++ queries on nodes, or NULL for the C
3463 dump_ada_specs (void (*collect_all_refs
)(const char *),
3464 int (*check
)(tree
, cpp_operation
))
3466 /* Iterate over the list of files to dump specs for. */
3467 for (int i
= 0; i
< source_refs_used
; i
++)
3468 dump_ads (source_refs
[i
], collect_all_refs
, check
);
3470 /* Free various tables. */
3472 delete overloaded_names
;