aboutsummaryrefslogtreecommitdiff
path: root/gdb/c-exp.y
diff options
context:
space:
mode:
authorJim Kingdon <jkingdon@engr.sgi.com>1993-07-30 19:50:29 +0000
committerJim Kingdon <jkingdon@engr.sgi.com>1993-07-30 19:50:29 +0000
commit96c68efaf7dfd77a07836211048dc4c1ac92c258 (patch)
tree690da3e1ac3075ef1e2cb1c24ee90539758b18e7 /gdb/c-exp.y
parent38cbb25c2b17a4b146901f82906bc1be81acab93 (diff)
downloadgdb-96c68efaf7dfd77a07836211048dc4c1ac92c258.zip
gdb-96c68efaf7dfd77a07836211048dc4c1ac92c258.tar.gz
gdb-96c68efaf7dfd77a07836211048dc4c1ac92c258.tar.bz2
* c-exp.y (yylex): Detect C++ nested types.
Diffstat (limited to 'gdb/c-exp.y')
-rw-r--r--gdb/c-exp.y67
1 files changed, 66 insertions, 1 deletions
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 3756721..b226509 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -1526,7 +1526,72 @@ yylex ()
}
if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
{
- yylval.tsym.type = SYMBOL_TYPE (sym);
+ char *p;
+ char *namestart;
+ struct symbol *best_sym;
+
+ /* Look ahead to detect nested types. This probably should be
+ done in the grammar, but trying seemed to introduce a lot
+ of shift/reduce and reduce/reduce conflicts. It's possible
+ that it could be done, though. Or perhaps a non-grammar, but
+ less ad hoc, approach would work well. */
+
+ /* Since we do not currently have any way of distinguishing
+ a nested type from a non-nested one (the stabs don't tell
+ us whether a type is nested), we just ignore the
+ containing type. */
+
+ p = lexptr;
+ best_sym = sym;
+ while (1)
+ {
+ /* Skip whitespace. */
+ while (*p == ' ' || *p == '\t' || *p == '\n')
+ ++p;
+ if (*p == ':' && p[1] == ':')
+ {
+ /* Skip the `::'. */
+ p += 2;
+ /* Skip whitespace. */
+ while (*p == ' ' || *p == '\t' || *p == '\n')
+ ++p;
+ namestart = p;
+ while (*p == '_' || *p == '$' || (*p >= '0' && *p <= '9')
+ || (*p >= 'a' && *p <= 'z')
+ || (*p >= 'A' && *p <= 'Z'))
+ ++p;
+ if (p != namestart)
+ {
+ struct symbol *cur_sym;
+ /* As big as the whole rest of the expression, which is
+ at least big enough. */
+ char *tmp = alloca (strlen (namestart));
+
+ memcpy (tmp, namestart, p - namestart);
+ tmp[p - namestart] = '\0';
+ cur_sym = lookup_symbol (tmp, expression_context_block,
+ VAR_NAMESPACE, NULL);
+ if (cur_sym)
+ {
+ if (SYMBOL_CLASS (cur_sym) == LOC_TYPEDEF)
+ {
+ best_sym = cur_sym;
+ lexptr = p;
+ }
+ else
+ break;
+ }
+ else
+ break;
+ }
+ else
+ break;
+ }
+ else
+ break;
+ }
+
+ yylval.tsym.type = SYMBOL_TYPE (best_sym);
return TYPENAME;
}
if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0)