diff options
author | Jim Kingdon <jkingdon@engr.sgi.com> | 1993-07-30 19:50:29 +0000 |
---|---|---|
committer | Jim Kingdon <jkingdon@engr.sgi.com> | 1993-07-30 19:50:29 +0000 |
commit | 96c68efaf7dfd77a07836211048dc4c1ac92c258 (patch) | |
tree | 690da3e1ac3075ef1e2cb1c24ee90539758b18e7 /gdb/c-exp.y | |
parent | 38cbb25c2b17a4b146901f82906bc1be81acab93 (diff) | |
download | gdb-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.y | 67 |
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) |