* c-exp.y (yylex): Detect C++ nested types.
authorJim Kingdon <jkingdon@engr.sgi.com>
Fri, 30 Jul 1993 19:50:29 +0000 (19:50 +0000)
committerJim Kingdon <jkingdon@engr.sgi.com>
Fri, 30 Jul 1993 19:50:29 +0000 (19:50 +0000)
gdb/ChangeLog
gdb/c-exp.y

index ef1a5d839da8cdecc5cadd00cd997f30af21a78f..8a0c96405524c822fa207de28d1bc6dbea1017cd 100644 (file)
@@ -1,3 +1,7 @@
+Fri Jul 30 14:44:21 1993  Jim Kingdon  (kingdon@lioth.cygnus.com)
+
+       * c-exp.y (yylex): Detect C++ nested types.
+
 start-sanitize-v9
 Fri Jul 30 11:07:37 1993  Doug Evans  (dje@canuck.cygnus.com)
 
index 3756721faf06f8492d5de94a49792fc666d71cec..b2265091e3363af8e95fb970385a925d34cc7a71 100644 (file)
@@ -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)