@@ -1718,6 +1718,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 +1967,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 +2788,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 +2976,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. */