* defs.h (HOST_CHAR_BIT): New macro, defaults to either CHAR_BIT
authorFred Fish <fnf@specifix.com>
Wed, 6 Jan 1993 16:52:10 +0000 (16:52 +0000)
committerFred Fish <fnf@specifix.com>
Wed, 6 Jan 1993 16:52:10 +0000 (16:52 +0000)
from a configuration file (typically including <limits.h>), or to
TARGET_CHAR_BIT if CHAR_BIT is not defined.
* eval.c (evaluate_subexp):  Use new BYTES_TO_EXP_ELEM macro.
* eval.c (evaluate_subexp):  Add case for OP_BITSTRING.
* expprint.c (print_subexp):  Use new BYTES_TO_EXP_ELEM macro.
* exppritn.c (print_subexp, dump_expression):  Add case for
OP_BITSTRING.
* expression.h (OP_BITSTRING):  New expression element type for
packed bitstrings.
* expression.h (EXP_ELEM_TO_BYTES, BYTES_TO_EXP_ELEM):  New
macros to convert between number of expression elements and bytes
to store that many elements.
* i960-tdep.c (leafproc_return):  Use new macros to access
minimal symbol name and address fields.
* m88k-pinsn.c (sprint_address):  Use new macros to access
minimal symbol name and address fields.
* nindy-tdep.c (nindy_frame_chain_valid):  Use new macro to access
minimal symbol address field.
* parse.c (write_exp_elt, write_exp_string, prefixify_expression,
parse_exp_1):  Use new EXP_ELEM_TO_BYTES macro.
* parse.c (write_exp_string, length_of_subexp, prefixify_expression):
Use new BYTES_TO_EXP_ELEM macro.
* parse.c (write_exp_bitstring):  New function to write packed
bitstrings into the expression element vector.
* parse.c (length_of_subexp, prefixify_subexp):  Add case for
OP_BITSTRING.
* parser-defs.h (struct stoken):  Document that it is used for
OP_BITSTRING as well as OP_STRING.
* parser-defs.h (write_exp_bitstring):  Add prototype.
**** start-sanitize-chill ****
* ch-exp.y (BIT_STRING_LITERAL):  Change token type to sval.
* ch-exp.y (NUM, PRED, SUCC, ABS, CARD, MAX, MIN, SIZE, UPPER,
LOWER, LENGTH):  New tokens for keywords.
* ch-exp.y (chill_value_built_in_routine_call, mode_argument,
upper_lower_argument, length_argument, array_mode_name,
string_mode_name, variant_structure_mode_name):  New non-terminals
and productions.
* ch-exp.y (literal):  Useful production for BIT_STRING_LITERAL.
* ch-exp.y (match_bitstring_literal):  New lexer support function
to recognize bitstring literals.
* ch-exp.y (tokentab6):  New token table for 6 character keywords.
* ch-exp.y (tokentab5):  Add LOWER, UPPER.
* ch-exp.y (tokentab4):  Add PRED, SUCC, CARD, SIZE.
* ch-exp.y (tokentab3):  Add NUM, ABS, MIN, MAX.
* ch-exp.y (yylex):  Check tokentab6.
* ch-exp.y (yylex):  Call match_bitstring_literal.
**** end-sanitize-chill ****

gdb/ChangeLog
gdb/ch-exp.y
gdb/i960-tdep.c
gdb/m88k-pinsn.c
gdb/nindy-tdep.c
gdb/parse.c
gdb/parser-defs.h

index 7f12df60df560f9353805c7d7f3e9f2ea1ee509d..32d7f3610bd746f2977802b566ced6311ca19ebd 100644 (file)
@@ -1,3 +1,54 @@
+Wed Jan  6 08:19:11 1993  Fred Fish  (fnf@cygnus.com)
+
+       * defs.h (HOST_CHAR_BIT):  New macro, defaults to either CHAR_BIT
+       from a configuration file (typically including <limits.h>), or to
+       TARGET_CHAR_BIT if CHAR_BIT is not defined.
+       * eval.c (evaluate_subexp):  Use new BYTES_TO_EXP_ELEM macro.
+       * eval.c (evaluate_subexp):  Add case for OP_BITSTRING.
+       * expprint.c (print_subexp):  Use new BYTES_TO_EXP_ELEM macro.
+       * exppritn.c (print_subexp, dump_expression):  Add case for
+       OP_BITSTRING.
+       * expression.h (OP_BITSTRING):  New expression element type for
+       packed bitstrings.
+       * expression.h (EXP_ELEM_TO_BYTES, BYTES_TO_EXP_ELEM):  New
+       macros to convert between number of expression elements and bytes
+       to store that many elements.
+       * i960-tdep.c (leafproc_return):  Use new macros to access
+       minimal symbol name and address fields.
+       * m88k-pinsn.c (sprint_address):  Use new macros to access
+       minimal symbol name and address fields.
+       * nindy-tdep.c (nindy_frame_chain_valid):  Use new macro to access
+       minimal symbol address field.
+       * parse.c (write_exp_elt, write_exp_string, prefixify_expression,
+       parse_exp_1):  Use new EXP_ELEM_TO_BYTES macro.
+       * parse.c (write_exp_string, length_of_subexp, prefixify_expression):
+       Use new BYTES_TO_EXP_ELEM macro.
+       * parse.c (write_exp_bitstring):  New function to write packed
+       bitstrings into the expression element vector.
+       * parse.c (length_of_subexp, prefixify_subexp):  Add case for
+       OP_BITSTRING.
+       * parser-defs.h (struct stoken):  Document that it is used for
+       OP_BITSTRING as well as OP_STRING.
+       * parser-defs.h (write_exp_bitstring):  Add prototype.
+       **** start-sanitize-chill ****
+       * ch-exp.y (BIT_STRING_LITERAL):  Change token type to sval.
+       * ch-exp.y (NUM, PRED, SUCC, ABS, CARD, MAX, MIN, SIZE, UPPER,
+       LOWER, LENGTH):  New tokens for keywords.
+       * ch-exp.y (chill_value_built_in_routine_call, mode_argument, 
+       upper_lower_argument, length_argument, array_mode_name,
+       string_mode_name, variant_structure_mode_name):  New non-terminals
+       and productions.
+       * ch-exp.y (literal):  Useful production for BIT_STRING_LITERAL.
+       * ch-exp.y (match_bitstring_literal):  New lexer support function
+       to recognize bitstring literals.
+       * ch-exp.y (tokentab6):  New token table for 6 character keywords.
+       * ch-exp.y (tokentab5):  Add LOWER, UPPER.
+       * ch-exp.y (tokentab4):  Add PRED, SUCC, CARD, SIZE.
+       * ch-exp.y (tokentab3):  Add NUM, ABS, MIN, MAX.
+       * ch-exp.y (yylex):  Check tokentab6.
+       * ch-exp.y (yylex):  Call match_bitstring_literal.
+       **** end-sanitize-chill ****
+
 Mon Jan  4 16:54:18 1993  Fred Fish  (fnf@cygnus.com)
 
        * xcoffexec.c (vmap_symtab):  Use new macros to access minimal
index 38211d2f319185ad15f7f286ae0362f24358f4de..40865c0517851076c08706905f71b15f11c2b8ab 100644 (file)
@@ -150,7 +150,7 @@ yyerror PARAMS ((char *));
 %token <voidval>       SET_LITERAL
 %token <voidval>       EMPTINESS_LITERAL
 %token <voidval>       CHARACTER_STRING_LITERAL
-%token <voidval>       BIT_STRING_LITERAL
+%token <sval>          BIT_STRING_LITERAL
 
 %token <voidval>       STRING
 %token <voidval>       CONSTANT
@@ -194,6 +194,17 @@ yyerror PARAMS ((char *));
 %token <voidval>       FI
 %token <voidval>       ELSIF
 %token <voidval>       ILLEGAL_TOKEN
+%token <voidval>       NUM
+%token <voidval>       PRED
+%token <voidval>       SUCC
+%token <voidval>       ABS
+%token <voidval>       CARD
+%token <voidval>       MAX
+%token <voidval>       MIN
+%token <voidval>       SIZE
+%token <voidval>       UPPER
+%token <voidval>       LOWER
+%token <voidval>       LENGTH
 
 /* Tokens which are not Chill tokens used in expressions, but rather GDB
    specific things that we recognize in the same context as Chill tokens
@@ -219,6 +230,7 @@ yyerror PARAMS ((char *));
 %type <voidval>                expression_conversion
 %type <voidval>                value_procedure_call
 %type <voidval>                value_built_in_routine_call
+%type <voidval>                chill_value_built_in_routine_call
 %type <voidval>                start_expression
 %type <voidval>                zero_adic_operator
 %type <voidval>                parenthesised_expression
@@ -254,7 +266,13 @@ yyerror PARAMS ((char *));
 %type <voidval>                first_element
 %type <voidval>                structure_primitive_value
 %type <voidval>                field_name
+%type <voidval>                mode_argument
+%type <voidval>                upper_lower_argument
+%type <voidval>                length_argument
 %type <voidval>                mode_name
+%type <voidval>                array_mode_name
+%type <voidval>                string_mode_name
+%type <voidval>                variant_structure_mode_name
 %type <voidval>                boolean_expression
 %type <voidval>                case_selector_list
 %type <voidval>                subexpression
@@ -479,7 +497,9 @@ literal             :       INTEGER_LITERAL
                        }
                |       BIT_STRING_LITERAL
                        {
-                         $$ = 0;       /* FIXME */
+                         write_exp_elt_opcode (OP_BITSTRING);
+                         write_exp_bitstring ($1);
+                         write_exp_elt_opcode (OP_BITSTRING);
                        }
                ;
 
@@ -564,7 +584,7 @@ value_procedure_call:       FIXME
 
 /* Z.200, 5.2.13 */
 
-value_built_in_routine_call:   FIXME
+value_built_in_routine_call:   chill_value_built_in_routine_call
                        {
                          $$ = 0;       /* FIXME */
                        }
@@ -804,10 +824,107 @@ operand_6        :       POINTER location
 
 /* Z.200, 6.2 */
 
-single_assignment_action :     location GDB_ASSIGNMENT value
+single_assignment_action :
+                       location GDB_ASSIGNMENT value
                        {
                          write_exp_elt_opcode (BINOP_ASSIGN);
                        }
+               ;
+
+/* Z.200, 6.20.3 */
+
+chill_value_built_in_routine_call :
+                       NUM '(' expression ')'
+                       {
+                         $$ = 0;       /* FIXME */
+                       }
+               |       PRED '(' expression ')'
+                       {
+                         $$ = 0;       /* FIXME */
+                       }
+               |       SUCC '(' expression ')'
+                       {
+                         $$ = 0;       /* FIXME */
+                       }
+               |       ABS '(' expression ')'
+                       {
+                         $$ = 0;       /* FIXME */
+                       }
+               |       CARD '(' expression ')'
+                       {
+                         $$ = 0;       /* FIXME */
+                       }
+               |       MAX '(' expression ')'
+                       {
+                         $$ = 0;       /* FIXME */
+                       }
+               |       MIN '(' expression ')'
+                       {
+                         $$ = 0;       /* FIXME */
+                       }
+               |       SIZE '(' location ')'
+                       {
+                         $$ = 0;       /* FIXME */
+                       }
+               |       SIZE '(' mode_argument ')'
+                       {
+                         $$ = 0;       /* FIXME */
+                       }
+               |       UPPER '(' upper_lower_argument ')'
+                       {
+                         $$ = 0;       /* FIXME */
+                       }
+               |       LOWER '(' upper_lower_argument ')'
+                       {
+                         $$ = 0;       /* FIXME */
+                       }
+               |       LENGTH '(' length_argument ')'
+                       {
+                         $$ = 0;       /* FIXME */
+                       }
+               ;
+
+mode_argument :                mode_name
+                       {
+                         $$ = 0;       /* FIXME */
+                       }
+               |       array_mode_name '(' expression ')'
+                       {
+                         $$ = 0;       /* FIXME */
+                       }
+               |       string_mode_name '(' expression ')'
+                       {
+                         $$ = 0;       /* FIXME */
+                       }
+               |       variant_structure_mode_name '(' expression_list ')'
+                       {
+                         $$ = 0;       /* FIXME */
+                       }
+               ;
+
+upper_lower_argument : location
+                       {
+                         $$ = 0;       /* FIXME */
+                       }
+               |       expression
+                       {
+                         $$ = 0;       /* FIXME */
+                       }
+               |       mode_name
+                       {
+                         $$ = 0;       /* FIXME */
+                       }
+               ;
+
+length_argument :      location
+                       {
+                         $$ = 0;       /* FIXME */
+                       }
+               |       expression
+                       {
+                         $$ = 0;       /* FIXME */
+                       }
+               ;
 
 /* Z.200, 12.4.3 */
 /* FIXME:  For now we just accept only a single integer literal. */
@@ -817,6 +934,7 @@ integer_literal_expression:
                        {
                          $$ = 0;
                        }
+               ;
 
 /* Z.200, 12.4.3 */
 
@@ -824,10 +942,14 @@ array_primitive_value :   primitive_value
                        {
                          $$ = 0;
                        }
+               ;
 
 
 /* Things which still need productions... */
 
+array_mode_name                :       FIXME { $$ = 0; }
+string_mode_name       :       FIXME { $$ = 0; }
+variant_structure_mode_name:   FIXME { $$ = 0; }
 synonym_name           :       FIXME { $$ = 0; }
 value_enumeration_name         :       FIXME { $$ = 0; }
 value_do_with_name     :       FIXME { $$ = 0; }
@@ -1247,6 +1369,129 @@ match_integer_literal ()
     }
 }
 
+/* Recognize a bit-string literal, as specified in Z.200 sec 5.2.4.8
+   Note that according to 5.2.4.8, a single "_" is also a valid bit-string
+   literal, however GNU-chill requires there to be at least one "digit"
+   in any bit-string literal. */
+
+static int
+match_bitstring_literal ()
+{
+  char *tokptr = lexptr;
+  int mask;
+  int bitoffset = 0;
+  int bitcount = 0;
+  int base;
+  int digit;
+  static char *tempbuf;
+  static int tempbufsize;
+  static int tempbufindex;
+  
+  /* Look for the required explicit base specifier. */
+  
+  switch (*tokptr++)
+    {
+    case 'b':
+    case 'B':
+      base = 2;
+      break;
+    case 'o':
+    case 'O':
+      base = 8;
+      break;
+    case 'h':
+    case 'H':
+      base = 16;
+      break;
+    default:
+      return (0);
+      break;
+    }
+  
+  /* Ensure that the character after the explicit base is a single quote. */
+  
+  if (*tokptr++ != '\'')
+    {
+      return (0);
+    }
+  
+  while (*tokptr != '\0' && *tokptr != '\'')
+    {
+      digit = tolower (*tokptr);
+      tokptr++;
+      switch (digit)
+       {
+         case '_':
+           continue;
+         case '0':  case '1':  case '2':  case '3':  case '4':
+         case '5':  case '6':  case '7':  case '8':  case '9':
+           digit -= '0';
+           break;
+         case 'a':  case 'b':  case 'c':  case 'd':  case 'e': case 'f':
+           digit -= 'a';
+           digit += 10;
+           break;
+         default:
+           return (0);
+           break;
+       }
+      if (digit >= base)
+       {
+         /* Found something not in domain for current base. */
+         return (0);
+       }
+      else
+       {
+         /* Extract bits from digit, starting with the msbit appropriate for
+            the current base, and packing them into the bitstring byte,
+            starting at the lsbit. */
+         for (mask = (base >> 1); mask > 0; mask >>= 1)
+           {
+             bitcount++;
+             /* Grow the static temp buffer if necessary, including allocating
+                the first one on demand. */
+             if (tempbufindex >= tempbufsize)
+               {
+                 tempbufsize += 64;
+                 if (tempbuf == NULL)
+                   {
+                     tempbuf = (char *) malloc (tempbufsize);
+                   }
+                 else
+                   {
+                     tempbuf = (char *) realloc (tempbuf, tempbufsize);
+                   }
+               }
+             if (digit & mask)
+               {
+                 tempbuf[tempbufindex] |= (1 << bitoffset);
+               }
+             bitoffset++;
+             if (bitoffset == HOST_CHAR_BIT)
+               {
+                 bitoffset = 0;
+                 tempbufindex++;
+               }
+           }
+       }
+    }
+  
+  /* Verify that we consumed everything up to the trailing single quote,
+     and that we found some bits (IE not just underbars). */
+
+  if (*tokptr++ != '\'')
+    {
+      return (0);
+    }
+  else 
+    {
+      yylval.sval.ptr = tempbuf;
+      yylval.sval.length = bitcount;
+      lexptr = tokptr;
+      return (BIT_STRING_LITERAL);
+    }
+}
+
 /* Recognize tokens that start with '$'.  These include:
 
        $regname        A native register name or a "standard
@@ -1378,18 +1623,33 @@ struct token
   int token;
 };
 
+static const struct token tokentab6[] =
+{
+    { "LENGTH", LENGTH }
+};
+
 static const struct token tokentab5[] =
 {
+    { "LOWER", LOWER },
+    { "UPPER", UPPER },
     { "ANDIF", ANDIF }
 };
 
 static const struct token tokentab4[] =
 {
+    { "PRED", PRED },
+    { "SUCC", SUCC },
+    { "CARD", CARD },
+    { "SIZE", SIZE },
     { "ORIF", ORIF }
 };
 
 static const struct token tokentab3[] =
 {
+    { "NUM", NUM },
+    { "ABS", ABS },
+    { "MAX", MAX },
+    { "MIN", MIN },
     { "MOD", MOD },
     { "REM", REM },
     { "NOT", NOT },
@@ -1467,6 +1727,15 @@ yylex ()
            }
          break;
       }
+    /* See if it is a special token of length 6.  */
+    for (i = 0; i < sizeof (tokentab6) / sizeof (tokentab6[0]); i++)
+       {
+           if (STREQN (lexptr, tokentab6[i].operator, 6))
+               {
+                   lexptr += 6;
+                   return (tokentab6[i].token);
+               }
+       }
     /* See if it is a special token of length 5.  */
     for (i = 0; i < sizeof (tokentab5) / sizeof (tokentab5[0]); i++)
        {
@@ -1530,6 +1799,11 @@ yylex ()
     /* Look for a float literal before looking for an integer literal, so
        we match as much of the input stream as possible. */
     token = match_float_literal ();
+    if (token != 0)
+       {
+           return (token);
+       }
+    token = match_bitstring_literal ();
     if (token != 0)
        {
            return (token);
index 7ab0661dda6ae4504c88ce7ee720fbf25582f0b3..0fb444863d4f87f91742066d3f4e3ec50a97eaec 100644 (file)
@@ -472,9 +472,9 @@ leafproc_return (ip)
 
   if ((msymbol = lookup_minimal_symbol_by_pc (ip)) != NULL)
     {
-      if ((p = index (msymbol -> name, '.')) && STREQ (p, ".lf"))
+      if ((p = index (SYMBOL_NAME (msymbol), '.')) && STREQ (p, ".lf"))
        {
-         if (next_insn (msymbol -> address, &insn1, &insn2)
+         if (next_insn (SYMBOL_VALUE_ADDRESS (msymbol), &insn1, &insn2)
              && (insn1 & 0xff87ffff) == 0x5c80161e       /* mov g14, gx */
              && (dst = REG_SRCDST (insn1)) <= G0_REGNUM + 7)
            {
@@ -483,7 +483,8 @@ leafproc_return (ip)
                 the return address from g14; otherwise, read it
                 from the register into which g14 was moved.  */
 
-             return_addr = read_register ((ip == msymbol->address)
+             return_addr =
+                 read_register ((ip == SYMBOL_VALUE_ADDRESS (msymbol))
                                           ? G14_REGNUM : dst);
 
              /* We know we are in a leaf procedure, but we don't know
index 70dee951b75ebc0f3b479f769e4d2473bf487f8c..b1060e01adfbed1c8c0174e9d205afb2bcbe209b 100644 (file)
@@ -343,8 +343,8 @@ void sprint_address (addr, buffer)
            if (msymbol == NULL) return;  /* If nothing comes through, don't
                                             print anything symbolic */
 
-           name = msymbol -> name;
-           name_location = msymbol -> address;
+           name = SYMBOL_NAME (msymbol);
+           name_location = SYMBOL_VALUE_ADDRESS (msymbol);
        } else {
            name = fs->name;
            name_location = BLOCK_START (SYMBOL_BLOCK_VALUE (fs));
index 1d31601b65939817f57dfa9f648b44fafb001406..e2f46aa100d4a99c8aa54afb1db6a08f53b514e4 100644 (file)
@@ -66,7 +66,7 @@ nindy_frame_chain_valid (chain, curframe)
                msymbol = lookup_minimal_symbol (sf, (struct objfile *) NULL);
                if (msymbol == NULL)
                        return 0;
-               a = msymbol -> address;
+               a = SYMBOL_VALUE_ADDRESS (msymbol);
        }
 
        return ( chain != read_memory_integer(a,4) );
index e6e6fff068dc81e17e0dbcbbc922b81b228c40e1..81f79e77ca276163501f38b96731d7fece26b333 100644 (file)
@@ -126,9 +126,9 @@ write_exp_elt (expelt)
   if (expout_ptr >= expout_size)
     {
       expout_size *= 2;
-      expout = (struct expression *) xrealloc ((char *) expout,
-                                              sizeof (struct expression)
-                                              + expout_size * sizeof (union exp_element));
+      expout = (struct expression *)
+       xrealloc ((char *) expout, sizeof (struct expression)
+                 + EXP_ELEM_TO_BYTES (expout_size));
     }
   expout->elts[expout_ptr++] = expelt;
 }
@@ -233,7 +233,7 @@ write_exp_string (str)
      at each end to record the actual string length (not including the
      null byte terminator). */
 
-  lenelt = 2 + (len + sizeof (union exp_element)) / sizeof (union exp_element);
+  lenelt = 2 + BYTES_TO_EXP_ELEM (len + 1);
 
   /* Ensure that we have enough available expression elements to store
      everything. */
@@ -243,7 +243,7 @@ write_exp_string (str)
       expout_size = max (expout_size * 2, expout_ptr + lenelt + 10);
       expout = (struct expression *)
        xrealloc ((char *) expout, (sizeof (struct expression)
-                          + (expout_size * sizeof (union exp_element))));
+                                   + EXP_ELEM_TO_BYTES (expout_size)));
     }
 
   /* Write the leading length expression element (which advances the current
@@ -258,6 +258,54 @@ write_exp_string (str)
   expout_ptr += lenelt - 2;
   write_exp_elt_longcst ((LONGEST) len);
 }
+
+/* Add a bitstring constant to the end of the expression.
+
+   Bitstring constants are stored by first writing an expression element
+   that contains the length of the bitstring (in bits), then stuffing the
+   bitstring constant itself into however many expression elements are
+   needed to hold it, and then writing another expression element that
+   contains the length of the bitstring.  I.E. an expression element at
+   each end of the bitstring records the bitstring length, so you can skip
+   over the expression elements containing the actual bitstring bytes from
+   either end of the bitstring. */
+
+void
+write_exp_bitstring (str)
+     struct stoken str;
+{
+  register int bits = str.length;      /* length in bits */
+  register int len = (bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
+  register int lenelt;
+  register char *strdata;
+
+  /* Compute the number of expression elements required to hold the bitstring,
+     along with one expression element at each end to record the actual
+     bitstring length in bits. */
+
+  lenelt = 2 + BYTES_TO_EXP_ELEM (len);
+
+  /* Ensure that we have enough available expression elements to store
+     everything. */
+
+  if ((expout_ptr + lenelt) >= expout_size)
+    {
+      expout_size = max (expout_size * 2, expout_ptr + lenelt + 10);
+      expout = (struct expression *)
+       xrealloc ((char *) expout, (sizeof (struct expression)
+                                   + EXP_ELEM_TO_BYTES (expout_size)));
+    }
+
+  /* Write the leading length expression element (which advances the current
+     expression element index), then write the bitstring constant, and then
+     write the trailing length expression element. */
+
+  write_exp_elt_longcst ((LONGEST) bits);
+  strdata = (char *) &expout->elts[expout_ptr];
+  memcpy (strdata, str.ptr, len);
+  expout_ptr += lenelt - 2;
+  write_exp_elt_longcst ((LONGEST) bits);
+}
 \f
 /* Return a null-terminated temporary copy of the name
    of a string token.  */
@@ -278,8 +326,8 @@ static void
 prefixify_expression (expr)
      register struct expression *expr;
 {
-  register int len = sizeof (struct expression) +
-                                   expr->nelts * sizeof (union exp_element);
+  register int len =
+    sizeof (struct expression) + EXP_ELEM_TO_BYTES (expr->nelts);
   register struct expression *temp;
   register int inpos = expr->nelts, outpos = 0;
 
@@ -312,9 +360,8 @@ length_of_subexp (expr, endpos)
     {
       /* C++  */
     case OP_SCOPE:
-      oplen = 5 + ((longest_to_int (expr->elts[endpos - 2].longconst)
-                   + sizeof (union exp_element))
-                  / sizeof (union exp_element));
+      oplen = longest_to_int (expr->elts[endpos - 2].longconst);
+      oplen = 5 + BYTES_TO_EXP_ELEM (oplen + 1);
       break;
 
     case OP_LONG:
@@ -366,9 +413,14 @@ length_of_subexp (expr, endpos)
       /* fall through */
     case OP_M2_STRING:
     case OP_STRING:
-      oplen = 4 + ((longest_to_int (expr->elts[endpos - 2].longconst)
-                   + sizeof (union exp_element))
-                  / sizeof (union exp_element));
+      oplen = longest_to_int (expr->elts[endpos - 2].longconst);
+      oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1);
+      break;
+
+    case OP_BITSTRING:
+      oplen = longest_to_int (expr->elts[endpos - 2].longconst);
+      oplen = (oplen + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
+      oplen = 4 + BYTES_TO_EXP_ELEM (oplen);
       break;
 
     case TERNOP_COND:
@@ -430,9 +482,8 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
     {
       /* C++  */
     case OP_SCOPE:
-      oplen = 5 + ((longest_to_int (inexpr->elts[inend - 2].longconst)
-                   + sizeof (union exp_element))
-                  / sizeof (union exp_element));
+      oplen = longest_to_int (inexpr->elts[inend - 2].longconst);
+      oplen = 5 + BYTES_TO_EXP_ELEM (oplen + 1);
       break;
 
     case OP_LONG:
@@ -483,9 +534,14 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
       /* fall through */
     case OP_M2_STRING:
     case OP_STRING:
-      oplen = 4 + ((longest_to_int (inexpr->elts[inend - 2].longconst)
-                   + sizeof (union exp_element))
-                  / sizeof (union exp_element));
+      oplen = longest_to_int (inexpr->elts[inend - 2].longconst);
+      oplen = 4 + BYTES_TO_EXP_ELEM (oplen + 1);
+      break;
+
+    case OP_BITSTRING:
+      oplen = longest_to_int (inexpr->elts[inend - 2].longconst);
+      oplen = (oplen + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
+      oplen = 4 + BYTES_TO_EXP_ELEM (oplen);
       break;
 
     case TERNOP_COND:
@@ -516,7 +572,7 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
      to the beginning of the output.  */
   inend -= oplen;
   memcpy (&outexpr->elts[outbeg], &inexpr->elts[inend],
-                oplen * sizeof (union exp_element));
+         EXP_ELEM_TO_BYTES (oplen));
   outbeg += oplen;
 
   /* Find the lengths of the arg subexpressions.  */
@@ -582,8 +638,7 @@ parse_exp_1 (stringptr, block, comma)
   expout_size = 10;
   expout_ptr = 0;
   expout = (struct expression *)
-    xmalloc (sizeof (struct expression)
-            + expout_size * sizeof (union exp_element));
+    xmalloc (sizeof (struct expression) + EXP_ELEM_TO_BYTES (expout_size));
   expout->language_defn = current_language;
   make_cleanup (free_current_contents, &expout);
 
@@ -599,8 +654,7 @@ parse_exp_1 (stringptr, block, comma)
   expout->nelts = expout_ptr;
   expout = (struct expression *)
     xrealloc ((char *) expout,
-             sizeof (struct expression)
-             + expout_ptr * sizeof (union exp_element));
+             sizeof (struct expression) + EXP_ELEM_TO_BYTES (expout_ptr));;
 
   /* Convert expression from postfix form as generated by yacc
      parser, to a prefix form. */
index 8de2c838f1ca699311c48d52b159fa4a48c80228..098cd39bfa7e74fac4691b81255ff820516af67c 100644 (file)
@@ -60,12 +60,14 @@ struct funcall
 
 struct funcall *funcall_chain;
 
-/* This kind of datum is used to represent the name
-   of a symbol token.  */
+/* A string token, either a char-string or bit-string.  Char-strings are
+   used, for example, for the names of symbols. */
 
 struct stoken
   {
+    /* Pointer to first byte of char-string or first bit of bit-string */
     char *ptr;
+    /* Length of string in bytes for char-string or bits for bit-string */
     int length;
   };
 
@@ -118,6 +120,9 @@ write_exp_elt_intern PARAMS ((struct internalvar *));
 extern void
 write_exp_string PARAMS ((struct stoken));
 
+extern void
+write_exp_bitstring PARAMS ((struct stoken));
+
 extern void
 start_arglist PARAMS ((void));