X-Git-Url: http://drtracing.org/?a=blobdiff_plain;ds=sidebyside;f=gdb%2Fada-lang.c;h=f3f1f3496241bb831c36d92705733050d65cbc87;hb=781b42b0ba532fe1d16fddce1301180dfd184788;hp=49da2ec43bf65e9eaf54687a1d9bd4e310233233;hpb=a93c0eb6957e86a30b624c0fb097f9370ea56e9c;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 49da2ec43b..f3f1f34962 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -55,6 +55,7 @@ #include "valprint.h" #include "source.h" #include "observer.h" +#include "vec.h" #ifndef ADA_RETAIN_DOTS #define ADA_RETAIN_DOTS 0 @@ -68,7 +69,6 @@ #define TRUNCATION_TOWARDS_ZERO ((-5 / 2) == -2) #endif - static void extract_string (CORE_ADDR addr, char *buf); static void modify_general_field (char *, LONGEST, int, int); @@ -115,13 +115,12 @@ static struct value *make_array_descriptor (struct type *, struct value *, static void ada_add_block_symbols (struct obstack *, struct block *, const char *, - domain_enum, struct objfile *, - struct symtab *, int); + domain_enum, struct objfile *, int); static int is_nonfunction (struct ada_symbol_info *, int); static void add_defn_to_vec (struct obstack *, struct symbol *, - struct block *, struct symtab *); + struct block *); static int num_defns_collected (struct obstack *); @@ -316,6 +315,37 @@ static struct obstack symbol_list_obstack; /* Utilities */ +/* Given DECODED_NAME a string holding a symbol name in its + decoded form (ie using the Ada dotted notation), returns + its unqualified name. */ + +static const char * +ada_unqualified_name (const char *decoded_name) +{ + const char *result = strrchr (decoded_name, '.'); + + if (result != NULL) + result++; /* Skip the dot... */ + else + result = decoded_name; + + return result; +} + +/* Return a string starting with '<', followed by STR, and '>'. + The result is good until the next call. */ + +static char * +add_angle_brackets (const char *str) +{ + static char *result = NULL; + + xfree (result); + result = (char *) xmalloc ((strlen (str) + 3) * sizeof (char)); + + sprintf (result, "<%s>", str); + return result; +} static char * ada_get_gdb_completer_word_break_characters (void) @@ -1875,7 +1905,8 @@ decode_packed_array (struct value *arr) return NULL; } - if (BITS_BIG_ENDIAN && ada_is_modular_type (value_type (arr))) + if (gdbarch_bits_big_endian (current_gdbarch) + && ada_is_modular_type (value_type (arr))) { /* This is a (right-justified) modular type representing a packed array with no wrapper. In order to interpret the value through @@ -1998,7 +2029,7 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr, int len = (bit_size + bit_offset + HOST_CHAR_BIT - 1) / 8; /* Transmit bytes from least to most significant; delta is the direction the indices move. */ - int delta = BITS_BIG_ENDIAN ? -1 : 1; + int delta = gdbarch_bits_big_endian (current_gdbarch) ? -1 : 1; type = ada_check_typedef (type); @@ -2007,7 +2038,7 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr, v = allocate_value (type); bytes = (unsigned char *) (valaddr + offset); } - else if (value_lazy (obj)) + else if (VALUE_LVAL (obj) == lval_memory && value_lazy (obj)) { v = value_at (type, VALUE_ADDRESS (obj) + value_offset (obj) + offset); @@ -2047,7 +2078,7 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr, memset (unpacked, 0, TYPE_LENGTH (type)); return v; } - else if (BITS_BIG_ENDIAN) + else if (gdbarch_bits_big_endian (current_gdbarch)) { src = len - 1; if (has_negatives (type) @@ -2141,7 +2172,7 @@ move_bits (gdb_byte *target, int targ_offset, const gdb_byte *source, targ_offset %= HOST_CHAR_BIT; source += src_offset / HOST_CHAR_BIT; src_offset %= HOST_CHAR_BIT; - if (BITS_BIG_ENDIAN) + if (gdbarch_bits_big_endian (current_gdbarch)) { accum = (unsigned char) *source; source += 1; @@ -2221,6 +2252,7 @@ ada_value_assign (struct value *toval, struct value *fromval) { int len = (value_bitpos (toval) + bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT; + int from_size; char *buffer = (char *) alloca (len); struct value *val; CORE_ADDR to_addr = VALUE_ADDRESS (toval) + value_offset (toval); @@ -2229,11 +2261,12 @@ ada_value_assign (struct value *toval, struct value *fromval) fromval = value_cast (type, fromval); read_memory (to_addr, buffer, len); - if (BITS_BIG_ENDIAN) + from_size = value_bitsize (fromval); + if (from_size == 0) + from_size = TYPE_LENGTH (value_type (fromval)) * TARGET_CHAR_BIT; + if (gdbarch_bits_big_endian (current_gdbarch)) move_bits (buffer, value_bitpos (toval), - value_contents (fromval), - TYPE_LENGTH (value_type (fromval)) * TARGET_CHAR_BIT - - bits, bits); + value_contents (fromval), from_size - bits, bits); else move_bits (buffer, value_bitpos (toval), value_contents (fromval), 0, bits); @@ -2276,7 +2309,7 @@ value_assign_to_component (struct value *container, struct value *component, else bits = value_bitsize (component); - if (BITS_BIG_ENDIAN) + if (gdbarch_bits_big_endian (current_gdbarch)) move_bits (value_contents_writeable (container) + offset_in_container, value_bitpos (container) + bit_offset_in_container, value_contents (val), @@ -2859,14 +2892,9 @@ resolve_subexp (struct expression **expp, int *pos, int deprocedure_p, case LOC_REGISTER: case LOC_ARG: case LOC_REF_ARG: - case LOC_REGPARM: case LOC_REGPARM_ADDR: case LOC_LOCAL: - case LOC_LOCAL_ARG: - case LOC_BASEREG: - case LOC_BASEREG_ARG: case LOC_COMPUTED: - case LOC_COMPUTED_ARG: goto FoundNonType; default: break; @@ -3280,12 +3308,24 @@ user_select_syms (struct ada_symbol_info *syms, int nsyms, int max_results) int *chosen = (int *) alloca (sizeof (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_unfiltered (_("[0] cancel\n")); if (max_results > 1) printf_unfiltered (_("[1] all\n")); @@ -3380,18 +3420,15 @@ get_selections (int *choices, int n_choices, int max_results, int is_all_choice, char *annotation_suffix) { char *args; - const char *prompt; + char *prompt; int n_chosen; int first_choice = is_all_choice ? 2 : 1; prompt = getenv ("PS2"); if (prompt == NULL) - prompt = ">"; - - printf_unfiltered (("%s "), prompt); - gdb_flush (gdb_stdout); + prompt = "> "; - args = command_line_input ((char *) NULL, 0, annotation_suffix); + args = command_line_input (prompt, 0, annotation_suffix); if (args == NULL) error_no_arg (_("one or more choice numbers")); @@ -3935,15 +3972,14 @@ make_array_descriptor (struct type *type, struct value *arr, CORE_ADDR *sp) static int lookup_cached_symbol (const char *name, domain_enum namespace, - struct symbol **sym, struct block **block, - struct symtab **symtab) + struct symbol **sym, struct block **block) { return 0; } static void cache_symbol (const char *name, domain_enum namespace, struct symbol *sym, - struct block *block, struct symtab *symtab) + struct block *block) { } @@ -3957,13 +3993,11 @@ standard_lookup (const char *name, const struct block *block, domain_enum domain) { struct symbol *sym; - struct symtab *symtab; - if (lookup_cached_symbol (name, domain, &sym, NULL, NULL)) + if (lookup_cached_symbol (name, domain, &sym, NULL)) return sym; - sym = - lookup_symbol_in_language (name, block, domain, language_c, 0, &symtab); - cache_symbol (name, domain, sym, block_found, symtab); + sym = lookup_symbol_in_language (name, block, domain, language_c, 0); + cache_symbol (name, domain, sym, block_found); return sym; } @@ -4048,7 +4082,7 @@ lesseq_defined_than (struct symbol *sym0, struct symbol *sym1) static void add_defn_to_vec (struct obstack *obstackp, struct symbol *sym, - struct block *block, struct symtab *symtab) + struct block *block) { int i; size_t tmp; @@ -4071,7 +4105,6 @@ add_defn_to_vec (struct obstack *obstackp, { prevDefns[i].sym = sym; prevDefns[i].block = block; - prevDefns[i].symtab = symtab; return; } } @@ -4081,7 +4114,6 @@ add_defn_to_vec (struct obstack *obstackp, info.sym = sym; info.block = block; - info.symtab = symtab; obstack_grow (obstackp, &info, sizeof (struct ada_symbol_info)); } } @@ -4136,7 +4168,8 @@ ada_lookup_partial_symbol (struct partial_symtab *pst, const char *name, { struct partial_symbol *psym = start[i]; - if (SYMBOL_DOMAIN (psym) == namespace + if (symbol_matches_domain (SYMBOL_LANGUAGE (psym), + SYMBOL_DOMAIN (psym), namespace) && wild_match (name, name_len, SYMBOL_LINKAGE_NAME (psym))) return psym; } @@ -4170,7 +4203,8 @@ ada_lookup_partial_symbol (struct partial_symtab *pst, const char *name, { struct partial_symbol *psym = start[i]; - if (SYMBOL_DOMAIN (psym) == namespace) + if (symbol_matches_domain (SYMBOL_LANGUAGE (psym), + SYMBOL_DOMAIN (psym), namespace)) { int cmp = strncmp (name, SYMBOL_LINKAGE_NAME (psym), name_len); @@ -4213,7 +4247,8 @@ ada_lookup_partial_symbol (struct partial_symtab *pst, const char *name, { struct partial_symbol *psym = start[i]; - if (SYMBOL_DOMAIN (psym) == namespace) + if (symbol_matches_domain (SYMBOL_LANGUAGE (psym), + SYMBOL_DOMAIN (psym), namespace)) { int cmp; @@ -4280,15 +4315,10 @@ symtab_for_sym (struct symbol *sym) case LOC_REGISTER: case LOC_ARG: case LOC_REF_ARG: - case LOC_REGPARM: case LOC_REGPARM_ADDR: case LOC_LOCAL: case LOC_TYPEDEF: - case LOC_LOCAL_ARG: - case LOC_BASEREG: - case LOC_BASEREG_ARG: case LOC_COMPUTED: - case LOC_COMPUTED_ARG: for (j = FIRST_LOCAL_BLOCK; j < BLOCKVECTOR_NBLOCKS (BLOCKVECTOR (s)); j += 1) { @@ -4595,7 +4625,7 @@ remove_irrelevant_renamings (struct ada_symbol_info *syms, if (current_block == NULL) return nsyms; - current_function = block_function (current_block); + current_function = block_linkage_function (current_block); if (current_function == NULL) return nsyms; @@ -4628,7 +4658,7 @@ remove_irrelevant_renamings (struct ada_symbol_info *syms, /* Find symbols in DOMAIN matching NAME0, in BLOCK0 and enclosing scope and in global scopes, returning the number of matches. Sets - *RESULTS to point to a vector of (SYM,BLOCK,SYMTAB) triples, + *RESULTS to point to a vector of (SYM,BLOCK) tuples, indicating the symbols found and the blocks and symbol tables (if any) in which they were found. This vector are transient---good only to the next call of ada_lookup_symbol_list. Any non-function/non-enumeral @@ -4682,7 +4712,7 @@ ada_lookup_symbol_list (const char *name0, const struct block *block0, { block_depth += 1; ada_add_block_symbols (&symbol_list_obstack, block, name, - namespace, NULL, NULL, wild_match); + namespace, NULL, wild_match); /* If we found a non-function match, assume that's the one. */ if (is_nonfunction (defns_collected (&symbol_list_obstack, 0), @@ -4704,10 +4734,10 @@ ada_lookup_symbol_list (const char *name0, const struct block *block0, goto done; cacheIfUnique = 1; - if (lookup_cached_symbol (name0, namespace, &sym, &block, &s)) + if (lookup_cached_symbol (name0, namespace, &sym, &block)) { if (sym != NULL) - add_defn_to_vec (&symbol_list_obstack, sym, block, s); + add_defn_to_vec (&symbol_list_obstack, sym, block); goto done; } @@ -4720,7 +4750,7 @@ ada_lookup_symbol_list (const char *name0, const struct block *block0, bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); ada_add_block_symbols (&symbol_list_obstack, block, name, namespace, - objfile, s, wild_match); + objfile, wild_match); } if (namespace == VAR_DOMAIN) @@ -4743,14 +4773,14 @@ ada_lookup_symbol_list (const char *name0, const struct block *block0, block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); ada_add_block_symbols (&symbol_list_obstack, block, SYMBOL_LINKAGE_NAME (msymbol), - namespace, objfile, s, wild_match); + namespace, objfile, wild_match); if (num_defns_collected (&symbol_list_obstack) == ndefns0) { block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); ada_add_block_symbols (&symbol_list_obstack, block, SYMBOL_LINKAGE_NAME (msymbol), - namespace, objfile, s, + namespace, objfile, wild_match); } } @@ -4771,7 +4801,7 @@ ada_lookup_symbol_list (const char *name0, const struct block *block0, bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); ada_add_block_symbols (&symbol_list_obstack, block, name, - namespace, objfile, s, wild_match); + namespace, objfile, wild_match); } } @@ -4788,7 +4818,7 @@ ada_lookup_symbol_list (const char *name0, const struct block *block0, bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); ada_add_block_symbols (&symbol_list_obstack, block, name, namespace, - objfile, s, wild_match); + objfile, wild_match); } ALL_PSYMTABS (objfile, ps) @@ -4803,7 +4833,7 @@ ada_lookup_symbol_list (const char *name0, const struct block *block0, continue; block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); ada_add_block_symbols (&symbol_list_obstack, block, name, - namespace, objfile, s, wild_match); + namespace, objfile, wild_match); } } } @@ -4815,11 +4845,10 @@ done: ndefns = remove_extra_symbols (*results, ndefns); if (ndefns == 0) - cache_symbol (name0, namespace, NULL, NULL, NULL); + cache_symbol (name0, namespace, NULL, NULL); if (ndefns == 1 && cacheIfUnique) - cache_symbol (name0, namespace, (*results)[0].sym, (*results)[0].block, - (*results)[0].symtab); + cache_symbol (name0, namespace, (*results)[0].sym, (*results)[0].block); ndefns = remove_irrelevant_renamings (*results, ndefns, block0); @@ -4828,8 +4857,7 @@ done: struct symbol * ada_lookup_encoded_symbol (const char *name, const struct block *block0, - domain_enum namespace, - struct block **block_found, struct symtab **symtab) + domain_enum namespace, struct block **block_found) { struct ada_symbol_info *candidates; int n_candidates; @@ -4842,40 +4870,7 @@ ada_lookup_encoded_symbol (const char *name, const struct block *block0, if (block_found != NULL) *block_found = candidates[0].block; - if (symtab != NULL) - { - *symtab = candidates[0].symtab; - if (*symtab == NULL && candidates[0].block != NULL) - { - struct objfile *objfile; - struct symtab *s; - struct block *b; - struct blockvector *bv; - - /* Search the list of symtabs for one which contains the - address of the start of this block. */ - ALL_PRIMARY_SYMTABS (objfile, s) - { - bv = BLOCKVECTOR (s); - b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - if (BLOCK_START (b) <= BLOCK_START (candidates[0].block) - && BLOCK_END (b) > BLOCK_START (candidates[0].block)) - { - *symtab = s; - return fixup_symbol_section (candidates[0].sym, objfile); - } - } - /* FIXME: brobecker/2004-11-12: I think that we should never - reach this point. I don't see a reason why we would not - find a symtab for a given block, so I suggest raising an - internal_error exception here. Otherwise, we end up - returning a symbol but no symtab, which certain parts of - the code that rely (indirectly) on this function do not - expect, eventually causing a SEGV. */ - return fixup_symbol_section (candidates[0].sym, NULL); - } - } - return candidates[0].sym; + return fixup_symbol_section (candidates[0].sym, NULL); } /* Return a symbol in DOMAIN matching NAME, in BLOCK0 and enclosing @@ -4887,27 +4882,26 @@ ada_lookup_encoded_symbol (const char *name, const struct block *block0, assignments occur only if the pointers are non-null). */ struct symbol * ada_lookup_symbol (const char *name, const struct block *block0, - domain_enum namespace, int *is_a_field_of_this, - struct symtab **symtab) + domain_enum namespace, int *is_a_field_of_this) { if (is_a_field_of_this != NULL) *is_a_field_of_this = 0; return ada_lookup_encoded_symbol (ada_encode (ada_fold_name (name)), - block0, namespace, NULL, symtab); + block0, namespace, NULL); } static struct symbol * ada_lookup_symbol_nonlocal (const char *name, const char *linkage_name, const struct block *block, - const domain_enum domain, struct symtab **symtab) + const domain_enum domain) { if (linkage_name == NULL) linkage_name = name; return ada_lookup_symbol (linkage_name, block_static_block (block), domain, - NULL, symtab); + NULL); } @@ -5196,7 +5190,7 @@ static void ada_add_block_symbols (struct obstack *obstackp, struct block *block, const char *name, domain_enum domain, struct objfile *objfile, - struct symtab *symtab, int wild) + int wild) { struct dict_iterator iter; int name_len = strlen (name); @@ -5213,28 +5207,20 @@ ada_add_block_symbols (struct obstack *obstackp, struct symbol *sym; ALL_BLOCK_SYMBOLS (block, iter, sym) { - if (SYMBOL_DOMAIN (sym) == domain + if (symbol_matches_domain (SYMBOL_LANGUAGE (sym), + SYMBOL_DOMAIN (sym), domain) && wild_match (name, name_len, SYMBOL_LINKAGE_NAME (sym))) { - switch (SYMBOL_CLASS (sym)) - { - case LOC_ARG: - case LOC_LOCAL_ARG: - case LOC_REF_ARG: - case LOC_REGPARM: - case LOC_REGPARM_ADDR: - case LOC_BASEREG_ARG: - case LOC_COMPUTED_ARG: - arg_sym = sym; - break; - case LOC_UNRESOLVED: - continue; - default: + if (SYMBOL_CLASS (sym) == LOC_UNRESOLVED) + continue; + else if (SYMBOL_IS_ARGUMENT (sym)) + arg_sym = sym; + else + { found_sym = 1; add_defn_to_vec (obstackp, fixup_symbol_section (sym, objfile), - block, symtab); - break; + block); } } } @@ -5243,32 +5229,25 @@ ada_add_block_symbols (struct obstack *obstackp, { ALL_BLOCK_SYMBOLS (block, iter, sym) { - if (SYMBOL_DOMAIN (sym) == domain) + if (symbol_matches_domain (SYMBOL_LANGUAGE (sym), + SYMBOL_DOMAIN (sym), domain)) { int cmp = strncmp (name, SYMBOL_LINKAGE_NAME (sym), name_len); if (cmp == 0 && is_name_suffix (SYMBOL_LINKAGE_NAME (sym) + name_len)) { - switch (SYMBOL_CLASS (sym)) - { - case LOC_ARG: - case LOC_LOCAL_ARG: - case LOC_REF_ARG: - case LOC_REGPARM: - case LOC_REGPARM_ADDR: - case LOC_BASEREG_ARG: - case LOC_COMPUTED_ARG: - arg_sym = sym; - break; - case LOC_UNRESOLVED: - break; - default: - found_sym = 1; - add_defn_to_vec (obstackp, - fixup_symbol_section (sym, objfile), - block, symtab); - break; - } + if (SYMBOL_CLASS (sym) != LOC_UNRESOLVED) + { + if (SYMBOL_IS_ARGUMENT (sym)) + arg_sym = sym; + else + { + found_sym = 1; + add_defn_to_vec (obstackp, + fixup_symbol_section (sym, objfile), + block); + } + } } } } @@ -5278,7 +5257,7 @@ ada_add_block_symbols (struct obstack *obstackp, { add_defn_to_vec (obstackp, fixup_symbol_section (arg_sym, objfile), - block, symtab); + block); } if (!wild) @@ -5288,7 +5267,8 @@ ada_add_block_symbols (struct obstack *obstackp, ALL_BLOCK_SYMBOLS (block, iter, sym) { - if (SYMBOL_DOMAIN (sym) == domain) + if (symbol_matches_domain (SYMBOL_LANGUAGE (sym), + SYMBOL_DOMAIN (sym), domain)) { int cmp; @@ -5304,26 +5284,18 @@ ada_add_block_symbols (struct obstack *obstackp, if (cmp == 0 && is_name_suffix (SYMBOL_LINKAGE_NAME (sym) + name_len + 5)) { - switch (SYMBOL_CLASS (sym)) - { - case LOC_ARG: - case LOC_LOCAL_ARG: - case LOC_REF_ARG: - case LOC_REGPARM: - case LOC_REGPARM_ADDR: - case LOC_BASEREG_ARG: - case LOC_COMPUTED_ARG: - arg_sym = sym; - break; - case LOC_UNRESOLVED: - break; - default: - found_sym = 1; - add_defn_to_vec (obstackp, - fixup_symbol_section (sym, objfile), - block, symtab); - break; - } + if (SYMBOL_CLASS (sym) != LOC_UNRESOLVED) + { + if (SYMBOL_IS_ARGUMENT (sym)) + arg_sym = sym; + else + { + found_sym = 1; + add_defn_to_vec (obstackp, + fixup_symbol_section (sym, objfile), + block); + } + } } } } @@ -5334,11 +5306,312 @@ ada_add_block_symbols (struct obstack *obstackp, { add_defn_to_vec (obstackp, fixup_symbol_section (arg_sym, objfile), - block, symtab); + block); } } } + + /* Symbol Completion */ + +/* If SYM_NAME is a completion candidate for TEXT, return this symbol + name in a form that's appropriate for the completion. The result + does not need to be deallocated, but is only good until the next call. + + TEXT_LEN is equal to the length of TEXT. + Perform a wild match if WILD_MATCH is set. + ENCODED should be set if TEXT represents the start of a symbol name + in its encoded form. */ + +static const char * +symbol_completion_match (const char *sym_name, + const char *text, int text_len, + int wild_match, int encoded) +{ + char *result; + const int verbatim_match = (text[0] == '<'); + int match = 0; + + if (verbatim_match) + { + /* Strip the leading angle bracket. */ + text = text + 1; + text_len--; + } + + /* First, test against the fully qualified name of the symbol. */ + + if (strncmp (sym_name, text, text_len) == 0) + match = 1; + + if (match && !encoded) + { + /* One needed check before declaring a positive match is to verify + that iff we are doing a verbatim match, the decoded version + of the symbol name starts with '<'. Otherwise, this symbol name + is not a suitable completion. */ + const char *sym_name_copy = sym_name; + int has_angle_bracket; + + sym_name = ada_decode (sym_name); + has_angle_bracket = (sym_name[0] == '<'); + match = (has_angle_bracket == verbatim_match); + sym_name = sym_name_copy; + } + + if (match && !verbatim_match) + { + /* When doing non-verbatim match, another check that needs to + be done is to verify that the potentially matching symbol name + does not include capital letters, because the ada-mode would + not be able to understand these symbol names without the + angle bracket notation. */ + const char *tmp; + + for (tmp = sym_name; *tmp != '\0' && !isupper (*tmp); tmp++); + if (*tmp != '\0') + match = 0; + } + + /* Second: Try wild matching... */ + + if (!match && wild_match) + { + /* Since we are doing wild matching, this means that TEXT + may represent an unqualified symbol name. We therefore must + also compare TEXT against the unqualified name of the symbol. */ + sym_name = ada_unqualified_name (ada_decode (sym_name)); + + if (strncmp (sym_name, text, text_len) == 0) + match = 1; + } + + /* Finally: If we found a mach, prepare the result to return. */ + + if (!match) + return NULL; + + if (verbatim_match) + sym_name = add_angle_brackets (sym_name); + + if (!encoded) + sym_name = ada_decode (sym_name); + + return sym_name; +} + +typedef char *char_ptr; +DEF_VEC_P (char_ptr); + +/* A companion function to ada_make_symbol_completion_list(). + Check if SYM_NAME represents a symbol which name would be suitable + to complete TEXT (TEXT_LEN is the length of TEXT), in which case + it is appended at the end of the given string vector SV. + + ORIG_TEXT is the string original string from the user command + that needs to be completed. WORD is the entire command on which + completion should be performed. These two parameters are used to + determine which part of the symbol name should be added to the + completion vector. + if WILD_MATCH is set, then wild matching is performed. + ENCODED should be set if TEXT represents a symbol name in its + encoded formed (in which case the completion should also be + encoded). */ + +static void +symbol_completion_add (VEC(char_ptr) **sv, + const char *sym_name, + const char *text, int text_len, + const char *orig_text, const char *word, + int wild_match, int encoded) +{ + const char *match = symbol_completion_match (sym_name, text, text_len, + wild_match, encoded); + char *completion; + + if (match == NULL) + return; + + /* We found a match, so add the appropriate completion to the given + string vector. */ + + if (word == orig_text) + { + completion = xmalloc (strlen (match) + 5); + strcpy (completion, match); + } + else if (word > orig_text) + { + /* Return some portion of sym_name. */ + completion = xmalloc (strlen (match) + 5); + strcpy (completion, match + (word - orig_text)); + } + else + { + /* Return some of ORIG_TEXT plus sym_name. */ + completion = xmalloc (strlen (match) + (orig_text - word) + 5); + strncpy (completion, word, orig_text - word); + completion[orig_text - word] = '\0'; + strcat (completion, match); + } + + VEC_safe_push (char_ptr, *sv, completion); +} + +/* Return a list of possible symbol names completing TEXT0. The list + is NULL terminated. WORD is the entire command on which completion + is made. */ + +static char ** +ada_make_symbol_completion_list (char *text0, char *word) +{ + char *text; + int text_len; + int wild_match; + int encoded; + VEC(char_ptr) *completions = VEC_alloc (char_ptr, 128); + struct symbol *sym; + struct symtab *s; + struct partial_symtab *ps; + struct minimal_symbol *msymbol; + struct objfile *objfile; + struct block *b, *surrounding_static_block = 0; + int i; + struct dict_iterator iter; + + if (text0[0] == '<') + { + text = xstrdup (text0); + make_cleanup (xfree, text); + text_len = strlen (text); + wild_match = 0; + encoded = 1; + } + else + { + text = xstrdup (ada_encode (text0)); + make_cleanup (xfree, text); + text_len = strlen (text); + for (i = 0; i < text_len; i++) + text[i] = tolower (text[i]); + + encoded = (strstr (text0, "__") != NULL); + /* If the name contains a ".", then the user is entering a fully + qualified entity name, and the match must not be done in wild + mode. Similarly, if the user wants to complete what looks like + an encoded name, the match must not be done in wild mode. */ + wild_match = (strchr (text0, '.') == NULL && !encoded); + } + + /* First, look at the partial symtab symbols. */ + ALL_PSYMTABS (objfile, ps) + { + struct partial_symbol **psym; + + /* If the psymtab's been read in we'll get it when we search + through the blockvector. */ + if (ps->readin) + continue; + + for (psym = objfile->global_psymbols.list + ps->globals_offset; + psym < (objfile->global_psymbols.list + ps->globals_offset + + ps->n_global_syms); psym++) + { + QUIT; + symbol_completion_add (&completions, SYMBOL_LINKAGE_NAME (*psym), + text, text_len, text0, word, + wild_match, encoded); + } + + for (psym = objfile->static_psymbols.list + ps->statics_offset; + psym < (objfile->static_psymbols.list + ps->statics_offset + + ps->n_static_syms); psym++) + { + QUIT; + symbol_completion_add (&completions, SYMBOL_LINKAGE_NAME (*psym), + text, text_len, text0, word, + wild_match, encoded); + } + } + + /* At this point scan through the misc symbol vectors and add each + symbol you find to the list. Eventually we want to ignore + anything that isn't a text symbol (everything else will be + handled by the psymtab code above). */ + + ALL_MSYMBOLS (objfile, msymbol) + { + QUIT; + symbol_completion_add (&completions, SYMBOL_LINKAGE_NAME (msymbol), + text, text_len, text0, word, wild_match, encoded); + } + + /* Search upwards from currently selected frame (so that we can + complete on local vars. */ + + for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b)) + { + if (!BLOCK_SUPERBLOCK (b)) + surrounding_static_block = b; /* For elmin of dups */ + + ALL_BLOCK_SYMBOLS (b, iter, sym) + { + symbol_completion_add (&completions, SYMBOL_LINKAGE_NAME (sym), + text, text_len, text0, word, + wild_match, encoded); + } + } + + /* Go through the symtabs and check the externs and statics for + symbols which match. */ + + ALL_SYMTABS (objfile, s) + { + QUIT; + b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK); + ALL_BLOCK_SYMBOLS (b, iter, sym) + { + symbol_completion_add (&completions, SYMBOL_LINKAGE_NAME (sym), + text, text_len, text0, word, + wild_match, encoded); + } + } + + ALL_SYMTABS (objfile, s) + { + QUIT; + b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK); + /* Don't do this block twice. */ + if (b == surrounding_static_block) + continue; + ALL_BLOCK_SYMBOLS (b, iter, sym) + { + symbol_completion_add (&completions, SYMBOL_LINKAGE_NAME (sym), + text, text_len, text0, word, + wild_match, encoded); + } + } + + /* Append the closing NULL entry. */ + VEC_safe_push (char_ptr, completions, NULL); + + /* Make a copy of the COMPLETIONS VEC before we free it, and then + return the copy. It's unfortunate that we have to make a copy + of an array that we're about to destroy, but there is nothing much + we can do about it. Fortunately, it's typically not a very large + array. */ + { + const size_t completions_size = + VEC_length (char_ptr, completions) * sizeof (char *); + char **result = malloc (completions_size); + + memcpy (result, VEC_address (char_ptr, completions), completions_size); + + VEC_free (char_ptr, completions); + return result; + } +} + /* Field Access */ /* Return non-zero if TYPE is a pointer to the GNAT dispatch table used @@ -6448,7 +6721,7 @@ ada_find_renaming_symbol (const char *name, struct block *block) static struct symbol * find_old_style_renaming_symbol (const char *name, struct block *block) { - const struct symbol *function_sym = block_function (block); + const struct symbol *function_sym = block_linkage_function (block); char *rename; if (function_sym != NULL) @@ -7631,8 +7904,7 @@ unwrap_value (struct value *val) struct type *type = ada_check_typedef (value_type (val)); if (ada_is_aligner_type (type)) { - struct value *v = value_struct_elt (&val, NULL, "F", - NULL, "internal structure"); + struct value *v = ada_value_struct_elt (val, "F", 0); struct type *val_type = ada_check_typedef (value_type (v)); if (ada_type_name (val_type) == NULL) TYPE_NAME (val_type) = ada_type_name (type); @@ -8211,7 +8483,14 @@ ada_evaluate_subexp (struct type *expect_type, struct expression *exp, return arg1; return ada_value_assign (arg1, arg1); } - arg2 = evaluate_subexp (value_type (arg1), exp, pos, noside); + /* Force the evaluation of the rhs ARG2 to the type of the lhs ARG1, + except if the lhs of our assignment is a convenience variable. + In the case of assigning to a convenience variable, the lhs + should be exactly the result of the evaluation of the rhs. */ + type = value_type (arg1); + if (VALUE_LVAL (arg1) == lval_internalvar) + type = NULL; + arg2 = evaluate_subexp (type, exp, pos, noside); if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS) return arg1; if (ada_is_fixed_point_type (value_type (arg1))) @@ -9490,7 +9769,7 @@ ada_exception_support_info_sniffer (void) each time a new executable is loaded by GDB. */ static void -ada_executable_changed_observer (void *unused) +ada_executable_changed_observer (void) { /* If the executable changed, then it is possible that the Ada runtime is different. So we need to invalidate the exception support info @@ -10666,7 +10945,7 @@ const struct language_defn ada_language_defn = { ada_val_print, /* Print a value using appropriate syntax */ ada_value_print, /* Print a top-level value */ NULL, /* Language specific skip_trampoline */ - NULL, /* value_of_this */ + NULL, /* name_of_this */ ada_lookup_symbol_nonlocal, /* Looking up non-local symbols. */ basic_lookup_transparent_type, /* lookup_transparent_type */ ada_la_decode, /* Language specific symbol demangler */ @@ -10675,6 +10954,7 @@ const struct language_defn ada_language_defn = { 0, /* c-style arrays */ 1, /* String lower bound */ ada_get_gdb_completer_word_break_characters, + ada_make_symbol_completion_list, ada_language_arch_info, ada_print_array_index, default_pass_by_reference,