diff options
author | Leszek Swirski <leszeks@google.com> | 2018-01-25 16:20:47 +0000 |
---|---|---|
committer | Simon Marchi <simon.marchi@polymtl.ca> | 2018-02-01 22:34:20 -0500 |
commit | 59498c305e6f1db2a1ed8d44cb58f0d24ec092fe (patch) | |
tree | 5d02582d3c31d0ac78156328185204d487ece91f /gdb/c-exp.y | |
parent | 17545aa1bfa291def4674c6700c1c7a3575ee5c1 (diff) | |
download | gdb-59498c305e6f1db2a1ed8d44cb58f0d24ec092fe.zip gdb-59498c305e6f1db2a1ed8d44cb58f0d24ec092fe.tar.gz gdb-59498c305e6f1db2a1ed8d44cb58f0d24ec092fe.tar.bz2 |
Do not classify C struct members as a filename
There is existing logic in C/C++ expression parsing to avoid classifying
names as a filename when they are a field on the this object. This
change extends this logic to also avoid classifying names after a
struct-op (-> or .) as a filename, which otherwise causes a syntax
error.
Thus, it is now possible in the file
#include <map>
struct D {
void map();
}
D d;
to call
(gdb) print d.map()
where previously this would have been a syntax error.
Tested on gdb.cp/*.exp
gdb/ChangeLog:
* c-exp.y (lex_one_token, classify_name, yylex): Don't classify
names after a structop as a filename
gdb/testsuite/ChangeLog:
* gdb.cp/filename.cc, gdb.cp/filename.exp: Test that member
functions with the same name as an include file are parsed
correctly.
Diffstat (limited to 'gdb/c-exp.y')
-rw-r--r-- | gdb/c-exp.y | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 0482e85..8f0aa00 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -2447,24 +2447,23 @@ static struct macro_scope *expression_macro_scope; static int saw_name_at_eof; /* This is set if the previously-returned token was a structure - operator -- either '.' or ARROW. This is used only when parsing to - do field name completion. */ -static int last_was_structop; + operator -- either '.' or ARROW. */ +static bool last_was_structop; /* Read one token, getting characters through lexptr. */ static int -lex_one_token (struct parser_state *par_state, int *is_quoted_name) +lex_one_token (struct parser_state *par_state, bool *is_quoted_name) { int c; int namelen; unsigned int i; const char *tokstart; - int saw_structop = last_was_structop; + bool saw_structop = last_was_structop; char *copy; - last_was_structop = 0; - *is_quoted_name = 0; + last_was_structop = false; + *is_quoted_name = false; retry: @@ -2505,7 +2504,7 @@ lex_one_token (struct parser_state *par_state, int *is_quoted_name) lexptr += 2; yylval.opcode = tokentab2[i].opcode; - if (parse_completion && tokentab2[i].token == ARROW) + if (tokentab2[i].token == ARROW) last_was_structop = 1; return tokentab2[i].token; } @@ -2529,7 +2528,7 @@ lex_one_token (struct parser_state *par_state, int *is_quoted_name) saw_name_at_eof = 0; return COMPLETE; } - else if (saw_structop) + else if (parse_completion && saw_structop) return COMPLETE; else return 0; @@ -2569,8 +2568,7 @@ lex_one_token (struct parser_state *par_state, int *is_quoted_name) /* Might be a floating point number. */ if (lexptr[1] < '0' || lexptr[1] > '9') { - if (parse_completion) - last_was_structop = 1; + last_was_structop = true; goto symbol; /* Nope, must be a symbol. */ } /* FALL THRU into number case. */ @@ -2711,7 +2709,7 @@ lex_one_token (struct parser_state *par_state, int *is_quoted_name) { ++tokstart; namelen = lexptr - tokstart - 1; - *is_quoted_name = 1; + *is_quoted_name = true; goto tryname; } @@ -2859,11 +2857,12 @@ auto_obstack name_obstack; Updates yylval and returns the new token type. BLOCK is the block in which lookups start; this can be NULL to mean the global scope. IS_QUOTED_NAME is non-zero if the name token was originally quoted - in single quotes. */ + in single quotes. IS_AFTER_STRUCTOP is true if this name follows + a structure operator -- either '.' or ARROW */ static int classify_name (struct parser_state *par_state, const struct block *block, - int is_quoted_name) + bool is_quoted_name, bool is_after_structop) { struct block_symbol bsym; char *copy; @@ -2907,11 +2906,13 @@ classify_name (struct parser_state *par_state, const struct block *block, } } - /* If we found a field, then we want to prefer it over a + /* If we found a field on the "this" object, or we are looking + up a field on a struct, then we want to prefer it over a filename. However, if the name was quoted, then it is better to check for a filename or a block, since this is the only way the user has of requiring the extension to be used. */ - if (is_a_field_of_this.type == NULL || is_quoted_name) + if ((is_a_field_of_this.type == NULL && !is_after_structop) + || is_quoted_name) { /* See if it's a file name. */ struct symtab *symtab; @@ -2992,7 +2993,7 @@ classify_inner_name (struct parser_state *par_state, char *copy; if (context == NULL) - return classify_name (par_state, block, 0); + return classify_name (par_state, block, false, false); type = check_typedef (context); if (!type_aggregate_p (type)) @@ -3066,19 +3067,21 @@ yylex (void) struct type *context_type = NULL; int last_to_examine, next_to_examine, checkpoint; const struct block *search_block; - int is_quoted_name; + bool is_quoted_name, last_lex_was_structop; if (popping && !VEC_empty (token_and_value, token_fifo)) goto do_pop; popping = 0; + last_lex_was_structop = last_was_structop; + /* Read the first token and decide what to do. Most of the subsequent code is C++-only; but also depends on seeing a "::" or name-like token. */ current.token = lex_one_token (pstate, &is_quoted_name); if (current.token == NAME) current.token = classify_name (pstate, expression_context_block, - is_quoted_name); + is_quoted_name, last_lex_was_structop); if (parse_language (pstate)->la_language != language_cplus || (current.token != TYPENAME && current.token != COLONCOLON && current.token != FILENAME)) @@ -3091,7 +3094,7 @@ yylex (void) last_was_coloncolon = current.token == COLONCOLON; while (1) { - int ignore; + bool ignore; /* We ignore quoted names other than the very first one. Subsequent ones do not have any special meaning. */ @@ -3242,7 +3245,7 @@ c_parse (struct parser_state *par_state) parser_debug); /* Initialize some state used by the lexer. */ - last_was_structop = 0; + last_was_structop = false; saw_name_at_eof = 0; VEC_free (token_and_value, token_fifo); |