Upgrade GDB from 7.4.1 to 7.6.1 on the vendor branch
[dragonfly.git] / contrib / gdb-7 / gdb / d-lang.c
CommitLineData
cf7f2e2d
JM
1/* D language support routines for GDB, the GNU debugger.
2
ef5ccd6c 3 Copyright (C) 2005-2013 Free Software Foundation, Inc.
cf7f2e2d
JM
4
5 This file is part of GDB.
6
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.
11
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.
16
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/>. */
19
20#include "defs.h"
21#include "symtab.h"
22#include "language.h"
23#include "d-lang.h"
24#include "c-lang.h"
25#include "gdb_string.h"
26#include "parser-defs.h"
27#include "gdb_obstack.h"
28
29#include <ctype.h>
30
31/* Extract identifiers from MANGLED_STR and append it to TEMPBUF.
32 Return 1 on success or 0 on failure. */
33static int
34extract_identifiers (const char *mangled_str, struct obstack *tempbuf)
35{
36 long i = 0;
37
38 while (isdigit (*mangled_str))
39 {
40 char *end_ptr;
41
42 i = strtol (mangled_str, &end_ptr, 10);
43 mangled_str = end_ptr;
44 if (i <= 0 || strlen (mangled_str) < i)
45 return 0;
46 obstack_grow (tempbuf, mangled_str, i);
47 mangled_str += i;
48 obstack_grow_str (tempbuf, ".");
49 }
50 if (*mangled_str == '\0' || i == 0)
51 return 0;
52 obstack_blank (tempbuf, -1);
53 return 1;
54}
55
56/* Extract and demangle type from MANGLED_STR and append it to TEMPBUF.
57 Return 1 on success or 0 on failure. */
58static int
59extract_type_info (const char *mangled_str, struct obstack *tempbuf)
60{
61 if (*mangled_str == '\0')
62 return 0;
63 switch (*mangled_str++)
64 {
65 case 'A': /* dynamic array */
66 case 'G': /* static array */
67 case 'H': /* associative array */
68 if (!extract_type_info (mangled_str, tempbuf))
69 return 0;
70 obstack_grow_str (tempbuf, "[]");
71 return 1;
72 case 'P': /* pointer */
73 if (!extract_type_info (mangled_str, tempbuf))
74 return 0;
75 obstack_grow_str (tempbuf, "*");
76 return 1;
77 case 'R': /* reference */
78 if (!extract_type_info (mangled_str, tempbuf))
79 return 0;
80 obstack_grow_str (tempbuf, "&");
81 return 1;
82 case 'Z': /* return value */
83 return extract_type_info (mangled_str, tempbuf);
84 case 'J': /* out */
85 obstack_grow_str (tempbuf, "out ");
86 return extract_type_info (mangled_str, tempbuf);
87 case 'K': /* inout */
88 obstack_grow_str (tempbuf, "inout ");
89 return extract_type_info (mangled_str, tempbuf);
90 case 'E': /* enum */
91 case 'T': /* typedef */
92 case 'D': /* delegate */
93 case 'C': /* class */
94 case 'S': /* struct */
95 return extract_identifiers (mangled_str, tempbuf);
96
97 /* basic types: */
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;
111
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;
119
120 /* other types: */
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;
125
126 default:
127 obstack_grow_str (tempbuf, "unknown");
128 return 1;
129 }
130}
131
132/* Implements the la_demangle language_defn routine for language D. */
133char *
134d_demangle (const char *symbol, int options)
135{
136 struct obstack tempbuf;
137 char *out_str;
138 unsigned char is_func = 0;
139
140 if (symbol == NULL)
141 return NULL;
142 else if (strcmp (symbol, "_Dmain") == 0)
143 return xstrdup ("D main");
144
145 obstack_init (&tempbuf);
146
147 if (symbol[0] == '_' && symbol[1] == 'D')
148 {
149 symbol += 2;
150 is_func = 1;
151 }
152 else if (strncmp (symbol, "__Class_", 8) == 0)
153 symbol += 8;
154 else if (strncmp (symbol, "__init_", 7) == 0)
155 symbol += 7;
156 else if (strncmp (symbol, "__vtbl_", 7) == 0)
157 symbol += 7;
158 else if (strncmp (symbol, "__modctor_", 10) == 0)
159 symbol += 10;
160 else if (strncmp (symbol, "__moddtor_", 10) == 0)
161 symbol += 10;
162 else if (strncmp (symbol, "__ModuleInfo_", 13) == 0)
163 symbol += 13;
164 else
165 {
166 obstack_free (&tempbuf, NULL);
167 return NULL;
168 }
169
170 if (!extract_identifiers (symbol, &tempbuf))
171 {
172 obstack_free (&tempbuf, NULL);
173 return NULL;
174 }
175
176 obstack_grow_str (&tempbuf, "(");
177 if (is_func == 1 && *symbol == 'F')
178 {
179 symbol++;
180 while (*symbol != '\0' && *symbol != 'Z')
181 {
182 if (is_func == 1)
183 is_func++;
184 else
185 obstack_grow_str (&tempbuf, ", ");
186 if (!extract_type_info (symbol, &tempbuf))
187 {
188 obstack_free (&tempbuf, NULL);
189 return NULL;
190 }
191 }
192 }
193 obstack_grow_str0 (&tempbuf, ")");
194
195 /* Doesn't display the return type, but wouldn't be too hard to do. */
196
197 out_str = xstrdup (obstack_finish (&tempbuf));
198 obstack_free (&tempbuf, NULL);
199 return out_str;
200}
201
202/* Table mapping opcodes into strings for printing operators
203 and precedences of the operators. */
204static const struct op_print d_op_print_tab[] =
205{
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},
235 {NULL, 0, 0, 0}
236};
237
238static const struct language_defn d_language_defn =
239{
240 "d",
241 language_d,
242 range_check_off,
cf7f2e2d
JM
243 case_sensitive_on,
244 array_row_major,
245 macro_expansion_c,
246 &exp_descriptor_c,
247 c_parse,
248 c_error,
249 null_post_parser,
250 c_printchar, /* Print a character constant. */
251 c_printstr, /* Function to print string constant. */
252 c_emit_char, /* Print a single char. */
253 c_print_type, /* Print a type using appropriate syntax. */
c50c785c
JM
254 c_print_typedef, /* Print a typedef using appropriate
255 syntax. */
cf7f2e2d
JM
256 d_val_print, /* Print a value using appropriate syntax. */
257 c_value_print, /* Print a top-level value. */
ef5ccd6c 258 default_read_var_value, /* la_read_var_value */
cf7f2e2d
JM
259 NULL, /* Language specific skip_trampoline. */
260 "this",
261 basic_lookup_symbol_nonlocal,
262 basic_lookup_transparent_type,
263 d_demangle, /* Language specific symbol demangler. */
c50c785c
JM
264 NULL, /* Language specific
265 class_name_from_physname. */
cf7f2e2d
JM
266 d_op_print_tab, /* Expression operators for printing. */
267 1, /* C-style arrays. */
268 0, /* String lower bound. */
269 default_word_break_characters,
270 default_make_symbol_completion_list,
271 c_language_arch_info,
272 default_print_array_index,
273 default_pass_by_reference,
274 c_get_string,
ef5ccd6c
JM
275 NULL, /* la_get_symbol_name_cmp */
276 iterate_over_symbols,
cf7f2e2d
JM
277 LANG_MAGIC
278};
279
ef5ccd6c
JM
280/* Provide a prototype to silence -Wmissing-prototypes. */
281extern initialize_file_ftype _initialize_d_language;
282
cf7f2e2d
JM
283void
284_initialize_d_language (void)
285{
286 add_language (&d_language_defn);
287}