2005-02-15 Andrew Cagney <cagney@gnu.org>
[deliverable/binutils-gdb.git] / gdb / cp-support.c
index 9e6d44b119c87271bcff8cf9ef21102c5cad8d41..ecda4a53950642904812751d24c8d2adb8be1e21 100644 (file)
@@ -33,6 +33,7 @@
 #include "symtab.h"
 #include "block.h"
 #include "complaints.h"
+#include "gdbtypes.h"
 
 /* Functions related to demangled name parsing.  */
 
@@ -51,7 +52,15 @@ static struct symbol **sym_return_val;
 
 static char *remove_params (const char *demangled_name);
 
-static void overload_list_add_symbol (struct symbol *sym, char *oload_name);
+static void overload_list_add_symbol (struct symbol *sym,
+                                     const 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.  */
 
@@ -139,12 +148,12 @@ find_last_component (const char *name)
 /* Return the name of the class containing method PHYSNAME.  */
 
 char *
-class_name_from_physname (const char *physname)
+cp_class_name_from_physname (const char *physname)
 {
   char *ret = NULL;
   const char *end;
   int depth = 0;
-  char *demangled_name = cplus_demangle (physname, DMGL_ANSI);
+  char *demangled_name = cplus_demangle (physname, DMGL_ANSI | DMGL_PARAMS);
 
   if (demangled_name == NULL)
     return NULL;
@@ -169,7 +178,7 @@ method_name_from_physname (const char *physname)
   char *ret = NULL;
   const char *end;
   int depth = 0;
-  char *demangled_name = cplus_demangle (physname, DMGL_ANSI);
+  char *demangled_name = cplus_demangle (physname, DMGL_ANSI | DMGL_PARAMS);
 
   if (demangled_name == NULL)
     return NULL;
@@ -385,6 +394,34 @@ cp_entire_prefix_len (const char *name)
   return previous_len;
 }
 
+/* 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)
+{
+  const char *previous_component = full_name;
+  const char *next_component;
+
+  if (!full_name)
+    return NULL;
+
+  for (next_component = (previous_component
+                        + cp_find_first_component (previous_component));
+       *next_component == ':';
+       next_component = (previous_component
+                        + cp_find_first_component (previous_component)))
+    {
+      /* Skip '::'.  */
+      previous_component = next_component + 2;
+    }
+
+  return remove_params (previous_component);
+}
+
 /* Overload resolution functions.  */
 
 static char *
@@ -419,7 +456,7 @@ remove_params (const char *demangled_name)
     }
   if (depth != 0)
     internal_error (__FILE__, __LINE__,
-                   "bad demangled name %s\n", demangled_name);
+                   _("bad demangled name %s\n"), demangled_name);
   while (argp[-1] == ' ' && argp > demangled_name)
     argp --;
 
@@ -429,12 +466,12 @@ remove_params (const char *demangled_name)
   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;
@@ -446,11 +483,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;
 
@@ -475,82 +513,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)
 {
-  struct symbol *sym;
-  struct symtab *s;
-  struct partial_symtab *ps;
-  struct objfile *objfile;
-  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);
 
-      return 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;
+
+  /* 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 */
-       }
-
-      /* Also catch fields of types defined in this places which match our
-         text string.  Only complete on types visible from current context. */
+      dict = BLOCK_DICT (b);
 
-      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.  */
 
@@ -558,10 +622,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)
@@ -571,24 +639,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. */
+
+static void
+read_in_psymtabs (const char *func_name)
+{
+  struct partial_symtab *ps;
+  struct objfile *objfile;
 
-  xfree (oload_name);
+  ALL_PSYMTABS (objfile, ps)
+  {
+    if (ps->readin)
+      continue;
 
-  return (sym_return_val);
+    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);
 }
 
@@ -614,12 +746,12 @@ 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.030659 seconds and 4 git commands to generate.