gdb/
[deliverable/binutils-gdb.git] / gdb / symtab.c
index d116e57663688dd0b780861e031e2177539a2b50..a39e5bf458fbb02596c63013388a0f143737d118 100644 (file)
@@ -27,7 +27,6 @@
 #include "symfile.h"
 #include "objfiles.h"
 #include "gdbcmd.h"
-#include "call-cmds.h"
 #include "gdb_regex.h"
 #include "expression.h"
 #include "language.h"
@@ -62,6 +61,7 @@
 #include "macroscope.h"
 
 #include "psymtab.h"
+#include "parser-defs.h"
 
 /* Prototypes for local functions */
 
@@ -81,7 +81,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,
@@ -146,15 +146,14 @@ const struct block *block_found;
 
 /* See whether FILENAME matches SEARCH_NAME using the rule that we
    advertise to the user.  (The manual's description of linespecs
-   describes what we advertise).  SEARCH_LEN is the length of
-   SEARCH_NAME.  We assume that SEARCH_NAME is a relative path.
-   Returns true if they match, false otherwise.  */
+   describes what we advertise).  We assume that SEARCH_NAME is
+   a relative path.  Returns true if they match, false otherwise.  */
 
 int
-compare_filenames_for_search (const char *filename, const char *search_name,
-                             int search_len)
+compare_filenames_for_search (const char *filename, const char *search_name)
 {
   int len = strlen (filename);
+  size_t search_len = strlen (search_name);
 
   if (len < search_len)
     return 0;
@@ -195,7 +194,6 @@ iterate_over_some_symtabs (const char *name,
 {
   struct symtab *s = NULL;
   const char* base_name = lbasename (name);
-  int name_len = strlen (name);
   int is_abs = IS_ABSOLUTE_PATH (name);
 
   for (s = first; s != NULL && s != after_last; s = s->next)
@@ -207,7 +205,7 @@ iterate_over_some_symtabs (const char *name,
            return 1;
        }
 
-      if (!is_abs && compare_filenames_for_search (s->filename, name, name_len))
+      if (!is_abs && compare_filenames_for_search (s->filename, name))
        {
          if (callback (s, data))
            return 1;
@@ -226,14 +224,13 @@ iterate_over_some_symtabs (const char *name,
       {
         const char *fp = symtab_to_fullname (s);
 
-        if (fp != NULL && FILENAME_CMP (full_path, fp) == 0)
+        if (FILENAME_CMP (full_path, fp) == 0)
           {
            if (callback (s, data))
              return 1;
           }
 
-       if (fp != NULL && !is_abs && compare_filenames_for_search (fp, name,
-                                                                  name_len))
+       if (!is_abs && compare_filenames_for_search (fp, name))
          {
            if (callback (s, data))
              return 1;
@@ -242,25 +239,21 @@ iterate_over_some_symtabs (const char *name,
 
     if (real_path != NULL)
       {
-        char *fullname = symtab_to_fullname (s);
+        const char *fullname = symtab_to_fullname (s);
+       char *rp = gdb_realpath (fullname);
 
-        if (fullname != NULL)
-          {
-            char *rp = gdb_realpath (fullname);
-
-            make_cleanup (xfree, rp);
-            if (FILENAME_CMP (real_path, rp) == 0)
-             {
-               if (callback (s, data))
-                 return 1;
-             }
+       make_cleanup (xfree, rp);
+       if (FILENAME_CMP (real_path, rp) == 0)
+         {
+           if (callback (s, data))
+             return 1;
+         }
 
-           if (!is_abs && compare_filenames_for_search (rp, name, name_len))
-             {
-               if (callback (s, data))
-                 return 1;
-             }
-          }
+       if (!is_abs && compare_filenames_for_search (rp, name))
+         {
+           if (callback (s, data))
+             return 1;
+         }
       }
     }
 
@@ -402,19 +395,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 +1217,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 +1235,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 +1271,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.  */
@@ -1307,7 +1346,10 @@ lookup_symbol_aux (const char *name, const struct block *block,
 
   langdef = language_def (language);
 
-  if (is_a_field_of_this != NULL)
+  /* Don't do this check if we are searching for a struct.  It will
+     not be found by check_field, but will be found by other
+     means.  */
+  if (is_a_field_of_this != NULL && domain != STRUCT_DOMAIN)
     {
       struct symbol *sym = lookup_language_this (langdef, block);
 
@@ -1327,11 +1369,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;
        }
     }
 
@@ -1767,7 +1806,7 @@ lookup_symbol_global (const char *name,
   lookup_data.name = name;
   lookup_data.domain = domain;
   gdbarch_iterate_over_objfiles_in_search_order
-    (objfile != NULL ? get_objfile_arch (objfile) : target_gdbarch,
+    (objfile != NULL ? get_objfile_arch (objfile) : target_gdbarch (),
      lookup_symbol_global_iterator_cb, &lookup_data, objfile);
 
   return lookup_data.result;
@@ -2148,6 +2187,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;
@@ -2506,9 +2547,6 @@ find_line_symtab (struct symtab *symtab, int line,
                                                         symtab->filename);
       }
 
-      /* Get symbol full file name if possible.  */
-      symtab_to_fullname (symtab);
-
       ALL_SYMTABS (objfile, s)
       {
        struct linetable *l;
@@ -2516,9 +2554,7 @@ find_line_symtab (struct symtab *symtab, int line,
 
        if (FILENAME_CMP (symtab->filename, s->filename) != 0)
          continue;
-       if (symtab->fullname != NULL
-           && symtab_to_fullname (s) != NULL
-           && FILENAME_CMP (symtab->fullname, s->fullname) != 0)
+       if (FILENAME_CMP (symtab->fullname, symtab_to_fullname (s)) != 0)
          continue;     
        l = LINETABLE (s);
        ind = find_line_common (l, line, &exact, 0);
@@ -2810,7 +2846,7 @@ skip_prologue_sal (struct symtab_and_line *sal)
   struct block *b, *function_block;
   int force_skip, skip;
 
-  /* Do not change the SAL is PC was specified explicitly.  */
+  /* Do not change the SAL if PC was specified explicitly.  */
   if (sal->explicit_pc)
     return;
 
@@ -3108,14 +3144,9 @@ operator_chars (char *p, char **end)
 struct filename_seen_cache
 {
   /* Table of files seen so far.  */
-  const char **tab;
-
-  /* Allocated size of tab in elements.  */
-  int tab_alloc_size;
+  htab_t tab;
+  /* Initial size of the table.  It automagically grows from here.  */
 #define INITIAL_FILENAME_SEEN_CACHE_SIZE 100
-
-  /* Current size of tab in elements.  */
-  int tab_cur_size;
 };
 
 /* filename_seen_cache constructor.  */
@@ -3126,9 +3157,9 @@ create_filename_seen_cache (void)
   struct filename_seen_cache *cache;
 
   cache = XNEW (struct filename_seen_cache);
-  cache->tab_alloc_size = INITIAL_FILENAME_SEEN_CACHE_SIZE;
-  cache->tab = XNEWVEC (const char *, cache->tab_alloc_size);
-  cache->tab_cur_size = 0;
+  cache->tab = htab_create_alloc (INITIAL_FILENAME_SEEN_CACHE_SIZE,
+                                 filename_hash, filename_eq,
+                                 NULL, xcalloc, xfree);
 
   return cache;
 }
@@ -3136,9 +3167,9 @@ create_filename_seen_cache (void)
 /* Empty the cache, but do not delete it.  */
 
 static void
-clear_filename_seen_cache (struct filename_seen_cache * cache)
+clear_filename_seen_cache (struct filename_seen_cache *cache)
 {
-  cache->tab_cur_size = 0;
+  htab_empty (cache->tab);
 }
 
 /* filename_seen_cache destructor.
@@ -3149,35 +3180,30 @@ delete_filename_seen_cache (void *ptr)
 {
   struct filename_seen_cache *cache = ptr;
 
-  xfree (cache->tab);
+  htab_delete (cache->tab);
   xfree (cache);
 }
 
 /* If FILE is not already in the table of files in CACHE, return zero;
    otherwise return non-zero.  Optionally add FILE to the table if ADD
-   is non-zero.  */
+   is non-zero.
+
+   NOTE: We don't manage space for FILE, we assume FILE lives as long
+   as the caller needs.  */
 
 static int
 filename_seen (struct filename_seen_cache *cache, const char *file, int add)
 {
-  const char **p;
+  void **slot;
 
   /* Is FILE in tab?  */
-  for (p = cache->tab; p < cache->tab + cache->tab_cur_size; p++)
-    if (filename_cmp (*p, file) == 0)
-      return 1;
+  slot = htab_find_slot (cache->tab, file, add ? INSERT : NO_INSERT);
+  if (*slot != NULL)
+    return 1;
 
   /* No; maybe add it to tab.  */
   if (add)
-    {
-      if (cache->tab_cur_size == cache->tab_alloc_size)
-       {
-         cache->tab_alloc_size *= 2;
-         cache->tab = XRESIZEVEC (const char *, cache->tab,
-                                  cache->tab_alloc_size);
-       }
-      cache->tab[cache->tab_cur_size++] = file;
-    }
+    *slot = (char *) file;
 
   return 0;
 }
@@ -3259,7 +3285,7 @@ sources_info (char *ignore, int from_tty)
   {
     const char *fullname = symtab_to_fullname (s);
 
-    output_source_filename (fullname ? fullname : s->filename, &data);
+    output_source_filename (fullname, &data);
   }
   printf_filtered ("\n\n");
 
@@ -3787,10 +3813,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)
     {
@@ -3800,7 +3827,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);
@@ -4209,7 +4236,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
@@ -4316,13 +4344,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
@@ -4339,10 +4372,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
@@ -4355,13 +4395,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.  */
@@ -4372,7 +4415,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);
       }
   }
 
@@ -4382,11 +4428,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;
 
@@ -4414,9 +4466,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
@@ -4426,7 +4479,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.032635 seconds and 4 git commands to generate.