daily update
[deliverable/binutils-gdb.git] / gdb / symtab.c
index 632893d2229b867496a7a40d2b37fbc8096b0417..e645567e14add7dd4844679105a9750f9d8ea925 100644 (file)
@@ -91,7 +91,8 @@ 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);
+                                        int *is_a_field_of_this,
+                                        int for_type);
 
 static
 struct symbol *lookup_symbol_aux_local (const char *name,
@@ -340,21 +341,74 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id)
   return (mangled_name);
 }
 
+/* Initialize the cplus_specific structure.  'cplus_specific' should
+   only be allocated for use with cplus symbols.  */
+
+static void
+symbol_init_cplus_specific (struct general_symbol_info *gsymbol,
+                           struct objfile *objfile)
+{
+  /* A language_specific structure should not have been previously
+     initialized.  */
+  gdb_assert (gsymbol->language_specific.cplus_specific == NULL);
+  gdb_assert (objfile != NULL);
+
+  gsymbol->language_specific.cplus_specific =
+      OBSTACK_ZALLOC (&objfile->objfile_obstack, struct cplus_specific);
+}
+
+/* Set the demangled name of GSYMBOL to NAME.  NAME must be already
+   correctly allocated.  For C++ symbols a cplus_specific struct is
+   allocated so OBJFILE must not be NULL. If this is a non C++ symbol
+   OBJFILE can be NULL.  */
+void
+symbol_set_demangled_name (struct general_symbol_info *gsymbol,
+                           char *name,
+                           struct objfile *objfile)
+{
+  if (gsymbol->language == language_cplus)
+    {
+      if (gsymbol->language_specific.cplus_specific == NULL)
+       symbol_init_cplus_specific (gsymbol, objfile);
+
+      gsymbol->language_specific.cplus_specific->demangled_name = name;
+    }
+  else
+    gsymbol->language_specific.mangled_lang.demangled_name = name;
+}
+
+/* Return the demangled name of GSYMBOL.  */
+char *
+symbol_get_demangled_name (const struct general_symbol_info *gsymbol)
+{
+  if (gsymbol->language == language_cplus)
+    {
+      if (gsymbol->language_specific.cplus_specific != NULL)
+       return gsymbol->language_specific.cplus_specific->demangled_name;
+      else
+       return NULL;
+    }
+  else
+    return gsymbol->language_specific.mangled_lang.demangled_name;
+}
+
 \f
 /* Initialize the language dependent portion of a symbol
    depending upon the language for the symbol. */
 void
-symbol_init_language_specific (struct general_symbol_info *gsymbol,
-                              enum language language)
+symbol_set_language (struct general_symbol_info *gsymbol,
+                     enum language language)
 {
   gsymbol->language = language;
-  if (gsymbol->language == language_cplus
-      || gsymbol->language == language_d
+  if (gsymbol->language == language_d
       || gsymbol->language == language_java
-      || gsymbol->language == language_objc)
+      || gsymbol->language == language_objc
+      || gsymbol->language == language_fortran)
     {
-      gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+      symbol_set_demangled_name (gsymbol, NULL, NULL);
     }
+  else if (gsymbol->language == language_cplus)
+    gsymbol->language_specific.cplus_specific = NULL;
   else
     {
       memset (&gsymbol->language_specific, 0,
@@ -465,6 +519,11 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol,
          return demangled;
        }
     }
+  /* We could support `gsymbol->language == language_fortran' here to provide
+     module namespaces also for inferiors with only minimal symbol table (ELF
+     symbols).  Just the mangling standard is not standardized across compilers
+     and there is no DW_AT_producer available for inferiors with only the ELF
+     symbols to check the mangling kind.  */
   return NULL;
 }
 
@@ -531,7 +590,7 @@ symbol_set_names (struct general_symbol_info *gsymbol,
          memcpy (gsymbol->name, linkage_name, len);
          gsymbol->name[len] = '\0';
        }
-      gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+      symbol_set_demangled_name (gsymbol, NULL, NULL);
 
       return;
     }
@@ -627,10 +686,9 @@ symbol_set_names (struct general_symbol_info *gsymbol,
 
   gsymbol->name = (*slot)->mangled + lookup_len - len;
   if ((*slot)->demangled[0] != '\0')
-    gsymbol->language_specific.cplus_specific.demangled_name
-      = (*slot)->demangled;
+    symbol_set_demangled_name (gsymbol, (*slot)->demangled, objfile);
   else
-    gsymbol->language_specific.cplus_specific.demangled_name = NULL;
+    symbol_set_demangled_name (gsymbol, NULL, objfile);
 }
 
 /* Return the source code name of a symbol.  In languages where
@@ -645,12 +703,13 @@ symbol_natural_name (const struct general_symbol_info *gsymbol)
     case language_d:
     case language_java:
     case language_objc:
-      if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
-       return gsymbol->language_specific.cplus_specific.demangled_name;
+    case language_fortran:
+      if (symbol_get_demangled_name (gsymbol) != NULL)
+       return symbol_get_demangled_name (gsymbol);
       break;
     case language_ada:
-      if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
-       return gsymbol->language_specific.cplus_specific.demangled_name;
+      if (symbol_get_demangled_name (gsymbol) != NULL)
+       return symbol_get_demangled_name (gsymbol);
       else
        return ada_decode_symbol (gsymbol);
       break;
@@ -671,12 +730,13 @@ symbol_demangled_name (const struct general_symbol_info *gsymbol)
     case language_d:
     case language_java:
     case language_objc:
-      if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
-       return gsymbol->language_specific.cplus_specific.demangled_name;
+    case language_fortran:
+      if (symbol_get_demangled_name (gsymbol) != NULL)
+       return symbol_get_demangled_name (gsymbol);
       break;
     case language_ada:
-      if (gsymbol->language_specific.cplus_specific.demangled_name != NULL)
-       return gsymbol->language_specific.cplus_specific.demangled_name;
+      if (symbol_get_demangled_name (gsymbol) != NULL)
+       return symbol_get_demangled_name (gsymbol);
       else
        return ada_decode_symbol (gsymbol);
       break;
@@ -935,6 +995,8 @@ fixup_symbol_section (struct symbol *sym, struct objfile *objfile)
    C++: if IS_A_FIELD_OF_THIS is nonzero on entry, check to see if
    NAME is a field of the current implied argument `this'.  If so set
    *IS_A_FIELD_OF_THIS to 1, otherwise set it to zero.
+   FOR_TYPE is non-zero if searching specifically for a type; zero
+   otherwise.
    BLOCK_FOUND is set to the block in which NAME is found (in the case of
    a field of `this', value_of_this sets BLOCK_FOUND to the proper value.) */
 
@@ -948,10 +1010,10 @@ fixup_symbol_section (struct symbol *sym, struct objfile *objfile)
    variable and thus can probably assume it will never hit the C++
    code).  */
 
-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)
+static struct symbol *
+lookup_symbol_in_language_full (const char *name, const struct block *block,
+                               const domain_enum domain, enum language lang,
+                               int *is_a_field_of_this, int for_type)
 {
   char *demangled_name = NULL;
   const char *modified_name = NULL;
@@ -1016,12 +1078,41 @@ lookup_symbol_in_language (const char *name, const struct block *block,
     }
 
   returnval = lookup_symbol_aux (modified_name, block, domain, lang,
-                                is_a_field_of_this);
+                                is_a_field_of_this, for_type);
   do_cleanups (cleanup);
 
   return returnval;
 }
 
+/* Find the definition for a specified symbol name NAME
+   in domain DOMAIN, visible from lexical block BLOCK.
+   Returns the struct symbol pointer, or zero if no symbol is found.
+   C++: if IS_A_FIELD_OF_THIS is nonzero on entry, check to see if
+   NAME is a field of the current implied argument `this'.  If so set
+   *IS_A_FIELD_OF_THIS to 1, otherwise set it to zero.
+   BLOCK_FOUND is set to the block in which NAME is found (in the case of
+   a field of `this', value_of_this sets BLOCK_FOUND to the proper value.) */
+
+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)
+{
+  return lookup_symbol_in_language_full (name, block, domain, lang,
+                                        is_a_field_of_this, 0);
+}
+
+/* Like lookup_symbol_in_language, but search specifically for a
+   type.  */
+
+struct symbol *
+lookup_type_symbol (const char *name, const struct block *block,
+                   const domain_enum domain, enum language lang)
+{
+  return lookup_symbol_in_language_full (name, block, domain, lang,
+                                        NULL, 1);
+}
+
 /* Behave like lookup_symbol_in_language, but performed with the
    current language.  */
 
@@ -1042,11 +1133,11 @@ lookup_symbol (const char *name, const struct block *block,
 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)
+                  int *is_a_field_of_this,
+                  int for_type)
 {
   struct symbol *sym;
   const struct language_defn *langdef;
-  struct objfile *objfile;
 
   /* 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
@@ -1107,17 +1198,34 @@ lookup_symbol_aux (const char *name, const struct block *block,
     }
 
   /* Now do whatever is appropriate for LANGUAGE to look
-     up static and global variables.  */
+     up static and global variables.  If we are searching for a type,
+     we bypass this lookup, because types aren't global.  */
 
-  sym = langdef->la_lookup_symbol_nonlocal (name, block, domain);
-  if (sym != NULL)
-    return sym;
+  if (!for_type)
+    {
+      sym = langdef->la_lookup_symbol_nonlocal (name, block, domain);
+      if (sym != NULL)
+       return sym;
+    }
 
-  /* Now search all static file-level symbols.  Not strictly correct,
-     but more useful than an error.  Do the symtabs first, then check
-     the psymtabs.  If a psymtab indicates the existence of the
-     desired name as a file-level static, then do psymtab-to-symtab
-     conversion on the fly and return the found symbol. */
+  /* Now search all static file-level symbols.  When searching for a
+     type, this is what we generally want, because types are put into
+     the file scope.  For other objects, not strictly correct, but
+     more useful than an error.  */
+
+  return lookup_static_symbol_aux (name, domain);
+}
+
+/* Search all static file-level symbols for NAME from DOMAIN.  Do the symtabs
+   first, then check the psymtabs.  If a psymtab indicates the existence of the
+   desired name as a file-level static, then do psymtab-to-symtab conversion on
+   the fly and return the found symbol. */
+
+struct symbol *
+lookup_static_symbol_aux (const char *name, const domain_enum domain)
+{
+  struct objfile *objfile;
+  struct symbol *sym;
 
   sym = lookup_symbol_aux_symtabs (STATIC_BLOCK, name, domain);
   if (sym != NULL)
@@ -1156,14 +1264,10 @@ lookup_symbol_aux_local (const char *name, const struct block *block,
       if (sym != NULL)
        return sym;
 
-      if (language == language_cplus)
+      if (language == language_cplus || language == language_fortran)
         {
-          sym = cp_lookup_symbol_imports (scope,
-                                          name,
-                                          block,
-                                          domain,
-                                          1,
-                                          1);
+          sym = cp_lookup_symbol_imports_or_template (scope, name, block,
+                                                     domain);
           if (sym != NULL)
             return sym;
         }
@@ -1262,6 +1366,35 @@ lookup_global_symbol_from_objfile (const struct objfile *main_objfile,
   return NULL;
 }
 
+/* A helper for lookup_symbol_aux_symtabs that is passed as a callback
+   to the expand_one_symtab_matching quick function.  */
+
+static struct symbol *
+match_symbol_aux (struct symtab *symtab,
+                 int kind, const char *name, domain_enum domain,
+                 void *arg)
+{
+  struct objfile *objfile = arg;
+
+  if (symtab->primary)
+    {
+      struct symbol *sym;
+      struct blockvector *bv;
+      const struct block *block;
+
+      bv = BLOCKVECTOR (symtab);
+      block = BLOCKVECTOR_BLOCK (bv, kind);
+      sym = lookup_block_symbol (block, name, domain);
+      if (sym)
+       {
+         block_found = block;
+         return fixup_symbol_section (sym, objfile);
+       }
+    }
+
+  return NULL;
+}
+
 /* Check to see if the symbol is defined in one of the symtabs.
    BLOCK_INDEX should be either GLOBAL_BLOCK or STATIC_BLOCK,
    depending on whether or not we want to search global symbols or
@@ -1277,15 +1410,30 @@ lookup_symbol_aux_symtabs (int block_index, const char *name,
   const struct block *block;
   struct symtab *s;
 
-  ALL_PRIMARY_SYMTABS (objfile, s)
+  ALL_OBJFILES (objfile)
   {
-    bv = BLOCKVECTOR (s);
-    block = BLOCKVECTOR_BLOCK (bv, block_index);
-    sym = lookup_block_symbol (block, name, domain);
-    if (sym)
+    ALL_OBJFILE_SYMTABS (objfile, s)
+      if (s->primary)
+       {
+         bv = BLOCKVECTOR (s);
+         block = BLOCKVECTOR_BLOCK (bv, block_index);
+         sym = lookup_block_symbol (block, name, domain);
+         if (sym)
+           {
+             block_found = block;
+             return fixup_symbol_section (sym, objfile);
+           }
+       }
+
+    if (objfile->sf)
       {
-       block_found = block;
-       return fixup_symbol_section (sym, objfile);
+       sym = objfile->sf->qf->expand_one_symtab_matching (objfile,
+                                                          block_index,
+                                                          name, domain,
+                                                          match_symbol_aux,
+                                                          objfile);
+       if (sym)
+         return sym;
       }
   }
 
@@ -1508,6 +1656,30 @@ basic_lookup_transparent_type_quick (struct objfile *objfile, int kind,
   return NULL;
 }
 
+/* A helper function for basic_lookup_transparent_type that is passed
+   to the expand_one_symtab_matching quick function.  */
+
+static struct symbol *
+match_transparent_type (struct symtab *symtab,
+                       int kind, const char *name, domain_enum domain,
+                       void *data)
+{
+  if (symtab->primary)
+    {
+      struct blockvector *bv;
+      struct block *block;
+      struct symbol *sym;
+
+      bv = BLOCKVECTOR (symtab);
+      block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+      sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
+      if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+       return sym;
+    }
+
+  return NULL;
+}
+
 /* The standard implementation of lookup_transparent_type.  This code
    was modeled on lookup_symbol -- the parts not relevant to looking
    up types were just left out.  In particular it's assumed here that
@@ -1529,14 +1701,30 @@ basic_lookup_transparent_type (const char *name)
      of the desired name as a global, then do psymtab-to-symtab
      conversion on the fly and return the found symbol.  */
 
-  ALL_PRIMARY_SYMTABS (objfile, s)
+  ALL_OBJFILES (objfile)
   {
-    bv = BLOCKVECTOR (s);
-    block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-    sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
-    if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+    ALL_OBJFILE_SYMTABS (objfile, s)
+      if (s->primary)
+       {
+         bv = BLOCKVECTOR (s);
+         block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+         sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
+         if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+           {
+             return SYMBOL_TYPE (sym);
+           }
+       }
+
+    if (objfile->sf)
       {
-       return SYMBOL_TYPE (sym);
+       sym
+         = objfile->sf->qf->expand_one_symtab_matching (objfile,
+                                                        GLOBAL_BLOCK, name,
+                                                        STRUCT_DOMAIN,
+                                                        match_transparent_type,
+                                                        NULL);
+       if (sym)
+         return SYMBOL_TYPE (sym);
       }
   }
 
@@ -1555,14 +1743,29 @@ basic_lookup_transparent_type (const char *name)
      conversion on the fly and return the found symbol.
    */
 
-  ALL_PRIMARY_SYMTABS (objfile, s)
+  ALL_OBJFILES (objfile)
   {
-    bv = BLOCKVECTOR (s);
-    block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-    sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
-    if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+    ALL_OBJFILE_SYMTABS (objfile, s)
+      {
+       bv = BLOCKVECTOR (s);
+       block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
+       sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
+       if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+         {
+           return SYMBOL_TYPE (sym);
+         }
+      }
+
+    if (objfile->sf)
       {
-       return SYMBOL_TYPE (sym);
+       sym
+         = objfile->sf->qf->expand_one_symtab_matching (objfile,
+                                                        STATIC_BLOCK, name,
+                                                        STRUCT_DOMAIN,
+                                                        match_transparent_type,
+                                                        NULL);
+       if (sym)
+         return SYMBOL_TYPE (sym);
       }
   }
 
@@ -1581,14 +1784,16 @@ basic_lookup_transparent_type (const char *name)
 /* FIXME:  What about languages without main() or specially linked
    executables that have no main() ? */
 
-char *
+const char *
 find_main_filename (void)
 {
   struct objfile *objfile;
-  char *result, *name = main_name ();
+  char *name = main_name ();
 
   ALL_OBJFILES (objfile)
   {
+    const char *result;
+
     if (!objfile->sf)
       continue;
     result = objfile->sf->qf->find_symbol_file (objfile, name);
@@ -2889,13 +3094,13 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
   struct minimal_symbol *msymbol;
   char *val;
   int found_misc = 0;
-  static enum minimal_symbol_type types[]
+  static const enum minimal_symbol_type types[]
     = {mst_data, mst_text, mst_abs, mst_unknown};
-  static enum minimal_symbol_type types2[]
+  static const enum minimal_symbol_type types2[]
     = {mst_bss, mst_file_text, mst_abs, mst_unknown};
-  static enum minimal_symbol_type types3[]
+  static const enum minimal_symbol_type types3[]
     = {mst_file_data, mst_solib_trampoline, mst_abs, mst_unknown};
-  static enum minimal_symbol_type types4[]
+  static const enum minimal_symbol_type types4[]
     = {mst_file_bss, mst_text, mst_abs, mst_unknown};
   enum minimal_symbol_type ourtype;
   enum minimal_symbol_type ourtype2;
@@ -3039,10 +3244,15 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[],
              if (file_matches (real_symtab->filename, files, nfiles)
                  && ((regexp == NULL
                       || re_exec (SYMBOL_NATURAL_NAME (sym)) != 0)
-                     && ((kind == VARIABLES_DOMAIN && SYMBOL_CLASS (sym) != LOC_TYPEDEF
+                     && ((kind == VARIABLES_DOMAIN
+                          && SYMBOL_CLASS (sym) != LOC_TYPEDEF
                           && SYMBOL_CLASS (sym) != LOC_UNRESOLVED
                           && SYMBOL_CLASS (sym) != LOC_BLOCK
-                          && SYMBOL_CLASS (sym) != LOC_CONST)
+                          /* LOC_CONST can be used for more than just enums,
+                             e.g., c++ static const members.
+                             We only want to skip enums here.  */
+                          && !(SYMBOL_CLASS (sym) == LOC_CONST
+                               && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_ENUM))
                          || (kind == FUNCTIONS_DOMAIN && SYMBOL_CLASS (sym) == LOC_BLOCK)
                          || (kind == TYPES_DOMAIN && SYMBOL_CLASS (sym) == LOC_TYPEDEF))))
                {
@@ -3196,7 +3406,8 @@ print_msymbol_info (struct minimal_symbol *msymbol)
 static void
 symtab_symbol_info (char *regexp, domain_enum kind, int from_tty)
 {
-  static char *classnames[] = {"variable", "function", "type", "method"};
+  static const char * const classnames[] =
+    {"variable", "function", "type", "method"};
   struct symbol_search *symbols;
   struct symbol_search *p;
   struct cleanup *old_chain;
@@ -3582,7 +3793,8 @@ add_partial_symbol_name (const char *name, void *user_data)
 }
 
 char **
-default_make_symbol_completion_list (char *text, char *word)
+default_make_symbol_completion_list_break_on (char *text, char *word,
+                                             const char *break_on)
 {
   /* Problem: All of the symbols have to be copied because readline
      frees them.  I'm not going to worry about this; hopefully there
@@ -3645,7 +3857,7 @@ default_make_symbol_completion_list (char *text, char *word)
        while (p > text)
          {
            if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0'
-               || p[-1] == ':')
+               || p[-1] == ':' || strchr (break_on, p[-1]) != NULL)
              --p;
            else
              break;
@@ -3771,6 +3983,12 @@ default_make_symbol_completion_list (char *text, char *word)
   return (return_val);
 }
 
+char **
+default_make_symbol_completion_list (char *text, char *word)
+{
+  return default_make_symbol_completion_list_break_on (text, word, "");
+}
+
 /* Return a NULL terminated array of all symbols (regardless of class)
    which begin by matching TEXT.  If the answer is no symbols, then
    the return value is an array which contains only a NULL pointer.  */
@@ -3967,7 +4185,7 @@ struct add_partial_filename_data
 
 /* A callback for map_partial_symbol_filenames.  */
 static void
-maybe_add_partial_symtab_filename (const char *fullname, const char *filename,
+maybe_add_partial_symtab_filename (const char *filename, const char *fullname,
                                   void *user_data)
 {
   struct add_partial_filename_data *data = user_data;
This page took 0.031782 seconds and 4 git commands to generate.