1 /* D language support routines for GDB, the GNU debugger.
3 Copyright (C) 2005-2006, 2008-2012 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
25 #include "gdb_string.h"
26 #include "parser-defs.h"
27 #include "gdb_obstack.h"
31 /* Extract identifiers from MANGLED_STR and append it to TEMPBUF.
32 Return 1 on success or 0 on failure. */
34 extract_identifiers (const char *mangled_str
, struct obstack
*tempbuf
)
38 while (isdigit (*mangled_str
))
42 i
= strtol (mangled_str
, &end_ptr
, 10);
43 mangled_str
= end_ptr
;
44 if (i
<= 0 || strlen (mangled_str
) < i
)
46 obstack_grow (tempbuf
, mangled_str
, i
);
48 obstack_grow_str (tempbuf
, ".");
50 if (*mangled_str
== '\0' || i
== 0)
52 obstack_blank (tempbuf
, -1);
56 /* Extract and demangle type from MANGLED_STR and append it to TEMPBUF.
57 Return 1 on success or 0 on failure. */
59 extract_type_info (const char *mangled_str
, struct obstack
*tempbuf
)
61 if (*mangled_str
== '\0')
63 switch (*mangled_str
++)
65 case 'A': /* dynamic array */
66 case 'G': /* static array */
67 case 'H': /* associative array */
68 if (!extract_type_info (mangled_str
, tempbuf
))
70 obstack_grow_str (tempbuf
, "[]");
72 case 'P': /* pointer */
73 if (!extract_type_info (mangled_str
, tempbuf
))
75 obstack_grow_str (tempbuf
, "*");
77 case 'R': /* reference */
78 if (!extract_type_info (mangled_str
, tempbuf
))
80 obstack_grow_str (tempbuf
, "&");
82 case 'Z': /* return value */
83 return extract_type_info (mangled_str
, tempbuf
);
85 obstack_grow_str (tempbuf
, "out ");
86 return extract_type_info (mangled_str
, tempbuf
);
88 obstack_grow_str (tempbuf
, "inout ");
89 return extract_type_info (mangled_str
, tempbuf
);
91 case 'T': /* typedef */
92 case 'D': /* delegate */
94 case 'S': /* struct */
95 return extract_identifiers (mangled_str
, tempbuf
);
98 case 'n': obstack_grow_str (tempbuf
, "none"); return 1;
99 case 'v': obstack_grow_str (tempbuf
, "void"); return 1;
100 case 'g': obstack_grow_str (tempbuf
, "byte"); return 1;
101 case 'h': obstack_grow_str (tempbuf
, "ubyte"); return 1;
102 case 's': obstack_grow_str (tempbuf
, "short"); return 1;
103 case 't': obstack_grow_str (tempbuf
, "ushort"); return 1;
104 case 'i': obstack_grow_str (tempbuf
, "int"); return 1;
105 case 'k': obstack_grow_str (tempbuf
, "uint"); return 1;
106 case 'l': obstack_grow_str (tempbuf
, "long"); return 1;
107 case 'm': obstack_grow_str (tempbuf
, "ulong"); return 1;
108 case 'f': obstack_grow_str (tempbuf
, "float"); return 1;
109 case 'd': obstack_grow_str (tempbuf
, "double"); return 1;
110 case 'e': obstack_grow_str (tempbuf
, "real"); return 1;
112 /* imaginary and complex: */
113 case 'o': obstack_grow_str (tempbuf
, "ifloat"); return 1;
114 case 'p': obstack_grow_str (tempbuf
, "idouble"); return 1;
115 case 'j': obstack_grow_str (tempbuf
, "ireal"); return 1;
116 case 'q': obstack_grow_str (tempbuf
, "cfloat"); return 1;
117 case 'r': obstack_grow_str (tempbuf
, "cdouble"); return 1;
118 case 'c': obstack_grow_str (tempbuf
, "creal"); return 1;
121 case 'b': obstack_grow_str (tempbuf
, "bit"); return 1;
122 case 'a': obstack_grow_str (tempbuf
, "char"); return 1;
123 case 'u': obstack_grow_str (tempbuf
, "wchar"); return 1;
124 case 'w': obstack_grow_str (tempbuf
, "dchar"); return 1;
127 obstack_grow_str (tempbuf
, "unknown");
132 /* Implements the la_demangle language_defn routine for language D. */
134 d_demangle (const char *symbol
, int options
)
136 struct obstack tempbuf
;
138 unsigned char is_func
= 0;
142 else if (strcmp (symbol
, "_Dmain") == 0)
143 return xstrdup ("D main");
145 obstack_init (&tempbuf
);
147 if (symbol
[0] == '_' && symbol
[1] == 'D')
152 else if (strncmp (symbol
, "__Class_", 8) == 0)
154 else if (strncmp (symbol
, "__init_", 7) == 0)
156 else if (strncmp (symbol
, "__vtbl_", 7) == 0)
158 else if (strncmp (symbol
, "__modctor_", 10) == 0)
160 else if (strncmp (symbol
, "__moddtor_", 10) == 0)
162 else if (strncmp (symbol
, "__ModuleInfo_", 13) == 0)
166 obstack_free (&tempbuf
, NULL
);
170 if (!extract_identifiers (symbol
, &tempbuf
))
172 obstack_free (&tempbuf
, NULL
);
176 obstack_grow_str (&tempbuf
, "(");
177 if (is_func
== 1 && *symbol
== 'F')
180 while (*symbol
!= '\0' && *symbol
!= 'Z')
185 obstack_grow_str (&tempbuf
, ", ");
186 if (!extract_type_info (symbol
, &tempbuf
))
188 obstack_free (&tempbuf
, NULL
);
193 obstack_grow_str0 (&tempbuf
, ")");
195 /* Doesn't display the return type, but wouldn't be too hard to do. */
197 out_str
= xstrdup (obstack_finish (&tempbuf
));
198 obstack_free (&tempbuf
, NULL
);
202 /* Table mapping opcodes into strings for printing operators
203 and precedences of the operators. */
204 static const struct op_print d_op_print_tab
[] =
206 {",", BINOP_COMMA
, PREC_COMMA
, 0},
207 {"=", BINOP_ASSIGN
, PREC_ASSIGN
, 1},
208 {"||", BINOP_LOGICAL_OR
, PREC_LOGICAL_OR
, 0},
209 {"&&", BINOP_LOGICAL_AND
, PREC_LOGICAL_AND
, 0},
210 {"|", BINOP_BITWISE_IOR
, PREC_BITWISE_IOR
, 0},
211 {"^", BINOP_BITWISE_XOR
, PREC_BITWISE_XOR
, 0},
212 {"&", BINOP_BITWISE_AND
, PREC_BITWISE_AND
, 0},
213 {"==", BINOP_EQUAL
, PREC_EQUAL
, 0},
214 {"!=", BINOP_NOTEQUAL
, PREC_EQUAL
, 0},
215 {"<=", BINOP_LEQ
, PREC_ORDER
, 0},
216 {">=", BINOP_GEQ
, PREC_ORDER
, 0},
217 {">", BINOP_GTR
, PREC_ORDER
, 0},
218 {"<", BINOP_LESS
, PREC_ORDER
, 0},
219 {">>", BINOP_RSH
, PREC_SHIFT
, 0},
220 {"<<", BINOP_LSH
, PREC_SHIFT
, 0},
221 {"+", BINOP_ADD
, PREC_ADD
, 0},
222 {"-", BINOP_SUB
, PREC_ADD
, 0},
223 {"*", BINOP_MUL
, PREC_MUL
, 0},
224 {"/", BINOP_DIV
, PREC_MUL
, 0},
225 {"%", BINOP_REM
, PREC_MUL
, 0},
226 {"@", BINOP_REPEAT
, PREC_REPEAT
, 0},
227 {"-", UNOP_NEG
, PREC_PREFIX
, 0},
228 {"!", UNOP_LOGICAL_NOT
, PREC_PREFIX
, 0},
229 {"~", UNOP_COMPLEMENT
, PREC_PREFIX
, 0},
230 {"*", UNOP_IND
, PREC_PREFIX
, 0},
231 {"&", UNOP_ADDR
, PREC_PREFIX
, 0},
232 {"sizeof ", UNOP_SIZEOF
, PREC_PREFIX
, 0},
233 {"++", UNOP_PREINCREMENT
, PREC_PREFIX
, 0},
234 {"--", UNOP_PREDECREMENT
, PREC_PREFIX
, 0},
238 static const struct language_defn d_language_defn
=
251 c_printchar
, /* Print a character constant. */
252 c_printstr
, /* Function to print string constant. */
253 c_emit_char
, /* Print a single char. */
254 c_print_type
, /* Print a type using appropriate syntax. */
255 c_print_typedef
, /* Print a typedef using appropriate
257 d_val_print
, /* Print a value using appropriate syntax. */
258 c_value_print
, /* Print a top-level value. */
259 default_read_var_value
, /* la_read_var_value */
260 NULL
, /* Language specific skip_trampoline. */
262 basic_lookup_symbol_nonlocal
,
263 basic_lookup_transparent_type
,
264 d_demangle
, /* Language specific symbol demangler. */
265 NULL
, /* Language specific
266 class_name_from_physname. */
267 d_op_print_tab
, /* Expression operators for printing. */
268 1, /* C-style arrays. */
269 0, /* String lower bound. */
270 default_word_break_characters
,
271 default_make_symbol_completion_list
,
272 c_language_arch_info
,
273 default_print_array_index
,
274 default_pass_by_reference
,
276 NULL
, /* la_get_symbol_name_cmp */
277 iterate_over_symbols
,
281 /* Provide a prototype to silence -Wmissing-prototypes. */
282 extern initialize_file_ftype _initialize_d_language
;
285 _initialize_d_language (void)
287 add_language (&d_language_defn
);