X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fada-lang.c;h=098a5a6858f71cb99a9c3caa3dc237ccf6da436b;hb=cd9a314824b2b87207a8ba7a8003639989d2406b;hp=c3e562c0bc90fb4debd3c37ec415d37aea863e5e;hpb=886d459fbea73da4b07bae37f4526b766cbd90e8;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index c3e562c0bc..098a5a6858 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -57,6 +57,7 @@ #include "gdbsupport/function-view.h" #include "gdbsupport/byte-vector.h" #include +#include "ada-exp.h" /* Define whether or not the C operator '/' truncates towards zero for differently signed operands (truncation direction is undefined in C). @@ -100,24 +101,22 @@ static int ada_args_match (struct symbol *, struct value **, int); static struct value *make_array_descriptor (struct type *, struct value *); -static void ada_add_block_symbols (struct obstack *, +static void ada_add_block_symbols (std::vector &, const struct block *, const lookup_name_info &lookup_name, domain_enum, struct objfile *); -static void ada_add_all_symbols (struct obstack *, const struct block *, +static void ada_add_all_symbols (std::vector &, + const struct block *, const lookup_name_info &lookup_name, domain_enum, int, int *); -static int is_nonfunction (struct block_symbol *, int); +static int is_nonfunction (const std::vector &); -static void add_defn_to_vec (struct obstack *, struct symbol *, +static void add_defn_to_vec (std::vector &, + struct symbol *, const struct block *); -static int num_defns_collected (struct obstack *); - -static struct block_symbol *defns_collected (struct obstack *, int); - static struct value *resolve_subexp (expression_up *, int *, int, struct type *, int, innermost_block_tracker *); @@ -194,8 +193,6 @@ static struct value *value_pos_atr (struct type *, struct value *); static struct value *val_atr (struct type *, LONGEST); -static struct value *value_val_atr (struct type *, struct value *); - static struct symbol *standard_lookup (const char *, const struct block *, domain_enum); @@ -205,7 +202,7 @@ static struct value *ada_search_struct_field (const char *, struct value *, int, static int find_struct_field (const char *, struct type *, int, struct type **, int *, int *, int *, int *); -static int ada_resolve_function (struct block_symbol *, int, +static int ada_resolve_function (std::vector &, struct value **, int, const char *, struct type *, int); @@ -477,29 +474,6 @@ add_angle_brackets (const char *str) return string_printf ("<%s>", str); } -/* 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. */ - -static void * -grow_vect (void *vect, size_t *size, size_t min_size, int element_size) -{ - if (*size < min_size) - { - *size *= 2; - if (*size < min_size) - *size = min_size; - vect = xrealloc (vect, *size * element_size); - } - return vect; -} - /* True (non-zero) iff TARGET matches FIELD_NAME up to any trailing suffix of FIELD_NAME beginning "___". */ @@ -963,30 +937,21 @@ ada_encode (const char *decoded) quotes, unfolded, but with the quotes stripped away. Result good to next call. */ -static char * +static const char * ada_fold_name (gdb::string_view name) { - static char *fold_buffer = NULL; - static size_t fold_buffer_size = 0; - - int len = name.size (); - GROW_VECT (fold_buffer, fold_buffer_size, len + 1); + static std::string fold_storage; if (!name.empty () && name[0] == '\'') - { - strncpy (fold_buffer, name.data () + 1, len - 2); - fold_buffer[len - 2] = '\000'; - } + fold_storage = gdb::to_string (name.substr (1, name.size () - 2)); else { - int i; - - for (i = 0; i < len; i += 1) - fold_buffer[i] = tolower (name[i]); - fold_buffer[i] = '\0'; + fold_storage = gdb::to_string (name); + for (int i = 0; i < name.size (); i += 1) + fold_storage[i] = tolower (fold_storage[i]); } - return fold_buffer; + return fold_storage.c_str (); } /* Return nonzero if C is either a digit or a lowercase alphabet character. */ @@ -3449,6 +3414,126 @@ See set/show multiple-symbol.")); return n_chosen; } +/* See ada-lang.h. */ + +block_symbol +ada_find_operator_symbol (enum exp_opcode op, int parse_completion, + int nargs, value *argvec[]) +{ + if (possible_user_operator_p (op, argvec)) + { + std::vector candidates + = ada_lookup_symbol_list (ada_decoded_op_name (op), + NULL, VAR_DOMAIN); + + int i = ada_resolve_function (candidates, argvec, + nargs, ada_decoded_op_name (op), NULL, + parse_completion); + if (i >= 0) + return candidates[i]; + } + return {}; +} + +/* See ada-lang.h. */ + +block_symbol +ada_resolve_funcall (struct symbol *sym, const struct block *block, + struct type *context_type, + int parse_completion, + int nargs, value *argvec[], + innermost_block_tracker *tracker) +{ + std::vector candidates + = ada_lookup_symbol_list (sym->linkage_name (), block, VAR_DOMAIN); + + int i; + if (candidates.size () == 1) + i = 0; + else + { + i = ada_resolve_function + (candidates, + argvec, nargs, + sym->linkage_name (), + context_type, parse_completion); + if (i < 0) + error (_("Could not find a match for %s"), sym->print_name ()); + } + + tracker->update (candidates[i]); + return candidates[i]; +} + +/* See ada-lang.h. */ + +block_symbol +ada_resolve_variable (struct symbol *sym, const struct block *block, + struct type *context_type, + int parse_completion, + int deprocedure_p, + innermost_block_tracker *tracker) +{ + std::vector candidates + = ada_lookup_symbol_list (sym->linkage_name (), block, VAR_DOMAIN); + + if (std::any_of (candidates.begin (), + candidates.end (), + [] (block_symbol &bsym) + { + switch (SYMBOL_CLASS (bsym.symbol)) + { + case LOC_REGISTER: + case LOC_ARG: + case LOC_REF_ARG: + case LOC_REGPARM_ADDR: + case LOC_LOCAL: + case LOC_COMPUTED: + return true; + default: + return false; + } + })) + { + /* Types tend to get re-introduced locally, so if there + are any local symbols that are not types, first filter + out all types. */ + candidates.erase + (std::remove_if + (candidates.begin (), + candidates.end (), + [] (block_symbol &bsym) + { + return SYMBOL_CLASS (bsym.symbol) == LOC_TYPEDEF; + }), + candidates.end ()); + } + + int i; + if (candidates.empty ()) + error (_("No definition found for %s"), sym->print_name ()); + else if (candidates.size () == 1) + i = 0; + else if (deprocedure_p && !is_nonfunction (candidates)) + { + i = ada_resolve_function + (candidates, NULL, 0, + sym->linkage_name (), + context_type, parse_completion); + if (i < 0) + error (_("Could not find a match for %s"), sym->print_name ()); + } + else + { + printf_filtered (_("Multiple matches for %s\n"), sym->print_name ()); + user_select_syms (candidates.data (), candidates.size (), 1); + i = 0; + } + + tracker->update (candidates[i]); + return candidates[i]; +} + /* 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 @@ -3653,76 +3738,13 @@ resolve_subexp (expression_up *expp, int *pos, int deprocedure_p, case OP_VAR_VALUE: if (SYMBOL_DOMAIN (exp->elts[pc + 2].symbol) == UNDEF_DOMAIN) { - std::vector candidates; - int n_candidates; - - n_candidates = - ada_lookup_symbol_list (exp->elts[pc + 2].symbol->linkage_name (), - exp->elts[pc + 1].block, VAR_DOMAIN, - &candidates); - /* Paranoia. */ - candidates.resize (n_candidates); - - if (std::any_of (candidates.begin (), - candidates.end (), - [] (block_symbol &sym) - { - switch (SYMBOL_CLASS (sym.symbol)) - { - case LOC_REGISTER: - case LOC_ARG: - case LOC_REF_ARG: - case LOC_REGPARM_ADDR: - case LOC_LOCAL: - case LOC_COMPUTED: - return true; - default: - return false; - } - })) - { - /* Types tend to get re-introduced locally, so if there - are any local symbols that are not types, first filter - out all types. */ - candidates.erase - (std::remove_if - (candidates.begin (), - candidates.end (), - [] (block_symbol &sym) - { - return SYMBOL_CLASS (sym.symbol) == LOC_TYPEDEF; - }), - candidates.end ()); - n_candidates = candidates.size (); - } - - if (n_candidates == 0) - error (_("No definition found for %s"), - exp->elts[pc + 2].symbol->print_name ()); - 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, - exp->elts[pc + 2].symbol->linkage_name (), - context_type, parse_completion); - if (i < 0) - error (_("Could not find a match for %s"), - exp->elts[pc + 2].symbol->print_name ()); - } - else - { - printf_filtered (_("Multiple matches for %s\n"), - exp->elts[pc + 2].symbol->print_name ()); - user_select_syms (candidates.data (), n_candidates, 1); - i = 0; - } - - exp->elts[pc + 1].block = candidates[i].block; - exp->elts[pc + 2].symbol = candidates[i].symbol; - tracker->update (candidates[i]); + block_symbol resolved + = ada_resolve_variable (exp->elts[pc + 2].symbol, + exp->elts[pc + 1].block, + context_type, parse_completion, + deprocedure_p, tracker); + exp->elts[pc + 1].block = resolved.block; + exp->elts[pc + 2].symbol = resolved.symbol; } if (deprocedure_p @@ -3741,31 +3763,14 @@ resolve_subexp (expression_up *expp, int *pos, int deprocedure_p, if (exp->elts[pc + 3].opcode == OP_VAR_VALUE && SYMBOL_DOMAIN (exp->elts[pc + 5].symbol) == UNDEF_DOMAIN) { - std::vector candidates; - int n_candidates; - - n_candidates = - ada_lookup_symbol_list (exp->elts[pc + 5].symbol->linkage_name (), - 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, - exp->elts[pc + 5].symbol->linkage_name (), - context_type, parse_completion); - if (i < 0) - error (_("Could not find a match for %s"), - exp->elts[pc + 5].symbol->print_name ()); - } - - exp->elts[pc + 4].block = candidates[i].block; - exp->elts[pc + 5].symbol = candidates[i].symbol; - tracker->update (candidates[i]); + block_symbol resolved + = ada_resolve_funcall (exp->elts[pc + 5].symbol, + exp->elts[pc + 4].block, + context_type, parse_completion, + nargs, argvec, + tracker); + exp->elts[pc + 4].block = resolved.block; + exp->elts[pc + 5].symbol = resolved.symbol; } } break; @@ -3790,27 +3795,16 @@ resolve_subexp (expression_up *expp, int *pos, int deprocedure_p, case UNOP_PLUS: case UNOP_LOGICAL_NOT: case UNOP_ABS: - if (possible_user_operator_p (op, argvec)) - { - std::vector 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; + { + block_symbol found = ada_find_operator_symbol (op, parse_completion, + nargs, argvec); + if (found.symbol == nullptr) + break; - replace_operator_with_call (expp, pc, nargs, 1, - candidates[i].symbol, - candidates[i].block); - exp = expp->get (); - } + replace_operator_with_call (expp, pc, nargs, 1, + found.symbol, found.block); + exp = expp->get (); + } break; case OP_TYPE: @@ -3953,7 +3947,7 @@ return_match (struct type *func_type, struct type *context_type) } -/* Returns the index in SYMS[0..NSYMS-1] that contains the symbol for the +/* Returns the index in SYMS 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 @@ -3966,8 +3960,8 @@ return_match (struct type *func_type, struct type *context_type) the process; the index returned is for the modified vector. */ static int -ada_resolve_function (struct block_symbol syms[], - int nsyms, struct value **args, int nargs, +ada_resolve_function (std::vector &syms, + struct value **args, int nargs, const char *name, struct type *context_type, int parse_completion) { @@ -3981,7 +3975,7 @@ ada_resolve_function (struct block_symbol syms[], where every function is accepted. */ for (fallback = 0; m == 0 && fallback < 2; fallback++) { - for (k = 0; k < nsyms; k += 1) + for (k = 0; k < syms.size (); k += 1) { struct type *type = ada_check_typedef (SYMBOL_TYPE (syms[k].symbol)); @@ -4003,7 +3997,7 @@ ada_resolve_function (struct block_symbol syms[], else if (m > 1 && !parse_completion) { printf_filtered (_("Multiple matches for %s\n"), name); - user_select_syms (syms, m, 1); + user_select_syms (syms.data (), m, 1); return 0; } return 0; @@ -4734,17 +4728,15 @@ standard_lookup (const char *name, const struct block *block, /* Non-zero iff there is at least one non-function/non-enumeral symbol - in the symbol fields of SYMS[0..N-1]. We treat enumerals as functions, + in the symbol fields of SYMS. We treat enumerals as functions, since they contend in overloading in the same way. */ static int -is_nonfunction (struct block_symbol syms[], int n) +is_nonfunction (const std::vector &syms) { - int i; - - for (i = 0; i < n; i += 1) - if (SYMBOL_TYPE (syms[i].symbol)->code () != TYPE_CODE_FUNC - && (SYMBOL_TYPE (syms[i].symbol)->code () != TYPE_CODE_ENUM - || SYMBOL_CLASS (syms[i].symbol) != LOC_CONST)) + for (const block_symbol &sym : syms) + if (SYMBOL_TYPE (sym.symbol)->code () != TYPE_CODE_FUNC + && (SYMBOL_TYPE (sym.symbol)->code () != TYPE_CODE_ENUM + || SYMBOL_CLASS (sym.symbol) != LOC_CONST)) return 1; return 0; @@ -4817,17 +4809,14 @@ lesseq_defined_than (struct symbol *sym0, struct symbol *sym1) } } -/* Append (SYM,BLOCK,SYMTAB) to the end of the array of struct block_symbol - records in OBSTACKP. Do nothing if SYM is a duplicate. */ +/* Append (SYM,BLOCK) to the end of the array of struct block_symbol + records in RESULT. Do nothing if SYM is a duplicate. */ static void -add_defn_to_vec (struct obstack *obstackp, +add_defn_to_vec (std::vector &result, struct symbol *sym, const struct block *block) { - int i; - struct block_symbol *prevDefns = defns_collected (obstackp, 0); - /* Do not try to complete stub types, as the debugger is probably already scanning all symbols matching a certain name at the time when this function is called. Trying to replace the stub @@ -4837,46 +4826,22 @@ add_defn_to_vec (struct obstack *obstackp, matches, with at least one of them complete. It can then filter out the stub ones if needed. */ - for (i = num_defns_collected (obstackp) - 1; i >= 0; i -= 1) + for (int i = result.size () - 1; i >= 0; i -= 1) { - if (lesseq_defined_than (sym, prevDefns[i].symbol)) + if (lesseq_defined_than (sym, result[i].symbol)) return; - else if (lesseq_defined_than (prevDefns[i].symbol, sym)) + else if (lesseq_defined_than (result[i].symbol, sym)) { - prevDefns[i].symbol = sym; - prevDefns[i].block = block; + result[i].symbol = sym; + result[i].block = block; return; } } - { - struct block_symbol info; - - info.symbol = sym; - info.block = block; - obstack_grow (obstackp, &info, sizeof (struct block_symbol)); - } -} - -/* Number of block_symbol structures currently collected in current vector in - OBSTACKP. */ - -static int -num_defns_collected (struct obstack *obstackp) -{ - return obstack_object_size (obstackp) / sizeof (struct block_symbol); -} - -/* Vector of block_symbol structures currently collected in current vector in - OBSTACKP. If FINISH, close off the vector and return its final address. */ - -static struct block_symbol * -defns_collected (struct obstack *obstackp, int finish) -{ - if (finish) - return (struct block_symbol *) obstack_finish (obstackp); - else - return (struct block_symbol *) obstack_base (obstackp); + struct block_symbol info; + info.symbol = sym; + info.block = block; + result.push_back (info); } /* Return a bound minimal symbol matching NAME according to Ada @@ -4917,12 +4882,12 @@ ada_lookup_simple_minsym (const char *name) /* For all subprograms that statically enclose the subprogram of the selected frame, add symbols matching identifier NAME in DOMAIN - and their blocks to the list of data in OBSTACKP, as for + and their blocks to the list of data in RESULT, as for ada_add_block_symbols (q.v.). If WILD_MATCH_P, treat as NAME with a wildcard prefix. */ static void -add_symbols_from_enclosing_procs (struct obstack *obstackp, +add_symbols_from_enclosing_procs (std::vector &result, const lookup_name_info &lookup_name, domain_enum domain) { @@ -5045,10 +5010,9 @@ symbols_are_identical_enums (const std::vector &syms) duplicate other symbols in the list (The only case I know of where this happens is when object files containing stabs-in-ecoff are linked with files containing ordinary ecoff debugging symbols (or no - debugging symbols)). Modifies SYMS to squeeze out deleted entries. - Returns the number of items in the modified list. */ + debugging symbols)). Modifies SYMS to squeeze out deleted entries. */ -static int +static void remove_extra_symbols (std::vector *syms) { int i, j; @@ -5057,7 +5021,7 @@ remove_extra_symbols (std::vector *syms) cannot be any extra symbol in that case. But it's easy to handle, since we have nothing to do in that case. */ if (syms->size () < 2) - return syms->size (); + return; i = 0; while (i < syms->size ()) @@ -5122,8 +5086,6 @@ remove_extra_symbols (std::vector *syms) isn't missing some choices that were identical and yet distinct. */ if (symbols_are_identical_enums (*syms)) syms->resize (1); - - return syms->size (); } /* Given a type that corresponds to a renaming entity, use the type name @@ -5215,8 +5177,8 @@ old_renaming_is_invisible (const struct symbol *sym, const char *function_name) is not visible from the function associated with CURRENT_BLOCK or that is superfluous due to the presence of more specific renaming information. Places surviving symbols in the initial entries of - SYMS and returns the number of surviving symbols. - + SYMS. + Rationale: First, in cases where an object renaming is implemented as a reference variable, GNAT may produce both the actual reference @@ -5248,7 +5210,7 @@ old_renaming_is_invisible (const struct symbol *sym, const char *function_name) has been changed by an "Export" pragma. As a consequence, the user will be unable to print such rename entities. */ -static int +static void remove_irrelevant_renamings (std::vector *syms, const struct block *current_block) { @@ -5297,22 +5259,23 @@ remove_irrelevant_renamings (std::vector *syms, (*syms)[k] = (*syms)[j]; k += 1; } - return k; + syms->resize (k); + return; } /* Extract the function name associated to CURRENT_BLOCK. Abort if unable to do so. */ if (current_block == NULL) - return syms->size (); + return; current_function = block_linkage_function (current_block); if (current_function == NULL) - return syms->size (); + return; current_function_name = current_function->linkage_name (); if (current_function_name == NULL) - return syms->size (); + return; /* Check each of the symbols, and remove it from the list if it is a type corresponding to a renaming that is out of the scope of @@ -5329,11 +5292,9 @@ remove_irrelevant_renamings (std::vector *syms, else i += 1; } - - return syms->size (); } -/* Add to OBSTACKP all symbols from BLOCK (and its super-blocks) +/* Add to RESULT all symbols from BLOCK (and its super-blocks) whose name and domain match NAME and DOMAIN respectively. If no match was found, then extend the search to "enclosing" routines (in other words, if we're inside a nested function, @@ -5341,10 +5302,10 @@ remove_irrelevant_renamings (std::vector *syms, If WILD_MATCH_P is nonzero, perform the naming matching in "wild" mode (see function "wild_match" for more info). - Note: This function assumes that OBSTACKP has 0 (zero) element in it. */ + Note: This function assumes that RESULT has 0 (zero) element in it. */ static void -ada_add_local_symbols (struct obstack *obstackp, +ada_add_local_symbols (std::vector &result, const lookup_name_info &lookup_name, const struct block *block, domain_enum domain) { @@ -5353,11 +5314,10 @@ ada_add_local_symbols (struct obstack *obstackp, while (block != NULL) { block_depth += 1; - ada_add_block_symbols (obstackp, block, lookup_name, domain, NULL); + ada_add_block_symbols (result, block, lookup_name, domain, NULL); /* If we found a non-function match, assume that's the one. */ - if (is_nonfunction (defns_collected (obstackp, 0), - num_defns_collected (obstackp))) + if (is_nonfunction (result)) return; block = BLOCK_SUPERBLOCK (block); @@ -5365,8 +5325,8 @@ ada_add_local_symbols (struct obstack *obstackp, /* If no luck so far, try to find NAME as a local symbol in some lexically enclosing subprogram. */ - if (num_defns_collected (obstackp) == 0 && block_depth > 2) - add_symbols_from_enclosing_procs (obstackp, lookup_name, domain); + if (result.empty () && block_depth > 2) + add_symbols_from_enclosing_procs (result, lookup_name, domain); } /* An object of this type is used as the user_data argument when @@ -5374,15 +5334,21 @@ ada_add_local_symbols (struct obstack *obstackp, struct match_data { - struct objfile *objfile; - struct obstack *obstackp; - struct symbol *arg_sym; - int found_sym; + explicit match_data (std::vector *rp) + : resultp (rp) + { + } + DISABLE_COPY_AND_ASSIGN (match_data); + + struct objfile *objfile = nullptr; + std::vector *resultp; + struct symbol *arg_sym = nullptr; + bool found_sym = false; }; /* A callback for add_nonlocal_symbols that adds symbol, found in BSYM, to a list of symbols. DATA is a pointer to a struct match_data * - containing the obstack that collects the symbol list, the file that SYM + containing the vector that collects the symbol list, the file that SYM must come from, a flag indicating whether a non-argument symbol has been found in the current block, and the last argument symbol passed in SYM within the current block (if any). When SYM is null, @@ -5399,10 +5365,10 @@ aux_add_nonlocal_symbols (struct block_symbol *bsym, if (sym == NULL) { if (!data->found_sym && data->arg_sym != NULL) - add_defn_to_vec (data->obstackp, + add_defn_to_vec (*data->resultp, fixup_symbol_section (data->arg_sym, data->objfile), block); - data->found_sym = 0; + data->found_sym = false; data->arg_sym = NULL; } else @@ -5413,8 +5379,8 @@ aux_add_nonlocal_symbols (struct block_symbol *bsym, data->arg_sym = sym; else { - data->found_sym = 1; - add_defn_to_vec (data->obstackp, + data->found_sym = true; + add_defn_to_vec (*data->resultp, fixup_symbol_section (sym, data->objfile), block); } @@ -5424,16 +5390,16 @@ aux_add_nonlocal_symbols (struct block_symbol *bsym, /* Helper for add_nonlocal_symbols. Find symbols in DOMAIN which are targeted by renamings matching LOOKUP_NAME in BLOCK. Add these - symbols to OBSTACKP. Return whether we found such symbols. */ + symbols to RESULT. Return whether we found such symbols. */ static int -ada_add_block_renamings (struct obstack *obstackp, +ada_add_block_renamings (std::vector &result, const struct block *block, const lookup_name_info &lookup_name, domain_enum domain) { struct using_direct *renaming; - int defns_mark = num_defns_collected (obstackp); + int defns_mark = result.size (); symbol_name_matcher_ftype *name_match = ada_get_symbol_name_matcher (lookup_name); @@ -5471,12 +5437,12 @@ ada_add_block_renamings (struct obstack *obstackp, { lookup_name_info decl_lookup_name (renaming->declaration, lookup_name.match_type ()); - ada_add_all_symbols (obstackp, block, decl_lookup_name, domain, + ada_add_all_symbols (result, block, decl_lookup_name, domain, 1, NULL); } renaming->searched = 0; } - return num_defns_collected (obstackp) != defns_mark; + return result.size () != defns_mark; } /* Implements compare_names, but only applying the comparision using @@ -5573,20 +5539,17 @@ ada_lookup_name (const lookup_name_info &lookup_name) return lookup_name.ada ().lookup_name ().c_str (); } -/* Add to OBSTACKP all non-local symbols whose name and domain match +/* Add to RESULT all non-local symbols whose name and domain match LOOKUP_NAME and DOMAIN respectively. The search is performed on GLOBAL_BLOCK symbols if GLOBAL is non-zero, or on STATIC_BLOCK symbols otherwise. */ static void -add_nonlocal_symbols (struct obstack *obstackp, +add_nonlocal_symbols (std::vector &result, const lookup_name_info &lookup_name, domain_enum domain, int global) { - struct match_data data; - - memset (&data, 0, sizeof data); - data.obstackp = obstackp; + struct match_data data (&result); bool is_wild_match = lookup_name.ada ().wild_match_p (); @@ -5610,13 +5573,13 @@ add_nonlocal_symbols (struct obstack *obstackp, const struct block *global_block = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cu), GLOBAL_BLOCK); - if (ada_add_block_renamings (obstackp, global_block, lookup_name, + if (ada_add_block_renamings (result, global_block, lookup_name, domain)) - data.found_sym = 1; + data.found_sym = true; } } - if (num_defns_collected (obstackp) == 0 && global && !is_wild_match) + if (result.empty () && global && !is_wild_match) { const char *name = ada_lookup_name (lookup_name); std::string bracket_name = std::string ("<_ada_") + name + '>'; @@ -5635,7 +5598,7 @@ add_nonlocal_symbols (struct obstack *obstackp, /* Find symbols in DOMAIN matching LOOKUP_NAME, in BLOCK and, if FULL_SEARCH is non-zero, enclosing scope and in global scopes, - returning the number of matches. Add these to OBSTACKP. + returning the number of matches. Add these to RESULT. When FULL_SEARCH is non-zero, any non-function/non-enumeral symbol match within the nest of blocks whose innermost member is BLOCK, @@ -5651,7 +5614,7 @@ add_nonlocal_symbols (struct obstack *obstackp, to lookup global symbols. */ static void -ada_add_all_symbols (struct obstack *obstackp, +ada_add_all_symbols (std::vector &result, const struct block *block, const lookup_name_info &lookup_name, domain_enum domain, @@ -5678,15 +5641,15 @@ ada_add_all_symbols (struct obstack *obstackp, if (block != NULL) { if (full_search) - ada_add_local_symbols (obstackp, lookup_name, block, domain); + ada_add_local_symbols (result, lookup_name, block, domain); else { /* In the !full_search case we're are being called by iterate_over_symbols, and we don't want to search superblocks. */ - ada_add_block_symbols (obstackp, block, lookup_name, domain, NULL); + ada_add_block_symbols (result, block, lookup_name, domain, NULL); } - if (num_defns_collected (obstackp) > 0 || !full_search) + if (!result.empty () || !full_search) return; } @@ -5698,7 +5661,7 @@ ada_add_all_symbols (struct obstack *obstackp, domain, &sym, &block)) { if (sym != NULL) - add_defn_to_vec (obstackp, sym, block); + add_defn_to_vec (result, sym, block); return; } @@ -5707,21 +5670,20 @@ ada_add_all_symbols (struct obstack *obstackp, /* Search symbols from all global blocks. */ - add_nonlocal_symbols (obstackp, lookup_name, domain, 1); + add_nonlocal_symbols (result, lookup_name, domain, 1); /* Now add symbols from all per-file blocks if we've gotten no hits (not strictly correct, but perhaps better than an error). */ - if (num_defns_collected (obstackp) == 0) - add_nonlocal_symbols (obstackp, lookup_name, domain, 0); + if (result.empty ()) + add_nonlocal_symbols (result, lookup_name, domain, 0); } /* Find symbols in DOMAIN matching LOOKUP_NAME, in BLOCK and, if FULL_SEARCH - is non-zero, enclosing scope and in global scopes, returning the number of - matches. - Fills *RESULTS with (SYM,BLOCK) tuples, indicating the symbols - found and the blocks and symbol tables (if any) in which they were - found. + is non-zero, enclosing scope and in global scopes. + + Returns (SYM,BLOCK) tuples, indicating the symbols found and the + blocks and symbol tables (if any) in which they were found. When full_search is non-zero, any non-function/non-enumeral symbol match within the nest of blocks whose innermost member is BLOCK, @@ -5732,55 +5694,44 @@ ada_add_all_symbols (struct obstack *obstackp, Names prefixed with "standard__" are handled specially: "standard__" is first stripped off, and only static and global symbols are searched. */ -static int +static std::vector ada_lookup_symbol_list_worker (const lookup_name_info &lookup_name, const struct block *block, domain_enum domain, - std::vector *results, int full_search) { int syms_from_global_search; - int ndefns; - auto_obstack obstack; + std::vector results; - ada_add_all_symbols (&obstack, block, lookup_name, + ada_add_all_symbols (results, block, lookup_name, domain, full_search, &syms_from_global_search); - ndefns = num_defns_collected (&obstack); - - struct block_symbol *base = defns_collected (&obstack, 1); - for (int i = 0; i < ndefns; ++i) - results->push_back (base[i]); + remove_extra_symbols (&results); - ndefns = remove_extra_symbols (results); - - if (ndefns == 0 && full_search && syms_from_global_search) + if (results.empty () && full_search && syms_from_global_search) cache_symbol (ada_lookup_name (lookup_name), domain, NULL, NULL); - if (ndefns == 1 && full_search && syms_from_global_search) + if (results.size () == 1 && full_search && syms_from_global_search) cache_symbol (ada_lookup_name (lookup_name), domain, - (*results)[0].symbol, (*results)[0].block); - - ndefns = remove_irrelevant_renamings (results, block); + results[0].symbol, results[0].block); - return ndefns; + remove_irrelevant_renamings (&results, block); + return results; } /* Find symbols in DOMAIN matching NAME, in BLOCK and enclosing scope and - in global scopes, returning the number of matches, and filling *RESULTS - with (SYM,BLOCK) tuples. + in global scopes, returning (SYM,BLOCK) tuples. See ada_lookup_symbol_list_worker for further details. */ -int +std::vector ada_lookup_symbol_list (const char *name, const struct block *block, - domain_enum domain, - std::vector *results) + domain_enum domain) { symbol_name_match_type name_match_type = name_match_type_from_name (name); lookup_name_info lookup_name (name, name_match_type); - return ada_lookup_symbol_list_worker (lookup_name, block, domain, results, 1); + return ada_lookup_symbol_list_worker (lookup_name, block, domain, 1); } /* The result is as for ada_lookup_symbol_list with FULL_SEARCH set @@ -5816,12 +5767,10 @@ struct block_symbol ada_lookup_symbol (const char *name, const struct block *block0, domain_enum domain) { - std::vector candidates; - int n_candidates; - - n_candidates = ada_lookup_symbol_list (name, block0, domain, &candidates); + std::vector candidates + = ada_lookup_symbol_list (name, block0, domain); - if (n_candidates == 0) + if (candidates.empty ()) return {}; block_symbol info = candidates[0]; @@ -6080,12 +6029,11 @@ wild_match (const char *name, const char *patn) } } -/* Add symbols from BLOCK matching LOOKUP_NAME in DOMAIN to vector - *defn_symbols, updating the list of symbols in OBSTACKP (if +/* Add symbols from BLOCK matching LOOKUP_NAME in DOMAIN to RESULT (if necessary). OBJFILE is the section containing BLOCK. */ static void -ada_add_block_symbols (struct obstack *obstackp, +ada_add_block_symbols (std::vector &result, const struct block *block, const lookup_name_info &lookup_name, domain_enum domain, struct objfile *objfile) @@ -6094,11 +6042,11 @@ ada_add_block_symbols (struct obstack *obstackp, /* A matching argument symbol, if any. */ struct symbol *arg_sym; /* Set true when we find a matching non-argument symbol. */ - int found_sym; + bool found_sym; struct symbol *sym; arg_sym = NULL; - found_sym = 0; + found_sym = false; for (sym = block_iter_match_first (block, lookup_name, &iter); sym != NULL; sym = block_iter_match_next (lookup_name, &iter)) @@ -6111,8 +6059,8 @@ ada_add_block_symbols (struct obstack *obstackp, arg_sym = sym; else { - found_sym = 1; - add_defn_to_vec (obstackp, + found_sym = true; + add_defn_to_vec (result, fixup_symbol_section (sym, objfile), block); } @@ -6122,12 +6070,12 @@ ada_add_block_symbols (struct obstack *obstackp, /* Handle renamings. */ - if (ada_add_block_renamings (obstackp, block, lookup_name, domain)) - found_sym = 1; + if (ada_add_block_renamings (result, block, lookup_name, domain)) + found_sym = true; if (!found_sym && arg_sym != NULL) { - add_defn_to_vec (obstackp, + add_defn_to_vec (result, fixup_symbol_section (arg_sym, objfile), block); } @@ -6135,7 +6083,7 @@ ada_add_block_symbols (struct obstack *obstackp, if (!lookup_name.ada ().wild_match_p ()) { arg_sym = NULL; - found_sym = 0; + found_sym = false; const std::string &ada_lookup_name = lookup_name.ada ().lookup_name (); const char *name = ada_lookup_name.c_str (); size_t name_len = ada_lookup_name.size (); @@ -6165,8 +6113,8 @@ ada_add_block_symbols (struct obstack *obstackp, arg_sym = sym; else { - found_sym = 1; - add_defn_to_vec (obstackp, + found_sym = true; + add_defn_to_vec (result, fixup_symbol_section (sym, objfile), block); } @@ -6179,7 +6127,7 @@ ada_add_block_symbols (struct obstack *obstackp, They aren't parameters, right? */ if (!found_sym && arg_sym != NULL) { - add_defn_to_vec (obstackp, + add_defn_to_vec (result, fixup_symbol_section (arg_sym, objfile), block); } @@ -6761,8 +6709,7 @@ ada_is_others_clause (struct type *type, int field_num) const char * ada_variant_discrim_name (struct type *type0) { - static char *result = NULL; - static size_t result_len = 0; + static std::string result; struct type *type; const char *name; const char *discrim_end; @@ -6798,10 +6745,8 @@ ada_variant_discrim_name (struct type *type0) break; } - GROW_VECT (result, result_len, discrim_end - discrim_start + 1); - strncpy (result, discrim_start, discrim_end - discrim_start); - result[discrim_end - discrim_start] = '\0'; - return result; + result = std::string (discrim_start, discrim_end - discrim_start); + return result.c_str (); } /* Scan STR for a subtype-encoded number, beginning at position K. @@ -8944,8 +8889,11 @@ val_atr (struct type *type, LONGEST val) } static struct value * -value_val_atr (struct type *type, struct value *arg) +ada_val_atr (enum noside noside, struct type *type, struct value *arg) { + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (type, not_lval); + if (!discrete_type_p (type)) error (_("'VAL only defined on discrete types")); if (!integer_type_p (value_type (arg))) @@ -9114,8 +9062,7 @@ ada_aligned_value_addr (struct type *type, const gdb_byte *valaddr) const char * ada_enum_name (const char *name) { - static char *result; - static size_t result_len = 0; + static std::string storage; const char *tmp; /* First, unqualify the enumeration name: @@ -9154,22 +9101,20 @@ ada_enum_name (const char *name) || (name[1] >= 'a' && name[1] <= 'z')) && name[2] == '\0') { - GROW_VECT (result, result_len, 4); - xsnprintf (result, result_len, "'%c'", name[1]); - return result; + storage = string_printf ("'%c'", name[1]); + return storage.c_str (); } else return name; - GROW_VECT (result, result_len, 16); if (isascii (v) && isprint (v)) - xsnprintf (result, result_len, "'%c'", v); + storage = string_printf ("'%c'", v); else if (name[1] == 'U') - xsnprintf (result, result_len, "[\"%02x\"]", v); + storage = string_printf ("[\"%02x\"]", v); else - xsnprintf (result, result_len, "[\"%04x\"]", v); + storage = string_printf ("[\"%04x\"]", v); - return result; + return storage.c_str (); } else { @@ -9178,10 +9123,8 @@ ada_enum_name (const char *name) tmp = strstr (name, "$"); if (tmp != NULL) { - GROW_VECT (result, result_len, tmp - name + 1); - strncpy (result, name, tmp - name); - result[tmp - name] = '\0'; - return result; + storage = std::string (name, tmp - name); + return storage.c_str (); } return name; @@ -9235,33 +9178,6 @@ unwrap_value (struct value *val) } } -static struct value * -cast_from_gnat_encoded_fixed_point_type (struct type *type, struct value *arg) -{ - struct value *scale - = gnat_encoded_fixed_point_scaling_factor (value_type (arg)); - arg = value_cast (value_type (scale), arg); - - arg = value_binop (arg, scale, BINOP_MUL); - return value_cast (type, arg); -} - -static struct value * -cast_to_gnat_encoded_fixed_point_type (struct type *type, struct value *arg) -{ - if (type == value_type (arg)) - return arg; - - struct value *scale = gnat_encoded_fixed_point_scaling_factor (type); - if (ada_is_gnat_encoded_fixed_point_type (value_type (arg))) - arg = cast_from_gnat_encoded_fixed_point_type (value_type (scale), arg); - else - arg = value_cast (value_type (scale), arg); - - arg = value_binop (arg, scale, BINOP_DIV); - return value_cast (type, arg); -} - /* Given two array types T1 and T2, return nonzero iff both arrays contain the same number of elements. */ @@ -9761,12 +9677,6 @@ ada_value_cast (struct type *type, struct value *arg2) if (type == ada_check_typedef (value_type (arg2))) return arg2; - if (ada_is_gnat_encoded_fixed_point_type (type)) - return cast_to_gnat_encoded_fixed_point_type (type, arg2); - - if (ada_is_gnat_encoded_fixed_point_type (value_type (arg2))) - return cast_from_gnat_encoded_fixed_point_type (type, arg2); - return value_cast (type, arg2); } @@ -10076,6 +9986,514 @@ ada_evaluate_subexp_for_cast (expression *exp, int *pos, return ada_value_cast (to_type, val); } +/* A helper function for TERNOP_IN_RANGE. */ + +static value * +eval_ternop_in_range (struct type *expect_type, struct expression *exp, + enum noside noside, + value *arg1, value *arg2, value *arg3) +{ + if (noside == EVAL_SKIP) + return eval_skip_value (exp); + + binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2); + binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg3); + struct type *type = language_bool_type (exp->language_defn, exp->gdbarch); + return + value_from_longest (type, + (value_less (arg1, arg3) + || value_equal (arg1, arg3)) + && (value_less (arg2, arg1) + || value_equal (arg2, arg1))); +} + +/* A helper function for UNOP_NEG. */ + +value * +ada_unop_neg (struct type *expect_type, + struct expression *exp, + enum noside noside, enum exp_opcode op, + struct value *arg1) +{ + if (noside == EVAL_SKIP) + return eval_skip_value (exp); + unop_promote (exp->language_defn, exp->gdbarch, &arg1); + return value_neg (arg1); +} + +/* A helper function for UNOP_IN_RANGE. */ + +value * +ada_unop_in_range (struct type *expect_type, + struct expression *exp, + enum noside noside, enum exp_opcode op, + struct value *arg1, struct type *type) +{ + if (noside == EVAL_SKIP) + return eval_skip_value (exp); + + struct value *arg2, *arg3; + switch (type->code ()) + { + default: + lim_warning (_("Membership test incompletely implemented; " + "always returns true")); + type = language_bool_type (exp->language_defn, exp->gdbarch); + return value_from_longest (type, (LONGEST) 1); + + case TYPE_CODE_RANGE: + arg2 = value_from_longest (type, + type->bounds ()->low.const_val ()); + arg3 = value_from_longest (type, + type->bounds ()->high.const_val ()); + binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2); + binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg3); + type = language_bool_type (exp->language_defn, exp->gdbarch); + return + value_from_longest (type, + (value_less (arg1, arg3) + || value_equal (arg1, arg3)) + && (value_less (arg2, arg1) + || value_equal (arg2, arg1))); + } +} + +/* A helper function for OP_ATR_TAG. */ + +value * +ada_atr_tag (struct type *expect_type, + struct expression *exp, + enum noside noside, enum exp_opcode op, + struct value *arg1) +{ + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (ada_tag_type (arg1), not_lval); + + return ada_value_tag (arg1); +} + +/* A helper function for OP_ATR_SIZE. */ + +value * +ada_atr_size (struct type *expect_type, + struct expression *exp, + enum noside noside, enum exp_opcode op, + struct value *arg1) +{ + struct type *type = value_type (arg1); + + /* If the argument is a reference, then dereference its type, since + the user is really asking for the size of the actual object, + not the size of the pointer. */ + if (type->code () == TYPE_CODE_REF) + type = TYPE_TARGET_TYPE (type); + + if (noside == EVAL_SKIP) + return eval_skip_value (exp); + else if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (builtin_type (exp->gdbarch)->builtin_int, not_lval); + else + return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, + TARGET_CHAR_BIT * TYPE_LENGTH (type)); +} + +/* A helper function for UNOP_ABS. */ + +value * +ada_abs (struct type *expect_type, + struct expression *exp, + enum noside noside, enum exp_opcode op, + struct value *arg1) +{ + unop_promote (exp->language_defn, exp->gdbarch, &arg1); + if (value_less (arg1, value_zero (value_type (arg1), not_lval))) + return value_neg (arg1); + else + return arg1; +} + +/* A helper function for BINOP_MUL. */ + +static value * +ada_mult_binop (struct type *expect_type, + struct expression *exp, + enum noside noside, enum exp_opcode op, + struct value *arg1, struct value *arg2) +{ + if (noside == EVAL_AVOID_SIDE_EFFECTS) + { + binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2); + return value_zero (value_type (arg1), not_lval); + } + else + { + binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2); + return ada_value_binop (arg1, arg2, op); + } +} + +/* A helper function for BINOP_EQUAL and BINOP_NOTEQUAL. */ + +static value * +ada_equal_binop (struct type *expect_type, + struct expression *exp, + enum noside noside, enum exp_opcode op, + struct value *arg1, struct value *arg2) +{ + int tem; + if (noside == EVAL_AVOID_SIDE_EFFECTS) + tem = 0; + else + { + binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2); + tem = ada_value_equal (arg1, arg2); + } + if (op == BINOP_NOTEQUAL) + tem = !tem; + struct type *type = language_bool_type (exp->language_defn, exp->gdbarch); + return value_from_longest (type, (LONGEST) tem); +} + +/* A helper function for TERNOP_SLICE. */ + +static value * +ada_ternop_slice (struct expression *exp, + enum noside noside, + struct value *array, struct value *low_bound_val, + struct value *high_bound_val) +{ + LONGEST low_bound; + LONGEST high_bound; + + low_bound_val = coerce_ref (low_bound_val); + high_bound_val = coerce_ref (high_bound_val); + low_bound = value_as_long (low_bound_val); + high_bound = value_as_long (high_bound_val); + + /* If this is a reference to an aligner type, then remove all + the aligners. */ + if (value_type (array)->code () == TYPE_CODE_REF + && ada_is_aligner_type (TYPE_TARGET_TYPE (value_type (array)))) + TYPE_TARGET_TYPE (value_type (array)) = + ada_aligned_type (TYPE_TARGET_TYPE (value_type (array))); + + if (ada_is_any_packed_array_type (value_type (array))) + error (_("cannot slice a packed array")); + + /* If this is a reference to an array or an array lvalue, + convert to a pointer. */ + if (value_type (array)->code () == TYPE_CODE_REF + || (value_type (array)->code () == TYPE_CODE_ARRAY + && VALUE_LVAL (array) == lval_memory)) + array = value_addr (array); + + if (noside == EVAL_AVOID_SIDE_EFFECTS + && ada_is_array_descriptor_type (ada_check_typedef + (value_type (array)))) + return empty_array (ada_type_of_array (array, 0), low_bound, + high_bound); + + array = ada_coerce_to_simple_array_ptr (array); + + /* If we have more than one level of pointer indirection, + dereference the value until we get only one level. */ + while (value_type (array)->code () == TYPE_CODE_PTR + && (TYPE_TARGET_TYPE (value_type (array))->code () + == TYPE_CODE_PTR)) + array = value_ind (array); + + /* Make sure we really do have an array type before going further, + to avoid a SEGV when trying to get the index type or the target + type later down the road if the debug info generated by + the compiler is incorrect or incomplete. */ + if (!ada_is_simple_array_type (value_type (array))) + error (_("cannot take slice of non-array")); + + if (ada_check_typedef (value_type (array))->code () + == TYPE_CODE_PTR) + { + struct type *type0 = ada_check_typedef (value_type (array)); + + if (high_bound < low_bound || noside == EVAL_AVOID_SIDE_EFFECTS) + return empty_array (TYPE_TARGET_TYPE (type0), low_bound, high_bound); + else + { + struct type *arr_type0 = + to_fixed_array_type (TYPE_TARGET_TYPE (type0), NULL, 1); + + return ada_value_slice_from_ptr (array, arr_type0, + longest_to_int (low_bound), + longest_to_int (high_bound)); + } + } + else if (noside == EVAL_AVOID_SIDE_EFFECTS) + return array; + else if (high_bound < low_bound) + return empty_array (value_type (array), low_bound, high_bound); + else + return ada_value_slice (array, longest_to_int (low_bound), + longest_to_int (high_bound)); +} + +/* A helper function for BINOP_IN_BOUNDS. */ + +static value * +ada_binop_in_bounds (struct expression *exp, enum noside noside, + struct value *arg1, struct value *arg2, int n) +{ + if (noside == EVAL_AVOID_SIDE_EFFECTS) + { + struct type *type = language_bool_type (exp->language_defn, + exp->gdbarch); + return value_zero (type, not_lval); + } + + struct type *type = ada_index_type (value_type (arg2), n, "range"); + if (!type) + type = value_type (arg1); + + value *arg3 = value_from_longest (type, ada_array_bound (arg2, n, 1)); + arg2 = value_from_longest (type, ada_array_bound (arg2, n, 0)); + + binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2); + binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg3); + type = language_bool_type (exp->language_defn, exp->gdbarch); + return value_from_longest (type, + (value_less (arg1, arg3) + || value_equal (arg1, arg3)) + && (value_less (arg2, arg1) + || value_equal (arg2, arg1))); +} + +/* A helper function for some attribute operations. */ + +static value * +ada_unop_atr (struct expression *exp, enum noside noside, enum exp_opcode op, + struct value *arg1, struct type *type_arg, int tem) +{ + if (noside == EVAL_AVOID_SIDE_EFFECTS) + { + if (type_arg == NULL) + type_arg = value_type (arg1); + + if (ada_is_constrained_packed_array_type (type_arg)) + type_arg = decode_constrained_packed_array_type (type_arg); + + if (!discrete_type_p (type_arg)) + { + switch (op) + { + default: /* Should never happen. */ + error (_("unexpected attribute encountered")); + case OP_ATR_FIRST: + case OP_ATR_LAST: + type_arg = ada_index_type (type_arg, tem, + ada_attribute_name (op)); + break; + case OP_ATR_LENGTH: + type_arg = builtin_type (exp->gdbarch)->builtin_int; + break; + } + } + + return value_zero (type_arg, not_lval); + } + else if (type_arg == NULL) + { + arg1 = ada_coerce_ref (arg1); + + if (ada_is_constrained_packed_array_type (value_type (arg1))) + arg1 = ada_coerce_to_simple_array (arg1); + + struct type *type; + if (op == OP_ATR_LENGTH) + type = builtin_type (exp->gdbarch)->builtin_int; + else + { + type = ada_index_type (value_type (arg1), tem, + ada_attribute_name (op)); + if (type == NULL) + type = builtin_type (exp->gdbarch)->builtin_int; + } + + switch (op) + { + default: /* Should never happen. */ + error (_("unexpected attribute encountered")); + case OP_ATR_FIRST: + return value_from_longest + (type, ada_array_bound (arg1, tem, 0)); + case OP_ATR_LAST: + return value_from_longest + (type, ada_array_bound (arg1, tem, 1)); + case OP_ATR_LENGTH: + return value_from_longest + (type, ada_array_length (arg1, tem)); + } + } + else if (discrete_type_p (type_arg)) + { + struct type *range_type; + const char *name = ada_type_name (type_arg); + + range_type = NULL; + if (name != NULL && type_arg->code () != TYPE_CODE_ENUM) + range_type = to_fixed_range_type (type_arg, NULL); + if (range_type == NULL) + range_type = type_arg; + switch (op) + { + default: + error (_("unexpected attribute encountered")); + case OP_ATR_FIRST: + return value_from_longest + (range_type, ada_discrete_type_low_bound (range_type)); + case OP_ATR_LAST: + return value_from_longest + (range_type, ada_discrete_type_high_bound (range_type)); + case OP_ATR_LENGTH: + error (_("the 'length attribute applies only to array types")); + } + } + else if (type_arg->code () == TYPE_CODE_FLT) + error (_("unimplemented type attribute")); + else + { + LONGEST low, high; + + if (ada_is_constrained_packed_array_type (type_arg)) + type_arg = decode_constrained_packed_array_type (type_arg); + + struct type *type; + if (op == OP_ATR_LENGTH) + type = builtin_type (exp->gdbarch)->builtin_int; + else + { + type = ada_index_type (type_arg, tem, ada_attribute_name (op)); + if (type == NULL) + type = builtin_type (exp->gdbarch)->builtin_int; + } + + switch (op) + { + default: + error (_("unexpected attribute encountered")); + case OP_ATR_FIRST: + low = ada_array_bound_from_type (type_arg, tem, 0); + return value_from_longest (type, low); + case OP_ATR_LAST: + high = ada_array_bound_from_type (type_arg, tem, 1); + return value_from_longest (type, high); + case OP_ATR_LENGTH: + low = ada_array_bound_from_type (type_arg, tem, 0); + high = ada_array_bound_from_type (type_arg, tem, 1); + return value_from_longest (type, high - low + 1); + } + } +} + +/* A helper function for OP_ATR_MIN and OP_ATR_MAX. */ + +static struct value * +ada_binop_minmax (struct type *expect_type, + struct expression *exp, + enum noside noside, enum exp_opcode op, + struct value *arg1, struct value *arg2) +{ + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (value_type (arg1), not_lval); + else + { + binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2); + return value_binop (arg1, arg2, + op == OP_ATR_MIN ? BINOP_MIN : BINOP_MAX); + } +} + +/* A helper function for BINOP_EXP. */ + +static struct value * +ada_binop_exp (struct type *expect_type, + struct expression *exp, + enum noside noside, enum exp_opcode op, + struct value *arg1, struct value *arg2) +{ + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return value_zero (value_type (arg1), not_lval); + else + { + /* For integer exponentiation operations, + only promote the first argument. */ + if (is_integral_type (value_type (arg2))) + unop_promote (exp->language_defn, exp->gdbarch, &arg1); + else + binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2); + + return value_binop (arg1, arg2, op); + } +} + +namespace expr +{ + +value * +ada_wrapped_operation::evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) +{ + value *result = std::get<0> (m_storage)->evaluate (expect_type, exp, noside); + if (noside == EVAL_NORMAL) + result = unwrap_value (result); + + /* If evaluating an OP_FLOAT and an EXPECT_TYPE was provided, + then we need to perform the conversion manually, because + evaluate_subexp_standard doesn't do it. This conversion is + necessary in Ada because the different kinds of float/fixed + types in Ada have different representations. + + Similarly, we need to perform the conversion from OP_LONG + ourselves. */ + if ((opcode () == OP_FLOAT || opcode () == OP_LONG) && expect_type != NULL) + result = ada_value_cast (expect_type, result); + + return result; +} + +value * +ada_string_operation::evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) +{ + value *result = string_operation::evaluate (expect_type, exp, noside); + /* The result type will have code OP_STRING, bashed there from + OP_ARRAY. Bash it back. */ + if (value_type (result)->code () == TYPE_CODE_STRING) + value_type (result)->set_code (TYPE_CODE_ARRAY); + return result; +} + +value * +ada_qual_operation::evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) +{ + struct type *type = std::get<1> (m_storage); + return std::get<0> (m_storage)->evaluate (type, exp, noside); +} + +value * +ada_ternop_range_operation::evaluate (struct type *expect_type, + struct expression *exp, + enum noside noside) +{ + value *arg0 = std::get<0> (m_storage)->evaluate (nullptr, exp, noside); + value *arg1 = std::get<1> (m_storage)->evaluate (nullptr, exp, noside); + value *arg2 = std::get<2> (m_storage)->evaluate (nullptr, exp, noside); + return eval_ternop_in_range (expect_type, exp, noside, arg0, arg1, arg2); +} + +} + /* Implement the evaluate_exp routine in the exp_descriptor structure for the Ada language. */ @@ -10164,11 +10582,6 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp, { /* Nothing. */ } - else if (ada_is_gnat_encoded_fixed_point_type (value_type (arg1))) - arg2 = cast_to_gnat_encoded_fixed_point_type (value_type (arg1), arg2); - else if (ada_is_gnat_encoded_fixed_point_type (value_type (arg2))) - error - (_("Fixed-point values must be assigned to fixed-point variables")); else arg2 = coerce_for_assign (value_type (arg1), arg2); return ada_value_assign (arg1, arg2); @@ -10192,14 +10605,7 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp, type = value_type (arg1); while (type->code () == TYPE_CODE_REF) type = TYPE_TARGET_TYPE (type); - if (ada_is_gnat_encoded_fixed_point_type (value_type (arg1)) - || ada_is_gnat_encoded_fixed_point_type (value_type (arg2))) - { - if (value_type (arg1) != value_type (arg2)) - error (_("Operands of fixed-point addition must have the same type")); - } - else - binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2); + binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2); arg1 = value_binop (arg1, arg2, BINOP_ADD); /* We need to special-case the result of adding to a range. This is done for the benefit of "ptype". gdb's Ada support @@ -10228,15 +10634,7 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp, type = value_type (arg1); while (type->code () == TYPE_CODE_REF) type = TYPE_TARGET_TYPE (type); - if (ada_is_gnat_encoded_fixed_point_type (value_type (arg1)) - || ada_is_gnat_encoded_fixed_point_type (value_type (arg2))) - { - if (value_type (arg1) != value_type (arg2)) - error (_("Operands of fixed-point subtraction " - "must have the same type")); - } - else - binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2); + binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2); arg1 = value_binop (arg1, arg2, BINOP_SUB); /* We need to special-case the result of adding to a range. This is done for the benefit of "ptype". gdb's Ada support @@ -10254,21 +10652,8 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp, arg2 = evaluate_subexp (nullptr, exp, pos, noside); if (noside == EVAL_SKIP) goto nosideret; - else if (noside == EVAL_AVOID_SIDE_EFFECTS) - { - binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2); - return value_zero (value_type (arg1), not_lval); - } - else - { - type = builtin_type (exp->gdbarch)->builtin_double; - if (ada_is_gnat_encoded_fixed_point_type (value_type (arg1))) - arg1 = cast_from_gnat_encoded_fixed_point_type (type, arg1); - if (ada_is_gnat_encoded_fixed_point_type (value_type (arg2))) - arg2 = cast_from_gnat_encoded_fixed_point_type (type, arg2); - binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2); - return ada_value_binop (arg1, arg2, op); - } + return ada_mult_binop (expect_type, exp, noside, op, + arg1, arg2); case BINOP_EQUAL: case BINOP_NOTEQUAL: @@ -10276,29 +10661,11 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp, arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside); if (noside == EVAL_SKIP) goto nosideret; - if (noside == EVAL_AVOID_SIDE_EFFECTS) - tem = 0; - else - { - binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2); - tem = ada_value_equal (arg1, arg2); - } - if (op == BINOP_NOTEQUAL) - tem = !tem; - type = language_bool_type (exp->language_defn, exp->gdbarch); - return value_from_longest (type, (LONGEST) tem); + return ada_equal_binop (expect_type, exp, noside, op, arg1, arg2); case UNOP_NEG: arg1 = evaluate_subexp (nullptr, exp, pos, noside); - if (noside == EVAL_SKIP) - goto nosideret; - else if (ada_is_gnat_encoded_fixed_point_type (value_type (arg1))) - return value_cast (value_type (arg1), value_neg (arg1)); - else - { - unop_promote (exp->language_defn, exp->gdbarch, &arg1); - return value_neg (arg1); - } + return ada_unop_neg (expect_type, exp, noside, op, arg1); case BINOP_LOGICAL_AND: case BINOP_LOGICAL_OR: @@ -10568,113 +10935,19 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp, = evaluate_subexp (nullptr, exp, pos, noside); struct value *high_bound_val = evaluate_subexp (nullptr, exp, pos, noside); - LONGEST low_bound; - LONGEST high_bound; - - low_bound_val = coerce_ref (low_bound_val); - high_bound_val = coerce_ref (high_bound_val); - low_bound = value_as_long (low_bound_val); - high_bound = value_as_long (high_bound_val); if (noside == EVAL_SKIP) goto nosideret; - /* If this is a reference to an aligner type, then remove all - the aligners. */ - if (value_type (array)->code () == TYPE_CODE_REF - && ada_is_aligner_type (TYPE_TARGET_TYPE (value_type (array)))) - TYPE_TARGET_TYPE (value_type (array)) = - ada_aligned_type (TYPE_TARGET_TYPE (value_type (array))); - - if (ada_is_any_packed_array_type (value_type (array))) - error (_("cannot slice a packed array")); - - /* If this is a reference to an array or an array lvalue, - convert to a pointer. */ - if (value_type (array)->code () == TYPE_CODE_REF - || (value_type (array)->code () == TYPE_CODE_ARRAY - && VALUE_LVAL (array) == lval_memory)) - array = value_addr (array); - - if (noside == EVAL_AVOID_SIDE_EFFECTS - && ada_is_array_descriptor_type (ada_check_typedef - (value_type (array)))) - return empty_array (ada_type_of_array (array, 0), low_bound, - high_bound); - - array = ada_coerce_to_simple_array_ptr (array); - - /* If we have more than one level of pointer indirection, - dereference the value until we get only one level. */ - while (value_type (array)->code () == TYPE_CODE_PTR - && (TYPE_TARGET_TYPE (value_type (array))->code () - == TYPE_CODE_PTR)) - array = value_ind (array); - - /* Make sure we really do have an array type before going further, - to avoid a SEGV when trying to get the index type or the target - type later down the road if the debug info generated by - the compiler is incorrect or incomplete. */ - if (!ada_is_simple_array_type (value_type (array))) - error (_("cannot take slice of non-array")); - - if (ada_check_typedef (value_type (array))->code () - == TYPE_CODE_PTR) - { - struct type *type0 = ada_check_typedef (value_type (array)); - - if (high_bound < low_bound || noside == EVAL_AVOID_SIDE_EFFECTS) - return empty_array (TYPE_TARGET_TYPE (type0), low_bound, high_bound); - else - { - struct type *arr_type0 = - to_fixed_array_type (TYPE_TARGET_TYPE (type0), NULL, 1); - - return ada_value_slice_from_ptr (array, arr_type0, - longest_to_int (low_bound), - longest_to_int (high_bound)); - } - } - else if (noside == EVAL_AVOID_SIDE_EFFECTS) - return array; - else if (high_bound < low_bound) - return empty_array (value_type (array), low_bound, high_bound); - else - return ada_value_slice (array, longest_to_int (low_bound), - longest_to_int (high_bound)); + return ada_ternop_slice (exp, noside, array, low_bound_val, + high_bound_val); } case UNOP_IN_RANGE: (*pos) += 2; arg1 = evaluate_subexp (nullptr, exp, pos, noside); type = check_typedef (exp->elts[pc + 1].type); - - if (noside == EVAL_SKIP) - goto nosideret; - - switch (type->code ()) - { - default: - lim_warning (_("Membership test incompletely implemented; " - "always returns true")); - type = language_bool_type (exp->language_defn, exp->gdbarch); - return value_from_longest (type, (LONGEST) 1); - - case TYPE_CODE_RANGE: - arg2 = value_from_longest (type, - type->bounds ()->low.const_val ()); - arg3 = value_from_longest (type, - type->bounds ()->high.const_val ()); - binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2); - binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg3); - type = language_bool_type (exp->language_defn, exp->gdbarch); - return - value_from_longest (type, - (value_less (arg1, arg3) - || value_equal (arg1, arg3)) - && (value_less (arg2, arg1) - || value_equal (arg2, arg1))); - } + return ada_unop_in_range (expect_type, exp, noside, op, arg1, type); case BINOP_IN_BOUNDS: (*pos) += 2; @@ -10684,48 +10957,16 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp, if (noside == EVAL_SKIP) goto nosideret; - if (noside == EVAL_AVOID_SIDE_EFFECTS) - { - type = language_bool_type (exp->language_defn, exp->gdbarch); - return value_zero (type, not_lval); - } - tem = longest_to_int (exp->elts[pc + 1].longconst); - type = ada_index_type (value_type (arg2), tem, "range"); - if (!type) - type = value_type (arg1); - - arg3 = value_from_longest (type, ada_array_bound (arg2, tem, 1)); - arg2 = value_from_longest (type, ada_array_bound (arg2, tem, 0)); - - binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2); - binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg3); - type = language_bool_type (exp->language_defn, exp->gdbarch); - return - value_from_longest (type, - (value_less (arg1, arg3) - || value_equal (arg1, arg3)) - && (value_less (arg2, arg1) - || value_equal (arg2, arg1))); + return ada_binop_in_bounds (exp, noside, arg1, arg2, tem); case TERNOP_IN_RANGE: arg1 = evaluate_subexp (nullptr, exp, pos, noside); arg2 = evaluate_subexp (nullptr, exp, pos, noside); arg3 = evaluate_subexp (nullptr, exp, pos, noside); - if (noside == EVAL_SKIP) - goto nosideret; - - binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2); - binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg3); - type = language_bool_type (exp->language_defn, exp->gdbarch); - return - value_from_longest (type, - (value_less (arg1, arg3) - || value_equal (arg1, arg3)) - && (value_less (arg2, arg1) - || value_equal (arg2, arg1))); + return eval_ternop_in_range (expect_type, exp, noside, arg1, arg2, arg3); case OP_ATR_FIRST: case OP_ATR_LAST: @@ -10752,134 +10993,15 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp, if (noside == EVAL_SKIP) goto nosideret; - else if (noside == EVAL_AVOID_SIDE_EFFECTS) - { - if (type_arg == NULL) - type_arg = value_type (arg1); - - if (ada_is_constrained_packed_array_type (type_arg)) - type_arg = decode_constrained_packed_array_type (type_arg); - - if (!discrete_type_p (type_arg)) - { - switch (op) - { - default: /* Should never happen. */ - error (_("unexpected attribute encountered")); - case OP_ATR_FIRST: - case OP_ATR_LAST: - type_arg = ada_index_type (type_arg, tem, - ada_attribute_name (op)); - break; - case OP_ATR_LENGTH: - type_arg = builtin_type (exp->gdbarch)->builtin_int; - break; - } - } - - return value_zero (type_arg, not_lval); - } - else if (type_arg == NULL) - { - arg1 = ada_coerce_ref (arg1); - if (ada_is_constrained_packed_array_type (value_type (arg1))) - arg1 = ada_coerce_to_simple_array (arg1); - - if (op == OP_ATR_LENGTH) - type = builtin_type (exp->gdbarch)->builtin_int; - else - { - type = ada_index_type (value_type (arg1), tem, - ada_attribute_name (op)); - if (type == NULL) - type = builtin_type (exp->gdbarch)->builtin_int; - } - - switch (op) - { - default: /* Should never happen. */ - error (_("unexpected attribute encountered")); - case OP_ATR_FIRST: - return value_from_longest - (type, ada_array_bound (arg1, tem, 0)); - case OP_ATR_LAST: - return value_from_longest - (type, ada_array_bound (arg1, tem, 1)); - case OP_ATR_LENGTH: - return value_from_longest - (type, ada_array_length (arg1, tem)); - } - } - else if (discrete_type_p (type_arg)) - { - struct type *range_type; - const char *name = ada_type_name (type_arg); - - range_type = NULL; - if (name != NULL && type_arg->code () != TYPE_CODE_ENUM) - range_type = to_fixed_range_type (type_arg, NULL); - if (range_type == NULL) - range_type = type_arg; - switch (op) - { - default: - error (_("unexpected attribute encountered")); - case OP_ATR_FIRST: - return value_from_longest - (range_type, ada_discrete_type_low_bound (range_type)); - case OP_ATR_LAST: - return value_from_longest - (range_type, ada_discrete_type_high_bound (range_type)); - case OP_ATR_LENGTH: - error (_("the 'length attribute applies only to array types")); - } - } - else if (type_arg->code () == TYPE_CODE_FLT) - error (_("unimplemented type attribute")); - else - { - LONGEST low, high; - - if (ada_is_constrained_packed_array_type (type_arg)) - type_arg = decode_constrained_packed_array_type (type_arg); - - if (op == OP_ATR_LENGTH) - type = builtin_type (exp->gdbarch)->builtin_int; - else - { - type = ada_index_type (type_arg, tem, ada_attribute_name (op)); - if (type == NULL) - type = builtin_type (exp->gdbarch)->builtin_int; - } - - switch (op) - { - default: - error (_("unexpected attribute encountered")); - case OP_ATR_FIRST: - low = ada_array_bound_from_type (type_arg, tem, 0); - return value_from_longest (type, low); - case OP_ATR_LAST: - high = ada_array_bound_from_type (type_arg, tem, 1); - return value_from_longest (type, high); - case OP_ATR_LENGTH: - low = ada_array_bound_from_type (type_arg, tem, 0); - high = ada_array_bound_from_type (type_arg, tem, 1); - return value_from_longest (type, high - low + 1); - } - } + return ada_unop_atr (exp, noside, op, arg1, type_arg, tem); } case OP_ATR_TAG: arg1 = evaluate_subexp (nullptr, exp, pos, noside); if (noside == EVAL_SKIP) goto nosideret; - - if (noside == EVAL_AVOID_SIDE_EFFECTS) - return value_zero (ada_tag_type (arg1), not_lval); - - return ada_value_tag (arg1); + return ada_atr_tag (expect_type, exp, noside, op, arg1); case OP_ATR_MIN: case OP_ATR_MAX: @@ -10888,14 +11010,7 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp, arg2 = evaluate_subexp (nullptr, exp, pos, noside); if (noside == EVAL_SKIP) goto nosideret; - else if (noside == EVAL_AVOID_SIDE_EFFECTS) - return value_zero (value_type (arg1), not_lval); - else - { - binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2); - return value_binop (arg1, arg2, - op == OP_ATR_MIN ? BINOP_MIN : BINOP_MAX); - } + return ada_binop_minmax (expect_type, exp, noside, op, arg1, arg2); case OP_ATR_MODULUS: { @@ -10926,21 +11041,7 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp, case OP_ATR_SIZE: arg1 = evaluate_subexp (nullptr, exp, pos, noside); - type = value_type (arg1); - - /* If the argument is a reference, then dereference its type, since - the user is really asking for the size of the actual object, - not the size of the pointer. */ - if (type->code () == TYPE_CODE_REF) - type = TYPE_TARGET_TYPE (type); - - if (noside == EVAL_SKIP) - goto nosideret; - else if (noside == EVAL_AVOID_SIDE_EFFECTS) - return value_zero (builtin_type (exp->gdbarch)->builtin_int, not_lval); - else - return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, - TARGET_CHAR_BIT * TYPE_LENGTH (type)); + return ada_atr_size (expect_type, exp, noside, op, arg1); case OP_ATR_VAL: evaluate_subexp (nullptr, exp, pos, EVAL_SKIP); @@ -10948,29 +11049,14 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp, type = exp->elts[pc + 2].type; if (noside == EVAL_SKIP) goto nosideret; - else if (noside == EVAL_AVOID_SIDE_EFFECTS) - return value_zero (type, not_lval); - else - return value_val_atr (type, arg1); + return ada_val_atr (noside, type, arg1); case BINOP_EXP: arg1 = evaluate_subexp (nullptr, exp, pos, noside); arg2 = evaluate_subexp (nullptr, exp, pos, noside); if (noside == EVAL_SKIP) goto nosideret; - else if (noside == EVAL_AVOID_SIDE_EFFECTS) - return value_zero (value_type (arg1), not_lval); - else - { - /* For integer exponentiation operations, - only promote the first argument. */ - if (is_integral_type (value_type (arg2))) - unop_promote (exp->language_defn, exp->gdbarch, &arg1); - else - binop_promote (exp->language_defn, exp->gdbarch, &arg1, &arg2); - - return value_binop (arg1, arg2, op); - } + return ada_binop_exp (expect_type, exp, noside, op, arg1, arg2); case UNOP_PLUS: arg1 = evaluate_subexp (nullptr, exp, pos, noside); @@ -10983,11 +11069,7 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp, arg1 = evaluate_subexp (nullptr, exp, pos, noside); if (noside == EVAL_SKIP) goto nosideret; - unop_promote (exp->language_defn, exp->gdbarch, &arg1); - if (value_less (arg1, value_zero (value_type (arg1), not_lval))) - return value_neg (arg1); - else - return arg1; + return ada_abs (expect_type, exp, noside, op, arg1); case UNOP_IND: preeval_pos = *pos; @@ -11159,41 +11241,6 @@ nosideret: } - /* Fixed point */ - -/* If TYPE encodes an Ada fixed-point type, return the suffix of the - type name that encodes the 'small and 'delta information. - Otherwise, return NULL. */ - -static const char * -gnat_encoded_fixed_point_type_info (struct type *type) -{ - const char *name = ada_type_name (type); - enum type_code code = (type == NULL) ? TYPE_CODE_UNDEF : type->code (); - - if ((code == TYPE_CODE_INT || code == TYPE_CODE_RANGE) && name != NULL) - { - const char *tail = strstr (name, "___XF_"); - - if (tail == NULL) - return NULL; - else - return tail + 5; - } - else if (code == TYPE_CODE_RANGE && TYPE_TARGET_TYPE (type) != type) - return gnat_encoded_fixed_point_type_info (TYPE_TARGET_TYPE (type)); - else - return NULL; -} - -/* Returns non-zero iff TYPE represents an Ada fixed-point type. */ - -int -ada_is_gnat_encoded_fixed_point_type (struct type *type) -{ - return gnat_encoded_fixed_point_type_info (type) != NULL; -} - /* Return non-zero iff TYPE represents a System.Address type. */ int @@ -11202,60 +11249,6 @@ ada_is_system_address_type (struct type *type) return (type->name () && strcmp (type->name (), "system__address") == 0); } -/* Assuming that TYPE is the representation of an Ada fixed-point - type, return the target floating-point type to be used to represent - of this type during internal computation. */ - -static struct type * -ada_scaling_type (struct type *type) -{ - return builtin_type (type->arch ())->builtin_long_double; -} - -/* Assuming that TYPE is the representation of an Ada fixed-point - type, return its delta, or NULL if the type is malformed and the - delta cannot be determined. */ - -struct value * -gnat_encoded_fixed_point_delta (struct type *type) -{ - const char *encoding = gnat_encoded_fixed_point_type_info (type); - struct type *scale_type = ada_scaling_type (type); - - long long num, den; - - if (sscanf (encoding, "_%lld_%lld", &num, &den) < 2) - return nullptr; - else - return value_binop (value_from_longest (scale_type, num), - value_from_longest (scale_type, den), BINOP_DIV); -} - -/* Assuming that ada_is_gnat_encoded_fixed_point_type (TYPE), return - the scaling factor ('SMALL value) associated with the type. */ - -struct value * -gnat_encoded_fixed_point_scaling_factor (struct type *type) -{ - const char *encoding = gnat_encoded_fixed_point_type_info (type); - struct type *scale_type = ada_scaling_type (type); - - long long num0, den0, num1, den1; - int n; - - n = sscanf (encoding, "_%lld_%lld_%lld_%lld", - &num0, &den0, &num1, &den1); - - if (n < 2) - return value_from_longest (scale_type, 1); - else if (n == 4) - return value_binop (value_from_longest (scale_type, num1), - value_from_longest (scale_type, den1), BINOP_DIV); - else - return value_binop (value_from_longest (scale_type, num0), - value_from_longest (scale_type, den0), BINOP_DIV); -} - /* Range types */ @@ -11270,8 +11263,7 @@ static int scan_discrim_bound (const char *str, int k, struct value *dval, LONGEST * px, int *pnew_k) { - static char *bound_buffer = NULL; - static size_t bound_buffer_len = 0; + static std::string storage; const char *pstart, *pend, *bound; struct value *bound_val; @@ -11290,11 +11282,8 @@ scan_discrim_bound (const char *str, int k, struct value *dval, LONGEST * px, int len = pend - pstart; /* Strip __ and beyond. */ - GROW_VECT (bound_buffer, bound_buffer_len, len + 1); - strncpy (bound_buffer, pstart, len); - bound_buffer[len] = '\0'; - - bound = bound_buffer; + storage = std::string (pstart, len); + bound = storage.c_str (); k = pend - str; } @@ -11319,12 +11308,12 @@ get_var_value (const char *name, const char *err_msg) lookup_name_info lookup_name (quoted_name, symbol_name_match_type::FULL); - std::vector syms; - int nsyms = ada_lookup_symbol_list_worker (lookup_name, - get_selected_block (0), - VAR_DOMAIN, &syms, 1); + std::vector syms + = ada_lookup_symbol_list_worker (lookup_name, + get_selected_block (0), + VAR_DOMAIN, 1); - if (nsyms != 1) + if (syms.size () != 1) { if (err_msg == NULL) return 0; @@ -11391,18 +11380,12 @@ to_fixed_range_type (struct type *raw_type, struct value *dval) } else { - static char *name_buf = NULL; - static size_t name_len = 0; int prefix_len = subtype_info - name; LONGEST L, U; struct type *type; const char *bounds_str; int n; - GROW_VECT (name_buf, name_len, prefix_len + 5); - strncpy (name_buf, name, prefix_len); - name_buf[prefix_len] = '\0'; - subtype_info += 5; bounds_str = strchr (subtype_info, '_'); n = 1; @@ -11420,8 +11403,8 @@ to_fixed_range_type (struct type *raw_type, struct value *dval) } else { - strcpy (name_buf + prefix_len, "___L"); - if (!get_int_var_value (name_buf, L)) + std::string name_buf = std::string (name, prefix_len) + "___L"; + if (!get_int_var_value (name_buf.c_str (), L)) { lim_warning (_("Unknown lower bound, using 1.")); L = 1; @@ -11436,8 +11419,8 @@ to_fixed_range_type (struct type *raw_type, struct value *dval) } else { - strcpy (name_buf + prefix_len, "___U"); - if (!get_int_var_value (name_buf, U)) + std::string name_buf = std::string (name, prefix_len) + "___U"; + if (!get_int_var_value (name_buf.c_str (), U)) { lim_warning (_("Unknown upper bound, using %ld."), (long) L); U = L; @@ -13854,9 +13837,8 @@ public: domain_enum domain, gdb::function_view callback) const override { - std::vector results; - - ada_lookup_symbol_list_worker (name, block, domain, &results, 0); + std::vector results + = ada_lookup_symbol_list_worker (name, block, domain, 0); for (block_symbol &sym : results) { if (!callback (&sym))