This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [rfa] teach parser about C++ nested types


On Thu, 25 Sep 2003 09:02:51 -0700, David Carlton <carlton@kealia.com> said:
> On Thu, 25 Sep 2003 11:49:01 -0400, Daniel Jacobowitz <drow@mvista.com> said:

>> With the style corrections and another big fat comment in the parser
>> about why the reduce/reduce conflict is almost OK, this is approved.

> Thanks!  Geez, now I'll feel guilty if I don't generate my next patch
> quickly. :-)

It's in.  Big fat comment is right: if you see a 40-line comment
before a rule in your parser, you know something is wrong somewhere...

David Carlton
carlton@kealia.com

2003-09-25  David Carlton  <carlton@kealia.com>

	* c-exp.y: Include cp-support.h.  Add qualified_type.
	(yylex): Delete nested type hack; add comments.
	* cp-namespace.c (cp_lookup_nested_type): New function.
	* cp-support.h: Declare cp_lookup_nested_type.
	* eval.c (evaluate_subexp_standard): Call value_aggregate_elt
	instead of value_struct_elt_for_reference.
	* valops.c: Include cp-support.h.
	(value_aggregate_elt): New function.
	(value_namespace_elt): Ditto.
	(value_struct_elt_for_reference): Make static.
	* value.h: Delete declaration of value_struct_elt_for_reference;
	add declaration for value_aggregate_elt.
	* Makefile.in (c-exp.tab.o): Depend on $(cp_support_h).
	(valops.o): Ditto.

2003-09-25  David Carlton  <carlton@kealia.com>

	* gdb.cp/namespace.exp: Tweak comments.  Add non-quoted versions
	of some print tests, where appropriate.  Add tests for C::D::cd,
	E::ce, F::cXfX, G::XgX.
	* gdb.cp/namespace.cc: Add XgX, cXfX, ce.

Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.447
diff -u -p -r1.447 Makefile.in
--- Makefile.in	25 Sep 2003 09:10:29 -0000	1.447
+++ Makefile.in	25 Sep 2003 16:30:13 -0000
@@ -1412,7 +1412,7 @@ ada-lex.c: ada-lex.l
 .PRECIOUS: c-exp.tab.c
 c-exp.tab.o: c-exp.tab.c $(defs_h) $(gdb_string_h) $(expression_h) \
 	$(value_h) $(parser_defs_h) $(language_h) $(c_lang_h) $(bfd_h) \
-	$(symfile_h) $(objfiles_h) $(charset_h) $(block_h)
+	$(symfile_h) $(objfiles_h) $(charset_h) $(block_h) $(cp_support_h)
 c-exp.tab.c: c-exp.y
 	$(SHELL) $(YLWRAP) "$(YACC)" \
 	    $(srcdir)/c-exp.y  y.tab.c c-exp.tmp -- $(YFLAGS) 
@@ -2418,7 +2418,8 @@ valarith.o: valarith.c $(defs_h) $(value
 valops.o: valops.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(value_h) $(frame_h) \
 	$(inferior_h) $(gdbcore_h) $(target_h) $(demangle_h) $(language_h) \
 	$(gdbcmd_h) $(regcache_h) $(cp_abi_h) $(block_h) $(infcall_h) \
-	$(dictionary_h) $(cp_support_h) $(gdb_string_h) $(gdb_assert_h)
+	$(dictionary_h) $(cp_support_h) $(gdb_string_h) $(gdb_assert_h) \
+	$(cp_support_h)
 valprint.o: valprint.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
 	$(value_h) $(gdbcore_h) $(gdbcmd_h) $(target_h) $(language_h) \
 	$(annotate_h) $(valprint_h) $(floatformat_h) $(doublest_h)
Index: c-exp.y
===================================================================
RCS file: /cvs/src/src/gdb/c-exp.y,v
retrieving revision 1.21
diff -u -p -r1.21 c-exp.y
--- c-exp.y	18 May 2003 17:39:45 -0000	1.21
+++ c-exp.y	25 Sep 2003 16:30:13 -0000
@@ -51,6 +51,7 @@ Foundation, Inc., 59 Temple Place - Suit
 #include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
 #include "charset.h"
 #include "block.h"
+#include "cp-support.h"
 
 /* Flag indicating we're dealing with HP-compiled objects */ 
 extern int hp_som_som_object_present;
@@ -153,7 +154,7 @@ static int parse_number (char *, int, in
 
 %type <voidval> exp exp1 type_exp start variable qualified_name lcurly
 %type <lval> rcurly
-%type <tval> type typebase
+%type <tval> type typebase qualified_type
 %type <tvec> nonempty_typelist
 /* %type <bval> block */
 
@@ -595,7 +596,8 @@ qualified_name:	typebase COLONCOLON name
 			{
 			  struct type *type = $1;
 			  if (TYPE_CODE (type) != TYPE_CODE_STRUCT
-			      && TYPE_CODE (type) != TYPE_CODE_UNION)
+			      && TYPE_CODE (type) != TYPE_CODE_UNION
+			      && TYPE_CODE (type) != TYPE_CODE_NAMESPACE)
 			    error ("`%s' is not defined as an aggregate type.",
 				   TYPE_NAME (type));
 
@@ -609,7 +611,8 @@ qualified_name:	typebase COLONCOLON name
 			  struct type *type = $1;
 			  struct stoken tmp_token;
 			  if (TYPE_CODE (type) != TYPE_CODE_STRUCT
-			      && TYPE_CODE (type) != TYPE_CODE_UNION)
+			      && TYPE_CODE (type) != TYPE_CODE_UNION
+			      && TYPE_CODE (type) != TYPE_CODE_NAMESPACE)
 			    error ("`%s' is not defined as an aggregate type.",
 				   TYPE_NAME (type));
 
@@ -888,6 +891,80 @@ typebase  /* Implements (approximately):
 			{ $$ = follow_types ($2); }
 	| typebase const_or_volatile_or_space_identifier_noopt 
 			{ $$ = follow_types ($1); }
+	| qualified_type
+	;
+
+/* FIXME: carlton/2003-09-25: This next bit leads to lots of
+   reduce-reduce conflicts, because the parser doesn't know whether or
+   not to use qualified_name or qualified_type: the rules are
+   identical.  If the parser is parsing 'A::B::x', then, when it sees
+   the second '::', it knows that the expression to the left of it has
+   to be a type, so it uses qualified_type.  But if it is parsing just
+   'A::B', then it doesn't have any way of knowing which rule to use,
+   so there's a reduce-reduce conflict; it picks qualified_name, since
+   that occurs earlier in this file than qualified_type.
+
+   There's no good way to fix this with the grammar as it stands; as
+   far as I can tell, some of the problems arise from ambiguities that
+   GDB introduces ('start' can be either an expression or a type), but
+   some of it is inherent to the nature of C++ (you want to treat the
+   input "(FOO)" fairly differently depending on whether FOO is an
+   expression or a type, and if FOO is a complex expression, this can
+   be hard to determine at the right time).  Fortunately, it works
+   pretty well in most cases.  For example, if you do 'ptype A::B',
+   where A::B is a nested type, then the parser will mistakenly
+   misidentify it as an expression; but evaluate_subexp will get
+   called with 'noside' set to EVAL_AVOID_SIDE_EFFECTS, and everything
+   will work out anyways.  But there are situations where the parser
+   will get confused: the most common one that I've run into is when
+   you want to do
+
+     print *((A::B *) x)"
+
+   where the parser doesn't realize that A::B has to be a type until
+   it hits the first right paren, at which point it's too late.  (The
+   workaround is to type "print *(('A::B' *) x)" instead.)  (And
+   another solution is to fix our symbol-handling code so that the
+   user never wants to type something like that in the first place,
+   because we get all the types right without the user's help!)
+
+   Perhaps we could fix this by making the lexer smarter.  Some of
+   this functionality used to be in the lexer, but in a way that
+   worked even less well than the current solution: that attempt
+   involved having the parser sometimes handle '::' and having the
+   lexer sometimes handle it, and without a clear division of
+   responsibility, it quickly degenerated into a big mess.  Probably
+   the eventual correct solution will give more of a role to the lexer
+   (ideally via code that is shared between the lexer and
+   decode_line_1), but I'm not holding my breath waiting for somebody
+   to get around to cleaning this up...  */
+
+/* FIXME: carlton/2003-09-25: Currently, the only qualified type
+   symbols that we generate are nested namespaces.  Next on my TODO
+   list is to generate all nested type names properly (or at least as
+   well as possible, assuming that we're using DWARF-2).  */
+
+qualified_type: typebase COLONCOLON name
+		{
+		  struct type *type = $1;
+		  struct type *new_type;
+		  char *ncopy = alloca ($3.length + 1);
+
+		  memcpy (ncopy, $3.ptr, $3.length);
+		  ncopy[$3.length] = '\0';
+
+		  if (TYPE_CODE (type) != TYPE_CODE_NAMESPACE)
+		    error ("`%s' is not defined as a namespace.",
+			   TYPE_NAME (type));
+
+		  new_type = cp_lookup_nested_type (type, ncopy,
+						    expression_context_block);
+		  if (new_type == NULL)
+		    error ("No type \"%s\" in namespace \"%s\".",
+			   ncopy, TYPE_NAME (type));
+		  
+		  $$ = new_type;
+		}
 	;
 
 typename:	TYPENAME
@@ -1633,7 +1710,13 @@ yylex ()
      string to get a reasonable class/namespace spec or a
      fully-qualified name.  This is a kludge to get around the
      HP aCC compiler's generation of symbol names with embedded
-     colons for namespace and nested classes. */ 
+     colons for namespace and nested classes. */
+
+  /* NOTE: carlton/2003-09-24: I don't entirely understand the
+     HP-specific code, either here or in linespec.  Having said that,
+     I suspect that we're actually moving towards their model: we want
+     symbols whose names are fully qualified, which matches the
+     description above.  */
   if (unquoted_expr)
     {
       /* Only do it if not inside single quotes */ 
@@ -1687,92 +1770,10 @@ yylex ()
 
     if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
         {
-#if 1
-	  /* Despite the following flaw, we need to keep this code enabled.
-	     Because we can get called from check_stub_method, if we don't
-	     handle nested types then it screws many operations in any
-	     program which uses nested types.  */
-	  /* In "A::x", if x is a member function of A and there happens
-	     to be a type (nested or not, since the stabs don't make that
-	     distinction) named x, then this code incorrectly thinks we
-	     are dealing with nested types rather than a member function.  */
-
-	  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 *ncopy = alloca (strlen (tmp)+strlen (namestart)+3);
-		      char *tmp1;
-
-		      tmp1 = ncopy;
-		      memcpy (tmp1, tmp, strlen (tmp));
-		      tmp1 += strlen (tmp);
-		      memcpy (tmp1, "::", 2);
-		      tmp1 += 2;
-		      memcpy (tmp1, namestart, p - namestart);
-		      tmp1[p - namestart] = '\0';
-		      cur_sym = lookup_symbol (ncopy, expression_context_block,
-					       VAR_DOMAIN, (int *) NULL,
-					       (struct symtab **) 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);
-#else /* not 0 */
+	  /* NOTE: carlton/2003-09-25: There used to be code here to
+	     handle nested types.  It didn't work very well.  See the
+	     comment before qualified_type for more info.  */
 	  yylval.tsym.type = SYMBOL_TYPE (sym);
-#endif /* not 0 */
 	  return TYPENAME;
         }
     if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0)
Index: cp-namespace.c
===================================================================
RCS file: /cvs/src/src/gdb/cp-namespace.c,v
retrieving revision 1.4
diff -u -p -r1.4 cp-namespace.c
--- cp-namespace.c	11 Sep 2003 19:49:17 -0000	1.4
+++ cp-namespace.c	25 Sep 2003 16:30:13 -0000
@@ -508,6 +508,41 @@ lookup_symbol_file (const char *name,
   return NULL;
 }
 
+/* Look up a type named NESTED_NAME that is nested inside the C++
+   class or namespace given by PARENT_TYPE, from within the context
+   given by BLOCK.  Return NULL if there is no such nested type.  */
+
+/* FIXME: carlton/2003-09-24: For now, this only works for nested
+   namespaces; the patch to make this work on other sorts of nested
+   types is next on my TODO list.  */
+
+struct type *
+cp_lookup_nested_type (struct type *parent_type,
+		       const char *nested_name,
+		       const struct block *block)
+{
+  switch (TYPE_CODE (parent_type))
+    {
+    case TYPE_CODE_NAMESPACE:
+      {
+	const char *parent_name = TYPE_TAG_NAME (parent_type);
+	struct symbol *sym = cp_lookup_symbol_namespace (parent_name,
+							 nested_name,
+							 NULL,
+							 block,
+							 VAR_DOMAIN,
+							 NULL);
+	if (sym == NULL || SYMBOL_CLASS (sym) != LOC_TYPEDEF)
+	  return NULL;
+	else
+	  return SYMBOL_TYPE (sym);
+      }
+    default:
+      internal_error (__FILE__, __LINE__,
+		      "cp_lookup_nested_type called on a non-namespace.");
+    }
+}
+
 /* Now come functions for dealing with symbols associated to
    namespaces.  (They're used to store the namespaces themselves, not
    objects that live in the namespaces.)  These symbols come in two
Index: cp-support.h
===================================================================
RCS file: /cvs/src/src/gdb/cp-support.h,v
retrieving revision 1.8
diff -u -p -r1.8 cp-support.h
--- cp-support.h	14 Sep 2003 02:04:44 -0000	1.8
+++ cp-support.h	25 Sep 2003 16:30:13 -0000
@@ -97,6 +97,10 @@ extern struct symbol *cp_lookup_symbol_n
 						  const domain_enum domain,
 						  struct symtab **symtab);
 
+extern struct type *cp_lookup_nested_type (struct type *parent_type,
+					   const char *nested_name,
+					   const struct block *block);
+
 extern void cp_check_possible_namespace_symbols (const char *name,
 						 struct objfile *objfile);
 
Index: eval.c
===================================================================
RCS file: /cvs/src/src/gdb/eval.c,v
retrieving revision 1.37
diff -u -p -r1.37 eval.c
--- eval.c	25 Sep 2003 08:40:45 -0000	1.37
+++ eval.c	25 Sep 2003 16:30:14 -0000
@@ -408,11 +408,9 @@ evaluate_subexp_standard (struct type *e
     case OP_SCOPE:
       tem = longest_to_int (exp->elts[pc + 2].longconst);
       (*pos) += 4 + BYTES_TO_EXP_ELEM (tem + 1);
-      arg1 = value_struct_elt_for_reference (exp->elts[pc + 1].type,
-					     0,
-					     exp->elts[pc + 1].type,
-					     &exp->elts[pc + 3].string,
-					     NULL_TYPE);
+      arg1 = value_aggregate_elt (exp->elts[pc + 1].type,
+				  &exp->elts[pc + 3].string,
+				  noside);
       if (arg1 == NULL)
 	error ("There is no field named %s", &exp->elts[pc + 3].string);
       return arg1;
Index: valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.115
diff -u -p -r1.115 valops.c
--- valops.c	16 Sep 2003 18:56:35 -0000	1.115
+++ valops.c	25 Sep 2003 16:30:14 -0000
@@ -41,6 +41,7 @@
 #include <errno.h>
 #include "gdb_string.h"
 #include "gdb_assert.h"
+#include "cp-support.h"
 
 /* Flag indicating HP compilers were used; needed to correctly handle some
    value operations with HP aCC code/runtime. */
@@ -63,6 +64,17 @@ static struct value *search_struct_metho
 
 static int check_field_in (struct type *, const char *);
 
+
+static struct value *value_struct_elt_for_reference (struct type *domain,
+						     int offset,
+						     struct type *curtype,
+						     char *name,
+						     struct type *intype);
+
+static struct value *value_namespace_elt (const struct type *curtype,
+					  const char *name,
+					  enum noside noside);
+
 static CORE_ADDR allocate_space_in_inferior (int);
 
 static struct value *cast_into_complex (struct type *, struct value *);
@@ -2208,6 +2220,30 @@ check_field (struct value *arg1, const c
 }
 
 /* C++: Given an aggregate type CURTYPE, and a member name NAME,
+   return the appropriate member.  This function is used to resolve
+   user expressions of the form "DOMAIN::NAME".  For more details on
+   what happens, see the comment before
+   value_struct_elt_for_reference.  */
+
+struct value *
+value_aggregate_elt (struct type *curtype,
+		     char *name,
+		     enum noside noside)
+{
+  switch (TYPE_CODE (curtype))
+    {
+    case TYPE_CODE_STRUCT:
+    case TYPE_CODE_UNION:
+      return value_struct_elt_for_reference (curtype, 0, curtype, name, NULL);
+    case TYPE_CODE_NAMESPACE:
+      return value_namespace_elt (curtype, name, noside);
+    default:
+      internal_error (__FILE__, __LINE__,
+		      "non-aggregate type in value_aggregate_elt");
+    }
+}
+
+/* C++: Given an aggregate type CURTYPE, and a member name NAME,
    return the address of this member as a "pointer to member"
    type.  If INTYPE is non-null, then it will be the type
    of the member we are looking for.  This will help us resolve
@@ -2345,6 +2381,37 @@ value_struct_elt_for_reference (struct t
 	return v;
     }
   return 0;
+}
+
+/* C++: Return the member NAME of the namespace given by the type
+   CURTYPE.  */
+
+static struct value *
+value_namespace_elt (const struct type *curtype,
+		     const char *name,
+		     enum noside noside)
+{
+  const char *namespace_name = TYPE_TAG_NAME (curtype);
+  struct symbol *sym;
+  struct value *retval;
+
+  sym = cp_lookup_symbol_namespace (namespace_name, name, NULL,
+				    get_selected_block (0), VAR_DOMAIN,
+				    NULL);
+
+  if (sym == NULL)
+    retval = NULL;
+  else if ((noside == EVAL_AVOID_SIDE_EFFECTS)
+	   && (SYMBOL_CLASS (sym) == LOC_TYPEDEF))
+    retval = allocate_value (SYMBOL_TYPE (sym));
+  else
+    retval = value_of_variable (sym, get_selected_block (0));
+
+  if (retval == NULL)
+    error ("No symbol \"%s\" in namespace \"%s\".", name,
+	   TYPE_TAG_NAME (curtype));
+
+  return retval;
 }
 
 
Index: value.h
===================================================================
RCS file: /cvs/src/src/gdb/value.h,v
retrieving revision 1.51
diff -u -p -r1.51 value.h
--- value.h	13 Sep 2003 21:31:33 -0000	1.51
+++ value.h	25 Sep 2003 16:30:14 -0000
@@ -379,11 +379,9 @@ extern struct value *value_struct_elt (s
 				       char *name, int *static_memfuncp,
 				       char *err);
 
-extern struct value *value_struct_elt_for_reference (struct type *domain,
-						     int offset,
-						     struct type *curtype,
-						     char *name,
-						     struct type *intype);
+extern struct value *value_aggregate_elt (struct type *curtype,
+					  char *name,
+					  enum noside noside);
 
 extern struct value *value_static_field (struct type *type, int fieldno);
 
Index: testsuite/gdb.cp/namespace.cc
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/namespace.cc,v
retrieving revision 1.1
diff -u -p -r1.1 namespace.cc
--- testsuite/gdb.cp/namespace.cc	23 Aug 2003 03:55:59 -0000	1.1
+++ testsuite/gdb.cp/namespace.cc	25 Sep 2003 16:30:14 -0000
@@ -75,6 +75,11 @@ namespace
   namespace G
   {
     int Xg = 10;
+
+    namespace
+    {
+      int XgX = 11;
+    }
   }
 }
 
@@ -90,6 +95,11 @@ namespace C
     namespace F
     {
       int cXf = 7;
+
+      namespace
+      {
+	int cXfX = 8;
+      }
     }
   }
 
@@ -98,6 +108,11 @@ namespace C
     int cc = 2;
   }
 
+  namespace E
+  {
+    int ce = 4;
+  }
+
   namespace D
   {
     int cd = 3;
@@ -118,14 +133,18 @@ namespace C
       //cc;
       C::cc;
       cd;
+      //C::D::cd;
       E::cde;
       shadow;
+      //E::ce;
       cX;
       F::cXf;
+      F::cXfX;
       X;
       G::Xg;
       //cXOtherFile;
       //XOtherFile;
+      G::XgX;
 
       return;
     }
Index: testsuite/gdb.cp/namespace.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/namespace.exp,v
retrieving revision 1.2
diff -u -p -r1.2 namespace.exp
--- testsuite/gdb.cp/namespace.exp	11 Sep 2003 19:49:20 -0000	1.2
+++ testsuite/gdb.cp/namespace.exp	25 Sep 2003 16:30:14 -0000
@@ -18,11 +18,11 @@
 # bug-gdb@prep.ai.mit.edu
 
 # tests for namespaces
-# Written by Satish Pai <pai@apollo.hp.com> 1997-07-23
+# Originally written by Satish Pai <pai@apollo.hp.com> 1997-07-23
 
 # This file is part of the gdb testsuite
 
-# Note: These tests are geared to the HP aCC compiler,
+# Note: The original tests were geared to the HP aCC compiler,
 # which has an idiosyncratic way of emitting debug info
 # for namespaces.
 # Note: As of 2000-06-03, these pass under g++ - djb
@@ -84,6 +84,11 @@ gdb_test "up" ".*main.*" "up from marker
 # Access a data item inside a namespace using colons and
 # single quotes :-(
 
+# NOTE: carlton/2003-09-24: the quotes are becoming less necessary (or
+# even desirable.)  For tests where it should still work with quotes,
+# I'm including versions both with and without quotes; for tests that
+# shouldn't work with quotes, I'm only including one version.
+
 send_gdb "print 'AAA::c'\n"
 gdb_expect {
    -re "\\$\[0-9\]* = 0 '\\\\(0|000)'\r\n$gdb_prompt $" { pass "print 'AAA::c'" }
@@ -91,6 +96,13 @@ gdb_expect {
    timeout { fail "(timeout) print 'AAA::c'" }
 }
 
+send_gdb "print AAA::c\n"
+gdb_expect {
+   -re "\\$\[0-9\]* = 0 '\\\\(0|000)'\r\n$gdb_prompt $" { pass "print AAA::c" }
+   -re ".*$gdb_prompt $" { fail "print AAA::c" }
+   timeout { fail "(timeout) print AAA::c" }
+}
+
 # An object declared using "using".
 
 send_gdb "print ina\n"
@@ -137,6 +149,15 @@ gdb_expect {
    timeout { fail "(timeout) print 'AAA::xyzq'('x')" }
 }
        
+send_gdb "print AAA::xyzq('x')\n"
+gdb_expect {
+   -re "\\$\[0-9\]* = 97 'a'\r\n$gdb_prompt $" {
+       pass "print AAA::xyzq('x')"
+   }
+   -re ".*$gdb_prompt $" { fail "print AAA::xyzq('x')" }
+   timeout { fail "(timeout) print AAA::xyzq('x')" }
+}
+       
 # Break on a function in a namespace
 
 send_gdb "break AAA::xyzq\n"
@@ -159,6 +180,15 @@ gdb_expect {
    timeout { fail "(timeout) print 'BBB::CCC::xyzq'('x')" }
 }
        
+send_gdb "print BBB::CCC::xyzq('x')\n"
+gdb_expect {
+   -re "\\$\[0-9\]* = 122 'z'\r\n$gdb_prompt $" {
+       pass "print BBB::CCC::xyzq('x')"
+   }
+   -re ".*$gdb_prompt $" { fail "print BBB::CCC::xyzq('x')" }
+   timeout { fail "(timeout) print BBB::CCC::xyzq('x')" }
+}
+       
 # Break on a function in a nested namespace
 
 send_gdb "break BBB::CCC::xyzq\n"
@@ -204,9 +234,13 @@ if ![runto "C::D::marker2"] then {
 gdb_test "print c" "\\$\[0-9\].* = 1"
 gdb_test "print cc" "No symbol \"cc\" in current context."
 gdb_test "print 'C::cc'" "\\$\[0-9\].* = 2"
+gdb_test "print C::cc" "\\$\[0-9\].* = 2"
 gdb_test "print cd" "\\$\[0-9\].* = 3"
+gdb_test "print C::D::cd" "No type \"D\" in namespace \"C::C\"."
 gdb_test "print 'E::cde'" "\\$\[0-9\].* = 5"
+gdb_test "print E::cde" "\\$\[0-9\].* = 5"
 gdb_test "print shadow" "\\$\[0-9\].* = 13"
+gdb_test "print E::ce" "No symbol \"ce\" in namespace \"C::D::E\"."
 gdb_test "print cOtherFile" "\\$\[0-9\].* = 316"
 gdb_test "ptype C" "type = namespace C::C"
 gdb_test "ptype E" "type = namespace C::D::E"
@@ -215,7 +249,11 @@ gdb_test "ptype E" "type = namespace C::
 
 gdb_test "print cX" "\\$\[0-9\].* = 6"
 gdb_test "print 'F::cXf'" "\\$\[0-9\].* = 7"
+gdb_test "print F::cXf" "\\$\[0-9\].* = 7"
+gdb_test "print F::cXfX" "\\$\[0-9\].* = 8"
 gdb_test "print X" "\\$\[0-9\].* = 9"
 gdb_test "print 'G::Xg'" "\\$\[0-9\].* = 10"
+gdb_test "print G::Xg" "\\$\[0-9\].* = 10"
+gdb_test "print G::XgX" "\\$\[0-9\].* = 11"
 gdb_test "print cXOtherFile" "No symbol \"cXOtherFile\" in current context."
 gdb_test "print XOtherFile" "No symbol \"XOtherFile\" in current context."


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]