1 /* Print GENERIC declaration (functions, variables, types) trees coming from
2 the C and C++ front-ends as well as macros in Ada syntax.
3 Copyright (C) 2010 Free Software Foundation, Inc.
4 Adapted from tree-pretty-print.c by Arnaud Charlet <charlet@adacore.com>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
24 #include "coretypes.h"
28 #include "c-ada-spec.h"
31 #include "cpp-id-data.h"
33 /* Adapted from hwint.h to use the Ada prefix. */
34 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
35 # if HOST_BITS_PER_WIDE_INT == 64
36 # define ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX \
37 "16#%" HOST_LONG_FORMAT "x%016" HOST_LONG_FORMAT "x#"
39 # define ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX \
40 "16#%" HOST_LONG_FORMAT "x%08" HOST_LONG_FORMAT "x#"
43 /* We can assume that 'long long' is at least 64 bits. */
44 # define ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX \
45 "16#%" HOST_LONG_LONG_FORMAT "x%016" HOST_LONG_LONG_FORMAT "x#"
46 #endif /* HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG */
48 /* Local functions, macros and variables. */
49 static int dump_generic_ada_node (pretty_printer
*, tree
, tree
,
50 int (*)(tree
, cpp_operation
), int, int, bool);
51 static int print_ada_declaration (pretty_printer
*, tree
, tree
,
52 int (*cpp_check
)(tree
, cpp_operation
), int);
53 static void print_ada_struct_decl (pretty_printer
*, tree
, tree
,
54 int (*cpp_check
)(tree
, cpp_operation
), int,
56 static void dump_sloc (pretty_printer
*buffer
, tree node
);
57 static void print_comment (pretty_printer
*, const char *);
58 static void print_generic_ada_decl (pretty_printer
*, tree
,
59 int (*)(tree
, cpp_operation
), const char *);
60 static char *get_ada_package (const char *);
61 static void dump_ada_nodes (pretty_printer
*, const char *,
62 int (*)(tree
, cpp_operation
));
63 static void reset_ada_withs (void);
64 static void dump_ada_withs (FILE *);
65 static void dump_ads (const char *, void (*)(const char *),
66 int (*)(tree
, cpp_operation
));
67 static char *to_ada_name (const char *, int *);
68 static bool separate_class_package (tree
);
70 #define INDENT(SPACE) do { \
71 int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
75 /* Given a cpp MACRO, compute the max length BUFFER_LEN of the macro, as well
76 as max length PARAM_LEN of arguments for fun_like macros, and also set
77 SUPPORTED to 0 if the macro cannot be mapped to an Ada construct. */
80 macro_length (const cpp_macro
*macro
, int *supported
, int *buffer_len
,
93 for (i
= 0; i
< macro
->paramc
; i
++)
95 cpp_hashnode
*param
= macro
->params
[i
];
97 *param_len
+= NODE_LEN (param
);
99 if (i
+ 1 < macro
->paramc
)
101 *param_len
+= 2; /* ", " */
103 else if (macro
->variadic
)
109 *param_len
+= 2; /* ")\0" */
112 for (j
= 0; j
< macro
->count
; j
++)
114 cpp_token
*token
= ¯o
->exp
.tokens
[j
];
116 if (token
->flags
& PREV_WHITE
)
119 if (token
->flags
& STRINGIFY_ARG
|| token
->flags
& PASTE_LEFT
)
125 if (token
->type
== CPP_MACRO_ARG
)
127 NODE_LEN (macro
->params
[token
->val
.macro_arg
.arg_no
- 1]);
129 /* Include enough extra space to handle e.g. special characters. */
130 *buffer_len
+= (cpp_token_len (token
) + 1) * 8;
136 /* Dump into PP a set of MAX_ADA_MACROS MACROS (C/C++) as Ada constants when
140 print_ada_macros (pretty_printer
*pp
, cpp_hashnode
**macros
, int max_ada_macros
)
142 int j
, num_macros
= 0, prev_line
= -1;
144 for (j
= 0; j
< max_ada_macros
; j
++)
146 cpp_hashnode
*node
= macros
[j
];
147 const cpp_macro
*macro
= node
->value
.macro
;
149 int supported
= 1, prev_is_one
= 0, buffer_len
, param_len
;
150 int is_string
= 0, is_char
= 0;
152 unsigned char *s
, *params
, *buffer
, *buf_param
, *char_one
= NULL
;
154 macro_length (macro
, &supported
, &buffer_len
, ¶m_len
);
155 s
= buffer
= XALLOCAVEC (unsigned char, buffer_len
);
156 params
= buf_param
= XALLOCAVEC (unsigned char, param_len
);
163 for (i
= 0; i
< macro
->paramc
; i
++)
165 cpp_hashnode
*param
= macro
->params
[i
];
167 memcpy (buf_param
, NODE_NAME (param
), NODE_LEN (param
));
168 buf_param
+= NODE_LEN (param
);
170 if (i
+ 1 < macro
->paramc
)
175 else if (macro
->variadic
)
185 for (i
= 0; supported
&& i
< macro
->count
; i
++)
187 cpp_token
*token
= ¯o
->exp
.tokens
[i
];
190 if (token
->flags
& PREV_WHITE
)
193 if (token
->flags
& STRINGIFY_ARG
|| token
->flags
& PASTE_LEFT
)
203 cpp_hashnode
*param
=
204 macro
->params
[token
->val
.macro_arg
.arg_no
- 1];
205 memcpy (buffer
, NODE_NAME (param
), NODE_LEN (param
));
206 buffer
+= NODE_LEN (param
);
210 case CPP_EQ_EQ
: *buffer
++ = '='; break;
211 case CPP_GREATER
: *buffer
++ = '>'; break;
212 case CPP_LESS
: *buffer
++ = '<'; break;
213 case CPP_PLUS
: *buffer
++ = '+'; break;
214 case CPP_MINUS
: *buffer
++ = '-'; break;
215 case CPP_MULT
: *buffer
++ = '*'; break;
216 case CPP_DIV
: *buffer
++ = '/'; break;
217 case CPP_COMMA
: *buffer
++ = ','; break;
218 case CPP_OPEN_SQUARE
:
219 case CPP_OPEN_PAREN
: *buffer
++ = '('; break;
220 case CPP_CLOSE_SQUARE
: /* fallthrough */
221 case CPP_CLOSE_PAREN
: *buffer
++ = ')'; break;
222 case CPP_DEREF
: /* fallthrough */
223 case CPP_SCOPE
: /* fallthrough */
224 case CPP_DOT
: *buffer
++ = '.'; break;
226 case CPP_EQ
: *buffer
++ = ':'; *buffer
++ = '='; break;
227 case CPP_NOT_EQ
: *buffer
++ = '/'; *buffer
++ = '='; break;
228 case CPP_GREATER_EQ
: *buffer
++ = '>'; *buffer
++ = '='; break;
229 case CPP_LESS_EQ
: *buffer
++ = '<'; *buffer
++ = '='; break;
232 *buffer
++ = 'n'; *buffer
++ = 'o'; *buffer
++ = 't'; break;
234 *buffer
++ = 'm'; *buffer
++ = 'o'; *buffer
++ = 'd'; break;
236 *buffer
++ = 'a'; *buffer
++ = 'n'; *buffer
++ = 'd'; break;
238 *buffer
++ = 'o'; *buffer
++ = 'r'; break;
240 *buffer
++ = 'x'; *buffer
++ = 'o'; *buffer
++ = 'r'; break;
242 strcpy ((char *) buffer
, " and then ");
246 strcpy ((char *) buffer
, " or else ");
252 is_one
= prev_is_one
;
255 case CPP_COMMENT
: break;
267 if (!macro
->fun_like
)
270 buffer
= cpp_spell_token (parse_in
, token
, buffer
, false);
280 c
= cpp_interpret_charconst (parse_in
, token
,
281 &chars_seen
, &ignored
);
282 if (c
>= 32 && c
<= 126)
285 *buffer
++ = (char) c
;
291 ((char *) buffer
, "Character'Val (%d)", (int) c
);
292 buffer
+= chars_seen
;
300 /* Replace "1 << N" by "2 ** N" */
327 case CPP_CLOSE_BRACE
:
331 case CPP_MINUS_MINUS
:
335 case CPP_HEADER_NAME
:
338 case CPP_OBJC_STRING
:
340 if (!macro
->fun_like
)
343 buffer
= cpp_spell_token (parse_in
, token
, buffer
, false);
347 prev_is_one
= is_one
;
354 if (macro
->fun_like
&& supported
)
356 char *start
= (char *) s
;
359 pp_string (pp
, " -- arg-macro: ");
361 if (*start
== '(' && buffer
[-1] == ')')
366 pp_string (pp
, "function ");
370 pp_string (pp
, "procedure ");
373 pp_string (pp
, (const char *) NODE_NAME (node
));
375 pp_string (pp
, (char *) params
);
377 pp_string (pp
, " -- ");
381 pp_string (pp
, "return ");
382 pp_string (pp
, start
);
386 pp_string (pp
, start
);
392 expanded_location sloc
= expand_location (macro
->line
);
394 if (sloc
.line
!= prev_line
+ 1)
398 prev_line
= sloc
.line
;
401 ada_name
= to_ada_name ((const char *) NODE_NAME (node
), NULL
);
402 pp_string (pp
, ada_name
);
404 pp_string (pp
, " : ");
407 pp_string (pp
, "aliased constant String");
409 pp_string (pp
, "aliased constant Character");
411 pp_string (pp
, "constant");
413 pp_string (pp
, " := ");
414 pp_string (pp
, (char *) s
);
417 pp_string (pp
, " & ASCII.NUL");
419 pp_string (pp
, "; -- ");
420 pp_string (pp
, sloc
.file
);
421 pp_character (pp
, ':');
422 pp_scalar (pp
, "%d", sloc
.line
);
427 pp_string (pp
, " -- unsupported macro: ");
428 pp_string (pp
, (const char *) cpp_macro_definition (parse_in
, node
));
437 static const char *source_file
;
438 static int max_ada_macros
;
440 /* Callback used to count the number of relevant macros from
441 cpp_forall_identifiers. PFILE and V are not used. NODE is the current macro
445 count_ada_macro (cpp_reader
*pfile ATTRIBUTE_UNUSED
, cpp_hashnode
*node
,
446 void *v ATTRIBUTE_UNUSED
)
448 const cpp_macro
*macro
= node
->value
.macro
;
450 if (node
->type
== NT_MACRO
&& !(node
->flags
& NODE_BUILTIN
)
452 && *NODE_NAME (node
) != '_'
453 && LOCATION_FILE (macro
->line
) == source_file
)
459 static int store_ada_macro_index
;
461 /* Callback used to store relevant macros from cpp_forall_identifiers.
462 PFILE is not used. NODE is the current macro to store if relevant.
463 MACROS is an array of cpp_hashnode* used to store NODE. */
466 store_ada_macro (cpp_reader
*pfile ATTRIBUTE_UNUSED
,
467 cpp_hashnode
*node
, void *macros
)
469 const cpp_macro
*macro
= node
->value
.macro
;
471 if (node
->type
== NT_MACRO
&& !(node
->flags
& NODE_BUILTIN
)
473 && *NODE_NAME (node
) != '_'
474 && LOCATION_FILE (macro
->line
) == source_file
)
475 ((cpp_hashnode
**) macros
)[store_ada_macro_index
++] = node
;
480 /* Callback used to compare (during qsort) macros. NODE1 and NODE2 are the
481 two macro nodes to compare. */
484 compare_macro (const void *node1
, const void *node2
)
486 typedef const cpp_hashnode
*const_hnode
;
488 const_hnode n1
= *(const const_hnode
*) node1
;
489 const_hnode n2
= *(const const_hnode
*) node2
;
491 return n1
->value
.macro
->line
- n2
->value
.macro
->line
;
494 /* Dump in PP all relevant macros appearing in FILE. */
497 dump_ada_macros (pretty_printer
*pp
, const char* file
)
499 cpp_hashnode
**macros
;
501 /* Initialize file-scope variables. */
503 store_ada_macro_index
= 0;
506 /* Count all potentially relevant macros, and then sort them by sloc. */
507 cpp_forall_identifiers (parse_in
, count_ada_macro
, NULL
);
508 macros
= XALLOCAVEC (cpp_hashnode
*, max_ada_macros
);
509 cpp_forall_identifiers (parse_in
, store_ada_macro
, macros
);
510 qsort (macros
, max_ada_macros
, sizeof (cpp_hashnode
*), compare_macro
);
512 print_ada_macros (pp
, macros
, max_ada_macros
);
515 /* Current source file being handled. */
517 static const char *source_file_base
;
519 /* Compare the declaration (DECL) of struct-like types based on the sloc of
520 their last field (if LAST is true), so that more nested types collate before
522 If ORIG_TYPE is true, also consider struct with a DECL_ORIGINAL_TYPE. */
525 decl_sloc_common (const_tree decl
, bool last
, bool orig_type
)
527 tree type
= TREE_TYPE (decl
);
529 if (TREE_CODE (decl
) == TYPE_DECL
530 && (orig_type
|| !DECL_ORIGINAL_TYPE (decl
))
531 && RECORD_OR_UNION_TYPE_P (type
)
532 && TYPE_FIELDS (type
))
534 tree f
= TYPE_FIELDS (type
);
537 while (TREE_CHAIN (f
))
540 return DECL_SOURCE_LOCATION (f
);
543 return DECL_SOURCE_LOCATION (decl
);
546 /* Return sloc of DECL, using sloc of last field if LAST is true. */
549 decl_sloc (const_tree decl
, bool last
)
551 return decl_sloc_common (decl
, last
, false);
554 /* Compare two locations LHS and RHS. */
557 compare_location (location_t lhs
, location_t rhs
)
559 expanded_location xlhs
= expand_location (lhs
);
560 expanded_location xrhs
= expand_location (rhs
);
562 if (xlhs
.file
!= xrhs
.file
)
563 return filename_cmp (xlhs
.file
, xrhs
.file
);
565 if (xlhs
.line
!= xrhs
.line
)
566 return xlhs
.line
- xrhs
.line
;
568 if (xlhs
.column
!= xrhs
.column
)
569 return xlhs
.column
- xrhs
.column
;
574 /* Compare two declarations (LP and RP) by their source location. */
577 compare_node (const void *lp
, const void *rp
)
579 const_tree lhs
= *((const tree
*) lp
);
580 const_tree rhs
= *((const tree
*) rp
);
582 return compare_location (decl_sloc (lhs
, true), decl_sloc (rhs
, true));
585 /* Compare two comments (LP and RP) by their source location. */
588 compare_comment (const void *lp
, const void *rp
)
590 const cpp_comment
*lhs
= (const cpp_comment
*) lp
;
591 const cpp_comment
*rhs
= (const cpp_comment
*) rp
;
593 return compare_location (lhs
->sloc
, rhs
->sloc
);
596 static tree
*to_dump
= NULL
;
597 static int to_dump_count
= 0;
599 /* Collect a list of declarations from T relevant to SOURCE_FILE to be dumped
600 by a subsequent call to dump_ada_nodes. */
603 collect_ada_nodes (tree t
, const char *source_file
)
606 int i
= to_dump_count
;
608 /* Count the likely relevant nodes. */
609 for (n
= t
; n
; n
= TREE_CHAIN (n
))
610 if (!DECL_IS_BUILTIN (n
)
611 && LOCATION_FILE (decl_sloc (n
, false)) == source_file
)
614 /* Allocate sufficient storage for all nodes. */
615 to_dump
= XRESIZEVEC (tree
, to_dump
, to_dump_count
);
617 /* Store the relevant nodes. */
618 for (n
= t
; n
; n
= TREE_CHAIN (n
))
619 if (!DECL_IS_BUILTIN (n
)
620 && LOCATION_FILE (decl_sloc (n
, false)) == source_file
)
624 /* Call back for walk_tree to clear the TREE_VISITED flag of TP. */
627 unmark_visited_r (tree
*tp
, int *walk_subtrees ATTRIBUTE_UNUSED
,
628 void *data ATTRIBUTE_UNUSED
)
630 if (TREE_VISITED (*tp
))
631 TREE_VISITED (*tp
) = 0;
638 /* Dump nodes into PP relevant to SOURCE_FILE, as collected by previous calls
639 to collect_ada_nodes. CPP_CHECK is used to perform C++ queries on nodes. */
642 dump_ada_nodes (pretty_printer
*pp
, const char *source_file
,
643 int (*cpp_check
)(tree
, cpp_operation
))
646 cpp_comment_table
*comments
;
648 /* Sort the table of declarations to dump by sloc. */
649 qsort (to_dump
, to_dump_count
, sizeof (tree
), compare_node
);
651 /* Fetch the table of comments. */
652 comments
= cpp_get_comments (parse_in
);
654 /* Sort the comments table by sloc. */
655 qsort (comments
->entries
, comments
->count
, sizeof (cpp_comment
),
658 /* Interleave comments and declarations in line number order. */
662 /* Advance j until comment j is in this file. */
663 while (j
!= comments
->count
664 && LOCATION_FILE (comments
->entries
[j
].sloc
) != source_file
)
667 /* Advance j until comment j is not a duplicate. */
668 while (j
< comments
->count
- 1
669 && !compare_comment (&comments
->entries
[j
],
670 &comments
->entries
[j
+ 1]))
673 /* Write decls until decl i collates after comment j. */
674 while (i
!= to_dump_count
)
676 if (j
== comments
->count
677 || LOCATION_LINE (decl_sloc (to_dump
[i
], false))
678 < LOCATION_LINE (comments
->entries
[j
].sloc
))
679 print_generic_ada_decl (pp
, to_dump
[i
++], cpp_check
, source_file
);
684 /* Write comment j, if there is one. */
685 if (j
!= comments
->count
)
686 print_comment (pp
, comments
->entries
[j
++].comment
);
688 } while (i
!= to_dump_count
|| j
!= comments
->count
);
690 /* Clear the TREE_VISITED flag over each subtree we've dumped. */
691 for (i
= 0; i
< to_dump_count
; i
++)
692 walk_tree (&to_dump
[i
], unmark_visited_r
, NULL
, NULL
);
694 /* Finalize the to_dump table. */
703 /* Print a COMMENT to the output stream PP. */
706 print_comment (pretty_printer
*pp
, const char *comment
)
708 int len
= strlen (comment
);
709 char *str
= XALLOCAVEC (char, len
+ 1);
711 bool extra_newline
= false;
713 memcpy (str
, comment
, len
+ 1);
715 /* Trim C/C++ comment indicators. */
716 if (str
[len
- 2] == '*' && str
[len
- 1] == '/')
723 tok
= strtok (str
, "\n");
725 pp_string (pp
, " --");
728 tok
= strtok (NULL
, "\n");
730 /* Leave a blank line after multi-line comments. */
732 extra_newline
= true;
739 /* Prints declaration DECL to PP in Ada syntax. The current source file being
740 handled is SOURCE_FILE, and CPP_CHECK is used to perform C++ queries on
744 print_generic_ada_decl (pretty_printer
*pp
, tree decl
,
745 int (*cpp_check
)(tree
, cpp_operation
),
746 const char* source_file
)
748 source_file_base
= source_file
;
750 if (print_ada_declaration (pp
, decl
, 0, cpp_check
, INDENT_INCR
))
757 /* Dump a newline and indent BUFFER by SPC chars. */
760 newline_and_indent (pretty_printer
*buffer
, int spc
)
766 struct with
{ char *s
; const char *in_file
; int limited
; };
767 static struct with
*withs
= NULL
;
768 static int withs_max
= 4096;
769 static int with_len
= 0;
771 /* Record a "with" clause on package S (a limited with if LIMITED_ACCESS is
772 true), if not already done. */
775 append_withs (const char *s
, int limited_access
)
780 withs
= XNEWVEC (struct with
, withs_max
);
782 if (with_len
== withs_max
)
785 withs
= XRESIZEVEC (struct with
, withs
, withs_max
);
788 for (i
= 0; i
< with_len
; i
++)
789 if (!strcmp (s
, withs
[i
].s
)
790 && source_file_base
== withs
[i
].in_file
)
792 withs
[i
].limited
&= limited_access
;
796 withs
[with_len
].s
= xstrdup (s
);
797 withs
[with_len
].in_file
= source_file_base
;
798 withs
[with_len
].limited
= limited_access
;
802 /* Reset "with" clauses. */
805 reset_ada_withs (void)
812 for (i
= 0; i
< with_len
; i
++)
820 /* Dump "with" clauses in F. */
823 dump_ada_withs (FILE *f
)
827 fprintf (f
, "with Interfaces.C; use Interfaces.C;\n");
829 for (i
= 0; i
< with_len
; i
++)
831 (f
, "%swith %s;\n", withs
[i
].limited
? "limited " : "", withs
[i
].s
);
834 /* Return suitable Ada package name from FILE. */
837 get_ada_package (const char *file
)
845 s
= strstr (file
, "/include/");
849 base
= lbasename (file
);
851 if (ada_specs_parent
== NULL
)
854 plen
= strlen (ada_specs_parent
) + 1;
856 res
= XNEWVEC (char, plen
+ strlen (base
) + 1);
857 if (ada_specs_parent
!= NULL
) {
858 strcpy (res
, ada_specs_parent
);
862 for (i
= plen
; *base
; base
++, i
++)
874 res
[i
] = (i
== 0 || res
[i
- 1] == '.' || res
[i
- 1] == '_') ? 'u' : '_';
886 static const char *ada_reserved
[] = {
887 "abort", "abs", "abstract", "accept", "access", "aliased", "all", "and",
888 "array", "at", "begin", "body", "case", "constant", "declare", "delay",
889 "delta", "digits", "do", "else", "elsif", "end", "entry", "exception",
890 "exit", "for", "function", "generic", "goto", "if", "in", "interface", "is",
891 "limited", "loop", "mod", "new", "not", "null", "others", "out", "of", "or",
892 "overriding", "package", "pragma", "private", "procedure", "protected",
893 "raise", "range", "record", "rem", "renames", "requeue", "return", "reverse",
894 "select", "separate", "subtype", "synchronized", "tagged", "task",
895 "terminate", "then", "type", "until", "use", "when", "while", "with", "xor",
898 /* ??? would be nice to specify this list via a config file, so that users
899 can create their own dictionary of conflicts. */
900 static const char *c_duplicates
[] = {
901 /* system will cause troubles with System.Address. */
904 /* The following values have other definitions with same name/other
910 "rl_readline_version",
916 /* Return a declaration tree corresponding to TYPE. */
919 get_underlying_decl (tree type
)
921 tree decl
= NULL_TREE
;
923 if (type
== NULL_TREE
)
926 /* type is a declaration. */
930 /* type is a typedef. */
931 if (TYPE_P (type
) && TYPE_NAME (type
) && DECL_P (TYPE_NAME (type
)))
932 decl
= TYPE_NAME (type
);
934 /* TYPE_STUB_DECL has been set for type. */
935 if (TYPE_P (type
) && TYPE_STUB_DECL (type
) &&
936 DECL_P (TYPE_STUB_DECL (type
)))
937 decl
= TYPE_STUB_DECL (type
);
942 /* Return whether TYPE has static fields. */
945 has_static_fields (const_tree type
)
949 for (tmp
= TYPE_FIELDS (type
); tmp
; tmp
= TREE_CHAIN (tmp
))
951 if (DECL_NAME (tmp
) && TREE_STATIC (tmp
))
957 /* Return whether TYPE corresponds to an Ada tagged type (has a dispatch
961 is_tagged_type (const_tree type
)
965 if (!type
|| !RECORD_OR_UNION_TYPE_P (type
))
968 for (tmp
= TYPE_METHODS (type
); tmp
; tmp
= TREE_CHAIN (tmp
))
969 if (DECL_VINDEX (tmp
))
975 /* Generate a legal Ada name from a C NAME, returning a malloc'd string.
976 SPACE_FOUND, if not NULL, is used to indicate whether a space was found in
980 to_ada_name (const char *name
, int *space_found
)
983 int len
= strlen (name
);
986 char *s
= XNEWVEC (char, len
* 2 + 5);
990 *space_found
= false;
992 /* Add trailing "c_" if name is an Ada reserved word. */
993 for (names
= ada_reserved
; *names
; names
++)
994 if (!strcasecmp (name
, *names
))
1003 /* Add trailing "c_" if name is an potential case sensitive duplicate. */
1004 for (names
= c_duplicates
; *names
; names
++)
1005 if (!strcmp (name
, *names
))
1013 for (j
= 0; name
[j
] == '_'; j
++)
1018 else if (*name
== '.' || *name
== '$')
1028 /* Replace unsuitable characters for Ada identifiers. */
1030 for (; j
< len
; j
++)
1035 *space_found
= true;
1039 /* ??? missing some C++ operators. */
1043 if (name
[j
+ 1] == '=')
1058 if (name
[j
+ 1] == '=')
1076 s
[len2
++] = name
[j
] == '&' ? 'a' : name
[j
] == '|' ? 'o' : 'x';
1078 if (name
[j
+ 1] == '=')
1091 if (s
[len2
- 1] != '_')
1094 switch (name
[j
+ 1]) {
1097 switch (name
[j
- 1]) {
1098 case '+': s
[len2
++] = 'p'; break; /* + */
1099 case '-': s
[len2
++] = 'm'; break; /* - */
1100 case '*': s
[len2
++] = 't'; break; /* * */
1101 case '/': s
[len2
++] = 'd'; break; /* / */
1107 switch (name
[j
- 1]) {
1108 case '+': s
[len2
++] = 'p'; break; /* += */
1109 case '-': s
[len2
++] = 'm'; break; /* -= */
1110 case '*': s
[len2
++] = 't'; break; /* *= */
1111 case '/': s
[len2
++] = 'd'; break; /* /= */
1145 c
= name
[j
] == '<' ? 'l' : 'g';
1148 switch (name
[j
+ 1]) {
1174 if (len2
&& s
[len2
- 1] == '_')
1179 s
[len2
++] = name
[j
];
1182 if (s
[len2
- 1] == '_')
1190 /* Return true if DECL refers to a C++ class type for which a
1191 separate enclosing package has been or should be generated. */
1194 separate_class_package (tree decl
)
1198 tree type
= TREE_TYPE (decl
);
1200 && TREE_CODE (type
) == RECORD_TYPE
1201 && (TYPE_METHODS (type
) || has_static_fields (type
));
1207 static bool package_prefix
= true;
1209 /* Dump in BUFFER the name of an identifier NODE of type TYPE, following Ada
1210 syntax. LIMITED_ACCESS indicates whether NODE can be accessed via a limited
1211 'with' clause rather than a regular 'with' clause. */
1214 pp_ada_tree_identifier (pretty_printer
*buffer
, tree node
, tree type
,
1217 const char *name
= IDENTIFIER_POINTER (node
);
1218 int space_found
= false;
1219 char *s
= to_ada_name (name
, &space_found
);
1222 /* If the entity is a type and comes from another file, generate "package"
1225 decl
= get_underlying_decl (type
);
1229 expanded_location xloc
= expand_location (decl_sloc (decl
, false));
1231 if (xloc
.file
&& xloc
.line
)
1233 if (xloc
.file
!= source_file_base
)
1235 switch (TREE_CODE (type
))
1240 case FIXED_POINT_TYPE
:
1242 case REFERENCE_TYPE
:
1247 case QUAL_UNION_TYPE
:
1250 char *s1
= get_ada_package (xloc
.file
);
1254 append_withs (s1
, limited_access
);
1255 pp_string (buffer
, s1
);
1256 pp_character (buffer
, '.');
1265 if (separate_class_package (decl
))
1267 pp_string (buffer
, "Class_");
1268 pp_string (buffer
, s
);
1269 pp_string (buffer
, ".");
1277 if (!strcmp (s
, "short_int"))
1278 pp_string (buffer
, "short");
1279 else if (!strcmp (s
, "short_unsigned_int"))
1280 pp_string (buffer
, "unsigned_short");
1281 else if (!strcmp (s
, "unsigned_int"))
1282 pp_string (buffer
, "unsigned");
1283 else if (!strcmp (s
, "long_int"))
1284 pp_string (buffer
, "long");
1285 else if (!strcmp (s
, "long_unsigned_int"))
1286 pp_string (buffer
, "unsigned_long");
1287 else if (!strcmp (s
, "long_long_int"))
1288 pp_string (buffer
, "Long_Long_Integer");
1289 else if (!strcmp (s
, "long_long_unsigned_int"))
1293 append_withs ("Interfaces.C.Extensions", false);
1294 pp_string (buffer
, "Extensions.unsigned_long_long");
1297 pp_string (buffer
, "unsigned_long_long");
1300 pp_string(buffer
, s
);
1302 if (!strcmp (s
, "bool"))
1306 append_withs ("Interfaces.C.Extensions", false);
1307 pp_string (buffer
, "Extensions.bool");
1310 pp_string (buffer
, "bool");
1313 pp_string(buffer
, s
);
1318 /* Dump in BUFFER the assembly name of T. */
1321 pp_asm_name (pretty_printer
*buffer
, tree t
)
1323 tree name
= DECL_ASSEMBLER_NAME (t
);
1324 char *ada_name
= XALLOCAVEC (char, IDENTIFIER_LENGTH (name
) + 1), *s
;
1325 const char *ident
= IDENTIFIER_POINTER (name
);
1327 for (s
= ada_name
; *ident
; ident
++)
1331 else if (*ident
!= '*')
1336 pp_string (buffer
, ada_name
);
1339 /* Dump in BUFFER the name of a DECL node if set, following Ada syntax.
1340 LIMITED_ACCESS indicates whether NODE can be accessed via a limited
1341 'with' clause rather than a regular 'with' clause. */
1344 dump_ada_decl_name (pretty_printer
*buffer
, tree decl
, int limited_access
)
1346 if (DECL_NAME (decl
))
1347 pp_ada_tree_identifier (buffer
, DECL_NAME (decl
), decl
, limited_access
);
1350 tree type_name
= TYPE_NAME (TREE_TYPE (decl
));
1354 pp_string (buffer
, "anon");
1355 if (TREE_CODE (decl
) == FIELD_DECL
)
1356 pp_scalar (buffer
, "%d", DECL_UID (decl
));
1358 pp_scalar (buffer
, "%d", TYPE_UID (TREE_TYPE (decl
)));
1360 else if (TREE_CODE (type_name
) == IDENTIFIER_NODE
)
1361 pp_ada_tree_identifier (buffer
, type_name
, decl
, limited_access
);
1365 /* Dump in BUFFER a name based on both T1 and T2, followed by S. */
1368 dump_ada_double_name (pretty_printer
*buffer
, tree t1
, tree t2
, const char *s
)
1371 pp_ada_tree_identifier (buffer
, DECL_NAME (t1
), t1
, false);
1374 pp_string (buffer
, "anon");
1375 pp_scalar (buffer
, "%d", TYPE_UID (TREE_TYPE (t1
)));
1378 pp_character (buffer
, '_');
1381 pp_ada_tree_identifier (buffer
, DECL_NAME (t2
), t2
, false);
1384 pp_string (buffer
, "anon");
1385 pp_scalar (buffer
, "%d", TYPE_UID (TREE_TYPE (t2
)));
1388 pp_string (buffer
, s
);
1391 /* Dump in BUFFER pragma Import C/CPP on a given node T. */
1394 dump_ada_import (pretty_printer
*buffer
, tree t
)
1396 const char *name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t
));
1397 int is_stdcall
= TREE_CODE (t
) == FUNCTION_DECL
&&
1398 lookup_attribute ("stdcall", TYPE_ATTRIBUTES (TREE_TYPE (t
)));
1401 pp_string (buffer
, "pragma Import (Stdcall, ");
1402 else if (name
[0] == '_' && name
[1] == 'Z')
1403 pp_string (buffer
, "pragma Import (CPP, ");
1405 pp_string (buffer
, "pragma Import (C, ");
1407 dump_ada_decl_name (buffer
, t
, false);
1408 pp_string (buffer
, ", \"");
1411 pp_string (buffer
, IDENTIFIER_POINTER (DECL_NAME (t
)));
1413 pp_asm_name (buffer
, t
);
1415 pp_string (buffer
, "\");");
1418 /* Check whether T and its type have different names, and append "the_"
1419 otherwise in BUFFER. */
1422 check_name (pretty_printer
*buffer
, tree t
)
1425 tree tmp
= TREE_TYPE (t
);
1427 while (TREE_CODE (tmp
) == POINTER_TYPE
&& !TYPE_NAME (tmp
))
1428 tmp
= TREE_TYPE (tmp
);
1430 if (TREE_CODE (tmp
) != FUNCTION_TYPE
)
1432 if (TREE_CODE (tmp
) == IDENTIFIER_NODE
)
1433 s
= IDENTIFIER_POINTER (tmp
);
1434 else if (!TYPE_NAME (tmp
))
1436 else if (TREE_CODE (TYPE_NAME (tmp
)) == IDENTIFIER_NODE
)
1437 s
= IDENTIFIER_POINTER (TYPE_NAME (tmp
));
1439 s
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (tmp
)));
1441 if (!strcasecmp (IDENTIFIER_POINTER (DECL_NAME (t
)), s
))
1442 pp_string (buffer
, "the_");
1446 /* Dump in BUFFER a function declaration FUNC with Ada syntax.
1447 IS_METHOD indicates whether FUNC is a C++ method.
1448 IS_CONSTRUCTOR whether FUNC is a C++ constructor.
1449 IS_DESTRUCTOR whether FUNC is a C++ destructor.
1450 SPC is the current indentation level. */
1453 dump_ada_function_declaration (pretty_printer
*buffer
, tree func
,
1454 int is_method
, int is_constructor
,
1455 int is_destructor
, int spc
)
1458 const tree node
= TREE_TYPE (func
);
1460 int num
= 0, num_args
= 0, have_args
= true, have_ellipsis
= false;
1462 /* Compute number of arguments. */
1463 arg
= TYPE_ARG_TYPES (node
);
1467 while (TREE_CHAIN (arg
) && arg
!= error_mark_node
)
1470 arg
= TREE_CHAIN (arg
);
1473 if (TREE_CODE (TREE_VALUE (arg
)) != VOID_TYPE
)
1476 have_ellipsis
= true;
1487 newline_and_indent (buffer
, spc
+ 1);
1492 pp_character (buffer
, '(');
1495 if (TREE_CODE (func
) == FUNCTION_DECL
)
1496 arg
= DECL_ARGUMENTS (func
);
1500 if (arg
== NULL_TREE
)
1503 arg
= TYPE_ARG_TYPES (node
);
1505 if (arg
&& TREE_CODE (TREE_VALUE (arg
)) == VOID_TYPE
)
1510 arg
= TREE_CHAIN (arg
);
1512 /* Print the argument names (if available) & types. */
1514 for (num
= 1; num
<= num_args
; num
++)
1518 if (DECL_NAME (arg
))
1520 check_name (buffer
, arg
);
1521 pp_ada_tree_identifier (buffer
, DECL_NAME (arg
), 0, false);
1522 pp_string (buffer
, " : ");
1526 sprintf (buf
, "arg%d : ", num
);
1527 pp_string (buffer
, buf
);
1530 dump_generic_ada_node
1531 (buffer
, TREE_TYPE (arg
), node
, NULL
, spc
, 0, true);
1535 sprintf (buf
, "arg%d : ", num
);
1536 pp_string (buffer
, buf
);
1537 dump_generic_ada_node
1538 (buffer
, TREE_VALUE (arg
), node
, NULL
, spc
, 0, true);
1541 if (TREE_TYPE (arg
) && TREE_TYPE (TREE_TYPE (arg
))
1542 && is_tagged_type (TREE_TYPE (TREE_TYPE (arg
))))
1545 || (num
!= 1 || (!DECL_VINDEX (func
) && !is_constructor
)))
1546 pp_string (buffer
, "'Class");
1549 arg
= TREE_CHAIN (arg
);
1553 pp_character (buffer
, ';');
1556 newline_and_indent (buffer
, spc
+ INDENT_INCR
);
1564 pp_string (buffer
, " -- , ...");
1565 newline_and_indent (buffer
, spc
+ INDENT_INCR
);
1569 pp_character (buffer
, ')');
1573 /* Dump in BUFFER all the domains associated with an array NODE,
1574 using Ada syntax. SPC is the current indentation level. */
1577 dump_ada_array_domains (pretty_printer
*buffer
, tree node
, int spc
)
1580 pp_character (buffer
, '(');
1582 for (; TREE_CODE (node
) == ARRAY_TYPE
; node
= TREE_TYPE (node
))
1584 tree domain
= TYPE_DOMAIN (node
);
1588 tree min
= TYPE_MIN_VALUE (domain
);
1589 tree max
= TYPE_MAX_VALUE (domain
);
1592 pp_string (buffer
, ", ");
1596 dump_generic_ada_node (buffer
, min
, NULL_TREE
, NULL
, spc
, 0, true);
1597 pp_string (buffer
, " .. ");
1599 /* If the upper bound is zero, gcc may generate a NULL_TREE
1600 for TYPE_MAX_VALUE rather than an integer_cst. */
1602 dump_generic_ada_node (buffer
, max
, NULL_TREE
, NULL
, spc
, 0, true);
1604 pp_string (buffer
, "0");
1607 pp_string (buffer
, "size_t");
1609 pp_character (buffer
, ')');
1612 /* Dump in BUFFER file:line information related to NODE. */
1615 dump_sloc (pretty_printer
*buffer
, tree node
)
1617 expanded_location xloc
;
1621 if (TREE_CODE_CLASS (TREE_CODE (node
)) == tcc_declaration
)
1622 xloc
= expand_location (DECL_SOURCE_LOCATION (node
));
1623 else if (EXPR_HAS_LOCATION (node
))
1624 xloc
= expand_location (EXPR_LOCATION (node
));
1628 pp_string (buffer
, xloc
.file
);
1629 pp_string (buffer
, ":");
1630 pp_decimal_int (buffer
, xloc
.line
);
1634 /* Return true if T designates a one dimension array of "char". */
1637 is_char_array (tree t
)
1642 /* Retrieve array's type. */
1644 while (TREE_CODE (TREE_TYPE (tmp
)) == ARRAY_TYPE
)
1647 tmp
= TREE_TYPE (tmp
);
1650 tmp
= TREE_TYPE (tmp
);
1651 return num_dim
== 1 && TREE_CODE (tmp
) == INTEGER_TYPE
1652 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (tmp
))), "char");
1655 /* Dump in BUFFER an array type T in Ada syntax. Assume that the "type"
1656 keyword and name have already been printed. SPC is the indentation
1660 dump_ada_array_type (pretty_printer
*buffer
, tree t
, int spc
)
1663 bool char_array
= is_char_array (t
);
1665 /* Special case char arrays. */
1668 pp_string (buffer
, "Interfaces.C.char_array ");
1671 pp_string (buffer
, "array ");
1673 /* Print the dimensions. */
1674 dump_ada_array_domains (buffer
, TREE_TYPE (t
), spc
);
1676 /* Retrieve array's type. */
1677 tmp
= TREE_TYPE (t
);
1678 while (TREE_CODE (TREE_TYPE (tmp
)) == ARRAY_TYPE
)
1679 tmp
= TREE_TYPE (tmp
);
1681 /* Print array's type. */
1684 pp_string (buffer
, " of ");
1686 if (TREE_CODE (TREE_TYPE (tmp
)) != POINTER_TYPE
)
1687 pp_string (buffer
, "aliased ");
1689 dump_generic_ada_node
1690 (buffer
, TREE_TYPE (tmp
), TREE_TYPE (t
), NULL
, spc
, false, true);
1694 /* Dump in BUFFER type names associated with a template, each prepended with
1695 '_'. TYPES is the TREE_PURPOSE of a DECL_TEMPLATE_INSTANTIATIONS.
1696 CPP_CHECK is used to perform C++ queries on nodes.
1697 SPC is the indentation level. */
1700 dump_template_types (pretty_printer
*buffer
, tree types
,
1701 int (*cpp_check
)(tree
, cpp_operation
), int spc
)
1704 size_t len
= TREE_VEC_LENGTH (types
);
1706 for (i
= 0; i
< len
; i
++)
1708 tree elem
= TREE_VEC_ELT (types
, i
);
1709 pp_character (buffer
, '_');
1710 if (!dump_generic_ada_node (buffer
, elem
, 0, cpp_check
, spc
, false, true))
1712 pp_string (buffer
, "unknown");
1713 pp_scalar (buffer
, "%lu", (unsigned long) TREE_HASH (elem
));
1718 /* Dump in BUFFER the contents of all class instantiations associated with
1719 a given template T. CPP_CHECK is used to perform C++ queries on nodes.
1720 SPC is the indentation level. */
1723 dump_ada_template (pretty_printer
*buffer
, tree t
,
1724 int (*cpp_check
)(tree
, cpp_operation
), int spc
)
1726 /* DECL_VINDEX is DECL_TEMPLATE_INSTANTIATIONS in this context. */
1727 tree inst
= DECL_VINDEX (t
);
1728 /* DECL_RESULT_FLD is DECL_TEMPLATE_RESULT in this context. */
1729 tree result
= DECL_RESULT_FLD (t
);
1732 /* Don't look at template declarations declaring something coming from
1733 another file. This can occur for template friend declarations. */
1734 if (LOCATION_FILE (decl_sloc (result
, false))
1735 != LOCATION_FILE (decl_sloc (t
, false)))
1738 while (inst
&& inst
!= error_mark_node
)
1740 tree types
= TREE_PURPOSE (inst
);
1741 tree instance
= TREE_VALUE (inst
);
1743 if (TREE_VEC_LENGTH (types
) == 0)
1746 if (!TYPE_P (instance
) || !TYPE_METHODS (instance
))
1751 pp_string (buffer
, "package ");
1752 package_prefix
= false;
1753 dump_generic_ada_node (buffer
, instance
, t
, cpp_check
, spc
, false, true);
1754 dump_template_types (buffer
, types
, cpp_check
, spc
);
1755 pp_string (buffer
, " is");
1757 newline_and_indent (buffer
, spc
);
1759 TREE_VISITED (get_underlying_decl (instance
)) = 1;
1760 pp_string (buffer
, "type ");
1761 dump_generic_ada_node (buffer
, instance
, t
, cpp_check
, spc
, false, true);
1762 package_prefix
= true;
1764 if (is_tagged_type (instance
))
1765 pp_string (buffer
, " is tagged limited ");
1767 pp_string (buffer
, " is limited ");
1769 dump_generic_ada_node (buffer
, instance
, t
, cpp_check
, spc
, false, false);
1770 pp_newline (buffer
);
1772 newline_and_indent (buffer
, spc
);
1774 pp_string (buffer
, "end;");
1775 newline_and_indent (buffer
, spc
);
1776 pp_string (buffer
, "use ");
1777 package_prefix
= false;
1778 dump_generic_ada_node (buffer
, instance
, t
, cpp_check
, spc
, false, true);
1779 dump_template_types (buffer
, types
, cpp_check
, spc
);
1780 package_prefix
= true;
1781 pp_semicolon (buffer
);
1782 pp_newline (buffer
);
1783 pp_newline (buffer
);
1785 inst
= TREE_CHAIN (inst
);
1788 return num_inst
> 0;
1791 /* Return true if NODE is a simple enum types, that can be mapped to an
1792 Ada enum type directly. */
1795 is_simple_enum (tree node
)
1797 unsigned HOST_WIDE_INT count
= 0;
1800 for (value
= TYPE_VALUES (node
); value
; value
= TREE_CHAIN (value
))
1802 tree int_val
= TREE_VALUE (value
);
1804 if (TREE_CODE (int_val
) != INTEGER_CST
)
1805 int_val
= DECL_INITIAL (int_val
);
1807 if (!host_integerp (int_val
, 0))
1809 else if (TREE_INT_CST_LOW (int_val
) != count
)
1818 static bool in_function
= true;
1819 static bool bitfield_used
= false;
1821 /* Recursively dump in BUFFER Ada declarations corresponding to NODE of type
1822 TYPE. CPP_CHECK is used to perform C++ queries on nodes. SPC is the
1823 indentation level. LIMITED_ACCESS indicates whether NODE can be referenced
1824 via a "limited with" clause. NAME_ONLY indicates whether we should only
1825 dump the name of NODE, instead of its full declaration. */
1828 dump_generic_ada_node (pretty_printer
*buffer
, tree node
, tree type
,
1829 int (*cpp_check
)(tree
, cpp_operation
), int spc
,
1830 int limited_access
, bool name_only
)
1832 if (node
== NULL_TREE
)
1835 switch (TREE_CODE (node
))
1838 pp_string (buffer
, "<<< error >>>");
1841 case IDENTIFIER_NODE
:
1842 pp_ada_tree_identifier (buffer
, node
, type
, limited_access
);
1846 pp_string (buffer
, "--- unexpected node: TREE_LIST");
1850 dump_generic_ada_node
1851 (buffer
, BINFO_TYPE (node
), type
, cpp_check
,
1852 spc
, limited_access
, name_only
);
1855 pp_string (buffer
, "--- unexpected node: TREE_VEC");
1861 append_withs ("System", false);
1862 pp_string (buffer
, "System.Address");
1865 pp_string (buffer
, "address");
1869 pp_string (buffer
, "<vector>");
1873 pp_string (buffer
, "<complex>");
1878 dump_generic_ada_node
1879 (buffer
, TYPE_NAME (node
), node
, cpp_check
, spc
, 0, true);
1882 tree value
= TYPE_VALUES (node
);
1884 if (is_simple_enum (node
))
1888 newline_and_indent (buffer
, spc
- 1);
1889 pp_string (buffer
, "(");
1890 for (; value
; value
= TREE_CHAIN (value
))
1896 pp_string (buffer
, ",");
1897 newline_and_indent (buffer
, spc
);
1900 pp_ada_tree_identifier
1901 (buffer
, TREE_PURPOSE (value
), node
, false);
1903 pp_string (buffer
, ");");
1905 newline_and_indent (buffer
, spc
);
1906 pp_string (buffer
, "pragma Convention (C, ");
1907 dump_generic_ada_node
1908 (buffer
, DECL_NAME (type
) ? type
: TYPE_NAME (node
), type
,
1909 cpp_check
, spc
, 0, true);
1910 pp_string (buffer
, ")");
1914 pp_string (buffer
, "unsigned");
1915 for (; value
; value
= TREE_CHAIN (value
))
1917 pp_semicolon (buffer
);
1918 newline_and_indent (buffer
, spc
);
1920 pp_ada_tree_identifier
1921 (buffer
, TREE_PURPOSE (value
), node
, false);
1922 pp_string (buffer
, " : constant ");
1924 dump_generic_ada_node
1925 (buffer
, DECL_NAME (type
) ? type
: TYPE_NAME (node
), type
,
1926 cpp_check
, spc
, 0, true);
1928 pp_string (buffer
, " := ");
1929 dump_generic_ada_node
1931 TREE_CODE (TREE_VALUE (value
)) == INTEGER_CST
?
1932 TREE_VALUE (value
) : DECL_INITIAL (TREE_VALUE (value
)),
1933 node
, cpp_check
, spc
, false, true);
1941 case FIXED_POINT_TYPE
:
1944 enum tree_code_class tclass
;
1946 tclass
= TREE_CODE_CLASS (TREE_CODE (node
));
1948 if (tclass
== tcc_declaration
)
1950 if (DECL_NAME (node
))
1951 pp_ada_tree_identifier
1952 (buffer
, DECL_NAME (node
), 0, limited_access
);
1954 pp_string (buffer
, "<unnamed type decl>");
1956 else if (tclass
== tcc_type
)
1958 if (TYPE_NAME (node
))
1960 if (TREE_CODE (TYPE_NAME (node
)) == IDENTIFIER_NODE
)
1961 pp_ada_tree_identifier (buffer
, TYPE_NAME (node
),
1962 node
, limited_access
);
1963 else if (TREE_CODE (TYPE_NAME (node
)) == TYPE_DECL
1964 && DECL_NAME (TYPE_NAME (node
)))
1965 dump_ada_decl_name (buffer
, TYPE_NAME (node
), limited_access
);
1967 pp_string (buffer
, "<unnamed type>");
1969 else if (TREE_CODE (node
) == INTEGER_TYPE
)
1971 append_withs ("Interfaces.C.Extensions", false);
1972 bitfield_used
= true;
1974 if (TYPE_PRECISION (node
) == 1)
1975 pp_string (buffer
, "Extensions.Unsigned_1");
1978 pp_string (buffer
, (TYPE_UNSIGNED (node
)
1979 ? "Extensions.Unsigned_"
1980 : "Extensions.Signed_"));
1981 pp_decimal_int (buffer
, TYPE_PRECISION (node
));
1985 pp_string (buffer
, "<unnamed type>");
1991 case REFERENCE_TYPE
:
1992 if (name_only
&& TYPE_NAME (node
))
1993 dump_generic_ada_node
1994 (buffer
, TYPE_NAME (node
), node
, cpp_check
,
1995 spc
, limited_access
, true);
1997 else if (TREE_CODE (TREE_TYPE (node
)) == FUNCTION_TYPE
)
1999 tree fnode
= TREE_TYPE (node
);
2001 bool prev_in_function
= in_function
;
2003 if (VOID_TYPE_P (TREE_TYPE (fnode
)))
2005 is_function
= false;
2006 pp_string (buffer
, "access procedure");
2011 pp_string (buffer
, "access function");
2014 in_function
= is_function
;
2015 dump_ada_function_declaration
2016 (buffer
, node
, false, false, false, spc
+ INDENT_INCR
);
2017 in_function
= prev_in_function
;
2021 pp_string (buffer
, " return ");
2022 dump_generic_ada_node
2023 (buffer
, TREE_TYPE (fnode
), type
, cpp_check
, spc
, 0, true);
2026 /* If we are dumping the full type, it means we are part of a
2027 type definition and need also a Convention C pragma. */
2030 pp_semicolon (buffer
);
2031 newline_and_indent (buffer
, spc
);
2032 pp_string (buffer
, "pragma Convention (C, ");
2033 dump_generic_ada_node
2034 (buffer
, type
, 0, cpp_check
, spc
, false, true);
2035 pp_string (buffer
, ")");
2040 int is_access
= false;
2041 unsigned int quals
= TYPE_QUALS (TREE_TYPE (node
));
2043 if (VOID_TYPE_P (TREE_TYPE (node
)))
2046 pp_string (buffer
, "new ");
2049 append_withs ("System", false);
2050 pp_string (buffer
, "System.Address");
2053 pp_string (buffer
, "address");
2057 if (TREE_CODE (node
) == POINTER_TYPE
2058 && TREE_CODE (TREE_TYPE (node
)) == INTEGER_TYPE
2060 (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME
2061 (TREE_TYPE (node
)))), "char"))
2064 pp_string (buffer
, "new ");
2068 pp_string (buffer
, "Interfaces.C.Strings.chars_ptr");
2069 append_withs ("Interfaces.C.Strings", false);
2072 pp_string (buffer
, "chars_ptr");
2076 /* For now, handle all access-to-access or
2077 access-to-unknown-structs as opaque system.address. */
2079 tree type_name
= TYPE_NAME (TREE_TYPE (node
));
2080 const_tree typ2
= !type
||
2081 DECL_P (type
) ? type
: TYPE_NAME (type
);
2082 const_tree underlying_type
=
2083 get_underlying_decl (TREE_TYPE (node
));
2085 if (TREE_CODE (TREE_TYPE (node
)) == POINTER_TYPE
2086 /* Pointer to pointer. */
2088 || (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node
))
2089 && (!underlying_type
2090 || !TYPE_FIELDS (TREE_TYPE (underlying_type
))))
2091 /* Pointer to opaque structure. */
2093 || underlying_type
== NULL_TREE
2095 && !TREE_VISITED (underlying_type
)
2096 && !TREE_VISITED (type_name
)
2097 && !is_tagged_type (TREE_TYPE (node
))
2098 && DECL_SOURCE_FILE (underlying_type
)
2099 == source_file_base
)
2100 || (type_name
&& typ2
2101 && DECL_P (underlying_type
)
2103 && decl_sloc (underlying_type
, true)
2104 > decl_sloc (typ2
, true)
2105 && DECL_SOURCE_FILE (underlying_type
)
2106 == DECL_SOURCE_FILE (typ2
)))
2110 append_withs ("System", false);
2112 pp_string (buffer
, "new ");
2113 pp_string (buffer
, "System.Address");
2116 pp_string (buffer
, "address");
2120 if (!package_prefix
)
2121 pp_string (buffer
, "access");
2122 else if (AGGREGATE_TYPE_P (TREE_TYPE (node
)))
2124 if (!type
|| TREE_CODE (type
) != FUNCTION_DECL
)
2126 pp_string (buffer
, "access ");
2129 if (quals
& TYPE_QUAL_CONST
)
2130 pp_string (buffer
, "constant ");
2131 else if (!name_only
)
2132 pp_string (buffer
, "all ");
2134 else if (quals
& TYPE_QUAL_CONST
)
2135 pp_string (buffer
, "in ");
2136 else if (in_function
)
2139 pp_string (buffer
, "access ");
2144 pp_string (buffer
, "access ");
2145 /* ??? should be configurable: access or in out. */
2151 pp_string (buffer
, "access ");
2154 pp_string (buffer
, "all ");
2157 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node
))
2158 && type_name
!= NULL_TREE
)
2159 dump_generic_ada_node
2161 TREE_TYPE (node
), cpp_check
, spc
, is_access
, true);
2163 dump_generic_ada_node
2164 (buffer
, TREE_TYPE (node
), TREE_TYPE (node
),
2165 cpp_check
, spc
, 0, true);
2173 dump_generic_ada_node
2174 (buffer
, TYPE_NAME (node
), node
, cpp_check
,
2175 spc
, limited_access
, true);
2177 dump_ada_array_type (buffer
, node
, spc
);
2182 case QUAL_UNION_TYPE
:
2185 if (TYPE_NAME (node
))
2186 dump_generic_ada_node
2187 (buffer
, TYPE_NAME (node
), node
, cpp_check
,
2188 spc
, limited_access
, true);
2191 pp_string (buffer
, "anon_");
2192 pp_scalar (buffer
, "%d", TYPE_UID (node
));
2196 print_ada_struct_decl
2197 (buffer
, node
, type
, cpp_check
, spc
, true);
2201 /* We treat the upper half of the sizetype range as negative. This
2202 is consistent with the internal treatment and makes it possible
2203 to generate the (0 .. -1) range for flexible array members. */
2204 if (TREE_TYPE (node
) == sizetype
)
2205 node
= fold_convert (ssizetype
, node
);
2206 if (host_integerp (node
, 0))
2207 pp_wide_integer (buffer
, TREE_INT_CST_LOW (node
));
2208 else if (host_integerp (node
, 1))
2209 pp_unsigned_wide_integer (buffer
, TREE_INT_CST_LOW (node
));
2213 unsigned HOST_WIDE_INT low
= TREE_INT_CST_LOW (val
);
2214 HOST_WIDE_INT high
= TREE_INT_CST_HIGH (val
);
2216 if (tree_int_cst_sgn (val
) < 0)
2218 pp_character (buffer
, '-');
2219 high
= ~high
+ !low
;
2222 sprintf (pp_buffer (buffer
)->digit_buffer
,
2223 ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX
,
2224 (unsigned HOST_WIDE_INT
) high
, low
);
2225 pp_string (buffer
, pp_buffer (buffer
)->digit_buffer
);
2238 dump_ada_decl_name (buffer
, node
, limited_access
);
2242 if (DECL_IS_BUILTIN (node
))
2244 /* Don't print the declaration of built-in types. */
2248 /* If we're in the middle of a declaration, defaults to
2252 append_withs ("System", false);
2253 pp_string (buffer
, "System.Address");
2256 pp_string (buffer
, "address");
2262 dump_ada_decl_name (buffer
, node
, limited_access
);
2265 if (is_tagged_type (TREE_TYPE (node
)))
2267 tree tmp
= TYPE_FIELDS (TREE_TYPE (node
));
2270 /* Look for ancestors. */
2271 for (; tmp
; tmp
= TREE_CHAIN (tmp
))
2273 if (!DECL_NAME (tmp
) && is_tagged_type (TREE_TYPE (tmp
)))
2277 pp_string (buffer
, "limited new ");
2281 pp_string (buffer
, " and ");
2284 (buffer
, TYPE_NAME (TREE_TYPE (tmp
)), false);
2288 pp_string (buffer
, first
? "tagged limited " : " with ");
2290 else if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node
))
2291 && TYPE_METHODS (TREE_TYPE (node
)))
2292 pp_string (buffer
, "limited ");
2294 dump_generic_ada_node
2295 (buffer
, TREE_TYPE (node
), type
, cpp_check
, spc
, false, false);
2302 case NAMESPACE_DECL
:
2303 dump_ada_decl_name (buffer
, node
, false);
2307 /* Ignore other nodes (e.g. expressions). */
2314 /* Dump in BUFFER NODE's methods. CPP_CHECK is used to perform C++ queries on
2315 nodes. SPC is the indentation level. */
2318 print_ada_methods (pretty_printer
*buffer
, tree node
,
2319 int (*cpp_check
)(tree
, cpp_operation
), int spc
)
2321 tree tmp
= TYPE_METHODS (node
);
2326 pp_semicolon (buffer
);
2328 for (; tmp
; tmp
= TREE_CHAIN (tmp
))
2332 pp_newline (buffer
);
2333 pp_newline (buffer
);
2335 res
= print_ada_declaration (buffer
, tmp
, node
, cpp_check
, spc
);
2340 /* Dump in BUFFER anonymous types nested inside T's definition.
2341 PARENT is the parent node of T.
2342 FORWARD indicates whether a forward declaration of T should be generated.
2343 CPP_CHECK is used to perform C++ queries on
2344 nodes. SPC is the indentation level. */
2347 dump_nested_types (pretty_printer
*buffer
, tree t
, tree parent
, bool forward
,
2348 int (*cpp_check
)(tree
, cpp_operation
), int spc
)
2350 tree field
, outer
, decl
;
2352 /* Avoid recursing over the same tree. */
2353 if (TREE_VISITED (t
))
2356 /* Find possible anonymous arrays/unions/structs recursively. */
2358 outer
= TREE_TYPE (t
);
2360 if (outer
== NULL_TREE
)
2365 pp_string (buffer
, "type ");
2366 dump_generic_ada_node
2367 (buffer
, t
, t
, cpp_check
, spc
, false, true);
2368 pp_semicolon (buffer
);
2369 newline_and_indent (buffer
, spc
);
2370 TREE_VISITED (t
) = 1;
2373 field
= TYPE_FIELDS (outer
);
2376 if ((TREE_TYPE (field
) != outer
2377 || (TREE_CODE (TREE_TYPE (field
)) == POINTER_TYPE
2378 && TREE_TYPE (TREE_TYPE (field
)) != outer
))
2379 && (!TYPE_NAME (TREE_TYPE (field
))
2380 || (TREE_CODE (field
) == TYPE_DECL
2381 && DECL_NAME (field
) != DECL_NAME (t
)
2382 && TYPE_NAME (TREE_TYPE (field
)) != TYPE_NAME (outer
))))
2384 switch (TREE_CODE (TREE_TYPE (field
)))
2387 decl
= TREE_TYPE (TREE_TYPE (field
));
2389 if (TREE_CODE (decl
) == FUNCTION_TYPE
)
2390 for (decl
= TREE_TYPE (decl
);
2391 decl
&& TREE_CODE (decl
) == POINTER_TYPE
;
2392 decl
= TREE_TYPE (decl
))
2395 decl
= get_underlying_decl (decl
);
2399 && decl_sloc (decl
, true) > decl_sloc (t
, true)
2400 && DECL_SOURCE_FILE (decl
) == DECL_SOURCE_FILE (t
)
2401 && !TREE_VISITED (decl
)
2402 && !DECL_IS_BUILTIN (decl
)
2403 && (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl
))
2404 || TYPE_FIELDS (TREE_TYPE (decl
))))
2406 /* Generate forward declaration. */
2408 pp_string (buffer
, "type ");
2409 dump_generic_ada_node
2410 (buffer
, decl
, 0, cpp_check
, spc
, false, true);
2411 pp_semicolon (buffer
);
2412 newline_and_indent (buffer
, spc
);
2414 /* Ensure we do not generate duplicate forward
2415 declarations for this type. */
2416 TREE_VISITED (decl
) = 1;
2421 /* Special case char arrays. */
2422 if (is_char_array (field
))
2423 pp_string (buffer
, "sub");
2425 pp_string (buffer
, "type ");
2426 dump_ada_double_name (buffer
, parent
, field
, "_array is ");
2427 dump_ada_array_type (buffer
, field
, spc
);
2428 pp_semicolon (buffer
);
2429 newline_and_indent (buffer
, spc
);
2433 TREE_VISITED (t
) = 1;
2434 dump_nested_types (buffer
, field
, t
, false, cpp_check
, spc
);
2436 pp_string (buffer
, "type ");
2438 if (TYPE_NAME (TREE_TYPE (field
)))
2440 dump_generic_ada_node
2441 (buffer
, TYPE_NAME (TREE_TYPE (field
)), 0, cpp_check
,
2443 pp_string (buffer
, " (discr : unsigned := 0) is ");
2444 print_ada_struct_decl
2445 (buffer
, TREE_TYPE (field
), t
, cpp_check
, spc
, false);
2447 pp_string (buffer
, "pragma Convention (C_Pass_By_Copy, ");
2448 dump_generic_ada_node
2449 (buffer
, TREE_TYPE (field
), 0, cpp_check
,
2451 pp_string (buffer
, ");");
2452 newline_and_indent (buffer
, spc
);
2454 pp_string (buffer
, "pragma Unchecked_Union (");
2455 dump_generic_ada_node
2456 (buffer
, TREE_TYPE (field
), 0, cpp_check
,
2458 pp_string (buffer
, ");");
2462 dump_ada_double_name
2463 (buffer
, parent
, field
,
2464 "_union (discr : unsigned := 0) is ");
2465 print_ada_struct_decl
2466 (buffer
, TREE_TYPE (field
), t
, cpp_check
, spc
, false);
2467 pp_string (buffer
, "pragma Convention (C_Pass_By_Copy, ");
2468 dump_ada_double_name (buffer
, parent
, field
, "_union);");
2469 newline_and_indent (buffer
, spc
);
2471 pp_string (buffer
, "pragma Unchecked_Union (");
2472 dump_ada_double_name (buffer
, parent
, field
, "_union);");
2475 newline_and_indent (buffer
, spc
);
2479 if (TYPE_NAME (TREE_TYPE (t
)) && !TREE_VISITED (t
))
2481 pp_string (buffer
, "type ");
2482 dump_generic_ada_node
2483 (buffer
, t
, parent
, 0, spc
, false, true);
2484 pp_semicolon (buffer
);
2485 newline_and_indent (buffer
, spc
);
2488 TREE_VISITED (t
) = 1;
2489 dump_nested_types (buffer
, field
, t
, false, cpp_check
, spc
);
2490 pp_string (buffer
, "type ");
2492 if (TYPE_NAME (TREE_TYPE (field
)))
2494 dump_generic_ada_node
2495 (buffer
, TREE_TYPE (field
), 0, cpp_check
,
2497 pp_string (buffer
, " is ");
2498 print_ada_struct_decl
2499 (buffer
, TREE_TYPE (field
), t
, cpp_check
, spc
, false);
2500 pp_string (buffer
, "pragma Convention (C_Pass_By_Copy, ");
2501 dump_generic_ada_node
2502 (buffer
, TREE_TYPE (field
), 0, cpp_check
,
2504 pp_string (buffer
, ");");
2508 dump_ada_double_name
2509 (buffer
, parent
, field
, "_struct is ");
2510 print_ada_struct_decl
2511 (buffer
, TREE_TYPE (field
), t
, cpp_check
, spc
, false);
2512 pp_string (buffer
, "pragma Convention (C_Pass_By_Copy, ");
2513 dump_ada_double_name (buffer
, parent
, field
, "_struct);");
2516 newline_and_indent (buffer
, spc
);
2523 field
= TREE_CHAIN (field
);
2526 TREE_VISITED (t
) = 1;
2529 /* Dump in BUFFER destructor spec corresponding to T. */
2532 print_destructor (pretty_printer
*buffer
, tree t
)
2534 const char *s
= IDENTIFIER_POINTER (DECL_NAME (t
));
2537 for (s
+= 2; *s
!= ' '; s
++)
2538 pp_character (buffer
, *s
);
2541 pp_string (buffer
, "Delete_");
2542 pp_ada_tree_identifier (buffer
, DECL_NAME (t
), t
, false);
2546 /* Return the name of type T. */
2551 tree n
= TYPE_NAME (t
);
2553 if (TREE_CODE (n
) == IDENTIFIER_NODE
)
2554 return IDENTIFIER_POINTER (n
);
2556 return IDENTIFIER_POINTER (DECL_NAME (n
));
2559 /* Print in BUFFER the declaration of a variable T of type TYPE in Ada syntax.
2560 CPP_CHECK is used to perform C++ queries on nodes. SPC is the indentation
2561 level. Return 1 if a declaration was printed, 0 otherwise. */
2564 print_ada_declaration (pretty_printer
*buffer
, tree t
, tree type
,
2565 int (*cpp_check
)(tree
, cpp_operation
), int spc
)
2567 int is_var
= 0, need_indent
= 0;
2568 int is_class
= false;
2569 tree name
= TYPE_NAME (TREE_TYPE (t
));
2570 tree decl_name
= DECL_NAME (t
);
2571 tree orig
= NULL_TREE
;
2573 if (cpp_check
&& cpp_check (t
, IS_TEMPLATE
))
2574 return dump_ada_template (buffer
, t
, cpp_check
, spc
);
2576 if (TREE_CODE (t
) == CONST_DECL
&& TREE_CODE (TREE_TYPE (t
)) == ENUMERAL_TYPE
)
2577 /* Skip enumeral values: will be handled as part of the type itself. */
2580 if (TREE_CODE (t
) == TYPE_DECL
)
2582 orig
= DECL_ORIGINAL_TYPE (t
);
2584 if (orig
&& TYPE_STUB_DECL (orig
))
2586 tree stub
= TYPE_STUB_DECL (orig
);
2587 tree typ
= TREE_TYPE (stub
);
2589 if (TYPE_NAME (typ
))
2591 /* If types have same representation, and same name (ignoring
2592 casing), then ignore the second type. */
2593 if (type_name (typ
) == type_name (TREE_TYPE (t
))
2594 || !strcasecmp (type_name (typ
), type_name (TREE_TYPE (t
))))
2599 if (RECORD_OR_UNION_TYPE_P (typ
) && !TYPE_FIELDS (typ
))
2601 pp_string (buffer
, "-- skipped empty struct ");
2602 dump_generic_ada_node (buffer
, t
, type
, 0, spc
, false, true);
2606 if (!TREE_VISITED (stub
)
2607 && DECL_SOURCE_FILE (stub
) == source_file_base
)
2609 (buffer
, stub
, stub
, true, cpp_check
, spc
);
2611 pp_string (buffer
, "subtype ");
2612 dump_generic_ada_node (buffer
, t
, type
, 0, spc
, false, true);
2613 pp_string (buffer
, " is ");
2614 dump_generic_ada_node
2615 (buffer
, typ
, type
, 0, spc
, false, true);
2616 pp_semicolon (buffer
);
2622 /* Skip unnamed or anonymous structs/unions/enum types. */
2623 if (!orig
&& !decl_name
&& !name
)
2628 if (cpp_check
|| TREE_CODE (TREE_TYPE (t
)) == ENUMERAL_TYPE
)
2631 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t
)))
2633 /* Search next items until finding a named type decl. */
2634 sloc
= decl_sloc_common (t
, true, true);
2636 for (tmp
= TREE_CHAIN (t
); tmp
; tmp
= TREE_CHAIN (tmp
))
2638 if (TREE_CODE (tmp
) == TYPE_DECL
2639 && (DECL_NAME (tmp
) || TYPE_NAME (TREE_TYPE (tmp
))))
2641 /* If same sloc, it means we can ignore the anonymous
2643 if (decl_sloc_common (tmp
, true, true) == sloc
)
2655 && TREE_CODE (TREE_TYPE (t
)) == ENUMERAL_TYPE
2657 && (*IDENTIFIER_POINTER (decl_name
) == '.'
2658 || *IDENTIFIER_POINTER (decl_name
) == '$'))
2659 /* Skip anonymous enum types (duplicates of real types). */
2664 switch (TREE_CODE (TREE_TYPE (t
)))
2668 case QUAL_UNION_TYPE
:
2669 /* Skip empty structs (typically forward references to real
2671 if (!TYPE_FIELDS (TREE_TYPE (t
)))
2673 pp_string (buffer
, "-- skipped empty struct ");
2674 dump_generic_ada_node (buffer
, t
, type
, 0, spc
, false, true);
2679 && (*IDENTIFIER_POINTER (decl_name
) == '.'
2680 || *IDENTIFIER_POINTER (decl_name
) == '$'))
2682 pp_string (buffer
, "-- skipped anonymous struct ");
2683 dump_generic_ada_node (buffer
, t
, type
, 0, spc
, false, true);
2684 TREE_VISITED (t
) = 1;
2688 if (orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
))
2689 pp_string (buffer
, "subtype ");
2692 dump_nested_types (buffer
, t
, t
, false, cpp_check
, spc
);
2694 if (separate_class_package (t
))
2697 pp_string (buffer
, "package Class_");
2698 dump_generic_ada_node
2699 (buffer
, t
, type
, 0, spc
, false, true);
2700 pp_string (buffer
, " is");
2702 newline_and_indent (buffer
, spc
);
2705 pp_string (buffer
, "type ");
2711 case REFERENCE_TYPE
:
2712 if ((orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
))
2713 || is_char_array (t
))
2714 pp_string (buffer
, "subtype ");
2716 pp_string (buffer
, "type ");
2720 pp_string (buffer
, "-- skipped function type ");
2721 dump_generic_ada_node (buffer
, t
, type
, 0, spc
, false, true);
2726 if ((orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
))
2727 || !is_simple_enum (TREE_TYPE (t
)))
2728 pp_string (buffer
, "subtype ");
2730 pp_string (buffer
, "type ");
2734 pp_string (buffer
, "subtype ");
2736 TREE_VISITED (t
) = 1;
2740 if (TREE_CODE (t
) == VAR_DECL
2742 && *IDENTIFIER_POINTER (decl_name
) == '_')
2748 /* Print the type and name. */
2749 if (TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
)
2754 /* Print variable's name. */
2755 dump_generic_ada_node (buffer
, t
, type
, cpp_check
, spc
, false, true);
2757 if (TREE_CODE (t
) == TYPE_DECL
)
2759 pp_string (buffer
, " is ");
2761 if (orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
))
2762 dump_generic_ada_node
2763 (buffer
, TYPE_NAME (orig
), type
,
2764 cpp_check
, spc
, false, true);
2766 dump_ada_array_type (buffer
, t
, spc
);
2770 tree tmp
= TYPE_NAME (TREE_TYPE (t
));
2772 if (spc
== INDENT_INCR
|| TREE_STATIC (t
))
2775 pp_string (buffer
, " : ");
2779 if (TREE_CODE (TREE_TYPE (tmp
)) != POINTER_TYPE
2780 && TREE_CODE (tmp
) != INTEGER_TYPE
)
2781 pp_string (buffer
, "aliased ");
2783 dump_generic_ada_node (buffer
, tmp
, type
, 0, spc
, false, true);
2787 pp_string (buffer
, "aliased ");
2790 dump_ada_array_type (buffer
, t
, spc
);
2792 dump_ada_double_name (buffer
, type
, t
, "_array");
2796 else if (TREE_CODE (t
) == FUNCTION_DECL
)
2798 bool is_function
= true, is_method
, is_abstract_class
= false;
2799 tree decl_name
= DECL_NAME (t
);
2800 int prev_in_function
= in_function
;
2801 bool is_abstract
= false;
2802 bool is_constructor
= false;
2803 bool is_destructor
= false;
2804 bool is_copy_constructor
= false;
2811 is_abstract
= cpp_check (t
, IS_ABSTRACT
);
2812 is_constructor
= cpp_check (t
, IS_CONSTRUCTOR
);
2813 is_destructor
= cpp_check (t
, IS_DESTRUCTOR
);
2814 is_copy_constructor
= cpp_check (t
, IS_COPY_CONSTRUCTOR
);
2817 /* Skip __comp_dtor destructor which is redundant with the '~class()'
2820 && !strncmp (IDENTIFIER_POINTER (decl_name
), "__comp", 6))
2823 /* Skip copy constructors: some are internal only, and those that are
2824 not cannot be called easily from Ada anyway. */
2825 if (is_copy_constructor
)
2828 /* If this function has an entry in the dispatch table, we cannot
2830 if (!DECL_VINDEX (t
) && *IDENTIFIER_POINTER (decl_name
) == '_')
2832 if (IDENTIFIER_POINTER (decl_name
)[1] == '_')
2836 pp_string (buffer
, "-- skipped func ");
2837 pp_string (buffer
, IDENTIFIER_POINTER (decl_name
));
2845 pp_string (buffer
, "function New_");
2846 else if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (t
))))
2848 is_function
= false;
2849 pp_string (buffer
, "procedure ");
2852 pp_string (buffer
, "function ");
2854 in_function
= is_function
;
2855 is_method
= TREE_CODE (TREE_TYPE (t
)) == METHOD_TYPE
;
2858 print_destructor (buffer
, t
);
2860 dump_ada_decl_name (buffer
, t
, false);
2862 dump_ada_function_declaration
2863 (buffer
, t
, is_method
, is_constructor
, is_destructor
, spc
);
2864 in_function
= prev_in_function
;
2868 pp_string (buffer
, " return ");
2872 dump_ada_decl_name (buffer
, t
, false);
2876 dump_generic_ada_node
2877 (buffer
, TREE_TYPE (TREE_TYPE (t
)), type
, cpp_check
,
2882 if (is_constructor
&& cpp_check
&& type
2883 && AGGREGATE_TYPE_P (type
)
2884 && TYPE_METHODS (type
))
2886 tree tmp
= TYPE_METHODS (type
);
2888 for (; tmp
; tmp
= TREE_CHAIN (tmp
))
2889 if (cpp_check (tmp
, IS_ABSTRACT
))
2891 is_abstract_class
= 1;
2896 if (is_abstract
|| is_abstract_class
)
2897 pp_string (buffer
, " is abstract");
2899 pp_semicolon (buffer
);
2900 pp_string (buffer
, " -- ");
2901 dump_sloc (buffer
, t
);
2906 newline_and_indent (buffer
, spc
);
2910 pp_string (buffer
, "pragma CPP_Constructor (New_");
2911 dump_ada_decl_name (buffer
, t
, false);
2912 pp_string (buffer
, ", \"");
2913 pp_asm_name (buffer
, t
);
2914 pp_string (buffer
, "\");");
2916 else if (is_destructor
)
2918 pp_string (buffer
, "pragma Import (CPP, ");
2919 print_destructor (buffer
, t
);
2920 pp_string (buffer
, ", \"");
2921 pp_asm_name (buffer
, t
);
2922 pp_string (buffer
, "\");");
2926 dump_ada_import (buffer
, t
);
2931 else if (TREE_CODE (t
) == TYPE_DECL
&& !DECL_ORIGINAL_TYPE (t
))
2933 int is_interface
= 0;
2934 int is_abstract_record
= 0;
2939 /* Anonymous structs/unions */
2940 dump_generic_ada_node
2941 (buffer
, TREE_TYPE (t
), t
, cpp_check
, spc
, false, true);
2943 if (TREE_CODE (TREE_TYPE (t
)) == UNION_TYPE
2944 || TREE_CODE (TREE_TYPE (t
)) == QUAL_UNION_TYPE
)
2946 pp_string (buffer
, " (discr : unsigned := 0)");
2949 pp_string (buffer
, " is ");
2951 /* Check whether we have an Ada interface compatible class. */
2952 if (cpp_check
&& AGGREGATE_TYPE_P (TREE_TYPE (t
))
2953 && TYPE_METHODS (TREE_TYPE (t
)))
2956 tree tmp
= TYPE_FIELDS (TREE_TYPE (t
));
2958 /* Check that there are no fields other than the virtual table. */
2959 for (; tmp
; tmp
= TREE_CHAIN (tmp
))
2961 if (TREE_CODE (tmp
) == TYPE_DECL
)
2966 if (num_fields
== 1)
2969 /* Also check that there are only virtual methods. */
2970 for (tmp
= TYPE_METHODS (TREE_TYPE (t
)); tmp
; tmp
= TREE_CHAIN (tmp
))
2972 if (cpp_check (tmp
, IS_ABSTRACT
))
2973 is_abstract_record
= 1;
2979 TREE_VISITED (t
) = 1;
2982 pp_string (buffer
, "limited interface; -- ");
2983 dump_sloc (buffer
, t
);
2984 newline_and_indent (buffer
, spc
);
2985 pp_string (buffer
, "pragma Import (CPP, ");
2986 dump_generic_ada_node
2987 (buffer
, TYPE_NAME (TREE_TYPE (t
)), type
, cpp_check
,
2989 pp_character (buffer
, ')');
2991 print_ada_methods (buffer
, TREE_TYPE (t
), cpp_check
, spc
);
2995 if (is_abstract_record
)
2996 pp_string (buffer
, "abstract ");
2997 dump_generic_ada_node (buffer
, t
, t
, cpp_check
, spc
, false, false);
3005 if (TREE_CODE (t
) == FIELD_DECL
&& DECL_NAME (t
))
3006 check_name (buffer
, t
);
3008 /* Print variable/type's name. */
3009 dump_generic_ada_node (buffer
, t
, t
, cpp_check
, spc
, false, true);
3011 if (TREE_CODE (t
) == TYPE_DECL
)
3013 tree orig
= DECL_ORIGINAL_TYPE (t
);
3014 int is_subtype
= orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
);
3017 && (TREE_CODE (TREE_TYPE (t
)) == UNION_TYPE
3018 || TREE_CODE (TREE_TYPE (t
)) == QUAL_UNION_TYPE
))
3019 pp_string (buffer
, " (discr : unsigned := 0)");
3021 pp_string (buffer
, " is ");
3023 dump_generic_ada_node
3024 (buffer
, orig
, t
, cpp_check
, spc
, false, is_subtype
);
3028 if (spc
== INDENT_INCR
|| TREE_STATIC (t
))
3031 pp_string (buffer
, " : ");
3033 /* Print type declaration. */
3035 if (TREE_CODE (TREE_TYPE (t
)) == UNION_TYPE
3036 && !TYPE_NAME (TREE_TYPE (t
)))
3038 dump_ada_double_name (buffer
, type
, t
, "_union");
3040 else if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t
)))
3042 if (TREE_CODE (TREE_TYPE (t
)) == RECORD_TYPE
)
3043 pp_string (buffer
, "aliased ");
3045 dump_generic_ada_node
3046 (buffer
, TREE_TYPE (t
), t
, cpp_check
, spc
, false, true);
3050 if (TREE_CODE (TREE_TYPE (t
)) != POINTER_TYPE
3051 && (TYPE_NAME (TREE_TYPE (t
))
3052 || TREE_CODE (TREE_TYPE (t
)) != INTEGER_TYPE
))
3053 pp_string (buffer
, "aliased ");
3055 dump_generic_ada_node
3056 (buffer
, TREE_TYPE (t
), TREE_TYPE (t
), cpp_check
,
3065 newline_and_indent (buffer
, spc
);
3066 pp_string (buffer
, "end;");
3067 newline_and_indent (buffer
, spc
);
3068 pp_string (buffer
, "use Class_");
3069 dump_generic_ada_node (buffer
, t
, type
, 0, spc
, false, true);
3070 pp_semicolon (buffer
);
3071 pp_newline (buffer
);
3073 /* All needed indentation/newline performed already, so return 0. */
3078 pp_string (buffer
, "; -- ");
3079 dump_sloc (buffer
, t
);
3084 newline_and_indent (buffer
, spc
);
3085 dump_ada_import (buffer
, t
);
3091 /* Prints in BUFFER a structure NODE of type TYPE: name, fields, and methods
3092 with Ada syntax. CPP_CHECK is used to perform C++ queries on nodes. SPC
3093 is the indentation level. If DISPLAY_CONVENTION is true, also print the
3094 pragma Convention for NODE. */
3097 print_ada_struct_decl (pretty_printer
*buffer
, tree node
, tree type
,
3098 int (*cpp_check
)(tree
, cpp_operation
), int spc
,
3099 bool display_convention
)
3103 TREE_CODE (node
) == UNION_TYPE
|| TREE_CODE (node
) == QUAL_UNION_TYPE
;
3106 int field_spc
= spc
+ INDENT_INCR
;
3109 bitfield_used
= false;
3111 if (!TYPE_FIELDS (node
))
3112 pp_string (buffer
, "null record;");
3115 pp_string (buffer
, "record");
3117 /* Print the contents of the structure. */
3121 newline_and_indent (buffer
, spc
+ INDENT_INCR
);
3122 pp_string (buffer
, "case discr is");
3123 field_spc
= spc
+ INDENT_INCR
* 3;
3126 pp_newline (buffer
);
3128 /* Print the non-static fields of the structure. */
3129 for (tmp
= TYPE_FIELDS (node
); tmp
; tmp
= TREE_CHAIN (tmp
))
3131 /* Add parent field if needed. */
3132 if (!DECL_NAME (tmp
))
3134 if (!is_tagged_type (TREE_TYPE (tmp
)))
3136 if (!TYPE_NAME (TREE_TYPE (tmp
)))
3137 print_ada_declaration
3138 (buffer
, tmp
, type
, cpp_check
, field_spc
);
3144 pp_string (buffer
, "parent : aliased ");
3147 sprintf (buf
, "field_%d : aliased ", field_num
+ 1);
3148 pp_string (buffer
, buf
);
3151 (buffer
, TYPE_NAME (TREE_TYPE (tmp
)), false);
3152 pp_semicolon (buffer
);
3154 pp_newline (buffer
);
3158 /* Avoid printing the structure recursively. */
3159 else if ((TREE_TYPE (tmp
) != node
3160 || (TREE_CODE (TREE_TYPE (tmp
)) == POINTER_TYPE
3161 && TREE_TYPE (TREE_TYPE (tmp
)) != node
))
3162 && TREE_CODE (tmp
) != TYPE_DECL
3163 && !TREE_STATIC (tmp
))
3165 /* Skip internal virtual table field. */
3166 if (strncmp (IDENTIFIER_POINTER (DECL_NAME (tmp
)), "_vptr", 5))
3170 if (TREE_CHAIN (tmp
)
3171 && TREE_TYPE (TREE_CHAIN (tmp
)) != node
3172 && TREE_CODE (TREE_CHAIN (tmp
)) != TYPE_DECL
)
3173 sprintf (buf
, "when %d =>", field_num
);
3175 sprintf (buf
, "when others =>");
3177 INDENT (spc
+ INDENT_INCR
* 2);
3178 pp_string (buffer
, buf
);
3179 pp_newline (buffer
);
3182 if (print_ada_declaration (buffer
,
3183 tmp
, type
, cpp_check
, field_spc
))
3185 pp_newline (buffer
);
3194 INDENT (spc
+ INDENT_INCR
);
3195 pp_string (buffer
, "end case;");
3196 pp_newline (buffer
);
3201 INDENT (spc
+ INDENT_INCR
);
3202 pp_string (buffer
, "null;");
3203 pp_newline (buffer
);
3207 pp_string (buffer
, "end record;");
3210 newline_and_indent (buffer
, spc
);
3212 if (!display_convention
)
3215 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type
)))
3217 if (TYPE_METHODS (TREE_TYPE (type
)))
3218 pp_string (buffer
, "pragma Import (CPP, ");
3220 pp_string (buffer
, "pragma Convention (C_Pass_By_Copy, ");
3223 pp_string (buffer
, "pragma Convention (C, ");
3225 package_prefix
= false;
3226 dump_generic_ada_node
3227 (buffer
, TREE_TYPE (type
), type
, cpp_check
, spc
, false, true);
3228 package_prefix
= true;
3229 pp_character (buffer
, ')');
3233 pp_semicolon (buffer
);
3234 newline_and_indent (buffer
, spc
);
3235 pp_string (buffer
, "pragma Unchecked_Union (");
3237 dump_generic_ada_node
3238 (buffer
, TREE_TYPE (type
), type
, cpp_check
, spc
, false, true);
3239 pp_character (buffer
, ')');
3244 pp_semicolon (buffer
);
3245 newline_and_indent (buffer
, spc
);
3246 pp_string (buffer
, "pragma Pack (");
3247 dump_generic_ada_node
3248 (buffer
, TREE_TYPE (type
), type
, cpp_check
, spc
, false, true);
3249 pp_character (buffer
, ')');
3250 bitfield_used
= false;
3253 print_ada_methods (buffer
, node
, cpp_check
, spc
);
3255 /* Print the static fields of the structure, if any. */
3256 need_semicolon
= TYPE_METHODS (node
) == NULL_TREE
;
3257 for (tmp
= TYPE_FIELDS (node
); tmp
; tmp
= TREE_CHAIN (tmp
))
3259 if (DECL_NAME (tmp
) && TREE_STATIC (tmp
))
3263 need_semicolon
= false;
3264 pp_semicolon (buffer
);
3266 pp_newline (buffer
);
3267 pp_newline (buffer
);
3268 print_ada_declaration (buffer
, tmp
, type
, cpp_check
, spc
);
3273 /* Dump all the declarations in SOURCE_FILE to an Ada spec.
3274 COLLECT_ALL_REFS is a front-end callback used to collect all relevant
3275 nodes for SOURCE_FILE. CPP_CHECK is used to perform C++ queries on
3279 dump_ads (const char *source_file
,
3280 void (*collect_all_refs
)(const char *),
3281 int (*cpp_check
)(tree
, cpp_operation
))
3288 pkg_name
= get_ada_package (source_file
);
3290 /* Construct the .ads filename and package name. */
3291 ads_name
= xstrdup (pkg_name
);
3293 for (s
= ads_name
; *s
; s
++)
3299 ads_name
= reconcat (ads_name
, ads_name
, ".ads", NULL
);
3301 /* Write out the .ads file. */
3302 f
= fopen (ads_name
, "w");
3307 pp_construct (&pp
, NULL
, 0);
3308 pp_needs_newline (&pp
) = true;
3309 pp
.buffer
->stream
= f
;
3311 /* Dump all relevant macros. */
3312 dump_ada_macros (&pp
, source_file
);
3314 /* Reset the table of withs for this file. */
3317 (*collect_all_refs
) (source_file
);
3319 /* Dump all references. */
3320 dump_ada_nodes (&pp
, source_file
, cpp_check
);
3322 /* Requires Ada 2005 syntax, so generate corresponding pragma.
3323 Also, disable style checks since this file is auto-generated. */
3324 fprintf (f
, "pragma Ada_2005;\npragma Style_Checks (Off);\n\n");
3329 fprintf (f
, "\npackage %s is\n\n", pkg_name
);
3330 pp_write_text_to_stream (&pp
);
3331 /* ??? need to free pp */
3332 fprintf (f
, "end %s;\n", pkg_name
);
3340 static const char **source_refs
= NULL
;
3341 static int source_refs_used
= 0;
3342 static int source_refs_allocd
= 0;
3344 /* Add an entry for FILENAME to the table SOURCE_REFS. */
3347 collect_source_ref (const char *filename
)
3354 if (source_refs_allocd
== 0)
3356 source_refs_allocd
= 1024;
3357 source_refs
= XNEWVEC (const char *, source_refs_allocd
);
3360 for (i
= 0; i
< source_refs_used
; i
++)
3361 if (filename
== source_refs
[i
])
3364 if (source_refs_used
== source_refs_allocd
)
3366 source_refs_allocd
*= 2;
3367 source_refs
= XRESIZEVEC (const char *, source_refs
, source_refs_allocd
);
3370 source_refs
[source_refs_used
++] = filename
;
3373 /* Main entry point: dump all Ada specs corresponding to SOURCE_REFS
3374 using callbacks COLLECT_ALL_REFS and CPP_CHECK.
3375 COLLECT_ALL_REFS is a front-end callback used to collect all relevant
3376 nodes for a given source file.
3377 CPP_CHECK is used to perform C++ queries on nodes, or NULL for the C
3381 dump_ada_specs (void (*collect_all_refs
)(const char *),
3382 int (*cpp_check
)(tree
, cpp_operation
))
3386 /* Iterate over the list of files to dump specs for */
3387 for (i
= 0; i
< source_refs_used
; i
++)
3388 dump_ads (source_refs
[i
], collect_all_refs
, cpp_check
);
3390 /* Free files table. */