diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 5e10d2a3b4..b0dd6c7caf 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -73,6 +73,8 @@ void yyerror (const char *); static int type_aggregate_p (struct type *); +static bool is_identifier_separator (char); + %} /* Although the yacc "value" of an expression is not used, @@ -1718,6 +1720,53 @@ type_aggregate_p (struct type *type) && TYPE_DECLARED_CLASS (type))); } +/* While iterating all the characters in an identifier, an identifier separator + is a boundary where we know the iteration is done. */ + +static bool +is_identifier_separator (char c) +{ + switch (c) + { + case ' ': + case '\t': + case '\n': + case '\0': + case '\'': + case '"': + case '\\': + case '(': + case ')': + case ',': + case '.': + case '+': + case '-': + case '*': + case '/': + case '|': + case '&': + case '^': + case '~': + case '!': + case '@': + case '[': + case ']': + /* '<' should not be a token separator, because it can be an open angle + bracket followed by a nested template identifier in C++. */ + case '>': + case '?': + case ':': + case '=': + case '{': + case '}': + case ';': + return true; + default: + break; + } + return false; +} + /* Validate a parameter typelist. */ static void @@ -1920,7 +1969,7 @@ parse_number (struct parser_state *par_state, FIXME: This check is wrong; for example it doesn't find overflow on 0x123456789 when LONGEST is 32 bits. */ if (c != 'l' && c != 'u' && n != 0) - { + { if ((unsigned_p && (ULONGEST) prevn >= (ULONGEST) n)) error (_("Numeric constant too large.")); } @@ -2741,16 +2790,13 @@ lex_one_token (struct parser_state *par_state, bool *is_quoted_name) } } - if (!(c == '_' || c == '$' - || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) + if (is_identifier_separator(c)) /* We must have come across a bad character (e.g. ';'). */ error (_("Invalid character '%c' in expression."), c); /* It's a name. See how long it is. */ namelen = 0; - for (c = tokstart[namelen]; - (c == '_' || c == '$' || (c >= '0' && c <= '9') - || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '<');) + for (c = tokstart[namelen]; !is_identifier_separator(c);) { /* Template parameter lists are part of the name. FIXME: This mishandles `print $a<4&&$a>3'. */ @@ -2932,7 +2978,7 @@ classify_name (struct parser_state *par_state, const struct block *block, 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_after_structop) + if ((is_a_field_of_this.type == NULL && !is_after_structop) || is_quoted_name) { /* See if it's a file name. */