aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog6
-rw-r--r--gdb/c-exp.y129
-rw-r--r--gdb/testsuite/ChangeLog5
-rw-r--r--gdb/testsuite/gdb.cp/cpexprs.exp3
-rw-r--r--gdb/testsuite/gdb.cp/misc.exp3
5 files changed, 95 insertions, 51 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 10e8cd6..7aab4ef 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,11 @@
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.
(c_print_token): New function.
diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 313a63f..0ab1cde 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -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;
}
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index b3a444d..afbb5eb 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -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
diff --git a/gdb/testsuite/gdb.cp/cpexprs.exp b/gdb/testsuite/gdb.cp/cpexprs.exp
index ec49135..52a293b 100644
--- a/gdb/testsuite/gdb.cp/cpexprs.exp
+++ b/gdb/testsuite/gdb.cp/cpexprs.exp
@@ -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
diff --git a/gdb/testsuite/gdb.cp/misc.exp b/gdb/testsuite/gdb.cp/misc.exp
index bcb0c2b..bd2353a 100644
--- a/gdb/testsuite/gdb.cp/misc.exp
+++ b/gdb/testsuite/gdb.cp/misc.exp
@@ -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"