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] |