diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 5123042..7b0b299 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -184,6 +184,7 @@ static int parse_number (char *, int, int, YYSTYPE *); %token STRING %token NAME /* BLOCKNAME defined below to give it higher precedence. */ +%token UNKNOWN_NAME %token COMPLETE %token TYPENAME %type name string_exp @@ -384,6 +385,30 @@ exp : exp '(' write_exp_elt_opcode (OP_FUNCALL); } ; +exp : 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); + } + ; + +adl_func : UNKNOWN_NAME + {/* This could potentially be a an argument dependet 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); + } + ; + + lcurly : '{' { start_arglist (); } ; @@ -796,6 +821,7 @@ variable: name_not_typename ; space_identifier : '@' NAME + | '@' UNKNOWN_NAME { push_type_address_space (copy_name ($2.stoken)); push_type (tp_space_identifier); } @@ -1091,10 +1117,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 +2044,11 @@ yylex () if (in_parse_field && *lexptr == '\0') saw_name_at_eof = 1; + if (sym == NULL && !lookup_minimal_symbol (tmp, NULL, NULL) && !is_a_field_of_this) + { + return UNKNOWN_NAME; + } + return NAME; } } diff --git a/gdb/eval.c b/gdb/eval.c index 0262b35..3775321 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -672,6 +672,9 @@ evaluate_subexp_standard (struct type *expect_type, struct type **arg_types; int save_pos1; + static char** prefix_array = NULL; + static int prefix_array_size = 0; + pc = (*pos)++; op = exp->elts[pc].opcode; @@ -704,6 +707,57 @@ 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: + { + char *func_name; + char *prefix; + char *concatenated_name; + struct symbol *sym = NULL; + int string_length; + int i = 0; + int string_pc = pc + 3; + + string_length = longest_to_int (exp->elts[string_pc].longconst); + + func_name = (char*) alloca(string_length+1); + strcpy (func_name, &exp->elts[string_pc + 1].string); + sym = exp->elts[pc + 2].symbol; + if (sym == NULL) + { /* Symbol has not been resolved yet. */ + for (i = 0; sym == NULL && i < prefix_array_size; i++) + { + prefix = prefix_array[i]; + concatenated_name = alloca (strlen (prefix) + 1 + strlen (func_name) + 1); + strcpy(concatenated_name, prefix); + strcat(concatenated_name, "::"); + strcat(concatenated_name, func_name); + + sym = lookup_symbol(concatenated_name, + exp->elts[pc + 1].block, VAR_DOMAIN, (int *) NULL); + + if (sym) + { + exp->elts[pc + 2].symbol = sym; + break; + } + } + + /* free prefix_array */ + for (i = 0; i < prefix_array_size; ++i) + { + xfree(prefix_array[i]); + } + xfree(prefix_array); + prefix_array = NULL; + prefix_array_size = 0; + } + + if (sym == NULL) + { + error("No function \"%s\" in specified context.", func_name); + } + } + /* Now fall through for normal symbol evaluation */ case OP_VAR_VALUE: (*pos) += 3; if (noside == EVAL_SKIP) @@ -1276,6 +1330,10 @@ evaluate_subexp_standard (struct type *expect_type, break; case OP_FUNCALL: + { + int adl_func_pos = 0; + int adl_func = 0; + (*pos) += 2; op = exp->elts[*pos].opcode; nargs = longest_to_int (exp->elts[pc + 1].longconst); @@ -1362,8 +1420,21 @@ evaluate_subexp_standard (struct type *expect_type, /* Now, say which argument to start evaluating from */ tem = 2; } - else + else if ( op == OP_ADL_FUNC ) { + int temp; + adl_func_pos = *pos; + tem = 1; + adl_func = 1; + + prefix_array = xzalloc (sizeof(char*) * nargs); + temp = longest_to_int (exp->elts[adl_func_pos + 3].longconst); + (*pos)++; // block + (*pos)++; // symbol + (*pos)++; // strlng + (*pos) += 3 + BYTES_TO_EXP_ELEM (temp + 1); // string + a null terminator + } + else{ /* Non-method function call */ save_pos1 = *pos; argvec[0] = evaluate_subexp_with_coercion (exp, pos, noside); @@ -1386,8 +1457,39 @@ evaluate_subexp_standard (struct type *expect_type, /* Evaluate arguments */ for (; tem <= nargs; tem++) { + /* Ensure that array expressions are coerced into pointer objects. */ argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside); + + if(adl_func) + { + /* save prefixes */ + char* cindex; + char* name; + + name = TYPE_NAME (value_type (argvec[tem])); + cindex = rindex(name, ':'); + if(cindex != NULL){ + prefix_array[prefix_array_size] = savestring(name, (int)(cindex - name) - 1); + prefix_array_size++; + } + } + + } + + if(adl_func){ + struct symbol *symp; + save_pos1 = adl_func_pos; + argvec[0] = evaluate_subexp_with_coercion (exp, &adl_func_pos, noside); + + (void) find_overload_match (argvec, nargs, NULL /* no need for name */ , + 0 /* not method */ , 0 /* strict match */ , + NULL, exp->elts[save_pos1+2].symbol /* the function */ , + 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); } /* signal end of arglist */ @@ -1502,9 +1604,10 @@ evaluate_subexp_standard (struct type *expect_type, else error (_("Expression of type other than \"Function returning ...\" used as function")); } + return call_function_by_hand (argvec[0], nargs, argvec + 1); /* pai: FIXME save value from call_function_by_hand, then adjust pc by adjust_fn_pc if +ve */ - + } case OP_F77_UNDETERMINED_ARGLIST: /* Remember that in F77, functions, substring ops and 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..ec8df4d 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 (keonig 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..c6f1c9a 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++; // block + oplen++; // symbol + break; + case OP_LABELED: case STRUCTOP_STRUCT: case STRUCTOP_PTR: