OLD | NEW |
1 /* Parser for linespec for the GNU debugger, GDB. | 1 /* Parser for linespec for the GNU debugger, GDB. |
2 | 2 |
3 Copyright (C) 1986-2005, 2007-2012 Free Software Foundation, Inc. | 3 Copyright (C) 1986-2005, 2007-2012 Free Software Foundation, Inc. |
4 | 4 |
5 This file is part of GDB. | 5 This file is part of GDB. |
6 | 6 |
7 This program is free software; you can redistribute it and/or modify | 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 | 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 | 9 the Free Software Foundation; either version 3 of the License, or |
10 (at your option) any later version. | 10 (at your option) any later version. |
(...skipping 25 matching lines...) Expand all Loading... |
36 #include "exceptions.h" | 36 #include "exceptions.h" |
37 #include "language.h" | 37 #include "language.h" |
38 #include "interps.h" | 38 #include "interps.h" |
39 #include "mi/mi-cmds.h" | 39 #include "mi/mi-cmds.h" |
40 #include "target.h" | 40 #include "target.h" |
41 #include "arch-utils.h" | 41 #include "arch-utils.h" |
42 #include <ctype.h> | 42 #include <ctype.h> |
43 #include "cli/cli-utils.h" | 43 #include "cli/cli-utils.h" |
44 #include "filenames.h" | 44 #include "filenames.h" |
45 #include "ada-lang.h" | 45 #include "ada-lang.h" |
| 46 #include "stack.h" |
46 | 47 |
47 typedef struct symtab *symtab_p; | 48 typedef struct symtab *symtab_p; |
48 DEF_VEC_P (symtab_p); | 49 DEF_VEC_P (symtab_p); |
49 | 50 |
50 typedef struct symbol *symbolp; | 51 typedef struct symbol *symbolp; |
51 DEF_VEC_P (symbolp); | 52 DEF_VEC_P (symbolp); |
52 | 53 |
53 typedef struct type *typep; | 54 typedef struct type *typep; |
54 DEF_VEC_P (typep); | 55 DEF_VEC_P (typep); |
55 | 56 |
56 /* An address entry is used to ensure that any given location is only | 57 /* An address entry is used to ensure that any given location is only |
57 added to the result a single time. It holds an address and the | 58 added to the result a single time. It holds an address and the |
58 program space from which the address came. */ | 59 program space from which the address came. */ |
59 | 60 |
60 struct address_entry | 61 struct address_entry |
61 { | 62 { |
62 struct program_space *pspace; | 63 struct program_space *pspace; |
63 CORE_ADDR addr; | 64 CORE_ADDR addr; |
64 }; | 65 }; |
65 | 66 |
| 67 /* A helper struct which just holds a minimal symbol and the object |
| 68 file from which it came. */ |
| 69 |
| 70 typedef struct minsym_and_objfile |
| 71 { |
| 72 struct minimal_symbol *minsym; |
| 73 struct objfile *objfile; |
| 74 } minsym_and_objfile_d; |
| 75 |
| 76 DEF_VEC_O (minsym_and_objfile_d); |
| 77 |
| 78 /* An enumeration of possible signs for a line offset. */ |
| 79 enum offset_relative_sign |
| 80 { |
| 81 /* No sign */ |
| 82 LINE_OFFSET_NONE, |
| 83 |
| 84 /* A plus sign ("+") */ |
| 85 LINE_OFFSET_PLUS, |
| 86 |
| 87 /* A minus sign ("-") */ |
| 88 LINE_OFFSET_MINUS, |
| 89 |
| 90 /* A special "sign" for unspecified offset. */ |
| 91 LINE_OFFSET_UNKNOWN |
| 92 }; |
| 93 |
| 94 /* A line offset in a linespec. */ |
| 95 |
| 96 struct line_offset |
| 97 { |
| 98 /* Line offset and any specified sign. */ |
| 99 int offset; |
| 100 enum offset_relative_sign sign; |
| 101 }; |
| 102 |
| 103 /* A linespec. Elements of this structure are filled in by a parser |
| 104 (either parse_linespec or some other function). The structure is |
| 105 then converted into SALs by convert_linespec_to_sals. */ |
| 106 |
| 107 struct linespec |
| 108 { |
| 109 /* An expression and the resulting PC. Specifying an expression |
| 110 currently precludes the use of other members. */ |
| 111 |
| 112 /* The expression entered by the user. */ |
| 113 char *expression; |
| 114 |
| 115 /* The resulting PC expression derived from evaluating EXPRESSION. */ |
| 116 CORE_ADDR expr_pc; |
| 117 |
| 118 /* Any specified file symtabs. */ |
| 119 |
| 120 /* The user-supplied source filename or NULL if none was specified. */ |
| 121 char *source_filename; |
| 122 |
| 123 /* The list of symtabs to search to which to limit the search. May not |
| 124 be NULL. If SOURCE_FILENAME is NULL (no user-specified filename), |
| 125 FILE_SYMTABS should contain one single NULL member. This will |
| 126 cause the code to use the default symtab. */ |
| 127 VEC (symtab_p) *file_symtabs; |
| 128 |
| 129 /* The name of a function or method and any matching symbols. */ |
| 130 |
| 131 /* The user-specified function name. If no function name was |
| 132 supplied, this may be NULL. */ |
| 133 char *function_name; |
| 134 |
| 135 /* A list of matching function symbols and minimal symbols. Both lists |
| 136 may be NULL if no matching symbols were found. */ |
| 137 VEC (symbolp) *function_symbols; |
| 138 VEC (minsym_and_objfile_d) *minimal_symbols; |
| 139 |
| 140 /* The name of a label and matching symbols. */ |
| 141 |
| 142 /* The user-specified label name. */ |
| 143 char *label_name; |
| 144 |
| 145 /* A structure of matching label symbols and the corresponding |
| 146 function symbol in which the label was found. Both may be NULL |
| 147 or both must be non-NULL. */ |
| 148 struct |
| 149 { |
| 150 VEC (symbolp) *label_symbols; |
| 151 VEC (symbolp) *function_symbols; |
| 152 } labels; |
| 153 |
| 154 /* Line offset. It may be LINE_OFFSET_UNKNOWN, meaning that no |
| 155 offset was specified. */ |
| 156 struct line_offset line_offset; |
| 157 }; |
| 158 typedef struct linespec *linespec_p; |
| 159 |
66 /* An instance of this is used to keep all state while linespec | 160 /* An instance of this is used to keep all state while linespec |
67 operates. This instance is passed around as a 'this' pointer to | 161 operates. This instance is passed around as a 'this' pointer to |
68 the various implementation methods. */ | 162 the various implementation methods. */ |
69 | 163 |
70 struct linespec_state | 164 struct linespec_state |
71 { | 165 { |
| 166 /* The language in use during linespec processing. */ |
| 167 const struct language_defn *language; |
| 168 |
72 /* The program space as seen when the module was entered. */ | 169 /* The program space as seen when the module was entered. */ |
73 struct program_space *program_space; | 170 struct program_space *program_space; |
74 | 171 |
75 /* The default symtab to use, if no other symtab is specified. */ | 172 /* The default symtab to use, if no other symtab is specified. */ |
76 struct symtab *default_symtab; | 173 struct symtab *default_symtab; |
77 | 174 |
78 /* The default line to use. */ | 175 /* The default line to use. */ |
79 int default_line; | 176 int default_line; |
80 | 177 |
81 /* If the linespec started with "FILE:", this holds all the matching | |
82 symtabs. Otherwise, it will hold a single NULL entry, meaning | |
83 that the default symtab should be used. */ | |
84 VEC (symtab_p) *file_symtabs; | |
85 | |
86 /* If the linespec started with "FILE:", this holds an xmalloc'd | |
87 copy of "FILE". */ | |
88 char *user_filename; | |
89 | |
90 /* If the linespec is "FUNCTION:LABEL", this holds an xmalloc'd copy | |
91 of "FUNCTION". */ | |
92 char *user_function; | |
93 | |
94 /* The 'funfirstline' value that was passed in to decode_line_1 or | 178 /* The 'funfirstline' value that was passed in to decode_line_1 or |
95 decode_line_full. */ | 179 decode_line_full. */ |
96 int funfirstline; | 180 int funfirstline; |
97 | 181 |
98 /* Nonzero if we are running in 'list' mode; see decode_line_list. */ | 182 /* Nonzero if we are running in 'list' mode; see decode_line_list. */ |
99 int list_mode; | 183 int list_mode; |
100 | 184 |
101 /* The 'canonical' value passed to decode_line_full, or NULL. */ | 185 /* The 'canonical' value passed to decode_line_full, or NULL. */ |
102 struct linespec_result *canonical; | 186 struct linespec_result *canonical; |
103 | 187 |
104 /* Canonical strings that mirror the symtabs_and_lines result. */ | 188 /* Canonical strings that mirror the symtabs_and_lines result. */ |
105 char **canonical_names; | 189 char **canonical_names; |
106 | 190 |
107 /* This is a set of address_entry objects which is used to prevent | 191 /* This is a set of address_entry objects which is used to prevent |
108 duplicate symbols from being entered into the result. */ | 192 duplicate symbols from being entered into the result. */ |
109 htab_t addr_set; | 193 htab_t addr_set; |
110 }; | 194 }; |
111 | 195 |
112 /* This is a helper object that is used when collecting symbols into a | 196 /* This is a helper object that is used when collecting symbols into a |
113 result. */ | 197 result. */ |
114 | 198 |
115 struct collect_info | 199 struct collect_info |
116 { | 200 { |
117 /* The linespec object in use. */ | 201 /* The linespec object in use. */ |
118 struct linespec_state *state; | 202 struct linespec_state *state; |
119 | 203 |
| 204 /* A list of symtabs to which to restrict matches. */ |
| 205 VEC (symtab_p) *file_symtabs; |
| 206 |
120 /* The result being accumulated. */ | 207 /* The result being accumulated. */ |
121 struct symtabs_and_lines result; | 208 struct |
| 209 { |
| 210 VEC (symbolp) *symbols; |
| 211 VEC (minsym_and_objfile_d) *minimal_symbols; |
| 212 } result; |
122 }; | 213 }; |
123 | 214 |
| 215 /* Token types */ |
| 216 |
| 217 enum ls_token_type |
| 218 { |
| 219 /* A keyword */ |
| 220 LSTOKEN_KEYWORD = 0, |
| 221 |
| 222 /* A colon "separator" */ |
| 223 LSTOKEN_COLON, |
| 224 |
| 225 /* A string */ |
| 226 LSTOKEN_STRING, |
| 227 |
| 228 /* A number */ |
| 229 LSTOKEN_NUMBER, |
| 230 |
| 231 /* A comma */ |
| 232 LSTOKEN_COMMA, |
| 233 |
| 234 /* EOI (end of input) */ |
| 235 LSTOKEN_EOI, |
| 236 |
| 237 /* Consumed token */ |
| 238 LSTOKEN_CONSUMED |
| 239 }; |
| 240 typedef enum ls_token_type linespec_token_type; |
| 241 |
| 242 /* List of keywords */ |
| 243 |
| 244 static const char * const linespec_keywords[] = { "if", "thread", "task" }; |
| 245 |
| 246 /* A token of the linespec lexer */ |
| 247 |
| 248 struct ls_token |
| 249 { |
| 250 /* The type of the token */ |
| 251 linespec_token_type type; |
| 252 |
| 253 /* Data for the token */ |
| 254 union |
| 255 { |
| 256 /* A string, given as a stoken */ |
| 257 struct stoken string; |
| 258 |
| 259 /* A keyword */ |
| 260 const char *keyword; |
| 261 } data; |
| 262 }; |
| 263 typedef struct ls_token linespec_token; |
| 264 |
| 265 #define LS_TOKEN_STOKEN(TOK) (TOK).data.string |
| 266 #define LS_TOKEN_KEYWORD(TOK) (TOK).data.keyword |
| 267 |
| 268 /* An instance of the linespec parser. */ |
| 269 |
| 270 struct ls_parser |
| 271 { |
| 272 /* Lexer internal data */ |
| 273 struct |
| 274 { |
| 275 /* Save head of input stream. */ |
| 276 char *saved_arg; |
| 277 |
| 278 /* Head of the input stream. */ |
| 279 char **stream; |
| 280 #define PARSER_STREAM(P) (*(P)->lexer.stream) |
| 281 |
| 282 /* The current token. */ |
| 283 linespec_token current; |
| 284 } lexer; |
| 285 |
| 286 /* Is the entire linespec quote-enclosed? */ |
| 287 int is_quote_enclosed; |
| 288 |
| 289 /* Is a keyword syntactically valid at this point? |
| 290 In, e.g., "break thread thread 1", the leading "keyword" must not |
| 291 be interpreted as such. */ |
| 292 int keyword_ok; |
| 293 |
| 294 /* The state of the parse. */ |
| 295 struct linespec_state state; |
| 296 #define PARSER_STATE(PPTR) (&(PPTR)->state) |
| 297 |
| 298 /* The result of the parse. */ |
| 299 struct linespec result; |
| 300 #define PARSER_RESULT(PPTR) (&(PPTR)->result) |
| 301 }; |
| 302 typedef struct ls_parser linespec_parser; |
| 303 |
124 /* Prototypes for local functions. */ | 304 /* Prototypes for local functions. */ |
125 | 305 |
126 static void initialize_defaults (struct symtab **default_symtab, | 306 static void initialize_defaults (struct symtab **default_symtab, |
127 int *default_line); | 307 int *default_line); |
128 | 308 |
129 static struct symtabs_and_lines decode_indirect (struct linespec_state *self, | 309 static CORE_ADDR linespec_expression_to_pc (char **exp_ptr); |
130 » » » » » » char **argptr); | |
131 | |
132 static char *locate_first_half (char **argptr, int *is_quote_enclosed); | |
133 | 310 |
134 static struct symtabs_and_lines decode_objc (struct linespec_state *self, | 311 static struct symtabs_and_lines decode_objc (struct linespec_state *self, |
| 312 linespec_p ls, |
135 char **argptr); | 313 char **argptr); |
136 | 314 |
137 static struct symtabs_and_lines decode_compound (struct linespec_state *self, | 315 static VEC (symtab_p) *symtabs_from_filename (const char *); |
138 » » » » » » char **argptr, | |
139 » » » » » » char *saved_arg, | |
140 » » » » » » char *p); | |
141 | 316 |
142 static VEC (symbolp) *lookup_prefix_sym (char **argptr, char *p, | 317 static VEC (symbolp) *find_label_symbols (struct linespec_state *self, |
143 » » » » » VEC (symtab_p) *, | 318 » » » » » VEC (symbolp) *function_symbols, |
144 » » » » » char **); | 319 » » » » » VEC (symbolp) **label_funcs_ret, |
| 320 » » » » » const char *name); |
145 | 321 |
146 static struct symtabs_and_lines find_method (struct linespec_state *self, | 322 void find_linespec_symbols (struct linespec_state *self, |
147 » » » » » char *saved_arg, | 323 » » » VEC (symtab_p) *file_symtabs, |
148 » » » » » char *copy, | 324 » » » const char *name, |
149 » » » » » const char *class_name, | 325 » » » VEC (symbolp) **symbols, |
150 » » » » » VEC (symbolp) *sym_classes); | 326 » » » VEC (minsym_and_objfile_d) **minsyms); |
151 | 327 |
152 static void cplusplus_error (const char *name, const char *fmt, ...) | 328 static struct line_offset |
153 ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF (2, 3); | 329 linespec_parse_variable (struct linespec_state *self, |
154 | 330 » » » const char *variable); |
155 static char *find_toplevel_char (char *s, char c); | |
156 | |
157 static int is_objc_method_format (const char *s); | |
158 | |
159 static VEC (symtab_p) *symtabs_from_filename (char **argptr, | |
160 » » » » » char *p, int is_quote_enclosed, | |
161 » » » » » char **user_filename); | |
162 | |
163 static VEC (symbolp) *find_function_symbols (char **argptr, char *p, | |
164 » » » » » int is_quote_enclosed, | |
165 » » » » » char **user_function); | |
166 | |
167 static struct symtabs_and_lines decode_all_digits (struct linespec_state *self, | |
168 » » » » » » char **argptr, | |
169 » » » » » » char *q); | |
170 | |
171 static struct symtabs_and_lines decode_dollar (struct linespec_state *self, | |
172 » » » » » char *copy); | |
173 | |
174 static int decode_label (struct linespec_state *self, | |
175 » » » VEC (symbolp) *function_symbols, | |
176 » » » char *copy, | |
177 » » » struct symtabs_and_lines *result); | |
178 | |
179 static struct symtabs_and_lines decode_variable (struct linespec_state *self, | |
180 » » » » » » char *copy); | |
181 | 331 |
182 static int symbol_to_sal (struct symtab_and_line *result, | 332 static int symbol_to_sal (struct symtab_and_line *result, |
183 int funfirstline, struct symbol *sym); | 333 int funfirstline, struct symbol *sym); |
184 | 334 |
185 static void add_matching_symbols_to_info (const char *name, | 335 static void add_matching_symbols_to_info (const char *name, |
186 struct collect_info *info, | 336 struct collect_info *info, |
187 struct program_space *pspace); | 337 struct program_space *pspace); |
188 | 338 |
189 static void add_all_symbol_names_from_pspace (struct collect_info *info, | 339 static void add_all_symbol_names_from_pspace (struct collect_info *info, |
190 struct program_space *pspace, | 340 struct program_space *pspace, |
191 VEC (const_char_ptr) *names); | 341 VEC (const_char_ptr) *names); |
192 | 342 |
| 343 static VEC (symtab_p) *collect_symtabs_from_filename (const char *file); |
| 344 |
| 345 static void decode_digits_ordinary (struct linespec_state *self, |
| 346 linespec_p ls, |
| 347 int line, |
| 348 struct symtabs_and_lines *sals, |
| 349 struct linetable_entry **best_entry); |
| 350 |
| 351 static void decode_digits_list_mode (struct linespec_state *self, |
| 352 linespec_p ls, |
| 353 struct symtabs_and_lines *values, |
| 354 struct symtab_and_line val); |
| 355 |
| 356 static void minsym_found (struct linespec_state *self, struct objfile *objfile, |
| 357 struct minimal_symbol *msymbol, |
| 358 struct symtabs_and_lines *result); |
| 359 |
| 360 static int compare_symbols (const void *a, const void *b); |
| 361 |
| 362 static int compare_msymbols (const void *a, const void *b); |
| 363 |
| 364 static const char *find_toplevel_char (const char *s, char c); |
| 365 |
| 366 /* Permitted quote characters for the parser. This is different from the |
| 367 completer's quote characters to allow backward compatibility with the |
| 368 previous parser. */ |
| 369 static const char *const linespec_quote_characters = "\"\'"; |
| 370 |
| 371 /* Lexer functions. */ |
| 372 |
| 373 /* Lex a number from the input in PARSER. This only supports |
| 374 decimal numbers. |
| 375 |
| 376 Return true if input is decimal numbers. Return false if not. */ |
| 377 |
| 378 static int |
| 379 linespec_lexer_lex_number (linespec_parser *parser, linespec_token *tokenp) |
| 380 { |
| 381 tokenp->type = LSTOKEN_NUMBER; |
| 382 LS_TOKEN_STOKEN (*tokenp).length = 0; |
| 383 LS_TOKEN_STOKEN (*tokenp).ptr = PARSER_STREAM (parser); |
| 384 |
| 385 /* Keep any sign at the start of the stream. */ |
| 386 if (*PARSER_STREAM (parser) == '+' || *PARSER_STREAM (parser) == '-') |
| 387 { |
| 388 ++LS_TOKEN_STOKEN (*tokenp).length; |
| 389 ++(PARSER_STREAM (parser)); |
| 390 } |
| 391 |
| 392 while (isdigit (*PARSER_STREAM (parser))) |
| 393 { |
| 394 ++LS_TOKEN_STOKEN (*tokenp).length; |
| 395 ++(PARSER_STREAM (parser)); |
| 396 } |
| 397 |
| 398 /* If the next character in the input buffer is not a space, comma, |
| 399 quote, or colon, the input does not represent a number. */ |
| 400 if (*PARSER_STREAM (parser) != '\0' |
| 401 && !isspace (*PARSER_STREAM (parser)) && *PARSER_STREAM (parser) != ',' |
| 402 && *PARSER_STREAM (parser) != ':' |
| 403 && !strchr (linespec_quote_characters, *PARSER_STREAM (parser))) |
| 404 { |
| 405 PARSER_STREAM (parser) = LS_TOKEN_STOKEN (*tokenp).ptr; |
| 406 return 0; |
| 407 } |
| 408 |
| 409 return 1; |
| 410 } |
| 411 |
| 412 /* Does P represent one of the keywords? If so, return |
| 413 the keyword. If not, return NULL. */ |
| 414 |
| 415 static const char * |
| 416 linespec_lexer_lex_keyword (const char *p) |
| 417 { |
| 418 int i; |
| 419 |
| 420 if (p != NULL) |
| 421 { |
| 422 for (i = 0; i < ARRAY_SIZE (linespec_keywords); ++i) |
| 423 { |
| 424 int len = strlen (linespec_keywords[i]); |
| 425 |
| 426 /* If P begins with one of the keywords and the next |
| 427 character is not a valid identifier character, |
| 428 we have found a keyword. */ |
| 429 if (strncmp (p, linespec_keywords[i], len) == 0 |
| 430 && !(isalnum (p[len]) || p[len] == '_')) |
| 431 return linespec_keywords[i]; |
| 432 } |
| 433 } |
| 434 |
| 435 return NULL; |
| 436 } |
| 437 |
| 438 /* Does STRING represent an Ada operator? If so, return the length |
| 439 of the decoded operator name. If not, return 0. */ |
| 440 |
| 441 static int |
| 442 is_ada_operator (const char *string) |
| 443 { |
| 444 const struct ada_opname_map *mapping; |
| 445 |
| 446 for (mapping = ada_opname_table; |
| 447 mapping->encoded != NULL |
| 448 && strncmp (mapping->decoded, string, |
| 449 strlen (mapping->decoded)) != 0; ++mapping) |
| 450 ; |
| 451 |
| 452 return mapping->decoded == NULL ? 0 : strlen (mapping->decoded); |
| 453 } |
| 454 |
| 455 /* Find QUOTE_CHAR in STRING, accounting for the ':' terminal. Return |
| 456 the location of QUOTE_CHAR, or NULL if not found. */ |
| 457 |
| 458 static const char * |
| 459 skip_quote_char (const char *string, char quote_char) |
| 460 { |
| 461 const char *p, *last; |
| 462 |
| 463 p = last = find_toplevel_char (string, quote_char); |
| 464 while (p && *p != '\0' && *p != ':') |
| 465 { |
| 466 p = find_toplevel_char (p, quote_char); |
| 467 if (p != NULL) |
| 468 last = p++; |
| 469 } |
| 470 |
| 471 return last; |
| 472 } |
| 473 |
| 474 /* Make a writable copy of the string given in TOKEN, trimming |
| 475 any trailing whitespace. */ |
| 476 |
| 477 static char * |
| 478 copy_token_string (linespec_token token) |
| 479 { |
| 480 char *str, *s; |
| 481 |
| 482 if (token.type == LSTOKEN_KEYWORD) |
| 483 return xstrdup (LS_TOKEN_KEYWORD (token)); |
| 484 |
| 485 str = savestring (LS_TOKEN_STOKEN (token).ptr, |
| 486 LS_TOKEN_STOKEN (token).length); |
| 487 s = remove_trailing_whitespace (str, str + LS_TOKEN_STOKEN (token).length); |
| 488 *s = '\0'; |
| 489 |
| 490 return str; |
| 491 } |
| 492 |
| 493 /* Does P represent the end of a quote-enclosed linespec? */ |
| 494 |
| 495 static int |
| 496 is_closing_quote_enclosed (const char *p) |
| 497 { |
| 498 if (strchr (linespec_quote_characters, *p)) |
| 499 ++p; |
| 500 p = skip_spaces ((char *) p); |
| 501 return (*p == '\0' || linespec_lexer_lex_keyword (p)); |
| 502 } |
| 503 |
| 504 /* Find the end of the parameter list that starts with *INPUT. |
| 505 This helper function assists with lexing string segments |
| 506 which might contain valid (non-terminating) commas. */ |
| 507 |
| 508 static char * |
| 509 find_parameter_list_end (char *input) |
| 510 { |
| 511 char end_char, start_char; |
| 512 int depth; |
| 513 char *p; |
| 514 |
| 515 start_char = *input; |
| 516 if (start_char == '(') |
| 517 end_char = ')'; |
| 518 else if (start_char == '<') |
| 519 end_char = '>'; |
| 520 else |
| 521 return NULL; |
| 522 |
| 523 p = input; |
| 524 depth = 0; |
| 525 while (*p) |
| 526 { |
| 527 if (*p == start_char) |
| 528 ++depth; |
| 529 else if (*p == end_char) |
| 530 { |
| 531 if (--depth == 0) |
| 532 { |
| 533 ++p; |
| 534 break; |
| 535 } |
| 536 } |
| 537 ++p; |
| 538 } |
| 539 |
| 540 return p; |
| 541 } |
| 542 |
| 543 |
| 544 /* Lex a string from the input in PARSER. */ |
| 545 |
| 546 static linespec_token |
| 547 linespec_lexer_lex_string (linespec_parser *parser) |
| 548 { |
| 549 linespec_token token; |
| 550 char *start = PARSER_STREAM (parser); |
| 551 |
| 552 token.type = LSTOKEN_STRING; |
| 553 |
| 554 /* If the input stream starts with a quote character, skip to the next |
| 555 quote character, regardless of the content. */ |
| 556 if (strchr (linespec_quote_characters, *PARSER_STREAM (parser))) |
| 557 { |
| 558 const char *end; |
| 559 char quote_char = *PARSER_STREAM (parser); |
| 560 |
| 561 /* Special case: Ada operators. */ |
| 562 if (PARSER_STATE (parser)->language->la_language == language_ada |
| 563 && quote_char == '\"') |
| 564 { |
| 565 int len = is_ada_operator (PARSER_STREAM (parser)); |
| 566 |
| 567 if (len != 0) |
| 568 { |
| 569 /* The input is an Ada operator. Return the quoted string |
| 570 as-is. */ |
| 571 LS_TOKEN_STOKEN (token).ptr = PARSER_STREAM (parser); |
| 572 LS_TOKEN_STOKEN (token).length = len; |
| 573 PARSER_STREAM (parser) += len; |
| 574 return token; |
| 575 } |
| 576 |
| 577 /* The input does not represent an Ada operator -- fall through |
| 578 to normal quoted string handling. */ |
| 579 } |
| 580 |
| 581 /* Skip past the beginning quote. */ |
| 582 ++(PARSER_STREAM (parser)); |
| 583 |
| 584 /* Mark the start of the string. */ |
| 585 LS_TOKEN_STOKEN (token).ptr = PARSER_STREAM (parser); |
| 586 |
| 587 /* Skip to the ending quote. */ |
| 588 end = skip_quote_char (PARSER_STREAM (parser), quote_char); |
| 589 |
| 590 /* Error if the input did not terminate properly. */ |
| 591 if (end == NULL) |
| 592 error (_("unmatched quote")); |
| 593 |
| 594 /* Skip over the ending quote and mark the length of the string. */ |
| 595 PARSER_STREAM (parser) = (char *) ++end; |
| 596 LS_TOKEN_STOKEN (token).length = PARSER_STREAM (parser) - 2 - start; |
| 597 } |
| 598 else |
| 599 { |
| 600 char *p; |
| 601 |
| 602 /* Otherwise, only identifier characters are permitted. |
| 603 Spaces are the exception. In general, we keep spaces, |
| 604 but only if the next characters in the input do not resolve |
| 605 to one of the keywords. |
| 606 |
| 607 This allows users to forgo quoting CV-qualifiers, template arguments, |
| 608 and similar common language constructs. */ |
| 609 |
| 610 while (1) |
| 611 { |
| 612 if (isspace (*PARSER_STREAM (parser))) |
| 613 { |
| 614 p = skip_spaces (PARSER_STREAM (parser)); |
| 615 /* When we get here we know we've found something followed by |
| 616 a space (we skip over parens and templates below). |
| 617 So if we find a keyword now, we know it is a keyword and not, |
| 618 say, a function name. */ |
| 619 if (linespec_lexer_lex_keyword (p) != NULL) |
| 620 { |
| 621 LS_TOKEN_STOKEN (token).ptr = start; |
| 622 LS_TOKEN_STOKEN (token).length |
| 623 = PARSER_STREAM (parser) - start; |
| 624 return token; |
| 625 } |
| 626 |
| 627 /* Advance past the whitespace. */ |
| 628 PARSER_STREAM (parser) = p; |
| 629 } |
| 630 |
| 631 /* If the next character is EOI or (single) ':', the |
| 632 string is complete; return the token. */ |
| 633 if (*PARSER_STREAM (parser) == 0) |
| 634 { |
| 635 LS_TOKEN_STOKEN (token).ptr = start; |
| 636 LS_TOKEN_STOKEN (token).length = PARSER_STREAM (parser) - start; |
| 637 return token; |
| 638 } |
| 639 else if (PARSER_STREAM (parser)[0] == ':') |
| 640 { |
| 641 /* Do not tokenize the C++ scope operator. */ |
| 642 if (PARSER_STREAM (parser)[1] == ':') |
| 643 ++(PARSER_STREAM (parser)); |
| 644 |
| 645 /* Do not tokenify if the input length so far is one |
| 646 (i.e, a single-letter drive name) and the next character |
| 647 is a directory separator. This allows Windows-style |
| 648 paths to be recognized as filenames without quoting it. */ |
| 649 else if ((PARSER_STREAM (parser) - start) != 1 |
| 650 || !IS_DIR_SEPARATOR (PARSER_STREAM (parser)[1])) |
| 651 { |
| 652 LS_TOKEN_STOKEN (token).ptr = start; |
| 653 LS_TOKEN_STOKEN (token).length |
| 654 = PARSER_STREAM (parser) - start; |
| 655 return token; |
| 656 } |
| 657 } |
| 658 /* Special case: permit quote-enclosed linespecs. */ |
| 659 else if (parser->is_quote_enclosed |
| 660 && strchr (linespec_quote_characters, |
| 661 *PARSER_STREAM (parser)) |
| 662 && is_closing_quote_enclosed (PARSER_STREAM (parser))) |
| 663 { |
| 664 LS_TOKEN_STOKEN (token).ptr = start; |
| 665 LS_TOKEN_STOKEN (token).length = PARSER_STREAM (parser) - start; |
| 666 return token; |
| 667 } |
| 668 /* Because commas may terminate a linespec and appear in |
| 669 the middle of valid string input, special cases for |
| 670 '<' and '(' are necessary. */ |
| 671 else if (*PARSER_STREAM (parser) == '<' |
| 672 || *PARSER_STREAM (parser) == '(') |
| 673 { |
| 674 char *p; |
| 675 |
| 676 p = find_parameter_list_end (PARSER_STREAM (parser)); |
| 677 if (p != NULL) |
| 678 { |
| 679 PARSER_STREAM (parser) = p; |
| 680 continue; |
| 681 } |
| 682 } |
| 683 /* Commas are terminators, but not if they are part of an |
| 684 operator name. */ |
| 685 else if (*PARSER_STREAM (parser) == ',') |
| 686 { |
| 687 if ((PARSER_STATE (parser)->language->la_language |
| 688 == language_cplus) |
| 689 && (PARSER_STREAM (parser) - start) > 8 |
| 690 /* strlen ("operator") */) |
| 691 { |
| 692 char *p = strstr (start, "operator"); |
| 693 |
| 694 if (p != NULL && is_operator_name (p)) |
| 695 { |
| 696 /* This is an operator name. Keep going. */ |
| 697 ++(PARSER_STREAM (parser)); |
| 698 continue; |
| 699 } |
| 700 } |
| 701 |
| 702 /* Comma terminates the string. */ |
| 703 LS_TOKEN_STOKEN (token).ptr = start; |
| 704 LS_TOKEN_STOKEN (token).length = PARSER_STREAM (parser) - start; |
| 705 return token; |
| 706 } |
| 707 |
| 708 /* Advance the stream. */ |
| 709 ++(PARSER_STREAM (parser)); |
| 710 } |
| 711 } |
| 712 |
| 713 return token; |
| 714 } |
| 715 |
| 716 /* Lex a single linespec token from PARSER. */ |
| 717 |
| 718 static linespec_token |
| 719 linespec_lexer_lex_one (linespec_parser *parser) |
| 720 { |
| 721 const char *keyword; |
| 722 |
| 723 if (parser->lexer.current.type == LSTOKEN_CONSUMED) |
| 724 { |
| 725 /* Skip any whitespace. */ |
| 726 PARSER_STREAM (parser) = skip_spaces (PARSER_STREAM (parser)); |
| 727 |
| 728 /* Check for a keyword, they end the linespec. */ |
| 729 keyword = NULL; |
| 730 if (parser->keyword_ok) |
| 731 keyword = linespec_lexer_lex_keyword (PARSER_STREAM (parser)); |
| 732 if (keyword != NULL) |
| 733 { |
| 734 parser->lexer.current.type = LSTOKEN_KEYWORD; |
| 735 LS_TOKEN_KEYWORD (parser->lexer.current) = keyword; |
| 736 return parser->lexer.current; |
| 737 } |
| 738 |
| 739 /* Handle other tokens. */ |
| 740 switch (*PARSER_STREAM (parser)) |
| 741 { |
| 742 case 0: |
| 743 parser->lexer.current.type = LSTOKEN_EOI; |
| 744 break; |
| 745 |
| 746 case '+': case '-': |
| 747 case '0': case '1': case '2': case '3': case '4': |
| 748 case '5': case '6': case '7': case '8': case '9': |
| 749 if (!linespec_lexer_lex_number (parser, &(parser->lexer.current))) |
| 750 parser->lexer.current = linespec_lexer_lex_string (parser); |
| 751 break; |
| 752 |
| 753 case ':': |
| 754 /* If we have a scope operator, lex the input as a string. |
| 755 Otherwise, return LSTOKEN_COLON. */ |
| 756 if (PARSER_STREAM (parser)[1] == ':') |
| 757 parser->lexer.current = linespec_lexer_lex_string (parser); |
| 758 else |
| 759 { |
| 760 parser->lexer.current.type = LSTOKEN_COLON; |
| 761 ++(PARSER_STREAM (parser)); |
| 762 } |
| 763 break; |
| 764 |
| 765 case '\'': case '\"': |
| 766 /* Special case: permit quote-enclosed linespecs. */ |
| 767 if (parser->is_quote_enclosed |
| 768 && is_closing_quote_enclosed (PARSER_STREAM (parser))) |
| 769 { |
| 770 ++(PARSER_STREAM (parser)); |
| 771 parser->lexer.current.type = LSTOKEN_EOI; |
| 772 } |
| 773 else |
| 774 parser->lexer.current = linespec_lexer_lex_string (parser); |
| 775 break; |
| 776 |
| 777 case ',': |
| 778 parser->lexer.current.type = LSTOKEN_COMMA; |
| 779 LS_TOKEN_STOKEN (parser->lexer.current).ptr |
| 780 = PARSER_STREAM (parser); |
| 781 LS_TOKEN_STOKEN (parser->lexer.current).length = 1; |
| 782 ++(PARSER_STREAM (parser)); |
| 783 break; |
| 784 |
| 785 default: |
| 786 /* If the input is not a number, it must be a string. |
| 787 [Keywords were already considered above.] */ |
| 788 parser->lexer.current = linespec_lexer_lex_string (parser); |
| 789 break; |
| 790 } |
| 791 } |
| 792 |
| 793 return parser->lexer.current; |
| 794 } |
| 795 |
| 796 /* Consume the current token and return the next token in PARSER's |
| 797 input stream. */ |
| 798 |
| 799 static linespec_token |
| 800 linespec_lexer_consume_token (linespec_parser *parser) |
| 801 { |
| 802 parser->lexer.current.type = LSTOKEN_CONSUMED; |
| 803 return linespec_lexer_lex_one (parser); |
| 804 } |
| 805 |
| 806 /* Return the next token without consuming the current token. */ |
| 807 |
| 808 static linespec_token |
| 809 linespec_lexer_peek_token (linespec_parser *parser) |
| 810 { |
| 811 linespec_token next; |
| 812 char *saved_stream = PARSER_STREAM (parser); |
| 813 linespec_token saved_token = parser->lexer.current; |
| 814 |
| 815 next = linespec_lexer_consume_token (parser); |
| 816 PARSER_STREAM (parser) = saved_stream; |
| 817 parser->lexer.current = saved_token; |
| 818 return next; |
| 819 } |
| 820 |
193 /* Helper functions. */ | 821 /* Helper functions. */ |
194 | 822 |
195 /* Add SAL to SALS. */ | 823 /* Add SAL to SALS. */ |
196 | 824 |
197 static void | 825 static void |
198 add_sal_to_sals_basic (struct symtabs_and_lines *sals, | 826 add_sal_to_sals_basic (struct symtabs_and_lines *sals, |
199 struct symtab_and_line *sal) | 827 struct symtab_and_line *sal) |
200 { | 828 { |
201 ++sals->nelts; | 829 ++sals->nelts; |
202 sals->sals = xrealloc (sals->sals, sals->nelts * sizeof (sals->sals[0])); | 830 sals->sals = xrealloc (sals->sals, sals->nelts * sizeof (sals->sals[0])); |
(...skipping 19 matching lines...) Expand all Loading... |
222 self->canonical_names = xrealloc (self->canonical_names, | 850 self->canonical_names = xrealloc (self->canonical_names, |
223 sals->nelts * sizeof (char *)); | 851 sals->nelts * sizeof (char *)); |
224 if (sal->symtab && sal->symtab->filename) | 852 if (sal->symtab && sal->symtab->filename) |
225 { | 853 { |
226 char *filename = sal->symtab->filename; | 854 char *filename = sal->symtab->filename; |
227 | 855 |
228 /* Note that the filter doesn't have to be a valid linespec | 856 /* Note that the filter doesn't have to be a valid linespec |
229 input. We only apply the ":LINE" treatment to Ada for | 857 input. We only apply the ":LINE" treatment to Ada for |
230 the time being. */ | 858 the time being. */ |
231 if (symname != NULL && sal->line != 0 | 859 if (symname != NULL && sal->line != 0 |
232 » && current_language->la_language == language_ada) | 860 » && self->language->la_language == language_ada) |
233 canonical_name = xstrprintf ("%s:%s:%d", filename, symname, | 861 canonical_name = xstrprintf ("%s:%s:%d", filename, symname, |
234 sal->line); | 862 sal->line); |
235 else if (symname != NULL) | 863 else if (symname != NULL) |
236 canonical_name = xstrprintf ("%s:%s", filename, symname); | 864 canonical_name = xstrprintf ("%s:%s", filename, symname); |
237 else | 865 else |
238 canonical_name = xstrprintf ("%s:%d", filename, sal->line); | 866 canonical_name = xstrprintf ("%s:%d", filename, sal->line); |
239 } | 867 } |
240 | 868 |
241 self->canonical_names[sals->nelts - 1] = canonical_name; | 869 self->canonical_names[sals->nelts - 1] = canonical_name; |
242 } | 870 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 if (*slot) | 909 if (*slot) |
282 return 0; | 910 return 0; |
283 | 911 |
284 p = XNEW (struct address_entry); | 912 p = XNEW (struct address_entry); |
285 memcpy (p, &e, sizeof (struct address_entry)); | 913 memcpy (p, &e, sizeof (struct address_entry)); |
286 *slot = p; | 914 *slot = p; |
287 | 915 |
288 return 1; | 916 return 1; |
289 } | 917 } |
290 | 918 |
291 /* Issue a helpful hint on using the command completion feature on | 919 /* A callback function and the additional data to call it with. */ |
292 single quoted demangled C++ symbols as part of the completion | 920 |
293 error. */ | 921 struct symbol_and_data_callback |
294 | 922 { |
295 static void | 923 /* The callback to use. */ |
296 cplusplus_error (const char *name, const char *fmt, ...) | 924 symbol_found_callback_ftype *callback; |
297 { | 925 |
298 struct ui_file *tmp_stream; | 926 /* Data to be passed to the callback. */ |
299 char *message; | 927 void *data; |
300 | 928 }; |
301 tmp_stream = mem_fileopen (); | 929 |
302 make_cleanup_ui_file_delete (tmp_stream); | 930 /* A helper for iterate_over_all_matching_symtabs that is used to |
303 | 931 restrict calls to another callback to symbols representing inline |
304 { | 932 symbols only. */ |
305 va_list args; | 933 |
306 | 934 static int |
307 va_start (args, fmt); | 935 iterate_inline_only (struct symbol *sym, void *d) |
308 vfprintf_unfiltered (tmp_stream, fmt, args); | 936 { |
309 va_end (args); | 937 if (SYMBOL_INLINED (sym)) |
310 } | 938 { |
311 | 939 struct symbol_and_data_callback *cad = d; |
312 while (*name == '\'') | 940 |
313 name++; | 941 return cad->callback (sym, cad->data); |
314 fprintf_unfiltered (tmp_stream, | 942 } |
315 » » ("Hint: try '%s<TAB> or '%s<ESC-?>\n" | 943 return 1; /* Continue iterating. */ |
316 » » "(Note leading single quote.)"), | 944 } |
317 » » name, name); | 945 |
318 | 946 /* Some data for the expand_symtabs_matching callback. */ |
319 message = ui_file_xstrdup (tmp_stream, NULL); | 947 |
320 make_cleanup (xfree, message); | 948 struct symbol_matcher_data |
321 throw_error (NOT_FOUND_ERROR, "%s", message); | 949 { |
322 } | 950 /* The lookup name against which symbol name should be compared. */ |
| 951 const char *lookup_name; |
| 952 |
| 953 /* The routine to be used for comparison. */ |
| 954 symbol_name_cmp_ftype symbol_name_cmp; |
| 955 }; |
323 | 956 |
324 /* A helper for iterate_over_all_matching_symtabs that is passed as a | 957 /* A helper for iterate_over_all_matching_symtabs that is passed as a |
325 callback to the expand_symtabs_matching method. */ | 958 callback to the expand_symtabs_matching method. */ |
326 | 959 |
327 static int | 960 static int |
328 iterate_name_matcher (const struct language_defn *language, | 961 iterate_name_matcher (const char *name, void *d) |
329 » » const char *name, void *d) | 962 { |
330 { | 963 const struct symbol_matcher_data *data = d; |
331 const char **dname = d; | 964 |
332 | 965 if (data->symbol_name_cmp (name, data->lookup_name) == 0) |
333 if (language->la_symbol_name_compare (name, *dname) == 0) | 966 return 1; /* Expand this symbol's symbol table. */ |
334 return 1; | 967 return 0; /* Skip this symbol. */ |
335 return 0; | |
336 } | 968 } |
337 | 969 |
338 /* A helper that walks over all matching symtabs in all objfiles and | 970 /* A helper that walks over all matching symtabs in all objfiles and |
339 calls CALLBACK for each symbol matching NAME. If SEARCH_PSPACE is | 971 calls CALLBACK for each symbol matching NAME. If SEARCH_PSPACE is |
340 not NULL, then the search is restricted to just that program | 972 not NULL, then the search is restricted to just that program |
341 space. */ | 973 space. If INCLUDE_INLINE is nonzero then symbols representing |
| 974 inlined instances of functions will be included in the result. */ |
342 | 975 |
343 static void | 976 static void |
344 iterate_over_all_matching_symtabs (const char *name, | 977 iterate_over_all_matching_symtabs (struct linespec_state *state, |
| 978 » » » » const char *name, |
345 const domain_enum domain, | 979 const domain_enum domain, |
346 » » » » int (*callback) (struct symbol *, void *), | 980 » » » » symbol_found_callback_ftype *callback, |
347 void *data, | 981 void *data, |
348 » » » » struct program_space *search_pspace) | 982 » » » » struct program_space *search_pspace, |
| 983 » » » » int include_inline) |
349 { | 984 { |
350 struct objfile *objfile; | 985 struct objfile *objfile; |
351 struct program_space *pspace; | 986 struct program_space *pspace; |
| 987 struct symbol_matcher_data matcher_data; |
| 988 |
| 989 matcher_data.lookup_name = name; |
| 990 matcher_data.symbol_name_cmp = |
| 991 state->language->la_get_symbol_name_cmp != NULL |
| 992 ? state->language->la_get_symbol_name_cmp (name) |
| 993 : strcmp_iw; |
352 | 994 |
353 ALL_PSPACES (pspace) | 995 ALL_PSPACES (pspace) |
354 { | 996 { |
355 if (search_pspace != NULL && search_pspace != pspace) | 997 if (search_pspace != NULL && search_pspace != pspace) |
356 continue; | 998 continue; |
357 if (pspace->executing_startup) | 999 if (pspace->executing_startup) |
358 continue; | 1000 continue; |
359 | 1001 |
360 set_current_program_space (pspace); | 1002 set_current_program_space (pspace); |
361 | 1003 |
362 ALL_OBJFILES (objfile) | 1004 ALL_OBJFILES (objfile) |
363 { | 1005 { |
364 struct symtab *symtab; | 1006 struct symtab *symtab; |
365 | 1007 |
366 if (objfile->sf) | 1008 if (objfile->sf) |
367 objfile->sf->qf->expand_symtabs_matching (objfile, NULL, | 1009 objfile->sf->qf->expand_symtabs_matching (objfile, NULL, |
368 iterate_name_matcher, | 1010 iterate_name_matcher, |
369 ALL_DOMAIN, | 1011 ALL_DOMAIN, |
370 » » » » » » &name); | 1012 » » » » » » &matcher_data); |
371 | 1013 |
372 ALL_OBJFILE_SYMTABS (objfile, symtab) | 1014 ALL_OBJFILE_PRIMARY_SYMTABS (objfile, symtab) |
373 { | 1015 { |
374 » if (symtab->primary) | 1016 » struct block *block; |
375 » { | 1017 |
376 » struct block *block; | 1018 » block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK); |
377 | 1019 » LA_ITERATE_OVER_SYMBOLS (block, name, domain, callback, data); |
378 » block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK); | 1020 |
379 » LA_ITERATE_OVER_SYMBOLS (block, name, domain, callback, data); | 1021 » if (include_inline) |
| 1022 » { |
| 1023 » struct symbol_and_data_callback cad = { callback, data }; |
| 1024 » int i; |
| 1025 |
| 1026 » for (i = FIRST_LOCAL_BLOCK; |
| 1027 » » i < BLOCKVECTOR_NBLOCKS (BLOCKVECTOR (symtab)); i++) |
| 1028 » » { |
| 1029 » » block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), i); |
| 1030 » » LA_ITERATE_OVER_SYMBOLS (block, name, domain, |
| 1031 » » » » » iterate_inline_only, &cad); |
| 1032 » » } |
380 } | 1033 } |
381 } | 1034 } |
382 } | 1035 } |
383 } | 1036 } |
384 } | 1037 } |
385 | 1038 |
386 /* Returns the block to be used for symbol searches for the given SYMTAB, | 1039 /* Returns the block to be used for symbol searches for the given SYMTAB, |
387 which may be NULL. */ | 1040 which may be NULL. */ |
388 | 1041 |
389 static struct block * | 1042 static struct block * |
(...skipping 11 matching lines...) Expand all Loading... |
401 no selected frame yet. */ | 1054 no selected frame yet. */ |
402 save_language = current_language->la_language; | 1055 save_language = current_language->la_language; |
403 block = get_selected_block (0); | 1056 block = get_selected_block (0); |
404 set_language (save_language); | 1057 set_language (save_language); |
405 } | 1058 } |
406 | 1059 |
407 return block; | 1060 return block; |
408 } | 1061 } |
409 | 1062 |
410 /* A helper for find_method. This finds all methods in type T which | 1063 /* A helper for find_method. This finds all methods in type T which |
411 match NAME. It adds resulting symbol names to RESULT_NAMES, and | 1064 match NAME. It adds matching symbol names to RESULT_NAMES, and |
412 adds T's direct superclasses to SUPERCLASSES. */ | 1065 adds T's direct superclasses to SUPERCLASSES. */ |
413 | 1066 |
414 static void | 1067 static void |
415 find_methods (struct type *t, const char *name, | 1068 find_methods (struct type *t, const char *name, |
416 VEC (const_char_ptr) **result_names, | 1069 VEC (const_char_ptr) **result_names, |
417 VEC (typep) **superclasses) | 1070 VEC (typep) **superclasses) |
418 { | 1071 { |
419 int i1 = 0; | 1072 int i1 = 0; |
420 int ibase; | 1073 int ibase; |
421 char *class_name = type_name_no_tag (t); | 1074 const char *class_name = type_name_no_tag (t); |
422 char *canon; | |
423 | 1075 |
424 /* Ignore this class if it doesn't have a name. This is ugly, but | 1076 /* Ignore this class if it doesn't have a name. This is ugly, but |
425 unless we figure out how to get the physname without the name of | 1077 unless we figure out how to get the physname without the name of |
426 the class, then the loop can't do any good. */ | 1078 the class, then the loop can't do any good. */ |
427 if (class_name) | 1079 if (class_name) |
428 { | 1080 { |
429 int method_counter; | 1081 int method_counter; |
430 int name_len = strlen (name); | 1082 int name_len = strlen (name); |
431 | 1083 |
432 CHECK_TYPEDEF (t); | 1084 CHECK_TYPEDEF (t); |
433 | 1085 |
434 /* Loop over each method name. At this level, all overloads of a name | 1086 /* Loop over each method name. At this level, all overloads of a name |
435 are counted as a single name. There is an inner loop which loops over | 1087 are counted as a single name. There is an inner loop which loops over |
436 each overload. */ | 1088 each overload. */ |
437 | 1089 |
438 for (method_counter = TYPE_NFN_FIELDS (t) - 1; | 1090 for (method_counter = TYPE_NFN_FIELDS (t) - 1; |
439 method_counter >= 0; | 1091 method_counter >= 0; |
440 --method_counter) | 1092 --method_counter) |
441 { | 1093 { |
442 » char *method_name = TYPE_FN_FIELDLIST_NAME (t, method_counter); | 1094 » const char *method_name = TYPE_FN_FIELDLIST_NAME (t, method_counter); |
443 char dem_opname[64]; | 1095 char dem_opname[64]; |
444 | 1096 |
445 if (strncmp (method_name, "__", 2) == 0 || | 1097 if (strncmp (method_name, "__", 2) == 0 || |
446 strncmp (method_name, "op", 2) == 0 || | 1098 strncmp (method_name, "op", 2) == 0 || |
447 strncmp (method_name, "type", 4) == 0) | 1099 strncmp (method_name, "type", 4) == 0) |
448 { | 1100 { |
449 if (cplus_demangle_opname (method_name, dem_opname, DMGL_ANSI)) | 1101 if (cplus_demangle_opname (method_name, dem_opname, DMGL_ANSI)) |
450 method_name = dem_opname; | 1102 method_name = dem_opname; |
451 else if (cplus_demangle_opname (method_name, dem_opname, 0)) | 1103 else if (cplus_demangle_opname (method_name, dem_opname, 0)) |
452 method_name = dem_opname; | 1104 method_name = dem_opname; |
(...skipping 23 matching lines...) Expand all Loading... |
476 | 1128 |
477 for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++) | 1129 for (ibase = 0; ibase < TYPE_N_BASECLASSES (t); ibase++) |
478 VEC_safe_push (typep, *superclasses, TYPE_BASECLASS (t, ibase)); | 1130 VEC_safe_push (typep, *superclasses, TYPE_BASECLASS (t, ibase)); |
479 } | 1131 } |
480 | 1132 |
481 /* Find an instance of the character C in the string S that is outside | 1133 /* Find an instance of the character C in the string S that is outside |
482 of all parenthesis pairs, single-quoted strings, and double-quoted | 1134 of all parenthesis pairs, single-quoted strings, and double-quoted |
483 strings. Also, ignore the char within a template name, like a ',' | 1135 strings. Also, ignore the char within a template name, like a ',' |
484 within foo<int, int>. */ | 1136 within foo<int, int>. */ |
485 | 1137 |
486 static char * | 1138 static const char * |
487 find_toplevel_char (char *s, char c) | 1139 find_toplevel_char (const char *s, char c) |
488 { | 1140 { |
489 int quoted = 0; /* zero if we're not in quotes; | 1141 int quoted = 0; /* zero if we're not in quotes; |
490 '"' if we're in a double-quoted string; | 1142 '"' if we're in a double-quoted string; |
491 '\'' if we're in a single-quoted string. */ | 1143 '\'' if we're in a single-quoted string. */ |
492 int depth = 0; /* Number of unclosed parens we've seen. */ | 1144 int depth = 0; /* Number of unclosed parens we've seen. */ |
493 char *scan; | 1145 const char *scan; |
494 | 1146 |
495 for (scan = s; *scan; scan++) | 1147 for (scan = s; *scan; scan++) |
496 { | 1148 { |
497 if (quoted) | 1149 if (quoted) |
498 { | 1150 { |
499 if (*scan == quoted) | 1151 if (*scan == quoted) |
500 quoted = 0; | 1152 quoted = 0; |
501 else if (*scan == '\\' && *(scan + 1)) | 1153 else if (*scan == '\\' && *(scan + 1)) |
502 scan++; | 1154 scan++; |
503 } | 1155 } |
504 else if (*scan == c && ! quoted && depth == 0) | 1156 else if (*scan == c && ! quoted && depth == 0) |
505 return scan; | 1157 return scan; |
506 else if (*scan == '"' || *scan == '\'') | 1158 else if (*scan == '"' || *scan == '\'') |
507 quoted = *scan; | 1159 quoted = *scan; |
508 else if (*scan == '(' || *scan == '<') | 1160 else if (*scan == '(' || *scan == '<') |
509 depth++; | 1161 depth++; |
510 else if ((*scan == ')' || *scan == '>') && depth > 0) | 1162 else if ((*scan == ')' || *scan == '>') && depth > 0) |
511 depth--; | 1163 depth--; |
512 } | 1164 } |
513 | 1165 |
514 return 0; | 1166 return 0; |
515 } | 1167 } |
516 | 1168 |
517 /* Determines if the gives string corresponds to an Objective-C method | 1169 /* The string equivalent of find_toplevel_char. Returns a pointer |
518 representation, such as -[Foo bar:] or +[Foo bar]. Objective-C symbols | 1170 to the location of NEEDLE in HAYSTACK, ignoring any occurrences |
519 are allowed to have spaces and parentheses in them. */ | 1171 inside "()" and "<>". Returns NULL if NEEDLE was not found. */ |
520 | 1172 |
521 static int | 1173 static const char * |
522 is_objc_method_format (const char *s) | 1174 find_toplevel_string (const char *haystack, const char *needle) |
523 { | 1175 { |
524 if (s == NULL || *s == '\0') | 1176 const char *s = haystack; |
525 return 0; | 1177 |
526 /* Handle arguments with the format FILENAME:SYMBOL. */ | 1178 do |
527 if ((s[0] == ':') && (strchr ("+-", s[1]) != NULL) | 1179 { |
528 && (s[2] == '[') && strchr(s, ']')) | 1180 s = find_toplevel_char (s, *needle); |
529 return 1; | 1181 |
530 /* Handle arguments that are just SYMBOL. */ | 1182 if (s != NULL) |
531 else if ((strchr ("+-", s[0]) != NULL) && (s[1] == '[') && strchr(s, ']')) | 1183 » { |
532 return 1; | 1184 » /* Found first char in HAYSTACK; check rest of string. */ |
533 return 0; | 1185 » if (strncmp (s, needle, strlen (needle)) == 0) |
| 1186 » return s; |
| 1187 |
| 1188 » /* Didn't find it; loop over HAYSTACK, looking for the next |
| 1189 » instance of the first character of NEEDLE. */ |
| 1190 » ++s; |
| 1191 » } |
| 1192 } |
| 1193 while (s != NULL && *s != '\0'); |
| 1194 |
| 1195 /* NEEDLE was not found in HAYSTACK. */ |
| 1196 return NULL; |
534 } | 1197 } |
535 | 1198 |
536 /* Given FILTERS, a list of canonical names, filter the sals in RESULT | 1199 /* Given FILTERS, a list of canonical names, filter the sals in RESULT |
537 and store the result in SELF->CANONICAL. */ | 1200 and store the result in SELF->CANONICAL. */ |
538 | 1201 |
539 static void | 1202 static void |
540 filter_results (struct linespec_state *self, | 1203 filter_results (struct linespec_state *self, |
541 struct symtabs_and_lines *result, | 1204 struct symtabs_and_lines *result, |
542 VEC (const_char_ptr) *filters) | 1205 VEC (const_char_ptr) *filters) |
543 { | 1206 { |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
624 if (select_mode == multiple_symbols_cancel | 1287 if (select_mode == multiple_symbols_cancel |
625 && VEC_length (const_char_ptr, item_names) > 1) | 1288 && VEC_length (const_char_ptr, item_names) > 1) |
626 error (_("canceled because the command is ambiguous\n" | 1289 error (_("canceled because the command is ambiguous\n" |
627 "See set/show multiple-symbol.")); | 1290 "See set/show multiple-symbol.")); |
628 | 1291 |
629 if (select_mode == multiple_symbols_all | 1292 if (select_mode == multiple_symbols_all |
630 || VEC_length (const_char_ptr, item_names) == 1) | 1293 || VEC_length (const_char_ptr, item_names) == 1) |
631 { | 1294 { |
632 do_cleanups (old_chain); | 1295 do_cleanups (old_chain); |
633 convert_results_to_lsals (self, result); | 1296 convert_results_to_lsals (self, result); |
error: old chunk mismatch |
None
OLD | NEW |