PR exp/15109:
authorTom Tromey <tromey@redhat.com>
Thu, 21 Mar 2013 15:19:33 +0000 (15:19 +0000)
committerTom Tromey <tromey@redhat.com>
Thu, 21 Mar 2013 15:19:33 +0000 (15:19 +0000)
* c-exp.y (yylex): Rewrite to push all tokens onto the FIFO.
Handle FILENAME token.
gdb/testsuite
* gdb.cp/cpexprs.exp: Add test for FILENAME:: case.
* gdb.cp/misc.exp: Add test for FILENAME:: case.

gdb/ChangeLog
gdb/c-exp.y
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.cp/cpexprs.exp
gdb/testsuite/gdb.cp/misc.exp

index 10e8cd6ce5bc7deaddf31a133819d49d6e70d573..7aab4effec8b89d806f98aee679e4eb12b9fc175 100644 (file)
@@ -1,3 +1,9 @@
+2013-03-21  Tom Tromey  <tromey@redhat.com>
+
+       PR exp/15109:
+       * c-exp.y (yylex): Rewrite to push all tokens onto the FIFO.
+       Handle FILENAME token.
+
 2013-03-21  Tom Tromey  <tromey@redhat.com>
 
        * c-exp.y (YYPRINT): Define.
index 313a63f10d511c0fe2dc34dec635c606cdec6ffb..0ab1cde2224bb9a70807a8a5f6be44f4b84995bb 100644 (file)
@@ -2917,58 +2917,91 @@ static int
 yylex (void)
 {
   token_and_value current;
-  int first_was_coloncolon, last_was_coloncolon, first_iter;
+  int first_was_coloncolon, last_was_coloncolon;
   struct type *context_type = NULL;
+  int last_to_examine, next_to_examine, checkpoint;
+  const struct block *search_block;
 
   if (popping && !VEC_empty (token_and_value, token_fifo))
-    {
-      token_and_value tv = *VEC_index (token_and_value, token_fifo, 0);
-      VEC_ordered_remove (token_and_value, token_fifo, 0);
-      yylval = tv.value;
-      return tv.token;
-    }
+    goto do_pop;
   popping = 0;
 
+  /* Read the first token and decide what to do.  Most of the
+     subsequent code is C++-only; but also depends on seeing a "::" or
+     name-like token.  */
   current.token = lex_one_token ();
   if (current.token == NAME)
     current.token = classify_name (expression_context_block);
   if (parse_language->la_language != language_cplus
-      || (current.token != TYPENAME && current.token != COLONCOLON))
+      || (current.token != TYPENAME && current.token != COLONCOLON
+         && current.token != FILENAME))
     return current.token;
 
-  first_was_coloncolon = current.token == COLONCOLON;
-  last_was_coloncolon = first_was_coloncolon;
+  /* Read any sequence of alternating "::" and name-like tokens into
+     the token FIFO.  */
+  current.value = yylval;
+  VEC_safe_push (token_and_value, token_fifo, &current);
+  last_was_coloncolon = current.token == COLONCOLON;
+  while (1)
+    {
+      current.token = lex_one_token ();
+      current.value = yylval;
+      VEC_safe_push (token_and_value, token_fifo, &current);
+
+      if ((last_was_coloncolon && current.token != NAME)
+         || (!last_was_coloncolon && current.token != COLONCOLON))
+       break;
+      last_was_coloncolon = !last_was_coloncolon;
+    }
+  popping = 1;
+
+  /* We always read one extra token, so compute the number of tokens
+     to examine accordingly.  */
+  last_to_examine = VEC_length (token_and_value, token_fifo) - 2;
+  next_to_examine = 0;
+
+  current = *VEC_index (token_and_value, token_fifo, next_to_examine);
+  ++next_to_examine;
+
   obstack_free (&name_obstack, obstack_base (&name_obstack));
-  if (!last_was_coloncolon)
+  checkpoint = 0;
+  if (current.token == FILENAME)
+    search_block = current.value.bval;
+  else if (current.token == COLONCOLON)
+    search_block = NULL;
+  else
     {
-      obstack_grow (&name_obstack, yylval.sval.ptr, yylval.sval.length);
-      context_type = yylval.tsym.type;
+      gdb_assert (current.token == TYPENAME);
+      search_block = expression_context_block;
+      obstack_grow (&name_obstack, current.value.sval.ptr,
+                   current.value.sval.length);
+      context_type = current.value.tsym.type;
+      checkpoint = 1;
     }
-  current.value = yylval;
-  first_iter = 1;
-  while (1)
+
+  first_was_coloncolon = current.token == COLONCOLON;
+  last_was_coloncolon = first_was_coloncolon;
+
+  while (next_to_examine <= last_to_examine)
     {
-      token_and_value next;
+      token_and_value *next;
 
-      next.token = lex_one_token ();
-      next.value = yylval;
+      next = VEC_index (token_and_value, token_fifo, next_to_examine);
+      ++next_to_examine;
 
-      if (next.token == NAME && last_was_coloncolon)
+      if (next->token == NAME && last_was_coloncolon)
        {
          int classification;
 
-         classification = classify_inner_name (first_was_coloncolon
-                                               ? NULL
-                                               : expression_context_block,
-                                               context_type);
+         yylval = next->value;
+         classification = classify_inner_name (search_block, context_type);
          /* We keep going until we either run out of names, or until
             we have a qualified name which is not a type.  */
          if (classification != TYPENAME && classification != NAME)
-           {
-             /* Push the final component and leave the loop.  */
-             VEC_safe_push (token_and_value, token_fifo, &next);
-             break;
-           }
+           break;
+
+         /* Accept up to this token.  */
+         checkpoint = next_to_examine;
 
          /* Update the partial name we are constructing.  */
          if (context_type != NULL)
@@ -2976,8 +3009,8 @@ yylex (void)
              /* We don't want to put a leading "::" into the name.  */
              obstack_grow_str (&name_obstack, "::");
            }
-         obstack_grow (&name_obstack, next.value.sval.ptr,
-                       next.value.sval.length);
+         obstack_grow (&name_obstack, next->value.sval.ptr,
+                       next->value.sval.length);
 
          yylval.sval.ptr = obstack_base (&name_obstack);
          yylval.sval.length = obstack_object_size (&name_obstack);
@@ -2991,38 +3024,32 @@ yylex (void)
 
          context_type = yylval.tsym.type;
        }
-      else if (next.token == COLONCOLON && !last_was_coloncolon)
+      else if (next->token == COLONCOLON && !last_was_coloncolon)
        last_was_coloncolon = 1;
       else
        {
          /* We've reached the end of the name.  */
-         VEC_safe_push (token_and_value, token_fifo, &next);
          break;
        }
-
-      first_iter = 0;
     }
 
-  popping = 1;
-
-  /* If we ended with a "::", insert it too.  */
-  if (last_was_coloncolon)
+  /* If we have a replacement token, install it as the first token in
+     the FIFO, and delete the other constituent tokens.  */
+  if (checkpoint > 0)
     {
-      token_and_value cc;
-      memset (&cc, 0, sizeof (token_and_value));
-      if (first_was_coloncolon && first_iter)
-       {
-         yylval = cc.value;
-         return COLONCOLON;
-       }
-      cc.token = COLONCOLON;
-      VEC_safe_insert (token_and_value, token_fifo, 0, &cc);
+      current.value.sval.ptr = obstack_copy0 (&expansion_obstack,
+                                             current.value.sval.ptr,
+                                             current.value.sval.length);
+
+      VEC_replace (token_and_value, token_fifo, 0, &current);
+      if (checkpoint > 1)
+       VEC_block_remove (token_and_value, token_fifo, 1, checkpoint - 1);
     }
 
+ do_pop:
+  current = *VEC_index (token_and_value, token_fifo, 0);
+  VEC_ordered_remove (token_and_value, token_fifo, 0);
   yylval = current.value;
-  yylval.sval.ptr = obstack_copy0 (&expansion_obstack,
-                                  yylval.sval.ptr,
-                                  yylval.sval.length);
   return current.token;
 }
 
index b3a444d86238d9b0141d94def163cc7011271e4d..afbb5eb25f0f8064db84bfe3b97cbd6bfc80298a 100644 (file)
@@ -1,3 +1,8 @@
+2013-03-21  Tom Tromey  <tromey@redhat.com>
+
+       * gdb.cp/cpexprs.exp: Add test for FILENAME:: case.
+       * gdb.cp/misc.exp: Add test for FILENAME:: case.
+
 2013-03-20  Pedro Alves  <palves@redhat.com>
 
        PR gdb/15289
index ec491358927664b0b7bc2edadf46d0de6a507b49..52a293bc6d442df512d51e0ab6f483bb92c8f09b 100644 (file)
@@ -731,5 +731,8 @@ gdb_test "p CV_f(int)"   { = {int \(int\)} 0x[0-9a-f]+ <CV_f\(int\)>}
 gdb_test "p CV_f(CV::t)" { = {int \(int\)} 0x[0-9a-f]+ <CV_f\(int\)>}
 gdb_test "p CV_f(CV::i)" " = 43"
 
+gdb_test "p CV_f('cpexprs.cc'::CV::t)" \
+    { = {int \(int\)} 0x[0-9a-f]+ <CV_f\(int\)>}
+
 gdb_exit
 return 0
index bcb0c2bb7a3695e47a221da6c2d4c447f2640947..bd2353a266e6b0cbe9cadfadf1237ecaa4c57db2 100644 (file)
@@ -107,3 +107,6 @@ gdb_test "print (bool)17.93" "\\$\[0-9\]* = true" "(bool)17.93"
 gdb_test "print (bool)0.0" "\\$\[0-9\]* = false" "(bool)0.0"
 gdb_test "print (int)true" "\\$\[0-9\]* = 1" "(int)true"
 gdb_test "print (int)false" "\\$\[0-9\]* = 0" "(int)false"
+
+gdb_test "print 'misc.cc'::v_bool" " = true" \
+    "expression using block qualifier"