1 /* D language support routines for GDB, the GNU debugger. 2 3 Copyright (C) 2005-2013 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 "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. */ 33 static int 34 extract_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. */ 58 static int 59 extract_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. */ 133 char * 134 d_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. */ 204 static 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 238 static const struct language_defn d_language_defn = 239 { 240 "d", 241 language_d, 242 range_check_off, 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. */ 254 c_print_typedef, /* Print a typedef using appropriate 255 syntax. */ 256 d_val_print, /* Print a value using appropriate syntax. */ 257 c_value_print, /* Print a top-level value. */ 258 default_read_var_value, /* la_read_var_value */ 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. */ 264 NULL, /* Language specific 265 class_name_from_physname. */ 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, 275 NULL, /* la_get_symbol_name_cmp */ 276 iterate_over_symbols, 277 LANG_MAGIC 278 }; 279 280 /* Provide a prototype to silence -Wmissing-prototypes. */ 281 extern initialize_file_ftype _initialize_d_language; 282 283 void 284 _initialize_d_language (void) 285 { 286 add_language (&d_language_defn); 287 } 288