+ fprintf_filtered (stream, " (");
+ for (i = 0; i < type->num_fields (); ++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_TARGET_TYPE (type)->code () != TYPE_CODE_VOID)
+ {
+ fprintf_filtered (stream, " return ");
+ ada_print_type (TYPE_TARGET_TYPE (type), NULL, stream, -1, 0, flags);
+ }
+}
+
+/* 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.
+
+ The user types choices as a sequence of numbers on one line
+ separated by blanks, encoding them as follows:
+
+ + 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.
+
+ The user is not allowed to choose more than MAX_RESULTS values.
+
+ ANNOTATION_SUFFIX, if present, is used to annotate the input
+ prompts (for use with the -f switch). */
+
+static int
+get_selections (int *choices, int n_choices, int max_results,
+ int is_all_choice, const char *annotation_suffix)
+{
+ const char *args;
+ const char *prompt;
+ int n_chosen;
+ int first_choice = is_all_choice ? 2 : 1;
+
+ prompt = getenv ("PS2");
+ if (prompt == NULL)
+ prompt = "> ";
+
+ args = command_line_input (prompt, annotation_suffix);
+
+ if (args == NULL)
+ error_no_arg (_("one or more choice numbers"));
+
+ n_chosen = 0;
+
+ /* 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;
+
+ args = skip_spaces (args);
+ if (*args == '\0' && n_chosen == 0)
+ error_no_arg (_("one or more choice numbers"));
+ else if (*args == '\0')
+ break;
+
+ 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"));
+
+ if (choice < first_choice)
+ {
+ n_chosen = n_choices;
+ for (j = 0; j < n_choices; j += 1)
+ choices[j] = j;
+ break;
+ }
+ choice -= first_choice;
+
+ for (j = n_chosen - 1; j >= 0 && choice < choices[j]; j -= 1)
+ {
+ }
+
+ if (j < 0 || choice != choices[j])
+ {
+ int k;
+
+ for (k = n_chosen - 1; k > j; k -= 1)
+ choices[k + 1] = choices[k];
+ choices[j + 1] = choice;
+ n_chosen += 1;
+ }
+ }
+
+ if (n_chosen > max_results)
+ error (_("Select no more than %d of the above"), max_results);
+
+ return n_chosen;
+}
+
+/* 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
+user_select_syms (struct block_symbol *syms, int nsyms, int max_results)
+{
+ 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"));
+
+ sort_choices (syms, nsyms);
+
+ for (i = 0; i < nsyms; i += 1)
+ {
+ 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;
+ }
+ else
+ {
+ int is_enumeral =
+ (SYMBOL_CLASS (syms[i].symbol) == LOC_CONST
+ && SYMBOL_TYPE (syms[i].symbol) != NULL
+ && SYMBOL_TYPE (syms[i].symbol)->code () == 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
+ && SYMBOL_TYPE (syms[i].symbol)->name () != 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"),
+ syms[i].symbol->print_name ());
+ }
+ 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"));
+ }
+ }
+ }
+
+ n_chosen = get_selections (chosen, nsyms, max_results, max_results > 1,
+ "overload-choice");
+
+ for (i = 0; i < n_chosen; i += 1)
+ syms[i] = syms[chosen[i]];
+
+ return n_chosen;
+}
+
+/* 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)
+{
+ struct type *context_type = NULL;
+ int pc = 0;
+
+ if (void_context_p)
+ context_type = builtin_type ((*expp)->gdbarch)->builtin_void;
+
+ resolve_subexp (expp, &pc, 1, context_type, parse_completion, tracker);
+}
+
+/* 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 struct value *
+resolve_subexp (expression_up *expp, int *pos, int deprocedure_p,
+ struct type *context_type, int parse_completion,
+ innermost_block_tracker *tracker)
+{
+ 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)
+ {
+ 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;
+
+ 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: