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-2014 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"
34 /* Local functions, macros and variables. */
35 static int dump_generic_ada_node (pretty_printer
*, tree
, tree
, int, int,
37 static int print_ada_declaration (pretty_printer
*, tree
, tree
, int);
38 static void print_ada_struct_decl (pretty_printer
*, tree
, tree
, int, bool);
39 static void dump_sloc (pretty_printer
*buffer
, tree node
);
40 static void print_comment (pretty_printer
*, const char *);
41 static void print_generic_ada_decl (pretty_printer
*, tree
, const char *);
42 static char *get_ada_package (const char *);
43 static void dump_ada_nodes (pretty_printer
*, const char *);
44 static void reset_ada_withs (void);
45 static void dump_ada_withs (FILE *);
46 static void dump_ads (const char *, void (*)(const char *),
47 int (*)(tree
, cpp_operation
));
48 static char *to_ada_name (const char *, int *);
49 static bool separate_class_package (tree
);
51 #define INDENT(SPACE) \
52 do { int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
56 /* Global hook used to perform C++ queries on nodes. */
57 static int (*cpp_check
) (tree
, cpp_operation
) = NULL
;
60 /* Given a cpp MACRO, compute the max length BUFFER_LEN of the macro, as well
61 as max length PARAM_LEN of arguments for fun_like macros, and also set
62 SUPPORTED to 0 if the macro cannot be mapped to an Ada construct. */
65 macro_length (const cpp_macro
*macro
, int *supported
, int *buffer_len
,
78 for (i
= 0; i
< macro
->paramc
; i
++)
80 cpp_hashnode
*param
= macro
->params
[i
];
82 *param_len
+= NODE_LEN (param
);
84 if (i
+ 1 < macro
->paramc
)
86 *param_len
+= 2; /* ", " */
88 else if (macro
->variadic
)
94 *param_len
+= 2; /* ")\0" */
97 for (j
= 0; j
< macro
->count
; j
++)
99 cpp_token
*token
= ¯o
->exp
.tokens
[j
];
101 if (token
->flags
& PREV_WHITE
)
104 if (token
->flags
& STRINGIFY_ARG
|| token
->flags
& PASTE_LEFT
)
110 if (token
->type
== CPP_MACRO_ARG
)
112 NODE_LEN (macro
->params
[token
->val
.macro_arg
.arg_no
- 1]);
114 /* Include enough extra space to handle e.g. special characters. */
115 *buffer_len
+= (cpp_token_len (token
) + 1) * 8;
121 /* Dump into PP a set of MAX_ADA_MACROS MACROS (C/C++) as Ada constants when
125 print_ada_macros (pretty_printer
*pp
, cpp_hashnode
**macros
, int max_ada_macros
)
127 int j
, num_macros
= 0, prev_line
= -1;
129 for (j
= 0; j
< max_ada_macros
; j
++)
131 cpp_hashnode
*node
= macros
[j
];
132 const cpp_macro
*macro
= node
->value
.macro
;
134 int supported
= 1, prev_is_one
= 0, buffer_len
, param_len
;
135 int is_string
= 0, is_char
= 0;
137 unsigned char *s
, *params
, *buffer
, *buf_param
, *char_one
= NULL
;
139 macro_length (macro
, &supported
, &buffer_len
, ¶m_len
);
140 s
= buffer
= XALLOCAVEC (unsigned char, buffer_len
);
141 params
= buf_param
= XALLOCAVEC (unsigned char, param_len
);
148 for (i
= 0; i
< macro
->paramc
; i
++)
150 cpp_hashnode
*param
= macro
->params
[i
];
152 memcpy (buf_param
, NODE_NAME (param
), NODE_LEN (param
));
153 buf_param
+= NODE_LEN (param
);
155 if (i
+ 1 < macro
->paramc
)
160 else if (macro
->variadic
)
170 for (i
= 0; supported
&& i
< macro
->count
; i
++)
172 cpp_token
*token
= ¯o
->exp
.tokens
[i
];
175 if (token
->flags
& PREV_WHITE
)
178 if (token
->flags
& STRINGIFY_ARG
|| token
->flags
& PASTE_LEFT
)
188 cpp_hashnode
*param
=
189 macro
->params
[token
->val
.macro_arg
.arg_no
- 1];
190 memcpy (buffer
, NODE_NAME (param
), NODE_LEN (param
));
191 buffer
+= NODE_LEN (param
);
195 case CPP_EQ_EQ
: *buffer
++ = '='; break;
196 case CPP_GREATER
: *buffer
++ = '>'; break;
197 case CPP_LESS
: *buffer
++ = '<'; break;
198 case CPP_PLUS
: *buffer
++ = '+'; break;
199 case CPP_MINUS
: *buffer
++ = '-'; break;
200 case CPP_MULT
: *buffer
++ = '*'; break;
201 case CPP_DIV
: *buffer
++ = '/'; break;
202 case CPP_COMMA
: *buffer
++ = ','; break;
203 case CPP_OPEN_SQUARE
:
204 case CPP_OPEN_PAREN
: *buffer
++ = '('; break;
205 case CPP_CLOSE_SQUARE
: /* fallthrough */
206 case CPP_CLOSE_PAREN
: *buffer
++ = ')'; break;
207 case CPP_DEREF
: /* fallthrough */
208 case CPP_SCOPE
: /* fallthrough */
209 case CPP_DOT
: *buffer
++ = '.'; break;
211 case CPP_EQ
: *buffer
++ = ':'; *buffer
++ = '='; break;
212 case CPP_NOT_EQ
: *buffer
++ = '/'; *buffer
++ = '='; break;
213 case CPP_GREATER_EQ
: *buffer
++ = '>'; *buffer
++ = '='; break;
214 case CPP_LESS_EQ
: *buffer
++ = '<'; *buffer
++ = '='; break;
217 *buffer
++ = 'n'; *buffer
++ = 'o'; *buffer
++ = 't'; break;
219 *buffer
++ = 'm'; *buffer
++ = 'o'; *buffer
++ = 'd'; break;
221 *buffer
++ = 'a'; *buffer
++ = 'n'; *buffer
++ = 'd'; break;
223 *buffer
++ = 'o'; *buffer
++ = 'r'; break;
225 *buffer
++ = 'x'; *buffer
++ = 'o'; *buffer
++ = 'r'; break;
227 strcpy ((char *) buffer
, " and then ");
231 strcpy ((char *) buffer
, " or else ");
237 is_one
= prev_is_one
;
240 case CPP_COMMENT
: break;
252 if (!macro
->fun_like
)
255 buffer
= cpp_spell_token (parse_in
, token
, buffer
, false);
265 c
= cpp_interpret_charconst (parse_in
, token
,
266 &chars_seen
, &ignored
);
267 if (c
>= 32 && c
<= 126)
270 *buffer
++ = (char) c
;
276 ((char *) buffer
, "Character'Val (%d)", (int) c
);
277 buffer
+= chars_seen
;
285 /* Replace "1 << N" by "2 ** N" */
312 case CPP_CLOSE_BRACE
:
316 case CPP_MINUS_MINUS
:
320 case CPP_HEADER_NAME
:
323 case CPP_OBJC_STRING
:
325 if (!macro
->fun_like
)
328 buffer
= cpp_spell_token (parse_in
, token
, buffer
, false);
332 prev_is_one
= is_one
;
339 if (macro
->fun_like
&& supported
)
341 char *start
= (char *) s
;
344 pp_string (pp
, " -- arg-macro: ");
346 if (*start
== '(' && buffer
[-1] == ')')
351 pp_string (pp
, "function ");
355 pp_string (pp
, "procedure ");
358 pp_string (pp
, (const char *) NODE_NAME (node
));
360 pp_string (pp
, (char *) params
);
362 pp_string (pp
, " -- ");
366 pp_string (pp
, "return ");
367 pp_string (pp
, start
);
371 pp_string (pp
, start
);
377 expanded_location sloc
= expand_location (macro
->line
);
379 if (sloc
.line
!= prev_line
+ 1)
383 prev_line
= sloc
.line
;
386 ada_name
= to_ada_name ((const char *) NODE_NAME (node
), NULL
);
387 pp_string (pp
, ada_name
);
389 pp_string (pp
, " : ");
392 pp_string (pp
, "aliased constant String");
394 pp_string (pp
, "aliased constant Character");
396 pp_string (pp
, "constant");
398 pp_string (pp
, " := ");
399 pp_string (pp
, (char *) s
);
402 pp_string (pp
, " & ASCII.NUL");
404 pp_string (pp
, "; -- ");
405 pp_string (pp
, sloc
.file
);
407 pp_scalar (pp
, "%d", sloc
.line
);
412 pp_string (pp
, " -- unsupported macro: ");
413 pp_string (pp
, (const char *) cpp_macro_definition (parse_in
, node
));
422 static const char *source_file
;
423 static int max_ada_macros
;
425 /* Callback used to count the number of relevant macros from
426 cpp_forall_identifiers. PFILE and V are not used. NODE is the current macro
430 count_ada_macro (cpp_reader
*pfile ATTRIBUTE_UNUSED
, cpp_hashnode
*node
,
431 void *v ATTRIBUTE_UNUSED
)
433 const cpp_macro
*macro
= node
->value
.macro
;
435 if (node
->type
== NT_MACRO
&& !(node
->flags
& NODE_BUILTIN
)
437 && *NODE_NAME (node
) != '_'
438 && LOCATION_FILE (macro
->line
) == source_file
)
444 static int store_ada_macro_index
;
446 /* Callback used to store relevant macros from cpp_forall_identifiers.
447 PFILE is not used. NODE is the current macro to store if relevant.
448 MACROS is an array of cpp_hashnode* used to store NODE. */
451 store_ada_macro (cpp_reader
*pfile ATTRIBUTE_UNUSED
,
452 cpp_hashnode
*node
, void *macros
)
454 const cpp_macro
*macro
= node
->value
.macro
;
456 if (node
->type
== NT_MACRO
&& !(node
->flags
& NODE_BUILTIN
)
458 && *NODE_NAME (node
) != '_'
459 && LOCATION_FILE (macro
->line
) == source_file
)
460 ((cpp_hashnode
**) macros
)[store_ada_macro_index
++] = node
;
465 /* Callback used to compare (during qsort) macros. NODE1 and NODE2 are the
466 two macro nodes to compare. */
469 compare_macro (const void *node1
, const void *node2
)
471 typedef const cpp_hashnode
*const_hnode
;
473 const_hnode n1
= *(const const_hnode
*) node1
;
474 const_hnode n2
= *(const const_hnode
*) node2
;
476 return n1
->value
.macro
->line
- n2
->value
.macro
->line
;
479 /* Dump in PP all relevant macros appearing in FILE. */
482 dump_ada_macros (pretty_printer
*pp
, const char* file
)
484 cpp_hashnode
**macros
;
486 /* Initialize file-scope variables. */
488 store_ada_macro_index
= 0;
491 /* Count all potentially relevant macros, and then sort them by sloc. */
492 cpp_forall_identifiers (parse_in
, count_ada_macro
, NULL
);
493 macros
= XALLOCAVEC (cpp_hashnode
*, max_ada_macros
);
494 cpp_forall_identifiers (parse_in
, store_ada_macro
, macros
);
495 qsort (macros
, max_ada_macros
, sizeof (cpp_hashnode
*), compare_macro
);
497 print_ada_macros (pp
, macros
, max_ada_macros
);
500 /* Current source file being handled. */
502 static const char *source_file_base
;
504 /* Compare the declaration (DECL) of struct-like types based on the sloc of
505 their last field (if LAST is true), so that more nested types collate before
507 If ORIG_TYPE is true, also consider struct with a DECL_ORIGINAL_TYPE. */
510 decl_sloc_common (const_tree decl
, bool last
, bool orig_type
)
512 tree type
= TREE_TYPE (decl
);
514 if (TREE_CODE (decl
) == TYPE_DECL
515 && (orig_type
|| !DECL_ORIGINAL_TYPE (decl
))
516 && RECORD_OR_UNION_TYPE_P (type
)
517 && TYPE_FIELDS (type
))
519 tree f
= TYPE_FIELDS (type
);
522 while (TREE_CHAIN (f
))
525 return DECL_SOURCE_LOCATION (f
);
528 return DECL_SOURCE_LOCATION (decl
);
531 /* Return sloc of DECL, using sloc of last field if LAST is true. */
534 decl_sloc (const_tree decl
, bool last
)
536 return decl_sloc_common (decl
, last
, false);
539 /* Compare two locations LHS and RHS. */
542 compare_location (location_t lhs
, location_t rhs
)
544 expanded_location xlhs
= expand_location (lhs
);
545 expanded_location xrhs
= expand_location (rhs
);
547 if (xlhs
.file
!= xrhs
.file
)
548 return filename_cmp (xlhs
.file
, xrhs
.file
);
550 if (xlhs
.line
!= xrhs
.line
)
551 return xlhs
.line
- xrhs
.line
;
553 if (xlhs
.column
!= xrhs
.column
)
554 return xlhs
.column
- xrhs
.column
;
559 /* Compare two declarations (LP and RP) by their source location. */
562 compare_node (const void *lp
, const void *rp
)
564 const_tree lhs
= *((const tree
*) lp
);
565 const_tree rhs
= *((const tree
*) rp
);
567 return compare_location (decl_sloc (lhs
, true), decl_sloc (rhs
, true));
570 /* Compare two comments (LP and RP) by their source location. */
573 compare_comment (const void *lp
, const void *rp
)
575 const cpp_comment
*lhs
= (const cpp_comment
*) lp
;
576 const cpp_comment
*rhs
= (const cpp_comment
*) rp
;
578 return compare_location (lhs
->sloc
, rhs
->sloc
);
581 static tree
*to_dump
= NULL
;
582 static int to_dump_count
= 0;
584 /* Collect a list of declarations from T relevant to SOURCE_FILE to be dumped
585 by a subsequent call to dump_ada_nodes. */
588 collect_ada_nodes (tree t
, const char *source_file
)
591 int i
= to_dump_count
;
593 /* Count the likely relevant nodes. */
594 for (n
= t
; n
; n
= TREE_CHAIN (n
))
595 if (!DECL_IS_BUILTIN (n
)
596 && LOCATION_FILE (decl_sloc (n
, false)) == source_file
)
599 /* Allocate sufficient storage for all nodes. */
600 to_dump
= XRESIZEVEC (tree
, to_dump
, to_dump_count
);
602 /* Store the relevant nodes. */
603 for (n
= t
; n
; n
= TREE_CHAIN (n
))
604 if (!DECL_IS_BUILTIN (n
)
605 && LOCATION_FILE (decl_sloc (n
, false)) == source_file
)
609 /* Call back for walk_tree to clear the TREE_VISITED flag of TP. */
612 unmark_visited_r (tree
*tp
, int *walk_subtrees ATTRIBUTE_UNUSED
,
613 void *data ATTRIBUTE_UNUSED
)
615 if (TREE_VISITED (*tp
))
616 TREE_VISITED (*tp
) = 0;
623 /* Dump nodes into PP relevant to SOURCE_FILE, as collected by previous calls
624 to collect_ada_nodes. */
627 dump_ada_nodes (pretty_printer
*pp
, const char *source_file
)
630 cpp_comment_table
*comments
;
632 /* Sort the table of declarations to dump by sloc. */
633 qsort (to_dump
, to_dump_count
, sizeof (tree
), compare_node
);
635 /* Fetch the table of comments. */
636 comments
= cpp_get_comments (parse_in
);
638 /* Sort the comments table by sloc. */
639 if (comments
->count
> 1)
640 qsort (comments
->entries
, comments
->count
, sizeof (cpp_comment
),
643 /* Interleave comments and declarations in line number order. */
647 /* Advance j until comment j is in this file. */
648 while (j
!= comments
->count
649 && LOCATION_FILE (comments
->entries
[j
].sloc
) != source_file
)
652 /* Advance j until comment j is not a duplicate. */
653 while (j
< comments
->count
- 1
654 && !compare_comment (&comments
->entries
[j
],
655 &comments
->entries
[j
+ 1]))
658 /* Write decls until decl i collates after comment j. */
659 while (i
!= to_dump_count
)
661 if (j
== comments
->count
662 || LOCATION_LINE (decl_sloc (to_dump
[i
], false))
663 < LOCATION_LINE (comments
->entries
[j
].sloc
))
664 print_generic_ada_decl (pp
, to_dump
[i
++], source_file
);
669 /* Write comment j, if there is one. */
670 if (j
!= comments
->count
)
671 print_comment (pp
, comments
->entries
[j
++].comment
);
673 } while (i
!= to_dump_count
|| j
!= comments
->count
);
675 /* Clear the TREE_VISITED flag over each subtree we've dumped. */
676 for (i
= 0; i
< to_dump_count
; i
++)
677 walk_tree (&to_dump
[i
], unmark_visited_r
, NULL
, NULL
);
679 /* Finalize the to_dump table. */
688 /* Print a COMMENT to the output stream PP. */
691 print_comment (pretty_printer
*pp
, const char *comment
)
693 int len
= strlen (comment
);
694 char *str
= XALLOCAVEC (char, len
+ 1);
696 bool extra_newline
= false;
698 memcpy (str
, comment
, len
+ 1);
700 /* Trim C/C++ comment indicators. */
701 if (str
[len
- 2] == '*' && str
[len
- 1] == '/')
708 tok
= strtok (str
, "\n");
710 pp_string (pp
, " --");
713 tok
= strtok (NULL
, "\n");
715 /* Leave a blank line after multi-line comments. */
717 extra_newline
= true;
724 /* Print declaration DECL to PP in Ada syntax. The current source file being
725 handled is SOURCE_FILE. */
728 print_generic_ada_decl (pretty_printer
*pp
, tree decl
, const char *source_file
)
730 source_file_base
= source_file
;
732 if (print_ada_declaration (pp
, decl
, 0, INDENT_INCR
))
739 /* Dump a newline and indent BUFFER by SPC chars. */
742 newline_and_indent (pretty_printer
*buffer
, int spc
)
748 struct with
{ char *s
; const char *in_file
; int limited
; };
749 static struct with
*withs
= NULL
;
750 static int withs_max
= 4096;
751 static int with_len
= 0;
753 /* Record a "with" clause on package S (a limited with if LIMITED_ACCESS is
754 true), if not already done. */
757 append_withs (const char *s
, int limited_access
)
762 withs
= XNEWVEC (struct with
, withs_max
);
764 if (with_len
== withs_max
)
767 withs
= XRESIZEVEC (struct with
, withs
, withs_max
);
770 for (i
= 0; i
< with_len
; i
++)
771 if (!strcmp (s
, withs
[i
].s
)
772 && source_file_base
== withs
[i
].in_file
)
774 withs
[i
].limited
&= limited_access
;
778 withs
[with_len
].s
= xstrdup (s
);
779 withs
[with_len
].in_file
= source_file_base
;
780 withs
[with_len
].limited
= limited_access
;
784 /* Reset "with" clauses. */
787 reset_ada_withs (void)
794 for (i
= 0; i
< with_len
; i
++)
802 /* Dump "with" clauses in F. */
805 dump_ada_withs (FILE *f
)
809 fprintf (f
, "with Interfaces.C; use Interfaces.C;\n");
811 for (i
= 0; i
< with_len
; i
++)
813 (f
, "%swith %s;\n", withs
[i
].limited
? "limited " : "", withs
[i
].s
);
816 /* Return suitable Ada package name from FILE. */
819 get_ada_package (const char *file
)
827 s
= strstr (file
, "/include/");
831 base
= lbasename (file
);
833 if (ada_specs_parent
== NULL
)
836 plen
= strlen (ada_specs_parent
) + 1;
838 res
= XNEWVEC (char, plen
+ strlen (base
) + 1);
839 if (ada_specs_parent
!= NULL
) {
840 strcpy (res
, ada_specs_parent
);
844 for (i
= plen
; *base
; base
++, i
++)
856 res
[i
] = (i
== 0 || res
[i
- 1] == '.' || res
[i
- 1] == '_') ? 'u' : '_';
868 static const char *ada_reserved
[] = {
869 "abort", "abs", "abstract", "accept", "access", "aliased", "all", "and",
870 "array", "at", "begin", "body", "case", "constant", "declare", "delay",
871 "delta", "digits", "do", "else", "elsif", "end", "entry", "exception",
872 "exit", "for", "function", "generic", "goto", "if", "in", "interface", "is",
873 "limited", "loop", "mod", "new", "not", "null", "others", "out", "of", "or",
874 "overriding", "package", "pragma", "private", "procedure", "protected",
875 "raise", "range", "record", "rem", "renames", "requeue", "return", "reverse",
876 "select", "separate", "subtype", "synchronized", "tagged", "task",
877 "terminate", "then", "type", "until", "use", "when", "while", "with", "xor",
880 /* ??? would be nice to specify this list via a config file, so that users
881 can create their own dictionary of conflicts. */
882 static const char *c_duplicates
[] = {
883 /* system will cause troubles with System.Address. */
886 /* The following values have other definitions with same name/other
892 "rl_readline_version",
898 /* Return a declaration tree corresponding to TYPE. */
901 get_underlying_decl (tree type
)
903 tree decl
= NULL_TREE
;
905 if (type
== NULL_TREE
)
908 /* type is a declaration. */
912 /* type is a typedef. */
913 if (TYPE_P (type
) && TYPE_NAME (type
) && DECL_P (TYPE_NAME (type
)))
914 decl
= TYPE_NAME (type
);
916 /* TYPE_STUB_DECL has been set for type. */
917 if (TYPE_P (type
) && TYPE_STUB_DECL (type
) &&
918 DECL_P (TYPE_STUB_DECL (type
)))
919 decl
= TYPE_STUB_DECL (type
);
924 /* Return whether TYPE has static fields. */
927 has_static_fields (const_tree type
)
931 if (!type
|| !RECORD_OR_UNION_TYPE_P (type
))
934 for (tmp
= TYPE_FIELDS (type
); tmp
; tmp
= TREE_CHAIN (tmp
))
935 if (DECL_NAME (tmp
) && TREE_STATIC (tmp
))
941 /* Return whether TYPE corresponds to an Ada tagged type (has a dispatch
945 is_tagged_type (const_tree type
)
949 if (!type
|| !RECORD_OR_UNION_TYPE_P (type
))
952 for (tmp
= TYPE_METHODS (type
); tmp
; tmp
= TREE_CHAIN (tmp
))
953 if (DECL_VINDEX (tmp
))
959 /* Return whether TYPE has non-trivial methods, i.e. methods that do something
960 for the objects of TYPE. In C++, all classes have implicit special methods,
961 e.g. constructors and destructors, but they can be trivial if the type is
962 sufficiently simple. */
965 has_nontrivial_methods (tree type
)
969 if (!type
|| !RECORD_OR_UNION_TYPE_P (type
))
972 /* Only C++ types can have methods. */
976 /* A non-trivial type has non-trivial special methods. */
977 if (!cpp_check (type
, IS_TRIVIAL
))
980 /* If there are user-defined methods, they are deemed non-trivial. */
981 for (tmp
= TYPE_METHODS (type
); tmp
; tmp
= TREE_CHAIN (tmp
))
982 if (!DECL_ARTIFICIAL (tmp
))
988 /* Generate a legal Ada name from a C NAME, returning a malloc'd string.
989 SPACE_FOUND, if not NULL, is used to indicate whether a space was found in
993 to_ada_name (const char *name
, int *space_found
)
996 int len
= strlen (name
);
999 char *s
= XNEWVEC (char, len
* 2 + 5);
1003 *space_found
= false;
1005 /* Add trailing "c_" if name is an Ada reserved word. */
1006 for (names
= ada_reserved
; *names
; names
++)
1007 if (!strcasecmp (name
, *names
))
1016 /* Add trailing "c_" if name is an potential case sensitive duplicate. */
1017 for (names
= c_duplicates
; *names
; names
++)
1018 if (!strcmp (name
, *names
))
1026 for (j
= 0; name
[j
] == '_'; j
++)
1031 else if (*name
== '.' || *name
== '$')
1041 /* Replace unsuitable characters for Ada identifiers. */
1043 for (; j
< len
; j
++)
1048 *space_found
= true;
1052 /* ??? missing some C++ operators. */
1056 if (name
[j
+ 1] == '=')
1071 if (name
[j
+ 1] == '=')
1089 s
[len2
++] = name
[j
] == '&' ? 'a' : name
[j
] == '|' ? 'o' : 'x';
1091 if (name
[j
+ 1] == '=')
1104 if (s
[len2
- 1] != '_')
1107 switch (name
[j
+ 1]) {
1110 switch (name
[j
- 1]) {
1111 case '+': s
[len2
++] = 'p'; break; /* + */
1112 case '-': s
[len2
++] = 'm'; break; /* - */
1113 case '*': s
[len2
++] = 't'; break; /* * */
1114 case '/': s
[len2
++] = 'd'; break; /* / */
1120 switch (name
[j
- 1]) {
1121 case '+': s
[len2
++] = 'p'; break; /* += */
1122 case '-': s
[len2
++] = 'm'; break; /* -= */
1123 case '*': s
[len2
++] = 't'; break; /* *= */
1124 case '/': s
[len2
++] = 'd'; break; /* /= */
1158 c
= name
[j
] == '<' ? 'l' : 'g';
1161 switch (name
[j
+ 1]) {
1187 if (len2
&& s
[len2
- 1] == '_')
1192 s
[len2
++] = name
[j
];
1195 if (s
[len2
- 1] == '_')
1203 /* Return true if DECL refers to a C++ class type for which a
1204 separate enclosing package has been or should be generated. */
1207 separate_class_package (tree decl
)
1209 tree type
= TREE_TYPE (decl
);
1210 return has_nontrivial_methods (type
) || has_static_fields (type
);
1213 static bool package_prefix
= true;
1215 /* Dump in BUFFER the name of an identifier NODE of type TYPE, following Ada
1216 syntax. LIMITED_ACCESS indicates whether NODE can be accessed via a limited
1217 'with' clause rather than a regular 'with' clause. */
1220 pp_ada_tree_identifier (pretty_printer
*buffer
, tree node
, tree type
,
1223 const char *name
= IDENTIFIER_POINTER (node
);
1224 int space_found
= false;
1225 char *s
= to_ada_name (name
, &space_found
);
1228 /* If the entity is a type and comes from another file, generate "package"
1230 decl
= get_underlying_decl (type
);
1234 expanded_location xloc
= expand_location (decl_sloc (decl
, false));
1236 if (xloc
.file
&& xloc
.line
)
1238 if (xloc
.file
!= source_file_base
)
1240 switch (TREE_CODE (type
))
1245 case FIXED_POINT_TYPE
:
1247 case REFERENCE_TYPE
:
1252 case QUAL_UNION_TYPE
:
1256 char *s1
= get_ada_package (xloc
.file
);
1257 append_withs (s1
, limited_access
);
1258 pp_string (buffer
, s1
);
1267 /* Generate the additional package prefix for C++ classes. */
1268 if (separate_class_package (decl
))
1270 pp_string (buffer
, "Class_");
1271 pp_string (buffer
, s
);
1279 if (!strcmp (s
, "short_int"))
1280 pp_string (buffer
, "short");
1281 else if (!strcmp (s
, "short_unsigned_int"))
1282 pp_string (buffer
, "unsigned_short");
1283 else if (!strcmp (s
, "unsigned_int"))
1284 pp_string (buffer
, "unsigned");
1285 else if (!strcmp (s
, "long_int"))
1286 pp_string (buffer
, "long");
1287 else if (!strcmp (s
, "long_unsigned_int"))
1288 pp_string (buffer
, "unsigned_long");
1289 else if (!strcmp (s
, "long_long_int"))
1290 pp_string (buffer
, "Long_Long_Integer");
1291 else if (!strcmp (s
, "long_long_unsigned_int"))
1295 append_withs ("Interfaces.C.Extensions", false);
1296 pp_string (buffer
, "Extensions.unsigned_long_long");
1299 pp_string (buffer
, "unsigned_long_long");
1302 pp_string(buffer
, s
);
1304 if (!strcmp (s
, "bool"))
1308 append_withs ("Interfaces.C.Extensions", false);
1309 pp_string (buffer
, "Extensions.bool");
1312 pp_string (buffer
, "bool");
1315 pp_string(buffer
, s
);
1320 /* Dump in BUFFER the assembly name of T. */
1323 pp_asm_name (pretty_printer
*buffer
, tree t
)
1325 tree name
= DECL_ASSEMBLER_NAME (t
);
1326 char *ada_name
= XALLOCAVEC (char, IDENTIFIER_LENGTH (name
) + 1), *s
;
1327 const char *ident
= IDENTIFIER_POINTER (name
);
1329 for (s
= ada_name
; *ident
; ident
++)
1333 else if (*ident
!= '*')
1338 pp_string (buffer
, ada_name
);
1341 /* Dump in BUFFER the name of a DECL node if set, following Ada syntax.
1342 LIMITED_ACCESS indicates whether NODE can be accessed via a limited
1343 'with' clause rather than a regular 'with' clause. */
1346 dump_ada_decl_name (pretty_printer
*buffer
, tree decl
, int limited_access
)
1348 if (DECL_NAME (decl
))
1349 pp_ada_tree_identifier (buffer
, DECL_NAME (decl
), decl
, limited_access
);
1352 tree type_name
= TYPE_NAME (TREE_TYPE (decl
));
1356 pp_string (buffer
, "anon");
1357 if (TREE_CODE (decl
) == FIELD_DECL
)
1358 pp_scalar (buffer
, "%d", DECL_UID (decl
));
1360 pp_scalar (buffer
, "%d", TYPE_UID (TREE_TYPE (decl
)));
1362 else if (TREE_CODE (type_name
) == IDENTIFIER_NODE
)
1363 pp_ada_tree_identifier (buffer
, type_name
, decl
, limited_access
);
1367 /* Dump in BUFFER a name based on both T1 and T2, followed by S. */
1370 dump_ada_double_name (pretty_printer
*buffer
, tree t1
, tree t2
, const char *s
)
1373 pp_ada_tree_identifier (buffer
, DECL_NAME (t1
), t1
, false);
1376 pp_string (buffer
, "anon");
1377 pp_scalar (buffer
, "%d", TYPE_UID (TREE_TYPE (t1
)));
1380 pp_underscore (buffer
);
1383 pp_ada_tree_identifier (buffer
, DECL_NAME (t2
), t2
, false);
1386 pp_string (buffer
, "anon");
1387 pp_scalar (buffer
, "%d", TYPE_UID (TREE_TYPE (t2
)));
1390 pp_string (buffer
, s
);
1393 /* Dump in BUFFER pragma Import C/CPP on a given node T. */
1396 dump_ada_import (pretty_printer
*buffer
, tree t
)
1398 const char *name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t
));
1399 int is_stdcall
= TREE_CODE (t
) == FUNCTION_DECL
&&
1400 lookup_attribute ("stdcall", TYPE_ATTRIBUTES (TREE_TYPE (t
)));
1403 pp_string (buffer
, "pragma Import (Stdcall, ");
1404 else if (name
[0] == '_' && name
[1] == 'Z')
1405 pp_string (buffer
, "pragma Import (CPP, ");
1407 pp_string (buffer
, "pragma Import (C, ");
1409 dump_ada_decl_name (buffer
, t
, false);
1410 pp_string (buffer
, ", \"");
1413 pp_string (buffer
, IDENTIFIER_POINTER (DECL_NAME (t
)));
1415 pp_asm_name (buffer
, t
);
1417 pp_string (buffer
, "\");");
1420 /* Check whether T and its type have different names, and append "the_"
1421 otherwise in BUFFER. */
1424 check_name (pretty_printer
*buffer
, tree t
)
1427 tree tmp
= TREE_TYPE (t
);
1429 while (TREE_CODE (tmp
) == POINTER_TYPE
&& !TYPE_NAME (tmp
))
1430 tmp
= TREE_TYPE (tmp
);
1432 if (TREE_CODE (tmp
) != FUNCTION_TYPE
)
1434 if (TREE_CODE (tmp
) == IDENTIFIER_NODE
)
1435 s
= IDENTIFIER_POINTER (tmp
);
1436 else if (!TYPE_NAME (tmp
))
1438 else if (TREE_CODE (TYPE_NAME (tmp
)) == IDENTIFIER_NODE
)
1439 s
= IDENTIFIER_POINTER (TYPE_NAME (tmp
));
1441 s
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (tmp
)));
1443 if (!strcasecmp (IDENTIFIER_POINTER (DECL_NAME (t
)), s
))
1444 pp_string (buffer
, "the_");
1448 /* Dump in BUFFER a function declaration FUNC with Ada syntax.
1449 IS_METHOD indicates whether FUNC is a C++ method.
1450 IS_CONSTRUCTOR whether FUNC is a C++ constructor.
1451 IS_DESTRUCTOR whether FUNC is a C++ destructor.
1452 SPC is the current indentation level. */
1455 dump_ada_function_declaration (pretty_printer
*buffer
, tree func
,
1456 int is_method
, int is_constructor
,
1457 int is_destructor
, int spc
)
1460 const tree node
= TREE_TYPE (func
);
1462 int num
= 0, num_args
= 0, have_args
= true, have_ellipsis
= false;
1464 /* Compute number of arguments. */
1465 arg
= TYPE_ARG_TYPES (node
);
1469 while (TREE_CHAIN (arg
) && arg
!= error_mark_node
)
1472 arg
= TREE_CHAIN (arg
);
1475 if (TREE_CODE (TREE_VALUE (arg
)) != VOID_TYPE
)
1478 have_ellipsis
= true;
1489 newline_and_indent (buffer
, spc
+ 1);
1494 pp_left_paren (buffer
);
1497 if (TREE_CODE (func
) == FUNCTION_DECL
)
1498 arg
= DECL_ARGUMENTS (func
);
1502 if (arg
== NULL_TREE
)
1505 arg
= TYPE_ARG_TYPES (node
);
1507 if (arg
&& TREE_CODE (TREE_VALUE (arg
)) == VOID_TYPE
)
1512 arg
= TREE_CHAIN (arg
);
1514 /* Print the argument names (if available) & types. */
1516 for (num
= 1; num
<= num_args
; num
++)
1520 if (DECL_NAME (arg
))
1522 check_name (buffer
, arg
);
1523 pp_ada_tree_identifier (buffer
, DECL_NAME (arg
), 0, false);
1524 pp_string (buffer
, " : ");
1528 sprintf (buf
, "arg%d : ", num
);
1529 pp_string (buffer
, buf
);
1532 dump_generic_ada_node (buffer
, TREE_TYPE (arg
), node
, spc
, 0, true);
1536 sprintf (buf
, "arg%d : ", num
);
1537 pp_string (buffer
, buf
);
1538 dump_generic_ada_node (buffer
, TREE_VALUE (arg
), node
, 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_semicolon (buffer
);
1556 newline_and_indent (buffer
, spc
+ INDENT_INCR
);
1564 pp_string (buffer
, " -- , ...");
1565 newline_and_indent (buffer
, spc
+ INDENT_INCR
);
1569 pp_right_paren (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_left_paren (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
, 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
, spc
, 0, true);
1604 pp_string (buffer
, "0");
1607 pp_string (buffer
, "size_t");
1609 pp_right_paren (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
);
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
), 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. SPC is
1696 the indentation level. */
1699 dump_template_types (pretty_printer
*buffer
, tree types
, int spc
)
1702 size_t len
= TREE_VEC_LENGTH (types
);
1704 for (i
= 0; i
< len
; i
++)
1706 tree elem
= TREE_VEC_ELT (types
, i
);
1707 pp_underscore (buffer
);
1708 if (!dump_generic_ada_node (buffer
, elem
, 0, spc
, false, true))
1710 pp_string (buffer
, "unknown");
1711 pp_scalar (buffer
, "%lu", (unsigned long) TREE_HASH (elem
));
1716 /* Dump in BUFFER the contents of all class instantiations associated with
1717 a given template T. SPC is the indentation level. */
1720 dump_ada_template (pretty_printer
*buffer
, tree t
, int spc
)
1722 /* DECL_VINDEX is DECL_TEMPLATE_INSTANTIATIONS in this context. */
1723 tree inst
= DECL_VINDEX (t
);
1724 /* DECL_RESULT_FLD is DECL_TEMPLATE_RESULT in this context. */
1725 tree result
= DECL_RESULT_FLD (t
);
1728 /* Don't look at template declarations declaring something coming from
1729 another file. This can occur for template friend declarations. */
1730 if (LOCATION_FILE (decl_sloc (result
, false))
1731 != LOCATION_FILE (decl_sloc (t
, false)))
1734 while (inst
&& inst
!= error_mark_node
)
1736 tree types
= TREE_PURPOSE (inst
);
1737 tree instance
= TREE_VALUE (inst
);
1739 if (TREE_VEC_LENGTH (types
) == 0)
1742 if (!TYPE_P (instance
) || !TYPE_METHODS (instance
))
1747 pp_string (buffer
, "package ");
1748 package_prefix
= false;
1749 dump_generic_ada_node (buffer
, instance
, t
, spc
, false, true);
1750 dump_template_types (buffer
, types
, spc
);
1751 pp_string (buffer
, " is");
1753 newline_and_indent (buffer
, spc
);
1755 TREE_VISITED (get_underlying_decl (instance
)) = 1;
1756 pp_string (buffer
, "type ");
1757 dump_generic_ada_node (buffer
, instance
, t
, spc
, false, true);
1758 package_prefix
= true;
1760 if (is_tagged_type (instance
))
1761 pp_string (buffer
, " is tagged limited ");
1763 pp_string (buffer
, " is limited ");
1765 dump_generic_ada_node (buffer
, instance
, t
, spc
, false, false);
1766 pp_newline (buffer
);
1768 newline_and_indent (buffer
, spc
);
1770 pp_string (buffer
, "end;");
1771 newline_and_indent (buffer
, spc
);
1772 pp_string (buffer
, "use ");
1773 package_prefix
= false;
1774 dump_generic_ada_node (buffer
, instance
, t
, spc
, false, true);
1775 dump_template_types (buffer
, types
, spc
);
1776 package_prefix
= true;
1777 pp_semicolon (buffer
);
1778 pp_newline (buffer
);
1779 pp_newline (buffer
);
1781 inst
= TREE_CHAIN (inst
);
1784 return num_inst
> 0;
1787 /* Return true if NODE is a simple enum types, that can be mapped to an
1788 Ada enum type directly. */
1791 is_simple_enum (tree node
)
1793 HOST_WIDE_INT count
= 0;
1796 for (value
= TYPE_VALUES (node
); value
; value
= TREE_CHAIN (value
))
1798 tree int_val
= TREE_VALUE (value
);
1800 if (TREE_CODE (int_val
) != INTEGER_CST
)
1801 int_val
= DECL_INITIAL (int_val
);
1803 if (!tree_fits_shwi_p (int_val
))
1805 else if (tree_to_shwi (int_val
) != count
)
1814 static bool in_function
= true;
1815 static bool bitfield_used
= false;
1817 /* Recursively dump in BUFFER Ada declarations corresponding to NODE of type
1818 TYPE. SPC is the indentation level. LIMITED_ACCESS indicates whether NODE
1819 can be referenced via a "limited with" clause. NAME_ONLY indicates whether
1820 we should only dump the name of NODE, instead of its full declaration. */
1823 dump_generic_ada_node (pretty_printer
*buffer
, tree node
, tree type
, int spc
,
1824 int limited_access
, bool name_only
)
1826 if (node
== NULL_TREE
)
1829 switch (TREE_CODE (node
))
1832 pp_string (buffer
, "<<< error >>>");
1835 case IDENTIFIER_NODE
:
1836 pp_ada_tree_identifier (buffer
, node
, type
, limited_access
);
1840 pp_string (buffer
, "--- unexpected node: TREE_LIST");
1844 dump_generic_ada_node
1845 (buffer
, BINFO_TYPE (node
), type
, spc
, limited_access
, name_only
);
1848 pp_string (buffer
, "--- unexpected node: TREE_VEC");
1854 append_withs ("System", false);
1855 pp_string (buffer
, "System.Address");
1858 pp_string (buffer
, "address");
1862 pp_string (buffer
, "<vector>");
1866 pp_string (buffer
, "<complex>");
1871 dump_generic_ada_node
1872 (buffer
, TYPE_NAME (node
), node
, spc
, 0, true);
1875 tree value
= TYPE_VALUES (node
);
1877 if (is_simple_enum (node
))
1881 newline_and_indent (buffer
, spc
- 1);
1882 pp_left_paren (buffer
);
1883 for (; value
; value
= TREE_CHAIN (value
))
1890 newline_and_indent (buffer
, spc
);
1893 pp_ada_tree_identifier
1894 (buffer
, TREE_PURPOSE (value
), node
, false);
1896 pp_string (buffer
, ");");
1898 newline_and_indent (buffer
, spc
);
1899 pp_string (buffer
, "pragma Convention (C, ");
1900 dump_generic_ada_node
1901 (buffer
, DECL_NAME (type
) ? type
: TYPE_NAME (node
), type
,
1903 pp_right_paren (buffer
);
1907 pp_string (buffer
, "unsigned");
1908 for (; value
; value
= TREE_CHAIN (value
))
1910 pp_semicolon (buffer
);
1911 newline_and_indent (buffer
, spc
);
1913 pp_ada_tree_identifier
1914 (buffer
, TREE_PURPOSE (value
), node
, false);
1915 pp_string (buffer
, " : constant ");
1917 dump_generic_ada_node
1918 (buffer
, DECL_NAME (type
) ? type
: TYPE_NAME (node
), type
,
1921 pp_string (buffer
, " := ");
1922 dump_generic_ada_node
1924 TREE_CODE (TREE_VALUE (value
)) == INTEGER_CST
?
1925 TREE_VALUE (value
) : DECL_INITIAL (TREE_VALUE (value
)),
1926 node
, spc
, false, true);
1934 case FIXED_POINT_TYPE
:
1937 enum tree_code_class tclass
;
1939 tclass
= TREE_CODE_CLASS (TREE_CODE (node
));
1941 if (tclass
== tcc_declaration
)
1943 if (DECL_NAME (node
))
1944 pp_ada_tree_identifier
1945 (buffer
, DECL_NAME (node
), 0, limited_access
);
1947 pp_string (buffer
, "<unnamed type decl>");
1949 else if (tclass
== tcc_type
)
1951 if (TYPE_NAME (node
))
1953 if (TREE_CODE (TYPE_NAME (node
)) == IDENTIFIER_NODE
)
1954 pp_ada_tree_identifier (buffer
, TYPE_NAME (node
),
1955 node
, limited_access
);
1956 else if (TREE_CODE (TYPE_NAME (node
)) == TYPE_DECL
1957 && DECL_NAME (TYPE_NAME (node
)))
1958 dump_ada_decl_name (buffer
, TYPE_NAME (node
), limited_access
);
1960 pp_string (buffer
, "<unnamed type>");
1962 else if (TREE_CODE (node
) == INTEGER_TYPE
)
1964 append_withs ("Interfaces.C.Extensions", false);
1965 bitfield_used
= true;
1967 if (TYPE_PRECISION (node
) == 1)
1968 pp_string (buffer
, "Extensions.Unsigned_1");
1971 pp_string (buffer
, (TYPE_UNSIGNED (node
)
1972 ? "Extensions.Unsigned_"
1973 : "Extensions.Signed_"));
1974 pp_decimal_int (buffer
, TYPE_PRECISION (node
));
1978 pp_string (buffer
, "<unnamed type>");
1984 case REFERENCE_TYPE
:
1985 if (name_only
&& TYPE_NAME (node
))
1986 dump_generic_ada_node
1987 (buffer
, TYPE_NAME (node
), node
, spc
, limited_access
, true);
1989 else if (TREE_CODE (TREE_TYPE (node
)) == FUNCTION_TYPE
)
1991 tree fnode
= TREE_TYPE (node
);
1993 bool prev_in_function
= in_function
;
1995 if (VOID_TYPE_P (TREE_TYPE (fnode
)))
1997 is_function
= false;
1998 pp_string (buffer
, "access procedure");
2003 pp_string (buffer
, "access function");
2006 in_function
= is_function
;
2007 dump_ada_function_declaration
2008 (buffer
, node
, false, false, false, spc
+ INDENT_INCR
);
2009 in_function
= prev_in_function
;
2013 pp_string (buffer
, " return ");
2014 dump_generic_ada_node
2015 (buffer
, TREE_TYPE (fnode
), type
, spc
, 0, true);
2018 /* If we are dumping the full type, it means we are part of a
2019 type definition and need also a Convention C pragma. */
2022 pp_semicolon (buffer
);
2023 newline_and_indent (buffer
, spc
);
2024 pp_string (buffer
, "pragma Convention (C, ");
2025 dump_generic_ada_node
2026 (buffer
, type
, 0, spc
, false, true);
2027 pp_right_paren (buffer
);
2032 int is_access
= false;
2033 unsigned int quals
= TYPE_QUALS (TREE_TYPE (node
));
2035 if (VOID_TYPE_P (TREE_TYPE (node
)))
2038 pp_string (buffer
, "new ");
2041 append_withs ("System", false);
2042 pp_string (buffer
, "System.Address");
2045 pp_string (buffer
, "address");
2049 if (TREE_CODE (node
) == POINTER_TYPE
2050 && TREE_CODE (TREE_TYPE (node
)) == INTEGER_TYPE
2052 (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME
2053 (TREE_TYPE (node
)))), "char"))
2056 pp_string (buffer
, "new ");
2060 pp_string (buffer
, "Interfaces.C.Strings.chars_ptr");
2061 append_withs ("Interfaces.C.Strings", false);
2064 pp_string (buffer
, "chars_ptr");
2068 /* For now, handle all access-to-access or
2069 access-to-unknown-structs as opaque system.address. */
2071 tree type_name
= TYPE_NAME (TREE_TYPE (node
));
2072 const_tree typ2
= !type
||
2073 DECL_P (type
) ? type
: TYPE_NAME (type
);
2074 const_tree underlying_type
=
2075 get_underlying_decl (TREE_TYPE (node
));
2077 if (TREE_CODE (TREE_TYPE (node
)) == POINTER_TYPE
2078 /* Pointer to pointer. */
2080 || (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node
))
2081 && (!underlying_type
2082 || !TYPE_FIELDS (TREE_TYPE (underlying_type
))))
2083 /* Pointer to opaque structure. */
2085 || underlying_type
== NULL_TREE
2087 && !TREE_VISITED (underlying_type
)
2088 && !TREE_VISITED (type_name
)
2089 && !is_tagged_type (TREE_TYPE (node
))
2090 && DECL_SOURCE_FILE (underlying_type
)
2091 == source_file_base
)
2092 || (type_name
&& typ2
2093 && DECL_P (underlying_type
)
2095 && decl_sloc (underlying_type
, true)
2096 > decl_sloc (typ2
, true)
2097 && DECL_SOURCE_FILE (underlying_type
)
2098 == DECL_SOURCE_FILE (typ2
)))
2102 append_withs ("System", false);
2104 pp_string (buffer
, "new ");
2105 pp_string (buffer
, "System.Address");
2108 pp_string (buffer
, "address");
2112 if (!package_prefix
)
2113 pp_string (buffer
, "access");
2114 else if (AGGREGATE_TYPE_P (TREE_TYPE (node
)))
2116 if (!type
|| TREE_CODE (type
) != FUNCTION_DECL
)
2118 pp_string (buffer
, "access ");
2121 if (quals
& TYPE_QUAL_CONST
)
2122 pp_string (buffer
, "constant ");
2123 else if (!name_only
)
2124 pp_string (buffer
, "all ");
2126 else if (quals
& TYPE_QUAL_CONST
)
2127 pp_string (buffer
, "in ");
2128 else if (in_function
)
2131 pp_string (buffer
, "access ");
2136 pp_string (buffer
, "access ");
2137 /* ??? should be configurable: access or in out. */
2143 pp_string (buffer
, "access ");
2146 pp_string (buffer
, "all ");
2149 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node
))
2150 && type_name
!= NULL_TREE
)
2151 dump_generic_ada_node
2153 TREE_TYPE (node
), spc
, is_access
, true);
2155 dump_generic_ada_node
2156 (buffer
, TREE_TYPE (node
), TREE_TYPE (node
),
2165 dump_generic_ada_node
2166 (buffer
, TYPE_NAME (node
), node
, spc
, limited_access
, true);
2168 dump_ada_array_type (buffer
, node
, spc
);
2173 case QUAL_UNION_TYPE
:
2176 if (TYPE_NAME (node
))
2177 dump_generic_ada_node
2178 (buffer
, TYPE_NAME (node
), node
, spc
, limited_access
, true);
2181 pp_string (buffer
, "anon_");
2182 pp_scalar (buffer
, "%d", TYPE_UID (node
));
2186 print_ada_struct_decl (buffer
, node
, type
, spc
, true);
2190 /* We treat the upper half of the sizetype range as negative. This
2191 is consistent with the internal treatment and makes it possible
2192 to generate the (0 .. -1) range for flexible array members. */
2193 if (TREE_TYPE (node
) == sizetype
)
2194 node
= fold_convert (ssizetype
, node
);
2195 if (tree_fits_shwi_p (node
))
2196 pp_wide_integer (buffer
, tree_to_shwi (node
));
2197 else if (tree_fits_uhwi_p (node
))
2198 pp_unsigned_wide_integer (buffer
, tree_to_uhwi (node
));
2201 wide_int val
= node
;
2203 if (wi::neg_p (val
))
2208 sprintf (pp_buffer (buffer
)->digit_buffer
,
2209 "16#%" HOST_WIDE_INT_PRINT
"x",
2210 val
.elt (val
.get_len () - 1));
2211 for (i
= val
.get_len () - 2; i
>= 0; i
--)
2212 sprintf (pp_buffer (buffer
)->digit_buffer
,
2213 HOST_WIDE_INT_PRINT_PADDED_HEX
, val
.elt (i
));
2214 pp_string (buffer
, pp_buffer (buffer
)->digit_buffer
);
2227 dump_ada_decl_name (buffer
, node
, limited_access
);
2231 if (DECL_IS_BUILTIN (node
))
2233 /* Don't print the declaration of built-in types. */
2237 /* If we're in the middle of a declaration, defaults to
2241 append_withs ("System", false);
2242 pp_string (buffer
, "System.Address");
2245 pp_string (buffer
, "address");
2251 dump_ada_decl_name (buffer
, node
, limited_access
);
2254 if (is_tagged_type (TREE_TYPE (node
)))
2256 tree tmp
= TYPE_FIELDS (TREE_TYPE (node
));
2259 /* Look for ancestors. */
2260 for (; tmp
; tmp
= TREE_CHAIN (tmp
))
2262 if (!DECL_NAME (tmp
) && is_tagged_type (TREE_TYPE (tmp
)))
2266 pp_string (buffer
, "limited new ");
2270 pp_string (buffer
, " and ");
2273 (buffer
, TYPE_NAME (TREE_TYPE (tmp
)), false);
2277 pp_string (buffer
, first
? "tagged limited " : " with ");
2279 else if (has_nontrivial_methods (TREE_TYPE (node
)))
2280 pp_string (buffer
, "limited ");
2282 dump_generic_ada_node
2283 (buffer
, TREE_TYPE (node
), type
, spc
, false, false);
2290 case NAMESPACE_DECL
:
2291 dump_ada_decl_name (buffer
, node
, false);
2295 /* Ignore other nodes (e.g. expressions). */
2302 /* Dump in BUFFER NODE's methods. SPC is the indentation level. Return 1 if
2303 methods were printed, 0 otherwise. */
2306 print_ada_methods (pretty_printer
*buffer
, tree node
, int spc
)
2311 if (!has_nontrivial_methods (node
))
2314 pp_semicolon (buffer
);
2316 for (tmp
= TYPE_METHODS (node
); tmp
; tmp
= TREE_CHAIN (tmp
))
2320 pp_newline (buffer
);
2321 pp_newline (buffer
);
2323 res
= print_ada_declaration (buffer
, tmp
, node
, spc
);
2329 /* Dump in BUFFER anonymous types nested inside T's definition.
2330 PARENT is the parent node of T.
2331 FORWARD indicates whether a forward declaration of T should be generated.
2332 SPC is the indentation level. */
2335 dump_nested_types (pretty_printer
*buffer
, tree t
, tree parent
, bool forward
,
2338 tree field
, outer
, decl
;
2340 /* Avoid recursing over the same tree. */
2341 if (TREE_VISITED (t
))
2344 /* Find possible anonymous arrays/unions/structs recursively. */
2346 outer
= TREE_TYPE (t
);
2348 if (outer
== NULL_TREE
)
2353 pp_string (buffer
, "type ");
2354 dump_generic_ada_node (buffer
, t
, t
, spc
, false, true);
2355 pp_semicolon (buffer
);
2356 newline_and_indent (buffer
, spc
);
2357 TREE_VISITED (t
) = 1;
2360 field
= TYPE_FIELDS (outer
);
2363 if ((TREE_TYPE (field
) != outer
2364 || (TREE_CODE (TREE_TYPE (field
)) == POINTER_TYPE
2365 && TREE_TYPE (TREE_TYPE (field
)) != outer
))
2366 && (!TYPE_NAME (TREE_TYPE (field
))
2367 || (TREE_CODE (field
) == TYPE_DECL
2368 && DECL_NAME (field
) != DECL_NAME (t
)
2369 && TYPE_NAME (TREE_TYPE (field
)) != TYPE_NAME (outer
))))
2371 switch (TREE_CODE (TREE_TYPE (field
)))
2374 decl
= TREE_TYPE (TREE_TYPE (field
));
2376 if (TREE_CODE (decl
) == FUNCTION_TYPE
)
2377 for (decl
= TREE_TYPE (decl
);
2378 decl
&& TREE_CODE (decl
) == POINTER_TYPE
;
2379 decl
= TREE_TYPE (decl
))
2382 decl
= get_underlying_decl (decl
);
2386 && decl_sloc (decl
, true) > decl_sloc (t
, true)
2387 && DECL_SOURCE_FILE (decl
) == DECL_SOURCE_FILE (t
)
2388 && !TREE_VISITED (decl
)
2389 && !DECL_IS_BUILTIN (decl
)
2390 && (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl
))
2391 || TYPE_FIELDS (TREE_TYPE (decl
))))
2393 /* Generate forward declaration. */
2395 pp_string (buffer
, "type ");
2396 dump_generic_ada_node (buffer
, decl
, 0, spc
, false, true);
2397 pp_semicolon (buffer
);
2398 newline_and_indent (buffer
, spc
);
2400 /* Ensure we do not generate duplicate forward
2401 declarations for this type. */
2402 TREE_VISITED (decl
) = 1;
2407 /* Special case char arrays. */
2408 if (is_char_array (field
))
2409 pp_string (buffer
, "sub");
2411 pp_string (buffer
, "type ");
2412 dump_ada_double_name (buffer
, parent
, field
, "_array is ");
2413 dump_ada_array_type (buffer
, field
, spc
);
2414 pp_semicolon (buffer
);
2415 newline_and_indent (buffer
, spc
);
2419 TREE_VISITED (t
) = 1;
2420 dump_nested_types (buffer
, field
, t
, false, spc
);
2422 pp_string (buffer
, "type ");
2424 if (TYPE_NAME (TREE_TYPE (field
)))
2426 dump_generic_ada_node
2427 (buffer
, TYPE_NAME (TREE_TYPE (field
)), 0, spc
, false,
2429 pp_string (buffer
, " (discr : unsigned := 0) is ");
2430 print_ada_struct_decl
2431 (buffer
, TREE_TYPE (field
), t
, spc
, false);
2433 pp_string (buffer
, "pragma Convention (C_Pass_By_Copy, ");
2434 dump_generic_ada_node
2435 (buffer
, TREE_TYPE (field
), 0, spc
, false, true);
2436 pp_string (buffer
, ");");
2437 newline_and_indent (buffer
, spc
);
2439 pp_string (buffer
, "pragma Unchecked_Union (");
2440 dump_generic_ada_node
2441 (buffer
, TREE_TYPE (field
), 0, spc
, false, true);
2442 pp_string (buffer
, ");");
2446 dump_ada_double_name
2447 (buffer
, parent
, field
,
2448 "_union (discr : unsigned := 0) is ");
2449 print_ada_struct_decl
2450 (buffer
, TREE_TYPE (field
), t
, spc
, false);
2451 pp_string (buffer
, "pragma Convention (C_Pass_By_Copy, ");
2452 dump_ada_double_name (buffer
, parent
, field
, "_union);");
2453 newline_and_indent (buffer
, spc
);
2455 pp_string (buffer
, "pragma Unchecked_Union (");
2456 dump_ada_double_name (buffer
, parent
, field
, "_union);");
2459 newline_and_indent (buffer
, spc
);
2463 if (TYPE_NAME (TREE_TYPE (t
)) && !TREE_VISITED (t
))
2465 pp_string (buffer
, "type ");
2466 dump_generic_ada_node
2467 (buffer
, t
, parent
, spc
, false, true);
2468 pp_semicolon (buffer
);
2469 newline_and_indent (buffer
, spc
);
2472 TREE_VISITED (t
) = 1;
2473 dump_nested_types (buffer
, field
, t
, false, spc
);
2474 pp_string (buffer
, "type ");
2476 if (TYPE_NAME (TREE_TYPE (field
)))
2478 dump_generic_ada_node
2479 (buffer
, TREE_TYPE (field
), 0, spc
, false, true);
2480 pp_string (buffer
, " is ");
2481 print_ada_struct_decl
2482 (buffer
, TREE_TYPE (field
), t
, spc
, false);
2483 pp_string (buffer
, "pragma Convention (C_Pass_By_Copy, ");
2484 dump_generic_ada_node
2485 (buffer
, TREE_TYPE (field
), 0, spc
, false, true);
2486 pp_string (buffer
, ");");
2490 dump_ada_double_name
2491 (buffer
, parent
, field
, "_struct is ");
2492 print_ada_struct_decl
2493 (buffer
, TREE_TYPE (field
), t
, spc
, false);
2494 pp_string (buffer
, "pragma Convention (C_Pass_By_Copy, ");
2495 dump_ada_double_name (buffer
, parent
, field
, "_struct);");
2498 newline_and_indent (buffer
, spc
);
2505 field
= TREE_CHAIN (field
);
2508 TREE_VISITED (t
) = 1;
2511 /* Dump in BUFFER constructor spec corresponding to T. */
2514 print_constructor (pretty_printer
*buffer
, tree t
)
2516 tree decl_name
= DECL_NAME (DECL_ORIGIN (t
));
2518 pp_string (buffer
, "New_");
2519 pp_ada_tree_identifier (buffer
, decl_name
, t
, false);
2522 /* Dump in BUFFER destructor spec corresponding to T. */
2525 print_destructor (pretty_printer
*buffer
, tree t
)
2527 tree decl_name
= DECL_NAME (DECL_ORIGIN (t
));
2528 const char *s
= IDENTIFIER_POINTER (decl_name
);
2532 for (s
+= 2; *s
!= ' '; s
++)
2533 pp_character (buffer
, *s
);
2537 pp_string (buffer
, "Delete_");
2538 pp_ada_tree_identifier (buffer
, decl_name
, t
, false);
2542 /* Return the name of type T. */
2547 tree n
= TYPE_NAME (t
);
2549 if (TREE_CODE (n
) == IDENTIFIER_NODE
)
2550 return IDENTIFIER_POINTER (n
);
2552 return IDENTIFIER_POINTER (DECL_NAME (n
));
2555 /* Print in BUFFER the declaration of a variable T of type TYPE in Ada syntax.
2556 SPC is the indentation level. Return 1 if a declaration was printed,
2560 print_ada_declaration (pretty_printer
*buffer
, tree t
, tree type
, int spc
)
2562 int is_var
= 0, need_indent
= 0;
2563 int is_class
= false;
2564 tree name
= TYPE_NAME (TREE_TYPE (t
));
2565 tree decl_name
= DECL_NAME (t
);
2566 tree orig
= NULL_TREE
;
2568 if (cpp_check
&& cpp_check (t
, IS_TEMPLATE
))
2569 return dump_ada_template (buffer
, t
, spc
);
2571 if (TREE_CODE (t
) == CONST_DECL
&& TREE_CODE (TREE_TYPE (t
)) == ENUMERAL_TYPE
)
2572 /* Skip enumeral values: will be handled as part of the type itself. */
2575 if (TREE_CODE (t
) == TYPE_DECL
)
2577 orig
= DECL_ORIGINAL_TYPE (t
);
2579 if (orig
&& TYPE_STUB_DECL (orig
))
2581 tree stub
= TYPE_STUB_DECL (orig
);
2582 tree typ
= TREE_TYPE (stub
);
2584 if (TYPE_NAME (typ
))
2586 /* If types have same representation, and same name (ignoring
2587 casing), then ignore the second type. */
2588 if (type_name (typ
) == type_name (TREE_TYPE (t
))
2589 || !strcasecmp (type_name (typ
), type_name (TREE_TYPE (t
))))
2594 if (RECORD_OR_UNION_TYPE_P (typ
) && !TYPE_FIELDS (typ
))
2596 pp_string (buffer
, "-- skipped empty struct ");
2597 dump_generic_ada_node (buffer
, t
, type
, spc
, false, true);
2601 if (!TREE_VISITED (stub
)
2602 && DECL_SOURCE_FILE (stub
) == source_file_base
)
2603 dump_nested_types (buffer
, stub
, stub
, true, spc
);
2605 pp_string (buffer
, "subtype ");
2606 dump_generic_ada_node (buffer
, t
, type
, spc
, false, true);
2607 pp_string (buffer
, " is ");
2608 dump_generic_ada_node (buffer
, typ
, type
, spc
, false, true);
2609 pp_semicolon (buffer
);
2615 /* Skip unnamed or anonymous structs/unions/enum types. */
2616 if (!orig
&& !decl_name
&& !name
)
2621 if (cpp_check
|| TREE_CODE (TREE_TYPE (t
)) == ENUMERAL_TYPE
)
2624 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t
)))
2626 /* Search next items until finding a named type decl. */
2627 sloc
= decl_sloc_common (t
, true, true);
2629 for (tmp
= TREE_CHAIN (t
); tmp
; tmp
= TREE_CHAIN (tmp
))
2631 if (TREE_CODE (tmp
) == TYPE_DECL
2632 && (DECL_NAME (tmp
) || TYPE_NAME (TREE_TYPE (tmp
))))
2634 /* If same sloc, it means we can ignore the anonymous
2636 if (decl_sloc_common (tmp
, true, true) == sloc
)
2648 && TREE_CODE (TREE_TYPE (t
)) == ENUMERAL_TYPE
2650 && (*IDENTIFIER_POINTER (decl_name
) == '.'
2651 || *IDENTIFIER_POINTER (decl_name
) == '$'))
2652 /* Skip anonymous enum types (duplicates of real types). */
2657 switch (TREE_CODE (TREE_TYPE (t
)))
2661 case QUAL_UNION_TYPE
:
2662 /* Skip empty structs (typically forward references to real
2664 if (!TYPE_FIELDS (TREE_TYPE (t
)))
2666 pp_string (buffer
, "-- skipped empty struct ");
2667 dump_generic_ada_node (buffer
, t
, type
, spc
, false, true);
2672 && (*IDENTIFIER_POINTER (decl_name
) == '.'
2673 || *IDENTIFIER_POINTER (decl_name
) == '$'))
2675 pp_string (buffer
, "-- skipped anonymous struct ");
2676 dump_generic_ada_node (buffer
, t
, type
, spc
, false, true);
2677 TREE_VISITED (t
) = 1;
2681 if (orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
))
2682 pp_string (buffer
, "subtype ");
2685 dump_nested_types (buffer
, t
, t
, false, spc
);
2687 if (separate_class_package (t
))
2690 pp_string (buffer
, "package Class_");
2691 dump_generic_ada_node (buffer
, t
, type
, spc
, false, true);
2692 pp_string (buffer
, " is");
2694 newline_and_indent (buffer
, spc
);
2697 pp_string (buffer
, "type ");
2703 case REFERENCE_TYPE
:
2704 if ((orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
))
2705 || is_char_array (t
))
2706 pp_string (buffer
, "subtype ");
2708 pp_string (buffer
, "type ");
2712 pp_string (buffer
, "-- skipped function type ");
2713 dump_generic_ada_node (buffer
, t
, type
, spc
, false, true);
2718 if ((orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
))
2719 || !is_simple_enum (TREE_TYPE (t
)))
2720 pp_string (buffer
, "subtype ");
2722 pp_string (buffer
, "type ");
2726 pp_string (buffer
, "subtype ");
2728 TREE_VISITED (t
) = 1;
2732 if (TREE_CODE (t
) == VAR_DECL
2734 && *IDENTIFIER_POINTER (decl_name
) == '_')
2740 /* Print the type and name. */
2741 if (TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
)
2746 /* Print variable's name. */
2747 dump_generic_ada_node (buffer
, t
, type
, spc
, false, true);
2749 if (TREE_CODE (t
) == TYPE_DECL
)
2751 pp_string (buffer
, " is ");
2753 if (orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
))
2754 dump_generic_ada_node
2755 (buffer
, TYPE_NAME (orig
), type
, spc
, false, true);
2757 dump_ada_array_type (buffer
, t
, spc
);
2761 tree tmp
= TYPE_NAME (TREE_TYPE (t
));
2763 if (spc
== INDENT_INCR
|| TREE_STATIC (t
))
2766 pp_string (buffer
, " : ");
2770 if (TREE_CODE (TREE_TYPE (tmp
)) != POINTER_TYPE
2771 && TREE_CODE (tmp
) != INTEGER_TYPE
)
2772 pp_string (buffer
, "aliased ");
2774 dump_generic_ada_node (buffer
, tmp
, type
, spc
, false, true);
2778 pp_string (buffer
, "aliased ");
2781 dump_ada_array_type (buffer
, t
, spc
);
2783 dump_ada_double_name (buffer
, type
, t
, "_array");
2787 else if (TREE_CODE (t
) == FUNCTION_DECL
)
2789 bool is_function
, is_abstract_class
= false;
2790 bool is_method
= TREE_CODE (TREE_TYPE (t
)) == METHOD_TYPE
;
2791 tree decl_name
= DECL_NAME (t
);
2792 int prev_in_function
= in_function
;
2793 bool is_abstract
= false;
2794 bool is_constructor
= false;
2795 bool is_destructor
= false;
2796 bool is_copy_constructor
= false;
2803 is_abstract
= cpp_check (t
, IS_ABSTRACT
);
2804 is_constructor
= cpp_check (t
, IS_CONSTRUCTOR
);
2805 is_destructor
= cpp_check (t
, IS_DESTRUCTOR
);
2806 is_copy_constructor
= cpp_check (t
, IS_COPY_CONSTRUCTOR
);
2809 /* Skip copy constructors: some are internal only, and those that are
2810 not cannot be called easily from Ada anyway. */
2811 if (is_copy_constructor
)
2814 if (is_constructor
|| is_destructor
)
2816 /* Only consider constructors/destructors for complete objects. */
2817 if (strncmp (IDENTIFIER_POINTER (decl_name
), "__comp", 6) != 0)
2821 /* If this function has an entry in the vtable, we cannot omit it. */
2822 else if (!DECL_VINDEX (t
) && *IDENTIFIER_POINTER (decl_name
) == '_')
2825 pp_string (buffer
, "-- skipped func ");
2826 pp_string (buffer
, IDENTIFIER_POINTER (decl_name
));
2833 if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (t
))) && !is_constructor
)
2835 pp_string (buffer
, "procedure ");
2836 is_function
= false;
2840 pp_string (buffer
, "function ");
2844 in_function
= is_function
;
2847 print_constructor (buffer
, t
);
2848 else if (is_destructor
)
2849 print_destructor (buffer
, t
);
2851 dump_ada_decl_name (buffer
, t
, false);
2853 dump_ada_function_declaration
2854 (buffer
, t
, is_method
, is_constructor
, is_destructor
, spc
);
2855 in_function
= prev_in_function
;
2859 pp_string (buffer
, " return ");
2861 = is_constructor
? DECL_CONTEXT (t
) : TREE_TYPE (TREE_TYPE (t
));
2862 dump_generic_ada_node (buffer
, ret_type
, type
, spc
, false, true);
2866 && RECORD_OR_UNION_TYPE_P (type
)
2867 && TYPE_METHODS (type
))
2871 for (tmp
= TYPE_METHODS (type
); tmp
; tmp
= TREE_CHAIN (tmp
))
2872 if (cpp_check (tmp
, IS_ABSTRACT
))
2874 is_abstract_class
= true;
2879 if (is_abstract
|| is_abstract_class
)
2880 pp_string (buffer
, " is abstract");
2882 pp_semicolon (buffer
);
2883 pp_string (buffer
, " -- ");
2884 dump_sloc (buffer
, t
);
2886 if (is_abstract
|| !DECL_ASSEMBLER_NAME (t
))
2889 newline_and_indent (buffer
, spc
);
2893 pp_string (buffer
, "pragma CPP_Constructor (");
2894 print_constructor (buffer
, t
);
2895 pp_string (buffer
, ", \"");
2896 pp_asm_name (buffer
, t
);
2897 pp_string (buffer
, "\");");
2899 else if (is_destructor
)
2901 pp_string (buffer
, "pragma Import (CPP, ");
2902 print_destructor (buffer
, t
);
2903 pp_string (buffer
, ", \"");
2904 pp_asm_name (buffer
, t
);
2905 pp_string (buffer
, "\");");
2909 dump_ada_import (buffer
, t
);
2914 else if (TREE_CODE (t
) == TYPE_DECL
&& !DECL_ORIGINAL_TYPE (t
))
2916 int is_interface
= 0;
2917 int is_abstract_record
= 0;
2922 /* Anonymous structs/unions */
2923 dump_generic_ada_node (buffer
, TREE_TYPE (t
), t
, spc
, false, true);
2925 if (TREE_CODE (TREE_TYPE (t
)) == UNION_TYPE
2926 || TREE_CODE (TREE_TYPE (t
)) == QUAL_UNION_TYPE
)
2928 pp_string (buffer
, " (discr : unsigned := 0)");
2931 pp_string (buffer
, " is ");
2933 /* Check whether we have an Ada interface compatible class. */
2935 && RECORD_OR_UNION_TYPE_P (TREE_TYPE (t
))
2936 && TYPE_METHODS (TREE_TYPE (t
)))
2941 /* Check that there are no fields other than the virtual table. */
2942 for (tmp
= TYPE_FIELDS (TREE_TYPE (t
)); tmp
; tmp
= TREE_CHAIN (tmp
))
2944 if (TREE_CODE (tmp
) == TYPE_DECL
)
2949 if (num_fields
== 1)
2952 /* Also check that there are only virtual methods. */
2953 for (tmp
= TYPE_METHODS (TREE_TYPE (t
)); tmp
; tmp
= TREE_CHAIN (tmp
))
2955 if (cpp_check (tmp
, IS_ABSTRACT
))
2956 is_abstract_record
= 1;
2962 TREE_VISITED (t
) = 1;
2965 pp_string (buffer
, "limited interface; -- ");
2966 dump_sloc (buffer
, t
);
2967 newline_and_indent (buffer
, spc
);
2968 pp_string (buffer
, "pragma Import (CPP, ");
2969 dump_generic_ada_node
2970 (buffer
, TYPE_NAME (TREE_TYPE (t
)), type
, spc
, false, true);
2971 pp_right_paren (buffer
);
2973 print_ada_methods (buffer
, TREE_TYPE (t
), spc
);
2977 if (is_abstract_record
)
2978 pp_string (buffer
, "abstract ");
2979 dump_generic_ada_node (buffer
, t
, t
, spc
, false, false);
2987 if (TREE_CODE (t
) == FIELD_DECL
&& DECL_NAME (t
))
2988 check_name (buffer
, t
);
2990 /* Print variable/type's name. */
2991 dump_generic_ada_node (buffer
, t
, t
, spc
, false, true);
2993 if (TREE_CODE (t
) == TYPE_DECL
)
2995 tree orig
= DECL_ORIGINAL_TYPE (t
);
2996 int is_subtype
= orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
);
2999 && (TREE_CODE (TREE_TYPE (t
)) == UNION_TYPE
3000 || TREE_CODE (TREE_TYPE (t
)) == QUAL_UNION_TYPE
))
3001 pp_string (buffer
, " (discr : unsigned := 0)");
3003 pp_string (buffer
, " is ");
3005 dump_generic_ada_node (buffer
, orig
, t
, spc
, false, is_subtype
);
3009 if (spc
== INDENT_INCR
|| TREE_STATIC (t
))
3012 pp_string (buffer
, " : ");
3014 /* Print type declaration. */
3016 if (TREE_CODE (TREE_TYPE (t
)) == UNION_TYPE
3017 && !TYPE_NAME (TREE_TYPE (t
)))
3019 dump_ada_double_name (buffer
, type
, t
, "_union");
3021 else if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t
)))
3023 if (TREE_CODE (TREE_TYPE (t
)) == RECORD_TYPE
)
3024 pp_string (buffer
, "aliased ");
3026 dump_generic_ada_node
3027 (buffer
, TREE_TYPE (t
), t
, spc
, false, true);
3031 if (TREE_CODE (TREE_TYPE (t
)) != POINTER_TYPE
3032 && (TYPE_NAME (TREE_TYPE (t
))
3033 || TREE_CODE (TREE_TYPE (t
)) != INTEGER_TYPE
))
3034 pp_string (buffer
, "aliased ");
3036 dump_generic_ada_node
3037 (buffer
, TREE_TYPE (t
), TREE_TYPE (t
), spc
, false, true);
3045 newline_and_indent (buffer
, spc
);
3046 pp_string (buffer
, "end;");
3047 newline_and_indent (buffer
, spc
);
3048 pp_string (buffer
, "use Class_");
3049 dump_generic_ada_node (buffer
, t
, type
, spc
, false, true);
3050 pp_semicolon (buffer
);
3051 pp_newline (buffer
);
3053 /* All needed indentation/newline performed already, so return 0. */
3058 pp_string (buffer
, "; -- ");
3059 dump_sloc (buffer
, t
);
3064 newline_and_indent (buffer
, spc
);
3065 dump_ada_import (buffer
, t
);
3071 /* Prints in BUFFER a structure NODE of type TYPE: name, fields, and methods
3072 with Ada syntax. SPC is the indentation level. If DISPLAY_CONVENTION is
3073 true, also print the pragma Convention for NODE. */
3076 print_ada_struct_decl (pretty_printer
*buffer
, tree node
, tree type
, int spc
,
3077 bool display_convention
)
3081 = TREE_CODE (node
) == UNION_TYPE
|| TREE_CODE (node
) == QUAL_UNION_TYPE
;
3084 int field_spc
= spc
+ INDENT_INCR
;
3087 bitfield_used
= false;
3089 if (!TYPE_FIELDS (node
))
3090 pp_string (buffer
, "null record;");
3093 pp_string (buffer
, "record");
3095 /* Print the contents of the structure. */
3099 newline_and_indent (buffer
, spc
+ INDENT_INCR
);
3100 pp_string (buffer
, "case discr is");
3101 field_spc
= spc
+ INDENT_INCR
* 3;
3104 pp_newline (buffer
);
3106 /* Print the non-static fields of the structure. */
3107 for (tmp
= TYPE_FIELDS (node
); tmp
; tmp
= TREE_CHAIN (tmp
))
3109 /* Add parent field if needed. */
3110 if (!DECL_NAME (tmp
))
3112 if (!is_tagged_type (TREE_TYPE (tmp
)))
3114 if (!TYPE_NAME (TREE_TYPE (tmp
)))
3115 print_ada_declaration (buffer
, tmp
, type
, field_spc
);
3121 pp_string (buffer
, "parent : aliased ");
3124 sprintf (buf
, "field_%d : aliased ", field_num
+ 1);
3125 pp_string (buffer
, buf
);
3128 (buffer
, TYPE_NAME (TREE_TYPE (tmp
)), false);
3129 pp_semicolon (buffer
);
3131 pp_newline (buffer
);
3135 /* Avoid printing the structure recursively. */
3136 else if ((TREE_TYPE (tmp
) != node
3137 || (TREE_CODE (TREE_TYPE (tmp
)) == POINTER_TYPE
3138 && TREE_TYPE (TREE_TYPE (tmp
)) != node
))
3139 && TREE_CODE (tmp
) != TYPE_DECL
3140 && !TREE_STATIC (tmp
))
3142 /* Skip internal virtual table field. */
3143 if (strncmp (IDENTIFIER_POINTER (DECL_NAME (tmp
)), "_vptr", 5))
3147 if (TREE_CHAIN (tmp
)
3148 && TREE_TYPE (TREE_CHAIN (tmp
)) != node
3149 && TREE_CODE (TREE_CHAIN (tmp
)) != TYPE_DECL
)
3150 sprintf (buf
, "when %d =>", field_num
);
3152 sprintf (buf
, "when others =>");
3154 INDENT (spc
+ INDENT_INCR
* 2);
3155 pp_string (buffer
, buf
);
3156 pp_newline (buffer
);
3159 if (print_ada_declaration (buffer
, tmp
, type
, field_spc
))
3161 pp_newline (buffer
);
3170 INDENT (spc
+ INDENT_INCR
);
3171 pp_string (buffer
, "end case;");
3172 pp_newline (buffer
);
3177 INDENT (spc
+ INDENT_INCR
);
3178 pp_string (buffer
, "null;");
3179 pp_newline (buffer
);
3183 pp_string (buffer
, "end record;");
3186 newline_and_indent (buffer
, spc
);
3188 if (!display_convention
)
3191 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type
)))
3193 if (has_nontrivial_methods (TREE_TYPE (type
)))
3194 pp_string (buffer
, "pragma Import (CPP, ");
3196 pp_string (buffer
, "pragma Convention (C_Pass_By_Copy, ");
3199 pp_string (buffer
, "pragma Convention (C, ");
3201 package_prefix
= false;
3202 dump_generic_ada_node (buffer
, TREE_TYPE (type
), type
, spc
, false, true);
3203 package_prefix
= true;
3204 pp_right_paren (buffer
);
3208 pp_semicolon (buffer
);
3209 newline_and_indent (buffer
, spc
);
3210 pp_string (buffer
, "pragma Unchecked_Union (");
3212 dump_generic_ada_node (buffer
, TREE_TYPE (type
), type
, spc
, false, true);
3213 pp_right_paren (buffer
);
3218 pp_semicolon (buffer
);
3219 newline_and_indent (buffer
, spc
);
3220 pp_string (buffer
, "pragma Pack (");
3221 dump_generic_ada_node
3222 (buffer
, TREE_TYPE (type
), type
, spc
, false, true);
3223 pp_right_paren (buffer
);
3224 bitfield_used
= false;
3227 need_semicolon
= !print_ada_methods (buffer
, node
, spc
);
3229 /* Print the static fields of the structure, if any. */
3230 for (tmp
= TYPE_FIELDS (node
); tmp
; tmp
= TREE_CHAIN (tmp
))
3232 if (DECL_NAME (tmp
) && TREE_STATIC (tmp
))
3236 need_semicolon
= false;
3237 pp_semicolon (buffer
);
3239 pp_newline (buffer
);
3240 pp_newline (buffer
);
3241 print_ada_declaration (buffer
, tmp
, type
, spc
);
3246 /* Dump all the declarations in SOURCE_FILE to an Ada spec.
3247 COLLECT_ALL_REFS is a front-end callback used to collect all relevant
3248 nodes for SOURCE_FILE. CHECK is used to perform C++ queries on nodes. */
3251 dump_ads (const char *source_file
,
3252 void (*collect_all_refs
)(const char *),
3253 int (*check
)(tree
, cpp_operation
))
3260 pkg_name
= get_ada_package (source_file
);
3262 /* Construct the .ads filename and package name. */
3263 ads_name
= xstrdup (pkg_name
);
3265 for (s
= ads_name
; *s
; s
++)
3271 ads_name
= reconcat (ads_name
, ads_name
, ".ads", NULL
);
3273 /* Write out the .ads file. */
3274 f
= fopen (ads_name
, "w");
3279 pp_needs_newline (&pp
) = true;
3280 pp
.buffer
->stream
= f
;
3282 /* Dump all relevant macros. */
3283 dump_ada_macros (&pp
, source_file
);
3285 /* Reset the table of withs for this file. */
3288 (*collect_all_refs
) (source_file
);
3290 /* Dump all references. */
3292 dump_ada_nodes (&pp
, source_file
);
3294 /* Requires Ada 2005 syntax, so generate corresponding pragma.
3295 Also, disable style checks since this file is auto-generated. */
3296 fprintf (f
, "pragma Ada_2005;\npragma Style_Checks (Off);\n\n");
3301 fprintf (f
, "\npackage %s is\n\n", pkg_name
);
3302 pp_write_text_to_stream (&pp
);
3303 /* ??? need to free pp */
3304 fprintf (f
, "end %s;\n", pkg_name
);
3312 static const char **source_refs
= NULL
;
3313 static int source_refs_used
= 0;
3314 static int source_refs_allocd
= 0;
3316 /* Add an entry for FILENAME to the table SOURCE_REFS. */
3319 collect_source_ref (const char *filename
)
3326 if (source_refs_allocd
== 0)
3328 source_refs_allocd
= 1024;
3329 source_refs
= XNEWVEC (const char *, source_refs_allocd
);
3332 for (i
= 0; i
< source_refs_used
; i
++)
3333 if (filename
== source_refs
[i
])
3336 if (source_refs_used
== source_refs_allocd
)
3338 source_refs_allocd
*= 2;
3339 source_refs
= XRESIZEVEC (const char *, source_refs
, source_refs_allocd
);
3342 source_refs
[source_refs_used
++] = filename
;
3345 /* Main entry point: dump all Ada specs corresponding to SOURCE_REFS
3346 using callbacks COLLECT_ALL_REFS and CHECK.
3347 COLLECT_ALL_REFS is a front-end callback used to collect all relevant
3348 nodes for a given source file.
3349 CHECK is used to perform C++ queries on nodes, or NULL for the C
3353 dump_ada_specs (void (*collect_all_refs
)(const char *),
3354 int (*check
)(tree
, cpp_operation
))
3358 /* Iterate over the list of files to dump specs for */
3359 for (i
= 0; i
< source_refs_used
; i
++)
3360 dump_ads (source_refs
[i
], collect_all_refs
, check
);
3362 /* Free files table. */