1 /* Print GENERIC declaration (functions, variables, types) trees coming from
2 the C and C++ front-ends as well as macros in Ada syntax.
3 Copyright (C) 2010 Free Software Foundation, Inc.
4 Adapted from tree-pretty-print.c by Arnaud Charlet <charlet@adacore.com>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
24 #include "coretypes.h"
27 #include "tree-pass.h" /* For TDI_ada and friends. */
29 #include "c-ada-spec.h"
32 #include "cpp-id-data.h"
34 /* Local functions, macros and variables. */
35 static int dump_generic_ada_node (pretty_printer
*, tree
, tree
,
36 int (*)(tree
, cpp_operation
), int, int, bool);
37 static int print_ada_declaration (pretty_printer
*, tree
, tree
,
38 int (*cpp_check
)(tree
, cpp_operation
), int);
39 static void print_ada_struct_decl (pretty_printer
*, tree
, tree
,
40 int (*cpp_check
)(tree
, cpp_operation
), int,
42 static void dump_sloc (pretty_printer
*buffer
, tree node
);
43 static void print_comment (pretty_printer
*, const char *);
44 static void print_generic_ada_decl (pretty_printer
*, tree
,
45 int (*)(tree
, cpp_operation
), const char *);
46 static char *get_ada_package (const char *);
47 static void dump_ada_nodes (pretty_printer
*, const char *,
48 int (*)(tree
, cpp_operation
));
49 static void reset_ada_withs (void);
50 static void dump_ada_withs (FILE *);
51 static void dump_ads (const char *, void (*)(const char *),
52 int (*)(tree
, cpp_operation
));
53 static char *to_ada_name (const char *, int *);
55 #define LOCATION_COL(LOC) ((expand_location (LOC)).column)
57 #define INDENT(SPACE) do { \
58 int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
62 /* Given a cpp MACRO, compute the max length BUFFER_LEN of the macro, as well
63 as max length PARAM_LEN of arguments for fun_like macros, and also set
64 SUPPORTED to 0 if the macro cannot be mapped to an Ada construct. */
67 macro_length (const cpp_macro
*macro
, int *supported
, int *buffer_len
,
80 for (i
= 0; i
< macro
->paramc
; i
++)
82 cpp_hashnode
*param
= macro
->params
[i
];
84 *param_len
+= NODE_LEN (param
);
86 if (i
+ 1 < macro
->paramc
)
88 *param_len
+= 2; /* ", " */
90 else if (macro
->variadic
)
96 *param_len
+= 2; /* ")\0" */
99 for (j
= 0; j
< macro
->count
; j
++)
101 cpp_token
*token
= ¯o
->exp
.tokens
[j
];
103 if (token
->flags
& PREV_WHITE
)
106 if (token
->flags
& STRINGIFY_ARG
|| token
->flags
& PASTE_LEFT
)
112 if (token
->type
== CPP_MACRO_ARG
)
114 NODE_LEN (macro
->params
[token
->val
.macro_arg
.arg_no
- 1]);
116 /* Include enough extra space to handle e.g. special characters. */
117 *buffer_len
+= (cpp_token_len (token
) + 1) * 8;
123 /* Dump into PP a set of MAX_ADA_MACROS MACROS (C/C++) as Ada constants when
127 print_ada_macros (pretty_printer
*pp
, cpp_hashnode
**macros
, int max_ada_macros
)
129 int j
, num_macros
= 0, prev_line
= -1;
131 for (j
= 0; j
< max_ada_macros
; j
++)
133 cpp_hashnode
*node
= macros
[j
];
134 const cpp_macro
*macro
= node
->value
.macro
;
136 int supported
= 1, prev_is_one
= 0, buffer_len
, param_len
;
137 int is_string
= 0, is_char
= 0;
139 unsigned char *s
, *params
, *buffer
, *buf_param
, *char_one
= NULL
;
141 macro_length (macro
, &supported
, &buffer_len
, ¶m_len
);
142 s
= buffer
= XALLOCAVEC (unsigned char, buffer_len
);
143 params
= buf_param
= XALLOCAVEC (unsigned char, param_len
);
150 for (i
= 0; i
< macro
->paramc
; i
++)
152 cpp_hashnode
*param
= macro
->params
[i
];
154 memcpy (buf_param
, NODE_NAME (param
), NODE_LEN (param
));
155 buf_param
+= NODE_LEN (param
);
157 if (i
+ 1 < macro
->paramc
)
162 else if (macro
->variadic
)
172 for (i
= 0; supported
&& i
< macro
->count
; i
++)
174 cpp_token
*token
= ¯o
->exp
.tokens
[i
];
177 if (token
->flags
& PREV_WHITE
)
180 if (token
->flags
& STRINGIFY_ARG
|| token
->flags
& PASTE_LEFT
)
190 cpp_hashnode
*param
=
191 macro
->params
[token
->val
.macro_arg
.arg_no
- 1];
192 memcpy (buffer
, NODE_NAME (param
), NODE_LEN (param
));
193 buffer
+= NODE_LEN (param
);
197 case CPP_EQ_EQ
: *buffer
++ = '='; break;
198 case CPP_GREATER
: *buffer
++ = '>'; break;
199 case CPP_LESS
: *buffer
++ = '<'; break;
200 case CPP_PLUS
: *buffer
++ = '+'; break;
201 case CPP_MINUS
: *buffer
++ = '-'; break;
202 case CPP_MULT
: *buffer
++ = '*'; break;
203 case CPP_DIV
: *buffer
++ = '/'; break;
204 case CPP_COMMA
: *buffer
++ = ','; break;
205 case CPP_OPEN_SQUARE
:
206 case CPP_OPEN_PAREN
: *buffer
++ = '('; break;
207 case CPP_CLOSE_SQUARE
: /* fallthrough */
208 case CPP_CLOSE_PAREN
: *buffer
++ = ')'; break;
209 case CPP_DEREF
: /* fallthrough */
210 case CPP_SCOPE
: /* fallthrough */
211 case CPP_DOT
: *buffer
++ = '.'; break;
213 case CPP_EQ
: *buffer
++ = ':'; *buffer
++ = '='; break;
214 case CPP_NOT_EQ
: *buffer
++ = '/'; *buffer
++ = '='; break;
215 case CPP_GREATER_EQ
: *buffer
++ = '>'; *buffer
++ = '='; break;
216 case CPP_LESS_EQ
: *buffer
++ = '<'; *buffer
++ = '='; break;
219 *buffer
++ = 'n'; *buffer
++ = 'o'; *buffer
++ = 't'; break;
221 *buffer
++ = 'm'; *buffer
++ = 'o'; *buffer
++ = 'd'; break;
223 *buffer
++ = 'a'; *buffer
++ = 'n'; *buffer
++ = 'd'; break;
225 *buffer
++ = 'o'; *buffer
++ = 'r'; break;
227 *buffer
++ = 'x'; *buffer
++ = 'o'; *buffer
++ = 'r'; break;
229 strcpy ((char *) buffer
, " and then ");
233 strcpy ((char *) buffer
, " or else ");
239 is_one
= prev_is_one
;
242 case CPP_COMMENT
: break;
254 if (!macro
->fun_like
)
257 buffer
= cpp_spell_token (parse_in
, token
, buffer
, false);
267 c
= cpp_interpret_charconst (parse_in
, token
,
268 &chars_seen
, &ignored
);
269 if (c
>= 32 && c
<= 126)
272 *buffer
++ = (char) c
;
278 ((char *) buffer
, "Character'Val (%d)", (int) c
);
279 buffer
+= chars_seen
;
287 /* Replace "1 << N" by "2 ** N" */
314 case CPP_CLOSE_BRACE
:
318 case CPP_MINUS_MINUS
:
322 case CPP_HEADER_NAME
:
325 case CPP_OBJC_STRING
:
327 if (!macro
->fun_like
)
330 buffer
= cpp_spell_token (parse_in
, token
, buffer
, false);
334 prev_is_one
= is_one
;
341 if (macro
->fun_like
&& supported
)
343 char *start
= (char *) s
;
346 pp_string (pp
, " -- arg-macro: ");
348 if (*start
== '(' && buffer
[-1] == ')')
353 pp_string (pp
, "function ");
357 pp_string (pp
, "procedure ");
360 pp_string (pp
, (const char *) NODE_NAME (node
));
362 pp_string (pp
, (char *) params
);
364 pp_string (pp
, " -- ");
368 pp_string (pp
, "return ");
369 pp_string (pp
, start
);
373 pp_string (pp
, start
);
379 expanded_location sloc
= expand_location (macro
->line
);
381 if (sloc
.line
!= prev_line
+ 1)
385 prev_line
= sloc
.line
;
388 ada_name
= to_ada_name ((const char *) NODE_NAME (node
), NULL
);
389 pp_string (pp
, ada_name
);
391 pp_string (pp
, " : ");
394 pp_string (pp
, "aliased constant String");
396 pp_string (pp
, "aliased constant Character");
398 pp_string (pp
, "constant");
400 pp_string (pp
, " := ");
401 pp_string (pp
, (char *) s
);
404 pp_string (pp
, " & ASCII.NUL");
406 pp_string (pp
, "; -- ");
407 pp_string (pp
, sloc
.file
);
408 pp_character (pp
, ':');
409 pp_scalar (pp
, "%d", sloc
.line
);
414 pp_string (pp
, " -- unsupported macro: ");
415 pp_string (pp
, (const char *) cpp_macro_definition (parse_in
, node
));
424 static const char *source_file
;
425 static int max_ada_macros
;
427 /* Callback used to count the number of relevant macros from
428 cpp_forall_identifiers. PFILE and V are not used. NODE is the current macro
432 count_ada_macro (cpp_reader
*pfile ATTRIBUTE_UNUSED
, cpp_hashnode
*node
,
433 void *v ATTRIBUTE_UNUSED
)
435 const cpp_macro
*macro
= node
->value
.macro
;
437 if (node
->type
== NT_MACRO
&& !(node
->flags
& NODE_BUILTIN
)
439 && *NODE_NAME (node
) != '_'
440 && LOCATION_FILE (macro
->line
) == source_file
)
446 static int store_ada_macro_index
;
448 /* Callback used to store relevant macros from cpp_forall_identifiers.
449 PFILE is not used. NODE is the current macro to store if relevant.
450 MACROS is an array of cpp_hashnode* used to store NODE. */
453 store_ada_macro (cpp_reader
*pfile ATTRIBUTE_UNUSED
,
454 cpp_hashnode
*node
, void *macros
)
456 const cpp_macro
*macro
= node
->value
.macro
;
458 if (node
->type
== NT_MACRO
&& !(node
->flags
& NODE_BUILTIN
)
460 && *NODE_NAME (node
) != '_'
461 && LOCATION_FILE (macro
->line
) == source_file
)
462 ((cpp_hashnode
**) macros
)[store_ada_macro_index
++] = node
;
467 /* Callback used to compare (during qsort) macros. NODE1 and NODE2 are the
468 two macro nodes to compare. */
471 compare_macro (const void *node1
, const void *node2
)
473 typedef const cpp_hashnode
*const_hnode
;
475 const_hnode n1
= *(const const_hnode
*) node1
;
476 const_hnode n2
= *(const const_hnode
*) node2
;
478 return n1
->value
.macro
->line
- n2
->value
.macro
->line
;
481 /* Dump in PP all relevant macros appearing in FILE. */
484 dump_ada_macros (pretty_printer
*pp
, const char* file
)
486 cpp_hashnode
**macros
;
488 /* Initialize file-scope variables. */
490 store_ada_macro_index
= 0;
493 /* Count all potentially relevant macros, and then sort them by sloc. */
494 cpp_forall_identifiers (parse_in
, count_ada_macro
, NULL
);
495 macros
= XALLOCAVEC (cpp_hashnode
*, max_ada_macros
);
496 cpp_forall_identifiers (parse_in
, store_ada_macro
, macros
);
497 qsort (macros
, max_ada_macros
, sizeof (cpp_hashnode
*), compare_macro
);
499 print_ada_macros (pp
, macros
, max_ada_macros
);
502 /* Current source file being handled. */
504 static const char *source_file_base
;
506 /* Compare the declaration (DECL) of struct-like types based on the sloc of
507 their last field (if LAST is true), so that more nested types collate before
509 If ORIG_TYPE is true, also consider struct with a DECL_ORIGINAL_TYPE. */
512 decl_sloc_common (const_tree decl
, bool last
, bool orig_type
)
514 tree type
= TREE_TYPE (decl
);
516 if (TREE_CODE (decl
) == TYPE_DECL
517 && (orig_type
|| !DECL_ORIGINAL_TYPE (decl
))
518 && RECORD_OR_UNION_TYPE_P (type
)
519 && TYPE_FIELDS (type
))
521 tree f
= TYPE_FIELDS (type
);
524 while (TREE_CHAIN (f
))
527 return DECL_SOURCE_LOCATION (f
);
530 return DECL_SOURCE_LOCATION (decl
);
533 /* Return sloc of DECL, using sloc of last field if LAST is true. */
536 decl_sloc (const_tree decl
, bool last
)
538 return decl_sloc_common (decl
, last
, false);
541 /* Compare two declarations (LP and RP) by their source location. */
544 compare_node (const void *lp
, const void *rp
)
546 const_tree lhs
= *((const tree
*) lp
);
547 const_tree rhs
= *((const tree
*) rp
);
549 return decl_sloc (lhs
, true) - decl_sloc (rhs
, true);
552 /* Compare two comments (LP and RP) by their source location. */
555 compare_comment (const void *lp
, const void *rp
)
557 const cpp_comment
*lhs
= (const cpp_comment
*) lp
;
558 const cpp_comment
*rhs
= (const cpp_comment
*) rp
;
560 if (LOCATION_FILE (lhs
->sloc
) != LOCATION_FILE (rhs
->sloc
))
561 return strcmp (LOCATION_FILE (lhs
->sloc
), LOCATION_FILE (rhs
->sloc
));
563 if (LOCATION_LINE (lhs
->sloc
) != LOCATION_LINE (rhs
->sloc
))
564 return LOCATION_LINE (lhs
->sloc
) - LOCATION_LINE (rhs
->sloc
);
566 if (LOCATION_COL (lhs
->sloc
) != LOCATION_COL (rhs
->sloc
))
567 return LOCATION_COL (lhs
->sloc
) - LOCATION_COL (rhs
->sloc
);
572 static tree
*to_dump
= NULL
;
573 static int to_dump_count
= 0;
575 /* Collect a list of declarations from T relevant to SOURCE_FILE to be dumped
576 by a subsequent call to dump_ada_nodes. */
579 collect_ada_nodes (tree t
, const char *source_file
)
582 int i
= to_dump_count
;
584 /* Count the likely relevant nodes. */
585 for (n
= t
; n
; n
= TREE_CHAIN (n
))
586 if (!DECL_IS_BUILTIN (n
)
587 && LOCATION_FILE (decl_sloc (n
, false)) == source_file
)
590 /* Allocate sufficient storage for all nodes. */
591 to_dump
= XRESIZEVEC (tree
, to_dump
, to_dump_count
);
593 /* Store the 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
)
600 /* Call back for walk_tree to clear the TREE_VISITED flag of TP. */
603 unmark_visited_r (tree
*tp
, int *walk_subtrees ATTRIBUTE_UNUSED
,
604 void *data ATTRIBUTE_UNUSED
)
606 if (TREE_VISITED (*tp
))
607 TREE_VISITED (*tp
) = 0;
614 /* Dump nodes into PP relevant to SOURCE_FILE, as collected by previous calls
615 to collect_ada_nodes. CPP_CHECK is used to perform C++ queries on nodes. */
618 dump_ada_nodes (pretty_printer
*pp
, const char *source_file
,
619 int (*cpp_check
)(tree
, cpp_operation
))
622 cpp_comment_table
*comments
;
624 /* Sort the table of declarations to dump by sloc. */
625 qsort (to_dump
, to_dump_count
, sizeof (tree
), compare_node
);
627 /* Fetch the table of comments. */
628 comments
= cpp_get_comments (parse_in
);
630 /* Sort the comments table by sloc. */
631 qsort (comments
->entries
, comments
->count
, sizeof (cpp_comment
),
634 /* Interleave comments and declarations in line number order. */
638 /* Advance j until comment j is in this file. */
639 while (j
!= comments
->count
640 && LOCATION_FILE (comments
->entries
[j
].sloc
) != source_file
)
643 /* Advance j until comment j is not a duplicate. */
644 while (j
< comments
->count
- 1
645 && !compare_comment (&comments
->entries
[j
],
646 &comments
->entries
[j
+ 1]))
649 /* Write decls until decl i collates after comment j. */
650 while (i
!= to_dump_count
)
652 if (j
== comments
->count
653 || LOCATION_LINE (decl_sloc (to_dump
[i
], false))
654 < LOCATION_LINE (comments
->entries
[j
].sloc
))
655 print_generic_ada_decl (pp
, to_dump
[i
++], cpp_check
, source_file
);
660 /* Write comment j, if there is one. */
661 if (j
!= comments
->count
)
662 print_comment (pp
, comments
->entries
[j
++].comment
);
664 } while (i
!= to_dump_count
|| j
!= comments
->count
);
666 /* Clear the TREE_VISITED flag over each subtree we've dumped. */
667 for (i
= 0; i
< to_dump_count
; i
++)
668 walk_tree (&to_dump
[i
], unmark_visited_r
, NULL
, NULL
);
670 /* Finalize the to_dump table. */
679 /* Print a COMMENT to the output stream PP. */
682 print_comment (pretty_printer
*pp
, const char *comment
)
684 int len
= strlen (comment
);
685 char *str
= XALLOCAVEC (char, len
+ 1);
687 bool extra_newline
= false;
689 memcpy (str
, comment
, len
+ 1);
691 /* Trim C/C++ comment indicators. */
692 if (str
[len
- 2] == '*' && str
[len
- 1] == '/')
699 tok
= strtok (str
, "\n");
701 pp_string (pp
, " --");
704 tok
= strtok (NULL
, "\n");
706 /* Leave a blank line after multi-line comments. */
708 extra_newline
= true;
715 /* Prints declaration DECL to PP in Ada syntax. The current source file being
716 handled is SOURCE_FILE, and CPP_CHECK is used to perform C++ queries on
720 print_generic_ada_decl (pretty_printer
*pp
, tree decl
,
721 int (*cpp_check
)(tree
, cpp_operation
),
722 const char* source_file
)
724 source_file_base
= source_file
;
726 if (print_ada_declaration (pp
, decl
, 0, cpp_check
, INDENT_INCR
))
733 /* Dump a newline and indent BUFFER by SPC chars. */
736 newline_and_indent (pretty_printer
*buffer
, int spc
)
742 struct with
{ char *s
; const char *in_file
; int limited
; };
743 static struct with
*withs
= NULL
;
744 static int withs_max
= 4096;
745 static int with_len
= 0;
747 /* Record a "with" clause on package S (a limited with if LIMITED_ACCESS is
748 true), if not already done. */
751 append_withs (const char *s
, int limited_access
)
756 withs
= XNEWVEC (struct with
, withs_max
);
758 if (with_len
== withs_max
)
761 withs
= XRESIZEVEC (struct with
, withs
, withs_max
);
764 for (i
= 0; i
< with_len
; i
++)
765 if (!strcmp (s
, withs
[i
].s
)
766 && source_file_base
== withs
[i
].in_file
)
768 withs
[i
].limited
&= limited_access
;
772 withs
[with_len
].s
= xstrdup (s
);
773 withs
[with_len
].in_file
= source_file_base
;
774 withs
[with_len
].limited
= limited_access
;
778 /* Reset "with" clauses. */
781 reset_ada_withs (void)
788 for (i
= 0; i
< with_len
; i
++)
796 /* Dump "with" clauses in F. */
799 dump_ada_withs (FILE *f
)
803 fprintf (f
, "with Interfaces.C; use Interfaces.C;\n");
805 for (i
= 0; i
< with_len
; i
++)
807 (f
, "%swith %s;\n", withs
[i
].limited
? "limited " : "", withs
[i
].s
);
810 /* Return suitable Ada package name from FILE. */
813 get_ada_package (const char *file
)
820 s
= strstr (file
, "/include/");
824 base
= lbasename (file
);
825 res
= XNEWVEC (char, strlen (base
) + 1);
827 for (i
= 0; *base
; base
++, i
++)
839 res
[i
] = (i
== 0 || res
[i
- 1] == '_') ? 'u' : '_';
851 static const char *ada_reserved
[] = {
852 "abort", "abs", "abstract", "accept", "access", "aliased", "all", "and",
853 "array", "at", "begin", "body", "case", "constant", "declare", "delay",
854 "delta", "digits", "do", "else", "elsif", "end", "entry", "exception",
855 "exit", "for", "function", "generic", "goto", "if", "in", "interface", "is",
856 "limited", "loop", "mod", "new", "not", "null", "others", "out", "of", "or",
857 "overriding", "package", "pragma", "private", "procedure", "protected",
858 "raise", "range", "record", "rem", "renames", "requeue", "return", "reverse",
859 "select", "separate", "subtype", "synchronized", "tagged", "task",
860 "terminate", "then", "type", "until", "use", "when", "while", "with", "xor",
863 /* ??? would be nice to specify this list via a config file, so that users
864 can create their own dictionary of conflicts. */
865 static const char *c_duplicates
[] = {
866 /* system will cause troubles with System.Address. */
869 /* The following values have other definitions with same name/other
875 "rl_readline_version",
881 /* Return a declaration tree corresponding to TYPE. */
884 get_underlying_decl (tree type
)
886 tree decl
= NULL_TREE
;
888 if (type
== NULL_TREE
)
891 /* type is a declaration. */
895 /* type is a typedef. */
896 if (TYPE_P (type
) && TYPE_NAME (type
) && DECL_P (TYPE_NAME (type
)))
897 decl
= TYPE_NAME (type
);
899 /* TYPE_STUB_DECL has been set for type. */
900 if (TYPE_P (type
) && TYPE_STUB_DECL (type
) &&
901 DECL_P (TYPE_STUB_DECL (type
)))
902 decl
= TYPE_STUB_DECL (type
);
907 /* Return whether TYPE has static fields. */
910 has_static_fields (const_tree type
)
914 for (tmp
= TYPE_FIELDS (type
); tmp
; tmp
= TREE_CHAIN (tmp
))
916 if (DECL_NAME (tmp
) && TREE_STATIC (tmp
))
922 /* Return whether TYPE corresponds to an Ada tagged type (has a dispatch
926 is_tagged_type (const_tree type
)
930 if (!type
|| !RECORD_OR_UNION_TYPE_P (type
))
933 for (tmp
= TYPE_METHODS (type
); tmp
; tmp
= TREE_CHAIN (tmp
))
934 if (DECL_VINDEX (tmp
))
940 /* Generate a legal Ada name from a C NAME, returning a malloc'd string.
941 SPACE_FOUND, if not NULL, is used to indicate whether a space was found in
945 to_ada_name (const char *name
, int *space_found
)
948 int len
= strlen (name
);
951 char *s
= XNEWVEC (char, len
* 2 + 5);
955 *space_found
= false;
957 /* Add trailing "c_" if name is an Ada reserved word. */
958 for (names
= ada_reserved
; *names
; names
++)
959 if (!strcasecmp (name
, *names
))
968 /* Add trailing "c_" if name is an potential case sensitive duplicate. */
969 for (names
= c_duplicates
; *names
; names
++)
970 if (!strcmp (name
, *names
))
978 for (j
= 0; name
[j
] == '_'; j
++)
983 else if (*name
== '.' || *name
== '$')
993 /* Replace unsuitable characters for Ada identifiers. */
1000 *space_found
= true;
1004 /* ??? missing some C++ operators. */
1008 if (name
[j
+ 1] == '=')
1023 if (name
[j
+ 1] == '=')
1041 s
[len2
++] = name
[j
] == '&' ? 'a' : name
[j
] == '|' ? 'o' : 'x';
1043 if (name
[j
+ 1] == '=')
1056 if (s
[len2
- 1] != '_')
1059 switch (name
[j
+ 1]) {
1062 switch (name
[j
- 1]) {
1063 case '+': s
[len2
++] = 'p'; break; /* + */
1064 case '-': s
[len2
++] = 'm'; break; /* - */
1065 case '*': s
[len2
++] = 't'; break; /* * */
1066 case '/': s
[len2
++] = 'd'; break; /* / */
1072 switch (name
[j
- 1]) {
1073 case '+': s
[len2
++] = 'p'; break; /* += */
1074 case '-': s
[len2
++] = 'm'; break; /* -= */
1075 case '*': s
[len2
++] = 't'; break; /* *= */
1076 case '/': s
[len2
++] = 'd'; break; /* /= */
1110 c
= name
[j
] == '<' ? 'l' : 'g';
1113 switch (name
[j
+ 1]) {
1139 if (len2
&& s
[len2
- 1] == '_')
1144 s
[len2
++] = name
[j
];
1147 if (s
[len2
- 1] == '_')
1155 static bool package_prefix
= true;
1157 /* Dump in BUFFER the name of an identifier NODE of type TYPE, following Ada
1158 syntax. LIMITED_ACCESS indicates whether NODE can be accessed via a limited
1159 'with' clause rather than a regular 'with' clause. */
1162 pp_ada_tree_identifier (pretty_printer
*buffer
, tree node
, tree type
,
1165 const char *name
= IDENTIFIER_POINTER (node
);
1166 int space_found
= false;
1167 char *s
= to_ada_name (name
, &space_found
);
1170 /* If the entity is a type and comes from another file, generate "package"
1173 decl
= get_underlying_decl (type
);
1177 expanded_location xloc
= expand_location (decl_sloc (decl
, false));
1179 if (xloc
.file
&& xloc
.line
)
1181 if (xloc
.file
!= source_file_base
)
1183 switch (TREE_CODE (type
))
1188 case FIXED_POINT_TYPE
:
1190 case REFERENCE_TYPE
:
1195 case QUAL_UNION_TYPE
:
1198 char *s1
= get_ada_package (xloc
.file
);
1202 append_withs (s1
, limited_access
);
1203 pp_string (buffer
, s1
);
1204 pp_character (buffer
, '.');
1217 if (!strcmp (s
, "short_int"))
1218 pp_string (buffer
, "short");
1219 else if (!strcmp (s
, "short_unsigned_int"))
1220 pp_string (buffer
, "unsigned_short");
1221 else if (!strcmp (s
, "unsigned_int"))
1222 pp_string (buffer
, "unsigned");
1223 else if (!strcmp (s
, "long_int"))
1224 pp_string (buffer
, "long");
1225 else if (!strcmp (s
, "long_unsigned_int"))
1226 pp_string (buffer
, "unsigned_long");
1227 else if (!strcmp (s
, "long_long_int"))
1228 pp_string (buffer
, "Long_Long_Integer");
1229 else if (!strcmp (s
, "long_long_unsigned_int"))
1233 append_withs ("Interfaces.C.Extensions", false);
1234 pp_string (buffer
, "Extensions.unsigned_long_long");
1237 pp_string (buffer
, "unsigned_long_long");
1240 pp_string(buffer
, s
);
1242 if (!strcmp (s
, "bool"))
1246 append_withs ("Interfaces.C.Extensions", false);
1247 pp_string (buffer
, "Extensions.bool");
1250 pp_string (buffer
, "bool");
1253 pp_string(buffer
, s
);
1258 /* Dump in BUFFER the assembly name of T. */
1261 pp_asm_name (pretty_printer
*buffer
, tree t
)
1263 tree name
= DECL_ASSEMBLER_NAME (t
);
1264 char *ada_name
= XALLOCAVEC (char, IDENTIFIER_LENGTH (name
) + 1), *s
;
1265 const char *ident
= IDENTIFIER_POINTER (name
);
1267 for (s
= ada_name
; *ident
; ident
++)
1271 else if (*ident
!= '*')
1276 pp_string (buffer
, ada_name
);
1279 /* Dump in BUFFER the name of a DECL node if set, following Ada syntax.
1280 LIMITED_ACCESS indicates whether NODE can be accessed via a limited
1281 'with' clause rather than a regular 'with' clause. */
1284 dump_ada_decl_name (pretty_printer
*buffer
, tree decl
, int limited_access
)
1286 if (DECL_NAME (decl
))
1287 pp_ada_tree_identifier (buffer
, DECL_NAME (decl
), decl
, limited_access
);
1290 tree type_name
= TYPE_NAME (TREE_TYPE (decl
));
1294 pp_string (buffer
, "anon");
1295 if (TREE_CODE (decl
) == FIELD_DECL
)
1296 pp_scalar (buffer
, "%d", DECL_UID (decl
));
1298 pp_scalar (buffer
, "%d", TYPE_UID (TREE_TYPE (decl
)));
1300 else if (TREE_CODE (type_name
) == IDENTIFIER_NODE
)
1301 pp_ada_tree_identifier (buffer
, type_name
, decl
, limited_access
);
1305 /* Dump in BUFFER a name based on both T1 and T2, followed by S. */
1308 dump_ada_double_name (pretty_printer
*buffer
, tree t1
, tree t2
, const char *s
)
1311 pp_ada_tree_identifier (buffer
, DECL_NAME (t1
), t1
, false);
1314 pp_string (buffer
, "anon");
1315 pp_scalar (buffer
, "%d", TYPE_UID (TREE_TYPE (t1
)));
1318 pp_character (buffer
, '_');
1321 pp_ada_tree_identifier (buffer
, DECL_NAME (t2
), t2
, false);
1324 pp_string (buffer
, "anon");
1325 pp_scalar (buffer
, "%d", TYPE_UID (TREE_TYPE (t2
)));
1328 pp_string (buffer
, s
);
1331 /* Dump in BUFFER pragma Import C/CPP on a given node T. */
1334 dump_ada_import (pretty_printer
*buffer
, tree t
)
1336 const char *name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t
));
1337 int is_stdcall
= TREE_CODE (t
) == FUNCTION_DECL
&&
1338 lookup_attribute ("stdcall", TYPE_ATTRIBUTES (TREE_TYPE (t
)));
1341 pp_string (buffer
, "pragma Import (Stdcall, ");
1342 else if (name
[0] == '_' && name
[1] == 'Z')
1343 pp_string (buffer
, "pragma Import (CPP, ");
1345 pp_string (buffer
, "pragma Import (C, ");
1347 dump_ada_decl_name (buffer
, t
, false);
1348 pp_string (buffer
, ", \"");
1351 pp_string (buffer
, IDENTIFIER_POINTER (DECL_NAME (t
)));
1353 pp_asm_name (buffer
, t
);
1355 pp_string (buffer
, "\");");
1358 /* Check whether T and its type have different names, and append "the_"
1359 otherwise in BUFFER. */
1362 check_name (pretty_printer
*buffer
, tree t
)
1365 tree tmp
= TREE_TYPE (t
);
1367 while (TREE_CODE (tmp
) == POINTER_TYPE
&& !TYPE_NAME (tmp
))
1368 tmp
= TREE_TYPE (tmp
);
1370 if (TREE_CODE (tmp
) != FUNCTION_TYPE
)
1372 if (TREE_CODE (tmp
) == IDENTIFIER_NODE
)
1373 s
= IDENTIFIER_POINTER (tmp
);
1374 else if (!TYPE_NAME (tmp
))
1376 else if (TREE_CODE (TYPE_NAME (tmp
)) == IDENTIFIER_NODE
)
1377 s
= IDENTIFIER_POINTER (TYPE_NAME (tmp
));
1379 s
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (tmp
)));
1381 if (!strcasecmp (IDENTIFIER_POINTER (DECL_NAME (t
)), s
))
1382 pp_string (buffer
, "the_");
1386 /* Dump in BUFFER a function declaration FUNC with Ada syntax.
1387 IS_METHOD indicates whether FUNC is a C++ method.
1388 IS_CONSTRUCTOR whether FUNC is a C++ constructor.
1389 IS_DESTRUCTOR whether FUNC is a C++ destructor.
1390 SPC is the current indentation level. */
1393 dump_ada_function_declaration (pretty_printer
*buffer
, tree func
,
1394 int is_method
, int is_constructor
,
1395 int is_destructor
, int spc
)
1398 const tree node
= TREE_TYPE (func
);
1400 int num
= 0, num_args
= 0, have_args
= true, have_ellipsis
= false;
1402 /* Compute number of arguments. */
1403 arg
= TYPE_ARG_TYPES (node
);
1407 while (TREE_CHAIN (arg
) && arg
!= error_mark_node
)
1410 arg
= TREE_CHAIN (arg
);
1413 if (TREE_CODE (TREE_VALUE (arg
)) != VOID_TYPE
)
1416 have_ellipsis
= true;
1427 newline_and_indent (buffer
, spc
+ 1);
1432 pp_character (buffer
, '(');
1435 if (TREE_CODE (func
) == FUNCTION_DECL
)
1436 arg
= DECL_ARGUMENTS (func
);
1440 if (arg
== NULL_TREE
)
1443 arg
= TYPE_ARG_TYPES (node
);
1445 if (arg
&& TREE_CODE (TREE_VALUE (arg
)) == VOID_TYPE
)
1450 arg
= TREE_CHAIN (arg
);
1452 /* Print the argument names (if available) & types. */
1454 for (num
= 1; num
<= num_args
; num
++)
1458 if (DECL_NAME (arg
))
1460 check_name (buffer
, arg
);
1461 pp_ada_tree_identifier (buffer
, DECL_NAME (arg
), 0, false);
1462 pp_string (buffer
, " : ");
1466 sprintf (buf
, "arg%d : ", num
);
1467 pp_string (buffer
, buf
);
1470 dump_generic_ada_node
1471 (buffer
, TREE_TYPE (arg
), node
, NULL
, spc
, 0, true);
1475 sprintf (buf
, "arg%d : ", num
);
1476 pp_string (buffer
, buf
);
1477 dump_generic_ada_node
1478 (buffer
, TREE_VALUE (arg
), node
, NULL
, spc
, 0, true);
1481 if (TREE_TYPE (arg
) && TREE_TYPE (TREE_TYPE (arg
))
1482 && is_tagged_type (TREE_TYPE (TREE_TYPE (arg
))))
1485 || (num
!= 1 || (!DECL_VINDEX (func
) && !is_constructor
)))
1486 pp_string (buffer
, "'Class");
1489 arg
= TREE_CHAIN (arg
);
1493 pp_character (buffer
, ';');
1496 newline_and_indent (buffer
, spc
+ INDENT_INCR
);
1504 pp_string (buffer
, " -- , ...");
1505 newline_and_indent (buffer
, spc
+ INDENT_INCR
);
1509 pp_character (buffer
, ')');
1513 /* Dump in BUFFER all the domains associated with an array NODE,
1514 using Ada syntax. SPC is the current indentation level. */
1517 dump_ada_array_domains (pretty_printer
*buffer
, tree node
, int spc
)
1520 pp_character (buffer
, '(');
1522 for (; TREE_CODE (node
) == ARRAY_TYPE
; node
= TREE_TYPE (node
))
1524 tree domain
= TYPE_DOMAIN (node
);
1528 tree min
= TYPE_MIN_VALUE (domain
);
1529 tree max
= TYPE_MAX_VALUE (domain
);
1532 pp_string (buffer
, ", ");
1536 dump_generic_ada_node (buffer
, min
, NULL_TREE
, NULL
, spc
, 0, true);
1537 pp_string (buffer
, " .. ");
1539 /* If the upper bound is zero, gcc may generate a NULL_TREE
1540 for TYPE_MAX_VALUE rather than an integer_cst. */
1542 dump_generic_ada_node (buffer
, max
, NULL_TREE
, NULL
, spc
, 0, true);
1544 pp_string (buffer
, "0");
1547 pp_string (buffer
, "size_t");
1549 pp_character (buffer
, ')');
1552 /* Dump in BUFFER file:line:col information related to NODE. */
1555 dump_sloc (pretty_printer
*buffer
, tree node
)
1557 expanded_location xloc
;
1561 if (TREE_CODE_CLASS (TREE_CODE (node
)) == tcc_declaration
)
1562 xloc
= expand_location (DECL_SOURCE_LOCATION (node
));
1563 else if (EXPR_HAS_LOCATION (node
))
1564 xloc
= expand_location (EXPR_LOCATION (node
));
1568 pp_string (buffer
, xloc
.file
);
1569 pp_string (buffer
, ":");
1570 pp_decimal_int (buffer
, xloc
.line
);
1571 pp_string (buffer
, ":");
1572 pp_decimal_int (buffer
, xloc
.column
);
1576 /* Return true if T designates a one dimension array of "char". */
1579 is_char_array (tree t
)
1584 /* Retrieve array's type. */
1586 while (TREE_CODE (TREE_TYPE (tmp
)) == ARRAY_TYPE
)
1589 tmp
= TREE_TYPE (tmp
);
1592 tmp
= TREE_TYPE (tmp
);
1593 return num_dim
== 1 && TREE_CODE (tmp
) == INTEGER_TYPE
1594 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (tmp
))), "char");
1597 /* Dump in BUFFER an array type T in Ada syntax. Assume that the "type"
1598 keyword and name have already been printed. SPC is the indentation
1602 dump_ada_array_type (pretty_printer
*buffer
, tree t
, int spc
)
1605 bool char_array
= is_char_array (t
);
1607 /* Special case char arrays. */
1610 pp_string (buffer
, "Interfaces.C.char_array ");
1613 pp_string (buffer
, "array ");
1615 /* Print the dimensions. */
1616 dump_ada_array_domains (buffer
, TREE_TYPE (t
), spc
);
1618 /* Retrieve array's type. */
1619 tmp
= TREE_TYPE (t
);
1620 while (TREE_CODE (TREE_TYPE (tmp
)) == ARRAY_TYPE
)
1621 tmp
= TREE_TYPE (tmp
);
1623 /* Print array's type. */
1626 pp_string (buffer
, " of ");
1628 if (TREE_CODE (TREE_TYPE (tmp
)) != POINTER_TYPE
)
1629 pp_string (buffer
, "aliased ");
1631 dump_generic_ada_node
1632 (buffer
, TREE_TYPE (tmp
), TREE_TYPE (t
), NULL
, spc
, false, true);
1636 /* Dump in BUFFER type names associated with a template, each prepended with
1637 '_'. TYPES is the TREE_PURPOSE of a DECL_TEMPLATE_INSTANTIATIONS.
1638 CPP_CHECK is used to perform C++ queries on nodes.
1639 SPC is the indentation level. */
1642 dump_template_types (pretty_printer
*buffer
, tree types
,
1643 int (*cpp_check
)(tree
, cpp_operation
), int spc
)
1646 size_t len
= TREE_VEC_LENGTH (types
);
1648 for (i
= 0; i
< len
; i
++)
1650 tree elem
= TREE_VEC_ELT (types
, i
);
1651 pp_character (buffer
, '_');
1652 if (!dump_generic_ada_node (buffer
, elem
, 0, cpp_check
, spc
, false, true))
1654 pp_string (buffer
, "unknown");
1655 pp_scalar (buffer
, "%lu", (unsigned long) TREE_HASH (elem
));
1660 /* Dump in BUFFER the contents of all instantiations associated with a given
1661 template T. CPP_CHECK is used to perform C++ queries on nodes.
1662 SPC is the indentation level. */
1665 dump_ada_template (pretty_printer
*buffer
, tree t
,
1666 int (*cpp_check
)(tree
, cpp_operation
), int spc
)
1668 tree inst
= DECL_VINDEX (t
);
1669 /* DECL_VINDEX is DECL_TEMPLATE_INSTANTIATIONS in this context. */
1672 while (inst
&& inst
!= error_mark_node
)
1674 tree types
= TREE_PURPOSE (inst
);
1675 tree instance
= TREE_VALUE (inst
);
1677 if (TREE_VEC_LENGTH (types
) == 0)
1680 if (!TYPE_METHODS (instance
))
1685 pp_string (buffer
, "package ");
1686 package_prefix
= false;
1687 dump_generic_ada_node (buffer
, instance
, t
, cpp_check
, spc
, false, true);
1688 dump_template_types (buffer
, types
, cpp_check
, spc
);
1689 pp_string (buffer
, " is");
1691 newline_and_indent (buffer
, spc
);
1693 pp_string (buffer
, "type ");
1694 dump_generic_ada_node (buffer
, instance
, t
, cpp_check
, spc
, false, true);
1695 package_prefix
= true;
1697 if (is_tagged_type (instance
))
1698 pp_string (buffer
, " is tagged limited ");
1700 pp_string (buffer
, " is limited ");
1702 dump_generic_ada_node (buffer
, instance
, t
, cpp_check
, spc
, false, false);
1703 pp_newline (buffer
);
1705 newline_and_indent (buffer
, spc
);
1707 pp_string (buffer
, "end;");
1708 newline_and_indent (buffer
, spc
);
1709 pp_string (buffer
, "use ");
1710 package_prefix
= false;
1711 dump_generic_ada_node (buffer
, instance
, t
, cpp_check
, spc
, false, true);
1712 dump_template_types (buffer
, types
, cpp_check
, spc
);
1713 package_prefix
= true;
1714 pp_semicolon (buffer
);
1715 pp_newline (buffer
);
1716 pp_newline (buffer
);
1718 inst
= TREE_CHAIN (inst
);
1721 return num_inst
> 0;
1724 static bool in_function
= true;
1725 static bool bitfield_used
= false;
1727 /* Recursively dump in BUFFER Ada declarations corresponding to NODE of type
1728 TYPE. CPP_CHECK is used to perform C++ queries on nodes. SPC is the
1729 indentation level. LIMITED_ACCESS indicates whether NODE can be referenced
1730 via a "limited with" clause. NAME_ONLY indicates whether we should only
1731 dump the name of NODE, instead of its full declaration. */
1734 dump_generic_ada_node (pretty_printer
*buffer
, tree node
, tree type
,
1735 int (*cpp_check
)(tree
, cpp_operation
), int spc
,
1736 int limited_access
, bool name_only
)
1738 if (node
== NULL_TREE
)
1741 switch (TREE_CODE (node
))
1744 pp_string (buffer
, "<<< error >>>");
1747 case IDENTIFIER_NODE
:
1748 pp_ada_tree_identifier (buffer
, node
, type
, limited_access
);
1752 pp_string (buffer
, "--- unexpected node: TREE_LIST");
1756 dump_generic_ada_node
1757 (buffer
, BINFO_TYPE (node
), type
, cpp_check
,
1758 spc
, limited_access
, name_only
);
1761 pp_string (buffer
, "--- unexpected node: TREE_VEC");
1767 append_withs ("System", false);
1768 pp_string (buffer
, "System.Address");
1771 pp_string (buffer
, "address");
1775 pp_string (buffer
, "<vector>");
1779 pp_string (buffer
, "<complex>");
1784 dump_generic_ada_node
1785 (buffer
, TYPE_NAME (node
), node
, cpp_check
, spc
, 0, true);
1790 pp_string (buffer
, "unsigned");
1792 for (value
= TYPE_VALUES (node
); value
; value
= TREE_CHAIN (value
))
1794 pp_semicolon (buffer
);
1795 newline_and_indent (buffer
, spc
);
1797 pp_ada_tree_identifier
1798 (buffer
, TREE_PURPOSE (value
), node
, false);
1799 pp_string (buffer
, " : constant ");
1801 dump_generic_ada_node
1802 (buffer
, DECL_NAME (type
) ? type
: TYPE_NAME (node
), type
,
1803 cpp_check
, spc
, 0, true);
1805 pp_string (buffer
, " := ");
1806 dump_generic_ada_node
1808 TREE_CODE (TREE_VALUE (value
)) == INTEGER_CST
?
1809 TREE_VALUE (value
) : DECL_INITIAL (TREE_VALUE (value
)),
1811 cpp_check
, spc
, false, true);
1818 case FIXED_POINT_TYPE
:
1821 enum tree_code_class tclass
;
1823 tclass
= TREE_CODE_CLASS (TREE_CODE (node
));
1825 if (tclass
== tcc_declaration
)
1827 if (DECL_NAME (node
))
1828 pp_ada_tree_identifier
1829 (buffer
, DECL_NAME (node
), 0, limited_access
);
1831 pp_string (buffer
, "<unnamed type decl>");
1833 else if (tclass
== tcc_type
)
1835 if (TYPE_NAME (node
))
1837 if (TREE_CODE (TYPE_NAME (node
)) == IDENTIFIER_NODE
)
1838 pp_ada_tree_identifier (buffer
, TYPE_NAME (node
),
1839 node
, limited_access
);
1840 else if (TREE_CODE (TYPE_NAME (node
)) == TYPE_DECL
1841 && DECL_NAME (TYPE_NAME (node
)))
1842 dump_ada_decl_name (buffer
, TYPE_NAME (node
), limited_access
);
1844 pp_string (buffer
, "<unnamed type>");
1846 else if (TREE_CODE (node
) == INTEGER_TYPE
)
1848 append_withs ("Interfaces.C.Extensions", false);
1849 bitfield_used
= true;
1851 if (TYPE_PRECISION (node
) == 1)
1852 pp_string (buffer
, "Extensions.Unsigned_1");
1855 pp_string (buffer
, (TYPE_UNSIGNED (node
)
1856 ? "Extensions.Unsigned_"
1857 : "Extensions.Signed_"));
1858 pp_decimal_int (buffer
, TYPE_PRECISION (node
));
1862 pp_string (buffer
, "<unnamed type>");
1868 case REFERENCE_TYPE
:
1869 if (TREE_CODE (TREE_TYPE (node
)) == FUNCTION_TYPE
)
1871 tree fnode
= TREE_TYPE (node
);
1873 bool prev_in_function
= in_function
;
1875 if (VOID_TYPE_P (TREE_TYPE (fnode
)))
1877 is_function
= false;
1878 pp_string (buffer
, "access procedure");
1883 pp_string (buffer
, "access function");
1886 in_function
= is_function
;
1887 dump_ada_function_declaration
1888 (buffer
, node
, false, false, false, spc
+ INDENT_INCR
);
1889 in_function
= prev_in_function
;
1893 pp_string (buffer
, " return ");
1894 dump_generic_ada_node
1895 (buffer
, TREE_TYPE (fnode
), type
, cpp_check
, spc
, 0, true);
1900 int is_access
= false;
1901 unsigned int quals
= TYPE_QUALS (TREE_TYPE (node
));
1903 if (name_only
&& TYPE_NAME (node
))
1904 dump_generic_ada_node
1905 (buffer
, TYPE_NAME (node
), node
, cpp_check
,
1906 spc
, limited_access
, true);
1907 else if (VOID_TYPE_P (TREE_TYPE (node
)))
1910 pp_string (buffer
, "new ");
1913 append_withs ("System", false);
1914 pp_string (buffer
, "System.Address");
1917 pp_string (buffer
, "address");
1921 if (TREE_CODE (node
) == POINTER_TYPE
1922 && TREE_CODE (TREE_TYPE (node
)) == INTEGER_TYPE
1924 (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME
1925 (TREE_TYPE (node
)))), "char"))
1928 pp_string (buffer
, "new ");
1932 pp_string (buffer
, "Interfaces.C.Strings.chars_ptr");
1933 append_withs ("Interfaces.C.Strings", false);
1936 pp_string (buffer
, "chars_ptr");
1940 /* For now, handle all access-to-access or
1941 access-to-unknown-structs as opaque system.address. */
1943 tree typ
= TYPE_NAME (TREE_TYPE (node
));
1944 const_tree typ2
= !type
||
1945 DECL_P (type
) ? type
: TYPE_NAME (type
);
1946 const_tree underlying_type
=
1947 get_underlying_decl (TREE_TYPE (node
));
1949 if (TREE_CODE (TREE_TYPE (node
)) == POINTER_TYPE
1950 /* Pointer to pointer. */
1952 || (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node
))
1953 && (!underlying_type
1954 || !TYPE_FIELDS (TREE_TYPE (underlying_type
))))
1955 /* Pointer to opaque structure. */
1958 && DECL_P (underlying_type
)
1960 && decl_sloc (underlying_type
, true)
1961 > decl_sloc (typ2
, true)
1962 && DECL_SOURCE_FILE (underlying_type
)
1963 == DECL_SOURCE_FILE (typ2
)))
1967 append_withs ("System", false);
1969 pp_string (buffer
, "new ");
1970 pp_string (buffer
, "System.Address");
1973 pp_string (buffer
, "address");
1977 if (!package_prefix
)
1978 pp_string (buffer
, "access");
1979 else if (AGGREGATE_TYPE_P (TREE_TYPE (node
)))
1981 if (!type
|| TREE_CODE (type
) != FUNCTION_DECL
)
1983 pp_string (buffer
, "access ");
1986 if (quals
& TYPE_QUAL_CONST
)
1987 pp_string (buffer
, "constant ");
1988 else if (!name_only
)
1989 pp_string (buffer
, "all ");
1991 else if (quals
& TYPE_QUAL_CONST
)
1992 pp_string (buffer
, "in ");
1993 else if (in_function
)
1996 pp_string (buffer
, "access ");
2001 pp_string (buffer
, "access ");
2002 /* ??? should be configurable: access or in out. */
2008 pp_string (buffer
, "access ");
2011 pp_string (buffer
, "all ");
2014 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node
))
2015 && TYPE_NAME (TREE_TYPE (node
)))
2017 tree name
= TYPE_NAME (TREE_TYPE (node
));
2020 if (TREE_CODE (name
) == TYPE_DECL
2021 && DECL_ORIGINAL_TYPE (name
)
2022 && TYPE_STUB_DECL (DECL_ORIGINAL_TYPE (name
)))
2024 tmp
= TYPE_NAME (TREE_TYPE (TYPE_STUB_DECL
2025 (DECL_ORIGINAL_TYPE (name
))));
2027 if (tmp
== NULL_TREE
)
2028 tmp
= TYPE_NAME (TREE_TYPE (node
));
2031 tmp
= TYPE_NAME (TREE_TYPE (node
));
2033 dump_generic_ada_node
2035 TREE_TYPE (node
), cpp_check
, spc
, is_access
, true);
2038 dump_generic_ada_node
2039 (buffer
, TREE_TYPE (node
), TREE_TYPE (node
),
2040 cpp_check
, spc
, 0, true);
2048 dump_generic_ada_node
2049 (buffer
, TYPE_NAME (node
), node
, cpp_check
,
2050 spc
, limited_access
, true);
2052 dump_ada_array_type (buffer
, node
, spc
);
2057 case QUAL_UNION_TYPE
:
2060 if (TYPE_NAME (node
))
2061 dump_generic_ada_node
2062 (buffer
, TYPE_NAME (node
), node
, cpp_check
,
2063 spc
, limited_access
, true);
2066 pp_string (buffer
, "anon_");
2067 pp_scalar (buffer
, "%d", TYPE_UID (node
));
2071 print_ada_struct_decl
2072 (buffer
, node
, type
, cpp_check
, spc
, true);
2076 if (TREE_CODE (TREE_TYPE (node
)) == POINTER_TYPE
)
2078 pp_wide_integer (buffer
, TREE_INT_CST_LOW (node
));
2079 pp_string (buffer
, "B"); /* pseudo-unit */
2081 else if (! host_integerp (node
, 0))
2084 unsigned HOST_WIDE_INT low
= TREE_INT_CST_LOW (val
);
2085 HOST_WIDE_INT high
= TREE_INT_CST_HIGH (val
);
2087 if (tree_int_cst_sgn (val
) < 0)
2089 pp_character (buffer
, '-');
2090 high
= ~high
+ !low
;
2093 sprintf (pp_buffer (buffer
)->digit_buffer
,
2094 HOST_WIDE_INT_PRINT_DOUBLE_HEX
,
2095 (unsigned HOST_WIDE_INT
) high
, low
);
2096 pp_string (buffer
, pp_buffer (buffer
)->digit_buffer
);
2099 pp_wide_integer (buffer
, TREE_INT_CST_LOW (node
));
2111 dump_ada_decl_name (buffer
, node
, limited_access
);
2115 if (DECL_IS_BUILTIN (node
))
2117 /* Don't print the declaration of built-in types. */
2121 /* If we're in the middle of a declaration, defaults to
2125 append_withs ("System", false);
2126 pp_string (buffer
, "System.Address");
2129 pp_string (buffer
, "address");
2135 dump_ada_decl_name (buffer
, node
, limited_access
);
2138 if (is_tagged_type (TREE_TYPE (node
)))
2140 tree tmp
= TYPE_FIELDS (TREE_TYPE (node
));
2143 /* Look for ancestors. */
2144 for (; tmp
; tmp
= TREE_CHAIN (tmp
))
2146 if (!DECL_NAME (tmp
) && is_tagged_type (TREE_TYPE (tmp
)))
2150 pp_string (buffer
, "limited new ");
2154 pp_string (buffer
, " and ");
2157 (buffer
, TYPE_NAME (TREE_TYPE (tmp
)), false);
2161 pp_string (buffer
, first
? "tagged limited " : " with ");
2163 else if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node
))
2164 && TYPE_METHODS (TREE_TYPE (node
)))
2165 pp_string (buffer
, "limited ");
2167 dump_generic_ada_node
2168 (buffer
, TREE_TYPE (node
), type
, cpp_check
, spc
, false, false);
2175 case NAMESPACE_DECL
:
2176 dump_ada_decl_name (buffer
, node
, false);
2180 /* Ignore other nodes (e.g. expressions). */
2187 /* Dump in BUFFER NODE's methods. CPP_CHECK is used to perform C++ queries on
2188 nodes. SPC is the indentation level. */
2191 print_ada_methods (pretty_printer
*buffer
, tree node
,
2192 int (*cpp_check
)(tree
, cpp_operation
), int spc
)
2194 tree tmp
= TYPE_METHODS (node
);
2199 pp_semicolon (buffer
);
2201 for (; tmp
; tmp
= TREE_CHAIN (tmp
))
2205 pp_newline (buffer
);
2206 pp_newline (buffer
);
2208 res
= print_ada_declaration (buffer
, tmp
, node
, cpp_check
, spc
);
2213 /* Dump in BUFFER anonymous types nested inside T's definition.
2214 PARENT is the parent node of T. CPP_CHECK is used to perform C++ queries on
2215 nodes. SPC is the indentation level. */
2218 dump_nested_types (pretty_printer
*buffer
, tree t
, tree parent
,
2219 int (*cpp_check
)(tree
, cpp_operation
), int spc
)
2221 tree field
, outer
, decl
;
2223 /* Avoid recursing over the same tree. */
2224 if (TREE_VISITED (t
))
2227 /* Find possible anonymous arrays/unions/structs recursively. */
2229 outer
= TREE_TYPE (t
);
2231 if (outer
== NULL_TREE
)
2234 field
= TYPE_FIELDS (outer
);
2237 if ((TREE_TYPE (field
) != outer
2238 || (TREE_CODE (TREE_TYPE (field
)) == POINTER_TYPE
2239 && TREE_TYPE (TREE_TYPE (field
)) != outer
))
2240 && (!TYPE_NAME (TREE_TYPE (field
))
2241 || (TREE_CODE (field
) == TYPE_DECL
2242 && DECL_NAME (field
) != DECL_NAME (t
)
2243 && TYPE_NAME (TREE_TYPE (field
)) != TYPE_NAME (outer
))))
2245 switch (TREE_CODE (TREE_TYPE (field
)))
2248 decl
= TREE_TYPE (TREE_TYPE (field
));
2250 if (TREE_CODE (decl
) == FUNCTION_TYPE
)
2251 for (decl
= TREE_TYPE (decl
);
2252 decl
&& TREE_CODE (decl
) == POINTER_TYPE
;
2253 decl
= TREE_TYPE (decl
));
2255 decl
= get_underlying_decl (decl
);
2259 && decl_sloc (decl
, true) > decl_sloc (t
, true)
2260 && DECL_SOURCE_FILE (decl
) == DECL_SOURCE_FILE (t
)
2261 && !TREE_VISITED (decl
)
2262 && !DECL_IS_BUILTIN (decl
)
2263 && (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl
))
2264 || TYPE_FIELDS (TREE_TYPE (decl
))))
2266 /* Generate forward declaration. */
2268 pp_string (buffer
, "type ");
2269 dump_generic_ada_node
2270 (buffer
, decl
, 0, cpp_check
, spc
, false, true);
2271 pp_semicolon (buffer
);
2272 newline_and_indent (buffer
, spc
);
2274 /* Ensure we do not generate duplicate forward
2275 declarations for this type. */
2276 TREE_VISITED (decl
) = 1;
2281 /* Special case char arrays. */
2282 if (is_char_array (field
))
2283 pp_string (buffer
, "sub");
2285 pp_string (buffer
, "type ");
2286 dump_ada_double_name (buffer
, parent
, field
, "_array is ");
2287 dump_ada_array_type (buffer
, field
, spc
);
2288 pp_semicolon (buffer
);
2289 newline_and_indent (buffer
, spc
);
2293 TREE_VISITED (t
) = 1;
2294 dump_nested_types (buffer
, field
, t
, cpp_check
, spc
);
2296 pp_string (buffer
, "type ");
2298 if (TYPE_NAME (TREE_TYPE (field
)))
2300 dump_generic_ada_node
2301 (buffer
, TYPE_NAME (TREE_TYPE (field
)), 0, cpp_check
,
2303 pp_string (buffer
, " (discr : unsigned := 0) is ");
2304 print_ada_struct_decl
2305 (buffer
, TREE_TYPE (field
), t
, cpp_check
, spc
, false);
2307 pp_string (buffer
, "pragma Convention (C_Pass_By_Copy, ");
2308 dump_generic_ada_node
2309 (buffer
, TREE_TYPE (field
), 0, cpp_check
,
2311 pp_string (buffer
, ");");
2312 newline_and_indent (buffer
, spc
);
2314 pp_string (buffer
, "pragma Unchecked_Union (");
2315 dump_generic_ada_node
2316 (buffer
, TREE_TYPE (field
), 0, cpp_check
,
2318 pp_string (buffer
, ");");
2322 dump_ada_double_name
2323 (buffer
, parent
, field
,
2324 "_union (discr : unsigned := 0) is ");
2325 print_ada_struct_decl
2326 (buffer
, TREE_TYPE (field
), t
, cpp_check
, spc
, false);
2327 pp_string (buffer
, "pragma Convention (C_Pass_By_Copy, ");
2328 dump_ada_double_name (buffer
, parent
, field
, "_union);");
2329 newline_and_indent (buffer
, spc
);
2331 pp_string (buffer
, "pragma Unchecked_Union (");
2332 dump_ada_double_name (buffer
, parent
, field
, "_union);");
2335 newline_and_indent (buffer
, spc
);
2339 if (TYPE_NAME (TREE_TYPE (t
)) && !TREE_VISITED (t
))
2341 pp_string (buffer
, "type ");
2342 dump_generic_ada_node
2343 (buffer
, t
, parent
, 0, spc
, false, true);
2344 pp_semicolon (buffer
);
2345 newline_and_indent (buffer
, spc
);
2348 TREE_VISITED (t
) = 1;
2349 dump_nested_types (buffer
, field
, t
, cpp_check
, spc
);
2350 pp_string (buffer
, "type ");
2352 if (TYPE_NAME (TREE_TYPE (field
)))
2354 dump_generic_ada_node
2355 (buffer
, TREE_TYPE (field
), 0, cpp_check
,
2357 pp_string (buffer
, " is ");
2358 print_ada_struct_decl
2359 (buffer
, TREE_TYPE (field
), t
, cpp_check
, spc
, false);
2360 pp_string (buffer
, "pragma Convention (C_Pass_By_Copy, ");
2361 dump_generic_ada_node
2362 (buffer
, TREE_TYPE (field
), 0, cpp_check
,
2364 pp_string (buffer
, ");");
2368 dump_ada_double_name
2369 (buffer
, parent
, field
, "_struct is ");
2370 print_ada_struct_decl
2371 (buffer
, TREE_TYPE (field
), t
, cpp_check
, spc
, false);
2372 pp_string (buffer
, "pragma Convention (C_Pass_By_Copy, ");
2373 dump_ada_double_name (buffer
, parent
, field
, "_struct);");
2376 newline_and_indent (buffer
, spc
);
2383 field
= TREE_CHAIN (field
);
2387 /* Dump in BUFFER destructor spec corresponding to T. */
2390 print_destructor (pretty_printer
*buffer
, tree t
)
2392 const char *s
= IDENTIFIER_POINTER (DECL_NAME (t
));
2395 for (s
+= 2; *s
!= ' '; s
++)
2396 pp_character (buffer
, *s
);
2399 pp_string (buffer
, "Delete_");
2400 pp_ada_tree_identifier (buffer
, DECL_NAME (t
), t
, false);
2404 /* Return the name of type T. */
2409 tree n
= TYPE_NAME (t
);
2411 if (TREE_CODE (n
) == IDENTIFIER_NODE
)
2412 return IDENTIFIER_POINTER (n
);
2414 return IDENTIFIER_POINTER (DECL_NAME (n
));
2417 /* Print in BUFFER the declaration of a variable T of type TYPE in Ada syntax.
2418 CPP_CHECK is used to perform C++ queries on nodes. SPC is the indentation
2419 level. Return 1 if a declaration was printed, 0 otherwise. */
2422 print_ada_declaration (pretty_printer
*buffer
, tree t
, tree type
,
2423 int (*cpp_check
)(tree
, cpp_operation
), int spc
)
2425 int is_var
= 0, need_indent
= 0;
2426 int is_class
= false;
2427 tree name
= TYPE_NAME (TREE_TYPE (t
));
2428 tree decl_name
= DECL_NAME (t
);
2429 bool dump_internal
= get_dump_file_info (TDI_ada
)->flags
& TDF_RAW
;
2430 tree orig
= NULL_TREE
;
2432 if (cpp_check
&& cpp_check (t
, IS_TEMPLATE
))
2433 return dump_ada_template (buffer
, t
, cpp_check
, spc
);
2435 if (TREE_CODE (t
) == CONST_DECL
&& TREE_CODE (TREE_TYPE (t
)) == ENUMERAL_TYPE
)
2436 /* Skip enumeral values: will be handled as part of the type itself. */
2439 if (TREE_CODE (t
) == TYPE_DECL
)
2441 orig
= DECL_ORIGINAL_TYPE (t
);
2443 if (orig
&& TYPE_STUB_DECL (orig
))
2445 tree typ
= TREE_TYPE (TYPE_STUB_DECL (orig
));
2447 if (TYPE_NAME (typ
))
2449 /* If types have same representation, and same name (ignoring
2450 casing), then ignore the second type. */
2451 if (type_name (typ
) == type_name (TREE_TYPE (t
))
2452 || !strcasecmp (type_name (typ
), type_name (TREE_TYPE (t
))))
2457 if (RECORD_OR_UNION_TYPE_P (typ
) && !TYPE_FIELDS (typ
))
2459 pp_string (buffer
, "-- skipped empty struct ");
2460 dump_generic_ada_node (buffer
, t
, type
, 0, spc
, false, true);
2464 pp_string (buffer
, "subtype ");
2465 dump_generic_ada_node (buffer
, t
, type
, 0, spc
, false, true);
2466 pp_string (buffer
, " is ");
2467 dump_generic_ada_node
2468 (buffer
, typ
, type
, 0, spc
, false, true);
2469 pp_semicolon (buffer
);
2475 /* Skip unnamed or anonymous structs/unions/enum types. */
2476 if (!orig
&& !decl_name
&& !name
)
2481 if (cpp_check
|| TREE_CODE (TREE_TYPE (t
)) == ENUMERAL_TYPE
)
2484 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t
)))
2486 /* Search next items until finding a named type decl. */
2487 sloc
= decl_sloc_common (t
, true, true);
2489 for (tmp
= TREE_CHAIN (t
); tmp
; tmp
= TREE_CHAIN (tmp
))
2491 if (TREE_CODE (tmp
) == TYPE_DECL
2492 && (DECL_NAME (tmp
) || TYPE_NAME (TREE_TYPE (tmp
))))
2494 /* If same sloc, it means we can ignore the anonymous
2496 if (decl_sloc_common (tmp
, true, true) == sloc
)
2508 && TREE_CODE (TREE_TYPE (t
)) == ENUMERAL_TYPE
2510 && (*IDENTIFIER_POINTER (decl_name
) == '.'
2511 || *IDENTIFIER_POINTER (decl_name
) == '$'))
2512 /* Skip anonymous enum types (duplicates of real types). */
2517 switch (TREE_CODE (TREE_TYPE (t
)))
2521 case QUAL_UNION_TYPE
:
2522 /* Skip empty structs (typically forward references to real
2524 if (!TYPE_FIELDS (TREE_TYPE (t
)))
2526 pp_string (buffer
, "-- skipped empty struct ");
2527 dump_generic_ada_node (buffer
, t
, type
, 0, spc
, false, true);
2532 && (*IDENTIFIER_POINTER (decl_name
) == '.'
2533 || *IDENTIFIER_POINTER (decl_name
) == '$'))
2535 pp_string (buffer
, "-- skipped anonymous struct ");
2536 dump_generic_ada_node (buffer
, t
, type
, 0, spc
, false, true);
2540 if (orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
))
2541 pp_string (buffer
, "subtype ");
2544 dump_nested_types (buffer
, t
, t
, cpp_check
, spc
);
2546 if (TYPE_METHODS (TREE_TYPE (t
))
2547 || has_static_fields (TREE_TYPE (t
)))
2550 pp_string (buffer
, "package Class_");
2551 dump_generic_ada_node
2552 (buffer
, t
, type
, 0, spc
, false, true);
2553 pp_string (buffer
, " is");
2555 newline_and_indent (buffer
, spc
);
2558 pp_string (buffer
, "type ");
2564 case REFERENCE_TYPE
:
2565 if ((orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
))
2566 || is_char_array (t
))
2567 pp_string (buffer
, "subtype ");
2569 pp_string (buffer
, "type ");
2573 pp_string (buffer
, "-- skipped function type ");
2574 dump_generic_ada_node (buffer
, t
, type
, 0, spc
, false, true);
2579 pp_string (buffer
, "subtype ");
2585 && TREE_CODE (t
) == VAR_DECL
2587 && *IDENTIFIER_POINTER (decl_name
) == '_')
2593 /* Print the type and name. */
2594 if (TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
)
2599 /* Print variable's name. */
2600 dump_generic_ada_node (buffer
, t
, type
, cpp_check
, spc
, false, true);
2602 if (TREE_CODE (t
) == TYPE_DECL
)
2604 pp_string (buffer
, " is ");
2606 if (orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
))
2607 dump_generic_ada_node
2608 (buffer
, TYPE_NAME (orig
), type
,
2609 cpp_check
, spc
, false, true);
2611 dump_ada_array_type (buffer
, t
, spc
);
2615 tree tmp
= TYPE_NAME (TREE_TYPE (t
));
2617 if (spc
== INDENT_INCR
|| TREE_STATIC (t
))
2620 pp_string (buffer
, " : ");
2624 if (TREE_CODE (TREE_TYPE (tmp
)) != POINTER_TYPE
2625 && TREE_CODE (tmp
) != INTEGER_TYPE
)
2626 pp_string (buffer
, "aliased ");
2628 dump_generic_ada_node (buffer
, tmp
, type
, 0, spc
, false, true);
2632 pp_string (buffer
, "aliased ");
2635 dump_ada_array_type (buffer
, t
, spc
);
2637 dump_ada_double_name (buffer
, type
, t
, "_array");
2641 else if (TREE_CODE (t
) == FUNCTION_DECL
)
2643 bool is_function
= true, is_method
, is_abstract_class
= false;
2644 tree decl_name
= DECL_NAME (t
);
2645 int prev_in_function
= in_function
;
2646 bool is_abstract
= false;
2647 bool is_constructor
= false;
2648 bool is_destructor
= false;
2649 bool is_copy_constructor
= false;
2656 is_abstract
= cpp_check (t
, IS_ABSTRACT
);
2657 is_constructor
= cpp_check (t
, IS_CONSTRUCTOR
);
2658 is_destructor
= cpp_check (t
, IS_DESTRUCTOR
);
2659 is_copy_constructor
= cpp_check (t
, IS_COPY_CONSTRUCTOR
);
2662 /* Skip __comp_dtor destructor which is redundant with the '~class()'
2665 && !strncmp (IDENTIFIER_POINTER (decl_name
), "__comp", 6))
2668 /* Skip copy constructors: some are internal only, and those that are
2669 not cannot be called easily from Ada anyway. */
2670 if (is_copy_constructor
)
2673 /* If this function has an entry in the dispatch table, we cannot
2675 if (!dump_internal
&& !DECL_VINDEX (t
)
2676 && *IDENTIFIER_POINTER (decl_name
) == '_')
2678 if (IDENTIFIER_POINTER (decl_name
)[1] == '_')
2682 pp_string (buffer
, "-- skipped func ");
2683 pp_string (buffer
, IDENTIFIER_POINTER (decl_name
));
2691 pp_string (buffer
, "function New_");
2692 else if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (t
))))
2694 is_function
= false;
2695 pp_string (buffer
, "procedure ");
2698 pp_string (buffer
, "function ");
2700 in_function
= is_function
;
2701 is_method
= TREE_CODE (TREE_TYPE (t
)) == METHOD_TYPE
;
2704 print_destructor (buffer
, t
);
2706 dump_ada_decl_name (buffer
, t
, false);
2708 dump_ada_function_declaration
2709 (buffer
, t
, is_method
, is_constructor
, is_destructor
, spc
);
2710 in_function
= prev_in_function
;
2714 pp_string (buffer
, " return ");
2718 dump_ada_decl_name (buffer
, t
, false);
2722 dump_generic_ada_node
2723 (buffer
, TREE_TYPE (TREE_TYPE (t
)), type
, cpp_check
,
2728 if (is_constructor
&& cpp_check
&& type
2729 && AGGREGATE_TYPE_P (type
)
2730 && TYPE_METHODS (type
))
2732 tree tmp
= TYPE_METHODS (type
);
2734 for (; tmp
; tmp
= TREE_CHAIN (tmp
))
2735 if (cpp_check (tmp
, IS_ABSTRACT
))
2737 is_abstract_class
= 1;
2742 if (is_abstract
|| is_abstract_class
)
2743 pp_string (buffer
, " is abstract");
2745 pp_semicolon (buffer
);
2746 pp_string (buffer
, " -- ");
2747 dump_sloc (buffer
, t
);
2752 newline_and_indent (buffer
, spc
);
2756 pp_string (buffer
, "pragma CPP_Constructor (New_");
2757 dump_ada_decl_name (buffer
, t
, false);
2758 pp_string (buffer
, ", \"");
2759 pp_asm_name (buffer
, t
);
2760 pp_string (buffer
, "\");");
2762 else if (is_destructor
)
2764 pp_string (buffer
, "pragma Import (CPP, ");
2765 print_destructor (buffer
, t
);
2766 pp_string (buffer
, ", \"");
2767 pp_asm_name (buffer
, t
);
2768 pp_string (buffer
, "\");");
2772 dump_ada_import (buffer
, t
);
2777 else if (TREE_CODE (t
) == TYPE_DECL
&& !DECL_ORIGINAL_TYPE (t
))
2779 int is_interface
= 0;
2780 int is_abstract_record
= 0;
2785 /* Anonymous structs/unions */
2786 dump_generic_ada_node
2787 (buffer
, TREE_TYPE (t
), t
, cpp_check
, spc
, false, true);
2789 if (TREE_CODE (TREE_TYPE (t
)) == UNION_TYPE
2790 || TREE_CODE (TREE_TYPE (t
)) == QUAL_UNION_TYPE
)
2792 pp_string (buffer
, " (discr : unsigned := 0)");
2795 pp_string (buffer
, " is ");
2797 /* Check whether we have an Ada interface compatible class. */
2798 if (cpp_check
&& AGGREGATE_TYPE_P (TREE_TYPE (t
))
2799 && TYPE_METHODS (TREE_TYPE (t
)))
2802 tree tmp
= TYPE_FIELDS (TREE_TYPE (t
));
2804 /* Check that there are no fields other than the virtual table. */
2805 for (; tmp
; tmp
= TREE_CHAIN (tmp
))
2807 if (TREE_CODE (tmp
) == TYPE_DECL
)
2812 if (num_fields
== 1)
2815 /* Also check that there are only virtual methods. */
2816 for (tmp
= TYPE_METHODS (TREE_TYPE (t
)); tmp
; tmp
= TREE_CHAIN (tmp
))
2818 if (cpp_check (tmp
, IS_ABSTRACT
))
2819 is_abstract_record
= 1;
2827 pp_string (buffer
, "limited interface; -- ");
2828 dump_sloc (buffer
, t
);
2829 newline_and_indent (buffer
, spc
);
2830 pp_string (buffer
, "pragma Import (CPP, ");
2831 dump_generic_ada_node
2832 (buffer
, TYPE_NAME (TREE_TYPE (t
)), type
, cpp_check
,
2834 pp_character (buffer
, ')');
2836 print_ada_methods (buffer
, TREE_TYPE (t
), cpp_check
, spc
);
2840 if (is_abstract_record
)
2841 pp_string (buffer
, "abstract ");
2842 dump_generic_ada_node (buffer
, t
, t
, cpp_check
, spc
, false, false);
2850 if (TREE_CODE (t
) == FIELD_DECL
&& DECL_NAME (t
))
2851 check_name (buffer
, t
);
2853 /* Print variable/type's name. */
2854 dump_generic_ada_node (buffer
, t
, t
, cpp_check
, spc
, false, true);
2856 if (TREE_CODE (t
) == TYPE_DECL
)
2858 tree orig
= DECL_ORIGINAL_TYPE (t
);
2859 int is_subtype
= orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
);
2862 && (TREE_CODE (TREE_TYPE (t
)) == UNION_TYPE
2863 || TREE_CODE (TREE_TYPE (t
)) == QUAL_UNION_TYPE
))
2864 pp_string (buffer
, " (discr : unsigned := 0)");
2866 pp_string (buffer
, " is ");
2868 dump_generic_ada_node
2869 (buffer
, orig
, t
, cpp_check
, spc
, false, is_subtype
);
2873 if (spc
== INDENT_INCR
|| TREE_STATIC (t
))
2876 pp_string (buffer
, " : ");
2878 /* Print type declaration. */
2880 if (TREE_CODE (TREE_TYPE (t
)) == UNION_TYPE
2881 && !TYPE_NAME (TREE_TYPE (t
)))
2883 dump_ada_double_name (buffer
, type
, t
, "_union");
2885 else if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t
)))
2887 if (TREE_CODE (TREE_TYPE (t
)) == RECORD_TYPE
)
2888 pp_string (buffer
, "aliased ");
2890 dump_generic_ada_node
2891 (buffer
, TREE_TYPE (t
), t
, cpp_check
, spc
, false, true);
2895 if (TREE_CODE (TREE_TYPE (t
)) != POINTER_TYPE
2896 && (TYPE_NAME (TREE_TYPE (t
))
2897 || TREE_CODE (TREE_TYPE (t
)) != INTEGER_TYPE
))
2898 pp_string (buffer
, "aliased ");
2900 dump_generic_ada_node
2901 (buffer
, TREE_TYPE (t
), TREE_TYPE (t
), cpp_check
,
2910 newline_and_indent (buffer
, spc
);
2911 pp_string (buffer
, "end;");
2912 newline_and_indent (buffer
, spc
);
2913 pp_string (buffer
, "use Class_");
2914 dump_generic_ada_node (buffer
, t
, type
, 0, spc
, false, true);
2915 pp_semicolon (buffer
);
2916 pp_newline (buffer
);
2918 /* All needed indentation/newline performed already, so return 0. */
2923 pp_string (buffer
, "; -- ");
2924 dump_sloc (buffer
, t
);
2929 newline_and_indent (buffer
, spc
);
2930 dump_ada_import (buffer
, t
);
2936 /* Prints in BUFFER a structure NODE of type TYPE: name, fields, and methods
2937 with Ada syntax. CPP_CHECK is used to perform C++ queries on nodes. SPC
2938 is the indentation level. If DISPLAY_CONVENTION is true, also print the
2939 pragma Convention for NODE. */
2942 print_ada_struct_decl (pretty_printer
*buffer
, tree node
, tree type
,
2943 int (*cpp_check
)(tree
, cpp_operation
), int spc
,
2944 bool display_convention
)
2948 TREE_CODE (node
) == UNION_TYPE
|| TREE_CODE (node
) == QUAL_UNION_TYPE
;
2951 int field_spc
= spc
+ INDENT_INCR
;
2954 bitfield_used
= false;
2956 if (!TYPE_FIELDS (node
))
2957 pp_string (buffer
, "null record;");
2960 pp_string (buffer
, "record");
2962 /* Print the contents of the structure. */
2966 newline_and_indent (buffer
, spc
+ INDENT_INCR
);
2967 pp_string (buffer
, "case discr is");
2968 field_spc
= spc
+ INDENT_INCR
* 3;
2971 pp_newline (buffer
);
2973 /* Print the non-static fields of the structure. */
2974 for (tmp
= TYPE_FIELDS (node
); tmp
; tmp
= TREE_CHAIN (tmp
))
2976 /* Add parent field if needed. */
2977 if (!DECL_NAME (tmp
))
2979 if (!is_tagged_type (TREE_TYPE (tmp
)))
2981 if (!TYPE_NAME (TREE_TYPE (tmp
)))
2982 print_ada_declaration
2983 (buffer
, tmp
, type
, cpp_check
, field_spc
);
2989 pp_string (buffer
, "parent : ");
2992 sprintf (buf
, "field_%d : ", field_num
+ 1);
2993 pp_string (buffer
, buf
);
2996 (buffer
, TYPE_NAME (TREE_TYPE (tmp
)), false);
2997 pp_semicolon (buffer
);
2999 pp_newline (buffer
);
3003 /* Avoid printing the structure recursively. */
3004 else if ((TREE_TYPE (tmp
) != node
3005 || (TREE_CODE (TREE_TYPE (tmp
)) == POINTER_TYPE
3006 && TREE_TYPE (TREE_TYPE (tmp
)) != node
))
3007 && TREE_CODE (tmp
) != TYPE_DECL
3008 && !TREE_STATIC (tmp
))
3010 /* Skip internal virtual table field. */
3011 if (strncmp (IDENTIFIER_POINTER (DECL_NAME (tmp
)), "_vptr", 5))
3015 if (TREE_CHAIN (tmp
)
3016 && TREE_TYPE (TREE_CHAIN (tmp
)) != node
3017 && TREE_CODE (TREE_CHAIN (tmp
)) != TYPE_DECL
)
3018 sprintf (buf
, "when %d =>", field_num
);
3020 sprintf (buf
, "when others =>");
3022 INDENT (spc
+ INDENT_INCR
* 2);
3023 pp_string (buffer
, buf
);
3024 pp_newline (buffer
);
3027 if (print_ada_declaration (buffer
,
3028 tmp
, type
, cpp_check
, field_spc
))
3030 pp_newline (buffer
);
3039 INDENT (spc
+ INDENT_INCR
);
3040 pp_string (buffer
, "end case;");
3041 pp_newline (buffer
);
3046 INDENT (spc
+ INDENT_INCR
);
3047 pp_string (buffer
, "null;");
3048 pp_newline (buffer
);
3052 pp_string (buffer
, "end record;");
3055 newline_and_indent (buffer
, spc
);
3057 if (!display_convention
)
3060 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type
)))
3062 if (TYPE_METHODS (TREE_TYPE (type
)))
3063 pp_string (buffer
, "pragma Import (CPP, ");
3065 pp_string (buffer
, "pragma Convention (C_Pass_By_Copy, ");
3068 pp_string (buffer
, "pragma Convention (C, ");
3070 package_prefix
= false;
3071 dump_generic_ada_node
3072 (buffer
, TREE_TYPE (type
), type
, cpp_check
, spc
, false, true);
3073 package_prefix
= true;
3074 pp_character (buffer
, ')');
3078 pp_semicolon (buffer
);
3079 newline_and_indent (buffer
, spc
);
3080 pp_string (buffer
, "pragma Unchecked_Union (");
3082 dump_generic_ada_node
3083 (buffer
, TREE_TYPE (type
), type
, cpp_check
, spc
, false, true);
3084 pp_character (buffer
, ')');
3089 pp_semicolon (buffer
);
3090 newline_and_indent (buffer
, spc
);
3091 pp_string (buffer
, "pragma Pack (");
3092 dump_generic_ada_node
3093 (buffer
, TREE_TYPE (type
), type
, cpp_check
, spc
, false, true);
3094 pp_character (buffer
, ')');
3095 bitfield_used
= false;
3098 print_ada_methods (buffer
, node
, cpp_check
, spc
);
3100 /* Print the static fields of the structure, if any. */
3101 need_semicolon
= TYPE_METHODS (node
) == NULL_TREE
;
3102 for (tmp
= TYPE_FIELDS (node
); tmp
; tmp
= TREE_CHAIN (tmp
))
3104 if (DECL_NAME (tmp
) && TREE_STATIC (tmp
))
3108 need_semicolon
= false;
3109 pp_semicolon (buffer
);
3111 pp_newline (buffer
);
3112 pp_newline (buffer
);
3113 print_ada_declaration (buffer
, tmp
, type
, cpp_check
, spc
);
3118 /* Dump all the declarations in SOURCE_FILE to an Ada spec.
3119 COLLECT_ALL_REFS is a front-end callback used to collect all relevant
3120 nodes for SOURCE_FILE. CPP_CHECK is used to perform C++ queries on
3124 dump_ads (const char *source_file
,
3125 void (*collect_all_refs
)(const char *),
3126 int (*cpp_check
)(tree
, cpp_operation
))
3133 pkg_name
= get_ada_package (source_file
);
3135 /* Construct the the .ads filename and package name. */
3136 ads_name
= xstrdup (pkg_name
);
3138 for (s
= ads_name
; *s
; s
++)
3141 ads_name
= reconcat (ads_name
, ads_name
, ".ads", NULL
);
3143 /* Write out the .ads file. */
3144 f
= fopen (ads_name
, "w");
3149 pp_construct (&pp
, NULL
, 0);
3150 pp_needs_newline (&pp
) = true;
3151 pp
.buffer
->stream
= f
;
3153 /* Dump all relevant macros. */
3154 dump_ada_macros (&pp
, source_file
);
3156 /* Reset the table of withs for this file. */
3159 (*collect_all_refs
) (source_file
);
3161 /* Dump all references. */
3162 dump_ada_nodes (&pp
, source_file
, cpp_check
);
3167 fprintf (f
, "\npackage %s is\n\n", pkg_name
);
3168 pp_write_text_to_stream (&pp
);
3169 /* ??? need to free pp */
3170 fprintf (f
, "end %s;\n", pkg_name
);
3178 static const char **source_refs
= NULL
;
3179 static int source_refs_used
= 0;
3180 static int source_refs_allocd
= 0;
3182 /* Add an entry for FILENAME to the table SOURCE_REFS. */
3185 collect_source_ref (const char *filename
)
3192 if (source_refs_allocd
== 0)
3194 source_refs_allocd
= 1024;
3195 source_refs
= XNEWVEC (const char *, source_refs_allocd
);
3198 for (i
= 0; i
< source_refs_used
; i
++)
3199 if (filename
== source_refs
[i
])
3202 if (source_refs_used
== source_refs_allocd
)
3204 source_refs_allocd
*= 2;
3205 source_refs
= XRESIZEVEC (const char *, source_refs
, source_refs_allocd
);
3208 source_refs
[source_refs_used
++] = filename
;
3211 /* Main entry point: dump all Ada specs corresponding to SOURCE_REFS
3212 using callbacks COLLECT_ALL_REFS and CPP_CHECK.
3213 COLLECT_ALL_REFS is a front-end callback used to collect all relevant
3214 nodes for a given source file.
3215 CPP_CHECK is used to perform C++ queries on nodes, or NULL for the C
3219 dump_ada_specs (void (*collect_all_refs
)(const char *),
3220 int (*cpp_check
)(tree
, cpp_operation
))
3224 /* Iterate over the list of files to dump specs for */
3225 for (i
= 0; i
< source_refs_used
; i
++)
3226 dump_ads (source_refs
[i
], collect_all_refs
, cpp_check
);
3228 /* Free files table. */