|
|
beeca6 |
;; Fix comma/struct member parser collision
|
|
|
beeca6 |
;; Tom Tromey and Leszek Swirski (RH BZ 18156900
|
|
|
beeca6 |
|
|
|
beeca6 |
commit b2f83c08372136fe9fe7d1df2feb5566c8b883fb
|
|
|
beeca6 |
Author: Tom Tromey <tromey@redhat.com>
|
|
|
beeca6 |
Date: Thu Mar 21 15:19:33 2013 +0000
|
|
|
beeca6 |
|
|
|
beeca6 |
PR exp/15109:
|
|
|
beeca6 |
* c-exp.y (yylex): Rewrite to push all tokens onto the FIFO.
|
|
|
beeca6 |
Handle FILENAME token.
|
|
|
beeca6 |
gdb/testsuite
|
|
|
beeca6 |
* gdb.cp/cpexprs.exp: Add test for FILENAME:: case.
|
|
|
beeca6 |
* gdb.cp/misc.exp: Add test for FILENAME:: case.
|
|
|
beeca6 |
|
|
|
beeca6 |
commit 805e1f190887b3b7dea3fd157d58bc25effcf688
|
|
|
beeca6 |
Author: Tom Tromey <tromey@redhat.com>
|
|
|
beeca6 |
Date: Mon Nov 4 12:38:10 2013 -0700
|
|
|
beeca6 |
|
|
|
beeca6 |
fix PR c++/16117
|
|
|
beeca6 |
|
|
|
beeca6 |
This patch fixes PR c++/16117.
|
|
|
beeca6 |
|
|
|
beeca6 |
gdb has an extension so that users can use expressions like FILE::NAME
|
|
|
beeca6 |
to choose a variable of the given name from the given file. The bug
|
|
|
beeca6 |
is that this extension takes precedence over ordinary C++ expressions
|
|
|
beeca6 |
of the same form. You might think this is merely hypothetical, but
|
|
|
beeca6 |
now that C++ headers commonly do not use an extension, it is more
|
|
|
beeca6 |
common.
|
|
|
beeca6 |
|
|
|
beeca6 |
This patch fixes the bug by making two related changes. First, it
|
|
|
beeca6 |
changes gdb to prefer the ordinary C++ meaning of a symbol over the
|
|
|
beeca6 |
extended meaning. Second, it arranges for single-quoting of the
|
|
|
beeca6 |
symbol to indicate a preference for the extension.
|
|
|
beeca6 |
|
|
|
beeca6 |
Built and regtested on x86-64 Fedora 18.
|
|
|
beeca6 |
New test case included.
|
|
|
beeca6 |
|
|
|
beeca6 |
|
|
|
beeca6 |
2013-11-15 Tom Tromey <tromey@redhat.com>
|
|
|
beeca6 |
|
|
|
beeca6 |
PR c++/16117:
|
|
|
beeca6 |
* c-exp.y (lex_one_token): Add "is_quoted_name" argument.
|
|
|
beeca6 |
(classify_name): Likewise. Prefer a field of "this" over a
|
|
|
beeca6 |
filename.
|
|
|
beeca6 |
(classify_inner_name, yylex): Update.
|
|
|
beeca6 |
|
|
|
beeca6 |
2013-11-15 Tom Tromey <tromey@redhat.com>
|
|
|
beeca6 |
|
|
|
beeca6 |
* gdb.texinfo (Variables): Note gdb rules for ambiguous cases.
|
|
|
beeca6 |
Add example.
|
|
|
beeca6 |
|
|
|
beeca6 |
2013-11-15 Tom Tromey <tromey@redhat.com>
|
|
|
beeca6 |
|
|
|
beeca6 |
* gdb.cp/includefile: New file.
|
|
|
beeca6 |
* gdb.cp/filename.exp: New file.
|
|
|
beeca6 |
* gdb.cp/filename.cc: New file.
|
|
|
beeca6 |
|
|
|
beeca6 |
commit 59498c305e6f1db2a1ed8d44cb58f0d24ec092fe
|
|
|
beeca6 |
Author: Leszek Swirski <leszeks@google.com>
|
|
|
beeca6 |
Date: Thu Jan 25 16:20:47 2018 +0000
|
|
|
beeca6 |
|
|
|
beeca6 |
Do not classify C struct members as a filename
|
|
|
beeca6 |
|
|
|
beeca6 |
There is existing logic in C/C++ expression parsing to avoid classifying
|
|
|
beeca6 |
names as a filename when they are a field on the this object. This
|
|
|
beeca6 |
change extends this logic to also avoid classifying names after a
|
|
|
beeca6 |
struct-op (-> or .) as a filename, which otherwise causes a syntax
|
|
|
beeca6 |
error.
|
|
|
beeca6 |
|
|
|
beeca6 |
Thus, it is now possible in the file
|
|
|
beeca6 |
|
|
|
beeca6 |
#include <map>
|
|
|
beeca6 |
struct D {
|
|
|
beeca6 |
void map();
|
|
|
beeca6 |
}
|
|
|
beeca6 |
D d;
|
|
|
beeca6 |
|
|
|
beeca6 |
to call
|
|
|
beeca6 |
|
|
|
beeca6 |
(gdb) print d.map()
|
|
|
beeca6 |
|
|
|
beeca6 |
where previously this would have been a syntax error.
|
|
|
beeca6 |
|
|
|
beeca6 |
Tested on gdb.cp/*.exp
|
|
|
beeca6 |
|
|
|
beeca6 |
gdb/ChangeLog:
|
|
|
beeca6 |
|
|
|
beeca6 |
* c-exp.y (lex_one_token, classify_name, yylex): Don't classify
|
|
|
beeca6 |
names after a structop as a filename
|
|
|
beeca6 |
|
|
|
beeca6 |
gdb/testsuite/ChangeLog:
|
|
|
beeca6 |
|
|
|
beeca6 |
* gdb.cp/filename.cc, gdb.cp/filename.exp: Test that member
|
|
|
beeca6 |
functions with the same name as an include file are parsed
|
|
|
beeca6 |
correctly.
|
|
|
beeca6 |
|
|
|
beeca6 |
*** gdb-7.6.1-orig/gdb/c-exp.y 2020-04-21 16:59:20.636119459 -0400
|
|
|
beeca6 |
--- gdb-7.6.1/gdb/c-exp.y 2020-04-22 16:41:04.560602687 -0400
|
|
|
beeca6 |
*************** static int last_was_structop;
|
|
|
beeca6 |
*** 2352,2358 ****
|
|
|
beeca6 |
/* Read one token, getting characters through lexptr. */
|
|
|
beeca6 |
|
|
|
beeca6 |
static int
|
|
|
beeca6 |
! lex_one_token (void)
|
|
|
beeca6 |
{
|
|
|
beeca6 |
int c;
|
|
|
beeca6 |
int namelen;
|
|
|
beeca6 |
--- 2352,2358 ----
|
|
|
beeca6 |
/* Read one token, getting characters through lexptr. */
|
|
|
beeca6 |
|
|
|
beeca6 |
static int
|
|
|
beeca6 |
! lex_one_token (int *is_quoted_name)
|
|
|
beeca6 |
{
|
|
|
beeca6 |
int c;
|
|
|
beeca6 |
int namelen;
|
|
|
beeca6 |
*************** lex_one_token (void)
|
|
|
beeca6 |
*** 2362,2367 ****
|
|
|
beeca6 |
--- 2362,2368 ----
|
|
|
beeca6 |
char *copy;
|
|
|
beeca6 |
|
|
|
beeca6 |
last_was_structop = 0;
|
|
|
beeca6 |
+ *is_quoted_name = 0;
|
|
|
beeca6 |
|
|
|
beeca6 |
retry:
|
|
|
beeca6 |
|
|
|
beeca6 |
*************** lex_one_token (void)
|
|
|
beeca6 |
*** 2402,2408 ****
|
|
|
beeca6 |
|
|
|
beeca6 |
lexptr += 2;
|
|
|
beeca6 |
yylval.opcode = tokentab2[i].opcode;
|
|
|
beeca6 |
! if (parse_completion && tokentab2[i].token == ARROW)
|
|
|
beeca6 |
last_was_structop = 1;
|
|
|
beeca6 |
return tokentab2[i].token;
|
|
|
beeca6 |
}
|
|
|
beeca6 |
--- 2403,2409 ----
|
|
|
beeca6 |
|
|
|
beeca6 |
lexptr += 2;
|
|
|
beeca6 |
yylval.opcode = tokentab2[i].opcode;
|
|
|
beeca6 |
! if (tokentab2[i].token == ARROW)
|
|
|
beeca6 |
last_was_structop = 1;
|
|
|
beeca6 |
return tokentab2[i].token;
|
|
|
beeca6 |
}
|
|
|
beeca6 |
*************** lex_one_token (void)
|
|
|
beeca6 |
*** 2426,2432 ****
|
|
|
beeca6 |
saw_name_at_eof = 0;
|
|
|
beeca6 |
return COMPLETE;
|
|
|
beeca6 |
}
|
|
|
beeca6 |
! else if (saw_structop)
|
|
|
beeca6 |
return COMPLETE;
|
|
|
beeca6 |
else
|
|
|
beeca6 |
return 0;
|
|
|
beeca6 |
--- 2427,2433 ----
|
|
|
beeca6 |
saw_name_at_eof = 0;
|
|
|
beeca6 |
return COMPLETE;
|
|
|
beeca6 |
}
|
|
|
beeca6 |
! else if (parse_completion && saw_structop)
|
|
|
beeca6 |
return COMPLETE;
|
|
|
beeca6 |
else
|
|
|
beeca6 |
return 0;
|
|
|
beeca6 |
*************** lex_one_token (void)
|
|
|
beeca6 |
*** 2465,2472 ****
|
|
|
beeca6 |
/* Might be a floating point number. */
|
|
|
beeca6 |
if (lexptr[1] < '0' || lexptr[1] > '9')
|
|
|
beeca6 |
{
|
|
|
beeca6 |
! if (parse_completion)
|
|
|
beeca6 |
! last_was_structop = 1;
|
|
|
beeca6 |
goto symbol; /* Nope, must be a symbol. */
|
|
|
beeca6 |
}
|
|
|
beeca6 |
/* FALL THRU into number case. */
|
|
|
beeca6 |
--- 2466,2472 ----
|
|
|
beeca6 |
/* Might be a floating point number. */
|
|
|
beeca6 |
if (lexptr[1] < '0' || lexptr[1] > '9')
|
|
|
beeca6 |
{
|
|
|
beeca6 |
! last_was_structop = 1;
|
|
|
beeca6 |
goto symbol; /* Nope, must be a symbol. */
|
|
|
beeca6 |
}
|
|
|
beeca6 |
/* FALL THRU into number case. */
|
|
|
beeca6 |
*************** lex_one_token (void)
|
|
|
beeca6 |
*** 2606,2611 ****
|
|
|
beeca6 |
--- 2606,2613 ----
|
|
|
beeca6 |
{
|
|
|
beeca6 |
++tokstart;
|
|
|
beeca6 |
namelen = lexptr - tokstart - 1;
|
|
|
beeca6 |
+ *is_quoted_name = 1;
|
|
|
beeca6 |
+
|
|
|
beeca6 |
goto tryname;
|
|
|
beeca6 |
}
|
|
|
beeca6 |
else if (host_len > 1)
|
|
|
beeca6 |
*************** static struct obstack name_obstack;
|
|
|
beeca6 |
*** 2748,2757 ****
|
|
|
beeca6 |
|
|
|
beeca6 |
/* Classify a NAME token. The contents of the token are in `yylval'.
|
|
|
beeca6 |
Updates yylval and returns the new token type. BLOCK is the block
|
|
|
beeca6 |
! in which lookups start; this can be NULL to mean the global
|
|
|
beeca6 |
! scope. */
|
|
|
beeca6 |
static int
|
|
|
beeca6 |
! classify_name (const struct block *block)
|
|
|
beeca6 |
{
|
|
|
beeca6 |
struct symbol *sym;
|
|
|
beeca6 |
char *copy;
|
|
|
beeca6 |
--- 2750,2763 ----
|
|
|
beeca6 |
|
|
|
beeca6 |
/* Classify a NAME token. The contents of the token are in `yylval'.
|
|
|
beeca6 |
Updates yylval and returns the new token type. BLOCK is the block
|
|
|
beeca6 |
! in which lookups start; this can be NULL to mean the global scope.
|
|
|
beeca6 |
! IS_QUOTED_NAME is non-zero if the name token was originally quoted
|
|
|
beeca6 |
! in single quotes. IS_AFTER_STRUCTOP is true if this name follows
|
|
|
beeca6 |
! a structure operator -- either '.' or ARROW. */
|
|
|
beeca6 |
!
|
|
|
beeca6 |
static int
|
|
|
beeca6 |
! classify_name (const struct block *block, int is_quoted_name,
|
|
|
beeca6 |
! int is_after_structop)
|
|
|
beeca6 |
{
|
|
|
beeca6 |
struct symbol *sym;
|
|
|
beeca6 |
char *copy;
|
|
|
beeca6 |
*************** classify_name (const struct block *block
|
|
|
beeca6 |
*** 2775,2790 ****
|
|
|
beeca6 |
}
|
|
|
beeca6 |
else if (!sym)
|
|
|
beeca6 |
{
|
|
|
beeca6 |
- /* See if it's a file name. */
|
|
|
beeca6 |
- struct symtab *symtab;
|
|
|
beeca6 |
-
|
|
|
beeca6 |
- symtab = lookup_symtab (copy);
|
|
|
beeca6 |
- if (symtab)
|
|
|
beeca6 |
- {
|
|
|
beeca6 |
- yylval.bval = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
|
|
|
beeca6 |
- return FILENAME;
|
|
|
beeca6 |
- }
|
|
|
beeca6 |
-
|
|
|
beeca6 |
/* If we found a field of 'this', we might have erroneously
|
|
|
beeca6 |
found a constructor where we wanted a type name. Handle this
|
|
|
beeca6 |
case by noticing that we found a constructor and then look up
|
|
|
beeca6 |
--- 2781,2786 ----
|
|
|
beeca6 |
*************** classify_name (const struct block *block
|
|
|
beeca6 |
*** 2804,2809 ****
|
|
|
beeca6 |
--- 2800,2825 ----
|
|
|
beeca6 |
return TYPENAME;
|
|
|
beeca6 |
}
|
|
|
beeca6 |
}
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ /* If we found a field on the "this" object, or we are looking
|
|
|
beeca6 |
+ up a field on a struct, then we want to prefer it over a
|
|
|
beeca6 |
+ filename. However, if the name was quoted, then it is better
|
|
|
beeca6 |
+ to check for a filename or a block, since this is the only
|
|
|
beeca6 |
+ way the user has of requiring the extension to be used. */
|
|
|
beeca6 |
+ if ((is_a_field_of_this.type == NULL && !is_after_structop)
|
|
|
beeca6 |
+ || is_quoted_name)
|
|
|
beeca6 |
+ {
|
|
|
beeca6 |
+ /* See if it's a file name. */
|
|
|
beeca6 |
+ struct symtab *symtab;
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ symtab = lookup_symtab (copy);
|
|
|
beeca6 |
+ if (symtab)
|
|
|
beeca6 |
+ {
|
|
|
beeca6 |
+ yylval.bval = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab),
|
|
|
beeca6 |
+ STATIC_BLOCK);
|
|
|
beeca6 |
+ return FILENAME;
|
|
|
beeca6 |
+ }
|
|
|
beeca6 |
+ }
|
|
|
beeca6 |
}
|
|
|
beeca6 |
|
|
|
beeca6 |
if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
|
|
|
beeca6 |
*************** classify_inner_name (const struct block
|
|
|
beeca6 |
*** 2873,2879 ****
|
|
|
beeca6 |
char *copy;
|
|
|
beeca6 |
|
|
|
beeca6 |
if (context == NULL)
|
|
|
beeca6 |
! return classify_name (block);
|
|
|
beeca6 |
|
|
|
beeca6 |
type = check_typedef (context);
|
|
|
beeca6 |
if (TYPE_CODE (type) != TYPE_CODE_STRUCT
|
|
|
beeca6 |
--- 2889,2895 ----
|
|
|
beeca6 |
char *copy;
|
|
|
beeca6 |
|
|
|
beeca6 |
if (context == NULL)
|
|
|
beeca6 |
! return classify_name (block, 0, 0);
|
|
|
beeca6 |
|
|
|
beeca6 |
type = check_typedef (context);
|
|
|
beeca6 |
if (TYPE_CODE (type) != TYPE_CODE_STRUCT
|
|
|
beeca6 |
*************** static int
|
|
|
beeca6 |
*** 2941,2998 ****
|
|
|
beeca6 |
yylex (void)
|
|
|
beeca6 |
{
|
|
|
beeca6 |
token_and_value current;
|
|
|
beeca6 |
! int first_was_coloncolon, last_was_coloncolon, first_iter;
|
|
|
beeca6 |
struct type *context_type = NULL;
|
|
|
beeca6 |
|
|
|
beeca6 |
if (popping && !VEC_empty (token_and_value, token_fifo))
|
|
|
beeca6 |
! {
|
|
|
beeca6 |
! token_and_value tv = *VEC_index (token_and_value, token_fifo, 0);
|
|
|
beeca6 |
! VEC_ordered_remove (token_and_value, token_fifo, 0);
|
|
|
beeca6 |
! yylval = tv.value;
|
|
|
beeca6 |
! return tv.token;
|
|
|
beeca6 |
! }
|
|
|
beeca6 |
popping = 0;
|
|
|
beeca6 |
|
|
|
beeca6 |
! current.token = lex_one_token ();
|
|
|
beeca6 |
if (current.token == NAME)
|
|
|
beeca6 |
! current.token = classify_name (expression_context_block);
|
|
|
beeca6 |
if (parse_language->la_language != language_cplus
|
|
|
beeca6 |
! || (current.token != TYPENAME && current.token != COLONCOLON))
|
|
|
beeca6 |
return current.token;
|
|
|
beeca6 |
|
|
|
beeca6 |
! first_was_coloncolon = current.token == COLONCOLON;
|
|
|
beeca6 |
! last_was_coloncolon = first_was_coloncolon;
|
|
|
beeca6 |
! obstack_free (&name_obstack, obstack_base (&name_obstack));
|
|
|
beeca6 |
! if (!last_was_coloncolon)
|
|
|
beeca6 |
! {
|
|
|
beeca6 |
! obstack_grow (&name_obstack, yylval.sval.ptr, yylval.sval.length);
|
|
|
beeca6 |
! context_type = yylval.tsym.type;
|
|
|
beeca6 |
! }
|
|
|
beeca6 |
current.value = yylval;
|
|
|
beeca6 |
! first_iter = 1;
|
|
|
beeca6 |
while (1)
|
|
|
beeca6 |
{
|
|
|
beeca6 |
! token_and_value next;
|
|
|
beeca6 |
|
|
|
beeca6 |
! next.token = lex_one_token ();
|
|
|
beeca6 |
! next.value = yylval;
|
|
|
beeca6 |
|
|
|
beeca6 |
! if (next.token == NAME && last_was_coloncolon)
|
|
|
beeca6 |
{
|
|
|
beeca6 |
int classification;
|
|
|
beeca6 |
|
|
|
beeca6 |
! classification = classify_inner_name (first_was_coloncolon
|
|
|
beeca6 |
! ? NULL
|
|
|
beeca6 |
! : expression_context_block,
|
|
|
beeca6 |
! context_type);
|
|
|
beeca6 |
/* We keep going until we either run out of names, or until
|
|
|
beeca6 |
we have a qualified name which is not a type. */
|
|
|
beeca6 |
if (classification != TYPENAME && classification != NAME)
|
|
|
beeca6 |
! {
|
|
|
beeca6 |
! /* Push the final component and leave the loop. */
|
|
|
beeca6 |
! VEC_safe_push (token_and_value, token_fifo, &next;;
|
|
|
beeca6 |
! break;
|
|
|
beeca6 |
! }
|
|
|
beeca6 |
|
|
|
beeca6 |
/* Update the partial name we are constructing. */
|
|
|
beeca6 |
if (context_type != NULL)
|
|
|
beeca6 |
--- 2957,3055 ----
|
|
|
beeca6 |
yylex (void)
|
|
|
beeca6 |
{
|
|
|
beeca6 |
token_and_value current;
|
|
|
beeca6 |
! int first_was_coloncolon, last_was_coloncolon;
|
|
|
beeca6 |
struct type *context_type = NULL;
|
|
|
beeca6 |
+ int last_to_examine, next_to_examine, checkpoint;
|
|
|
beeca6 |
+ const struct block *search_block;
|
|
|
beeca6 |
+ int is_quoted_name, last_lex_was_structop;
|
|
|
beeca6 |
|
|
|
beeca6 |
if (popping && !VEC_empty (token_and_value, token_fifo))
|
|
|
beeca6 |
! goto do_pop;
|
|
|
beeca6 |
popping = 0;
|
|
|
beeca6 |
|
|
|
beeca6 |
! last_lex_was_structop = last_was_structop;
|
|
|
beeca6 |
!
|
|
|
beeca6 |
! /* Read the first token and decide what to do. Most of the
|
|
|
beeca6 |
! subsequent code is C++-only; but also depends on seeing a "::" or
|
|
|
beeca6 |
! name-like token. */
|
|
|
beeca6 |
! current.token = lex_one_token (&is_quoted_name);
|
|
|
beeca6 |
if (current.token == NAME)
|
|
|
beeca6 |
! current.token = classify_name (expression_context_block, is_quoted_name,
|
|
|
beeca6 |
! last_lex_was_structop);
|
|
|
beeca6 |
if (parse_language->la_language != language_cplus
|
|
|
beeca6 |
! || (current.token != TYPENAME && current.token != COLONCOLON
|
|
|
beeca6 |
! && current.token != FILENAME))
|
|
|
beeca6 |
return current.token;
|
|
|
beeca6 |
|
|
|
beeca6 |
! /* Read any sequence of alternating "::" and name-like tokens into
|
|
|
beeca6 |
! the token FIFO. */
|
|
|
beeca6 |
current.value = yylval;
|
|
|
beeca6 |
! VEC_safe_push (token_and_value, token_fifo, ¤t;;
|
|
|
beeca6 |
! last_was_coloncolon = current.token == COLONCOLON;
|
|
|
beeca6 |
while (1)
|
|
|
beeca6 |
{
|
|
|
beeca6 |
! int ignore;
|
|
|
beeca6 |
!
|
|
|
beeca6 |
! /* We ignore quoted names other than the very first one.
|
|
|
beeca6 |
! Subsequent ones do not have any special meaning. */
|
|
|
beeca6 |
! current.token = lex_one_token (&ignore);
|
|
|
beeca6 |
! current.value = yylval;
|
|
|
beeca6 |
! VEC_safe_push (token_and_value, token_fifo, ¤t;;
|
|
|
beeca6 |
|
|
|
beeca6 |
! if ((last_was_coloncolon && current.token != NAME)
|
|
|
beeca6 |
! || (!last_was_coloncolon && current.token != COLONCOLON))
|
|
|
beeca6 |
! break;
|
|
|
beeca6 |
! last_was_coloncolon = !last_was_coloncolon;
|
|
|
beeca6 |
! }
|
|
|
beeca6 |
! popping = 1;
|
|
|
beeca6 |
|
|
|
beeca6 |
! /* We always read one extra token, so compute the number of tokens
|
|
|
beeca6 |
! to examine accordingly. */
|
|
|
beeca6 |
! last_to_examine = VEC_length (token_and_value, token_fifo) - 2;
|
|
|
beeca6 |
! next_to_examine = 0;
|
|
|
beeca6 |
!
|
|
|
beeca6 |
! current = *VEC_index (token_and_value, token_fifo, next_to_examine);
|
|
|
beeca6 |
! ++next_to_examine;
|
|
|
beeca6 |
!
|
|
|
beeca6 |
! obstack_free (&name_obstack, obstack_base (&name_obstack));
|
|
|
beeca6 |
! checkpoint = 0;
|
|
|
beeca6 |
! if (current.token == FILENAME)
|
|
|
beeca6 |
! search_block = current.value.bval;
|
|
|
beeca6 |
! else if (current.token == COLONCOLON)
|
|
|
beeca6 |
! search_block = NULL;
|
|
|
beeca6 |
! else
|
|
|
beeca6 |
! {
|
|
|
beeca6 |
! gdb_assert (current.token == TYPENAME);
|
|
|
beeca6 |
! search_block = expression_context_block;
|
|
|
beeca6 |
! obstack_grow (&name_obstack, current.value.sval.ptr,
|
|
|
beeca6 |
! current.value.sval.length);
|
|
|
beeca6 |
! context_type = current.value.tsym.type;
|
|
|
beeca6 |
! checkpoint = 1;
|
|
|
beeca6 |
! }
|
|
|
beeca6 |
!
|
|
|
beeca6 |
! first_was_coloncolon = current.token == COLONCOLON;
|
|
|
beeca6 |
! last_was_coloncolon = first_was_coloncolon;
|
|
|
beeca6 |
!
|
|
|
beeca6 |
! while (next_to_examine <= last_to_examine)
|
|
|
beeca6 |
! {
|
|
|
beeca6 |
! token_and_value *next;
|
|
|
beeca6 |
!
|
|
|
beeca6 |
! next = VEC_index (token_and_value, token_fifo, next_to_examine);
|
|
|
beeca6 |
! ++next_to_examine;
|
|
|
beeca6 |
!
|
|
|
beeca6 |
! if (next->token == NAME && last_was_coloncolon)
|
|
|
beeca6 |
{
|
|
|
beeca6 |
int classification;
|
|
|
beeca6 |
|
|
|
beeca6 |
! yylval = next->value;
|
|
|
beeca6 |
! classification = classify_inner_name (search_block, context_type);
|
|
|
beeca6 |
/* We keep going until we either run out of names, or until
|
|
|
beeca6 |
we have a qualified name which is not a type. */
|
|
|
beeca6 |
if (classification != TYPENAME && classification != NAME)
|
|
|
beeca6 |
! break;
|
|
|
beeca6 |
!
|
|
|
beeca6 |
! /* Accept up to this token. */
|
|
|
beeca6 |
! checkpoint = next_to_examine;
|
|
|
beeca6 |
|
|
|
beeca6 |
/* Update the partial name we are constructing. */
|
|
|
beeca6 |
if (context_type != NULL)
|
|
|
beeca6 |
*************** yylex (void)
|
|
|
beeca6 |
*** 3000,3007 ****
|
|
|
beeca6 |
/* We don't want to put a leading "::" into the name. */
|
|
|
beeca6 |
obstack_grow_str (&name_obstack, "::");
|
|
|
beeca6 |
}
|
|
|
beeca6 |
! obstack_grow (&name_obstack, next.value.sval.ptr,
|
|
|
beeca6 |
! next.value.sval.length);
|
|
|
beeca6 |
|
|
|
beeca6 |
yylval.sval.ptr = obstack_base (&name_obstack);
|
|
|
beeca6 |
yylval.sval.length = obstack_object_size (&name_obstack);
|
|
|
beeca6 |
--- 3057,3064 ----
|
|
|
beeca6 |
/* We don't want to put a leading "::" into the name. */
|
|
|
beeca6 |
obstack_grow_str (&name_obstack, "::");
|
|
|
beeca6 |
}
|
|
|
beeca6 |
! obstack_grow (&name_obstack, next->value.sval.ptr,
|
|
|
beeca6 |
! next->value.sval.length);
|
|
|
beeca6 |
|
|
|
beeca6 |
yylval.sval.ptr = obstack_base (&name_obstack);
|
|
|
beeca6 |
yylval.sval.length = obstack_object_size (&name_obstack);
|
|
|
beeca6 |
*************** yylex (void)
|
|
|
beeca6 |
*** 3015,3052 ****
|
|
|
beeca6 |
|
|
|
beeca6 |
context_type = yylval.tsym.type;
|
|
|
beeca6 |
}
|
|
|
beeca6 |
! else if (next.token == COLONCOLON && !last_was_coloncolon)
|
|
|
beeca6 |
last_was_coloncolon = 1;
|
|
|
beeca6 |
else
|
|
|
beeca6 |
{
|
|
|
beeca6 |
/* We've reached the end of the name. */
|
|
|
beeca6 |
- VEC_safe_push (token_and_value, token_fifo, &next;;
|
|
|
beeca6 |
break;
|
|
|
beeca6 |
}
|
|
|
beeca6 |
-
|
|
|
beeca6 |
- first_iter = 0;
|
|
|
beeca6 |
- }
|
|
|
beeca6 |
-
|
|
|
beeca6 |
- popping = 1;
|
|
|
beeca6 |
-
|
|
|
beeca6 |
- /* If we ended with a "::", insert it too. */
|
|
|
beeca6 |
- if (last_was_coloncolon)
|
|
|
beeca6 |
- {
|
|
|
beeca6 |
- token_and_value cc;
|
|
|
beeca6 |
- memset (&cc, 0, sizeof (token_and_value));
|
|
|
beeca6 |
- if (first_was_coloncolon && first_iter)
|
|
|
beeca6 |
- {
|
|
|
beeca6 |
- yylval = cc.value;
|
|
|
beeca6 |
- return COLONCOLON;
|
|
|
beeca6 |
- }
|
|
|
beeca6 |
- cc.token = COLONCOLON;
|
|
|
beeca6 |
- VEC_safe_insert (token_and_value, token_fifo, 0, &cc);
|
|
|
beeca6 |
}
|
|
|
beeca6 |
|
|
|
beeca6 |
yylval = current.value;
|
|
|
beeca6 |
- yylval.sval.ptr = obstack_copy0 (&expansion_obstack,
|
|
|
beeca6 |
- yylval.sval.ptr,
|
|
|
beeca6 |
- yylval.sval.length);
|
|
|
beeca6 |
return current.token;
|
|
|
beeca6 |
}
|
|
|
beeca6 |
|
|
|
beeca6 |
--- 3072,3103 ----
|
|
|
beeca6 |
|
|
|
beeca6 |
context_type = yylval.tsym.type;
|
|
|
beeca6 |
}
|
|
|
beeca6 |
! else if (next->token == COLONCOLON && !last_was_coloncolon)
|
|
|
beeca6 |
last_was_coloncolon = 1;
|
|
|
beeca6 |
else
|
|
|
beeca6 |
{
|
|
|
beeca6 |
/* We've reached the end of the name. */
|
|
|
beeca6 |
break;
|
|
|
beeca6 |
}
|
|
|
beeca6 |
}
|
|
|
beeca6 |
|
|
|
beeca6 |
+ /* If we have a replacement token, install it as the first token in
|
|
|
beeca6 |
+ the FIFO, and delete the other constituent tokens. */
|
|
|
beeca6 |
+ if (checkpoint > 0)
|
|
|
beeca6 |
+ {
|
|
|
beeca6 |
+ current.value.sval.ptr = obstack_copy0 (&expansion_obstack,
|
|
|
beeca6 |
+ current.value.sval.ptr,
|
|
|
beeca6 |
+ current.value.sval.length);
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ VEC_replace (token_and_value, token_fifo, 0, ¤t;;
|
|
|
beeca6 |
+ if (checkpoint > 1)
|
|
|
beeca6 |
+ VEC_block_remove (token_and_value, token_fifo, 1, checkpoint - 1);
|
|
|
beeca6 |
+ }
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ do_pop:
|
|
|
beeca6 |
+ current = *VEC_index (token_and_value, token_fifo, 0);
|
|
|
beeca6 |
+ VEC_ordered_remove (token_and_value, token_fifo, 0);
|
|
|
beeca6 |
yylval = current.value;
|
|
|
beeca6 |
return current.token;
|
|
|
beeca6 |
}
|
|
|
beeca6 |
|
|
|
beeca6 |
*** gdb-7.6.1-orig/gdb/doc/gdb.texinfo 2020-04-21 16:59:20.581119544 -0400
|
|
|
beeca6 |
--- gdb-7.6.1/gdb/doc/gdb.texinfo 2020-04-22 16:26:14.350165928 -0400
|
|
|
beeca6 |
*************** $4 = 0
|
|
|
beeca6 |
*** 8219,8229 ****
|
|
|
beeca6 |
@end smallexample
|
|
|
beeca6 |
|
|
|
beeca6 |
@cindex C@t{++} scope resolution
|
|
|
beeca6 |
! These uses of @samp{::} are very rarely in conflict with the very similar
|
|
|
beeca6 |
! use of the same notation in C@t{++}. @value{GDBN} also supports use of the C@t{++}
|
|
|
beeca6 |
! scope resolution operator in @value{GDBN} expressions.
|
|
|
beeca6 |
! @c FIXME: Um, so what happens in one of those rare cases where it's in
|
|
|
beeca6 |
! @c conflict?? --mew
|
|
|
beeca6 |
|
|
|
beeca6 |
@cindex wrong values
|
|
|
beeca6 |
@cindex variable values, wrong
|
|
|
beeca6 |
--- 8219,8242 ----
|
|
|
beeca6 |
@end smallexample
|
|
|
beeca6 |
|
|
|
beeca6 |
@cindex C@t{++} scope resolution
|
|
|
beeca6 |
! These uses of @samp{::} are very rarely in conflict with the very
|
|
|
beeca6 |
! similar use of the same notation in C@t{++}. When they are in
|
|
|
beeca6 |
! conflict, the C@t{++} meaning takes precedence; however, this can be
|
|
|
beeca6 |
! overridden by quoting the file or function name with single quotes.
|
|
|
beeca6 |
!
|
|
|
beeca6 |
! For example, suppose the program is stopped in a method of a class
|
|
|
beeca6 |
! that has a field named @code{includefile}, and there is also an
|
|
|
beeca6 |
! include file named @file{includefile} that defines a variable,
|
|
|
beeca6 |
! @code{some_global}.
|
|
|
beeca6 |
!
|
|
|
beeca6 |
! @smallexample
|
|
|
beeca6 |
! (@value{GDBP}) p includefile
|
|
|
beeca6 |
! $1 = 23
|
|
|
beeca6 |
! (@value{GDBP}) p includefile::some_global
|
|
|
beeca6 |
! A syntax error in expression, near `'.
|
|
|
beeca6 |
! (@value{GDBP}) p 'includefile'::some_global
|
|
|
beeca6 |
! $2 = 27
|
|
|
beeca6 |
! @end smallexample
|
|
|
beeca6 |
|
|
|
beeca6 |
@cindex wrong values
|
|
|
beeca6 |
@cindex variable values, wrong
|
|
|
beeca6 |
*** gdb-7.6.1-orig/gdb/testsuite/gdb.cp/cpexprs.exp 2020-04-21 16:59:20.413119804 -0400
|
|
|
beeca6 |
--- gdb-7.6.1/gdb/testsuite/gdb.cp/cpexprs.exp 2020-04-22 16:18:30.938538563 -0400
|
|
|
beeca6 |
*************** gdb_test "p CV_f(int)" { = {int \(int\
|
|
|
beeca6 |
*** 731,735 ****
|
|
|
beeca6 |
--- 731,738 ----
|
|
|
beeca6 |
gdb_test "p CV_f(CV::t)" { = {int \(int\)} 0x[0-9a-f]+ <CV_f\(int\)>}
|
|
|
beeca6 |
gdb_test "p CV_f(CV::i)" " = 43"
|
|
|
beeca6 |
|
|
|
beeca6 |
+ gdb_test "p CV_f('cpexprs.cc'::CV::t)" \
|
|
|
beeca6 |
+ { = {int \(int\)} 0x[0-9a-f]+ <CV_f\(int\)>}
|
|
|
beeca6 |
+
|
|
|
beeca6 |
gdb_exit
|
|
|
beeca6 |
return 0
|
|
|
beeca6 |
*** gdb-7.6.1-orig/gdb/testsuite/gdb.cp/misc.exp 2020-04-21 16:59:20.411119807 -0400
|
|
|
beeca6 |
--- gdb-7.6.1/gdb/testsuite/gdb.cp/misc.exp 2020-04-22 16:18:30.939538558 -0400
|
|
|
beeca6 |
*************** gdb_test "print (bool)17.93" "\\$\[0-9\]
|
|
|
beeca6 |
*** 107,109 ****
|
|
|
beeca6 |
--- 107,112 ----
|
|
|
beeca6 |
gdb_test "print (bool)0.0" "\\$\[0-9\]* = false" "(bool)0.0"
|
|
|
beeca6 |
gdb_test "print (int)true" "\\$\[0-9\]* = 1" "(int)true"
|
|
|
beeca6 |
gdb_test "print (int)false" "\\$\[0-9\]* = 0" "(int)false"
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ gdb_test "print 'misc.cc'::v_bool" " = true" \
|
|
|
beeca6 |
+ "expression using block qualifier"
|
|
|
beeca6 |
*** gdb-7.6.1-orig/gdb/testsuite/gdb.cp/filename.cc 1969-12-31 19:00:00.000000000 -0500
|
|
|
beeca6 |
--- gdb-7.6.1/gdb/testsuite/gdb.cp/filename.cc 2020-04-22 16:54:00.973626918 -0400
|
|
|
beeca6 |
***************
|
|
|
beeca6 |
*** 0 ****
|
|
|
beeca6 |
--- 1,57 ----
|
|
|
beeca6 |
+ /* This testcase is part of GDB, the GNU debugger.
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ Copyright 2013 Free Software Foundation, Inc.
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ This program is free software; you can redistribute it and/or modify
|
|
|
beeca6 |
+ it under the terms of the GNU General Public License as published by
|
|
|
beeca6 |
+ the Free Software Foundation; either version 3 of the License, or
|
|
|
beeca6 |
+ (at your option) any later version.
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ This program is distributed in the hope that it will be useful,
|
|
|
beeca6 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
beeca6 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
beeca6 |
+ GNU General Public License for more details.
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ You should have received a copy of the GNU General Public License
|
|
|
beeca6 |
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ #include "includefile"
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ class C {
|
|
|
beeca6 |
+ public:
|
|
|
beeca6 |
+ int includefile[1];
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ C() {
|
|
|
beeca6 |
+ includefile[0] = 23;
|
|
|
beeca6 |
+ }
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ void m() {
|
|
|
beeca6 |
+ /* stop inside C */
|
|
|
beeca6 |
+ }
|
|
|
beeca6 |
+ };
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ class D {
|
|
|
beeca6 |
+ public:
|
|
|
beeca6 |
+ int includefile();
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ void m() {
|
|
|
beeca6 |
+ /* stop inside D */
|
|
|
beeca6 |
+ }
|
|
|
beeca6 |
+ };
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ int D::includefile() {
|
|
|
beeca6 |
+ return 24;
|
|
|
beeca6 |
+ }
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ int main() {
|
|
|
beeca6 |
+ C c;
|
|
|
beeca6 |
+ C* pc = &c;
|
|
|
beeca6 |
+ c.m();
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ D d;
|
|
|
beeca6 |
+ D* pd = &d;
|
|
|
beeca6 |
+ d.m();
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ /* stop outside */
|
|
|
beeca6 |
+ return 0;
|
|
|
beeca6 |
+ }
|
|
|
beeca6 |
*** gdb-7.6.1-orig/gdb/testsuite/gdb.cp/filename.exp 1969-12-31 19:00:00.000000000 -0500
|
|
|
beeca6 |
--- gdb-7.6.1/gdb/testsuite/gdb.cp/filename.exp 2020-04-22 16:34:25.685647330 -0400
|
|
|
beeca6 |
***************
|
|
|
beeca6 |
*** 0 ****
|
|
|
beeca6 |
--- 1,49 ----
|
|
|
beeca6 |
+ # Copyright 2013 Free Software Foundation, Inc.
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ # This program is free software; you can redistribute it and/or modify
|
|
|
beeca6 |
+ # it under the terms of the GNU General Public License as published by
|
|
|
beeca6 |
+ # the Free Software Foundation; either version 3 of the License, or
|
|
|
beeca6 |
+ # (at your option) any later version.
|
|
|
beeca6 |
+ #
|
|
|
beeca6 |
+ # This program is distributed in the hope that it will be useful,
|
|
|
beeca6 |
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
beeca6 |
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
beeca6 |
+ # GNU General Public License for more details.
|
|
|
beeca6 |
+ #
|
|
|
beeca6 |
+ # You should have received a copy of the GNU General Public License
|
|
|
beeca6 |
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ if { [skip_cplus_tests] } { continue }
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ standard_testfile .cc
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}]} {
|
|
|
beeca6 |
+ return -1
|
|
|
beeca6 |
+ }
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ if ![runto_main] then {
|
|
|
beeca6 |
+ perror "couldn't run to main"
|
|
|
beeca6 |
+ continue
|
|
|
beeca6 |
+ }
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ gdb_breakpoint [gdb_get_line_number "stop inside C"]
|
|
|
beeca6 |
+ gdb_continue_to_breakpoint "stop inside C"
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ gdb_test "print includefile\[0\]" " = 23"
|
|
|
beeca6 |
+ gdb_test "print this->includefile\[0\]" " = 23"
|
|
|
beeca6 |
+ gdb_test "print 'includefile'::some_global" " = 27"
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ gdb_breakpoint [gdb_get_line_number "stop inside D"]
|
|
|
beeca6 |
+ gdb_continue_to_breakpoint "stop inside D"
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ gdb_test "print includefile()" " = 24"
|
|
|
beeca6 |
+ gdb_test "print this->includefile()" " = 24"
|
|
|
beeca6 |
+ gdb_test "print 'includefile'::some_global" " = 27"
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ gdb_breakpoint [gdb_get_line_number "stop outside"]
|
|
|
beeca6 |
+ gdb_continue_to_breakpoint "stop outside"
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ gdb_test "print c.includefile\[0\]" " = 23"
|
|
|
beeca6 |
+ gdb_test "print pc->includefile\[0\]" " = 23"
|
|
|
beeca6 |
+ gdb_test "print d.includefile()" " = 24"
|
|
|
beeca6 |
+ gdb_test "print pd->includefile()" " = 24"
|
|
|
beeca6 |
*** gdb-7.6.1-orig/gdb/testsuite/gdb.cp/includefile 1969-12-31 19:00:00.000000000 -0500
|
|
|
beeca6 |
--- gdb-7.6.1/gdb/testsuite/gdb.cp/includefile 2020-04-22 16:26:14.352165918 -0400
|
|
|
beeca6 |
***************
|
|
|
beeca6 |
*** 0 ****
|
|
|
beeca6 |
--- 1,18 ----
|
|
|
beeca6 |
+ /* This testcase is part of GDB, the GNU debugger.
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ Copyright 2013 Free Software Foundation, Inc.
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ This program is free software; you can redistribute it and/or modify
|
|
|
beeca6 |
+ it under the terms of the GNU General Public License as published by
|
|
|
beeca6 |
+ the Free Software Foundation; either version 3 of the License, or
|
|
|
beeca6 |
+ (at your option) any later version.
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ This program is distributed in the hope that it will be useful,
|
|
|
beeca6 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
beeca6 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
beeca6 |
+ GNU General Public License for more details.
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ You should have received a copy of the GNU General Public License
|
|
|
beeca6 |
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
beeca6 |
+
|
|
|
beeca6 |
+ int some_global = 27;
|