ChangeLog:
[deliverable/binutils-gdb.git] / gdb / cp-support.c
index df48f6021db212917b8ccb7439779b37570c8b90..d43d25fbbca7b468bf16859468c28e7356de110d 100644 (file)
@@ -1,5 +1,5 @@
 /* Helper routines for C++ support in GDB.
-   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008
+   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
    Contributed by MontaVista Software.
 #include "block.h"
 #include "complaints.h"
 #include "gdbtypes.h"
+#include "exceptions.h"
+#include "expression.h"
+#include "value.h"
 
 #include "safe-ctype.h"
 
+#include "psymtab.h"
+
 #define d_left(dc) (dc)->u.s_binary.left
 #define d_right(dc) (dc)->u.s_binary.right
 
@@ -59,8 +64,6 @@ static void make_symbol_overload_list_using (const char *func_name,
 
 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.  */
 
 struct cmd_list_element *maint_cplus_cmd_list = NULL;
@@ -70,6 +73,18 @@ struct cmd_list_element *maint_cplus_cmd_list = NULL;
 static void maint_cplus_command (char *arg, int from_tty);
 static void first_component_command (char *arg, int from_tty);
 
+/* Operator validation.
+   NOTE: Multi-byte operators (usually the assignment variety operator)
+   must appear before the single byte version, i.e., "+=" before "+".  */
+static const char *operator_tokens[] =
+  {
+    "++", "+=", "+", "->*", "->", "--", "-=", "-", "*=", "*", "/=", "/",
+    "%=", "%", "!=", "==", "!", "&&", "<<=", "<<", ">>=", ">>",
+    "<=", "<", ">=", ">", "~", "&=", "&", "|=", "||", "|", "^=", "^",
+    "=", "()", "[]", ",", "new", "delete"
+    /* new[] and delete[] require special whitespace handling */
+  };
+
 /* Return 1 if STRING is clearly already in canonical form.  This
    function is conservative; things which it does not recognize are
    assumed to be non-canonical, and the parser will sort them out
@@ -167,7 +182,7 @@ mangled_name_to_comp (const char *mangled_name, int options,
 
   if (ret == NULL)
     {
-      free (demangled_name);
+      xfree (demangled_name);
       return NULL;
     }
 
@@ -716,10 +731,10 @@ make_symbol_overload_list_using (const char *func_name,
        current != NULL;
        current = current->next)
     {
-      if (strcmp (namespace, current->outer) == 0)
+      if (strcmp (namespace, current->import_dest) == 0)
        {
          make_symbol_overload_list_using (func_name,
-                                          current->inner);
+                                          current->import_src);
        }
     }
 
@@ -757,7 +772,11 @@ make_symbol_overload_list_qualified (const char *func_name)
   /* Look through the partial symtabs for all symbols which begin
      by matching FUNC_NAME.  Make sure we read that symbol table in. */
 
-  read_in_psymtabs (func_name);
+  ALL_OBJFILES (objfile)
+  {
+    if (objfile->sf)
+      objfile->sf->qf->expand_symtabs_for_function (objfile, func_name);
+  }
 
   /* Search upwards from currently selected frame (so that we can
      complete on local vars.  */
@@ -811,28 +830,6 @@ make_symbol_overload_list_qualified (const char *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;
-
-  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 *
@@ -909,6 +906,107 @@ first_component_command (char *arg, int from_tty)
 
 extern initialize_file_ftype _initialize_cp_support; /* -Wmissing-prototypes */
 
+#define SKIP_SPACE(P)                          \
+  do                                           \
+  {                                            \
+    while (*(P) == ' ' || *(P) == '\t')                \
+      ++(P);                                   \
+  }                                            \
+  while (0)
+
+/* Returns the length of the operator name or 0 if INPUT does not
+   point to a valid C++ operator.  INPUT should start with "operator".  */
+int
+cp_validate_operator (const char *input)
+{
+  int i;
+  char *copy;
+  const char *p;
+  struct expression *expr;
+  struct value *val;
+  struct gdb_exception except;
+  struct cleanup *old_chain;
+
+  p = input;
+
+  if (strncmp (p, "operator", 8) == 0)
+    {
+      int valid = 0;
+      p += 8;
+
+      SKIP_SPACE (p);
+      for (i = 0; i < sizeof (operator_tokens) / sizeof (operator_tokens[0]);
+          ++i)
+       {
+         int length = strlen (operator_tokens[i]);
+         /* By using strncmp here, we MUST have operator_tokens ordered!
+            See additional notes where operator_tokens is defined above.  */
+         if (strncmp (p, operator_tokens[i], length) == 0)
+           {
+             const char *op = p;
+             valid = 1;
+             p += length;
+
+             if (strncmp (op, "new", 3) == 0
+                 || strncmp (op, "delete", 6) == 0)
+               {
+
+                 /* Special case: new[] and delete[].  We must be careful
+                    to swallow whitespace before/in "[]".  */
+                 SKIP_SPACE (p);
+
+                 if (*p == '[')
+                   {
+                     ++p;
+                     SKIP_SPACE (p);
+                     if (*p == ']')
+                       ++p;
+                     else
+                       valid = 0;
+                   }
+               }
+
+             if (valid)
+               return (p - input);
+           }
+       }
+
+      /* Check input for a conversion operator.  */
+
+      /* Skip past base typename */
+      while (*p != '*' && *p != '&' && *p != 0 && *p != ' ')
+       ++p;
+      SKIP_SPACE (p);
+
+      /* Add modifiers '*'/'&' */
+      while (*p == '*' || *p == '&')
+       {
+         ++p;
+         SKIP_SPACE (p);
+       }
+
+      /* Check for valid type.  [Remember: input starts with 
+        "operator".]  */
+      copy = savestring (input + 8, p - input - 8);
+      expr = NULL;
+      val = NULL;
+      TRY_CATCH (except, RETURN_MASK_ALL)
+       {
+         expr = parse_expression (copy);
+         val = evaluate_type (expr);
+       }
+
+      xfree (copy);
+      if (expr)
+       xfree (expr);
+
+      if (val != NULL && value_type (val) != NULL)
+       return (p - input);
+    }
+
+  return 0;
+}
+
 void
 _initialize_cp_support (void)
 {
This page took 0.02775 seconds and 4 git commands to generate.