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