* config/tc-xtensa.c (xg_assembly_relax): Increment steps_taken for
[deliverable/binutils-gdb.git] / gdb / cp-support.c
index 64b3f89ab53509b462486898d60be56b3d349200..ba4e891e19c9eab1c36548d3e536cd2aa4bd62c6 100644 (file)
@@ -1,5 +1,5 @@
 /* Helper routines for C++ support in GDB.
-   Copyright 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
 
    Contributed by MontaVista Software.
 
@@ -17,8 +17,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
 #include <ctype.h>
 #include "frame.h"
 #include "symtab.h"
 #include "block.h"
+#include "complaints.h"
+#include "gdbtypes.h"
+
+#define d_left(dc) (dc)->u.s_binary.left
+#define d_right(dc) (dc)->u.s_binary.right
+
+/* Functions related to demangled name parsing.  */
+
+static unsigned int cp_find_first_component_aux (const char *name,
+                                                int permissive);
+
+static void demangled_name_complaint (const char *name);
 
 /* Functions/variables related to overload resolution.  */
 
@@ -39,116 +51,239 @@ static int sym_return_val_size;
 static int sym_return_val_index;
 static struct symbol **sym_return_val;
 
-static char *remove_params (const char *demangled_name);
+static void overload_list_add_symbol (struct symbol *sym,
+                                     const char *oload_name);
 
-static void overload_list_add_symbol (struct symbol *sym, char *oload_name);
+static void make_symbol_overload_list_using (const char *func_name,
+                                            const char *namespace);
+
+static void make_symbol_overload_list_qualified (const char *func_name);
+
+static void read_in_psymtabs (const char *oload_name);
 
 /* The list of "maint cplus" commands.  */
 
-static struct cmd_list_element *maint_cplus_cmd_list = NULL;
+struct cmd_list_element *maint_cplus_cmd_list = NULL;
 
 /* The actual commands.  */
 
 static void maint_cplus_command (char *arg, int from_tty);
 static void first_component_command (char *arg, int from_tty);
 
-/* Here are some random pieces of trivia to keep in mind while trying
-   to take apart demangled names:
+/* Return the canonicalized form of STRING, or NULL if STRING can not be
+   parsed.  The return value is allocated via xmalloc.
 
-   - Names can contain function arguments or templates, so the process
-     has to be, to some extent recursive: maybe keep track of your
-     depth based on encountering <> and ().
+   drow/2005-03-07: Should we also return NULL for things that trivially do
+   not require any change?  e.g. simple identifiers.  This could be more
+   efficient.  */
 
-   - Parentheses don't just have to happen at the end of a name: they
-     can occur even if the name in question isn't a function, because
-     a template argument might be a type that's a function.
+char *
+cp_canonicalize_string (const char *string)
+{
+  void *storage;
+  struct demangle_component *ret_comp;
+  char *ret;
+  int len = strlen (string);
 
-   - Conversely, even if you're trying to deal with a function, its
-     demangled name might not end with ')': it could be a const or
-     volatile class method, in which case it ends with "const" or
-     "volatile".
+  len = len + len / 8;
 
-   - Parentheses are also used in anonymous namespaces: a variable
-     'foo' in an anonymous namespace gets demangled as "(anonymous
-     namespace)::foo".
+  ret_comp = cp_demangled_name_to_comp (string, &storage, NULL);
+  if (ret_comp == NULL)
+    return NULL;
 
-   - And operator names can contain parentheses or angle brackets.  */
+  ret = cp_comp_to_string (ret_comp, len);
 
-/* FIXME: carlton/2003-03-13: We have several functions here with
-   overlapping functionality; can we combine them?  Also, do they
-   handle all the above considerations correctly?  */
+  xfree (storage);
 
-/* Find the last component of the demangled C++ name NAME.  NAME
-   must be a method name including arguments, in order to correctly
-   locate the last component.
+  return ret;
+}
 
-   This function return a pointer to the first colon before the
-   last component, or NULL if the name had only one component.  */
+/* Convert a mangled name to a demangle_component tree.  *MEMORY is set to the
+   block of used memory that should be freed when finished with the tree. 
+   DEMANGLED_P is set to the char * that should be freed when finished with
+   the tree, or NULL if none was needed.  OPTIONS will be passed to the
+   demangler.  */
 
-static const char *
-find_last_component (const char *name)
+static struct demangle_component *
+mangled_name_to_comp (const char *mangled_name, int options,
+                     void **memory, char **demangled_p)
 {
-  const char *p;
-  int depth;
+  struct demangle_component *ret;
+  char *demangled_name;
+  int len;
 
-  /* Functions can have local classes, so we need to find the
-     beginning of the last argument list, not the end of the first
-     one.  */
-  p = name + strlen (name) - 1;
-  while (p > name && *p != ')')
-    p--;
+  /* If it looks like a v3 mangled name, then try to go directly
+     to trees.  */
+  if (mangled_name[0] == '_' && mangled_name[1] == 'Z')
+    {
+      ret = cplus_demangle_v3_components (mangled_name, options, memory);
+      if (ret)
+       {
+         *demangled_p = NULL;
+         return ret;
+       }
+    }
 
-  if (p == name)
-    return NULL;
+  /* If it doesn't, or if that failed, then try to demangle the name.  */
+  demangled_name = cplus_demangle (mangled_name, options);
+  if (demangled_name == NULL)
+   return NULL;
+  
+  /* If we could demangle the name, parse it to build the component tree.  */
+  ret = cp_demangled_name_to_comp (demangled_name, memory, NULL);
 
-  /* P now points at the `)' at the end of the argument list.  Walk
-     back to the beginning.  */
-  p--;
-  depth = 1;
-  while (p > name && depth > 0)
+  if (ret == NULL)
     {
-      if (*p == '<' || *p == '(')
-       depth--;
-      else if (*p == '>' || *p == ')')
-       depth++;
-      p--;
+      free (demangled_name);
+      return NULL;
     }
 
-  if (p == name)
-    return NULL;
+  *demangled_p = demangled_name;
+  return ret;
+}
 
-  while (p > name && *p != ':')
-    p--;
+/* Return the name of the class containing method PHYSNAME.  */
 
-  if (p == name || p == name + 1 || p[-1] != ':')
+char *
+cp_class_name_from_physname (const char *physname)
+{
+  void *storage;
+  char *demangled_name = NULL, *ret;
+  struct demangle_component *ret_comp, *prev_comp, *cur_comp;
+  int done;
+
+  ret_comp = mangled_name_to_comp (physname, DMGL_ANSI, &storage,
+                                  &demangled_name);
+  if (ret_comp == NULL)
     return NULL;
 
-  return p - 1;
+  done = 0;
+
+  /* First strip off any qualifiers, if we have a function or method.  */
+  while (!done)
+    switch (ret_comp->type)
+      {
+      case DEMANGLE_COMPONENT_CONST:
+      case DEMANGLE_COMPONENT_RESTRICT:
+      case DEMANGLE_COMPONENT_VOLATILE:
+      case DEMANGLE_COMPONENT_CONST_THIS:
+      case DEMANGLE_COMPONENT_RESTRICT_THIS:
+      case DEMANGLE_COMPONENT_VOLATILE_THIS:
+      case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
+        ret_comp = d_left (ret_comp);
+        break;
+      default:
+       done = 1;
+       break;
+      }
+
+  /* If what we have now is a function, discard the argument list.  */
+  if (ret_comp->type == DEMANGLE_COMPONENT_TYPED_NAME)
+    ret_comp = d_left (ret_comp);
+
+  /* If what we have now is a template, strip off the template
+     arguments.  The left subtree may be a qualified name.  */
+  if (ret_comp->type == DEMANGLE_COMPONENT_TEMPLATE)
+    ret_comp = d_left (ret_comp);
+
+  /* What we have now should be a name, possibly qualified.  Additional
+     qualifiers could live in the left subtree or the right subtree.  Find
+     the last piece.  */
+  done = 0;
+  prev_comp = NULL;
+  cur_comp = ret_comp;
+  while (!done)
+    switch (cur_comp->type)
+      {
+      case DEMANGLE_COMPONENT_QUAL_NAME:
+      case DEMANGLE_COMPONENT_LOCAL_NAME:
+       prev_comp = cur_comp;
+        cur_comp = d_right (cur_comp);
+        break;
+      case DEMANGLE_COMPONENT_TEMPLATE:
+      case DEMANGLE_COMPONENT_NAME:
+      case DEMANGLE_COMPONENT_CTOR:
+      case DEMANGLE_COMPONENT_DTOR:
+      case DEMANGLE_COMPONENT_OPERATOR:
+      case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
+       done = 1;
+       break;
+      default:
+       done = 1;
+       cur_comp = NULL;
+       break;
+      }
+
+  ret = NULL;
+  if (cur_comp != NULL && prev_comp != NULL)
+    {
+      /* We want to discard the rightmost child of PREV_COMP.  */
+      *prev_comp = *d_left (prev_comp);
+      /* The ten is completely arbitrary; we don't have a good estimate.  */
+      ret = cp_comp_to_string (ret_comp, 10);
+    }
+
+  xfree (storage);
+  if (demangled_name)
+    xfree (demangled_name);
+  return ret;
 }
 
-/* Return the name of the class containing method PHYSNAME.  */
+/* Return the child of COMP which is the basename of a method, variable,
+   et cetera.  All scope qualifiers are discarded, but template arguments
+   will be included.  The component tree may be modified.  */
 
-char *
-class_name_from_physname (const char *physname)
+static struct demangle_component *
+unqualified_name_from_comp (struct demangle_component *comp)
 {
-  char *ret = NULL;
-  const char *end;
-  int depth = 0;
-  char *demangled_name = cplus_demangle (physname, DMGL_ANSI);
+  struct demangle_component *ret_comp = comp, *last_template;
+  int done;
 
-  if (demangled_name == NULL)
-    return NULL;
+  done = 0;
+  last_template = NULL;
+  while (!done)
+    switch (ret_comp->type)
+      {
+      case DEMANGLE_COMPONENT_QUAL_NAME:
+      case DEMANGLE_COMPONENT_LOCAL_NAME:
+        ret_comp = d_right (ret_comp);
+        break;
+      case DEMANGLE_COMPONENT_TYPED_NAME:
+        ret_comp = d_left (ret_comp);
+        break;
+      case DEMANGLE_COMPONENT_TEMPLATE:
+       gdb_assert (last_template == NULL);
+       last_template = ret_comp;
+       ret_comp = d_left (ret_comp);
+       break;
+      case DEMANGLE_COMPONENT_CONST:
+      case DEMANGLE_COMPONENT_RESTRICT:
+      case DEMANGLE_COMPONENT_VOLATILE:
+      case DEMANGLE_COMPONENT_CONST_THIS:
+      case DEMANGLE_COMPONENT_RESTRICT_THIS:
+      case DEMANGLE_COMPONENT_VOLATILE_THIS:
+      case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
+        ret_comp = d_left (ret_comp);
+        break;
+      case DEMANGLE_COMPONENT_NAME:
+      case DEMANGLE_COMPONENT_CTOR:
+      case DEMANGLE_COMPONENT_DTOR:
+      case DEMANGLE_COMPONENT_OPERATOR:
+      case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
+       done = 1;
+       break;
+      default:
+       return NULL;
+       break;
+      }
 
-  end = find_last_component (demangled_name);
-  if (end != NULL)
+  if (last_template)
     {
-      ret = xmalloc (end - demangled_name + 1);
-      memcpy (ret, demangled_name, end - demangled_name);
-      ret[end - demangled_name] = '\0';
+      d_left (last_template) = ret_comp;
+      return last_template;
     }
 
-  xfree (demangled_name);
-  return ret;
+  return ret_comp;
 }
 
 /* Return the name of the method whose linkage name is PHYSNAME.  */
@@ -156,64 +291,161 @@ class_name_from_physname (const char *physname)
 char *
 method_name_from_physname (const char *physname)
 {
+  void *storage;
+  char *demangled_name = NULL, *ret;
+  struct demangle_component *ret_comp;
+  int done;
+
+  ret_comp = mangled_name_to_comp (physname, DMGL_ANSI, &storage,
+                                  &demangled_name);
+  if (ret_comp == NULL)
+    return NULL;
+
+  ret_comp = unqualified_name_from_comp (ret_comp);
+
+  ret = NULL;
+  if (ret_comp != NULL)
+    /* The ten is completely arbitrary; we don't have a good estimate.  */
+    ret = cp_comp_to_string (ret_comp, 10);
+
+  xfree (storage);
+  if (demangled_name)
+    xfree (demangled_name);
+  return ret;
+}
+
+/* If FULL_NAME is the demangled name of a C++ function (including an
+   arg list, possibly including namespace/class qualifications),
+   return a new string containing only the function name (without the
+   arg list/class qualifications).  Otherwise, return NULL.  The
+   caller is responsible for freeing the memory in question.  */
+
+char *
+cp_func_name (const char *full_name)
+{
+  void *storage;
+  char *ret;
+  struct demangle_component *ret_comp;
+  int done;
+
+  ret_comp = cp_demangled_name_to_comp (full_name, &storage, NULL);
+  if (!ret_comp)
+    return NULL;
+
+  ret_comp = unqualified_name_from_comp (ret_comp);
+
+  ret = NULL;
+  if (ret_comp != NULL)
+    ret = cp_comp_to_string (ret_comp, 10);
+
+  xfree (storage);
+  return ret;
+}
+
+/* DEMANGLED_NAME is the name of a function, including parameters and
+   (optionally) a return type.  Return the name of the function without
+   parameters or return type, or NULL if we can not parse the name.  */
+
+static char *
+remove_params (const char *demangled_name)
+{
+  int done = 0;
+  struct demangle_component *ret_comp;
+  void *storage;
   char *ret = NULL;
-  const char *end;
-  int depth = 0;
-  char *demangled_name = cplus_demangle (physname, DMGL_ANSI);
 
   if (demangled_name == NULL)
     return NULL;
 
-  end = find_last_component (demangled_name);
-  if (end != NULL)
-    {
-      char *args;
-      int len;
+  ret_comp = cp_demangled_name_to_comp (demangled_name, &storage, NULL);
+  if (ret_comp == NULL)
+    return NULL;
 
-      /* Skip "::".  */
-      end = end + 2;
+  /* First strip off any qualifiers, if we have a function or method.  */
+  while (!done)
+    switch (ret_comp->type)
+      {
+      case DEMANGLE_COMPONENT_CONST:
+      case DEMANGLE_COMPONENT_RESTRICT:
+      case DEMANGLE_COMPONENT_VOLATILE:
+      case DEMANGLE_COMPONENT_CONST_THIS:
+      case DEMANGLE_COMPONENT_RESTRICT_THIS:
+      case DEMANGLE_COMPONENT_VOLATILE_THIS:
+      case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
+        ret_comp = d_left (ret_comp);
+        break;
+      default:
+       done = 1;
+       break;
+      }
 
-      /* Find the argument list, if any.  */
-      args = strchr (end, '(');
-      if (args == NULL)
-       len = strlen (end + 2);
-      else
-       {
-         args --;
-         while (*args == ' ')
-           args --;
-         len = args - end + 1;
-       }
-      ret = xmalloc (len + 1);
-      memcpy (ret, end, len);
-      ret[len] = 0;
-    }
+  /* What we have now should be a function.  Return its name.  */
+  if (ret_comp->type == DEMANGLE_COMPONENT_TYPED_NAME)
+    ret = cp_comp_to_string (d_left (ret_comp), 10);
 
-  xfree (demangled_name);
+  xfree (storage);
   return ret;
 }
 
+/* Here are some random pieces of trivia to keep in mind while trying
+   to take apart demangled names:
+
+   - Names can contain function arguments or templates, so the process
+     has to be, to some extent recursive: maybe keep track of your
+     depth based on encountering <> and ().
+
+   - Parentheses don't just have to happen at the end of a name: they
+     can occur even if the name in question isn't a function, because
+     a template argument might be a type that's a function.
+
+   - Conversely, even if you're trying to deal with a function, its
+     demangled name might not end with ')': it could be a const or
+     volatile class method, in which case it ends with "const" or
+     "volatile".
+
+   - Parentheses are also used in anonymous namespaces: a variable
+     'foo' in an anonymous namespace gets demangled as "(anonymous
+     namespace)::foo".
+
+   - And operator names can contain parentheses or angle brackets.  */
+
+/* FIXME: carlton/2003-03-13: We have several functions here with
+   overlapping functionality; can we combine them?  Also, do they
+   handle all the above considerations correctly?  */
+
+
 /* This returns the length of first component of NAME, which should be
    the demangled name of a C++ variable/function/method/etc.
    Specifically, it returns the index of the first colon forming the
    boundary of the first component: so, given 'A::foo' or 'A::B::foo'
    it returns the 1, and given 'foo', it returns 0.  */
 
-/* Well, that's what it should do when called externally, but to make
-   the recursion easier, it also stops if it reaches an unexpected ')'
-   or '>'.  */
+/* The character in NAME indexed by the return value is guaranteed to
+   always be either ':' or '\0'.  */
 
 /* NOTE: carlton/2003-03-13: This function is currently only intended
    for internal use: it's probably not entirely safe when called on
-   user-generated input, because some of the 'index += 2' lines might
-   go past the end of malformed input.  */
+   user-generated input, because some of the 'index += 2' lines in
+   cp_find_first_component_aux might go past the end of malformed
+   input.  */
+
+unsigned int
+cp_find_first_component (const char *name)
+{
+  return cp_find_first_component_aux (name, 0);
+}
+
+/* Helper function for cp_find_first_component.  Like that function,
+   it returns the length of the first component of NAME, but to make
+   the recursion easier, it also stops if it reaches an unexpected ')'
+   or '>' if the value of PERMISSIVE is nonzero.  */
 
 /* Let's optimize away calls to strlen("operator").  */
 
 #define LENGTH_OF_OPERATOR 8
 
-unsigned int
-cp_find_first_component (const char *name)
+static unsigned int
+cp_find_first_component_aux (const char *name, int permissive)
 {
   unsigned int index = 0;
   /* Operator names can show up in unexpected places.  Since these can
@@ -234,11 +466,15 @@ cp_find_first_component (const char *name)
             terminating the component or a '::' between two
             components.  (Hence the '+ 2'.)  */
          index += 1;
-         for (index += cp_find_first_component (name + index);
+         for (index += cp_find_first_component_aux (name + index, 1);
               name[index] != '>';
-              index += cp_find_first_component (name + index))
+              index += cp_find_first_component_aux (name + index, 1))
            {
-             gdb_assert (name[index] == ':');
+             if (name[index] != ':')
+               {
+                 demangled_name_complaint (name);
+                 return strlen (name);
+               }
              index += 2;
            }
          operator_possible = 1;
@@ -246,17 +482,28 @@ cp_find_first_component (const char *name)
        case '(':
          /* Similar comment as to '<'.  */
          index += 1;
-         for (index += cp_find_first_component (name + index);
+         for (index += cp_find_first_component_aux (name + index, 1);
               name[index] != ')';
-              index += cp_find_first_component (name + index))
+              index += cp_find_first_component_aux (name + index, 1))
            {
-             gdb_assert (name[index] == ':');
+             if (name[index] != ':')
+               {
+                 demangled_name_complaint (name);
+                 return strlen (name);
+               }
              index += 2;
            }
          operator_possible = 1;
          break;
        case '>':
        case ')':
+         if (permissive)
+           return index;
+         else
+           {
+             demangled_name_complaint (name);
+             return strlen (name);
+           }
        case '\0':
        case ':':
          return index;
@@ -315,6 +562,16 @@ cp_find_first_component (const char *name)
     }
 }
 
+/* Complain about a demangled name that we don't know how to parse.
+   NAME is the demangled name in question.  */
+
+static void
+demangled_name_complaint (const char *name)
+{
+  complaint (&symfile_complaints,
+            "unexpected demangled name '%s'", name);
+}
+
 /* If NAME is the fully-qualified name of a C++
    function/variable/method/etc., this returns the length of its
    entire prefix: all of the namespaces and classes that make up its
@@ -341,54 +598,12 @@ cp_entire_prefix_len (const char *name)
 
 /* Overload resolution functions.  */
 
-static char *
-remove_params (const char *demangled_name)
-{
-  const char *argp;
-  char *new_name;
-  int depth;
-
-  if (demangled_name == NULL)
-    return NULL;
-
-  /* First find the end of the arg list.  */
-  argp = strrchr (demangled_name, ')');
-  if (argp == NULL)
-    return NULL;
-
-  /* Back up to the beginning.  */
-  depth = 1;
-
-  while (argp-- > demangled_name)
-    {
-      if (*argp == ')')
-       depth ++;
-      else if (*argp == '(')
-       {
-         depth --;
-
-         if (depth == 0)
-           break;
-       }
-    }
-  if (depth != 0)
-    internal_error (__FILE__, __LINE__,
-                   "bad demangled name %s\n", demangled_name);
-  while (argp[-1] == ' ' && argp > demangled_name)
-    argp --;
-
-  new_name = xmalloc (argp - demangled_name + 1);
-  memcpy (new_name, demangled_name, argp - demangled_name);
-  new_name[argp - demangled_name] = '\0';
-  return new_name;
-}
-
-/*  Test to see if the symbol specified by SYMNAME (which is already
-   demangled for C++ symbols) matches SYM_TEXT in the first SYM_TEXT_LEN
-   characters.  If so, add it to the current completion list. */
+/* Test to see if SYM is a symbol that we haven't seen corresponding
+   to a function named OLOAD_NAME.  If so, add it to the current
+   completion list. */
 
 static void
-overload_list_add_symbol (struct symbol *sym, char *oload_name)
+overload_list_add_symbol (struct symbol *sym, const char *oload_name)
 {
   int newsize;
   int i;
@@ -400,11 +615,12 @@ overload_list_add_symbol (struct symbol *sym, char *oload_name)
 
   /* skip any symbols that we've already considered. */
   for (i = 0; i < sym_return_val_index; ++i)
-    if (!strcmp (DEPRECATED_SYMBOL_NAME (sym), DEPRECATED_SYMBOL_NAME (sym_return_val[i])))
+    if (strcmp (SYMBOL_LINKAGE_NAME (sym),
+               SYMBOL_LINKAGE_NAME (sym_return_val[i])) == 0)
       return;
 
   /* Get the demangled name without parameters */
-  sym_name = remove_params (SYMBOL_DEMANGLED_NAME (sym));
+  sym_name = remove_params (SYMBOL_NATURAL_NAME (sym));
   if (!sym_name)
     return;
 
@@ -429,82 +645,108 @@ overload_list_add_symbol (struct symbol *sym, char *oload_name)
 }
 
 /* Return a null-terminated list of pointers to function symbols that
- * match name of the supplied symbol FSYM.
- * This is used in finding all overloaded instances of a function name.
- * This has been modified from make_symbol_completion_list.  */
-
+   are named FUNC_NAME and are visible within NAMESPACE.  */
 
 struct symbol **
-make_symbol_overload_list (struct symbol *fsym)
+make_symbol_overload_list (const char *func_name,
+                          const char *namespace)
 {
-  register struct symbol *sym;
-  register struct symtab *s;
-  register struct partial_symtab *ps;
-  register struct objfile *objfile;
-  register struct block *b, *surrounding_static_block = 0;
-  struct dict_iterator iter;
-  /* The name we are completing on. */
-  char *oload_name = NULL;
-  /* Length of name.  */
-  int oload_name_len = 0;
+  struct cleanup *old_cleanups;
 
-  /* Look for the symbol we are supposed to complete on.  */
+  sym_return_val_size = 100;
+  sym_return_val_index = 0;
+  sym_return_val = xmalloc ((sym_return_val_size + 1) *
+                           sizeof (struct symbol *));
+  sym_return_val[0] = NULL;
 
-  oload_name = remove_params (SYMBOL_DEMANGLED_NAME (fsym));
-  if (!oload_name)
-    {
-      sym_return_val_size = 1;
-      sym_return_val = (struct symbol **) xmalloc (2 * sizeof (struct symbol *));
-      sym_return_val[0] = fsym;
-      sym_return_val[1] = NULL;
+  old_cleanups = make_cleanup (xfree, sym_return_val);
+
+  make_symbol_overload_list_using (func_name, namespace);
+
+  discard_cleanups (old_cleanups);
+
+  return sym_return_val;
+}
+
+/* This applies the using directives to add namespaces to search in,
+   and then searches for overloads in all of those namespaces.  It
+   adds the symbols found to sym_return_val.  Arguments are as in
+   make_symbol_overload_list.  */
+
+static void
+make_symbol_overload_list_using (const char *func_name,
+                                const char *namespace)
+{
+  const struct using_direct *current;
 
-      return sym_return_val;
+  /* First, go through the using directives.  If any of them apply,
+     look in the appropriate namespaces for new functions to match
+     on.  */
+
+  for (current = block_using (get_selected_block (0));
+       current != NULL;
+       current = current->next)
+    {
+      if (strcmp (namespace, current->outer) == 0)
+       {
+         make_symbol_overload_list_using (func_name,
+                                          current->inner);
+       }
     }
-  oload_name_len = strlen (oload_name);
 
-  sym_return_val_size = 100;
-  sym_return_val_index = 0;
-  sym_return_val = (struct symbol **) xmalloc ((sym_return_val_size + 1) * sizeof (struct symbol *));
-  sym_return_val[0] = NULL;
+  /* Now, add names for this namespace.  */
+  
+  if (namespace[0] == '\0')
+    {
+      make_symbol_overload_list_qualified (func_name);
+    }
+  else
+    {
+      char *concatenated_name
+       = alloca (strlen (namespace) + 2 + strlen (func_name) + 1);
+      strcpy (concatenated_name, namespace);
+      strcat (concatenated_name, "::");
+      strcat (concatenated_name, func_name);
+      make_symbol_overload_list_qualified (concatenated_name);
+    }
+}
 
-  /* Read in all partial symtabs containing a partial symbol named
-     OLOAD_NAME.  */
+/* This does the bulk of the work of finding overloaded symbols.
+   FUNC_NAME is the name of the overloaded function we're looking for
+   (possibly including namespace info).  */
 
-  ALL_PSYMTABS (objfile, ps)
-  {
-    struct partial_symbol **psym;
+static void
+make_symbol_overload_list_qualified (const char *func_name)
+{
+  struct symbol *sym;
+  struct symtab *s;
+  struct objfile *objfile;
+  const struct block *b, *surrounding_static_block = 0;
+  struct dict_iterator iter;
+  const struct dictionary *dict;
 
-    /* If the psymtab's been read in we'll get it when we search
-       through the blockvector.  */
-    if (ps->readin)
-      continue;
+  /* Look through the partial symtabs for all symbols which begin
+     by matching FUNC_NAME.  Make sure we read that symbol table in. */
 
-    if ((lookup_partial_symbol (ps, oload_name, NULL, 1, VAR_DOMAIN)
-        != NULL)
-       || (lookup_partial_symbol (ps, oload_name, NULL, 0, VAR_DOMAIN)
-           != NULL))
-      PSYMTAB_TO_SYMTAB (ps);
-  }
+  read_in_psymtabs (func_name);
 
   /* 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 elimination of dups */
-       }
+      dict = BLOCK_DICT (b);
 
-      /* Also catch fields of types defined in this places which match our
-         text string.  Only complete on types visible from current context. */
-
-      ALL_BLOCK_SYMBOLS (b, iter, sym)
+      for (sym = dict_iter_name_first (dict, func_name, &iter);
+          sym;
+          sym = dict_iter_name_next (func_name, &iter))
        {
-         overload_list_add_symbol (sym, oload_name);
+         overload_list_add_symbol (sym, func_name);
        }
     }
 
+  surrounding_static_block = block_static_block (get_selected_block (0));
+
   /* Go through the symtabs and check the externs and statics for
      symbols which match.  */
 
@@ -512,10 +754,14 @@ make_symbol_overload_list (struct symbol *fsym)
   {
     QUIT;
     b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
-    ALL_BLOCK_SYMBOLS (b, iter, sym)
-      {
-       overload_list_add_symbol (sym, oload_name);
-      }
+    dict = BLOCK_DICT (b);
+
+    for (sym = dict_iter_name_first (dict, func_name, &iter);
+        sym;
+        sym = dict_iter_name_next (func_name, &iter))
+    {
+      overload_list_add_symbol (sym, func_name);
+    }
   }
 
   ALL_SYMTABS (objfile, s)
@@ -525,24 +771,88 @@ make_symbol_overload_list (struct symbol *fsym)
     /* Don't do this block twice.  */
     if (b == surrounding_static_block)
       continue;
-    ALL_BLOCK_SYMBOLS (b, iter, sym)
-      {
-       overload_list_add_symbol (sym, oload_name);
-      }
+    dict = BLOCK_DICT (b);
+
+    for (sym = dict_iter_name_first (dict, func_name, &iter);
+        sym;
+        sym = dict_iter_name_next (func_name, &iter))
+    {
+      overload_list_add_symbol (sym, func_name);
+    }
   }
+}
+
+/* Look through the partial symtabs for all symbols which begin
+   by matching FUNC_NAME.  Make sure we read that symbol table in. */
 
-  xfree (oload_name);
+static void
+read_in_psymtabs (const char *func_name)
+{
+  struct partial_symtab *ps;
+  struct objfile *objfile;
 
-  return (sym_return_val);
+  ALL_PSYMTABS (objfile, ps)
+  {
+    if (ps->readin)
+      continue;
+
+    if ((lookup_partial_symbol (ps, func_name, NULL, 1, VAR_DOMAIN)
+        != NULL)
+       || (lookup_partial_symbol (ps, func_name, NULL, 0, VAR_DOMAIN)
+           != NULL))
+      psymtab_to_symtab (ps);
+  }
 }
 
+/* Lookup the rtti type for a class name. */
+
+struct type *
+cp_lookup_rtti_type (const char *name, struct block *block)
+{
+  struct symbol * rtti_sym;
+  struct type * rtti_type;
+
+  rtti_sym = lookup_symbol (name, block, STRUCT_DOMAIN, NULL, NULL);
+
+  if (rtti_sym == NULL)
+    {
+      warning (_("RTTI symbol not found for class '%s'"), name);
+      return NULL;
+    }
+
+  if (SYMBOL_CLASS (rtti_sym) != LOC_TYPEDEF)
+    {
+      warning (_("RTTI symbol for class '%s' is not a type"), name);
+      return NULL;
+    }
+
+  rtti_type = SYMBOL_TYPE (rtti_sym);
+
+  switch (TYPE_CODE (rtti_type))
+    {
+    case TYPE_CODE_CLASS:
+      break;
+    case TYPE_CODE_NAMESPACE:
+      /* chastain/2003-11-26: the symbol tables often contain fake
+        symbols for namespaces with the same name as the struct.
+        This warning is an indication of a bug in the lookup order
+        or a bug in the way that the symbol tables are populated.  */
+      warning (_("RTTI symbol for class '%s' is a namespace"), name);
+      return NULL;
+    default:
+      warning (_("RTTI symbol for class '%s' has bad type"), name);
+      return NULL;
+    }
+
+  return rtti_type;
+}
 
 /* Don't allow just "maintenance cplus".  */
 
 static  void
 maint_cplus_command (char *arg, int from_tty)
 {
-  printf_unfiltered ("\"maintenance cplus\" must be followed by the name of a command.\n");
+  printf_unfiltered (_("\"maintenance cplus\" must be followed by the name of a command.\n"));
   help_list (maint_cplus_cmd_list, "maintenance cplus ", -1, gdb_stdout);
 }
 
@@ -568,12 +878,11 @@ void
 _initialize_cp_support (void)
 {
   add_prefix_cmd ("cplus", class_maintenance, maint_cplus_command,
-                 "C++ maintenance commands.", &maint_cplus_cmd_list,
+                 _("C++ maintenance commands."), &maint_cplus_cmd_list,
                  "maintenance cplus ", 0, &maintenancelist);
   add_alias_cmd ("cp", "cplus", class_maintenance, 1, &maintenancelist);
 
   add_cmd ("first_component", class_maintenance, first_component_command,
-          "Print the first class/namespace component of NAME.",
+          _("Print the first class/namespace component of NAME."),
           &maint_cplus_cmd_list);
-                 
 }
This page took 0.038682 seconds and 4 git commands to generate.