This is the mail archive of the gdb-patches@sourceware.org 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] | |
void foo(B){}
}int main(){
A::B b;
// (gdb) p foo(B)
return 0;
}diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index 1af76c9..d93815d 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -186,6 +186,7 @@ static struct stoken operator_stoken (const char *);
%token <tsval> STRING
%token <tsval> CHAR
%token <ssym> NAME /* BLOCKNAME defined below to give it higher precedence. */
+%token <ssym> UNKNOWN_CPP_NAME
%token <voidval> COMPLETE
%token <tsym> TYPENAME
%type <sval> name
@@ -391,6 +392,30 @@ exp : exp '('
write_exp_elt_opcode (OP_FUNCALL); }
;+exp : UNKNOWN_CPP_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 (); }
;
@@ -1224,6 +1249,7 @@ name : NAME { $$ = $1.stoken; }
| BLOCKNAME { $$ = $1.stoken; }
| TYPENAME { $$ = $1.stoken; }
| NAME_OR_INT { $$ = $1.stoken; }
+ | UNKNOWN_CPP_NAME { $$ = $1.stoken; }
| operator { $$ = $1; }
;@@ -1236,6 +1262,7 @@ name_not_typename : NAME context where only a name could occur, this might be useful. | NAME_OR_INT */ + | UNKNOWN_CPP_NAME ;
%% @@ -2379,6 +2406,12 @@ classify_name (struct block *block) /* Any other kind of symbol */ yylval.ssym.sym = sym; yylval.ssym.is_a_field_of_this = is_a_field_of_this; + + if (sym == NULL + && parse_language->la_language == language_cplus + && !lookup_minimal_symbol (copy, NULL, NULL)) + return UNKNOWN_CPP_NAME; + return NAME; }
diff --git a/gdb/cp-support.c b/gdb/cp-support.c index d43d25f..8c18304 100644 --- a/gdb/cp-support.c +++ b/gdb/cp-support.c @@ -52,7 +52,7 @@ static void demangled_name_complaint (const char *name);
-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;
@@ -712,6 +712,83 @@ 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
adds the symbols found to sym_return_val. Arguments are as in
@@ -739,20 +816,7 @@ make_symbol_overload_list_using (const char *func_name,
}/* This does the bulk of the work of finding overloaded symbols. diff --git a/gdb/cp-support.h b/gdb/cp-support.h index e10f5a9..f92ca67 100644 --- a/gdb/cp-support.h +++ b/gdb/cp-support.h @@ -79,6 +79,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 3bcd417..1e1ed0e 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -731,6 +731,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)
@@ -1453,6 +1454,17 @@ evaluate_subexp_standard (struct type *expect_type,
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 */
@@ -1483,6 +1495,32 @@ 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
|| (op == OP_SCOPE && function_name != NULL))
diff --git a/gdb/expprint.c b/gdb/expprint.c
index e378831..45deffe 100644
--- a/gdb/expprint.c
+++ b/gdb/expprint.c
@@ -816,6 +816,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 ca216cf..29ebde4 100644
--- a/gdb/expression.h
+++ b/gdb/expression.h
@@ -347,6 +347,10 @@ enum exp_opcode
Then comes another OP_DECFLOAT. */
OP_DECFLOAT,+ /* OP_ADL_FUNC specifies that the function is to be looked up in an
+ Argument Dependent manner (Koenig lookup). */
+ OP_ADL_FUNC,
+
/* First extension operator. Individual language modules define
extra operators in *.inc include files below always starting with
numbering at OP_EXTENDED0:
diff --git a/gdb/parse.c b/gdb/parse.c
index aabc461..b607c71 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -889,6 +889,13 @@ operator_length_standard (struct expression *expr, int endpos,
args = 1;
break;const char *obj_type_name = NULL; - char *func_name = NULL; + const char *func_name = NULL; enum oload_classification match_quality;
/* Get the list of overloaded methods or functions. */
@@ -2384,24 +2384,39 @@ find_overload_match (struct type **arg_types, int nargs,
}
else
{
- const char *qualified_name = SYMBOL_NATURAL_NAME (fsym);
+ const char *qualified_name = NULL;- /* If we have a function with a C++ name, try to extract just
- the function part. Do not try this for non-functions (e.g.
- function pointers). */
- if (qualified_name
- && TYPE_CODE (check_typedef (SYMBOL_TYPE (fsym))) == TYPE_CODE_FUNC)
+ if (fsym)
+ {
+ qualified_name = SYMBOL_NATURAL_NAME (fsym);
+
+ /* If we have a function with a C++ name, try to extract just
+ the function part. Do not try this for non-functions (e.g.
+ function pointers). */
+ if (qualified_name
+ && TYPE_CODE (check_typedef (SYMBOL_TYPE (fsym))) == TYPE_CODE_FUNC)
+ {
+ char *temp;
+
+ temp = cp_func_name (qualified_name);
+
+ /* If cp_func_name did not remove anything, the name of the
+ symbol did not include scope or argument types - it was
+ probably a C-style function. */
+ if (temp)
+ {
+ make_cleanup (xfree, temp);
+ if (strcmp (temp, qualified_name) == 0)
+ func_name = NULL;
+ else
+ func_name = temp;
+ }
+ }
+ }
+ else
{
- func_name = cp_func_name (qualified_name);
-
- /* If cp_func_name did not remove anything, the name of the
- symbol did not include scope or argument types - it was
- probably a C-style function. */
- if (func_name && strcmp (func_name, qualified_name) == 0)
- {
- xfree (func_name);
- func_name = NULL;
- }
+ func_name = name;
+ qualified_name = name;
} /* If there was no C++ name, this must be a C-style function or
@@ -2413,7 +2428,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);@@ -2424,8 +2438,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,
@@ -2482,8 +2499,8 @@ find_overload_match (struct type **arg_types, int nargs,
}
*objp = temp;
}
- if (old_cleanups != NULL)
- do_cleanups (old_cleanups);
+
+ do_cleanups (all_cleanups); switch (match_quality)
{
@@ -2591,6 +2608,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;@@ -2623,7 +2646,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;
Attachment:
adl.patch
Description: Text document
| Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
|---|---|---|
| Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |