This is the mail archive of the archer@sourceware.org mailing list for the Archer 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: [RFC] Koenig lookup patch 3



Sami> +exp	:	adl_func '('
Sami> +adl_func	:	UNKNOWN_NAME

It seems like these additions would introduce a parser ambiguity,
because UNKNOWN_NAME could be parsed as adl_func or as name_not_typename
(and hence variable).

Is bison silent about this?


Good point. Same goes for everything that is common between name and name_no_typename. Anyways I have changed this to:


exp : UNKOWN_NAME '('

Sami> +static void make_symbol_overload_list_namespace (const char *func_name,
Sami> +                                                 const char *namespace);
Sami> +
Sami> +static void make_symbol_overload_list_adl_namespace (struct type *type,
Sami> +                                                     const char *func_name);

GDB does this all over, but in new code we're now preferring that
functions be ordered so that prototypes aren't necessary for static
functions.  This is a bit simpler to maintain.


Done.


Sami> +    case OP_ADL_FUNC:
Sami>      case OP_VAR_VALUE:

I don't understand the placement of the new case here.
How do we ever end up in the new code here, which seems to be in the
OP_FUNCALL case?


After we have used find_overload_match to find a symbol for the function. we call evaluate_subexp_with_coercion here:


/* Now fix the expression being evaluated */
exp->elts[save_pos1+2].symbol = symp;
argvec[0] = evaluate_subexp_with_coercion (exp, &save_pos1, noside);

Sami> +  /* Check public base type */
Sami> +  if (TYPE_CODE(type) == TYPE_CODE_CLASS)
Sami> +    for (i = 0; i < TYPE_N_BASECLASSES (type); i++)
Sami> +      {
Sami> +        if(BASETYPE_VIA_PUBLIC (type, i))

Why the check for public?


I have not seen anything in the spec to require this. But it seems to be the case in gcc that the inheritance must be public for the parent class(s) to be added to the associated classes set.


Sami> + func_name = (char*) alloca (name_len+1);

Spaces around "+". I think I saw this in more than one place.


Sami> + find_overload_match (arg_types, nargs, func_name, Sami> + 0 /* not method */ , 0 /* strict match */ , Sami> + NULL, NULL /* pass NULL symbol to signal ADL lookup */ ,

If this is a new convention for the find_overload_match argument, then
it ought to be documented in that function's introductory comment.


That is an outdated comment. In the current code functions found through adl are just added overload set whether symbol is null or otherwise.


Sami> @@ -2108,12 +2108,25 @@ find_overload_match (struct type **arg_types, int nargs,
Sami> +              old_cleanups = make_cleanup (xfree, func_name);
Sami> -      old_cleanups = make_cleanup (xfree, func_name);
Sami>        make_cleanup (xfree, oload_syms);
Sami>        make_cleanup (xfree, oload_champ_bv);

I think the cleanup logic here is wrong now.
It seems like the code can make a cleanup but still have old_cleanups==NULL.
This will leave dangling cleanups; the usual rule (for functions not
return a cleanup or making one as a side effect) is that local cleanups
must always be run before function exit.

One way to do this would be to initialize old_cleanups as a null cleanup
early on.  Then, never set it elsewhere in the function, and change the
do_cleanups call at the end to be unconditional.  This is a typical
idiom elsewhere in gdb.


Gotcha! Done.


... I think there should probably be some
tests for nested namespaces.

Is this what you mean ?


+namespace L {
+  namespace A{
+    namespace B{
+    class O {};
+
+    int foo (O){
+      return 17;
+    }
+
+    }
+  }
+}
+
...
+#test lookup of objects belonging to nested namespaces
+gdb_test "p foo(labo)" "= 17"

The other is that it would be nice to be
assured that each supported case has a corresponding test;

That's the intention, but if I have missed cases let me know as you have done last time :)

tests for things like overload resolution picking the best match both
when the best match is found via ADL and when it is not.


How is this:


+namespace K{
+  class O{};
+
+  int foo(O, int){
+    return 15;
+  }
+}
+
+int foo(K::O, float){
+  return 16;
+}

...

+#test overload resolution
+gdb_test "p foo(ko,1)" "= 15"
+gdb_test "p foo(ko,1.0f)" "= 16"

The ambiguous case fails but I think that is the case even outside of Koenig.


Here is the latest patch:


2009-11-02 Sami Wagiaalla <swagiaal@redhat.com>

	* cp-support.c (make_symbol_overload_list_namespace): New function.
	(make_symbol_overload_list_using): Moved namespace checking code to
	make_symbol_overload_list_namespace.
	(make_symbol_overload_list_adl): New function.
	* parse.c (operator_length_standard): Added length information for
	OP_ADL_FUNC.
	* expression.h: Added OP_ADL_FUNC.
	* c-exp.y: Created token UNKOWN_NAME.
	Created grammar rules for UNKOWN_NAME.
	* eval.c (evaluate_subexp_standard): Added handling for for OP_ADL_FUNC.

2009-11-02 Sami Wagiaalla <swagiaal@redhat.com>

	* gdb.cp/namespace-koenig.exp: New test.
	* gdb.cp/namespace-koenig.cc: New test file.

diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 5123042..80e09d4 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -184,6 +184,7 @@ static int parse_number (char *, int, int, YYSTYPE *);

%token <sval> STRING
%token <ssym> NAME /* BLOCKNAME defined below to give it higher precedence. */
+%token <ssym> UNKNOWN_NAME
%token <voidval> COMPLETE
%token <tsym> TYPENAME
%type <sval> name string_exp
@@ -384,6 +385,30 @@ exp	:	exp '('
			  write_exp_elt_opcode (OP_FUNCALL); }
	;

+exp	:	UNKNOWN_NAME '('
+			{
+
+			 /* This could potentially be a an argument defined
+			    lookup function (Koenig).  */
+			  write_exp_elt_opcode (OP_ADL_FUNC);
+			  write_exp_elt_block (expression_context_block);
+			  write_exp_elt_sym (NULL); /* Place holder */
+			  write_exp_string ($1.stoken);
+			  write_exp_elt_opcode (OP_ADL_FUNC);
+
+			/* This is to save the value of arglist_len
+			   being accumulated by an outer function call.  */
+
+			  start_arglist ();
+			}
+		arglist ')'	%prec ARROW
+			{
+			  write_exp_elt_opcode (OP_FUNCALL);
+			  write_exp_elt_longcst ((LONGEST) end_arglist ());
+			  write_exp_elt_opcode (OP_FUNCALL);
+			}
+	;
+
lcurly	:	'{'
			{ start_arglist (); }
	;
@@ -795,7 +820,7 @@ variable:	name_not_typename
			}
	;

-space_identifier : '@' NAME
+space_identifier : '@' UNKNOWN_NAME
		{ push_type_address_space (copy_name ($2.stoken));
		  push_type (tp_space_identifier);
		}
@@ -1091,10 +1116,12 @@ name	:	NAME { $$ = $1.stoken; }
	|	BLOCKNAME { $$ = $1.stoken; }
	|	TYPENAME { $$ = $1.stoken; }
	|	NAME_OR_INT  { $$ = $1.stoken; }
+	|	UNKNOWN_NAME  { $$ = $1.stoken; }
	;

name_not_typename : NAME
| BLOCKNAME
+ | UNKNOWN_NAME
/* These would be useful if name_not_typename was useful, but it is just
a fake for "variable", so these cause reduce/reduce conflicts because
the parser can't tell whether NAME_OR_INT is a name_not_typename (=variable,
@@ -2016,6 +2043,9 @@ yylex ()
if (in_parse_field && *lexptr == '\0')
saw_name_at_eof = 1;
+ if (sym == NULL && !lookup_minimal_symbol (tmp, NULL, NULL))
+ return UNKNOWN_NAME;
+
return NAME;
}
}
diff --git a/gdb/cp-support.c b/gdb/cp-support.c
index bf42636..b95a450 100644
--- a/gdb/cp-support.c
+++ b/gdb/cp-support.c
@@ -47,7 +47,7 @@ static void demangled_name_complaint (const char *name);


/* Functions/variables related to overload resolution. */

-static int sym_return_val_size;
+static int sym_return_val_size = -1;
static int sym_return_val_index;
static struct symbol **sym_return_val;

@@ -696,6 +696,82 @@ make_symbol_overload_list (const char *func_name,

  return sym_return_val;
}
+/* Adds the function FUNC_NAME from NAMESPACE to the overload set.  */
+
+static void
+make_symbol_overload_list_namespace (const char *func_name,
+                                     const char *namespace)
+{
+
+  if (namespace[0] == '\0')
+    {
+      make_symbol_overload_list_qualified (func_name);
+    }
+  else
+    {
+      char *concatenated_name
+	= alloca (strlen (namespace) + 2 + strlen (func_name) + 1);
+      strcpy (concatenated_name, namespace);
+      strcat (concatenated_name, "::");
+      strcat (concatenated_name, func_name);
+      make_symbol_overload_list_qualified (concatenated_name);
+    }
+}
+
+/* Search the namespace of the given type and namespace of and public base
+ types.  */
+static void make_symbol_overload_list_adl_namespace (struct type *type,
+						     const char *func_name)
+{
+  char *namespace;
+  char *type_name;
+  int i, prefix_len;
+
+  if (TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_CODE (type) == TYPE_CODE_REF
+      || TYPE_CODE (type) == TYPE_CODE_ARRAY)
+    return make_symbol_overload_list_adl_namespace (TYPE_TARGET_TYPE (type),
+                                                    func_name);
+
+  type_name = TYPE_NAME (type);
+
+  prefix_len = cp_entire_prefix_len (type_name);
+
+  if (prefix_len != 0)
+    {
+      namespace = alloca (prefix_len + 1);
+      strncpy (namespace, type_name, prefix_len);
+      namespace[prefix_len] = '\0';
+
+      make_symbol_overload_list_namespace (func_name, namespace);
+    }
+
+  /* Check public base type */
+  if (TYPE_CODE(type) == TYPE_CODE_CLASS)
+    for (i = 0; i < TYPE_N_BASECLASSES (type); i++)
+      {
+	if (BASETYPE_VIA_PUBLIC (type, i))
+	  make_symbol_overload_list_adl_namespace (TYPE_BASECLASS (type, i),
+						   func_name);
+      }
+
+}
+
+/* Adds the the overload list overload candidates for FUNC_NAME found through
+   argument dependent lookup.  */
+
+struct symbol **
+make_symbol_overload_list_adl (struct type **arg_types, int nargs,
+                               const char *func_name)
+{
+  int i;
+
+  gdb_assert (sym_return_val_size != -1);
+
+  for (i = 1; i <= nargs; i++)
+    make_symbol_overload_list_adl_namespace (arg_types[i - 1], func_name);
+
+  return sym_return_val;
+}

/* This applies the using directives to add namespaces to search in,
   and then searches for overloads in all of those namespaces.  It
@@ -724,20 +800,7 @@ make_symbol_overload_list_using (const char *func_name,
    }

/* Now, add names for this namespace. */
- - if (namespace[0] == '\0')
- {
- make_symbol_overload_list_qualified (func_name);
- }
- else
- {
- char *concatenated_name
- = alloca (strlen (namespace) + 2 + strlen (func_name) + 1);
- strcpy (concatenated_name, namespace);
- strcat (concatenated_name, "::");
- strcat (concatenated_name, func_name);
- make_symbol_overload_list_qualified (concatenated_name);
- }
+ make_symbol_overload_list_namespace (func_name, namespace);
}


/* This does the bulk of the work of finding overloaded symbols.
diff --git a/gdb/cp-support.h b/gdb/cp-support.h
index 4ce85b5..0e4a378 100644
--- a/gdb/cp-support.h
+++ b/gdb/cp-support.h
@@ -84,6 +84,10 @@ extern char *cp_remove_params (const char *demangled_name);
extern struct symbol **make_symbol_overload_list (const char *,
						  const char *);

+extern struct symbol **make_symbol_overload_list_adl (struct type **arg_types,
+                                                      int nargs,
+                                                      const char *func_name);
+
extern struct type *cp_lookup_rtti_type (const char *name,
					 struct block *block);

diff --git a/gdb/eval.c b/gdb/eval.c
index 1d35571..8566414 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -704,6 +704,7 @@ evaluate_subexp_standard (struct type *expect_type,
      return value_from_decfloat (exp->elts[pc + 1].type,
				  exp->elts[pc + 2].decfloatconst);

+    case OP_ADL_FUNC:
    case OP_VAR_VALUE:
      (*pos) += 3;
      if (noside == EVAL_SKIP)
@@ -1362,6 +1363,17 @@ evaluate_subexp_standard (struct type *expect_type,
	  /* Now, say which argument to start evaluating from */
	  tem = 2;
	}
+      else if (op == OP_ADL_FUNC)
+        {
+          /* Save the function position and move pos so that the arguments
+             can be evaluated. */
+          int func_name_len;
+          save_pos1 = *pos;
+          tem = 1;
+
+          func_name_len = longest_to_int (exp->elts[save_pos1 + 3].longconst);
+          (*pos) += 6 + BYTES_TO_EXP_ELEM (func_name_len + 1);
+        }
      else
	{
	  /* Non-method function call */
@@ -1393,6 +1405,33 @@ evaluate_subexp_standard (struct type *expect_type,
      /* signal end of arglist */
      argvec[tem] = 0;

+      if (op == OP_ADL_FUNC)
+        {
+          struct symbol *symp;
+          char *func_name;
+          int  name_len;
+          int string_pc = save_pos1 + 3;
+
+          /* Extract the function name.  */
+          name_len = longest_to_int (exp->elts[string_pc].longconst);
+          func_name = (char *) alloca (name_len + 1);
+          strcpy (func_name, &exp->elts[string_pc + 1].string);
+
+          /* Prepare list of argument types for overload resolution */
+          arg_types = (struct type **) alloca (nargs * (sizeof (struct type *)));
+          for (ix = 1; ix <= nargs; ix++)
+            arg_types[ix - 1] = value_type (argvec[ix]);
+
+          find_overload_match (arg_types, nargs, func_name,
+                               0 /* not method */ , 0 /* strict match */ ,
+                               NULL, NULL /* pass NULL symbol since symbol is unknown */ ,
+                               NULL, &symp, NULL);
+
+          /* Now fix the expression being evaluated */
+          exp->elts[save_pos1 + 2].symbol = symp;
+          argvec[0] = evaluate_subexp_with_coercion (exp, &save_pos1, noside);
+        }
+
      if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR)
	{
	  int static_memfuncp;
diff --git a/gdb/expprint.c b/gdb/expprint.c
index 89bae03..fd2e1ce 100644
--- a/gdb/expprint.c
+++ b/gdb/expprint.c
@@ -799,6 +799,8 @@ op_name_standard (enum exp_opcode opcode)
      return "OP_TYPE";
    case OP_LABELED:
      return "OP_LABELED";
+    case OP_ADL_FUNC:
+      return "OP_ADL_FUNC";
    }
}

diff --git a/gdb/expression.h b/gdb/expression.h
index 12163e3..4cd8848 100644
--- a/gdb/expression.h
+++ b/gdb/expression.h
@@ -334,6 +334,10 @@ enum exp_opcode
       Then comes another OP_DECFLOAT.  */
    OP_DECFLOAT,

+ /* OP_ADL_FUNC specifies that the argument is to be looked up in an
+ Argument Dependent manner (Koenig lookup) */
+ OP_ADL_FUNC,
+
/* First extension operator. Individual language modules define
extra operators they need as constants with values OP_LANGUAGE_SPECIFIC0 + k, for k >= 0, using a separate diff --git a/gdb/parse.c b/gdb/parse.c
index eee1f8e..afa6a43 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -811,6 +811,13 @@ operator_length_standard (struct expression *expr, int endpos,
args = 1;
break;


+ case OP_ADL_FUNC:
+ oplen = longest_to_int (expr->elts[endpos - 2].longconst);
+ oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1);
+ oplen++;
+ oplen++;
+ break;
+
case OP_LABELED:
case STRUCTOP_STRUCT:
case STRUCTOP_PTR:
diff --git a/gdb/testsuite/gdb.cp/namespace-koenig.cc b/gdb/testsuite/gdb.cp/namespace-koenig.cc
new file mode 100644
index 0000000..6c2c01d
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/namespace-koenig.cc
@@ -0,0 +1,188 @@
+namespace A
+{
+ class C
+ {
+ public:
+ static const int x = 11;
+ };
+
+ int
+ first (C c)
+ {
+ return 11;
+ }
+
+ int
+ first (int a, C c)
+ {
+ return 22;
+ }
+
+ int
+ second (int a, int b, C cc, int c, int d)
+ {
+ return 33;
+ }
+
+}
+
+struct B
+{
+ A::C c;
+};
+
+//------------
+
+namespace E
+{
+ class O{};
+ int foo (O o){return 1; }
+ int foo (O o, O o2){return 2; }
+ int foo (O o, O o2, int i){return 3; }
+}
+
+namespace F
+{
+ class O{};
+ int foo ( O fo, ::E::O eo){ return 4;}
+ int foo (int i, O fo, ::E::O eo){ return 5;}
+}
+
+namespace G
+{
+ class O{};
+ int foo (O go, ::F::O fo, ::E::O eo){ return 6; }
+}
+
+//------------
+
+namespace H
+{
+ class O{};
+ int foo (O){ return 7;}
+}
+
+namespace I
+{
+ class O: public H::O {};
+ class X: H::O{};
+}
+
+//------------
+
+namespace J
+{
+ union U{};
+ struct S{};
+ enum E{};
+
+ class A{
+ public:
+ class B{};
+ };
+
+ class C{};
+
+ int foo (U){ return 8;}
+ int foo (S){ return 9;}
+ int foo (E){ return 10;}
+ int foo (A::B){ return 11;}
+ int foo (A*){ return 12;}
+ int foo (A**){ return 13;}
+ int foo (C[]){ return 14;}
+
+}
+//------------
+
+namespace K{
+ class O{};
+
+ int foo(O, int){
+ return 15;
+ }
+
+ int bar(O, int){
+ return 15;
+ }
+}
+
+int foo(K::O, float){
+ return 16;
+}
+
+int bar(K::O, int){
+ return 16;
+}
+//------------
+
+namespace L {
+ namespace A{
+ namespace B{
+ class O {};
+
+ int foo (O){
+ return 17;
+ }
+
+ }
+ }
+}
+
+//------------
+int
+main ()
+{
+ A::C c;
+ B b;
+
+ A::first (c);
+ first (0, c);
+ second (0, 0, c, 0, 0);
+ A::first (b.c);
+
+ E::O eo;
+ F::O fo;
+ G::O go;
+
+ foo (eo);
+ foo (eo, eo);
+ foo (eo, eo, 1);
+ foo (fo, eo);
+ foo (1 ,fo, eo);
+ foo (go, fo, eo);
+
+ I::O io;
+ I::X ix;
+
+ foo (io);
+//foo (ix);
+
+ J::U ju;
+ J::S js;
+ J::E je;
+ J::A::B jab;
+ J::A *jap;
+ J::A **japp;
+ J::C jca[3];
+
+ foo (ju);
+ foo (js);
+ foo (je);
+ foo (jab);
+ foo (jap);
+ foo (japp);
+ foo (jca);
+
+ K::O ko;
+ foo (ko, 1);
+ foo (ko, 1.0f);
+ //bar(ko,1);
+
+ L::A::B::O labo;
+ foo (labo);
+ + return first (0, c) + foo (eo) +
+ foo (eo, eo) + foo (eo, eo, 1) +
+ foo (fo, eo) + foo (1 ,fo, eo) +
+ foo (go, fo, eo);
+}
diff --git a/gdb/testsuite/gdb.cp/namespace-koenig.exp b/gdb/testsuite/gdb.cp/namespace-koenig.exp
new file mode 100644
index 0000000..616b816
--- /dev/null
+++ b/gdb/testsuite/gdb.cp/namespace-koenig.exp
@@ -0,0 +1,95 @@
+# Copyright 2008 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+if $tracelevel then {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+set testfile namespace-koenig
+set srcfile ${testfile}.cc
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } {
+ untested "Couldn't compile test program"
+ return -1
+}
+
+# Get things started.
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+############################################
+
+if ![runto_main] then {
+ perror "couldn't run to breakpoint main"
+ continue
+}
+
+# Test that koenig lookup finds correct function
+gdb_test "p first(c)" "= 11"
+
+# Change the number of parameters and position of
+# the qualifying parameter
+gdb_test "p second(0,0,c,0,0)" "= 33"
+
+# Test that koenig lookup finds correct function
+# even if it is overloaded
+gdb_test "p first(0,c)" "= 22"
+
+# Test that koenig lookup finds correct function
+# when the argument is an expression
+gdb_test "p first(b.c)" "= 11"
+
+# test that resolutions can be made across namespaces
+gdb_test "p foo(eo)" "= 1"
+gdb_test "p foo(eo, eo)" "= 2"
+gdb_test "p foo(eo, eo, 1)" "= 3"
+gdb_test "p foo(fo, eo)" "= 4"
+gdb_test "p foo(1 ,fo, eo)" "= 5"
+gdb_test "p foo(go, fo, eo)" "= 6"
+
+#test that gdb fails gracefully
+gdb_test "p fake(eo)" "No symbol \"fake\" in current context."
+
+#test that namespaces of base classes are searched
+gdb_test "p foo(io)" "= 7"
+gdb_test "p foo(ix)" "Cannot resolve function foo to any overloaded instance"
+
+#test for other types
+gdb_test "p foo(ju)" "= 8"
+gdb_test "p foo(js)" "= 9"
+gdb_test "p foo(je)" "= 10"
+
+#test for class members
+setup_xfail "*-*-*"
+gdb_test "p foo(jab)" "= 11"
+
+gdb_test "p foo(jap)" "= 12"
+gdb_test "p foo(japp)" "= 13"
+gdb_test "p foo(jca)" "= 14"
+
+#test overload resolution
+gdb_test "p foo(ko,1)" "= 15"
+gdb_test "p foo(ko,1.0f)" "= 16"
+setup_xfail "*-*-*"
+gdb_test "p bar(ko,1)" "= -1"
+
+#test lookup of objects belonging to nested namespaces
+gdb_test "p foo(labo)" "= 17"
diff --git a/gdb/valops.c b/gdb/valops.c
index 202dcce..4a1b231 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -2073,7 +2073,7 @@ find_overload_match (struct type **arg_types, int nargs,
int boffset;
int ix;
int static_offset;
- struct cleanup *old_cleanups = NULL;
+ struct cleanup *old_cleanups = make_cleanup (null_cleanup, NULL);


  const char *obj_type_name = NULL;
  char *func_name = NULL;
@@ -2108,12 +2108,25 @@ find_overload_match (struct type **arg_types, int nargs,
    }
  else
    {
-      const char *qualified_name = SYMBOL_CPLUS_DEMANGLED_NAME (fsym);
+      const char *qualified_name = NULL;

-      /* If we have a C++ name, try to extract just the function
-	 part.  */
-      if (qualified_name)
-	func_name = cp_func_name (qualified_name);
+      if (fsym)
+        {
+          qualified_name = SYMBOL_CPLUS_DEMANGLED_NAME (fsym);
+
+          /* If we have a C++ name, try to extract just the function
+             part.  */
+          if (qualified_name)
+            {
+              func_name = cp_func_name (qualified_name);
+              make_cleanup (xfree, func_name);
+            }
+        }
+      else
+        {
+          func_name = name;
+          qualified_name = name;
+        }

      /* If there was no C++ name, this must be a C-style function.
	 Just return the same symbol.  Do the same if cp_func_name
@@ -2124,7 +2137,6 @@ find_overload_match (struct type **arg_types, int nargs,
          return 0;
        }

-      old_cleanups = make_cleanup (xfree, func_name);
      make_cleanup (xfree, oload_syms);
      make_cleanup (xfree, oload_champ_bv);

@@ -2135,8 +2147,11 @@ find_overload_match (struct type **arg_types, int nargs,
						&oload_champ_bv);
    }

-  /* Check how bad the best match is.  */
+  /* Did we find a match ?  */
+  if (oload_champ == -1)
+    error ("No symbol \"%s\" in current context.", name);

+  /* Check how bad the best match is.  */
  match_quality =
    classify_oload_match (oload_champ_bv, nargs,
			  oload_method_static (method, fns_ptr,
@@ -2193,8 +2208,8 @@ find_overload_match (struct type **arg_types, int nargs,
	}
      *objp = temp;
    }
-  if (old_cleanups != NULL)
-    do_cleanups (old_cleanups);
+
+  do_cleanups (old_cleanups);

  switch (match_quality)
    {
@@ -2302,6 +2317,12 @@ find_oload_champ_namespace_loop (struct type **arg_types, int nargs,
  new_namespace[namespace_len] = '\0';
  new_oload_syms = make_symbol_overload_list (func_name,
					      new_namespace);
+
+  /* If we have reached the deepesst level perform argument
+     determined lookup.  */
+  if (!searched_deeper)
+    make_symbol_overload_list_adl (arg_types, nargs, func_name);
+
  while (new_oload_syms[num_fns])
    ++num_fns;

@@ -2334,7 +2355,6 @@ find_oload_champ_namespace_loop (struct type **arg_types, int nargs,
    }
  else
    {
-      gdb_assert (new_oload_champ != -1);
      *oload_syms = new_oload_syms;
      *oload_champ = new_oload_champ;
      *oload_champ_bv = new_oload_champ_bv;


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