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