/* la_watch_location_expression for Ada. */
-gdb::unique_xmalloc_ptr<char>
+static gdb::unique_xmalloc_ptr<char>
ada_watch_location_expression (struct type *type, CORE_ADDR addr)
{
type = check_typedef (TYPE_TARGET_TYPE (check_typedef (type)));
(xstrprintf ("{%s} %s", name.c_str (), core_addr_to_string (addr)));
}
+/* Assuming V points to an array of S objects, make sure that it contains at
+ least M objects, updating V and S as necessary. */
+
+#define GROW_VECT(v, s, m) \
+ if ((s) < (m)) (v) = (char *) grow_vect (v, &(s), m, sizeof *(v));
+
/* Assuming VECT points to an array of *SIZE objects of size
ELEMENT_SIZE, grow it to contain at least MIN_SIZE objects,
updating *SIZE as necessary and returning the (new) array. */
-void *
+static void *
grow_vect (void *vect, size_t *size, size_t min_size, int element_size)
{
if (*size < min_size)
/* If the main program is in Ada, return language_ada, otherwise return LANG
(the main program is in Ada iif the adainit symbol is found). */
-enum language
+static enum language
ada_update_initial_language (enum language lang)
{
if (lookup_minimal_symbol ("adainit", NULL, NULL).minsym != NULL)
quotes, unfolded, but with the quotes stripped away. Result good
to next call. */
-char *
+static char *
ada_fold_name (const char *name)
{
static char *fold_buffer = NULL;
the ARR denotes a null array descriptor and BOUNDS is non-zero,
returns NULL. The result is simply the type of ARR if ARR is not
a descriptor. */
-struct type *
+
+static struct type *
ada_type_of_array (struct value *arr, int bounds)
{
if (ada_is_constrained_packed_array_type (value_type (arr)))
error (_("Could not find operator name for opcode"));
}
+/* Returns true (non-zero) iff decoded name N0 should appear before N1
+ in a listing of choices during disambiguation (see sort_choices, below).
+ The idea is that overloadings of a subprogram name from the
+ same package should sort in their source order. We settle for ordering
+ such symbols by their trailing number (__N or $N). */
-/* Same as evaluate_type (*EXP), but resolves ambiguous symbol
- references (marked by OP_VAR_VALUE nodes in which the symbol has an
- undefined namespace) and converts operators that are
- user-defined into appropriate function calls. If CONTEXT_TYPE is
- non-null, it provides a preferred result type [at the moment, only
- type void has any effect---causing procedures to be preferred over
- functions in calls]. A null CONTEXT_TYPE indicates that a non-void
- return type is preferred. May change (expand) *EXP. */
-
-static void
-resolve (expression_up *expp, int void_context_p, int parse_completion,
- innermost_block_tracker *tracker)
+static int
+encoded_ordered_before (const char *N0, const char *N1)
{
- struct type *context_type = NULL;
- int pc = 0;
+ if (N1 == NULL)
+ return 0;
+ else if (N0 == NULL)
+ return 1;
+ else
+ {
+ int k0, k1;
- if (void_context_p)
- context_type = builtin_type ((*expp)->gdbarch)->builtin_void;
+ for (k0 = strlen (N0) - 1; k0 > 0 && isdigit (N0[k0]); k0 -= 1)
+ ;
+ for (k1 = strlen (N1) - 1; k1 > 0 && isdigit (N1[k1]); k1 -= 1)
+ ;
+ if ((N0[k0] == '_' || N0[k0] == '$') && N0[k0 + 1] != '\000'
+ && (N1[k1] == '_' || N1[k1] == '$') && N1[k1 + 1] != '\000')
+ {
+ int n0, n1;
- resolve_subexp (expp, &pc, 1, context_type, parse_completion, tracker);
+ n0 = k0;
+ while (N0[n0] == '_' && n0 > 0 && N0[n0 - 1] == '_')
+ n0 -= 1;
+ n1 = k1;
+ while (N1[n1] == '_' && n1 > 0 && N1[n1 - 1] == '_')
+ n1 -= 1;
+ if (n0 == n1 && strncmp (N0, N1, n0) == 0)
+ return (atoi (N0 + k0 + 1) < atoi (N1 + k1 + 1));
+ }
+ return (strcmp (N0, N1) < 0);
+ }
}
-/* Resolve the operator of the subexpression beginning at
- position *POS of *EXPP. "Resolving" consists of replacing
- the symbols that have undefined namespaces in OP_VAR_VALUE nodes
- with their resolutions, replacing built-in operators with
- function calls to user-defined operators, where appropriate, and,
- when DEPROCEDURE_P is non-zero, converting function-valued variables
- into parameterless calls. May expand *EXPP. The CONTEXT_TYPE functions
- are as in ada_resolve, above. */
+/* Sort SYMS[0..NSYMS-1] to put the choices in a canonical order by the
+ encoded names. */
-static struct value *
-resolve_subexp (expression_up *expp, int *pos, int deprocedure_p,
- struct type *context_type, int parse_completion,
- innermost_block_tracker *tracker)
+static void
+sort_choices (struct block_symbol syms[], int nsyms)
{
- int pc = *pos;
int i;
- struct expression *exp; /* Convenience: == *expp. */
- enum exp_opcode op = (*expp)->elts[pc].opcode;
- struct value **argvec; /* Vector of operand types (alloca'ed). */
- int nargs; /* Number of operands. */
- int oplen;
- argvec = NULL;
- nargs = 0;
- exp = expp->get ();
-
- /* Pass one: resolve operands, saving their types and updating *pos,
- if needed. */
- switch (op)
+ for (i = 1; i < nsyms; i += 1)
{
- case OP_FUNCALL:
- if (exp->elts[pc + 3].opcode == OP_VAR_VALUE
- && SYMBOL_DOMAIN (exp->elts[pc + 5].symbol) == UNDEF_DOMAIN)
- *pos += 7;
- else
+ struct block_symbol sym = syms[i];
+ int j;
+
+ for (j = i - 1; j >= 0; j -= 1)
{
- *pos += 3;
- resolve_subexp (expp, pos, 0, NULL, parse_completion, tracker);
+ if (encoded_ordered_before (SYMBOL_LINKAGE_NAME (syms[j].symbol),
+ SYMBOL_LINKAGE_NAME (sym.symbol)))
+ break;
+ syms[j + 1] = syms[j];
}
- nargs = longest_to_int (exp->elts[pc + 1].longconst);
- break;
+ syms[j + 1] = sym;
+ }
+}
- case UNOP_ADDR:
- *pos += 1;
- resolve_subexp (expp, pos, 0, NULL, parse_completion, tracker);
- break;
+/* Whether GDB should display formals and return types for functions in the
+ overloads selection menu. */
+static bool print_signatures = true;
- case UNOP_QUAL:
- *pos += 3;
- resolve_subexp (expp, pos, 1, check_typedef (exp->elts[pc + 1].type),
- parse_completion, tracker);
- break;
+/* Print the signature for SYM on STREAM according to the FLAGS options. For
+ all but functions, the signature is just the name of the symbol. For
+ functions, this is the name of the function, the list of types for formals
+ and the return type (if any). */
- case OP_ATR_MODULUS:
- case OP_ATR_SIZE:
- case OP_ATR_TAG:
- case OP_ATR_FIRST:
- case OP_ATR_LAST:
- case OP_ATR_LENGTH:
- case OP_ATR_POS:
- case OP_ATR_VAL:
- case OP_ATR_MIN:
- case OP_ATR_MAX:
- case TERNOP_IN_RANGE:
- case BINOP_IN_BOUNDS:
- case UNOP_IN_RANGE:
- case OP_AGGREGATE:
- case OP_OTHERS:
- case OP_CHOICES:
- case OP_POSITIONAL:
- case OP_DISCRETE_RANGE:
- case OP_NAME:
- ada_forward_operator_length (exp, pc, &oplen, &nargs);
- *pos += oplen;
- break;
+static void
+ada_print_symbol_signature (struct ui_file *stream, struct symbol *sym,
+ const struct type_print_options *flags)
+{
+ struct type *type = SYMBOL_TYPE (sym);
- case BINOP_ASSIGN:
- {
- struct value *arg1;
+ fprintf_filtered (stream, "%s", SYMBOL_PRINT_NAME (sym));
+ if (!print_signatures
+ || type == NULL
+ || TYPE_CODE (type) != TYPE_CODE_FUNC)
+ return;
- *pos += 1;
- arg1 = resolve_subexp (expp, pos, 0, NULL, parse_completion, tracker);
- if (arg1 == NULL)
- resolve_subexp (expp, pos, 1, NULL, parse_completion, tracker);
- else
- resolve_subexp (expp, pos, 1, value_type (arg1), parse_completion,
- tracker);
- break;
- }
+ if (TYPE_NFIELDS (type) > 0)
+ {
+ int i;
- case UNOP_CAST:
- *pos += 3;
- nargs = 1;
- break;
+ fprintf_filtered (stream, " (");
+ for (i = 0; i < TYPE_NFIELDS (type); ++i)
+ {
+ if (i > 0)
+ fprintf_filtered (stream, "; ");
+ ada_print_type (TYPE_FIELD_TYPE (type, i), NULL, stream, -1, 0,
+ flags);
+ }
+ fprintf_filtered (stream, ")");
+ }
+ if (TYPE_TARGET_TYPE (type) != NULL
+ && TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
+ {
+ fprintf_filtered (stream, " return ");
+ ada_print_type (TYPE_TARGET_TYPE (type), NULL, stream, -1, 0, flags);
+ }
+}
- case BINOP_ADD:
- case BINOP_SUB:
- case BINOP_MUL:
- case BINOP_DIV:
- case BINOP_REM:
- case BINOP_MOD:
- case BINOP_EXP:
- case BINOP_CONCAT:
- case BINOP_LOGICAL_AND:
- case BINOP_LOGICAL_OR:
- case BINOP_BITWISE_AND:
- case BINOP_BITWISE_IOR:
- case BINOP_BITWISE_XOR:
+/* Read and validate a set of numeric choices from the user in the
+ range 0 .. N_CHOICES-1. Place the results in increasing
+ order in CHOICES[0 .. N-1], and return N.
- case BINOP_EQUAL:
- case BINOP_NOTEQUAL:
- case BINOP_LESS:
- case BINOP_GTR:
- case BINOP_LEQ:
- case BINOP_GEQ:
+ The user types choices as a sequence of numbers on one line
+ separated by blanks, encoding them as follows:
- case BINOP_REPEAT:
- case BINOP_SUBSCRIPT:
- case BINOP_COMMA:
- *pos += 1;
- nargs = 2;
- break;
+ + A choice of 0 means to cancel the selection, throwing an error.
+ + If IS_ALL_CHOICE, a choice of 1 selects the entire set 0 .. N_CHOICES-1.
+ + The user chooses k by typing k+IS_ALL_CHOICE+1.
- case UNOP_NEG:
- case UNOP_PLUS:
- case UNOP_LOGICAL_NOT:
- case UNOP_ABS:
- case UNOP_IND:
- *pos += 1;
- nargs = 1;
- break;
+ The user is not allowed to choose more than MAX_RESULTS values.
- case OP_LONG:
- case OP_FLOAT:
- case OP_VAR_VALUE:
- case OP_VAR_MSYM_VALUE:
- *pos += 4;
- break;
+ ANNOTATION_SUFFIX, if present, is used to annotate the input
+ prompts (for use with the -f switch). */
- case OP_TYPE:
- case OP_BOOL:
- case OP_LAST:
- case OP_INTERNALVAR:
- *pos += 3;
- break;
+static int
+get_selections (int *choices, int n_choices, int max_results,
+ int is_all_choice, const char *annotation_suffix)
+{
+ char *args;
+ const char *prompt;
+ int n_chosen;
+ int first_choice = is_all_choice ? 2 : 1;
- case UNOP_MEMVAL:
- *pos += 3;
- nargs = 1;
- break;
-
- case OP_REGISTER:
- *pos += 4 + BYTES_TO_EXP_ELEM (exp->elts[pc + 1].longconst + 1);
- break;
-
- case STRUCTOP_STRUCT:
- *pos += 4 + BYTES_TO_EXP_ELEM (exp->elts[pc + 1].longconst + 1);
- nargs = 1;
- break;
-
- case TERNOP_SLICE:
- *pos += 1;
- nargs = 3;
- break;
+ prompt = getenv ("PS2");
+ if (prompt == NULL)
+ prompt = "> ";
- case OP_STRING:
- break;
+ args = command_line_input (prompt, annotation_suffix);
- default:
- error (_("Unexpected operator during name resolution"));
- }
+ if (args == NULL)
+ error_no_arg (_("one or more choice numbers"));
- argvec = XALLOCAVEC (struct value *, nargs + 1);
- for (i = 0; i < nargs; i += 1)
- argvec[i] = resolve_subexp (expp, pos, 1, NULL, parse_completion,
- tracker);
- argvec[i] = NULL;
- exp = expp->get ();
+ n_chosen = 0;
- /* Pass two: perform any resolution on principal operator. */
- switch (op)
+ /* Set choices[0 .. n_chosen-1] to the users' choices in ascending
+ order, as given in args. Choices are validated. */
+ while (1)
{
- default:
- break;
-
- case OP_VAR_VALUE:
- if (SYMBOL_DOMAIN (exp->elts[pc + 2].symbol) == UNDEF_DOMAIN)
- {
- std::vector<struct block_symbol> candidates;
- int n_candidates;
+ char *args2;
+ int choice, j;
- n_candidates =
- ada_lookup_symbol_list (SYMBOL_LINKAGE_NAME
- (exp->elts[pc + 2].symbol),
- exp->elts[pc + 1].block, VAR_DOMAIN,
- &candidates);
+ args = skip_spaces (args);
+ if (*args == '\0' && n_chosen == 0)
+ error_no_arg (_("one or more choice numbers"));
+ else if (*args == '\0')
+ break;
- if (n_candidates > 1)
- {
- /* Types tend to get re-introduced locally, so if there
- are any local symbols that are not types, first filter
- out all types. */
- int j;
- for (j = 0; j < n_candidates; j += 1)
- switch (SYMBOL_CLASS (candidates[j].symbol))
- {
- case LOC_REGISTER:
- case LOC_ARG:
- case LOC_REF_ARG:
- case LOC_REGPARM_ADDR:
- case LOC_LOCAL:
- case LOC_COMPUTED:
- goto FoundNonType;
- default:
- break;
- }
- FoundNonType:
- if (j < n_candidates)
- {
- j = 0;
- while (j < n_candidates)
- {
- if (SYMBOL_CLASS (candidates[j].symbol) == LOC_TYPEDEF)
- {
- candidates[j] = candidates[n_candidates - 1];
- n_candidates -= 1;
- }
- else
- j += 1;
- }
- }
- }
+ choice = strtol (args, &args2, 10);
+ if (args == args2 || choice < 0
+ || choice > n_choices + first_choice - 1)
+ error (_("Argument must be choice number"));
+ args = args2;
- if (n_candidates == 0)
- error (_("No definition found for %s"),
- SYMBOL_PRINT_NAME (exp->elts[pc + 2].symbol));
- else if (n_candidates == 1)
- i = 0;
- else if (deprocedure_p
- && !is_nonfunction (candidates.data (), n_candidates))
- {
- i = ada_resolve_function
- (candidates.data (), n_candidates, NULL, 0,
- SYMBOL_LINKAGE_NAME (exp->elts[pc + 2].symbol),
- context_type, parse_completion);
- if (i < 0)
- error (_("Could not find a match for %s"),
- SYMBOL_PRINT_NAME (exp->elts[pc + 2].symbol));
- }
- else
- {
- printf_filtered (_("Multiple matches for %s\n"),
- SYMBOL_PRINT_NAME (exp->elts[pc + 2].symbol));
- user_select_syms (candidates.data (), n_candidates, 1);
- i = 0;
- }
+ if (choice == 0)
+ error (_("cancelled"));
- exp->elts[pc + 1].block = candidates[i].block;
- exp->elts[pc + 2].symbol = candidates[i].symbol;
- tracker->update (candidates[i]);
+ if (choice < first_choice)
+ {
+ n_chosen = n_choices;
+ for (j = 0; j < n_choices; j += 1)
+ choices[j] = j;
+ break;
}
+ choice -= first_choice;
- if (deprocedure_p
- && (TYPE_CODE (SYMBOL_TYPE (exp->elts[pc + 2].symbol))
- == TYPE_CODE_FUNC))
+ for (j = n_chosen - 1; j >= 0 && choice < choices[j]; j -= 1)
{
- replace_operator_with_call (expp, pc, 0, 4,
- exp->elts[pc + 2].symbol,
- exp->elts[pc + 1].block);
- exp = expp->get ();
}
- break;
-
- case OP_FUNCALL:
- {
- if (exp->elts[pc + 3].opcode == OP_VAR_VALUE
- && SYMBOL_DOMAIN (exp->elts[pc + 5].symbol) == UNDEF_DOMAIN)
- {
- std::vector<struct block_symbol> candidates;
- int n_candidates;
-
- n_candidates =
- ada_lookup_symbol_list (SYMBOL_LINKAGE_NAME
- (exp->elts[pc + 5].symbol),
- exp->elts[pc + 4].block, VAR_DOMAIN,
- &candidates);
-
- if (n_candidates == 1)
- i = 0;
- else
- {
- i = ada_resolve_function
- (candidates.data (), n_candidates,
- argvec, nargs,
- SYMBOL_LINKAGE_NAME (exp->elts[pc + 5].symbol),
- context_type, parse_completion);
- if (i < 0)
- error (_("Could not find a match for %s"),
- SYMBOL_PRINT_NAME (exp->elts[pc + 5].symbol));
- }
- exp->elts[pc + 4].block = candidates[i].block;
- exp->elts[pc + 5].symbol = candidates[i].symbol;
- tracker->update (candidates[i]);
- }
- }
- break;
- case BINOP_ADD:
- case BINOP_SUB:
- case BINOP_MUL:
- case BINOP_DIV:
- case BINOP_REM:
- case BINOP_MOD:
- case BINOP_CONCAT:
- case BINOP_BITWISE_AND:
- case BINOP_BITWISE_IOR:
- case BINOP_BITWISE_XOR:
- case BINOP_EQUAL:
- case BINOP_NOTEQUAL:
- case BINOP_LESS:
- case BINOP_GTR:
- case BINOP_LEQ:
- case BINOP_GEQ:
- case BINOP_EXP:
- case UNOP_NEG:
- case UNOP_PLUS:
- case UNOP_LOGICAL_NOT:
- case UNOP_ABS:
- if (possible_user_operator_p (op, argvec))
+ if (j < 0 || choice != choices[j])
{
- std::vector<struct block_symbol> candidates;
- int n_candidates;
-
- n_candidates =
- ada_lookup_symbol_list (ada_decoded_op_name (op),
- NULL, VAR_DOMAIN,
- &candidates);
-
- i = ada_resolve_function (candidates.data (), n_candidates, argvec,
- nargs, ada_decoded_op_name (op), NULL,
- parse_completion);
- if (i < 0)
- break;
+ int k;
- replace_operator_with_call (expp, pc, nargs, 1,
- candidates[i].symbol,
- candidates[i].block);
- exp = expp->get ();
+ for (k = n_chosen - 1; k > j; k -= 1)
+ choices[k + 1] = choices[k];
+ choices[j + 1] = choice;
+ n_chosen += 1;
}
- break;
-
- case OP_TYPE:
- case OP_REGISTER:
- return NULL;
}
- *pos = pc;
- if (exp->elts[pc].opcode == OP_VAR_MSYM_VALUE)
- return evaluate_var_msym_value (EVAL_AVOID_SIDE_EFFECTS,
- exp->elts[pc + 1].objfile,
- exp->elts[pc + 2].msymbol);
- else
- return evaluate_subexp_type (exp, pos);
+ if (n_chosen > max_results)
+ error (_("Select no more than %d of the above"), max_results);
+
+ return n_chosen;
}
-/* Return non-zero if formal type FTYPE matches actual type ATYPE. If
- MAY_DEREF is non-zero, the formal may be a pointer and the actual
- a non-pointer. */
-/* The term "match" here is rather loose. The match is heuristic and
- liberal. */
+/* Given a list of NSYMS symbols in SYMS, select up to MAX_RESULTS>0
+ by asking the user (if necessary), returning the number selected,
+ and setting the first elements of SYMS items. Error if no symbols
+ selected. */
+
+/* NOTE: Adapted from decode_line_2 in symtab.c, with which it ought
+ to be re-integrated one of these days. */
static int
-ada_type_match (struct type *ftype, struct type *atype, int may_deref)
+user_select_syms (struct block_symbol *syms, int nsyms, int max_results)
{
- ftype = ada_check_typedef (ftype);
- atype = ada_check_typedef (atype);
-
- if (TYPE_CODE (ftype) == TYPE_CODE_REF)
- ftype = TYPE_TARGET_TYPE (ftype);
- if (TYPE_CODE (atype) == TYPE_CODE_REF)
- atype = TYPE_TARGET_TYPE (atype);
-
- switch (TYPE_CODE (ftype))
- {
- default:
- return TYPE_CODE (ftype) == TYPE_CODE (atype);
- case TYPE_CODE_PTR:
- if (TYPE_CODE (atype) == TYPE_CODE_PTR)
- return ada_type_match (TYPE_TARGET_TYPE (ftype),
- TYPE_TARGET_TYPE (atype), 0);
- else
- return (may_deref
- && ada_type_match (TYPE_TARGET_TYPE (ftype), atype, 0));
- case TYPE_CODE_INT:
- case TYPE_CODE_ENUM:
- case TYPE_CODE_RANGE:
- switch (TYPE_CODE (atype))
- {
- case TYPE_CODE_INT:
- case TYPE_CODE_ENUM:
- case TYPE_CODE_RANGE:
- return 1;
- default:
- return 0;
- }
+ int i;
+ int *chosen = XALLOCAVEC (int , nsyms);
+ int n_chosen;
+ int first_choice = (max_results == 1) ? 1 : 2;
+ const char *select_mode = multiple_symbols_select_mode ();
- case TYPE_CODE_ARRAY:
- return (TYPE_CODE (atype) == TYPE_CODE_ARRAY
- || ada_is_array_descriptor_type (atype));
+ if (max_results < 1)
+ error (_("Request to select 0 symbols!"));
+ if (nsyms <= 1)
+ return nsyms;
- case TYPE_CODE_STRUCT:
- if (ada_is_array_descriptor_type (ftype))
- return (TYPE_CODE (atype) == TYPE_CODE_ARRAY
- || ada_is_array_descriptor_type (atype));
- else
- return (TYPE_CODE (atype) == TYPE_CODE_STRUCT
- && !ada_is_array_descriptor_type (atype));
+ if (select_mode == multiple_symbols_cancel)
+ error (_("\
+canceled because the command is ambiguous\n\
+See set/show multiple-symbol."));
- case TYPE_CODE_UNION:
- case TYPE_CODE_FLT:
- return (TYPE_CODE (atype) == TYPE_CODE (ftype));
- }
-}
+ /* If select_mode is "all", then return all possible symbols.
+ Only do that if more than one symbol can be selected, of course.
+ Otherwise, display the menu as usual. */
+ if (select_mode == multiple_symbols_all && max_results > 1)
+ return nsyms;
-/* Return non-zero if the formals of FUNC "sufficiently match" the
- vector of actual argument types ACTUALS of size N_ACTUALS. FUNC
- may also be an enumeral, in which case it is treated as a 0-
- argument function. */
+ printf_filtered (_("[0] cancel\n"));
+ if (max_results > 1)
+ printf_filtered (_("[1] all\n"));
-static int
-ada_args_match (struct symbol *func, struct value **actuals, int n_actuals)
-{
- int i;
- struct type *func_type = SYMBOL_TYPE (func);
+ sort_choices (syms, nsyms);
- if (SYMBOL_CLASS (func) == LOC_CONST
- && TYPE_CODE (func_type) == TYPE_CODE_ENUM)
- return (n_actuals == 0);
- else if (func_type == NULL || TYPE_CODE (func_type) != TYPE_CODE_FUNC)
- return 0;
+ for (i = 0; i < nsyms; i += 1)
+ {
+ if (syms[i].symbol == NULL)
+ continue;
- if (TYPE_NFIELDS (func_type) != n_actuals)
- return 0;
+ if (SYMBOL_CLASS (syms[i].symbol) == LOC_BLOCK)
+ {
+ struct symtab_and_line sal =
+ find_function_start_sal (syms[i].symbol, 1);
- for (i = 0; i < n_actuals; i += 1)
- {
- if (actuals[i] == NULL)
- return 0;
+ printf_filtered ("[%d] ", i + first_choice);
+ ada_print_symbol_signature (gdb_stdout, syms[i].symbol,
+ &type_print_raw_options);
+ if (sal.symtab == NULL)
+ printf_filtered (_(" at %p[<no source file available>%p]:%d\n"),
+ metadata_style.style ().ptr (), nullptr, sal.line);
+ else
+ printf_filtered
+ (_(" at %ps:%d\n"),
+ styled_string (file_name_style.style (),
+ symtab_to_filename_for_display (sal.symtab)),
+ sal.line);
+ continue;
+ }
else
{
- struct type *ftype = ada_check_typedef (TYPE_FIELD_TYPE (func_type,
- i));
- struct type *atype = ada_check_typedef (value_type (actuals[i]));
+ int is_enumeral =
+ (SYMBOL_CLASS (syms[i].symbol) == LOC_CONST
+ && SYMBOL_TYPE (syms[i].symbol) != NULL
+ && TYPE_CODE (SYMBOL_TYPE (syms[i].symbol)) == TYPE_CODE_ENUM);
+ struct symtab *symtab = NULL;
- if (!ada_type_match (ftype, atype, 1))
- return 0;
+ if (SYMBOL_OBJFILE_OWNED (syms[i].symbol))
+ symtab = symbol_symtab (syms[i].symbol);
+
+ if (SYMBOL_LINE (syms[i].symbol) != 0 && symtab != NULL)
+ {
+ printf_filtered ("[%d] ", i + first_choice);
+ ada_print_symbol_signature (gdb_stdout, syms[i].symbol,
+ &type_print_raw_options);
+ printf_filtered (_(" at %s:%d\n"),
+ symtab_to_filename_for_display (symtab),
+ SYMBOL_LINE (syms[i].symbol));
+ }
+ else if (is_enumeral
+ && TYPE_NAME (SYMBOL_TYPE (syms[i].symbol)) != NULL)
+ {
+ printf_filtered (("[%d] "), i + first_choice);
+ ada_print_type (SYMBOL_TYPE (syms[i].symbol), NULL,
+ gdb_stdout, -1, 0, &type_print_raw_options);
+ printf_filtered (_("'(%s) (enumeral)\n"),
+ SYMBOL_PRINT_NAME (syms[i].symbol));
+ }
+ else
+ {
+ printf_filtered ("[%d] ", i + first_choice);
+ ada_print_symbol_signature (gdb_stdout, syms[i].symbol,
+ &type_print_raw_options);
+
+ if (symtab != NULL)
+ printf_filtered (is_enumeral
+ ? _(" in %s (enumeral)\n")
+ : _(" at %s:?\n"),
+ symtab_to_filename_for_display (symtab));
+ else
+ printf_filtered (is_enumeral
+ ? _(" (enumeral)\n")
+ : _(" at ?\n"));
+ }
}
}
- return 1;
-}
-
-/* False iff function type FUNC_TYPE definitely does not produce a value
- compatible with type CONTEXT_TYPE. Conservatively returns 1 if
- FUNC_TYPE is not a valid function type with a non-null return type
- or an enumerated type. A null CONTEXT_TYPE indicates any non-void type. */
-static int
-return_match (struct type *func_type, struct type *context_type)
-{
- struct type *return_type;
+ n_chosen = get_selections (chosen, nsyms, max_results, max_results > 1,
+ "overload-choice");
- if (func_type == NULL)
- return 1;
+ for (i = 0; i < n_chosen; i += 1)
+ syms[i] = syms[chosen[i]];
- if (TYPE_CODE (func_type) == TYPE_CODE_FUNC)
- return_type = get_base_type (TYPE_TARGET_TYPE (func_type));
- else
- return_type = get_base_type (func_type);
- if (return_type == NULL)
- return 1;
+ return n_chosen;
+}
- context_type = get_base_type (context_type);
+/* Same as evaluate_type (*EXP), but resolves ambiguous symbol
+ references (marked by OP_VAR_VALUE nodes in which the symbol has an
+ undefined namespace) and converts operators that are
+ user-defined into appropriate function calls. If CONTEXT_TYPE is
+ non-null, it provides a preferred result type [at the moment, only
+ type void has any effect---causing procedures to be preferred over
+ functions in calls]. A null CONTEXT_TYPE indicates that a non-void
+ return type is preferred. May change (expand) *EXP. */
- if (TYPE_CODE (return_type) == TYPE_CODE_ENUM)
- return context_type == NULL || return_type == context_type;
- else if (context_type == NULL)
- return TYPE_CODE (return_type) != TYPE_CODE_VOID;
- else
- return TYPE_CODE (return_type) == TYPE_CODE (context_type);
-}
+static void
+resolve (expression_up *expp, int void_context_p, int parse_completion,
+ innermost_block_tracker *tracker)
+{
+ struct type *context_type = NULL;
+ int pc = 0;
+ if (void_context_p)
+ context_type = builtin_type ((*expp)->gdbarch)->builtin_void;
-/* Returns the index in SYMS[0..NSYMS-1] that contains the symbol for the
- function (if any) that matches the types of the NARGS arguments in
- ARGS. If CONTEXT_TYPE is non-null and there is at least one match
- that returns that type, then eliminate matches that don't. If
- CONTEXT_TYPE is void and there is at least one match that does not
- return void, eliminate all matches that do.
+ resolve_subexp (expp, &pc, 1, context_type, parse_completion, tracker);
+}
- Asks the user if there is more than one match remaining. Returns -1
- if there is no such symbol or none is selected. NAME is used
- solely for messages. May re-arrange and modify SYMS in
- the process; the index returned is for the modified vector. */
+/* Resolve the operator of the subexpression beginning at
+ position *POS of *EXPP. "Resolving" consists of replacing
+ the symbols that have undefined namespaces in OP_VAR_VALUE nodes
+ with their resolutions, replacing built-in operators with
+ function calls to user-defined operators, where appropriate, and,
+ when DEPROCEDURE_P is non-zero, converting function-valued variables
+ into parameterless calls. May expand *EXPP. The CONTEXT_TYPE functions
+ are as in ada_resolve, above. */
-static int
-ada_resolve_function (struct block_symbol syms[],
- int nsyms, struct value **args, int nargs,
- const char *name, struct type *context_type,
- int parse_completion)
+static struct value *
+resolve_subexp (expression_up *expp, int *pos, int deprocedure_p,
+ struct type *context_type, int parse_completion,
+ innermost_block_tracker *tracker)
{
- int fallback;
- int k;
- int m; /* Number of hits */
+ int pc = *pos;
+ int i;
+ struct expression *exp; /* Convenience: == *expp. */
+ enum exp_opcode op = (*expp)->elts[pc].opcode;
+ struct value **argvec; /* Vector of operand types (alloca'ed). */
+ int nargs; /* Number of operands. */
+ int oplen;
- m = 0;
- /* In the first pass of the loop, we only accept functions matching
- context_type. If none are found, we add a second pass of the loop
- where every function is accepted. */
- for (fallback = 0; m == 0 && fallback < 2; fallback++)
- {
- for (k = 0; k < nsyms; k += 1)
- {
- struct type *type = ada_check_typedef (SYMBOL_TYPE (syms[k].symbol));
+ argvec = NULL;
+ nargs = 0;
+ exp = expp->get ();
- if (ada_args_match (syms[k].symbol, args, nargs)
- && (fallback || return_match (type, context_type)))
- {
- syms[m] = syms[k];
- m += 1;
- }
+ /* Pass one: resolve operands, saving their types and updating *pos,
+ if needed. */
+ switch (op)
+ {
+ case OP_FUNCALL:
+ if (exp->elts[pc + 3].opcode == OP_VAR_VALUE
+ && SYMBOL_DOMAIN (exp->elts[pc + 5].symbol) == UNDEF_DOMAIN)
+ *pos += 7;
+ else
+ {
+ *pos += 3;
+ resolve_subexp (expp, pos, 0, NULL, parse_completion, tracker);
}
- }
+ nargs = longest_to_int (exp->elts[pc + 1].longconst);
+ break;
- /* If we got multiple matches, ask the user which one to use. Don't do this
- interactive thing during completion, though, as the purpose of the
- completion is providing a list of all possible matches. Prompting the
- user to filter it down would be completely unexpected in this case. */
- if (m == 0)
- return -1;
- else if (m > 1 && !parse_completion)
- {
- printf_filtered (_("Multiple matches for %s\n"), name);
- user_select_syms (syms, m, 1);
- return 0;
+ case UNOP_ADDR:
+ *pos += 1;
+ resolve_subexp (expp, pos, 0, NULL, parse_completion, tracker);
+ break;
+
+ case UNOP_QUAL:
+ *pos += 3;
+ resolve_subexp (expp, pos, 1, check_typedef (exp->elts[pc + 1].type),
+ parse_completion, tracker);
+ break;
+
+ case OP_ATR_MODULUS:
+ case OP_ATR_SIZE:
+ case OP_ATR_TAG:
+ case OP_ATR_FIRST:
+ case OP_ATR_LAST:
+ case OP_ATR_LENGTH:
+ case OP_ATR_POS:
+ case OP_ATR_VAL:
+ case OP_ATR_MIN:
+ case OP_ATR_MAX:
+ case TERNOP_IN_RANGE:
+ case BINOP_IN_BOUNDS:
+ case UNOP_IN_RANGE:
+ case OP_AGGREGATE:
+ case OP_OTHERS:
+ case OP_CHOICES:
+ case OP_POSITIONAL:
+ case OP_DISCRETE_RANGE:
+ case OP_NAME:
+ ada_forward_operator_length (exp, pc, &oplen, &nargs);
+ *pos += oplen;
+ break;
+
+ case BINOP_ASSIGN:
+ {
+ struct value *arg1;
+
+ *pos += 1;
+ arg1 = resolve_subexp (expp, pos, 0, NULL, parse_completion, tracker);
+ if (arg1 == NULL)
+ resolve_subexp (expp, pos, 1, NULL, parse_completion, tracker);
+ else
+ resolve_subexp (expp, pos, 1, value_type (arg1), parse_completion,
+ tracker);
+ break;
+ }
+
+ case UNOP_CAST:
+ *pos += 3;
+ nargs = 1;
+ break;
+
+ case BINOP_ADD:
+ case BINOP_SUB:
+ case BINOP_MUL:
+ case BINOP_DIV:
+ case BINOP_REM:
+ case BINOP_MOD:
+ case BINOP_EXP:
+ case BINOP_CONCAT:
+ case BINOP_LOGICAL_AND:
+ case BINOP_LOGICAL_OR:
+ case BINOP_BITWISE_AND:
+ case BINOP_BITWISE_IOR:
+ case BINOP_BITWISE_XOR:
+
+ case BINOP_EQUAL:
+ case BINOP_NOTEQUAL:
+ case BINOP_LESS:
+ case BINOP_GTR:
+ case BINOP_LEQ:
+ case BINOP_GEQ:
+
+ case BINOP_REPEAT:
+ case BINOP_SUBSCRIPT:
+ case BINOP_COMMA:
+ *pos += 1;
+ nargs = 2;
+ break;
+
+ case UNOP_NEG:
+ case UNOP_PLUS:
+ case UNOP_LOGICAL_NOT:
+ case UNOP_ABS:
+ case UNOP_IND:
+ *pos += 1;
+ nargs = 1;
+ break;
+
+ case OP_LONG:
+ case OP_FLOAT:
+ case OP_VAR_VALUE:
+ case OP_VAR_MSYM_VALUE:
+ *pos += 4;
+ break;
+
+ case OP_TYPE:
+ case OP_BOOL:
+ case OP_LAST:
+ case OP_INTERNALVAR:
+ *pos += 3;
+ break;
+
+ case UNOP_MEMVAL:
+ *pos += 3;
+ nargs = 1;
+ break;
+
+ case OP_REGISTER:
+ *pos += 4 + BYTES_TO_EXP_ELEM (exp->elts[pc + 1].longconst + 1);
+ break;
+
+ case STRUCTOP_STRUCT:
+ *pos += 4 + BYTES_TO_EXP_ELEM (exp->elts[pc + 1].longconst + 1);
+ nargs = 1;
+ break;
+
+ case TERNOP_SLICE:
+ *pos += 1;
+ nargs = 3;
+ break;
+
+ case OP_STRING:
+ break;
+
+ default:
+ error (_("Unexpected operator during name resolution"));
}
- return 0;
-}
-/* Returns true (non-zero) iff decoded name N0 should appear before N1
- in a listing of choices during disambiguation (see sort_choices, below).
- The idea is that overloadings of a subprogram name from the
- same package should sort in their source order. We settle for ordering
- such symbols by their trailing number (__N or $N). */
+ argvec = XALLOCAVEC (struct value *, nargs + 1);
+ for (i = 0; i < nargs; i += 1)
+ argvec[i] = resolve_subexp (expp, pos, 1, NULL, parse_completion,
+ tracker);
+ argvec[i] = NULL;
+ exp = expp->get ();
-static int
-encoded_ordered_before (const char *N0, const char *N1)
-{
- if (N1 == NULL)
- return 0;
- else if (N0 == NULL)
- return 1;
- else
+ /* Pass two: perform any resolution on principal operator. */
+ switch (op)
{
- int k0, k1;
+ default:
+ break;
- for (k0 = strlen (N0) - 1; k0 > 0 && isdigit (N0[k0]); k0 -= 1)
- ;
- for (k1 = strlen (N1) - 1; k1 > 0 && isdigit (N1[k1]); k1 -= 1)
- ;
- if ((N0[k0] == '_' || N0[k0] == '$') && N0[k0 + 1] != '\000'
- && (N1[k1] == '_' || N1[k1] == '$') && N1[k1 + 1] != '\000')
+ case OP_VAR_VALUE:
+ if (SYMBOL_DOMAIN (exp->elts[pc + 2].symbol) == UNDEF_DOMAIN)
{
- int n0, n1;
+ std::vector<struct block_symbol> candidates;
+ int n_candidates;
- n0 = k0;
- while (N0[n0] == '_' && n0 > 0 && N0[n0 - 1] == '_')
- n0 -= 1;
- n1 = k1;
- while (N1[n1] == '_' && n1 > 0 && N1[n1 - 1] == '_')
- n1 -= 1;
- if (n0 == n1 && strncmp (N0, N1, n0) == 0)
- return (atoi (N0 + k0 + 1) < atoi (N1 + k1 + 1));
- }
- return (strcmp (N0, N1) < 0);
- }
-}
+ n_candidates =
+ ada_lookup_symbol_list (SYMBOL_LINKAGE_NAME
+ (exp->elts[pc + 2].symbol),
+ exp->elts[pc + 1].block, VAR_DOMAIN,
+ &candidates);
-/* Sort SYMS[0..NSYMS-1] to put the choices in a canonical order by the
- encoded names. */
+ if (n_candidates > 1)
+ {
+ /* Types tend to get re-introduced locally, so if there
+ are any local symbols that are not types, first filter
+ out all types. */
+ int j;
+ for (j = 0; j < n_candidates; j += 1)
+ switch (SYMBOL_CLASS (candidates[j].symbol))
+ {
+ case LOC_REGISTER:
+ case LOC_ARG:
+ case LOC_REF_ARG:
+ case LOC_REGPARM_ADDR:
+ case LOC_LOCAL:
+ case LOC_COMPUTED:
+ goto FoundNonType;
+ default:
+ break;
+ }
+ FoundNonType:
+ if (j < n_candidates)
+ {
+ j = 0;
+ while (j < n_candidates)
+ {
+ if (SYMBOL_CLASS (candidates[j].symbol) == LOC_TYPEDEF)
+ {
+ candidates[j] = candidates[n_candidates - 1];
+ n_candidates -= 1;
+ }
+ else
+ j += 1;
+ }
+ }
+ }
-static void
-sort_choices (struct block_symbol syms[], int nsyms)
-{
- int i;
+ if (n_candidates == 0)
+ error (_("No definition found for %s"),
+ SYMBOL_PRINT_NAME (exp->elts[pc + 2].symbol));
+ else if (n_candidates == 1)
+ i = 0;
+ else if (deprocedure_p
+ && !is_nonfunction (candidates.data (), n_candidates))
+ {
+ i = ada_resolve_function
+ (candidates.data (), n_candidates, NULL, 0,
+ SYMBOL_LINKAGE_NAME (exp->elts[pc + 2].symbol),
+ context_type, parse_completion);
+ if (i < 0)
+ error (_("Could not find a match for %s"),
+ SYMBOL_PRINT_NAME (exp->elts[pc + 2].symbol));
+ }
+ else
+ {
+ printf_filtered (_("Multiple matches for %s\n"),
+ SYMBOL_PRINT_NAME (exp->elts[pc + 2].symbol));
+ user_select_syms (candidates.data (), n_candidates, 1);
+ i = 0;
+ }
- for (i = 1; i < nsyms; i += 1)
- {
- struct block_symbol sym = syms[i];
- int j;
+ exp->elts[pc + 1].block = candidates[i].block;
+ exp->elts[pc + 2].symbol = candidates[i].symbol;
+ tracker->update (candidates[i]);
+ }
- for (j = i - 1; j >= 0; j -= 1)
+ if (deprocedure_p
+ && (TYPE_CODE (SYMBOL_TYPE (exp->elts[pc + 2].symbol))
+ == TYPE_CODE_FUNC))
{
- if (encoded_ordered_before (SYMBOL_LINKAGE_NAME (syms[j].symbol),
- SYMBOL_LINKAGE_NAME (sym.symbol)))
- break;
- syms[j + 1] = syms[j];
+ replace_operator_with_call (expp, pc, 0, 4,
+ exp->elts[pc + 2].symbol,
+ exp->elts[pc + 1].block);
+ exp = expp->get ();
}
- syms[j + 1] = sym;
- }
-}
+ break;
+
+ case OP_FUNCALL:
+ {
+ if (exp->elts[pc + 3].opcode == OP_VAR_VALUE
+ && SYMBOL_DOMAIN (exp->elts[pc + 5].symbol) == UNDEF_DOMAIN)
+ {
+ std::vector<struct block_symbol> candidates;
+ int n_candidates;
+
+ n_candidates =
+ ada_lookup_symbol_list (SYMBOL_LINKAGE_NAME
+ (exp->elts[pc + 5].symbol),
+ exp->elts[pc + 4].block, VAR_DOMAIN,
+ &candidates);
-/* Whether GDB should display formals and return types for functions in the
- overloads selection menu. */
-static bool print_signatures = true;
+ if (n_candidates == 1)
+ i = 0;
+ else
+ {
+ i = ada_resolve_function
+ (candidates.data (), n_candidates,
+ argvec, nargs,
+ SYMBOL_LINKAGE_NAME (exp->elts[pc + 5].symbol),
+ context_type, parse_completion);
+ if (i < 0)
+ error (_("Could not find a match for %s"),
+ SYMBOL_PRINT_NAME (exp->elts[pc + 5].symbol));
+ }
-/* Print the signature for SYM on STREAM according to the FLAGS options. For
- all but functions, the signature is just the name of the symbol. For
- functions, this is the name of the function, the list of types for formals
- and the return type (if any). */
+ exp->elts[pc + 4].block = candidates[i].block;
+ exp->elts[pc + 5].symbol = candidates[i].symbol;
+ tracker->update (candidates[i]);
+ }
+ }
+ break;
+ case BINOP_ADD:
+ case BINOP_SUB:
+ case BINOP_MUL:
+ case BINOP_DIV:
+ case BINOP_REM:
+ case BINOP_MOD:
+ case BINOP_CONCAT:
+ case BINOP_BITWISE_AND:
+ case BINOP_BITWISE_IOR:
+ case BINOP_BITWISE_XOR:
+ case BINOP_EQUAL:
+ case BINOP_NOTEQUAL:
+ case BINOP_LESS:
+ case BINOP_GTR:
+ case BINOP_LEQ:
+ case BINOP_GEQ:
+ case BINOP_EXP:
+ case UNOP_NEG:
+ case UNOP_PLUS:
+ case UNOP_LOGICAL_NOT:
+ case UNOP_ABS:
+ if (possible_user_operator_p (op, argvec))
+ {
+ std::vector<struct block_symbol> candidates;
+ int n_candidates;
-static void
-ada_print_symbol_signature (struct ui_file *stream, struct symbol *sym,
- const struct type_print_options *flags)
-{
- struct type *type = SYMBOL_TYPE (sym);
+ n_candidates =
+ ada_lookup_symbol_list (ada_decoded_op_name (op),
+ NULL, VAR_DOMAIN,
+ &candidates);
- fprintf_filtered (stream, "%s", SYMBOL_PRINT_NAME (sym));
- if (!print_signatures
- || type == NULL
- || TYPE_CODE (type) != TYPE_CODE_FUNC)
- return;
+ i = ada_resolve_function (candidates.data (), n_candidates, argvec,
+ nargs, ada_decoded_op_name (op), NULL,
+ parse_completion);
+ if (i < 0)
+ break;
- if (TYPE_NFIELDS (type) > 0)
- {
- int i;
+ replace_operator_with_call (expp, pc, nargs, 1,
+ candidates[i].symbol,
+ candidates[i].block);
+ exp = expp->get ();
+ }
+ break;
- fprintf_filtered (stream, " (");
- for (i = 0; i < TYPE_NFIELDS (type); ++i)
- {
- if (i > 0)
- fprintf_filtered (stream, "; ");
- ada_print_type (TYPE_FIELD_TYPE (type, i), NULL, stream, -1, 0,
- flags);
- }
- fprintf_filtered (stream, ")");
- }
- if (TYPE_TARGET_TYPE (type) != NULL
- && TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID)
- {
- fprintf_filtered (stream, " return ");
- ada_print_type (TYPE_TARGET_TYPE (type), NULL, stream, -1, 0, flags);
+ case OP_TYPE:
+ case OP_REGISTER:
+ return NULL;
}
-}
-/* Given a list of NSYMS symbols in SYMS, select up to MAX_RESULTS>0
- by asking the user (if necessary), returning the number selected,
- and setting the first elements of SYMS items. Error if no symbols
- selected. */
+ *pos = pc;
+ if (exp->elts[pc].opcode == OP_VAR_MSYM_VALUE)
+ return evaluate_var_msym_value (EVAL_AVOID_SIDE_EFFECTS,
+ exp->elts[pc + 1].objfile,
+ exp->elts[pc + 2].msymbol);
+ else
+ return evaluate_subexp_type (exp, pos);
+}
-/* NOTE: Adapted from decode_line_2 in symtab.c, with which it ought
- to be re-integrated one of these days. */
+/* Return non-zero if formal type FTYPE matches actual type ATYPE. If
+ MAY_DEREF is non-zero, the formal may be a pointer and the actual
+ a non-pointer. */
+/* The term "match" here is rather loose. The match is heuristic and
+ liberal. */
-int
-user_select_syms (struct block_symbol *syms, int nsyms, int max_results)
+static int
+ada_type_match (struct type *ftype, struct type *atype, int may_deref)
{
- int i;
- int *chosen = XALLOCAVEC (int , nsyms);
- int n_chosen;
- int first_choice = (max_results == 1) ? 1 : 2;
- const char *select_mode = multiple_symbols_select_mode ();
-
- if (max_results < 1)
- error (_("Request to select 0 symbols!"));
- if (nsyms <= 1)
- return nsyms;
-
- if (select_mode == multiple_symbols_cancel)
- error (_("\
-canceled because the command is ambiguous\n\
-See set/show multiple-symbol."));
-
- /* If select_mode is "all", then return all possible symbols.
- Only do that if more than one symbol can be selected, of course.
- Otherwise, display the menu as usual. */
- if (select_mode == multiple_symbols_all && max_results > 1)
- return nsyms;
-
- printf_filtered (_("[0] cancel\n"));
- if (max_results > 1)
- printf_filtered (_("[1] all\n"));
+ ftype = ada_check_typedef (ftype);
+ atype = ada_check_typedef (atype);
- sort_choices (syms, nsyms);
+ if (TYPE_CODE (ftype) == TYPE_CODE_REF)
+ ftype = TYPE_TARGET_TYPE (ftype);
+ if (TYPE_CODE (atype) == TYPE_CODE_REF)
+ atype = TYPE_TARGET_TYPE (atype);
- for (i = 0; i < nsyms; i += 1)
+ switch (TYPE_CODE (ftype))
{
- if (syms[i].symbol == NULL)
- continue;
-
- if (SYMBOL_CLASS (syms[i].symbol) == LOC_BLOCK)
- {
- struct symtab_and_line sal =
- find_function_start_sal (syms[i].symbol, 1);
-
- printf_filtered ("[%d] ", i + first_choice);
- ada_print_symbol_signature (gdb_stdout, syms[i].symbol,
- &type_print_raw_options);
- if (sal.symtab == NULL)
- printf_filtered (_(" at %p[<no source file available>%p]:%d\n"),
- metadata_style.style ().ptr (), nullptr, sal.line);
- else
- printf_filtered
- (_(" at %ps:%d\n"),
- styled_string (file_name_style.style (),
- symtab_to_filename_for_display (sal.symtab)),
- sal.line);
- continue;
- }
+ default:
+ return TYPE_CODE (ftype) == TYPE_CODE (atype);
+ case TYPE_CODE_PTR:
+ if (TYPE_CODE (atype) == TYPE_CODE_PTR)
+ return ada_type_match (TYPE_TARGET_TYPE (ftype),
+ TYPE_TARGET_TYPE (atype), 0);
else
+ return (may_deref
+ && ada_type_match (TYPE_TARGET_TYPE (ftype), atype, 0));
+ case TYPE_CODE_INT:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_RANGE:
+ switch (TYPE_CODE (atype))
{
- int is_enumeral =
- (SYMBOL_CLASS (syms[i].symbol) == LOC_CONST
- && SYMBOL_TYPE (syms[i].symbol) != NULL
- && TYPE_CODE (SYMBOL_TYPE (syms[i].symbol)) == TYPE_CODE_ENUM);
- struct symtab *symtab = NULL;
-
- if (SYMBOL_OBJFILE_OWNED (syms[i].symbol))
- symtab = symbol_symtab (syms[i].symbol);
-
- if (SYMBOL_LINE (syms[i].symbol) != 0 && symtab != NULL)
- {
- printf_filtered ("[%d] ", i + first_choice);
- ada_print_symbol_signature (gdb_stdout, syms[i].symbol,
- &type_print_raw_options);
- printf_filtered (_(" at %s:%d\n"),
- symtab_to_filename_for_display (symtab),
- SYMBOL_LINE (syms[i].symbol));
- }
- else if (is_enumeral
- && TYPE_NAME (SYMBOL_TYPE (syms[i].symbol)) != NULL)
- {
- printf_filtered (("[%d] "), i + first_choice);
- ada_print_type (SYMBOL_TYPE (syms[i].symbol), NULL,
- gdb_stdout, -1, 0, &type_print_raw_options);
- printf_filtered (_("'(%s) (enumeral)\n"),
- SYMBOL_PRINT_NAME (syms[i].symbol));
- }
- else
- {
- printf_filtered ("[%d] ", i + first_choice);
- ada_print_symbol_signature (gdb_stdout, syms[i].symbol,
- &type_print_raw_options);
-
- if (symtab != NULL)
- printf_filtered (is_enumeral
- ? _(" in %s (enumeral)\n")
- : _(" at %s:?\n"),
- symtab_to_filename_for_display (symtab));
- else
- printf_filtered (is_enumeral
- ? _(" (enumeral)\n")
- : _(" at ?\n"));
- }
+ case TYPE_CODE_INT:
+ case TYPE_CODE_ENUM:
+ case TYPE_CODE_RANGE:
+ return 1;
+ default:
+ return 0;
}
- }
- n_chosen = get_selections (chosen, nsyms, max_results, max_results > 1,
- "overload-choice");
+ case TYPE_CODE_ARRAY:
+ return (TYPE_CODE (atype) == TYPE_CODE_ARRAY
+ || ada_is_array_descriptor_type (atype));
- for (i = 0; i < n_chosen; i += 1)
- syms[i] = syms[chosen[i]];
+ case TYPE_CODE_STRUCT:
+ if (ada_is_array_descriptor_type (ftype))
+ return (TYPE_CODE (atype) == TYPE_CODE_ARRAY
+ || ada_is_array_descriptor_type (atype));
+ else
+ return (TYPE_CODE (atype) == TYPE_CODE_STRUCT
+ && !ada_is_array_descriptor_type (atype));
- return n_chosen;
+ case TYPE_CODE_UNION:
+ case TYPE_CODE_FLT:
+ return (TYPE_CODE (atype) == TYPE_CODE (ftype));
+ }
}
-/* Read and validate a set of numeric choices from the user in the
- range 0 .. N_CHOICES-1. Place the results in increasing
- order in CHOICES[0 .. N-1], and return N.
+/* Return non-zero if the formals of FUNC "sufficiently match" the
+ vector of actual argument types ACTUALS of size N_ACTUALS. FUNC
+ may also be an enumeral, in which case it is treated as a 0-
+ argument function. */
- The user types choices as a sequence of numbers on one line
- separated by blanks, encoding them as follows:
+static int
+ada_args_match (struct symbol *func, struct value **actuals, int n_actuals)
+{
+ int i;
+ struct type *func_type = SYMBOL_TYPE (func);
- + A choice of 0 means to cancel the selection, throwing an error.
- + If IS_ALL_CHOICE, a choice of 1 selects the entire set 0 .. N_CHOICES-1.
- + The user chooses k by typing k+IS_ALL_CHOICE+1.
+ if (SYMBOL_CLASS (func) == LOC_CONST
+ && TYPE_CODE (func_type) == TYPE_CODE_ENUM)
+ return (n_actuals == 0);
+ else if (func_type == NULL || TYPE_CODE (func_type) != TYPE_CODE_FUNC)
+ return 0;
- The user is not allowed to choose more than MAX_RESULTS values.
+ if (TYPE_NFIELDS (func_type) != n_actuals)
+ return 0;
- ANNOTATION_SUFFIX, if present, is used to annotate the input
- prompts (for use with the -f switch). */
+ for (i = 0; i < n_actuals; i += 1)
+ {
+ if (actuals[i] == NULL)
+ return 0;
+ else
+ {
+ struct type *ftype = ada_check_typedef (TYPE_FIELD_TYPE (func_type,
+ i));
+ struct type *atype = ada_check_typedef (value_type (actuals[i]));
-int
-get_selections (int *choices, int n_choices, int max_results,
- int is_all_choice, const char *annotation_suffix)
-{
- char *args;
- const char *prompt;
- int n_chosen;
- int first_choice = is_all_choice ? 2 : 1;
+ if (!ada_type_match (ftype, atype, 1))
+ return 0;
+ }
+ }
+ return 1;
+}
- prompt = getenv ("PS2");
- if (prompt == NULL)
- prompt = "> ";
+/* False iff function type FUNC_TYPE definitely does not produce a value
+ compatible with type CONTEXT_TYPE. Conservatively returns 1 if
+ FUNC_TYPE is not a valid function type with a non-null return type
+ or an enumerated type. A null CONTEXT_TYPE indicates any non-void type. */
- args = command_line_input (prompt, annotation_suffix);
+static int
+return_match (struct type *func_type, struct type *context_type)
+{
+ struct type *return_type;
- if (args == NULL)
- error_no_arg (_("one or more choice numbers"));
+ if (func_type == NULL)
+ return 1;
- n_chosen = 0;
+ if (TYPE_CODE (func_type) == TYPE_CODE_FUNC)
+ return_type = get_base_type (TYPE_TARGET_TYPE (func_type));
+ else
+ return_type = get_base_type (func_type);
+ if (return_type == NULL)
+ return 1;
- /* Set choices[0 .. n_chosen-1] to the users' choices in ascending
- order, as given in args. Choices are validated. */
- while (1)
- {
- char *args2;
- int choice, j;
+ context_type = get_base_type (context_type);
- args = skip_spaces (args);
- if (*args == '\0' && n_chosen == 0)
- error_no_arg (_("one or more choice numbers"));
- else if (*args == '\0')
- break;
+ if (TYPE_CODE (return_type) == TYPE_CODE_ENUM)
+ return context_type == NULL || return_type == context_type;
+ else if (context_type == NULL)
+ return TYPE_CODE (return_type) != TYPE_CODE_VOID;
+ else
+ return TYPE_CODE (return_type) == TYPE_CODE (context_type);
+}
- choice = strtol (args, &args2, 10);
- if (args == args2 || choice < 0
- || choice > n_choices + first_choice - 1)
- error (_("Argument must be choice number"));
- args = args2;
- if (choice == 0)
- error (_("cancelled"));
+/* Returns the index in SYMS[0..NSYMS-1] that contains the symbol for the
+ function (if any) that matches the types of the NARGS arguments in
+ ARGS. If CONTEXT_TYPE is non-null and there is at least one match
+ that returns that type, then eliminate matches that don't. If
+ CONTEXT_TYPE is void and there is at least one match that does not
+ return void, eliminate all matches that do.
- if (choice < first_choice)
- {
- n_chosen = n_choices;
- for (j = 0; j < n_choices; j += 1)
- choices[j] = j;
- break;
- }
- choice -= first_choice;
+ Asks the user if there is more than one match remaining. Returns -1
+ if there is no such symbol or none is selected. NAME is used
+ solely for messages. May re-arrange and modify SYMS in
+ the process; the index returned is for the modified vector. */
- for (j = n_chosen - 1; j >= 0 && choice < choices[j]; j -= 1)
- {
- }
+static int
+ada_resolve_function (struct block_symbol syms[],
+ int nsyms, struct value **args, int nargs,
+ const char *name, struct type *context_type,
+ int parse_completion)
+{
+ int fallback;
+ int k;
+ int m; /* Number of hits */
- if (j < 0 || choice != choices[j])
+ m = 0;
+ /* In the first pass of the loop, we only accept functions matching
+ context_type. If none are found, we add a second pass of the loop
+ where every function is accepted. */
+ for (fallback = 0; m == 0 && fallback < 2; fallback++)
+ {
+ for (k = 0; k < nsyms; k += 1)
{
- int k;
+ struct type *type = ada_check_typedef (SYMBOL_TYPE (syms[k].symbol));
- for (k = n_chosen - 1; k > j; k -= 1)
- choices[k + 1] = choices[k];
- choices[j + 1] = choice;
- n_chosen += 1;
+ if (ada_args_match (syms[k].symbol, args, nargs)
+ && (fallback || return_match (type, context_type)))
+ {
+ syms[m] = syms[k];
+ m += 1;
+ }
}
}
- if (n_chosen > max_results)
- error (_("Select no more than %d of the above"), max_results);
-
- return n_chosen;
+ /* If we got multiple matches, ask the user which one to use. Don't do this
+ interactive thing during completion, though, as the purpose of the
+ completion is providing a list of all possible matches. Prompting the
+ user to filter it down would be completely unexpected in this case. */
+ if (m == 0)
+ return -1;
+ else if (m > 1 && !parse_completion)
+ {
+ printf_filtered (_("Multiple matches for %s\n"), name);
+ user_select_syms (syms, m, 1);
+ return 0;
+ }
+ return 0;
}
/* Replace the operator of length OPLEN at position PC in *EXPP with a call
}
}
- if (renamed_entity != NULL)
- *renamed_entity = info;
- suffix = strstr (info, "___XE");
- if (suffix == NULL || suffix == info)
- return ADA_NOT_RENAMING;
- if (len != NULL)
- *len = strlen (info) - strlen (suffix);
- suffix += 5;
- if (renaming_expr != NULL)
- *renaming_expr = suffix;
- return kind;
-}
+ if (renamed_entity != NULL)
+ *renamed_entity = info;
+ suffix = strstr (info, "___XE");
+ if (suffix == NULL || suffix == info)
+ return ADA_NOT_RENAMING;
+ if (len != NULL)
+ *len = strlen (info) - strlen (suffix);
+ suffix += 5;
+ if (renaming_expr != NULL)
+ *renaming_expr = suffix;
+ return kind;
+}
+
+/* Compute the value of the given RENAMING_SYM, which is expected to
+ be a symbol encoding a renaming expression. BLOCK is the block
+ used to evaluate the renaming. */
+
+static struct value *
+ada_read_renaming_var_value (struct symbol *renaming_sym,
+ const struct block *block)
+{
+ const char *sym_name;
+
+ sym_name = SYMBOL_LINKAGE_NAME (renaming_sym);
+ expression_up expr = parse_exp_1 (&sym_name, 0, block, 0);
+ return evaluate_expression (expr.get ());
+}
+\f
+
+ /* Evaluation: Function Calls */
+
+/* Return an lvalue containing the value VAL. This is the identity on
+ lvalues, and otherwise has the side-effect of allocating memory
+ in the inferior where a copy of the value contents is copied. */
+
+static struct value *
+ensure_lval (struct value *val)
+{
+ if (VALUE_LVAL (val) == not_lval
+ || VALUE_LVAL (val) == lval_internalvar)
+ {
+ int len = TYPE_LENGTH (ada_check_typedef (value_type (val)));
+ const CORE_ADDR addr =
+ value_as_long (value_allocate_space_in_inferior (len));
+
+ VALUE_LVAL (val) = lval_memory;
+ set_value_address (val, addr);
+ write_memory (addr, value_contents (val), len);
+ }
+
+ return val;
+}
+
+/* Given ARG, a value of type (pointer or reference to a)*
+ structure/union, extract the component named NAME from the ultimate
+ target structure/union and return it as a value with its
+ appropriate type.
+
+ The routine searches for NAME among all members of the structure itself
+ and (recursively) among all members of any wrapper members
+ (e.g., '_parent').
+
+ If NO_ERR, then simply return NULL in case of error, rather than
+ calling error. */
+
+static struct value *
+ada_value_struct_elt (struct value *arg, const char *name, int no_err)
+{
+ struct type *t, *t1;
+ struct value *v;
+ int check_tag;
+
+ v = NULL;
+ t1 = t = ada_check_typedef (value_type (arg));
+ if (TYPE_CODE (t) == TYPE_CODE_REF)
+ {
+ t1 = TYPE_TARGET_TYPE (t);
+ if (t1 == NULL)
+ goto BadValue;
+ t1 = ada_check_typedef (t1);
+ if (TYPE_CODE (t1) == TYPE_CODE_PTR)
+ {
+ arg = coerce_ref (arg);
+ t = t1;
+ }
+ }
+
+ while (TYPE_CODE (t) == TYPE_CODE_PTR)
+ {
+ t1 = TYPE_TARGET_TYPE (t);
+ if (t1 == NULL)
+ goto BadValue;
+ t1 = ada_check_typedef (t1);
+ if (TYPE_CODE (t1) == TYPE_CODE_PTR)
+ {
+ arg = value_ind (arg);
+ t = t1;
+ }
+ else
+ break;
+ }
-/* Compute the value of the given RENAMING_SYM, which is expected to
- be a symbol encoding a renaming expression. BLOCK is the block
- used to evaluate the renaming. */
+ if (TYPE_CODE (t1) != TYPE_CODE_STRUCT && TYPE_CODE (t1) != TYPE_CODE_UNION)
+ goto BadValue;
-static struct value *
-ada_read_renaming_var_value (struct symbol *renaming_sym,
- const struct block *block)
-{
- const char *sym_name;
+ if (t1 == t)
+ v = ada_search_struct_field (name, arg, 0, t);
+ else
+ {
+ int bit_offset, bit_size, byte_offset;
+ struct type *field_type;
+ CORE_ADDR address;
- sym_name = SYMBOL_LINKAGE_NAME (renaming_sym);
- expression_up expr = parse_exp_1 (&sym_name, 0, block, 0);
- return evaluate_expression (expr.get ());
-}
-\f
+ if (TYPE_CODE (t) == TYPE_CODE_PTR)
+ address = value_address (ada_value_ind (arg));
+ else
+ address = value_address (ada_coerce_ref (arg));
- /* Evaluation: Function Calls */
+ /* Check to see if this is a tagged type. We also need to handle
+ the case where the type is a reference to a tagged type, but
+ we have to be careful to exclude pointers to tagged types.
+ The latter should be shown as usual (as a pointer), whereas
+ a reference should mostly be transparent to the user. */
-/* Return an lvalue containing the value VAL. This is the identity on
- lvalues, and otherwise has the side-effect of allocating memory
- in the inferior where a copy of the value contents is copied. */
+ if (ada_is_tagged_type (t1, 0)
+ || (TYPE_CODE (t1) == TYPE_CODE_REF
+ && ada_is_tagged_type (TYPE_TARGET_TYPE (t1), 0)))
+ {
+ /* We first try to find the searched field in the current type.
+ If not found then let's look in the fixed type. */
-static struct value *
-ensure_lval (struct value *val)
-{
- if (VALUE_LVAL (val) == not_lval
- || VALUE_LVAL (val) == lval_internalvar)
- {
- int len = TYPE_LENGTH (ada_check_typedef (value_type (val)));
- const CORE_ADDR addr =
- value_as_long (value_allocate_space_in_inferior (len));
+ if (!find_struct_field (name, t1, 0,
+ &field_type, &byte_offset, &bit_offset,
+ &bit_size, NULL))
+ check_tag = 1;
+ else
+ check_tag = 0;
+ }
+ else
+ check_tag = 0;
- VALUE_LVAL (val) = lval_memory;
- set_value_address (val, addr);
- write_memory (addr, value_contents (val), len);
+ /* Convert to fixed type in all cases, so that we have proper
+ offsets to each field in unconstrained record types. */
+ t1 = ada_to_fixed_type (ada_get_base_type (t1), NULL,
+ address, NULL, check_tag);
+
+ if (find_struct_field (name, t1, 0,
+ &field_type, &byte_offset, &bit_offset,
+ &bit_size, NULL))
+ {
+ if (bit_size != 0)
+ {
+ if (TYPE_CODE (t) == TYPE_CODE_REF)
+ arg = ada_coerce_ref (arg);
+ else
+ arg = ada_value_ind (arg);
+ v = ada_value_primitive_packed_val (arg, NULL, byte_offset,
+ bit_offset, bit_size,
+ field_type);
+ }
+ else
+ v = value_at_lazy (field_type, address + byte_offset);
+ }
}
- return val;
+ if (v != NULL || no_err)
+ return v;
+ else
+ error (_("There is no member named %s."), name);
+
+ BadValue:
+ if (no_err)
+ return NULL;
+ else
+ error (_("Attempt to extract a component of "
+ "a value that is not a record."));
}
/* Return the value ACTUAL, converted to be an appropriate value for a
/* The type of the tag on VAL. */
-struct type *
+static struct type *
ada_tag_type (struct value *val)
{
return ada_lookup_struct_elt_type (value_type (val), "_tag", 1, 0);
/* The value of the tag on VAL. */
-struct value *
+static struct value *
ada_value_tag (struct value *val)
{
return ada_value_struct_elt (val, "_tag", 0);
valid field number within it, returns 1 iff field FIELD_NUM of TYPE
represents a 'when others' clause; otherwise 0. */
-int
+static int
ada_is_others_clause (struct type *type, int field_num)
{
const char *name = TYPE_FIELD_NAME (type, field_num);
and FIELD_NUM is a valid field number within it, returns 1 iff VAL is
in the range encoded by field FIELD_NUM of TYPE; otherwise 0. */
-int
+static int
ada_in_variant (LONGEST val, struct type *type, int field_num)
{
const char *name = TYPE_FIELD_NAME (type, field_num);
return NULL;
}
-/* Given ARG, a value of type (pointer or reference to a)*
- structure/union, extract the component named NAME from the ultimate
- target structure/union and return it as a value with its
- appropriate type.
-
- The routine searches for NAME among all members of the structure itself
- and (recursively) among all members of any wrapper members
- (e.g., '_parent').
-
- If NO_ERR, then simply return NULL in case of error, rather than
- calling error. */
-
-struct value *
-ada_value_struct_elt (struct value *arg, const char *name, int no_err)
-{
- struct type *t, *t1;
- struct value *v;
- int check_tag;
-
- v = NULL;
- t1 = t = ada_check_typedef (value_type (arg));
- if (TYPE_CODE (t) == TYPE_CODE_REF)
- {
- t1 = TYPE_TARGET_TYPE (t);
- if (t1 == NULL)
- goto BadValue;
- t1 = ada_check_typedef (t1);
- if (TYPE_CODE (t1) == TYPE_CODE_PTR)
- {
- arg = coerce_ref (arg);
- t = t1;
- }
- }
-
- while (TYPE_CODE (t) == TYPE_CODE_PTR)
- {
- t1 = TYPE_TARGET_TYPE (t);
- if (t1 == NULL)
- goto BadValue;
- t1 = ada_check_typedef (t1);
- if (TYPE_CODE (t1) == TYPE_CODE_PTR)
- {
- arg = value_ind (arg);
- t = t1;
- }
- else
- break;
- }
-
- if (TYPE_CODE (t1) != TYPE_CODE_STRUCT && TYPE_CODE (t1) != TYPE_CODE_UNION)
- goto BadValue;
-
- if (t1 == t)
- v = ada_search_struct_field (name, arg, 0, t);
- else
- {
- int bit_offset, bit_size, byte_offset;
- struct type *field_type;
- CORE_ADDR address;
-
- if (TYPE_CODE (t) == TYPE_CODE_PTR)
- address = value_address (ada_value_ind (arg));
- else
- address = value_address (ada_coerce_ref (arg));
-
- /* Check to see if this is a tagged type. We also need to handle
- the case where the type is a reference to a tagged type, but
- we have to be careful to exclude pointers to tagged types.
- The latter should be shown as usual (as a pointer), whereas
- a reference should mostly be transparent to the user. */
-
- if (ada_is_tagged_type (t1, 0)
- || (TYPE_CODE (t1) == TYPE_CODE_REF
- && ada_is_tagged_type (TYPE_TARGET_TYPE (t1), 0)))
- {
- /* We first try to find the searched field in the current type.
- If not found then let's look in the fixed type. */
-
- if (!find_struct_field (name, t1, 0,
- &field_type, &byte_offset, &bit_offset,
- &bit_size, NULL))
- check_tag = 1;
- else
- check_tag = 0;
- }
- else
- check_tag = 0;
-
- /* Convert to fixed type in all cases, so that we have proper
- offsets to each field in unconstrained record types. */
- t1 = ada_to_fixed_type (ada_get_base_type (t1), NULL,
- address, NULL, check_tag);
-
- if (find_struct_field (name, t1, 0,
- &field_type, &byte_offset, &bit_offset,
- &bit_size, NULL))
- {
- if (bit_size != 0)
- {
- if (TYPE_CODE (t) == TYPE_CODE_REF)
- arg = ada_coerce_ref (arg);
- else
- arg = ada_value_ind (arg);
- v = ada_value_primitive_packed_val (arg, NULL, byte_offset,
- bit_offset, bit_size,
- field_type);
- }
- else
- v = value_at_lazy (field_type, address + byte_offset);
- }
- }
-
- if (v != NULL || no_err)
- return v;
- else
- error (_("There is no member named %s."), name);
-
- BadValue:
- if (no_err)
- return NULL;
- else
- error (_("Attempt to extract a component of "
- "a value that is not a record."));
-}
-
/* Return a string representation of type TYPE. */
static std::string
0
};
-const char *
+static const char *
ada_attribute_name (enum exp_opcode n)
{
if (n >= OP_ATR_FIRST && n <= (int) OP_ATR_VAL)