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 *);
54 static bool separate_class_package (tree
);
56 #define LOCATION_COL(LOC) ((expand_location (LOC)).column)
58 #define INDENT(SPACE) do { \
59 int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
63 /* Given a cpp MACRO, compute the max length BUFFER_LEN of the macro, as well
64 as max length PARAM_LEN of arguments for fun_like macros, and also set
65 SUPPORTED to 0 if the macro cannot be mapped to an Ada construct. */
68 macro_length (const cpp_macro
*macro
, int *supported
, int *buffer_len
,
81 for (i
= 0; i
< macro
->paramc
; i
++)
83 cpp_hashnode
*param
= macro
->params
[i
];
85 *param_len
+= NODE_LEN (param
);
87 if (i
+ 1 < macro
->paramc
)
89 *param_len
+= 2; /* ", " */
91 else if (macro
->variadic
)
97 *param_len
+= 2; /* ")\0" */
100 for (j
= 0; j
< macro
->count
; j
++)
102 cpp_token
*token
= ¯o
->exp
.tokens
[j
];
104 if (token
->flags
& PREV_WHITE
)
107 if (token
->flags
& STRINGIFY_ARG
|| token
->flags
& PASTE_LEFT
)
113 if (token
->type
== CPP_MACRO_ARG
)
115 NODE_LEN (macro
->params
[token
->val
.macro_arg
.arg_no
- 1]);
117 /* Include enough extra space to handle e.g. special characters. */
118 *buffer_len
+= (cpp_token_len (token
) + 1) * 8;
124 /* Dump into PP a set of MAX_ADA_MACROS MACROS (C/C++) as Ada constants when
128 print_ada_macros (pretty_printer
*pp
, cpp_hashnode
**macros
, int max_ada_macros
)
130 int j
, num_macros
= 0, prev_line
= -1;
132 for (j
= 0; j
< max_ada_macros
; j
++)
134 cpp_hashnode
*node
= macros
[j
];
135 const cpp_macro
*macro
= node
->value
.macro
;
137 int supported
= 1, prev_is_one
= 0, buffer_len
, param_len
;
138 int is_string
= 0, is_char
= 0;
140 unsigned char *s
, *params
, *buffer
, *buf_param
, *char_one
= NULL
;
142 macro_length (macro
, &supported
, &buffer_len
, ¶m_len
);
143 s
= buffer
= XALLOCAVEC (unsigned char, buffer_len
);
144 params
= buf_param
= XALLOCAVEC (unsigned char, param_len
);
151 for (i
= 0; i
< macro
->paramc
; i
++)
153 cpp_hashnode
*param
= macro
->params
[i
];
155 memcpy (buf_param
, NODE_NAME (param
), NODE_LEN (param
));
156 buf_param
+= NODE_LEN (param
);
158 if (i
+ 1 < macro
->paramc
)
163 else if (macro
->variadic
)
173 for (i
= 0; supported
&& i
< macro
->count
; i
++)
175 cpp_token
*token
= ¯o
->exp
.tokens
[i
];
178 if (token
->flags
& PREV_WHITE
)
181 if (token
->flags
& STRINGIFY_ARG
|| token
->flags
& PASTE_LEFT
)
191 cpp_hashnode
*param
=
192 macro
->params
[token
->val
.macro_arg
.arg_no
- 1];
193 memcpy (buffer
, NODE_NAME (param
), NODE_LEN (param
));
194 buffer
+= NODE_LEN (param
);
198 case CPP_EQ_EQ
: *buffer
++ = '='; break;
199 case CPP_GREATER
: *buffer
++ = '>'; break;
200 case CPP_LESS
: *buffer
++ = '<'; break;
201 case CPP_PLUS
: *buffer
++ = '+'; break;
202 case CPP_MINUS
: *buffer
++ = '-'; break;
203 case CPP_MULT
: *buffer
++ = '*'; break;
204 case CPP_DIV
: *buffer
++ = '/'; break;
205 case CPP_COMMA
: *buffer
++ = ','; break;
206 case CPP_OPEN_SQUARE
:
207 case CPP_OPEN_PAREN
: *buffer
++ = '('; break;
208 case CPP_CLOSE_SQUARE
: /* fallthrough */
209 case CPP_CLOSE_PAREN
: *buffer
++ = ')'; break;
210 case CPP_DEREF
: /* fallthrough */
211 case CPP_SCOPE
: /* fallthrough */
212 case CPP_DOT
: *buffer
++ = '.'; break;
214 case CPP_EQ
: *buffer
++ = ':'; *buffer
++ = '='; break;
215 case CPP_NOT_EQ
: *buffer
++ = '/'; *buffer
++ = '='; break;
216 case CPP_GREATER_EQ
: *buffer
++ = '>'; *buffer
++ = '='; break;
217 case CPP_LESS_EQ
: *buffer
++ = '<'; *buffer
++ = '='; break;
220 *buffer
++ = 'n'; *buffer
++ = 'o'; *buffer
++ = 't'; break;
222 *buffer
++ = 'm'; *buffer
++ = 'o'; *buffer
++ = 'd'; break;
224 *buffer
++ = 'a'; *buffer
++ = 'n'; *buffer
++ = 'd'; break;
226 *buffer
++ = 'o'; *buffer
++ = 'r'; break;
228 *buffer
++ = 'x'; *buffer
++ = 'o'; *buffer
++ = 'r'; break;
230 strcpy ((char *) buffer
, " and then ");
234 strcpy ((char *) buffer
, " or else ");
240 is_one
= prev_is_one
;
243 case CPP_COMMENT
: break;
255 if (!macro
->fun_like
)
258 buffer
= cpp_spell_token (parse_in
, token
, buffer
, false);
268 c
= cpp_interpret_charconst (parse_in
, token
,
269 &chars_seen
, &ignored
);
270 if (c
>= 32 && c
<= 126)
273 *buffer
++ = (char) c
;
279 ((char *) buffer
, "Character'Val (%d)", (int) c
);
280 buffer
+= chars_seen
;
288 /* Replace "1 << N" by "2 ** N" */
315 case CPP_CLOSE_BRACE
:
319 case CPP_MINUS_MINUS
:
323 case CPP_HEADER_NAME
:
326 case CPP_OBJC_STRING
:
328 if (!macro
->fun_like
)
331 buffer
= cpp_spell_token (parse_in
, token
, buffer
, false);
335 prev_is_one
= is_one
;
342 if (macro
->fun_like
&& supported
)
344 char *start
= (char *) s
;
347 pp_string (pp
, " -- arg-macro: ");
349 if (*start
== '(' && buffer
[-1] == ')')
354 pp_string (pp
, "function ");
358 pp_string (pp
, "procedure ");
361 pp_string (pp
, (const char *) NODE_NAME (node
));
363 pp_string (pp
, (char *) params
);
365 pp_string (pp
, " -- ");
369 pp_string (pp
, "return ");
370 pp_string (pp
, start
);
374 pp_string (pp
, start
);
380 expanded_location sloc
= expand_location (macro
->line
);
382 if (sloc
.line
!= prev_line
+ 1)
386 prev_line
= sloc
.line
;
389 ada_name
= to_ada_name ((const char *) NODE_NAME (node
), NULL
);
390 pp_string (pp
, ada_name
);
392 pp_string (pp
, " : ");
395 pp_string (pp
, "aliased constant String");
397 pp_string (pp
, "aliased constant Character");
399 pp_string (pp
, "constant");
401 pp_string (pp
, " := ");
402 pp_string (pp
, (char *) s
);
405 pp_string (pp
, " & ASCII.NUL");
407 pp_string (pp
, "; -- ");
408 pp_string (pp
, sloc
.file
);
409 pp_character (pp
, ':');
410 pp_scalar (pp
, "%d", sloc
.line
);
415 pp_string (pp
, " -- unsupported macro: ");
416 pp_string (pp
, (const char *) cpp_macro_definition (parse_in
, node
));
425 static const char *source_file
;
426 static int max_ada_macros
;
428 /* Callback used to count the number of relevant macros from
429 cpp_forall_identifiers. PFILE and V are not used. NODE is the current macro
433 count_ada_macro (cpp_reader
*pfile ATTRIBUTE_UNUSED
, cpp_hashnode
*node
,
434 void *v ATTRIBUTE_UNUSED
)
436 const cpp_macro
*macro
= node
->value
.macro
;
438 if (node
->type
== NT_MACRO
&& !(node
->flags
& NODE_BUILTIN
)
440 && *NODE_NAME (node
) != '_'
441 && LOCATION_FILE (macro
->line
) == source_file
)
447 static int store_ada_macro_index
;
449 /* Callback used to store relevant macros from cpp_forall_identifiers.
450 PFILE is not used. NODE is the current macro to store if relevant.
451 MACROS is an array of cpp_hashnode* used to store NODE. */
454 store_ada_macro (cpp_reader
*pfile ATTRIBUTE_UNUSED
,
455 cpp_hashnode
*node
, void *macros
)
457 const cpp_macro
*macro
= node
->value
.macro
;
459 if (node
->type
== NT_MACRO
&& !(node
->flags
& NODE_BUILTIN
)
461 && *NODE_NAME (node
) != '_'
462 && LOCATION_FILE (macro
->line
) == source_file
)
463 ((cpp_hashnode
**) macros
)[store_ada_macro_index
++] = node
;
468 /* Callback used to compare (during qsort) macros. NODE1 and NODE2 are the
469 two macro nodes to compare. */
472 compare_macro (const void *node1
, const void *node2
)
474 typedef const cpp_hashnode
*const_hnode
;
476 const_hnode n1
= *(const const_hnode
*) node1
;
477 const_hnode n2
= *(const const_hnode
*) node2
;
479 return n1
->value
.macro
->line
- n2
->value
.macro
->line
;
482 /* Dump in PP all relevant macros appearing in FILE. */
485 dump_ada_macros (pretty_printer
*pp
, const char* file
)
487 cpp_hashnode
**macros
;
489 /* Initialize file-scope variables. */
491 store_ada_macro_index
= 0;
494 /* Count all potentially relevant macros, and then sort them by sloc. */
495 cpp_forall_identifiers (parse_in
, count_ada_macro
, NULL
);
496 macros
= XALLOCAVEC (cpp_hashnode
*, max_ada_macros
);
497 cpp_forall_identifiers (parse_in
, store_ada_macro
, macros
);
498 qsort (macros
, max_ada_macros
, sizeof (cpp_hashnode
*), compare_macro
);
500 print_ada_macros (pp
, macros
, max_ada_macros
);
503 /* Current source file being handled. */
505 static const char *source_file_base
;
507 /* Compare the declaration (DECL) of struct-like types based on the sloc of
508 their last field (if LAST is true), so that more nested types collate before
510 If ORIG_TYPE is true, also consider struct with a DECL_ORIGINAL_TYPE. */
513 decl_sloc_common (const_tree decl
, bool last
, bool orig_type
)
515 tree type
= TREE_TYPE (decl
);
517 if (TREE_CODE (decl
) == TYPE_DECL
518 && (orig_type
|| !DECL_ORIGINAL_TYPE (decl
))
519 && RECORD_OR_UNION_TYPE_P (type
)
520 && TYPE_FIELDS (type
))
522 tree f
= TYPE_FIELDS (type
);
525 while (TREE_CHAIN (f
))
528 return DECL_SOURCE_LOCATION (f
);
531 return DECL_SOURCE_LOCATION (decl
);
534 /* Return sloc of DECL, using sloc of last field if LAST is true. */
537 decl_sloc (const_tree decl
, bool last
)
539 return decl_sloc_common (decl
, last
, false);
542 /* Compare two declarations (LP and RP) by their source location. */
545 compare_node (const void *lp
, const void *rp
)
547 const_tree lhs
= *((const tree
*) lp
);
548 const_tree rhs
= *((const tree
*) rp
);
550 return decl_sloc (lhs
, true) - decl_sloc (rhs
, true);
553 /* Compare two comments (LP and RP) by their source location. */
556 compare_comment (const void *lp
, const void *rp
)
558 const cpp_comment
*lhs
= (const cpp_comment
*) lp
;
559 const cpp_comment
*rhs
= (const cpp_comment
*) rp
;
561 if (LOCATION_FILE (lhs
->sloc
) != LOCATION_FILE (rhs
->sloc
))
562 return filename_cmp (LOCATION_FILE (lhs
->sloc
),
563 LOCATION_FILE (rhs
->sloc
));
565 if (LOCATION_LINE (lhs
->sloc
) != LOCATION_LINE (rhs
->sloc
))
566 return LOCATION_LINE (lhs
->sloc
) - LOCATION_LINE (rhs
->sloc
);
568 if (LOCATION_COL (lhs
->sloc
) != LOCATION_COL (rhs
->sloc
))
569 return LOCATION_COL (lhs
->sloc
) - LOCATION_COL (rhs
->sloc
);
574 static tree
*to_dump
= NULL
;
575 static int to_dump_count
= 0;
577 /* Collect a list of declarations from T relevant to SOURCE_FILE to be dumped
578 by a subsequent call to dump_ada_nodes. */
581 collect_ada_nodes (tree t
, const char *source_file
)
584 int i
= to_dump_count
;
586 /* Count the likely relevant nodes. */
587 for (n
= t
; n
; n
= TREE_CHAIN (n
))
588 if (!DECL_IS_BUILTIN (n
)
589 && LOCATION_FILE (decl_sloc (n
, false)) == source_file
)
592 /* Allocate sufficient storage for all nodes. */
593 to_dump
= XRESIZEVEC (tree
, to_dump
, to_dump_count
);
595 /* Store the relevant nodes. */
596 for (n
= t
; n
; n
= TREE_CHAIN (n
))
597 if (!DECL_IS_BUILTIN (n
)
598 && LOCATION_FILE (decl_sloc (n
, false)) == source_file
)
602 /* Call back for walk_tree to clear the TREE_VISITED flag of TP. */
605 unmark_visited_r (tree
*tp
, int *walk_subtrees ATTRIBUTE_UNUSED
,
606 void *data ATTRIBUTE_UNUSED
)
608 if (TREE_VISITED (*tp
))
609 TREE_VISITED (*tp
) = 0;
616 /* Dump nodes into PP relevant to SOURCE_FILE, as collected by previous calls
617 to collect_ada_nodes. CPP_CHECK is used to perform C++ queries on nodes. */
620 dump_ada_nodes (pretty_printer
*pp
, const char *source_file
,
621 int (*cpp_check
)(tree
, cpp_operation
))
624 cpp_comment_table
*comments
;
626 /* Sort the table of declarations to dump by sloc. */
627 qsort (to_dump
, to_dump_count
, sizeof (tree
), compare_node
);
629 /* Fetch the table of comments. */
630 comments
= cpp_get_comments (parse_in
);
632 /* Sort the comments table by sloc. */
633 qsort (comments
->entries
, comments
->count
, sizeof (cpp_comment
),
636 /* Interleave comments and declarations in line number order. */
640 /* Advance j until comment j is in this file. */
641 while (j
!= comments
->count
642 && LOCATION_FILE (comments
->entries
[j
].sloc
) != source_file
)
645 /* Advance j until comment j is not a duplicate. */
646 while (j
< comments
->count
- 1
647 && !compare_comment (&comments
->entries
[j
],
648 &comments
->entries
[j
+ 1]))
651 /* Write decls until decl i collates after comment j. */
652 while (i
!= to_dump_count
)
654 if (j
== comments
->count
655 || LOCATION_LINE (decl_sloc (to_dump
[i
], false))
656 < LOCATION_LINE (comments
->entries
[j
].sloc
))
657 print_generic_ada_decl (pp
, to_dump
[i
++], cpp_check
, source_file
);
662 /* Write comment j, if there is one. */
663 if (j
!= comments
->count
)
664 print_comment (pp
, comments
->entries
[j
++].comment
);
666 } while (i
!= to_dump_count
|| j
!= comments
->count
);
668 /* Clear the TREE_VISITED flag over each subtree we've dumped. */
669 for (i
= 0; i
< to_dump_count
; i
++)
670 walk_tree (&to_dump
[i
], unmark_visited_r
, NULL
, NULL
);
672 /* Finalize the to_dump table. */
681 /* Print a COMMENT to the output stream PP. */
684 print_comment (pretty_printer
*pp
, const char *comment
)
686 int len
= strlen (comment
);
687 char *str
= XALLOCAVEC (char, len
+ 1);
689 bool extra_newline
= false;
691 memcpy (str
, comment
, len
+ 1);
693 /* Trim C/C++ comment indicators. */
694 if (str
[len
- 2] == '*' && str
[len
- 1] == '/')
701 tok
= strtok (str
, "\n");
703 pp_string (pp
, " --");
706 tok
= strtok (NULL
, "\n");
708 /* Leave a blank line after multi-line comments. */
710 extra_newline
= true;
717 /* Prints declaration DECL to PP in Ada syntax. The current source file being
718 handled is SOURCE_FILE, and CPP_CHECK is used to perform C++ queries on
722 print_generic_ada_decl (pretty_printer
*pp
, tree decl
,
723 int (*cpp_check
)(tree
, cpp_operation
),
724 const char* source_file
)
726 source_file_base
= source_file
;
728 if (print_ada_declaration (pp
, decl
, 0, cpp_check
, INDENT_INCR
))
735 /* Dump a newline and indent BUFFER by SPC chars. */
738 newline_and_indent (pretty_printer
*buffer
, int spc
)
744 struct with
{ char *s
; const char *in_file
; int limited
; };
745 static struct with
*withs
= NULL
;
746 static int withs_max
= 4096;
747 static int with_len
= 0;
749 /* Record a "with" clause on package S (a limited with if LIMITED_ACCESS is
750 true), if not already done. */
753 append_withs (const char *s
, int limited_access
)
758 withs
= XNEWVEC (struct with
, withs_max
);
760 if (with_len
== withs_max
)
763 withs
= XRESIZEVEC (struct with
, withs
, withs_max
);
766 for (i
= 0; i
< with_len
; i
++)
767 if (!strcmp (s
, withs
[i
].s
)
768 && source_file_base
== withs
[i
].in_file
)
770 withs
[i
].limited
&= limited_access
;
774 withs
[with_len
].s
= xstrdup (s
);
775 withs
[with_len
].in_file
= source_file_base
;
776 withs
[with_len
].limited
= limited_access
;
780 /* Reset "with" clauses. */
783 reset_ada_withs (void)
790 for (i
= 0; i
< with_len
; i
++)
798 /* Dump "with" clauses in F. */
801 dump_ada_withs (FILE *f
)
805 fprintf (f
, "with Interfaces.C; use Interfaces.C;\n");
807 for (i
= 0; i
< with_len
; i
++)
809 (f
, "%swith %s;\n", withs
[i
].limited
? "limited " : "", withs
[i
].s
);
812 /* Return suitable Ada package name from FILE. */
815 get_ada_package (const char *file
)
822 s
= strstr (file
, "/include/");
826 base
= lbasename (file
);
827 res
= XNEWVEC (char, strlen (base
) + 1);
829 for (i
= 0; *base
; base
++, i
++)
841 res
[i
] = (i
== 0 || res
[i
- 1] == '_') ? 'u' : '_';
853 static const char *ada_reserved
[] = {
854 "abort", "abs", "abstract", "accept", "access", "aliased", "all", "and",
855 "array", "at", "begin", "body", "case", "constant", "declare", "delay",
856 "delta", "digits", "do", "else", "elsif", "end", "entry", "exception",
857 "exit", "for", "function", "generic", "goto", "if", "in", "interface", "is",
858 "limited", "loop", "mod", "new", "not", "null", "others", "out", "of", "or",
859 "overriding", "package", "pragma", "private", "procedure", "protected",
860 "raise", "range", "record", "rem", "renames", "requeue", "return", "reverse",
861 "select", "separate", "subtype", "synchronized", "tagged", "task",
862 "terminate", "then", "type", "until", "use", "when", "while", "with", "xor",
865 /* ??? would be nice to specify this list via a config file, so that users
866 can create their own dictionary of conflicts. */
867 static const char *c_duplicates
[] = {
868 /* system will cause troubles with System.Address. */
871 /* The following values have other definitions with same name/other
877 "rl_readline_version",
883 /* Return a declaration tree corresponding to TYPE. */
886 get_underlying_decl (tree type
)
888 tree decl
= NULL_TREE
;
890 if (type
== NULL_TREE
)
893 /* type is a declaration. */
897 /* type is a typedef. */
898 if (TYPE_P (type
) && TYPE_NAME (type
) && DECL_P (TYPE_NAME (type
)))
899 decl
= TYPE_NAME (type
);
901 /* TYPE_STUB_DECL has been set for type. */
902 if (TYPE_P (type
) && TYPE_STUB_DECL (type
) &&
903 DECL_P (TYPE_STUB_DECL (type
)))
904 decl
= TYPE_STUB_DECL (type
);
909 /* Return whether TYPE has static fields. */
912 has_static_fields (const_tree type
)
916 for (tmp
= TYPE_FIELDS (type
); tmp
; tmp
= TREE_CHAIN (tmp
))
918 if (DECL_NAME (tmp
) && TREE_STATIC (tmp
))
924 /* Return whether TYPE corresponds to an Ada tagged type (has a dispatch
928 is_tagged_type (const_tree type
)
932 if (!type
|| !RECORD_OR_UNION_TYPE_P (type
))
935 for (tmp
= TYPE_METHODS (type
); tmp
; tmp
= TREE_CHAIN (tmp
))
936 if (DECL_VINDEX (tmp
))
942 /* Generate a legal Ada name from a C NAME, returning a malloc'd string.
943 SPACE_FOUND, if not NULL, is used to indicate whether a space was found in
947 to_ada_name (const char *name
, int *space_found
)
950 int len
= strlen (name
);
953 char *s
= XNEWVEC (char, len
* 2 + 5);
957 *space_found
= false;
959 /* Add trailing "c_" if name is an Ada reserved word. */
960 for (names
= ada_reserved
; *names
; names
++)
961 if (!strcasecmp (name
, *names
))
970 /* Add trailing "c_" if name is an potential case sensitive duplicate. */
971 for (names
= c_duplicates
; *names
; names
++)
972 if (!strcmp (name
, *names
))
980 for (j
= 0; name
[j
] == '_'; j
++)
985 else if (*name
== '.' || *name
== '$')
995 /* Replace unsuitable characters for Ada identifiers. */
1002 *space_found
= true;
1006 /* ??? missing some C++ operators. */
1010 if (name
[j
+ 1] == '=')
1025 if (name
[j
+ 1] == '=')
1043 s
[len2
++] = name
[j
] == '&' ? 'a' : name
[j
] == '|' ? 'o' : 'x';
1045 if (name
[j
+ 1] == '=')
1058 if (s
[len2
- 1] != '_')
1061 switch (name
[j
+ 1]) {
1064 switch (name
[j
- 1]) {
1065 case '+': s
[len2
++] = 'p'; break; /* + */
1066 case '-': s
[len2
++] = 'm'; break; /* - */
1067 case '*': s
[len2
++] = 't'; break; /* * */
1068 case '/': s
[len2
++] = 'd'; break; /* / */
1074 switch (name
[j
- 1]) {
1075 case '+': s
[len2
++] = 'p'; break; /* += */
1076 case '-': s
[len2
++] = 'm'; break; /* -= */
1077 case '*': s
[len2
++] = 't'; break; /* *= */
1078 case '/': s
[len2
++] = 'd'; break; /* /= */
1112 c
= name
[j
] == '<' ? 'l' : 'g';
1115 switch (name
[j
+ 1]) {
1141 if (len2
&& s
[len2
- 1] == '_')
1146 s
[len2
++] = name
[j
];
1149 if (s
[len2
- 1] == '_')
1157 /* Return true if DECL refers to a C++ class type for which a
1158 separate enclosing package has been or should be generated. */
1161 separate_class_package (tree decl
)
1165 tree type
= TREE_TYPE (decl
);
1167 && TREE_CODE (type
) == RECORD_TYPE
1168 && (TYPE_METHODS (type
) || has_static_fields (type
));
1174 static bool package_prefix
= true;
1176 /* Dump in BUFFER the name of an identifier NODE of type TYPE, following Ada
1177 syntax. LIMITED_ACCESS indicates whether NODE can be accessed via a limited
1178 'with' clause rather than a regular 'with' clause. */
1181 pp_ada_tree_identifier (pretty_printer
*buffer
, tree node
, tree type
,
1184 const char *name
= IDENTIFIER_POINTER (node
);
1185 int space_found
= false;
1186 char *s
= to_ada_name (name
, &space_found
);
1189 /* If the entity is a type and comes from another file, generate "package"
1192 decl
= get_underlying_decl (type
);
1196 expanded_location xloc
= expand_location (decl_sloc (decl
, false));
1198 if (xloc
.file
&& xloc
.line
)
1200 if (xloc
.file
!= source_file_base
)
1202 switch (TREE_CODE (type
))
1207 case FIXED_POINT_TYPE
:
1209 case REFERENCE_TYPE
:
1214 case QUAL_UNION_TYPE
:
1217 char *s1
= get_ada_package (xloc
.file
);
1221 append_withs (s1
, limited_access
);
1222 pp_string (buffer
, s1
);
1223 pp_character (buffer
, '.');
1232 if (separate_class_package (decl
))
1234 pp_string (buffer
, "Class_");
1235 pp_string (buffer
, s
);
1236 pp_string (buffer
, ".");
1244 if (!strcmp (s
, "short_int"))
1245 pp_string (buffer
, "short");
1246 else if (!strcmp (s
, "short_unsigned_int"))
1247 pp_string (buffer
, "unsigned_short");
1248 else if (!strcmp (s
, "unsigned_int"))
1249 pp_string (buffer
, "unsigned");
1250 else if (!strcmp (s
, "long_int"))
1251 pp_string (buffer
, "long");
1252 else if (!strcmp (s
, "long_unsigned_int"))
1253 pp_string (buffer
, "unsigned_long");
1254 else if (!strcmp (s
, "long_long_int"))
1255 pp_string (buffer
, "Long_Long_Integer");
1256 else if (!strcmp (s
, "long_long_unsigned_int"))
1260 append_withs ("Interfaces.C.Extensions", false);
1261 pp_string (buffer
, "Extensions.unsigned_long_long");
1264 pp_string (buffer
, "unsigned_long_long");
1267 pp_string(buffer
, s
);
1269 if (!strcmp (s
, "bool"))
1273 append_withs ("Interfaces.C.Extensions", false);
1274 pp_string (buffer
, "Extensions.bool");
1277 pp_string (buffer
, "bool");
1280 pp_string(buffer
, s
);
1285 /* Dump in BUFFER the assembly name of T. */
1288 pp_asm_name (pretty_printer
*buffer
, tree t
)
1290 tree name
= DECL_ASSEMBLER_NAME (t
);
1291 char *ada_name
= XALLOCAVEC (char, IDENTIFIER_LENGTH (name
) + 1), *s
;
1292 const char *ident
= IDENTIFIER_POINTER (name
);
1294 for (s
= ada_name
; *ident
; ident
++)
1298 else if (*ident
!= '*')
1303 pp_string (buffer
, ada_name
);
1306 /* Dump in BUFFER the name of a DECL node if set, following Ada syntax.
1307 LIMITED_ACCESS indicates whether NODE can be accessed via a limited
1308 'with' clause rather than a regular 'with' clause. */
1311 dump_ada_decl_name (pretty_printer
*buffer
, tree decl
, int limited_access
)
1313 if (DECL_NAME (decl
))
1314 pp_ada_tree_identifier (buffer
, DECL_NAME (decl
), decl
, limited_access
);
1317 tree type_name
= TYPE_NAME (TREE_TYPE (decl
));
1321 pp_string (buffer
, "anon");
1322 if (TREE_CODE (decl
) == FIELD_DECL
)
1323 pp_scalar (buffer
, "%d", DECL_UID (decl
));
1325 pp_scalar (buffer
, "%d", TYPE_UID (TREE_TYPE (decl
)));
1327 else if (TREE_CODE (type_name
) == IDENTIFIER_NODE
)
1328 pp_ada_tree_identifier (buffer
, type_name
, decl
, limited_access
);
1332 /* Dump in BUFFER a name based on both T1 and T2, followed by S. */
1335 dump_ada_double_name (pretty_printer
*buffer
, tree t1
, tree t2
, const char *s
)
1338 pp_ada_tree_identifier (buffer
, DECL_NAME (t1
), t1
, false);
1341 pp_string (buffer
, "anon");
1342 pp_scalar (buffer
, "%d", TYPE_UID (TREE_TYPE (t1
)));
1345 pp_character (buffer
, '_');
1348 pp_ada_tree_identifier (buffer
, DECL_NAME (t2
), t2
, false);
1351 pp_string (buffer
, "anon");
1352 pp_scalar (buffer
, "%d", TYPE_UID (TREE_TYPE (t2
)));
1355 pp_string (buffer
, s
);
1358 /* Dump in BUFFER pragma Import C/CPP on a given node T. */
1361 dump_ada_import (pretty_printer
*buffer
, tree t
)
1363 const char *name
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t
));
1364 int is_stdcall
= TREE_CODE (t
) == FUNCTION_DECL
&&
1365 lookup_attribute ("stdcall", TYPE_ATTRIBUTES (TREE_TYPE (t
)));
1368 pp_string (buffer
, "pragma Import (Stdcall, ");
1369 else if (name
[0] == '_' && name
[1] == 'Z')
1370 pp_string (buffer
, "pragma Import (CPP, ");
1372 pp_string (buffer
, "pragma Import (C, ");
1374 dump_ada_decl_name (buffer
, t
, false);
1375 pp_string (buffer
, ", \"");
1378 pp_string (buffer
, IDENTIFIER_POINTER (DECL_NAME (t
)));
1380 pp_asm_name (buffer
, t
);
1382 pp_string (buffer
, "\");");
1385 /* Check whether T and its type have different names, and append "the_"
1386 otherwise in BUFFER. */
1389 check_name (pretty_printer
*buffer
, tree t
)
1392 tree tmp
= TREE_TYPE (t
);
1394 while (TREE_CODE (tmp
) == POINTER_TYPE
&& !TYPE_NAME (tmp
))
1395 tmp
= TREE_TYPE (tmp
);
1397 if (TREE_CODE (tmp
) != FUNCTION_TYPE
)
1399 if (TREE_CODE (tmp
) == IDENTIFIER_NODE
)
1400 s
= IDENTIFIER_POINTER (tmp
);
1401 else if (!TYPE_NAME (tmp
))
1403 else if (TREE_CODE (TYPE_NAME (tmp
)) == IDENTIFIER_NODE
)
1404 s
= IDENTIFIER_POINTER (TYPE_NAME (tmp
));
1406 s
= IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (tmp
)));
1408 if (!strcasecmp (IDENTIFIER_POINTER (DECL_NAME (t
)), s
))
1409 pp_string (buffer
, "the_");
1413 /* Dump in BUFFER a function declaration FUNC with Ada syntax.
1414 IS_METHOD indicates whether FUNC is a C++ method.
1415 IS_CONSTRUCTOR whether FUNC is a C++ constructor.
1416 IS_DESTRUCTOR whether FUNC is a C++ destructor.
1417 SPC is the current indentation level. */
1420 dump_ada_function_declaration (pretty_printer
*buffer
, tree func
,
1421 int is_method
, int is_constructor
,
1422 int is_destructor
, int spc
)
1425 const tree node
= TREE_TYPE (func
);
1427 int num
= 0, num_args
= 0, have_args
= true, have_ellipsis
= false;
1429 /* Compute number of arguments. */
1430 arg
= TYPE_ARG_TYPES (node
);
1434 while (TREE_CHAIN (arg
) && arg
!= error_mark_node
)
1437 arg
= TREE_CHAIN (arg
);
1440 if (TREE_CODE (TREE_VALUE (arg
)) != VOID_TYPE
)
1443 have_ellipsis
= true;
1454 newline_and_indent (buffer
, spc
+ 1);
1459 pp_character (buffer
, '(');
1462 if (TREE_CODE (func
) == FUNCTION_DECL
)
1463 arg
= DECL_ARGUMENTS (func
);
1467 if (arg
== NULL_TREE
)
1470 arg
= TYPE_ARG_TYPES (node
);
1472 if (arg
&& TREE_CODE (TREE_VALUE (arg
)) == VOID_TYPE
)
1477 arg
= TREE_CHAIN (arg
);
1479 /* Print the argument names (if available) & types. */
1481 for (num
= 1; num
<= num_args
; num
++)
1485 if (DECL_NAME (arg
))
1487 check_name (buffer
, arg
);
1488 pp_ada_tree_identifier (buffer
, DECL_NAME (arg
), 0, false);
1489 pp_string (buffer
, " : ");
1493 sprintf (buf
, "arg%d : ", num
);
1494 pp_string (buffer
, buf
);
1497 dump_generic_ada_node
1498 (buffer
, TREE_TYPE (arg
), node
, NULL
, spc
, 0, true);
1502 sprintf (buf
, "arg%d : ", num
);
1503 pp_string (buffer
, buf
);
1504 dump_generic_ada_node
1505 (buffer
, TREE_VALUE (arg
), node
, NULL
, spc
, 0, true);
1508 if (TREE_TYPE (arg
) && TREE_TYPE (TREE_TYPE (arg
))
1509 && is_tagged_type (TREE_TYPE (TREE_TYPE (arg
))))
1512 || (num
!= 1 || (!DECL_VINDEX (func
) && !is_constructor
)))
1513 pp_string (buffer
, "'Class");
1516 arg
= TREE_CHAIN (arg
);
1520 pp_character (buffer
, ';');
1523 newline_and_indent (buffer
, spc
+ INDENT_INCR
);
1531 pp_string (buffer
, " -- , ...");
1532 newline_and_indent (buffer
, spc
+ INDENT_INCR
);
1536 pp_character (buffer
, ')');
1540 /* Dump in BUFFER all the domains associated with an array NODE,
1541 using Ada syntax. SPC is the current indentation level. */
1544 dump_ada_array_domains (pretty_printer
*buffer
, tree node
, int spc
)
1547 pp_character (buffer
, '(');
1549 for (; TREE_CODE (node
) == ARRAY_TYPE
; node
= TREE_TYPE (node
))
1551 tree domain
= TYPE_DOMAIN (node
);
1555 tree min
= TYPE_MIN_VALUE (domain
);
1556 tree max
= TYPE_MAX_VALUE (domain
);
1559 pp_string (buffer
, ", ");
1563 dump_generic_ada_node (buffer
, min
, NULL_TREE
, NULL
, spc
, 0, true);
1564 pp_string (buffer
, " .. ");
1566 /* If the upper bound is zero, gcc may generate a NULL_TREE
1567 for TYPE_MAX_VALUE rather than an integer_cst. */
1569 dump_generic_ada_node (buffer
, max
, NULL_TREE
, NULL
, spc
, 0, true);
1571 pp_string (buffer
, "0");
1574 pp_string (buffer
, "size_t");
1576 pp_character (buffer
, ')');
1579 /* Dump in BUFFER file:line information related to NODE. */
1582 dump_sloc (pretty_printer
*buffer
, tree node
)
1584 expanded_location xloc
;
1588 if (TREE_CODE_CLASS (TREE_CODE (node
)) == tcc_declaration
)
1589 xloc
= expand_location (DECL_SOURCE_LOCATION (node
));
1590 else if (EXPR_HAS_LOCATION (node
))
1591 xloc
= expand_location (EXPR_LOCATION (node
));
1595 pp_string (buffer
, xloc
.file
);
1596 pp_string (buffer
, ":");
1597 pp_decimal_int (buffer
, xloc
.line
);
1601 /* Return true if T designates a one dimension array of "char". */
1604 is_char_array (tree t
)
1609 /* Retrieve array's type. */
1611 while (TREE_CODE (TREE_TYPE (tmp
)) == ARRAY_TYPE
)
1614 tmp
= TREE_TYPE (tmp
);
1617 tmp
= TREE_TYPE (tmp
);
1618 return num_dim
== 1 && TREE_CODE (tmp
) == INTEGER_TYPE
1619 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (tmp
))), "char");
1622 /* Dump in BUFFER an array type T in Ada syntax. Assume that the "type"
1623 keyword and name have already been printed. SPC is the indentation
1627 dump_ada_array_type (pretty_printer
*buffer
, tree t
, int spc
)
1630 bool char_array
= is_char_array (t
);
1632 /* Special case char arrays. */
1635 pp_string (buffer
, "Interfaces.C.char_array ");
1638 pp_string (buffer
, "array ");
1640 /* Print the dimensions. */
1641 dump_ada_array_domains (buffer
, TREE_TYPE (t
), spc
);
1643 /* Retrieve array's type. */
1644 tmp
= TREE_TYPE (t
);
1645 while (TREE_CODE (TREE_TYPE (tmp
)) == ARRAY_TYPE
)
1646 tmp
= TREE_TYPE (tmp
);
1648 /* Print array's type. */
1651 pp_string (buffer
, " of ");
1653 if (TREE_CODE (TREE_TYPE (tmp
)) != POINTER_TYPE
)
1654 pp_string (buffer
, "aliased ");
1656 dump_generic_ada_node
1657 (buffer
, TREE_TYPE (tmp
), TREE_TYPE (t
), NULL
, spc
, false, true);
1661 /* Dump in BUFFER type names associated with a template, each prepended with
1662 '_'. TYPES is the TREE_PURPOSE of a DECL_TEMPLATE_INSTANTIATIONS.
1663 CPP_CHECK is used to perform C++ queries on nodes.
1664 SPC is the indentation level. */
1667 dump_template_types (pretty_printer
*buffer
, tree types
,
1668 int (*cpp_check
)(tree
, cpp_operation
), int spc
)
1671 size_t len
= TREE_VEC_LENGTH (types
);
1673 for (i
= 0; i
< len
; i
++)
1675 tree elem
= TREE_VEC_ELT (types
, i
);
1676 pp_character (buffer
, '_');
1677 if (!dump_generic_ada_node (buffer
, elem
, 0, cpp_check
, spc
, false, true))
1679 pp_string (buffer
, "unknown");
1680 pp_scalar (buffer
, "%lu", (unsigned long) TREE_HASH (elem
));
1685 /* Dump in BUFFER the contents of all class instantiations associated with
1686 a given template T. CPP_CHECK is used to perform C++ queries on nodes.
1687 SPC is the indentation level. */
1690 dump_ada_template (pretty_printer
*buffer
, tree t
,
1691 int (*cpp_check
)(tree
, cpp_operation
), int spc
)
1693 tree inst
= DECL_VINDEX (t
);
1694 /* DECL_VINDEX is DECL_TEMPLATE_INSTANTIATIONS in this context. */
1697 while (inst
&& inst
!= error_mark_node
)
1699 tree types
= TREE_PURPOSE (inst
);
1700 tree instance
= TREE_VALUE (inst
);
1702 if (TREE_VEC_LENGTH (types
) == 0)
1705 if (!TYPE_P (instance
) || !TYPE_METHODS (instance
))
1710 pp_string (buffer
, "package ");
1711 package_prefix
= false;
1712 dump_generic_ada_node (buffer
, instance
, t
, cpp_check
, spc
, false, true);
1713 dump_template_types (buffer
, types
, cpp_check
, spc
);
1714 pp_string (buffer
, " is");
1716 newline_and_indent (buffer
, spc
);
1718 TREE_VISITED (get_underlying_decl (instance
)) = 1;
1719 pp_string (buffer
, "type ");
1720 dump_generic_ada_node (buffer
, instance
, t
, cpp_check
, spc
, false, true);
1721 package_prefix
= true;
1723 if (is_tagged_type (instance
))
1724 pp_string (buffer
, " is tagged limited ");
1726 pp_string (buffer
, " is limited ");
1728 dump_generic_ada_node (buffer
, instance
, t
, cpp_check
, spc
, false, false);
1729 pp_newline (buffer
);
1731 newline_and_indent (buffer
, spc
);
1733 pp_string (buffer
, "end;");
1734 newline_and_indent (buffer
, spc
);
1735 pp_string (buffer
, "use ");
1736 package_prefix
= false;
1737 dump_generic_ada_node (buffer
, instance
, t
, cpp_check
, spc
, false, true);
1738 dump_template_types (buffer
, types
, cpp_check
, spc
);
1739 package_prefix
= true;
1740 pp_semicolon (buffer
);
1741 pp_newline (buffer
);
1742 pp_newline (buffer
);
1744 inst
= TREE_CHAIN (inst
);
1747 return num_inst
> 0;
1750 /* Return true if NODE is a simple enum types, that can be mapped to an
1751 Ada enum type directly. */
1754 is_simple_enum (tree node
)
1756 unsigned HOST_WIDE_INT count
= 0;
1759 for (value
= TYPE_VALUES (node
); value
; value
= TREE_CHAIN (value
))
1761 tree int_val
= TREE_VALUE (value
);
1763 if (TREE_CODE (int_val
) != INTEGER_CST
)
1764 int_val
= DECL_INITIAL (int_val
);
1766 if (!host_integerp (int_val
, 0))
1768 else if (TREE_INT_CST_LOW (int_val
) != count
)
1777 static bool in_function
= true;
1778 static bool bitfield_used
= false;
1780 /* Recursively dump in BUFFER Ada declarations corresponding to NODE of type
1781 TYPE. CPP_CHECK is used to perform C++ queries on nodes. SPC is the
1782 indentation level. LIMITED_ACCESS indicates whether NODE can be referenced
1783 via a "limited with" clause. NAME_ONLY indicates whether we should only
1784 dump the name of NODE, instead of its full declaration. */
1787 dump_generic_ada_node (pretty_printer
*buffer
, tree node
, tree type
,
1788 int (*cpp_check
)(tree
, cpp_operation
), int spc
,
1789 int limited_access
, bool name_only
)
1791 if (node
== NULL_TREE
)
1794 switch (TREE_CODE (node
))
1797 pp_string (buffer
, "<<< error >>>");
1800 case IDENTIFIER_NODE
:
1801 pp_ada_tree_identifier (buffer
, node
, type
, limited_access
);
1805 pp_string (buffer
, "--- unexpected node: TREE_LIST");
1809 dump_generic_ada_node
1810 (buffer
, BINFO_TYPE (node
), type
, cpp_check
,
1811 spc
, limited_access
, name_only
);
1814 pp_string (buffer
, "--- unexpected node: TREE_VEC");
1820 append_withs ("System", false);
1821 pp_string (buffer
, "System.Address");
1824 pp_string (buffer
, "address");
1828 pp_string (buffer
, "<vector>");
1832 pp_string (buffer
, "<complex>");
1837 dump_generic_ada_node
1838 (buffer
, TYPE_NAME (node
), node
, cpp_check
, spc
, 0, true);
1841 tree value
= TYPE_VALUES (node
);
1843 if (is_simple_enum (node
))
1847 newline_and_indent (buffer
, spc
- 1);
1848 pp_string (buffer
, "(");
1849 for (; value
; value
= TREE_CHAIN (value
))
1855 pp_string (buffer
, ",");
1856 newline_and_indent (buffer
, spc
);
1859 pp_ada_tree_identifier
1860 (buffer
, TREE_PURPOSE (value
), node
, false);
1862 pp_string (buffer
, ");");
1864 newline_and_indent (buffer
, spc
);
1865 pp_string (buffer
, "pragma Convention (C, ");
1866 dump_generic_ada_node
1867 (buffer
, DECL_NAME (type
) ? type
: TYPE_NAME (node
), type
,
1868 cpp_check
, spc
, 0, true);
1869 pp_string (buffer
, ")");
1873 pp_string (buffer
, "unsigned");
1874 for (; value
; value
= TREE_CHAIN (value
))
1876 pp_semicolon (buffer
);
1877 newline_and_indent (buffer
, spc
);
1879 pp_ada_tree_identifier
1880 (buffer
, TREE_PURPOSE (value
), node
, false);
1881 pp_string (buffer
, " : constant ");
1883 dump_generic_ada_node
1884 (buffer
, DECL_NAME (type
) ? type
: TYPE_NAME (node
), type
,
1885 cpp_check
, spc
, 0, true);
1887 pp_string (buffer
, " := ");
1888 dump_generic_ada_node
1890 TREE_CODE (TREE_VALUE (value
)) == INTEGER_CST
?
1891 TREE_VALUE (value
) : DECL_INITIAL (TREE_VALUE (value
)),
1892 node
, cpp_check
, spc
, false, true);
1900 case FIXED_POINT_TYPE
:
1903 enum tree_code_class tclass
;
1905 tclass
= TREE_CODE_CLASS (TREE_CODE (node
));
1907 if (tclass
== tcc_declaration
)
1909 if (DECL_NAME (node
))
1910 pp_ada_tree_identifier
1911 (buffer
, DECL_NAME (node
), 0, limited_access
);
1913 pp_string (buffer
, "<unnamed type decl>");
1915 else if (tclass
== tcc_type
)
1917 if (TYPE_NAME (node
))
1919 if (TREE_CODE (TYPE_NAME (node
)) == IDENTIFIER_NODE
)
1920 pp_ada_tree_identifier (buffer
, TYPE_NAME (node
),
1921 node
, limited_access
);
1922 else if (TREE_CODE (TYPE_NAME (node
)) == TYPE_DECL
1923 && DECL_NAME (TYPE_NAME (node
)))
1924 dump_ada_decl_name (buffer
, TYPE_NAME (node
), limited_access
);
1926 pp_string (buffer
, "<unnamed type>");
1928 else if (TREE_CODE (node
) == INTEGER_TYPE
)
1930 append_withs ("Interfaces.C.Extensions", false);
1931 bitfield_used
= true;
1933 if (TYPE_PRECISION (node
) == 1)
1934 pp_string (buffer
, "Extensions.Unsigned_1");
1937 pp_string (buffer
, (TYPE_UNSIGNED (node
)
1938 ? "Extensions.Unsigned_"
1939 : "Extensions.Signed_"));
1940 pp_decimal_int (buffer
, TYPE_PRECISION (node
));
1944 pp_string (buffer
, "<unnamed type>");
1950 case REFERENCE_TYPE
:
1951 if (TREE_CODE (TREE_TYPE (node
)) == FUNCTION_TYPE
)
1953 tree fnode
= TREE_TYPE (node
);
1955 bool prev_in_function
= in_function
;
1957 if (VOID_TYPE_P (TREE_TYPE (fnode
)))
1959 is_function
= false;
1960 pp_string (buffer
, "access procedure");
1965 pp_string (buffer
, "access function");
1968 in_function
= is_function
;
1969 dump_ada_function_declaration
1970 (buffer
, node
, false, false, false, spc
+ INDENT_INCR
);
1971 in_function
= prev_in_function
;
1975 pp_string (buffer
, " return ");
1976 dump_generic_ada_node
1977 (buffer
, TREE_TYPE (fnode
), type
, cpp_check
, spc
, 0, true);
1982 int is_access
= false;
1983 unsigned int quals
= TYPE_QUALS (TREE_TYPE (node
));
1985 if (name_only
&& TYPE_NAME (node
))
1986 dump_generic_ada_node
1987 (buffer
, TYPE_NAME (node
), node
, cpp_check
,
1988 spc
, limited_access
, true);
1989 else if (VOID_TYPE_P (TREE_TYPE (node
)))
1992 pp_string (buffer
, "new ");
1995 append_withs ("System", false);
1996 pp_string (buffer
, "System.Address");
1999 pp_string (buffer
, "address");
2003 if (TREE_CODE (node
) == POINTER_TYPE
2004 && TREE_CODE (TREE_TYPE (node
)) == INTEGER_TYPE
2006 (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME
2007 (TREE_TYPE (node
)))), "char"))
2010 pp_string (buffer
, "new ");
2014 pp_string (buffer
, "Interfaces.C.Strings.chars_ptr");
2015 append_withs ("Interfaces.C.Strings", false);
2018 pp_string (buffer
, "chars_ptr");
2022 /* For now, handle all access-to-access or
2023 access-to-unknown-structs as opaque system.address. */
2025 tree type_name
= TYPE_NAME (TREE_TYPE (node
));
2026 const_tree typ2
= !type
||
2027 DECL_P (type
) ? type
: TYPE_NAME (type
);
2028 const_tree underlying_type
=
2029 get_underlying_decl (TREE_TYPE (node
));
2031 if (TREE_CODE (TREE_TYPE (node
)) == POINTER_TYPE
2032 /* Pointer to pointer. */
2034 || (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node
))
2035 && (!underlying_type
2036 || !TYPE_FIELDS (TREE_TYPE (underlying_type
))))
2037 /* Pointer to opaque structure. */
2039 || underlying_type
== NULL_TREE
2041 && !TREE_VISITED (underlying_type
)
2042 && !TREE_VISITED (type_name
)
2043 && !is_tagged_type (TREE_TYPE (node
))
2044 && DECL_SOURCE_FILE (underlying_type
)
2045 == source_file_base
)
2046 || (type_name
&& typ2
2047 && DECL_P (underlying_type
)
2049 && decl_sloc (underlying_type
, true)
2050 > decl_sloc (typ2
, true)
2051 && DECL_SOURCE_FILE (underlying_type
)
2052 == DECL_SOURCE_FILE (typ2
)))
2056 append_withs ("System", false);
2058 pp_string (buffer
, "new ");
2059 pp_string (buffer
, "System.Address");
2062 pp_string (buffer
, "address");
2066 if (!package_prefix
)
2067 pp_string (buffer
, "access");
2068 else if (AGGREGATE_TYPE_P (TREE_TYPE (node
)))
2070 if (!type
|| TREE_CODE (type
) != FUNCTION_DECL
)
2072 pp_string (buffer
, "access ");
2075 if (quals
& TYPE_QUAL_CONST
)
2076 pp_string (buffer
, "constant ");
2077 else if (!name_only
)
2078 pp_string (buffer
, "all ");
2080 else if (quals
& TYPE_QUAL_CONST
)
2081 pp_string (buffer
, "in ");
2082 else if (in_function
)
2085 pp_string (buffer
, "access ");
2090 pp_string (buffer
, "access ");
2091 /* ??? should be configurable: access or in out. */
2097 pp_string (buffer
, "access ");
2100 pp_string (buffer
, "all ");
2103 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node
))
2104 && type_name
!= NULL_TREE
)
2105 dump_generic_ada_node
2107 TREE_TYPE (node
), cpp_check
, spc
, is_access
, true);
2109 dump_generic_ada_node
2110 (buffer
, TREE_TYPE (node
), TREE_TYPE (node
),
2111 cpp_check
, spc
, 0, true);
2119 dump_generic_ada_node
2120 (buffer
, TYPE_NAME (node
), node
, cpp_check
,
2121 spc
, limited_access
, true);
2123 dump_ada_array_type (buffer
, node
, spc
);
2128 case QUAL_UNION_TYPE
:
2131 if (TYPE_NAME (node
))
2132 dump_generic_ada_node
2133 (buffer
, TYPE_NAME (node
), node
, cpp_check
,
2134 spc
, limited_access
, true);
2137 pp_string (buffer
, "anon_");
2138 pp_scalar (buffer
, "%d", TYPE_UID (node
));
2142 print_ada_struct_decl
2143 (buffer
, node
, type
, cpp_check
, spc
, true);
2147 if (TREE_CODE (TREE_TYPE (node
)) == POINTER_TYPE
)
2149 pp_wide_integer (buffer
, TREE_INT_CST_LOW (node
));
2150 pp_string (buffer
, "B"); /* pseudo-unit */
2152 else if (!host_integerp (node
, 0))
2155 unsigned HOST_WIDE_INT low
= TREE_INT_CST_LOW (val
);
2156 HOST_WIDE_INT high
= TREE_INT_CST_HIGH (val
);
2158 if (tree_int_cst_sgn (val
) < 0)
2160 pp_character (buffer
, '-');
2161 high
= ~high
+ !low
;
2164 sprintf (pp_buffer (buffer
)->digit_buffer
,
2165 HOST_WIDE_INT_PRINT_DOUBLE_HEX
,
2166 (unsigned HOST_WIDE_INT
) high
, low
);
2167 pp_string (buffer
, pp_buffer (buffer
)->digit_buffer
);
2170 pp_wide_integer (buffer
, TREE_INT_CST_LOW (node
));
2182 dump_ada_decl_name (buffer
, node
, limited_access
);
2186 if (DECL_IS_BUILTIN (node
))
2188 /* Don't print the declaration of built-in types. */
2192 /* If we're in the middle of a declaration, defaults to
2196 append_withs ("System", false);
2197 pp_string (buffer
, "System.Address");
2200 pp_string (buffer
, "address");
2206 dump_ada_decl_name (buffer
, node
, limited_access
);
2209 if (is_tagged_type (TREE_TYPE (node
)))
2211 tree tmp
= TYPE_FIELDS (TREE_TYPE (node
));
2214 /* Look for ancestors. */
2215 for (; tmp
; tmp
= TREE_CHAIN (tmp
))
2217 if (!DECL_NAME (tmp
) && is_tagged_type (TREE_TYPE (tmp
)))
2221 pp_string (buffer
, "limited new ");
2225 pp_string (buffer
, " and ");
2228 (buffer
, TYPE_NAME (TREE_TYPE (tmp
)), false);
2232 pp_string (buffer
, first
? "tagged limited " : " with ");
2234 else if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (node
))
2235 && TYPE_METHODS (TREE_TYPE (node
)))
2236 pp_string (buffer
, "limited ");
2238 dump_generic_ada_node
2239 (buffer
, TREE_TYPE (node
), type
, cpp_check
, spc
, false, false);
2246 case NAMESPACE_DECL
:
2247 dump_ada_decl_name (buffer
, node
, false);
2251 /* Ignore other nodes (e.g. expressions). */
2258 /* Dump in BUFFER NODE's methods. CPP_CHECK is used to perform C++ queries on
2259 nodes. SPC is the indentation level. */
2262 print_ada_methods (pretty_printer
*buffer
, tree node
,
2263 int (*cpp_check
)(tree
, cpp_operation
), int spc
)
2265 tree tmp
= TYPE_METHODS (node
);
2270 pp_semicolon (buffer
);
2272 for (; tmp
; tmp
= TREE_CHAIN (tmp
))
2276 pp_newline (buffer
);
2277 pp_newline (buffer
);
2279 res
= print_ada_declaration (buffer
, tmp
, node
, cpp_check
, spc
);
2284 /* Dump in BUFFER anonymous types nested inside T's definition.
2285 PARENT is the parent node of T.
2286 FORWARD indicates whether a forward declaration of T should be generated.
2287 CPP_CHECK is used to perform C++ queries on
2288 nodes. SPC is the indentation level. */
2291 dump_nested_types (pretty_printer
*buffer
, tree t
, tree parent
, bool forward
,
2292 int (*cpp_check
)(tree
, cpp_operation
), int spc
)
2294 tree field
, outer
, decl
;
2296 /* Avoid recursing over the same tree. */
2297 if (TREE_VISITED (t
))
2300 /* Find possible anonymous arrays/unions/structs recursively. */
2302 outer
= TREE_TYPE (t
);
2304 if (outer
== NULL_TREE
)
2309 pp_string (buffer
, "type ");
2310 dump_generic_ada_node
2311 (buffer
, t
, t
, cpp_check
, spc
, false, true);
2312 pp_semicolon (buffer
);
2313 newline_and_indent (buffer
, spc
);
2314 TREE_VISITED (t
) = 1;
2317 field
= TYPE_FIELDS (outer
);
2320 if ((TREE_TYPE (field
) != outer
2321 || (TREE_CODE (TREE_TYPE (field
)) == POINTER_TYPE
2322 && TREE_TYPE (TREE_TYPE (field
)) != outer
))
2323 && (!TYPE_NAME (TREE_TYPE (field
))
2324 || (TREE_CODE (field
) == TYPE_DECL
2325 && DECL_NAME (field
) != DECL_NAME (t
)
2326 && TYPE_NAME (TREE_TYPE (field
)) != TYPE_NAME (outer
))))
2328 switch (TREE_CODE (TREE_TYPE (field
)))
2331 decl
= TREE_TYPE (TREE_TYPE (field
));
2333 if (TREE_CODE (decl
) == FUNCTION_TYPE
)
2334 for (decl
= TREE_TYPE (decl
);
2335 decl
&& TREE_CODE (decl
) == POINTER_TYPE
;
2336 decl
= TREE_TYPE (decl
));
2338 decl
= get_underlying_decl (decl
);
2342 && decl_sloc (decl
, true) > decl_sloc (t
, true)
2343 && DECL_SOURCE_FILE (decl
) == DECL_SOURCE_FILE (t
)
2344 && !TREE_VISITED (decl
)
2345 && !DECL_IS_BUILTIN (decl
)
2346 && (!RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl
))
2347 || TYPE_FIELDS (TREE_TYPE (decl
))))
2349 /* Generate forward declaration. */
2351 pp_string (buffer
, "type ");
2352 dump_generic_ada_node
2353 (buffer
, decl
, 0, cpp_check
, spc
, false, true);
2354 pp_semicolon (buffer
);
2355 newline_and_indent (buffer
, spc
);
2357 /* Ensure we do not generate duplicate forward
2358 declarations for this type. */
2359 TREE_VISITED (decl
) = 1;
2364 /* Special case char arrays. */
2365 if (is_char_array (field
))
2366 pp_string (buffer
, "sub");
2368 pp_string (buffer
, "type ");
2369 dump_ada_double_name (buffer
, parent
, field
, "_array is ");
2370 dump_ada_array_type (buffer
, field
, spc
);
2371 pp_semicolon (buffer
);
2372 newline_and_indent (buffer
, spc
);
2376 TREE_VISITED (t
) = 1;
2377 dump_nested_types (buffer
, field
, t
, false, cpp_check
, spc
);
2379 pp_string (buffer
, "type ");
2381 if (TYPE_NAME (TREE_TYPE (field
)))
2383 dump_generic_ada_node
2384 (buffer
, TYPE_NAME (TREE_TYPE (field
)), 0, cpp_check
,
2386 pp_string (buffer
, " (discr : unsigned := 0) is ");
2387 print_ada_struct_decl
2388 (buffer
, TREE_TYPE (field
), t
, cpp_check
, spc
, false);
2390 pp_string (buffer
, "pragma Convention (C_Pass_By_Copy, ");
2391 dump_generic_ada_node
2392 (buffer
, TREE_TYPE (field
), 0, cpp_check
,
2394 pp_string (buffer
, ");");
2395 newline_and_indent (buffer
, spc
);
2397 pp_string (buffer
, "pragma Unchecked_Union (");
2398 dump_generic_ada_node
2399 (buffer
, TREE_TYPE (field
), 0, cpp_check
,
2401 pp_string (buffer
, ");");
2405 dump_ada_double_name
2406 (buffer
, parent
, field
,
2407 "_union (discr : unsigned := 0) is ");
2408 print_ada_struct_decl
2409 (buffer
, TREE_TYPE (field
), t
, cpp_check
, spc
, false);
2410 pp_string (buffer
, "pragma Convention (C_Pass_By_Copy, ");
2411 dump_ada_double_name (buffer
, parent
, field
, "_union);");
2412 newline_and_indent (buffer
, spc
);
2414 pp_string (buffer
, "pragma Unchecked_Union (");
2415 dump_ada_double_name (buffer
, parent
, field
, "_union);");
2418 newline_and_indent (buffer
, spc
);
2422 if (TYPE_NAME (TREE_TYPE (t
)) && !TREE_VISITED (t
))
2424 pp_string (buffer
, "type ");
2425 dump_generic_ada_node
2426 (buffer
, t
, parent
, 0, spc
, false, true);
2427 pp_semicolon (buffer
);
2428 newline_and_indent (buffer
, spc
);
2431 TREE_VISITED (t
) = 1;
2432 dump_nested_types (buffer
, field
, t
, false, cpp_check
, spc
);
2433 pp_string (buffer
, "type ");
2435 if (TYPE_NAME (TREE_TYPE (field
)))
2437 dump_generic_ada_node
2438 (buffer
, TREE_TYPE (field
), 0, cpp_check
,
2440 pp_string (buffer
, " is ");
2441 print_ada_struct_decl
2442 (buffer
, TREE_TYPE (field
), t
, cpp_check
, spc
, false);
2443 pp_string (buffer
, "pragma Convention (C_Pass_By_Copy, ");
2444 dump_generic_ada_node
2445 (buffer
, TREE_TYPE (field
), 0, cpp_check
,
2447 pp_string (buffer
, ");");
2451 dump_ada_double_name
2452 (buffer
, parent
, field
, "_struct is ");
2453 print_ada_struct_decl
2454 (buffer
, TREE_TYPE (field
), t
, cpp_check
, spc
, false);
2455 pp_string (buffer
, "pragma Convention (C_Pass_By_Copy, ");
2456 dump_ada_double_name (buffer
, parent
, field
, "_struct);");
2459 newline_and_indent (buffer
, spc
);
2466 field
= TREE_CHAIN (field
);
2469 TREE_VISITED (t
) = 1;
2472 /* Dump in BUFFER destructor spec corresponding to T. */
2475 print_destructor (pretty_printer
*buffer
, tree t
)
2477 const char *s
= IDENTIFIER_POINTER (DECL_NAME (t
));
2480 for (s
+= 2; *s
!= ' '; s
++)
2481 pp_character (buffer
, *s
);
2484 pp_string (buffer
, "Delete_");
2485 pp_ada_tree_identifier (buffer
, DECL_NAME (t
), t
, false);
2489 /* Return the name of type T. */
2494 tree n
= TYPE_NAME (t
);
2496 if (TREE_CODE (n
) == IDENTIFIER_NODE
)
2497 return IDENTIFIER_POINTER (n
);
2499 return IDENTIFIER_POINTER (DECL_NAME (n
));
2502 /* Print in BUFFER the declaration of a variable T of type TYPE in Ada syntax.
2503 CPP_CHECK is used to perform C++ queries on nodes. SPC is the indentation
2504 level. Return 1 if a declaration was printed, 0 otherwise. */
2507 print_ada_declaration (pretty_printer
*buffer
, tree t
, tree type
,
2508 int (*cpp_check
)(tree
, cpp_operation
), int spc
)
2510 int is_var
= 0, need_indent
= 0;
2511 int is_class
= false;
2512 tree name
= TYPE_NAME (TREE_TYPE (t
));
2513 tree decl_name
= DECL_NAME (t
);
2514 bool dump_internal
= get_dump_file_info (TDI_ada
)->flags
& TDF_RAW
;
2515 tree orig
= NULL_TREE
;
2517 if (cpp_check
&& cpp_check (t
, IS_TEMPLATE
))
2518 return dump_ada_template (buffer
, t
, cpp_check
, spc
);
2520 if (TREE_CODE (t
) == CONST_DECL
&& TREE_CODE (TREE_TYPE (t
)) == ENUMERAL_TYPE
)
2521 /* Skip enumeral values: will be handled as part of the type itself. */
2524 if (TREE_CODE (t
) == TYPE_DECL
)
2526 orig
= DECL_ORIGINAL_TYPE (t
);
2528 if (orig
&& TYPE_STUB_DECL (orig
))
2530 tree stub
= TYPE_STUB_DECL (orig
);
2531 tree typ
= TREE_TYPE (stub
);
2533 if (TYPE_NAME (typ
))
2535 /* If types have same representation, and same name (ignoring
2536 casing), then ignore the second type. */
2537 if (type_name (typ
) == type_name (TREE_TYPE (t
))
2538 || !strcasecmp (type_name (typ
), type_name (TREE_TYPE (t
))))
2543 if (RECORD_OR_UNION_TYPE_P (typ
) && !TYPE_FIELDS (typ
))
2545 pp_string (buffer
, "-- skipped empty struct ");
2546 dump_generic_ada_node (buffer
, t
, type
, 0, spc
, false, true);
2550 if (!TREE_VISITED (stub
)
2551 && DECL_SOURCE_FILE (stub
) == source_file_base
)
2553 (buffer
, stub
, stub
, true, cpp_check
, spc
);
2555 pp_string (buffer
, "subtype ");
2556 dump_generic_ada_node (buffer
, t
, type
, 0, spc
, false, true);
2557 pp_string (buffer
, " is ");
2558 dump_generic_ada_node
2559 (buffer
, typ
, type
, 0, spc
, false, true);
2560 pp_semicolon (buffer
);
2566 /* Skip unnamed or anonymous structs/unions/enum types. */
2567 if (!orig
&& !decl_name
&& !name
)
2572 if (cpp_check
|| TREE_CODE (TREE_TYPE (t
)) == ENUMERAL_TYPE
)
2575 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t
)))
2577 /* Search next items until finding a named type decl. */
2578 sloc
= decl_sloc_common (t
, true, true);
2580 for (tmp
= TREE_CHAIN (t
); tmp
; tmp
= TREE_CHAIN (tmp
))
2582 if (TREE_CODE (tmp
) == TYPE_DECL
2583 && (DECL_NAME (tmp
) || TYPE_NAME (TREE_TYPE (tmp
))))
2585 /* If same sloc, it means we can ignore the anonymous
2587 if (decl_sloc_common (tmp
, true, true) == sloc
)
2599 && TREE_CODE (TREE_TYPE (t
)) == ENUMERAL_TYPE
2601 && (*IDENTIFIER_POINTER (decl_name
) == '.'
2602 || *IDENTIFIER_POINTER (decl_name
) == '$'))
2603 /* Skip anonymous enum types (duplicates of real types). */
2608 switch (TREE_CODE (TREE_TYPE (t
)))
2612 case QUAL_UNION_TYPE
:
2613 /* Skip empty structs (typically forward references to real
2615 if (!TYPE_FIELDS (TREE_TYPE (t
)))
2617 pp_string (buffer
, "-- skipped empty struct ");
2618 dump_generic_ada_node (buffer
, t
, type
, 0, spc
, false, true);
2623 && (*IDENTIFIER_POINTER (decl_name
) == '.'
2624 || *IDENTIFIER_POINTER (decl_name
) == '$'))
2626 pp_string (buffer
, "-- skipped anonymous struct ");
2627 dump_generic_ada_node (buffer
, t
, type
, 0, spc
, false, true);
2628 TREE_VISITED (t
) = 1;
2632 if (orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
))
2633 pp_string (buffer
, "subtype ");
2636 dump_nested_types (buffer
, t
, t
, false, cpp_check
, spc
);
2638 if (separate_class_package (t
))
2641 pp_string (buffer
, "package Class_");
2642 dump_generic_ada_node
2643 (buffer
, t
, type
, 0, spc
, false, true);
2644 pp_string (buffer
, " is");
2646 newline_and_indent (buffer
, spc
);
2649 pp_string (buffer
, "type ");
2655 case REFERENCE_TYPE
:
2656 if ((orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
))
2657 || is_char_array (t
))
2658 pp_string (buffer
, "subtype ");
2660 pp_string (buffer
, "type ");
2664 pp_string (buffer
, "-- skipped function type ");
2665 dump_generic_ada_node (buffer
, t
, type
, 0, spc
, false, true);
2670 if ((orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
))
2671 || !is_simple_enum (TREE_TYPE (t
)))
2672 pp_string (buffer
, "subtype ");
2674 pp_string (buffer
, "type ");
2678 pp_string (buffer
, "subtype ");
2680 TREE_VISITED (t
) = 1;
2685 && TREE_CODE (t
) == VAR_DECL
2687 && *IDENTIFIER_POINTER (decl_name
) == '_')
2693 /* Print the type and name. */
2694 if (TREE_CODE (TREE_TYPE (t
)) == ARRAY_TYPE
)
2699 /* Print variable's name. */
2700 dump_generic_ada_node (buffer
, t
, type
, cpp_check
, spc
, false, true);
2702 if (TREE_CODE (t
) == TYPE_DECL
)
2704 pp_string (buffer
, " is ");
2706 if (orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
))
2707 dump_generic_ada_node
2708 (buffer
, TYPE_NAME (orig
), type
,
2709 cpp_check
, spc
, false, true);
2711 dump_ada_array_type (buffer
, t
, spc
);
2715 tree tmp
= TYPE_NAME (TREE_TYPE (t
));
2717 if (spc
== INDENT_INCR
|| TREE_STATIC (t
))
2720 pp_string (buffer
, " : ");
2724 if (TREE_CODE (TREE_TYPE (tmp
)) != POINTER_TYPE
2725 && TREE_CODE (tmp
) != INTEGER_TYPE
)
2726 pp_string (buffer
, "aliased ");
2728 dump_generic_ada_node (buffer
, tmp
, type
, 0, spc
, false, true);
2732 pp_string (buffer
, "aliased ");
2735 dump_ada_array_type (buffer
, t
, spc
);
2737 dump_ada_double_name (buffer
, type
, t
, "_array");
2741 else if (TREE_CODE (t
) == FUNCTION_DECL
)
2743 bool is_function
= true, is_method
, is_abstract_class
= false;
2744 tree decl_name
= DECL_NAME (t
);
2745 int prev_in_function
= in_function
;
2746 bool is_abstract
= false;
2747 bool is_constructor
= false;
2748 bool is_destructor
= false;
2749 bool is_copy_constructor
= false;
2756 is_abstract
= cpp_check (t
, IS_ABSTRACT
);
2757 is_constructor
= cpp_check (t
, IS_CONSTRUCTOR
);
2758 is_destructor
= cpp_check (t
, IS_DESTRUCTOR
);
2759 is_copy_constructor
= cpp_check (t
, IS_COPY_CONSTRUCTOR
);
2762 /* Skip __comp_dtor destructor which is redundant with the '~class()'
2765 && !strncmp (IDENTIFIER_POINTER (decl_name
), "__comp", 6))
2768 /* Skip copy constructors: some are internal only, and those that are
2769 not cannot be called easily from Ada anyway. */
2770 if (is_copy_constructor
)
2773 /* If this function has an entry in the dispatch table, we cannot
2775 if (!dump_internal
&& !DECL_VINDEX (t
)
2776 && *IDENTIFIER_POINTER (decl_name
) == '_')
2778 if (IDENTIFIER_POINTER (decl_name
)[1] == '_')
2782 pp_string (buffer
, "-- skipped func ");
2783 pp_string (buffer
, IDENTIFIER_POINTER (decl_name
));
2791 pp_string (buffer
, "function New_");
2792 else if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (t
))))
2794 is_function
= false;
2795 pp_string (buffer
, "procedure ");
2798 pp_string (buffer
, "function ");
2800 in_function
= is_function
;
2801 is_method
= TREE_CODE (TREE_TYPE (t
)) == METHOD_TYPE
;
2804 print_destructor (buffer
, t
);
2806 dump_ada_decl_name (buffer
, t
, false);
2808 dump_ada_function_declaration
2809 (buffer
, t
, is_method
, is_constructor
, is_destructor
, spc
);
2810 in_function
= prev_in_function
;
2814 pp_string (buffer
, " return ");
2818 dump_ada_decl_name (buffer
, t
, false);
2822 dump_generic_ada_node
2823 (buffer
, TREE_TYPE (TREE_TYPE (t
)), type
, cpp_check
,
2828 if (is_constructor
&& cpp_check
&& type
2829 && AGGREGATE_TYPE_P (type
)
2830 && TYPE_METHODS (type
))
2832 tree tmp
= TYPE_METHODS (type
);
2834 for (; tmp
; tmp
= TREE_CHAIN (tmp
))
2835 if (cpp_check (tmp
, IS_ABSTRACT
))
2837 is_abstract_class
= 1;
2842 if (is_abstract
|| is_abstract_class
)
2843 pp_string (buffer
, " is abstract");
2845 pp_semicolon (buffer
);
2846 pp_string (buffer
, " -- ");
2847 dump_sloc (buffer
, t
);
2852 newline_and_indent (buffer
, spc
);
2856 pp_string (buffer
, "pragma CPP_Constructor (New_");
2857 dump_ada_decl_name (buffer
, t
, false);
2858 pp_string (buffer
, ", \"");
2859 pp_asm_name (buffer
, t
);
2860 pp_string (buffer
, "\");");
2862 else if (is_destructor
)
2864 pp_string (buffer
, "pragma Import (CPP, ");
2865 print_destructor (buffer
, t
);
2866 pp_string (buffer
, ", \"");
2867 pp_asm_name (buffer
, t
);
2868 pp_string (buffer
, "\");");
2872 dump_ada_import (buffer
, t
);
2877 else if (TREE_CODE (t
) == TYPE_DECL
&& !DECL_ORIGINAL_TYPE (t
))
2879 int is_interface
= 0;
2880 int is_abstract_record
= 0;
2885 /* Anonymous structs/unions */
2886 dump_generic_ada_node
2887 (buffer
, TREE_TYPE (t
), t
, cpp_check
, spc
, false, true);
2889 if (TREE_CODE (TREE_TYPE (t
)) == UNION_TYPE
2890 || TREE_CODE (TREE_TYPE (t
)) == QUAL_UNION_TYPE
)
2892 pp_string (buffer
, " (discr : unsigned := 0)");
2895 pp_string (buffer
, " is ");
2897 /* Check whether we have an Ada interface compatible class. */
2898 if (cpp_check
&& AGGREGATE_TYPE_P (TREE_TYPE (t
))
2899 && TYPE_METHODS (TREE_TYPE (t
)))
2902 tree tmp
= TYPE_FIELDS (TREE_TYPE (t
));
2904 /* Check that there are no fields other than the virtual table. */
2905 for (; tmp
; tmp
= TREE_CHAIN (tmp
))
2907 if (TREE_CODE (tmp
) == TYPE_DECL
)
2912 if (num_fields
== 1)
2915 /* Also check that there are only virtual methods. */
2916 for (tmp
= TYPE_METHODS (TREE_TYPE (t
)); tmp
; tmp
= TREE_CHAIN (tmp
))
2918 if (cpp_check (tmp
, IS_ABSTRACT
))
2919 is_abstract_record
= 1;
2925 TREE_VISITED (t
) = 1;
2928 pp_string (buffer
, "limited interface; -- ");
2929 dump_sloc (buffer
, t
);
2930 newline_and_indent (buffer
, spc
);
2931 pp_string (buffer
, "pragma Import (CPP, ");
2932 dump_generic_ada_node
2933 (buffer
, TYPE_NAME (TREE_TYPE (t
)), type
, cpp_check
,
2935 pp_character (buffer
, ')');
2937 print_ada_methods (buffer
, TREE_TYPE (t
), cpp_check
, spc
);
2941 if (is_abstract_record
)
2942 pp_string (buffer
, "abstract ");
2943 dump_generic_ada_node (buffer
, t
, t
, cpp_check
, spc
, false, false);
2951 if (TREE_CODE (t
) == FIELD_DECL
&& DECL_NAME (t
))
2952 check_name (buffer
, t
);
2954 /* Print variable/type's name. */
2955 dump_generic_ada_node (buffer
, t
, t
, cpp_check
, spc
, false, true);
2957 if (TREE_CODE (t
) == TYPE_DECL
)
2959 tree orig
= DECL_ORIGINAL_TYPE (t
);
2960 int is_subtype
= orig
&& TYPE_NAME (orig
) && orig
!= TREE_TYPE (t
);
2963 && (TREE_CODE (TREE_TYPE (t
)) == UNION_TYPE
2964 || TREE_CODE (TREE_TYPE (t
)) == QUAL_UNION_TYPE
))
2965 pp_string (buffer
, " (discr : unsigned := 0)");
2967 pp_string (buffer
, " is ");
2969 dump_generic_ada_node
2970 (buffer
, orig
, t
, cpp_check
, spc
, false, is_subtype
);
2974 if (spc
== INDENT_INCR
|| TREE_STATIC (t
))
2977 pp_string (buffer
, " : ");
2979 /* Print type declaration. */
2981 if (TREE_CODE (TREE_TYPE (t
)) == UNION_TYPE
2982 && !TYPE_NAME (TREE_TYPE (t
)))
2984 dump_ada_double_name (buffer
, type
, t
, "_union");
2986 else if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (t
)))
2988 if (TREE_CODE (TREE_TYPE (t
)) == RECORD_TYPE
)
2989 pp_string (buffer
, "aliased ");
2991 dump_generic_ada_node
2992 (buffer
, TREE_TYPE (t
), t
, cpp_check
, spc
, false, true);
2996 if (TREE_CODE (TREE_TYPE (t
)) != POINTER_TYPE
2997 && (TYPE_NAME (TREE_TYPE (t
))
2998 || TREE_CODE (TREE_TYPE (t
)) != INTEGER_TYPE
))
2999 pp_string (buffer
, "aliased ");
3001 dump_generic_ada_node
3002 (buffer
, TREE_TYPE (t
), TREE_TYPE (t
), cpp_check
,
3011 newline_and_indent (buffer
, spc
);
3012 pp_string (buffer
, "end;");
3013 newline_and_indent (buffer
, spc
);
3014 pp_string (buffer
, "use Class_");
3015 dump_generic_ada_node (buffer
, t
, type
, 0, spc
, false, true);
3016 pp_semicolon (buffer
);
3017 pp_newline (buffer
);
3019 /* All needed indentation/newline performed already, so return 0. */
3024 pp_string (buffer
, "; -- ");
3025 dump_sloc (buffer
, t
);
3030 newline_and_indent (buffer
, spc
);
3031 dump_ada_import (buffer
, t
);
3037 /* Prints in BUFFER a structure NODE of type TYPE: name, fields, and methods
3038 with Ada syntax. CPP_CHECK is used to perform C++ queries on nodes. SPC
3039 is the indentation level. If DISPLAY_CONVENTION is true, also print the
3040 pragma Convention for NODE. */
3043 print_ada_struct_decl (pretty_printer
*buffer
, tree node
, tree type
,
3044 int (*cpp_check
)(tree
, cpp_operation
), int spc
,
3045 bool display_convention
)
3049 TREE_CODE (node
) == UNION_TYPE
|| TREE_CODE (node
) == QUAL_UNION_TYPE
;
3052 int field_spc
= spc
+ INDENT_INCR
;
3055 bitfield_used
= false;
3057 if (!TYPE_FIELDS (node
))
3058 pp_string (buffer
, "null record;");
3061 pp_string (buffer
, "record");
3063 /* Print the contents of the structure. */
3067 newline_and_indent (buffer
, spc
+ INDENT_INCR
);
3068 pp_string (buffer
, "case discr is");
3069 field_spc
= spc
+ INDENT_INCR
* 3;
3072 pp_newline (buffer
);
3074 /* Print the non-static fields of the structure. */
3075 for (tmp
= TYPE_FIELDS (node
); tmp
; tmp
= TREE_CHAIN (tmp
))
3077 /* Add parent field if needed. */
3078 if (!DECL_NAME (tmp
))
3080 if (!is_tagged_type (TREE_TYPE (tmp
)))
3082 if (!TYPE_NAME (TREE_TYPE (tmp
)))
3083 print_ada_declaration
3084 (buffer
, tmp
, type
, cpp_check
, field_spc
);
3090 pp_string (buffer
, "parent : ");
3093 sprintf (buf
, "field_%d : ", field_num
+ 1);
3094 pp_string (buffer
, buf
);
3097 (buffer
, TYPE_NAME (TREE_TYPE (tmp
)), false);
3098 pp_semicolon (buffer
);
3100 pp_newline (buffer
);
3104 /* Avoid printing the structure recursively. */
3105 else if ((TREE_TYPE (tmp
) != node
3106 || (TREE_CODE (TREE_TYPE (tmp
)) == POINTER_TYPE
3107 && TREE_TYPE (TREE_TYPE (tmp
)) != node
))
3108 && TREE_CODE (tmp
) != TYPE_DECL
3109 && !TREE_STATIC (tmp
))
3111 /* Skip internal virtual table field. */
3112 if (strncmp (IDENTIFIER_POINTER (DECL_NAME (tmp
)), "_vptr", 5))
3116 if (TREE_CHAIN (tmp
)
3117 && TREE_TYPE (TREE_CHAIN (tmp
)) != node
3118 && TREE_CODE (TREE_CHAIN (tmp
)) != TYPE_DECL
)
3119 sprintf (buf
, "when %d =>", field_num
);
3121 sprintf (buf
, "when others =>");
3123 INDENT (spc
+ INDENT_INCR
* 2);
3124 pp_string (buffer
, buf
);
3125 pp_newline (buffer
);
3128 if (print_ada_declaration (buffer
,
3129 tmp
, type
, cpp_check
, field_spc
))
3131 pp_newline (buffer
);
3140 INDENT (spc
+ INDENT_INCR
);
3141 pp_string (buffer
, "end case;");
3142 pp_newline (buffer
);
3147 INDENT (spc
+ INDENT_INCR
);
3148 pp_string (buffer
, "null;");
3149 pp_newline (buffer
);
3153 pp_string (buffer
, "end record;");
3156 newline_and_indent (buffer
, spc
);
3158 if (!display_convention
)
3161 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type
)))
3163 if (TYPE_METHODS (TREE_TYPE (type
)))
3164 pp_string (buffer
, "pragma Import (CPP, ");
3166 pp_string (buffer
, "pragma Convention (C_Pass_By_Copy, ");
3169 pp_string (buffer
, "pragma Convention (C, ");
3171 package_prefix
= false;
3172 dump_generic_ada_node
3173 (buffer
, TREE_TYPE (type
), type
, cpp_check
, spc
, false, true);
3174 package_prefix
= true;
3175 pp_character (buffer
, ')');
3179 pp_semicolon (buffer
);
3180 newline_and_indent (buffer
, spc
);
3181 pp_string (buffer
, "pragma Unchecked_Union (");
3183 dump_generic_ada_node
3184 (buffer
, TREE_TYPE (type
), type
, cpp_check
, spc
, false, true);
3185 pp_character (buffer
, ')');
3190 pp_semicolon (buffer
);
3191 newline_and_indent (buffer
, spc
);
3192 pp_string (buffer
, "pragma Pack (");
3193 dump_generic_ada_node
3194 (buffer
, TREE_TYPE (type
), type
, cpp_check
, spc
, false, true);
3195 pp_character (buffer
, ')');
3196 bitfield_used
= false;
3199 print_ada_methods (buffer
, node
, cpp_check
, spc
);
3201 /* Print the static fields of the structure, if any. */
3202 need_semicolon
= TYPE_METHODS (node
) == NULL_TREE
;
3203 for (tmp
= TYPE_FIELDS (node
); tmp
; tmp
= TREE_CHAIN (tmp
))
3205 if (DECL_NAME (tmp
) && TREE_STATIC (tmp
))
3209 need_semicolon
= false;
3210 pp_semicolon (buffer
);
3212 pp_newline (buffer
);
3213 pp_newline (buffer
);
3214 print_ada_declaration (buffer
, tmp
, type
, cpp_check
, spc
);
3219 /* Dump all the declarations in SOURCE_FILE to an Ada spec.
3220 COLLECT_ALL_REFS is a front-end callback used to collect all relevant
3221 nodes for SOURCE_FILE. CPP_CHECK is used to perform C++ queries on
3225 dump_ads (const char *source_file
,
3226 void (*collect_all_refs
)(const char *),
3227 int (*cpp_check
)(tree
, cpp_operation
))
3234 pkg_name
= get_ada_package (source_file
);
3236 /* Construct the .ads filename and package name. */
3237 ads_name
= xstrdup (pkg_name
);
3239 for (s
= ads_name
; *s
; s
++)
3242 ads_name
= reconcat (ads_name
, ads_name
, ".ads", NULL
);
3244 /* Write out the .ads file. */
3245 f
= fopen (ads_name
, "w");
3250 pp_construct (&pp
, NULL
, 0);
3251 pp_needs_newline (&pp
) = true;
3252 pp
.buffer
->stream
= f
;
3254 /* Dump all relevant macros. */
3255 dump_ada_macros (&pp
, source_file
);
3257 /* Reset the table of withs for this file. */
3260 (*collect_all_refs
) (source_file
);
3262 /* Dump all references. */
3263 dump_ada_nodes (&pp
, source_file
, cpp_check
);
3268 fprintf (f
, "\npackage %s is\n\n", pkg_name
);
3269 pp_write_text_to_stream (&pp
);
3270 /* ??? need to free pp */
3271 fprintf (f
, "end %s;\n", pkg_name
);
3279 static const char **source_refs
= NULL
;
3280 static int source_refs_used
= 0;
3281 static int source_refs_allocd
= 0;
3283 /* Add an entry for FILENAME to the table SOURCE_REFS. */
3286 collect_source_ref (const char *filename
)
3293 if (source_refs_allocd
== 0)
3295 source_refs_allocd
= 1024;
3296 source_refs
= XNEWVEC (const char *, source_refs_allocd
);
3299 for (i
= 0; i
< source_refs_used
; i
++)
3300 if (filename
== source_refs
[i
])
3303 if (source_refs_used
== source_refs_allocd
)
3305 source_refs_allocd
*= 2;
3306 source_refs
= XRESIZEVEC (const char *, source_refs
, source_refs_allocd
);
3309 source_refs
[source_refs_used
++] = filename
;
3312 /* Main entry point: dump all Ada specs corresponding to SOURCE_REFS
3313 using callbacks COLLECT_ALL_REFS and CPP_CHECK.
3314 COLLECT_ALL_REFS is a front-end callback used to collect all relevant
3315 nodes for a given source file.
3316 CPP_CHECK is used to perform C++ queries on nodes, or NULL for the C
3320 dump_ada_specs (void (*collect_all_refs
)(const char *),
3321 int (*cpp_check
)(tree
, cpp_operation
))
3325 /* Iterate over the list of files to dump specs for */
3326 for (i
= 0; i
< source_refs_used
; i
++)
3327 dump_ads (source_refs
[i
], collect_all_refs
, cpp_check
);
3329 /* Free files table. */