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;