1cf7f2e2dSJohn Marino /* D language support routines for GDB, the GNU debugger.
2cf7f2e2dSJohn Marino
3*ef5ccd6cSJohn Marino Copyright (C) 2005-2013 Free Software Foundation, Inc.
4cf7f2e2dSJohn Marino
5cf7f2e2dSJohn Marino This file is part of GDB.
6cf7f2e2dSJohn Marino
7cf7f2e2dSJohn Marino This program is free software; you can redistribute it and/or modify
8cf7f2e2dSJohn Marino it under the terms of the GNU General Public License as published by
9cf7f2e2dSJohn Marino the Free Software Foundation; either version 3 of the License, or
10cf7f2e2dSJohn Marino (at your option) any later version.
11cf7f2e2dSJohn Marino
12cf7f2e2dSJohn Marino This program is distributed in the hope that it will be useful,
13cf7f2e2dSJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
14cf7f2e2dSJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15cf7f2e2dSJohn Marino GNU General Public License for more details.
16cf7f2e2dSJohn Marino
17cf7f2e2dSJohn Marino You should have received a copy of the GNU General Public License
18cf7f2e2dSJohn Marino along with this program. If not, see <http://www.gnu.org/licenses/>. */
19cf7f2e2dSJohn Marino
20cf7f2e2dSJohn Marino #include "defs.h"
21cf7f2e2dSJohn Marino #include "symtab.h"
22cf7f2e2dSJohn Marino #include "language.h"
23cf7f2e2dSJohn Marino #include "d-lang.h"
24cf7f2e2dSJohn Marino #include "c-lang.h"
25cf7f2e2dSJohn Marino #include "gdb_string.h"
26cf7f2e2dSJohn Marino #include "parser-defs.h"
27cf7f2e2dSJohn Marino #include "gdb_obstack.h"
28cf7f2e2dSJohn Marino
29cf7f2e2dSJohn Marino #include <ctype.h>
30cf7f2e2dSJohn Marino
31cf7f2e2dSJohn Marino /* Extract identifiers from MANGLED_STR and append it to TEMPBUF.
32cf7f2e2dSJohn Marino Return 1 on success or 0 on failure. */
33cf7f2e2dSJohn Marino static int
extract_identifiers(const char * mangled_str,struct obstack * tempbuf)34cf7f2e2dSJohn Marino extract_identifiers (const char *mangled_str, struct obstack *tempbuf)
35cf7f2e2dSJohn Marino {
36cf7f2e2dSJohn Marino long i = 0;
37cf7f2e2dSJohn Marino
38cf7f2e2dSJohn Marino while (isdigit (*mangled_str))
39cf7f2e2dSJohn Marino {
40cf7f2e2dSJohn Marino char *end_ptr;
41cf7f2e2dSJohn Marino
42cf7f2e2dSJohn Marino i = strtol (mangled_str, &end_ptr, 10);
43cf7f2e2dSJohn Marino mangled_str = end_ptr;
44cf7f2e2dSJohn Marino if (i <= 0 || strlen (mangled_str) < i)
45cf7f2e2dSJohn Marino return 0;
46cf7f2e2dSJohn Marino obstack_grow (tempbuf, mangled_str, i);
47cf7f2e2dSJohn Marino mangled_str += i;
48cf7f2e2dSJohn Marino obstack_grow_str (tempbuf, ".");
49cf7f2e2dSJohn Marino }
50cf7f2e2dSJohn Marino if (*mangled_str == '\0' || i == 0)
51cf7f2e2dSJohn Marino return 0;
52cf7f2e2dSJohn Marino obstack_blank (tempbuf, -1);
53cf7f2e2dSJohn Marino return 1;
54cf7f2e2dSJohn Marino }
55cf7f2e2dSJohn Marino
56cf7f2e2dSJohn Marino /* Extract and demangle type from MANGLED_STR and append it to TEMPBUF.
57cf7f2e2dSJohn Marino Return 1 on success or 0 on failure. */
58cf7f2e2dSJohn Marino static int
extract_type_info(const char * mangled_str,struct obstack * tempbuf)59cf7f2e2dSJohn Marino extract_type_info (const char *mangled_str, struct obstack *tempbuf)
60cf7f2e2dSJohn Marino {
61cf7f2e2dSJohn Marino if (*mangled_str == '\0')
62cf7f2e2dSJohn Marino return 0;
63cf7f2e2dSJohn Marino switch (*mangled_str++)
64cf7f2e2dSJohn Marino {
65cf7f2e2dSJohn Marino case 'A': /* dynamic array */
66cf7f2e2dSJohn Marino case 'G': /* static array */
67cf7f2e2dSJohn Marino case 'H': /* associative array */
68cf7f2e2dSJohn Marino if (!extract_type_info (mangled_str, tempbuf))
69cf7f2e2dSJohn Marino return 0;
70cf7f2e2dSJohn Marino obstack_grow_str (tempbuf, "[]");
71cf7f2e2dSJohn Marino return 1;
72cf7f2e2dSJohn Marino case 'P': /* pointer */
73cf7f2e2dSJohn Marino if (!extract_type_info (mangled_str, tempbuf))
74cf7f2e2dSJohn Marino return 0;
75cf7f2e2dSJohn Marino obstack_grow_str (tempbuf, "*");
76cf7f2e2dSJohn Marino return 1;
77cf7f2e2dSJohn Marino case 'R': /* reference */
78cf7f2e2dSJohn Marino if (!extract_type_info (mangled_str, tempbuf))
79cf7f2e2dSJohn Marino return 0;
80cf7f2e2dSJohn Marino obstack_grow_str (tempbuf, "&");
81cf7f2e2dSJohn Marino return 1;
82cf7f2e2dSJohn Marino case 'Z': /* return value */
83cf7f2e2dSJohn Marino return extract_type_info (mangled_str, tempbuf);
84cf7f2e2dSJohn Marino case 'J': /* out */
85cf7f2e2dSJohn Marino obstack_grow_str (tempbuf, "out ");
86cf7f2e2dSJohn Marino return extract_type_info (mangled_str, tempbuf);
87cf7f2e2dSJohn Marino case 'K': /* inout */
88cf7f2e2dSJohn Marino obstack_grow_str (tempbuf, "inout ");
89cf7f2e2dSJohn Marino return extract_type_info (mangled_str, tempbuf);
90cf7f2e2dSJohn Marino case 'E': /* enum */
91cf7f2e2dSJohn Marino case 'T': /* typedef */
92cf7f2e2dSJohn Marino case 'D': /* delegate */
93cf7f2e2dSJohn Marino case 'C': /* class */
94cf7f2e2dSJohn Marino case 'S': /* struct */
95cf7f2e2dSJohn Marino return extract_identifiers (mangled_str, tempbuf);
96cf7f2e2dSJohn Marino
97cf7f2e2dSJohn Marino /* basic types: */
98cf7f2e2dSJohn Marino case 'n': obstack_grow_str (tempbuf, "none"); return 1;
99cf7f2e2dSJohn Marino case 'v': obstack_grow_str (tempbuf, "void"); return 1;
100cf7f2e2dSJohn Marino case 'g': obstack_grow_str (tempbuf, "byte"); return 1;
101cf7f2e2dSJohn Marino case 'h': obstack_grow_str (tempbuf, "ubyte"); return 1;
102cf7f2e2dSJohn Marino case 's': obstack_grow_str (tempbuf, "short"); return 1;
103cf7f2e2dSJohn Marino case 't': obstack_grow_str (tempbuf, "ushort"); return 1;
104cf7f2e2dSJohn Marino case 'i': obstack_grow_str (tempbuf, "int"); return 1;
105cf7f2e2dSJohn Marino case 'k': obstack_grow_str (tempbuf, "uint"); return 1;
106cf7f2e2dSJohn Marino case 'l': obstack_grow_str (tempbuf, "long"); return 1;
107cf7f2e2dSJohn Marino case 'm': obstack_grow_str (tempbuf, "ulong"); return 1;
108cf7f2e2dSJohn Marino case 'f': obstack_grow_str (tempbuf, "float"); return 1;
109cf7f2e2dSJohn Marino case 'd': obstack_grow_str (tempbuf, "double"); return 1;
110cf7f2e2dSJohn Marino case 'e': obstack_grow_str (tempbuf, "real"); return 1;
111cf7f2e2dSJohn Marino
112cf7f2e2dSJohn Marino /* imaginary and complex: */
113cf7f2e2dSJohn Marino case 'o': obstack_grow_str (tempbuf, "ifloat"); return 1;
114cf7f2e2dSJohn Marino case 'p': obstack_grow_str (tempbuf, "idouble"); return 1;
115cf7f2e2dSJohn Marino case 'j': obstack_grow_str (tempbuf, "ireal"); return 1;
116cf7f2e2dSJohn Marino case 'q': obstack_grow_str (tempbuf, "cfloat"); return 1;
117cf7f2e2dSJohn Marino case 'r': obstack_grow_str (tempbuf, "cdouble"); return 1;
118cf7f2e2dSJohn Marino case 'c': obstack_grow_str (tempbuf, "creal"); return 1;
119cf7f2e2dSJohn Marino
120cf7f2e2dSJohn Marino /* other types: */
121cf7f2e2dSJohn Marino case 'b': obstack_grow_str (tempbuf, "bit"); return 1;
122cf7f2e2dSJohn Marino case 'a': obstack_grow_str (tempbuf, "char"); return 1;
123cf7f2e2dSJohn Marino case 'u': obstack_grow_str (tempbuf, "wchar"); return 1;
124cf7f2e2dSJohn Marino case 'w': obstack_grow_str (tempbuf, "dchar"); return 1;
125cf7f2e2dSJohn Marino
126cf7f2e2dSJohn Marino default:
127cf7f2e2dSJohn Marino obstack_grow_str (tempbuf, "unknown");
128cf7f2e2dSJohn Marino return 1;
129cf7f2e2dSJohn Marino }
130cf7f2e2dSJohn Marino }
131cf7f2e2dSJohn Marino
132cf7f2e2dSJohn Marino /* Implements the la_demangle language_defn routine for language D. */
133cf7f2e2dSJohn Marino char *
d_demangle(const char * symbol,int options)134cf7f2e2dSJohn Marino d_demangle (const char *symbol, int options)
135cf7f2e2dSJohn Marino {
136cf7f2e2dSJohn Marino struct obstack tempbuf;
137cf7f2e2dSJohn Marino char *out_str;
138cf7f2e2dSJohn Marino unsigned char is_func = 0;
139cf7f2e2dSJohn Marino
140cf7f2e2dSJohn Marino if (symbol == NULL)
141cf7f2e2dSJohn Marino return NULL;
142cf7f2e2dSJohn Marino else if (strcmp (symbol, "_Dmain") == 0)
143cf7f2e2dSJohn Marino return xstrdup ("D main");
144cf7f2e2dSJohn Marino
145cf7f2e2dSJohn Marino obstack_init (&tempbuf);
146cf7f2e2dSJohn Marino
147cf7f2e2dSJohn Marino if (symbol[0] == '_' && symbol[1] == 'D')
148cf7f2e2dSJohn Marino {
149cf7f2e2dSJohn Marino symbol += 2;
150cf7f2e2dSJohn Marino is_func = 1;
151cf7f2e2dSJohn Marino }
152cf7f2e2dSJohn Marino else if (strncmp (symbol, "__Class_", 8) == 0)
153cf7f2e2dSJohn Marino symbol += 8;
154cf7f2e2dSJohn Marino else if (strncmp (symbol, "__init_", 7) == 0)
155cf7f2e2dSJohn Marino symbol += 7;
156cf7f2e2dSJohn Marino else if (strncmp (symbol, "__vtbl_", 7) == 0)
157cf7f2e2dSJohn Marino symbol += 7;
158cf7f2e2dSJohn Marino else if (strncmp (symbol, "__modctor_", 10) == 0)
159cf7f2e2dSJohn Marino symbol += 10;
160cf7f2e2dSJohn Marino else if (strncmp (symbol, "__moddtor_", 10) == 0)
161cf7f2e2dSJohn Marino symbol += 10;
162cf7f2e2dSJohn Marino else if (strncmp (symbol, "__ModuleInfo_", 13) == 0)
163cf7f2e2dSJohn Marino symbol += 13;
164cf7f2e2dSJohn Marino else
165cf7f2e2dSJohn Marino {
166cf7f2e2dSJohn Marino obstack_free (&tempbuf, NULL);
167cf7f2e2dSJohn Marino return NULL;
168cf7f2e2dSJohn Marino }
169cf7f2e2dSJohn Marino
170cf7f2e2dSJohn Marino if (!extract_identifiers (symbol, &tempbuf))
171cf7f2e2dSJohn Marino {
172cf7f2e2dSJohn Marino obstack_free (&tempbuf, NULL);
173cf7f2e2dSJohn Marino return NULL;
174cf7f2e2dSJohn Marino }
175cf7f2e2dSJohn Marino
176cf7f2e2dSJohn Marino obstack_grow_str (&tempbuf, "(");
177cf7f2e2dSJohn Marino if (is_func == 1 && *symbol == 'F')
178cf7f2e2dSJohn Marino {
179cf7f2e2dSJohn Marino symbol++;
180cf7f2e2dSJohn Marino while (*symbol != '\0' && *symbol != 'Z')
181cf7f2e2dSJohn Marino {
182cf7f2e2dSJohn Marino if (is_func == 1)
183cf7f2e2dSJohn Marino is_func++;
184cf7f2e2dSJohn Marino else
185cf7f2e2dSJohn Marino obstack_grow_str (&tempbuf, ", ");
186cf7f2e2dSJohn Marino if (!extract_type_info (symbol, &tempbuf))
187cf7f2e2dSJohn Marino {
188cf7f2e2dSJohn Marino obstack_free (&tempbuf, NULL);
189cf7f2e2dSJohn Marino return NULL;
190cf7f2e2dSJohn Marino }
191cf7f2e2dSJohn Marino }
192cf7f2e2dSJohn Marino }
193cf7f2e2dSJohn Marino obstack_grow_str0 (&tempbuf, ")");
194cf7f2e2dSJohn Marino
195cf7f2e2dSJohn Marino /* Doesn't display the return type, but wouldn't be too hard to do. */
196cf7f2e2dSJohn Marino
197cf7f2e2dSJohn Marino out_str = xstrdup (obstack_finish (&tempbuf));
198cf7f2e2dSJohn Marino obstack_free (&tempbuf, NULL);
199cf7f2e2dSJohn Marino return out_str;
200cf7f2e2dSJohn Marino }
201cf7f2e2dSJohn Marino
202cf7f2e2dSJohn Marino /* Table mapping opcodes into strings for printing operators
203cf7f2e2dSJohn Marino and precedences of the operators. */
204cf7f2e2dSJohn Marino static const struct op_print d_op_print_tab[] =
205cf7f2e2dSJohn Marino {
206cf7f2e2dSJohn Marino {",", BINOP_COMMA, PREC_COMMA, 0},
207cf7f2e2dSJohn Marino {"=", BINOP_ASSIGN, PREC_ASSIGN, 1},
208cf7f2e2dSJohn Marino {"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
209cf7f2e2dSJohn Marino {"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
210cf7f2e2dSJohn Marino {"|", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
211cf7f2e2dSJohn Marino {"^", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
212cf7f2e2dSJohn Marino {"&", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
213cf7f2e2dSJohn Marino {"==", BINOP_EQUAL, PREC_EQUAL, 0},
214cf7f2e2dSJohn Marino {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
215cf7f2e2dSJohn Marino {"<=", BINOP_LEQ, PREC_ORDER, 0},
216cf7f2e2dSJohn Marino {">=", BINOP_GEQ, PREC_ORDER, 0},
217cf7f2e2dSJohn Marino {">", BINOP_GTR, PREC_ORDER, 0},
218cf7f2e2dSJohn Marino {"<", BINOP_LESS, PREC_ORDER, 0},
219cf7f2e2dSJohn Marino {">>", BINOP_RSH, PREC_SHIFT, 0},
220cf7f2e2dSJohn Marino {"<<", BINOP_LSH, PREC_SHIFT, 0},
221cf7f2e2dSJohn Marino {"+", BINOP_ADD, PREC_ADD, 0},
222cf7f2e2dSJohn Marino {"-", BINOP_SUB, PREC_ADD, 0},
223cf7f2e2dSJohn Marino {"*", BINOP_MUL, PREC_MUL, 0},
224cf7f2e2dSJohn Marino {"/", BINOP_DIV, PREC_MUL, 0},
225cf7f2e2dSJohn Marino {"%", BINOP_REM, PREC_MUL, 0},
226cf7f2e2dSJohn Marino {"@", BINOP_REPEAT, PREC_REPEAT, 0},
227cf7f2e2dSJohn Marino {"-", UNOP_NEG, PREC_PREFIX, 0},
228cf7f2e2dSJohn Marino {"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
229cf7f2e2dSJohn Marino {"~", UNOP_COMPLEMENT, PREC_PREFIX, 0},
230cf7f2e2dSJohn Marino {"*", UNOP_IND, PREC_PREFIX, 0},
231cf7f2e2dSJohn Marino {"&", UNOP_ADDR, PREC_PREFIX, 0},
232cf7f2e2dSJohn Marino {"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0},
233cf7f2e2dSJohn Marino {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
234cf7f2e2dSJohn Marino {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
235cf7f2e2dSJohn Marino {NULL, 0, 0, 0}
236cf7f2e2dSJohn Marino };
237cf7f2e2dSJohn Marino
238cf7f2e2dSJohn Marino static const struct language_defn d_language_defn =
239cf7f2e2dSJohn Marino {
240cf7f2e2dSJohn Marino "d",
241cf7f2e2dSJohn Marino language_d,
242cf7f2e2dSJohn Marino range_check_off,
243cf7f2e2dSJohn Marino case_sensitive_on,
244cf7f2e2dSJohn Marino array_row_major,
245cf7f2e2dSJohn Marino macro_expansion_c,
246cf7f2e2dSJohn Marino &exp_descriptor_c,
247cf7f2e2dSJohn Marino c_parse,
248cf7f2e2dSJohn Marino c_error,
249cf7f2e2dSJohn Marino null_post_parser,
250cf7f2e2dSJohn Marino c_printchar, /* Print a character constant. */
251cf7f2e2dSJohn Marino c_printstr, /* Function to print string constant. */
252cf7f2e2dSJohn Marino c_emit_char, /* Print a single char. */
253cf7f2e2dSJohn Marino c_print_type, /* Print a type using appropriate syntax. */
254c50c785cSJohn Marino c_print_typedef, /* Print a typedef using appropriate
255c50c785cSJohn Marino syntax. */
256cf7f2e2dSJohn Marino d_val_print, /* Print a value using appropriate syntax. */
257cf7f2e2dSJohn Marino c_value_print, /* Print a top-level value. */
258*ef5ccd6cSJohn Marino default_read_var_value, /* la_read_var_value */
259cf7f2e2dSJohn Marino NULL, /* Language specific skip_trampoline. */
260cf7f2e2dSJohn Marino "this",
261cf7f2e2dSJohn Marino basic_lookup_symbol_nonlocal,
262cf7f2e2dSJohn Marino basic_lookup_transparent_type,
263cf7f2e2dSJohn Marino d_demangle, /* Language specific symbol demangler. */
264c50c785cSJohn Marino NULL, /* Language specific
265c50c785cSJohn Marino class_name_from_physname. */
266cf7f2e2dSJohn Marino d_op_print_tab, /* Expression operators for printing. */
267cf7f2e2dSJohn Marino 1, /* C-style arrays. */
268cf7f2e2dSJohn Marino 0, /* String lower bound. */
269cf7f2e2dSJohn Marino default_word_break_characters,
270cf7f2e2dSJohn Marino default_make_symbol_completion_list,
271cf7f2e2dSJohn Marino c_language_arch_info,
272cf7f2e2dSJohn Marino default_print_array_index,
273cf7f2e2dSJohn Marino default_pass_by_reference,
274cf7f2e2dSJohn Marino c_get_string,
275*ef5ccd6cSJohn Marino NULL, /* la_get_symbol_name_cmp */
276*ef5ccd6cSJohn Marino iterate_over_symbols,
277cf7f2e2dSJohn Marino LANG_MAGIC
278cf7f2e2dSJohn Marino };
279cf7f2e2dSJohn Marino
280*ef5ccd6cSJohn Marino /* Provide a prototype to silence -Wmissing-prototypes. */
281*ef5ccd6cSJohn Marino extern initialize_file_ftype _initialize_d_language;
282*ef5ccd6cSJohn Marino
283cf7f2e2dSJohn Marino void
_initialize_d_language(void)284cf7f2e2dSJohn Marino _initialize_d_language (void)
285cf7f2e2dSJohn Marino {
286cf7f2e2dSJohn Marino add_language (&d_language_defn);
287cf7f2e2dSJohn Marino }
288