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