Partial fix for PR c++/14160:
[deliverable/binutils-gdb.git] / gdb / symtab.c
index 65542a79e5224c49cfca378c390fa63d3934db3d..97f114fc34f331c46eb609ac15820161ca69a490 100644 (file)
@@ -62,6 +62,7 @@
 #include "macroscope.h"
 
 #include "psymtab.h"
+#include "parser-defs.h"
 
 /* Prototypes for local functions */
 
@@ -81,7 +82,7 @@ static struct symbol *lookup_symbol_aux (const char *name,
                                         const struct block *block,
                                         const domain_enum domain,
                                         enum language language,
-                                        int *is_a_field_of_this);
+                                        struct field_of_this_result *is_a_field_of_this);
 
 static
 struct symbol *lookup_symbol_aux_local (const char *name,
@@ -402,19 +403,20 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id)
 
   if (len == 0)
     {
-      sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
+      xsnprintf (buf, sizeof (buf), "__%s%s", const_prefix, volatile_prefix);
     }
   else if (physname[0] == 't' || physname[0] == 'Q')
     {
       /* The physname for template and qualified methods already includes
          the class name.  */
-      sprintf (buf, "__%s%s", const_prefix, volatile_prefix);
+      xsnprintf (buf, sizeof (buf), "__%s%s", const_prefix, volatile_prefix);
       newname = NULL;
       len = 0;
     }
   else
     {
-      sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len);
+      xsnprintf (buf, sizeof (buf), "__%s%s%d", const_prefix,
+                volatile_prefix, len);
     }
   mangled_name_len = ((is_constructor ? 0 : strlen (field_name))
                      + strlen (buf) + len + strlen (physname) + 1);
@@ -1223,7 +1225,7 @@ demangle_for_lookup (const char *name, enum language lang,
 struct symbol *
 lookup_symbol_in_language (const char *name, const struct block *block,
                           const domain_enum domain, enum language lang,
-                          int *is_a_field_of_this)
+                          struct field_of_this_result *is_a_field_of_this)
 {
   const char *modified_name;
   struct symbol *returnval;
@@ -1241,7 +1243,8 @@ lookup_symbol_in_language (const char *name, const struct block *block,
 
 struct symbol *
 lookup_symbol (const char *name, const struct block *block,
-              domain_enum domain, int *is_a_field_of_this)
+              domain_enum domain,
+              struct field_of_this_result *is_a_field_of_this)
 {
   return lookup_symbol_in_language (name, block, domain,
                                    current_language->la_language,
@@ -1276,24 +1279,68 @@ lookup_language_this (const struct language_defn *lang,
   return NULL;
 }
 
+/* Given TYPE, a structure/union,
+   return 1 if the component named NAME from the ultimate target
+   structure/union is defined, otherwise, return 0.  */
+
+static int
+check_field (struct type *type, const char *name,
+            struct field_of_this_result *is_a_field_of_this)
+{
+  int i;
+
+  /* The type may be a stub.  */
+  CHECK_TYPEDEF (type);
+
+  for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--)
+    {
+      const char *t_field_name = TYPE_FIELD_NAME (type, i);
+
+      if (t_field_name && (strcmp_iw (t_field_name, name) == 0))
+       {
+         is_a_field_of_this->type = type;
+         is_a_field_of_this->field = &TYPE_FIELD (type, i);
+         return 1;
+       }
+    }
+
+  /* C++: If it was not found as a data field, then try to return it
+     as a pointer to a method.  */
+
+  for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; --i)
+    {
+      if (strcmp_iw (TYPE_FN_FIELDLIST_NAME (type, i), name) == 0)
+       {
+         is_a_field_of_this->type = type;
+         is_a_field_of_this->fn_field = &TYPE_FN_FIELDLIST (type, i);
+         return 1;
+       }
+    }
+
+  for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
+    if (check_field (TYPE_BASECLASS (type, i), name, is_a_field_of_this))
+      return 1;
+
+  return 0;
+}
+
 /* Behave like lookup_symbol except that NAME is the natural name
    (e.g., demangled name) of the symbol that we're looking for.  */
 
 static struct symbol *
 lookup_symbol_aux (const char *name, const struct block *block,
                   const domain_enum domain, enum language language,
-                  int *is_a_field_of_this)
+                  struct field_of_this_result *is_a_field_of_this)
 {
   struct symbol *sym;
   const struct language_defn *langdef;
 
   /* Make sure we do something sensible with is_a_field_of_this, since
      the callers that set this parameter to some non-null value will
-     certainly use it later and expect it to be either 0 or 1.
-     If we don't set it, the contents of is_a_field_of_this are
-     undefined.  */
+     certainly use it later.  If we don't set it, the contents of
+     is_a_field_of_this are undefined.  */
   if (is_a_field_of_this != NULL)
-    *is_a_field_of_this = 0;
+    memset (is_a_field_of_this, 0, sizeof (*is_a_field_of_this));
 
   /* Search specified block and its superiors.  Don't search
      STATIC_BLOCK or GLOBAL_BLOCK.  */
@@ -1327,11 +1374,8 @@ lookup_symbol_aux (const char *name, const struct block *block,
            error (_("Internal error: `%s' is not an aggregate"),
                   langdef->la_name_of_this);
 
-         if (check_field (t, name))
-           {
-             *is_a_field_of_this = 1;
-             return NULL;
-           }
+         if (check_field (t, name, is_a_field_of_this))
+           return NULL;
        }
     }
 
@@ -2148,6 +2192,8 @@ find_pc_sect_symtab (CORE_ADDR pc, struct obj_section *section)
   if (best_s != NULL)
     return (best_s);
 
+  /* Not found in symtabs, search the "quick" symtabs (e.g. psymtabs).  */
+
   ALL_OBJFILES (objfile)
   {
     struct symtab *result;
@@ -3777,10 +3823,11 @@ symtab_symbol_info (char *regexp, enum search_domain kind, int from_tty)
   search_symbols (regexp, kind, 0, (char **) NULL, &symbols);
   old_chain = make_cleanup_free_search_symbols (symbols);
 
-  printf_filtered (regexp
-                  ? "All %ss matching regular expression \"%s\":\n"
-                  : "All defined %ss:\n",
-                  classnames[kind], regexp);
+  if (regexp != NULL)
+    printf_filtered (_("All %ss matching regular expression \"%s\":\n"),
+                    classnames[kind], regexp);
+  else
+    printf_filtered (_("All defined %ss:\n"), classnames[kind]);
 
   for (p = symbols; p != NULL; p = p->next)
     {
@@ -3790,7 +3837,7 @@ symtab_symbol_info (char *regexp, enum search_domain kind, int from_tty)
        {
          if (first)
            {
-             printf_filtered ("\nNon-debugging symbols:\n");
+             printf_filtered (_("\nNon-debugging symbols:\n"));
              first = 0;
            }
          print_msymbol_info (p->msymbol);
@@ -4199,7 +4246,8 @@ expand_partial_symbol_name (const char *name, void *user_data)
 
 VEC (char_ptr) *
 default_make_symbol_completion_list_break_on (char *text, char *word,
-                                             const char *break_on)
+                                             const char *break_on,
+                                             enum type_code code)
 {
   /* Problem: All of the symbols have to be copied because readline
      frees them.  I'm not going to worry about this; hopefully there
@@ -4306,13 +4354,18 @@ default_make_symbol_completion_list_break_on (char *text, char *word,
      anything that isn't a text symbol (everything else will be
      handled by the psymtab code above).  */
 
-  ALL_MSYMBOLS (objfile, msymbol)
-  {
-    QUIT;
-    COMPLETION_LIST_ADD_SYMBOL (msymbol, sym_text, sym_text_len, text, word);
+  if (code == TYPE_CODE_UNDEF)
+    {
+      ALL_MSYMBOLS (objfile, msymbol)
+       {
+         QUIT;
+         COMPLETION_LIST_ADD_SYMBOL (msymbol, sym_text, sym_text_len, text,
+                                     word);
 
-    completion_list_objc_symbol (msymbol, sym_text, sym_text_len, text, word);
-  }
+         completion_list_objc_symbol (msymbol, sym_text, sym_text_len, text,
+                                      word);
+       }
+    }
 
   /* Search upwards from currently selected frame (so that we can
      complete on local vars).  Also catch fields of types defined in
@@ -4329,10 +4382,17 @@ default_make_symbol_completion_list_break_on (char *text, char *word,
 
        ALL_BLOCK_SYMBOLS (b, iter, sym)
          {
-           COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text,
-                                       word);
-           completion_list_add_fields (sym, sym_text, sym_text_len, text,
-                                       word);
+           if (code == TYPE_CODE_UNDEF)
+             {
+               COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text,
+                                           word);
+               completion_list_add_fields (sym, sym_text, sym_text_len, text,
+                                           word);
+             }
+           else if (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN
+                    && TYPE_CODE (SYMBOL_TYPE (sym)) == code)
+             COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text,
+                                         word);
          }
 
        /* Stop when we encounter an enclosing function.  Do not stop for
@@ -4345,13 +4405,16 @@ default_make_symbol_completion_list_break_on (char *text, char *word,
 
   /* Add fields from the file's types; symbols will be added below.  */
 
-  if (surrounding_static_block != NULL)
-    ALL_BLOCK_SYMBOLS (surrounding_static_block, iter, sym)
-      completion_list_add_fields (sym, sym_text, sym_text_len, text, word);
+  if (code == TYPE_CODE_UNDEF)
+    {
+      if (surrounding_static_block != NULL)
+       ALL_BLOCK_SYMBOLS (surrounding_static_block, iter, sym)
+         completion_list_add_fields (sym, sym_text, sym_text_len, text, word);
 
-  if (surrounding_global_block != NULL)
-      ALL_BLOCK_SYMBOLS (surrounding_global_block, iter, sym)
-       completion_list_add_fields (sym, sym_text, sym_text_len, text, word);
+      if (surrounding_global_block != NULL)
+       ALL_BLOCK_SYMBOLS (surrounding_global_block, iter, sym)
+         completion_list_add_fields (sym, sym_text, sym_text_len, text, word);
+    }
 
   /* Go through the symtabs and check the externs and statics for
      symbols which match.  */
@@ -4362,7 +4425,10 @@ default_make_symbol_completion_list_break_on (char *text, char *word,
     b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
     ALL_BLOCK_SYMBOLS (b, iter, sym)
       {
-       COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
+       if (code == TYPE_CODE_UNDEF
+           || (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN
+               && TYPE_CODE (SYMBOL_TYPE (sym)) == code))
+         COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
       }
   }
 
@@ -4372,11 +4438,17 @@ default_make_symbol_completion_list_break_on (char *text, char *word,
     b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
     ALL_BLOCK_SYMBOLS (b, iter, sym)
       {
-       COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
+       if (code == TYPE_CODE_UNDEF
+           || (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN
+               && TYPE_CODE (SYMBOL_TYPE (sym)) == code))
+         COMPLETION_LIST_ADD_SYMBOL (sym, sym_text, sym_text_len, text, word);
       }
   }
 
-  if (current_language->la_macro_expansion == macro_expansion_c)
+  /* Skip macros if we are completing a struct tag -- arguable but
+     usually what is expected.  */
+  if (current_language->la_macro_expansion == macro_expansion_c
+      && code == TYPE_CODE_UNDEF)
     {
       struct macro_scope *scope;
 
@@ -4404,9 +4476,10 @@ default_make_symbol_completion_list_break_on (char *text, char *word,
 }
 
 VEC (char_ptr) *
-default_make_symbol_completion_list (char *text, char *word)
+default_make_symbol_completion_list (char *text, char *word,
+                                    enum type_code code)
 {
-  return default_make_symbol_completion_list_break_on (text, word, "");
+  return default_make_symbol_completion_list_break_on (text, word, "", code);
 }
 
 /* Return a vector of all symbols (regardless of class) which begin by
@@ -4416,7 +4489,21 @@ default_make_symbol_completion_list (char *text, char *word)
 VEC (char_ptr) *
 make_symbol_completion_list (char *text, char *word)
 {
-  return current_language->la_make_symbol_completion_list (text, word);
+  return current_language->la_make_symbol_completion_list (text, word,
+                                                          TYPE_CODE_UNDEF);
+}
+
+/* Like make_symbol_completion_list, but only return STRUCT_DOMAIN
+   symbols whose type code is CODE.  */
+
+VEC (char_ptr) *
+make_symbol_completion_type (char *text, char *word, enum type_code code)
+{
+  gdb_assert (code == TYPE_CODE_UNION
+             || code == TYPE_CODE_STRUCT
+             || code == TYPE_CODE_CLASS
+             || code == TYPE_CODE_ENUM);
+  return current_language->la_make_symbol_completion_list (text, word, code);
 }
 
 /* Like make_symbol_completion_list, but suitable for use as a
This page took 0.031188 seconds and 4 git commands to generate.