* symtab.c, symtab.h: Have a builtin_type_{,unsigned_}long_long
authorJim Kingdon <jkingdon@engr.sgi.com>
Fri, 26 Apr 1991 23:01:36 +0000 (23:01 +0000)
committerJim Kingdon <jkingdon@engr.sgi.com>
Fri, 26 Apr 1991 23:01:36 +0000 (23:01 +0000)
regardless of LONG_LONG.
symtab.c, symtab.h (allocate_stub_method): New function.
* symtab.c (decode_line_1): Deal with operators specified as
"operator" <optional whitespace> <symbols for operator>.
(operator_chars): Help do it.
* symtab.c (lookup_struct_elt_type): Call check_stub_type.
Take additional argument noerr.
Don't dump core if TYPE_FIELD_NAME is NULL.
Check the baseclasses recursively.

gdb/symtab.c

index 98b6ca186819b5dc48774ff2813e4f96592c860f..15e2ad6806b0d186f05fe99a8d7731b5a3309487 100644 (file)
@@ -60,16 +60,12 @@ struct type *builtin_type_char;
 struct type *builtin_type_short;
 struct type *builtin_type_int;
 struct type *builtin_type_long;
-#ifdef LONG_LONG
 struct type *builtin_type_long_long;
-#endif
 struct type *builtin_type_unsigned_char;
 struct type *builtin_type_unsigned_short;
 struct type *builtin_type_unsigned_int;
 struct type *builtin_type_unsigned_long;
-#ifdef LONG_LONG
 struct type *builtin_type_unsigned_long_long;
-#endif
 struct type *builtin_type_float;
 struct type *builtin_type_double;
 struct type *builtin_type_error;
@@ -385,12 +381,14 @@ lookup_enum (name, block)
 }
 
 /* Given a type TYPE, lookup the type of the component of type named
-   NAME.  */
+   NAME.  
+   If NOERR is nonzero, return zero if NAME is not suitably defined.  */
 
 struct type *
-lookup_struct_elt_type (type, name)
+lookup_struct_elt_type (type, name, noerr)
      struct type *type;
      char *name;
+     int noerr;
 {
   int i;
 
@@ -404,10 +402,27 @@ lookup_struct_elt_type (type, name)
       error (" is not a structure or union type.");
     }
 
+  check_stub_type (type);
+
   for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--)
-    if (!strcmp (TYPE_FIELD_NAME (type, i), name))
-      return TYPE_FIELD_TYPE (type, i);
+    {
+      char *t_field_name = TYPE_FIELD_NAME (type, i);
 
+      if (t_field_name && !strcmp (t_field_name, name))
+       return TYPE_FIELD_TYPE (type, i);
+    }
+  /* OK, it's not in this class.  Recursively check the baseclasses.  */
+  for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
+    {
+      struct type *t = lookup_struct_elt_type (TYPE_BASECLASS (type, i),
+                                              name, 0);
+      if (t != NULL)
+       return t;
+    }
+
+  if (noerr)
+    return NULL;
+  
   target_terminal_ours ();
   fflush (stdout);
   fprintf (stderr, "Type ");
@@ -538,6 +553,29 @@ lookup_member_type (type, domain)
   return mtype;
 }
 
+/* Allocate a stub method whose return type is
+   TYPE.  We will fill in arguments later.  This always
+   returns a fresh type.  If we unify this type with
+   an existing type later, the storage allocated
+   here can be freed.  */
+struct type *
+allocate_stub_method (type)
+     struct type *type;
+{
+  struct type *mtype = (struct type *)xmalloc (sizeof (struct type));
+  bzero (mtype, sizeof (struct type));
+  TYPE_MAIN_VARIANT (mtype) = mtype;
+  TYPE_TARGET_TYPE (mtype) = type;
+  TYPE_FLAGS (mtype) = TYPE_FLAG_STUB;
+  TYPE_CODE (mtype) = TYPE_CODE_METHOD;
+  TYPE_LENGTH (mtype) = 1;
+  return mtype;
+}
+
+/* Lookup a method type returning type TYPE, belonging
+   to class DOMAIN, and taking a list of arguments ARGS.
+   If one is not found, allocate a new one.  */
+
 struct type *
 lookup_method_type (type, domain, args)
      struct type *type, *domain, **args;
@@ -1613,6 +1651,81 @@ find_pc_line_pc_range (pc, startptr, endptr)
   return sal.symtab != 0;
 }
 \f
+/* If P is of the form "operator[ \t]+..." where `...' is
+   some legitimate operator text, return a pointer to the
+   beginning of the substring of the operator text.
+   Otherwise, return "".  */
+static char *
+operator_chars (p, end)
+     char *p;
+     char **end;
+{
+  *end = "";
+  if (strncmp (p, "operator", 8))
+    return *end;
+  p += 8;
+
+  /* Don't get faked out by `operator' being part of a longer
+     identifier.  */
+  if ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z')
+      || *p == '_' || *p == '$' || *p == '\0')
+    return *end;
+
+  /* Allow some whitespace between `operator' and the operator symbol.  */
+  while (*p == ' ' || *p == '\t')
+    p++;
+
+  switch (*p)
+    {
+    case '!':
+    case '=':
+    case '*':
+    case '/':
+    case '%':
+    case '^':
+      if (p[1] == '=')
+       *end = p+2;
+      else
+       *end = p+1;
+      return p;
+    case '<':
+    case '>':
+    case '+':
+    case '-':
+    case '&':
+    case '|':
+      if (p[1] == '=' || p[1] == p[0])
+       *end = p+2;
+      else
+       *end = p+1;
+      return p;
+    case '~':
+    case ',':
+      *end = p+1;
+      return p;
+    case '(':
+      if (p[1] != ')')
+       error ("`operator ()' must be specified without whitespace in `()'");
+      *end = p+2;
+      return p;
+    case '?':
+      if (p[1] != ':')
+       error ("`operator ?:' must be specified without whitespace in `?:'");
+      *end = p+2;
+      return p;
+    case '[':
+      if (p[1] != ']')
+       error ("`operator []' must be specified without whitespace in `[]'");
+      *end = p+2;
+      return p;
+    default:
+      error ("`operator %s' not supported", p);
+      break;
+    }
+  *end = "";
+  return *end;
+}
+
 /* Recursive helper function for decode_line_1.
  * Look for methods named NAME in type T.
  * Return number of matches.
@@ -1740,6 +1853,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
   struct symtabs_and_lines values;
   struct symtab_and_line val;
   register char *p, *p1;
+  char *q, *q1;
   register struct symtab *s;
 
   register struct symbol *sym;
@@ -1788,6 +1902,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
     }
   while (p[0] == ' ' || p[0] == '\t') p++;
 
+  q = operator_chars (*argptr, &q1);
   if (p[0] == ':')
     {
 
@@ -1817,9 +1932,23 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
                 Find the next token (everything up to end or next whitespace). */
              p = *argptr;
              while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p !=':') p++;
-             copy = (char *) alloca (p - *argptr + 1);
-             bcopy (*argptr, copy, p - *argptr);
-             copy[p - *argptr] = '\0';
+             q = operator_chars (*argptr, &q1);
+             
+             copy = (char *) alloca (p - *argptr + 1 + (q1 - q));
+             if (q1 - q)
+               {
+                 copy[0] = 'o';
+                 copy[1] = 'p';
+                 copy[2] = CPLUS_MARKER;
+                 bcopy (q, copy + 3, q1 - q);
+                 copy[3 + (q1 - q)] = '\0';
+                 p = q1;
+               }
+             else
+               {
+                 bcopy (*argptr, copy, p - *argptr);
+                 copy[p - *argptr] = '\0';
+               }
 
              /* no line number may be specified */
              while (*p == ' ' || *p == '\t') p++;
@@ -1875,7 +2004,19 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
                  return decode_line_2 (sym_arr, i1, funfirstline);
                }
              else
-               error ("that class does not have any method named %s",copy);
+               {
+                 char *tmp;
+
+                 if (OPNAME_PREFIX_P (copy))
+                   {
+                     tmp = (char *)alloca (strlen (copy+3) + 9);
+                     strcpy (tmp, "operator ");
+                     strcat (tmp, copy+3);
+                   }
+                 else
+                   tmp = copy;
+                 error ("that class does not have any method named %s", tmp);
+               }
            }
          else
            /* The quotes are important if copy is empty.  */
@@ -1887,9 +2028,21 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
       /* Extract the file name.  */
       p1 = p;
       while (p != *argptr && p[-1] == ' ') --p;
-      copy = (char *) alloca (p - *argptr + 1);
-      bcopy (*argptr, copy, p - *argptr);
-      copy[p - *argptr] = 0;
+      copy = (char *) alloca (p - *argptr + 1 + (q1 - q));
+      if (q1 - q)
+       {
+         copy[0] = 'o';
+         copy[1] = 'p';
+         copy[2] = CPLUS_MARKER;
+         bcopy (q, copy + 3, q1-q);
+         copy[3 + (q1-q)] = 0;
+         p = q1;
+       }
+      else
+       {
+         bcopy (*argptr, copy, p - *argptr);
+         copy[p - *argptr] = 0;
+       }
 
       /* Find that file's data.  */
       s = lookup_symtab (copy);
@@ -2746,12 +2899,14 @@ are listed.");
   builtin_type_unsigned_short = init_type (TYPE_CODE_INT, sizeof (short), 1, "unsigned short");
   builtin_type_unsigned_long = init_type (TYPE_CODE_INT, sizeof (long), 1, "unsigned long");
   builtin_type_unsigned_int = init_type (TYPE_CODE_INT, sizeof (int), 1, "unsigned int");
-#ifdef LONG_LONG
+
   builtin_type_long_long =
-    init_type (TYPE_CODE_INT, sizeof (long long), 0, "long long");
+    init_type (TYPE_CODE_INT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+              0, "long long");
   builtin_type_unsigned_long_long = 
-    init_type (TYPE_CODE_INT, sizeof (long long), 1, "unsigned long long");
-#endif
+    init_type (TYPE_CODE_INT, TARGET_LONG_LONG_BIT / TARGET_CHAR_BIT,
+              1, "unsigned long long");
+
   builtin_type_error = init_type (TYPE_CODE_ERROR, 0, 0, "<unknown type>");
 }