]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
* cp-names.y (%union): Remove typed_val_float.
authorDaniel Jacobowitz <drow@false.org>
Fri, 19 Dec 2003 18:54:02 +0000 (18:54 +0000)
committerDaniel Jacobowitz <drow@false.org>
Fri, 19 Dec 2003 18:54:02 +0000 (18:54 +0000)
(INT, FLOAT): Change to type comp.
(CONSTRUCTION_VTABLE): Change to untyped.
(demangler_special): Use D_COMP_CONSTRUCTION_VTABLE.
(array_indicator, exp): Update for new types of INT and FLOAT.
Handle D_COMP_LITERAL_NEG.
(parse_number): Simplify.  Use D_COMP_LITERAL_NEG.
(HANDLE_SPECIAL): Define.
(tokentab_big): Remove.
(yylex): Remove unused variables.  Optimize calls to strncmp
and handling of multi-word tokens.

gdb/ChangeLog.cplus
gdb/cp-names.y

index c058ff9206750a4f3c6b598e57c6f38718035527..f1fabe205f71d5d08a15c03305042d6e0dd60f74 100644 (file)
@@ -1,3 +1,17 @@
+2003-12-19  Daniel Jacobowitz  <drow@mvista.com>
+
+       * cp-names.y (%union): Remove typed_val_float.
+       (INT, FLOAT): Change to type comp.
+       (CONSTRUCTION_VTABLE): Change to untyped.
+       (demangler_special): Use D_COMP_CONSTRUCTION_VTABLE.
+       (array_indicator, exp): Update for new types of INT and FLOAT.
+       Handle D_COMP_LITERAL_NEG.
+       (parse_number): Simplify.  Use D_COMP_LITERAL_NEG.
+       (HANDLE_SPECIAL): Define.
+       (tokentab_big): Remove.
+       (yylex): Remove unused variables.  Optimize calls to strncmp
+       and handling of multi-word tokens.
+
 2003-12-19  Daniel Jacobowitz  <drow@mvista.com>
 
        * cp-names.y (symbol_end): New function.
index b5d3247fc08f1b71ce9dd61985805c27b2a3bafb..791bbd288fbeed5253e145e012eb66a08b849b79 100644 (file)
@@ -187,9 +187,6 @@ void yyerror (char *);
       LONGEST val;
       struct d_comp *type;
     } typed_val_int;
-    struct {
-      DOUBLEST dval;
-    } typed_val_float;
     const char *opname;
   }
 
@@ -221,8 +218,8 @@ static int parse_number (char *, int, int, YYSTYPE *);
 
 %type <lval> sign size int_type
 
-%token <typed_val_int> INT
-%token <typed_val_float> FLOAT
+%token <comp> INT
+%token <comp> FLOAT
 
 %token <comp> NAME
 %type <comp> name
@@ -245,8 +242,8 @@ static int parse_number (char *, int, int, YYSTYPE *);
 %token FALSEKEYWORD
 
 /* Non-C++ things we get from the demangler.  */
-%token <lval> DEMANGLER_SPECIAL CONSTRUCTION_VTABLE
-%token CONSTRUCTION_IN
+%token <lval> DEMANGLER_SPECIAL
+%token CONSTRUCTION_VTABLE CONSTRUCTION_IN
 %token <typed_val_int> GLOBAL
 
 %{
@@ -336,7 +333,7 @@ demangler_special
                          d_left ($$) = $2;
                          d_right ($$) = NULL; }
                |       CONSTRUCTION_VTABLE start CONSTRUCTION_IN start
-                       { $$ = d_make_comp (di, $1, $2, $4); }
+                       { $$ = d_make_comp (di, D_COMP_CONSTRUCTION_VTABLE, $2, $4); }
                |       GLOBAL
                        { $$ = d_make_empty (di, $1.val);
                          d_left ($$) = $1.type;
@@ -672,14 +669,8 @@ array_indicator    :       '[' ']'
                          d_left ($$) = NULL;
                        }
                |       '[' INT ']'
-                       { struct d_comp *i;
-                         /* FIXME: Blatant memory leak.  */
-                         char *buf = malloc (24);
-                         sprintf (buf, "%d", (int) $2.val);
-                         i = d_make_name (di, buf, strlen (buf));
-                         i = d_make_comp (di, D_COMP_LITERAL, $2.type, i);
-                         $$ = d_make_empty (di, D_COMP_ARRAY_TYPE);
-                         d_left ($$) = i;
+                       { $$ = d_make_empty (di, D_COMP_ARRAY_TYPE);
+                         d_left ($$) = $2;
                        }
 
 /* Details of this approach inspired by the G++ < 3.4 parser.  */
@@ -849,7 +840,8 @@ exp :       '~' exp    %prec UNARY
    its type.  */
 
 exp    :       '(' type ')' exp  %prec UNARY
-               { if ($4->type == D_COMP_LITERAL)
+               { if ($4->type == D_COMP_LITERAL
+                     || $4->type == D_COMP_LITERAL_NEG)
                    {
                      $$ = $4;
                      d_left ($4) = $2;
@@ -986,26 +978,10 @@ exp       :       exp '?' exp ':' exp     %prec '?'
        ;
                          
 exp    :       INT
-                       { struct d_comp *i;
-                         /* FIXME: Blatant memory leak.  */
-                         char *buf = malloc (24);
-                         sprintf (buf, "%d", (int) $1.val);
-                         i = d_make_name (di, buf, strlen (buf));
-                         $$ = d_make_comp (di, D_COMP_LITERAL, $1.type, i);
-                       }
        ;
 
 /* Not generally allowed.  */
 exp    :       FLOAT
-                       { struct d_comp *i;
-                         /* FIXME: Blatant memory leak.  */
-                         char *buf = malloc (24);
-                         sprintf (buf, "%f", (double) $1.dval);
-                         i = d_make_name (di, buf, strlen (buf));
-                         $$ = d_make_comp (di, D_COMP_LITERAL,
-                                           d_make_builtin_type (di, &d_builtin_types['d' - 'a']),
-                                           i);
-                       }
        ;
 
 exp    :       SIZEOF '(' type ')'     %prec UNARY
@@ -1172,228 +1148,107 @@ parse_number (p, len, parsed_float, putithere)
      int parsed_float;
      YYSTYPE *putithere;
 {
-  /* FIXME: Shouldn't these be unsigned?  We don't deal with negative values
-     here, and we do kind of silly things like cast to unsigned.  */
-  LONGEST n = 0;
-  LONGEST prevn = 0;
-  ULONGEST un;
-
-  int i = 0;
-  int c;
-  int base = 10;
   int unsigned_p = 0;
-  int negative_p = 0;
 
   /* Number of "L" suffixes encountered.  */
   int long_p = 0;
 
-  /* We have found a "L" or "U" suffix.  */
-  int found_suffix = 0;
-
-  ULONGEST high_bit;
   struct d_comp *signed_type;
   struct d_comp *unsigned_type;
+  struct d_comp *type, *name;
+  enum d_comp_type literal_type;
+
+  if (p[0] == '-')
+    {
+      literal_type = D_COMP_LITERAL_NEG;
+      p++;
+      len--;
+    }
+  else
+    literal_type = D_COMP_LITERAL;
 
   if (parsed_float)
     {
       /* It's a float since it contains a point or an exponent.  */
       char c;
-      int num = 0;     /* number of tokens scanned by scanf */
-      char saved_char = p[len];
-
-      p[len] = 0;      /* null-terminate the token */
-      if (sizeof (putithere->typed_val_float.dval) <= sizeof (float))
-       num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval,&c);
-      else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double))
-       num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval,&c);
-      else
-       {
-#ifdef SCANF_HAS_LONG_DOUBLE
-         num = sscanf (p, "%Lg%c", &putithere->typed_val_float.dval,&c);
-#else
-         /* Scan it into a double, then assign it to the long double.
-            This at least wins with values representable in the range
-            of doubles. */
-         double temp;
-         num = sscanf (p, "%lg%c", &temp,&c);
-         putithere->typed_val_float.dval = temp;
-#endif
-       }
-      p[len] = saved_char;     /* restore the input stream */
-      if (num != 1)            /* check scanf found ONLY a float ... */
-       return ERROR;
+
+      /* The GDB lexer checks the result of scanf at this point.  Not doing
+         this leaves our error checking slightly weaker but only for invalid
+         data.  */
+
       /* See if it has `f' or `l' suffix (float or long double).  */
 
       c = TOLOWER (p[len - 1]);
 
-#if 0
       if (c == 'f')
-       putithere->typed_val_float.type = builtin_type_float;
+       {
+         len--;
+         type = d_make_builtin_type (di, &d_builtin_types ['f' - 'a']);
+       }
       else if (c == 'l')
-       putithere->typed_val_float.type = builtin_type_long_double;
-      else if (isdigit (c) || c == '.')
-       putithere->typed_val_float.type = builtin_type_double;
+       {
+         len--;
+         type = d_make_builtin_type (di, &d_builtin_types ['e' - 'a']);
+       }
+      else if (ISDIGIT (c) || c == '.')
+       type = d_make_builtin_type (di, &d_builtin_types ['d' - 'a']);
       else
        return ERROR;
-#endif
 
-      return FLOAT;
-    }
+      name = d_make_name (di, p, len);
+      putithere->comp = d_make_comp (di, literal_type, type, name);
 
-  if (p[0] == '-')
-    {
-      negative_p = 1;
-      p++;
-      len--;
+      return FLOAT;
     }
-  else
-    negative_p = 0;
-
-  /* Handle base-switching prefixes 0x, 0t, 0d, 0 */
-  if (p[0] == '0')
-    switch (p[1])
-      {
-      case 'x':
-      case 'X':
-       if (len >= 3)
-         {
-           p += 2;
-           base = 16;
-           len -= 2;
-         }
-       break;
-
-      case 't':
-      case 'T':
-      case 'd':
-      case 'D':
-       if (len >= 3)
-         {
-           p += 2;
-           base = 10;
-           len -= 2;
-         }
-       break;
 
-      default:
-       base = 8;
-       break;
-      }
+  /* This treats 0x1 and 1 as different literals.  We also do not
+     automatically generate unsigned types.  */
 
-  while (len-- > 0)
+  long_p = 0;
+  unsigned_p = 0;
+  while (len > 0)
     {
-      c = *p++;
-      if (c >= 'A' && c <= 'Z')
-       c += 'a' - 'A';
-      if (c != 'l' && c != 'u')
-       n *= base;
-      if (c >= '0' && c <= '9')
+      if (p[len - 1] == 'l' || p[len - 1] == 'L')
        {
-         if (found_suffix)
-           return ERROR;
-         n += i = c - '0';
+         len--;
+         long_p++;
+         continue;
        }
-      else
+      if (p[len - 1] == 'u' || p[len - 1] == 'U')
        {
-         if (base > 10 && c >= 'a' && c <= 'f')
-           {
-             if (found_suffix)
-               return ERROR;
-             n += i = c - 'a' + 10;
-           }
-         else if (c == 'l')
-           {
-             ++long_p;
-             found_suffix = 1;
-           }
-         else if (c == 'u')
-           {
-             unsigned_p = 1;
-             found_suffix = 1;
-           }
-         else
-           return ERROR;       /* Char not a digit */
-       }
-      if (i >= base)
-       return ERROR;           /* Invalid digit in this base */
-
-      /* Portably test for overflow (only works for nonzero values, so make
-        a second check for zero).  FIXME: Can't we just make n and prevn
-        unsigned and avoid this?  */
-      if (c != 'l' && c != 'u' && (prevn >= n) && n != 0)
-       unsigned_p = 1;         /* Try something unsigned */
-
-      /* Portably test for unsigned overflow.
-        FIXME: This check is wrong; for example it doesn't find overflow
-        on 0x123456789 when LONGEST is 32 bits.  */
-      if (c != 'l' && c != 'u' && n != 0)
-       {       
-         if ((unsigned_p && (ULONGEST) prevn >= (ULONGEST) n))
-           error ("Numeric constant too large.");
+         len--;
+         unsigned_p++;
+         continue;
        }
-      prevn = n;
+      break;
     }
 
-  /* An integer constant is an int, a long, or a long long.  An L
-     suffix forces it to be long; an LL suffix forces it to be long
-     long.  If not forced to a larger size, it gets the first type of
-     the above that it fits in.  To figure out whether it fits, we
-     shift it right and see whether anything remains.  Note that we
-     can't shift sizeof (LONGEST) * HOST_CHAR_BIT bits or more in one
-     operation, because many compilers will warn about such a shift
-     (which always produces a zero result).  Sometimes TARGET_INT_BIT
-     or TARGET_LONG_BIT will be that big, sometimes not.  To deal with
-     the case where it is we just always shift the value more than
-     once, with fewer bits each time.  */
-
-  un = (ULONGEST)n >> 2;
-  if (long_p == 0
-      && (un >> (TARGET_INT_BIT - 2)) == 0)
+  if (long_p == 0)
     {
-      high_bit = ((ULONGEST)1) << (TARGET_INT_BIT-1);
-
-      /* A large decimal (not hex or octal) constant (between INT_MAX
-        and UINT_MAX) is a long or unsigned long, according to ANSI,
-        never an unsigned int, but this code treats it as unsigned
-        int.  This probably should be fixed.  GCC gives a warning on
-        such constants.  */
-
       unsigned_type = d_int_type ('j' - 'a');
       signed_type = d_int_type ('i' - 'a');
     }
-  else if (long_p <= 1
-          && (un >> (TARGET_LONG_BIT - 2)) == 0)
+  else if (long_p == 1)
     {
-      high_bit = ((ULONGEST)1) << (TARGET_LONG_BIT-1);
       unsigned_type = d_int_type ('m' - 'a');
       signed_type = d_int_type ('l' - 'a');
     }
   else
     {
-      int shift;
-      if (sizeof (ULONGEST) * HOST_CHAR_BIT < TARGET_LONG_LONG_BIT)
-       /* A long long does not fit in a LONGEST.  */
-       shift = (sizeof (ULONGEST) * HOST_CHAR_BIT - 1);
-      else
-       shift = (TARGET_LONG_LONG_BIT - 1);
-      high_bit = (ULONGEST) 1 << shift;
       unsigned_type = d_int_type ('x' - 'a');
       signed_type = d_int_type ('y' - 'a');
     }
 
-  /* FIXME: overflow, et cetera.  Dumb this whole function down a notch.  */
-  if (negative_p)
-    n = -n;
-
-   putithere->typed_val_int.val = n;
-
    /* If the high bit of the worked out type is set then this number
       has to be unsigned. */
 
-   if (unsigned_p || (n & high_bit)) 
-     putithere->typed_val_int.type = unsigned_type;
+   if (unsigned_p)
+     type = unsigned_type;
    else
-     putithere->typed_val_int.type = signed_type;
+     type = signed_type;
+
+   name = d_make_name (di, p, len);
+   putithere->comp = d_make_comp (di, literal_type, type, name);
 
    return INT;
 }
@@ -1588,26 +1443,18 @@ static const struct token tokentab2[] =
     {">=", GEQ, BINOP_END}
   };
 
-static const struct token tokentab_big[] = {
-  { "global constructors keyed to", 28, GLOBAL_CONSTRUCTORS},
-  { "global destructors keyed to", 27, GLOBAL_DESTRUCTORS},
-  { "construction vtable for", 23, D_COMP_CONSTRUCTION_VTABLE},
-  { "VTT for", 7, D_COMP_VTT},
-  { "vtable for", 10, D_COMP_VTABLE},
-  { "typeinfo for", 12, D_COMP_TYPEINFO},
-  { "typeinfo fn for", 15, D_COMP_TYPEINFO_FN},
-  { "typeinfo name for", 17, D_COMP_TYPEINFO_NAME},
-  { "non-virtual thunk to", 20, D_COMP_THUNK},
-  { "virtual thunk to", 16, D_COMP_VIRTUAL_THUNK},
-  { "covariant return thunk to", 25, D_COMP_COVARIANT_THUNK},
-  { "guard variable for", 18, D_COMP_GUARD},
-  { "reference temporary for", 23, D_COMP_REFTEMP}
-};
+#define HANDLE_SPECIAL(string, len, comp)              \
+  if (strncmp (tokstart, string, len) == 0)            \
+    {                                                  \
+      lexptr = tokstart + len;                         \
+      yylval.lval = comp;                              \
+      return DEMANGLER_SPECIAL;                                \
+    }
 
 /* Read one token, getting characters through lexptr.  */
 
 static int
-yylex ()
+yylex (void)
 {
   int c;
   int namelen;
@@ -1617,9 +1464,6 @@ yylex ()
   int tempbufindex;
   static char *tempbuf;
   static int tempbufsize;
-  struct symbol * sym_class = NULL;
-  char * token_string = NULL;
-  int class_prefix = 0;
   int unquoted_expr;
    
  retry:
@@ -1630,7 +1474,9 @@ yylex ()
   tokstart = lexptr;
   /* See if it is a special token of length 3.  */
   for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
-    if (strncmp (tokstart, tokentab3[i].operator, 3) == 0)
+    if (tokstart[0] == tokentab3[i].operator[0]
+        && tokstart[1] == tokentab3[i].operator[1]
+        && tokstart[2] == tokentab3[i].operator[2])
       {
        lexptr += 3;
        yylval.opname = tokentab3[i].operator;
@@ -1639,28 +1485,14 @@ yylex ()
 
   /* See if it is a special token of length 2.  */
   for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
-    if (strncmp (tokstart, tokentab2[i].operator, 2) == 0)
+    if (tokstart[0] == tokentab2[i].operator[0]
+        && tokstart[1] == tokentab2[i].operator[1])
       {
        lexptr += 2;
        yylval.opname = tokentab2[i].operator;
        return tokentab2[i].token;
       }
 
-  /* For construction vtables.  This is kind of hokey.  */
-  if (strncmp (tokstart, "-in-", 4) == 0)
-    {
-      lexptr += 4;
-      return CONSTRUCTION_IN;
-    }
-
-  if (strncmp (tokstart, "(anonymous namespace)", 21) == 0)
-    {
-      lexptr += 21;
-      yylval.comp = d_make_name (di, "(anonymous namespace)",
-                                sizeof "(anonymous namespace)" - 1);
-      return NAME;
-    }
-
   switch (c = *tokstart)
     {
     case 0:
@@ -1702,6 +1534,15 @@ yylex ()
       return INT;
 
     case '(':
+      if (strncmp (tokstart, "(anonymous namespace)", 21) == 0)
+       {
+         lexptr += 21;
+         yylval.comp = d_make_name (di, "(anonymous namespace)",
+                                    sizeof "(anonymous namespace)" - 1);
+         return NAME;
+       }
+       /* FALL THROUGH */
+
     case ')':
     case ',':
       lexptr++;
@@ -1720,6 +1561,13 @@ yylex ()
       /* FALL THRU into number case.  */
 
     case '-':
+      /* For construction vtables.  This is kind of hokey.  */
+      if (strncmp (tokstart, "-in-", 4) == 0)
+       {
+         lexptr += 4;
+         return CONSTRUCTION_IN;
+       }
+
       if (lexptr[1] < '0' || lexptr[1] > '9')
        {
          lexptr++;
@@ -1893,27 +1741,6 @@ yylex ()
     /* We must have come across a bad character (e.g. ';').  */
     error ("Invalid character '%c' in expression.", c);
 
-  /* Tokens containing spaces.  */
-  for (i = 0; i < sizeof tokentab_big / sizeof tokentab_big[0]; i++)
-    if (strncmp (tokstart, tokentab_big[i].operator, tokentab_big[i].token) == 0)
-      {
-       lexptr += tokentab_big[i].token;
-       yylval.lval = tokentab_big[i].opcode;
-       if (yylval.lval == D_COMP_CONSTRUCTION_VTABLE)
-         return CONSTRUCTION_VTABLE;
-       else if (yylval.lval == GLOBAL_CONSTRUCTORS
-                || yylval.lval == GLOBAL_DESTRUCTORS)
-         {
-           /* Skip the trailing space, find the end of the symbol.  */
-           char *p = symbol_end (lexptr + 1);
-           yylval.typed_val_int.val = yylval.lval;
-           yylval.typed_val_int.type = d_make_name (di, lexptr + 1, p - (lexptr + 1));
-           lexptr = p;
-           return GLOBAL;
-         }
-       return DEMANGLER_SPECIAL;
-      }  
-
   /* It's a name.  See how long it is.  */
   namelen = 0;
   for (c = tokstart[namelen];
@@ -1923,8 +1750,6 @@ yylex ()
 
   lexptr += namelen;
 
-  tryname:
-
   /* Catch specific keywords.  Should be done with a data structure.  */
   switch (namelen)
     {
@@ -1933,6 +1758,11 @@ yylex ()
         return REINTERPRET_CAST;
       break;
     case 12:
+      if (strncmp (tokstart, "construction vtable for", 23) == 0)
+       {
+         lexptr = tokstart + 23;
+         return CONSTRUCTION_VTABLE;
+       }
       if (strncmp (tokstart, "dynamic_cast", 12) == 0)
         return DYNAMIC_CAST;
       break;
@@ -1940,7 +1770,14 @@ yylex ()
       if (strncmp (tokstart, "static_cast", 11) == 0)
         return STATIC_CAST;
       break;
+    case 9:
+      HANDLE_SPECIAL ("covariant return thunk to", 25, D_COMP_COVARIANT_THUNK);
+      HANDLE_SPECIAL ("reference temporary for", 23, D_COMP_REFTEMP);
+      break;
     case 8:
+      HANDLE_SPECIAL ("typeinfo for", 12, D_COMP_TYPEINFO);
+      HANDLE_SPECIAL ("typeinfo fn for", 15, D_COMP_TYPEINFO_FN);
+      HANDLE_SPECIAL ("typeinfo name for", 17, D_COMP_TYPEINFO_NAME);
       if (strncmp (tokstart, "operator", 8) == 0)
        return OPERATOR;
       if (strncmp (tokstart, "restrict", 8) == 0)
@@ -1953,10 +1790,35 @@ yylex ()
        return VOLATILE_KEYWORD;
       break;
     case 7:
+      HANDLE_SPECIAL ("virtual thunk to", 16, D_COMP_VIRTUAL_THUNK);
       if (strncmp (tokstart, "wchar_t", 7) == 0)
        return WCHAR_T;
       break;
     case 6:
+      if (strncmp (tokstart, "global constructors keyed to", 28) == 0)
+       {
+         char *p;
+         lexptr = tokstart + 28;
+         yylval.typed_val_int.val = GLOBAL_CONSTRUCTORS;
+         /* Skip the trailing space, find the end of the symbol.  */
+         p = symbol_end (lexptr + 1);
+         yylval.typed_val_int.type = d_make_name (di, lexptr + 1, p - (lexptr + 1));
+         lexptr = p;
+         return GLOBAL;
+       }
+      if (strncmp (tokstart, "global destructors keyed to", 27) == 0)
+       {
+         char *p;
+         lexptr = tokstart + 27;
+         yylval.typed_val_int.val = GLOBAL_DESTRUCTORS;
+         /* Skip the trailing space, find the end of the symbol.  */
+         p = symbol_end (lexptr + 1);
+         yylval.typed_val_int.type = d_make_name (di, lexptr + 1, p - (lexptr + 1));
+         lexptr = p;
+         return GLOBAL;
+       }
+
+      HANDLE_SPECIAL ("vtable for", 10, D_COMP_VTABLE);
       if (strncmp (tokstart, "delete", 6) == 0)
        return DELETE;
       if (strncmp (tokstart, "struct", 6) == 0)
@@ -1969,6 +1831,7 @@ yylex ()
        return DOUBLE_KEYWORD;
       break;
     case 5:
+      HANDLE_SPECIAL ("guard variable for", 18, D_COMP_GUARD);
       if (strncmp (tokstart, "false", 5) == 0)
        return FALSEKEYWORD;
       if (strncmp (tokstart, "class", 5) == 0)
@@ -1997,6 +1860,8 @@ yylex ()
        return TRUEKEYWORD;
       break;
     case 3:
+      HANDLE_SPECIAL ("VTT for", 7, D_COMP_VTT);
+      HANDLE_SPECIAL ("non-virtual thunk to", 20, D_COMP_THUNK);
       if (strncmp (tokstart, "new", 3) == 0)
        return NEW;
       if (strncmp (tokstart, "int", 3) == 0)