aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ada-lang.c119
-rw-r--r--gdb/ada-lang.h14
-rw-r--r--gdb/dwarf2/cooked-index.c6
-rw-r--r--gdb/symtab.h13
4 files changed, 40 insertions, 112 deletions
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index c3a2b2b..edd68cd 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -1308,7 +1308,7 @@ convert_from_hex_encoded (std::string &out, const char *str, int n)
/* See ada-lang.h. */
std::string
-ada_decode (const char *encoded, bool wrap, bool operators)
+ada_decode (const char *encoded, bool wrap, bool operators, bool wide)
{
int i;
int len0;
@@ -1502,7 +1502,7 @@ ada_decode (const char *encoded, bool wrap, bool operators)
i++;
}
- if (i < len0 + 3 && encoded[i] == 'U' && isxdigit (encoded[i + 1]))
+ if (wide && i < len0 + 3 && encoded[i] == 'U' && isxdigit (encoded[i + 1]))
{
if (convert_from_hex_encoded (decoded, &encoded[i + 1], 2))
{
@@ -1510,7 +1510,7 @@ ada_decode (const char *encoded, bool wrap, bool operators)
continue;
}
}
- else if (i < len0 + 5 && encoded[i] == 'W' && isxdigit (encoded[i + 1]))
+ else if (wide && i < len0 + 5 && encoded[i] == 'W' && isxdigit (encoded[i + 1]))
{
if (convert_from_hex_encoded (decoded, &encoded[i + 1], 4))
{
@@ -1518,7 +1518,7 @@ ada_decode (const char *encoded, bool wrap, bool operators)
continue;
}
}
- else if (i < len0 + 10 && encoded[i] == 'W' && encoded[i + 1] == 'W'
+ else if (wide && i < len0 + 10 && encoded[i] == 'W' && encoded[i + 1] == 'W'
&& isxdigit (encoded[i + 2]))
{
if (convert_from_hex_encoded (decoded, &encoded[i + 2], 8))
@@ -5465,91 +5465,6 @@ ada_add_block_renamings (std::vector<struct block_symbol> &result,
return result.size () != defns_mark;
}
-/* Implements compare_names, but only applying the comparision using
- the given CASING. */
-
-static int
-compare_names_with_case (const char *string1, const char *string2,
- enum case_sensitivity casing)
-{
- while (*string1 != '\0' && *string2 != '\0')
- {
- char c1, c2;
-
- if (isspace (*string1) || isspace (*string2))
- return strcmp_iw_ordered (string1, string2);
-
- if (casing == case_sensitive_off)
- {
- c1 = tolower (*string1);
- c2 = tolower (*string2);
- }
- else
- {
- c1 = *string1;
- c2 = *string2;
- }
- if (c1 != c2)
- break;
-
- string1 += 1;
- string2 += 1;
- }
-
- switch (*string1)
- {
- case '(':
- return strcmp_iw_ordered (string1, string2);
- case '_':
- if (*string2 == '\0')
- {
- if (is_name_suffix (string1))
- return 0;
- else
- return 1;
- }
- [[fallthrough]];
- default:
- if (*string2 == '(')
- return strcmp_iw_ordered (string1, string2);
- else
- {
- if (casing == case_sensitive_off)
- return tolower (*string1) - tolower (*string2);
- else
- return *string1 - *string2;
- }
- }
-}
-
-/* Compare STRING1 to STRING2, with results as for strcmp.
- Compatible with strcmp_iw_ordered in that...
-
- strcmp_iw_ordered (STRING1, STRING2) <= 0
-
- ... implies...
-
- compare_names (STRING1, STRING2) <= 0
-
- (they may differ as to what symbols compare equal). */
-
-static int
-compare_names (const char *string1, const char *string2)
-{
- int result;
-
- /* Similar to what strcmp_iw_ordered does, we need to perform
- a case-insensitive comparison first, and only resort to
- a second, case-sensitive, comparison if the first one was
- not sufficient to differentiate the two strings. */
-
- result = compare_names_with_case (string1, string2, case_sensitive_off);
- if (result == 0)
- result = compare_names_with_case (string1, string2, case_sensitive_on);
-
- return result;
-}
-
/* Convenience function to get at the Ada encoded lookup name for
LOOKUP_NAME, as a C string. */
@@ -5559,29 +5474,24 @@ ada_lookup_name (const lookup_name_info &lookup_name)
return lookup_name.ada ().lookup_name ().c_str ();
}
-/* A helper for add_nonlocal_symbols. Call expand_matching_symbols
+/* A helper for add_nonlocal_symbols. Expand all necessary symtabs
for OBJFILE, then walk the objfile's symtabs and update the
results. */
static void
map_matching_symbols (struct objfile *objfile,
const lookup_name_info &lookup_name,
- bool is_wild_match,
domain_enum domain,
int global,
match_data &data)
{
data.objfile = objfile;
- if (is_wild_match || lookup_name.ada ().standard_p ())
- objfile->expand_matching_symbols (lookup_name, domain, global,
- is_wild_match ? nullptr : compare_names);
- else
- objfile->expand_symtabs_matching (nullptr, &lookup_name,
- nullptr, nullptr,
- global
- ? SEARCH_GLOBAL_BLOCK
- : SEARCH_STATIC_BLOCK,
- domain, ALL_DOMAIN);
+ objfile->expand_symtabs_matching (nullptr, &lookup_name,
+ nullptr, nullptr,
+ global
+ ? SEARCH_GLOBAL_BLOCK
+ : SEARCH_STATIC_BLOCK,
+ domain, ALL_DOMAIN);
const int block_kind = global ? GLOBAL_BLOCK : STATIC_BLOCK;
for (compunit_symtab *symtab : objfile->compunits ())
@@ -5610,8 +5520,7 @@ add_nonlocal_symbols (std::vector<struct block_symbol> &result,
for (objfile *objfile : current_program_space->objfiles ())
{
- map_matching_symbols (objfile, lookup_name, is_wild_match, domain,
- global, data);
+ map_matching_symbols (objfile, lookup_name, domain, global, data);
for (compunit_symtab *cu : objfile->compunits ())
{
@@ -5631,7 +5540,7 @@ add_nonlocal_symbols (std::vector<struct block_symbol> &result,
lookup_name_info name1 (bracket_name, symbol_name_match_type::FULL);
for (objfile *objfile : current_program_space->objfiles ())
- map_matching_symbols (objfile, name1, false, domain, global, data);
+ map_matching_symbols (objfile, name1, domain, global, data);
}
}
@@ -13297,6 +13206,8 @@ ada_lookup_name_info::ada_lookup_name_info (const lookup_name_info &lookup_name)
else
m_standard_p = false;
+ m_decoded_name = ada_decode (m_encoded_name.c_str (), true, false, false);
+
/* 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
diff --git a/gdb/ada-lang.h b/gdb/ada-lang.h
index 9eb9326..14a0be4 100644
--- a/gdb/ada-lang.h
+++ b/gdb/ada-lang.h
@@ -216,10 +216,18 @@ extern const char *ada_decode_symbol (const struct general_symbol_info *);
the name does not appear to be GNAT-encoded, then the result
depends on WRAP. If WRAP is true (the default), then the result is
simply wrapped in <...>. If WRAP is false, then the empty string
- will be returned. Also, when OPERATORS is false, operator names
- will not be decoded. */
+ will be returned.
+
+ When OPERATORS is false, operator names will not be decoded. By
+ default, they are decoded, e.g., 'Oadd' will be transformed to
+ '"+"'.
+
+ When WIDE is false, wide characters will be left as-is. By
+ default, they converted from their hex encoding to the host
+ charset. */
extern std::string ada_decode (const char *name, bool wrap = true,
- bool operators = true);
+ bool operators = true,
+ bool wide = true);
extern std::vector<struct block_symbol> ada_lookup_symbol_list
(const char *, const struct block *, domain_enum);
diff --git a/gdb/dwarf2/cooked-index.c b/gdb/dwarf2/cooked-index.c
index 10631dc..ba77f9c 100644
--- a/gdb/dwarf2/cooked-index.c
+++ b/gdb/dwarf2/cooked-index.c
@@ -263,7 +263,11 @@ gdb::unique_xmalloc_ptr<char>
cooked_index_shard::handle_gnat_encoded_entry (cooked_index_entry *entry,
htab_t gnat_entries)
{
- std::string canonical = ada_decode (entry->name, false, false);
+ /* We decode Ada names in a particular way: operators and wide
+ characters are left as-is. This is done to make name matching a
+ bit simpler; and for wide characters, it means the choice of Ada
+ source charset does not affect the indexer directly. */
+ std::string canonical = ada_decode (entry->name, false, false, false);
if (canonical.empty ())
return {};
std::vector<std::string_view> names = split_name (canonical.c_str (),
diff --git a/gdb/symtab.h b/gdb/symtab.h
index c224f47..e9406e8 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -128,21 +128,26 @@ class ada_lookup_name_info final
peculiarities. */
std::vector<std::string_view> split_name () const
{
- if (m_verbatim_p || m_standard_p)
+ if (m_verbatim_p)
{
+ /* For verbatim matches, just return the encoded name
+ as-is. */
std::vector<std::string_view> result;
- if (m_standard_p)
- result.emplace_back ("standard");
result.emplace_back (m_encoded_name);
return result;
}
- return ::split_name (m_encoded_name.c_str (), split_style::UNDERSCORE);
+ /* Otherwise, split the decoded name for matching. */
+ return ::split_name (m_decoded_name.c_str (), split_style::DOT_STYLE);
}
private:
/* The Ada-encoded lookup name. */
std::string m_encoded_name;
+ /* The decoded lookup name. This is formed by calling ada_decode
+ with both 'operators' and 'wide' set to false. */
+ std::string m_decoded_name;
+
/* Whether the user-provided lookup name was Ada encoded. If so,
then return encoded names in the 'matches' method's 'completion
match result' output. */