GDB (API)
|
00001 /* D language support routines for GDB, the GNU debugger. 00002 00003 Copyright (C) 2005-2013 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00019 00020 #include "defs.h" 00021 #include "symtab.h" 00022 #include "language.h" 00023 #include "d-lang.h" 00024 #include "c-lang.h" 00025 #include "gdb_string.h" 00026 #include "parser-defs.h" 00027 #include "gdb_obstack.h" 00028 00029 #include <ctype.h> 00030 00031 /* Extract identifiers from MANGLED_STR and append it to TEMPBUF. 00032 Return 1 on success or 0 on failure. */ 00033 static int 00034 extract_identifiers (const char *mangled_str, struct obstack *tempbuf) 00035 { 00036 long i = 0; 00037 00038 while (isdigit (*mangled_str)) 00039 { 00040 char *end_ptr; 00041 00042 i = strtol (mangled_str, &end_ptr, 10); 00043 mangled_str = end_ptr; 00044 if (i <= 0 || strlen (mangled_str) < i) 00045 return 0; 00046 obstack_grow (tempbuf, mangled_str, i); 00047 mangled_str += i; 00048 obstack_grow_str (tempbuf, "."); 00049 } 00050 if (*mangled_str == '\0' || i == 0) 00051 return 0; 00052 obstack_blank (tempbuf, -1); 00053 return 1; 00054 } 00055 00056 /* Extract and demangle type from MANGLED_STR and append it to TEMPBUF. 00057 Return 1 on success or 0 on failure. */ 00058 static int 00059 extract_type_info (const char *mangled_str, struct obstack *tempbuf) 00060 { 00061 if (*mangled_str == '\0') 00062 return 0; 00063 switch (*mangled_str++) 00064 { 00065 case 'A': /* dynamic array */ 00066 case 'G': /* static array */ 00067 case 'H': /* associative array */ 00068 if (!extract_type_info (mangled_str, tempbuf)) 00069 return 0; 00070 obstack_grow_str (tempbuf, "[]"); 00071 return 1; 00072 case 'P': /* pointer */ 00073 if (!extract_type_info (mangled_str, tempbuf)) 00074 return 0; 00075 obstack_grow_str (tempbuf, "*"); 00076 return 1; 00077 case 'R': /* reference */ 00078 if (!extract_type_info (mangled_str, tempbuf)) 00079 return 0; 00080 obstack_grow_str (tempbuf, "&"); 00081 return 1; 00082 case 'Z': /* return value */ 00083 return extract_type_info (mangled_str, tempbuf); 00084 case 'J': /* out */ 00085 obstack_grow_str (tempbuf, "out "); 00086 return extract_type_info (mangled_str, tempbuf); 00087 case 'K': /* inout */ 00088 obstack_grow_str (tempbuf, "inout "); 00089 return extract_type_info (mangled_str, tempbuf); 00090 case 'E': /* enum */ 00091 case 'T': /* typedef */ 00092 case 'D': /* delegate */ 00093 case 'C': /* class */ 00094 case 'S': /* struct */ 00095 return extract_identifiers (mangled_str, tempbuf); 00096 00097 /* basic types: */ 00098 case 'n': obstack_grow_str (tempbuf, "none"); return 1; 00099 case 'v': obstack_grow_str (tempbuf, "void"); return 1; 00100 case 'g': obstack_grow_str (tempbuf, "byte"); return 1; 00101 case 'h': obstack_grow_str (tempbuf, "ubyte"); return 1; 00102 case 's': obstack_grow_str (tempbuf, "short"); return 1; 00103 case 't': obstack_grow_str (tempbuf, "ushort"); return 1; 00104 case 'i': obstack_grow_str (tempbuf, "int"); return 1; 00105 case 'k': obstack_grow_str (tempbuf, "uint"); return 1; 00106 case 'l': obstack_grow_str (tempbuf, "long"); return 1; 00107 case 'm': obstack_grow_str (tempbuf, "ulong"); return 1; 00108 case 'f': obstack_grow_str (tempbuf, "float"); return 1; 00109 case 'd': obstack_grow_str (tempbuf, "double"); return 1; 00110 case 'e': obstack_grow_str (tempbuf, "real"); return 1; 00111 00112 /* imaginary and complex: */ 00113 case 'o': obstack_grow_str (tempbuf, "ifloat"); return 1; 00114 case 'p': obstack_grow_str (tempbuf, "idouble"); return 1; 00115 case 'j': obstack_grow_str (tempbuf, "ireal"); return 1; 00116 case 'q': obstack_grow_str (tempbuf, "cfloat"); return 1; 00117 case 'r': obstack_grow_str (tempbuf, "cdouble"); return 1; 00118 case 'c': obstack_grow_str (tempbuf, "creal"); return 1; 00119 00120 /* other types: */ 00121 case 'b': obstack_grow_str (tempbuf, "bit"); return 1; 00122 case 'a': obstack_grow_str (tempbuf, "char"); return 1; 00123 case 'u': obstack_grow_str (tempbuf, "wchar"); return 1; 00124 case 'w': obstack_grow_str (tempbuf, "dchar"); return 1; 00125 00126 default: 00127 obstack_grow_str (tempbuf, "unknown"); 00128 return 1; 00129 } 00130 } 00131 00132 /* Implements the la_demangle language_defn routine for language D. */ 00133 char * 00134 d_demangle (const char *symbol, int options) 00135 { 00136 struct obstack tempbuf; 00137 char *out_str; 00138 unsigned char is_func = 0; 00139 00140 if (symbol == NULL) 00141 return NULL; 00142 else if (strcmp (symbol, "_Dmain") == 0) 00143 return xstrdup ("D main"); 00144 00145 obstack_init (&tempbuf); 00146 00147 if (symbol[0] == '_' && symbol[1] == 'D') 00148 { 00149 symbol += 2; 00150 is_func = 1; 00151 } 00152 else if (strncmp (symbol, "__Class_", 8) == 0) 00153 symbol += 8; 00154 else if (strncmp (symbol, "__init_", 7) == 0) 00155 symbol += 7; 00156 else if (strncmp (symbol, "__vtbl_", 7) == 0) 00157 symbol += 7; 00158 else if (strncmp (symbol, "__modctor_", 10) == 0) 00159 symbol += 10; 00160 else if (strncmp (symbol, "__moddtor_", 10) == 0) 00161 symbol += 10; 00162 else if (strncmp (symbol, "__ModuleInfo_", 13) == 0) 00163 symbol += 13; 00164 else 00165 { 00166 obstack_free (&tempbuf, NULL); 00167 return NULL; 00168 } 00169 00170 if (!extract_identifiers (symbol, &tempbuf)) 00171 { 00172 obstack_free (&tempbuf, NULL); 00173 return NULL; 00174 } 00175 00176 obstack_grow_str (&tempbuf, "("); 00177 if (is_func == 1 && *symbol == 'F') 00178 { 00179 symbol++; 00180 while (*symbol != '\0' && *symbol != 'Z') 00181 { 00182 if (is_func == 1) 00183 is_func++; 00184 else 00185 obstack_grow_str (&tempbuf, ", "); 00186 if (!extract_type_info (symbol, &tempbuf)) 00187 { 00188 obstack_free (&tempbuf, NULL); 00189 return NULL; 00190 } 00191 } 00192 } 00193 obstack_grow_str0 (&tempbuf, ")"); 00194 00195 /* Doesn't display the return type, but wouldn't be too hard to do. */ 00196 00197 out_str = xstrdup (obstack_finish (&tempbuf)); 00198 obstack_free (&tempbuf, NULL); 00199 return out_str; 00200 } 00201 00202 /* Table mapping opcodes into strings for printing operators 00203 and precedences of the operators. */ 00204 static const struct op_print d_op_print_tab[] = 00205 { 00206 {",", BINOP_COMMA, PREC_COMMA, 0}, 00207 {"=", BINOP_ASSIGN, PREC_ASSIGN, 1}, 00208 {"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0}, 00209 {"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0}, 00210 {"|", BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0}, 00211 {"^", BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0}, 00212 {"&", BINOP_BITWISE_AND, PREC_BITWISE_AND, 0}, 00213 {"==", BINOP_EQUAL, PREC_EQUAL, 0}, 00214 {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0}, 00215 {"<=", BINOP_LEQ, PREC_ORDER, 0}, 00216 {">=", BINOP_GEQ, PREC_ORDER, 0}, 00217 {">", BINOP_GTR, PREC_ORDER, 0}, 00218 {"<", BINOP_LESS, PREC_ORDER, 0}, 00219 {">>", BINOP_RSH, PREC_SHIFT, 0}, 00220 {"<<", BINOP_LSH, PREC_SHIFT, 0}, 00221 {"+", BINOP_ADD, PREC_ADD, 0}, 00222 {"-", BINOP_SUB, PREC_ADD, 0}, 00223 {"*", BINOP_MUL, PREC_MUL, 0}, 00224 {"/", BINOP_DIV, PREC_MUL, 0}, 00225 {"%", BINOP_REM, PREC_MUL, 0}, 00226 {"@", BINOP_REPEAT, PREC_REPEAT, 0}, 00227 {"-", UNOP_NEG, PREC_PREFIX, 0}, 00228 {"!", UNOP_LOGICAL_NOT, PREC_PREFIX, 0}, 00229 {"~", UNOP_COMPLEMENT, PREC_PREFIX, 0}, 00230 {"*", UNOP_IND, PREC_PREFIX, 0}, 00231 {"&", UNOP_ADDR, PREC_PREFIX, 0}, 00232 {"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0}, 00233 {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0}, 00234 {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0}, 00235 {NULL, 0, 0, 0} 00236 }; 00237 00238 static const struct language_defn d_language_defn = 00239 { 00240 "d", 00241 language_d, 00242 range_check_off, 00243 case_sensitive_on, 00244 array_row_major, 00245 macro_expansion_c, 00246 &exp_descriptor_c, 00247 c_parse, 00248 c_error, 00249 null_post_parser, 00250 c_printchar, /* Print a character constant. */ 00251 c_printstr, /* Function to print string constant. */ 00252 c_emit_char, /* Print a single char. */ 00253 c_print_type, /* Print a type using appropriate syntax. */ 00254 c_print_typedef, /* Print a typedef using appropriate 00255 syntax. */ 00256 d_val_print, /* Print a value using appropriate syntax. */ 00257 c_value_print, /* Print a top-level value. */ 00258 default_read_var_value, /* la_read_var_value */ 00259 NULL, /* Language specific skip_trampoline. */ 00260 "this", 00261 basic_lookup_symbol_nonlocal, 00262 basic_lookup_transparent_type, 00263 d_demangle, /* Language specific symbol demangler. */ 00264 NULL, /* Language specific 00265 class_name_from_physname. */ 00266 d_op_print_tab, /* Expression operators for printing. */ 00267 1, /* C-style arrays. */ 00268 0, /* String lower bound. */ 00269 default_word_break_characters, 00270 default_make_symbol_completion_list, 00271 c_language_arch_info, 00272 default_print_array_index, 00273 default_pass_by_reference, 00274 c_get_string, 00275 NULL, /* la_get_symbol_name_cmp */ 00276 iterate_over_symbols, 00277 LANG_MAGIC 00278 }; 00279 00280 /* Provide a prototype to silence -Wmissing-prototypes. */ 00281 extern initialize_file_ftype _initialize_d_language; 00282 00283 void 00284 _initialize_d_language (void) 00285 { 00286 add_language (&d_language_defn); 00287 }