Fri Nov 21 02:19:57 1997 Geoffrey Noer <noer@cygnus.com>
[deliverable/binutils-gdb.git] / gdb / expprint.c
index 5a6986e992a28a0f3d28fdfc8d5b4fc34cfe000c..4effea27c2483dc0d09049c7acd79dc66c04e07d 100644 (file)
@@ -15,7 +15,7 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "defs.h"
 #include "symtab.h"
@@ -28,15 +28,12 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 /* Prototypes for local functions */
 
 static void
-print_subexp PARAMS ((struct expression *, int *, FILE *, enum precedence));
-
-static void
-print_simple_m2_func PARAMS ((char *, struct expression *, int *, FILE *));
+print_subexp PARAMS ((struct expression *, int *, GDB_FILE *, enum precedence));
 
 void
 print_expression (exp, stream)
      struct expression *exp;
-     FILE *stream;
+     GDB_FILE *stream;
 {
   int pc = 0;
   print_subexp (exp, &pc, stream, PREC_NULL);
@@ -51,7 +48,7 @@ static void
 print_subexp (exp, pos, stream, prec)
      register struct expression *exp;
      register int *pos;
-     FILE *stream;
+     GDB_FILE *stream;
      enum precedence prec;
 {
   register unsigned tem;
@@ -61,10 +58,11 @@ print_subexp (exp, pos, stream, prec)
   register char *op_str;
   int assign_modify = 0;
   enum exp_opcode opcode;
-  enum precedence myprec;
+  enum precedence myprec = PREC_NULL;
   /* Set to 1 for a right-associative operator.  */
-  int assoc;
-  value val;
+  int assoc = 0;
+  value_ptr val;
+  char *tempstr = NULL;
 
   op_print_tab = exp->language_defn->la_op_print_tab;
   pc = (*pos)++;
@@ -76,13 +74,10 @@ print_subexp (exp, pos, stream, prec)
     case OP_SCOPE:
       myprec = PREC_PREFIX;
       assoc = 0;
-      (*pos) += 3;
-      print_subexp (exp, pos, stream,
-                   (enum precedence) ((int) myprec + assoc));
-      fputs_filtered (" :: ", stream);
+      fputs_filtered (type_name_no_tag (exp->elts[pc + 1].type), stream);
+      fputs_filtered ("::", stream);
       nargs = longest_to_int (exp->elts[pc + 2].longconst);
-      (*pos) += 2 + (nargs + sizeof (union exp_element)) / sizeof (union exp_element);
-
+      (*pos) += 4 + BYTES_TO_EXP_ELEM (nargs + 1);
       fputs_filtered (&exp->elts[pc + 3].string, stream);
       return;
 
@@ -101,8 +96,19 @@ print_subexp (exp, pos, stream, prec)
       return;
 
     case OP_VAR_VALUE:
-      (*pos) += 2;
-      fputs_filtered (SYMBOL_SOURCE_NAME (exp->elts[pc + 1].symbol), stream);
+      {
+       struct block *b;
+       (*pos) += 3;
+       b = exp->elts[pc + 1].block;
+       if (b != NULL
+           && BLOCK_FUNCTION (b) != NULL
+           && SYMBOL_SOURCE_NAME (BLOCK_FUNCTION (b)) != NULL)
+         {
+           fputs_filtered (SYMBOL_SOURCE_NAME (BLOCK_FUNCTION (b)), stream);
+           fputs_filtered ("::", stream);
+         }
+       fputs_filtered (SYMBOL_SOURCE_NAME (exp->elts[pc + 2].symbol), stream);
+      }
       return;
 
     case OP_LAST:
@@ -144,16 +150,113 @@ print_subexp (exp, pos, stream, prec)
       fputs_filtered (")", stream);
       return;
 
+    case OP_NAME:
+    case OP_EXPRSTRING:
+      nargs = longest_to_int (exp -> elts[pc + 1].longconst);
+      (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1);
+      fputs_filtered (&exp->elts[pc + 2].string, stream);
+      return;
+
     case OP_STRING:
       nargs = longest_to_int (exp -> elts[pc + 1].longconst);
-      (*pos) += 3 + (nargs + sizeof (union exp_element))
-       / sizeof (union exp_element);
+      (*pos) += 3 + BYTES_TO_EXP_ELEM (nargs + 1);
       /* LA_PRINT_STRING will print using the current repeat count threshold.
         If necessary, we can temporarily set it to zero, or pass it as an
         additional parameter to LA_PRINT_STRING.  -fnf */
       LA_PRINT_STRING (stream, &exp->elts[pc + 2].string, nargs, 0);
       return;
 
+    case OP_BITSTRING:
+      nargs = longest_to_int (exp -> elts[pc + 1].longconst);
+      (*pos)
+       += 3 + BYTES_TO_EXP_ELEM ((nargs + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT);
+      fprintf (stream, "B'<unimplemented>'");
+      return;
+
+    case OP_ARRAY:
+      (*pos) += 3;
+      nargs = longest_to_int (exp->elts[pc + 2].longconst);
+      nargs -= longest_to_int (exp->elts[pc + 1].longconst);
+      nargs++;
+      tem = 0;
+      if (exp->elts[pc + 4].opcode == OP_LONG
+         && exp->elts[pc + 5].type == builtin_type_char
+         && exp->language_defn->la_language == language_c)
+       {
+         /* Attempt to print C character arrays using string syntax.
+            Walk through the args, picking up one character from each
+            of the OP_LONG expression elements.  If any array element
+            does not match our expection of what we should find for
+            a simple string, revert back to array printing.  Note that
+            the last expression element is an explicit null terminator
+            byte, which doesn't get printed. */
+         tempstr = alloca (nargs);
+         pc += 4;
+         while (tem < nargs)
+           {
+             if (exp->elts[pc].opcode != OP_LONG
+                 || exp->elts[pc + 1].type != builtin_type_char)
+               {
+                 /* Not a simple array of char, use regular array printing. */
+                 tem = 0;
+                 break;
+               }
+             else
+               {
+                 tempstr[tem++] =
+                   longest_to_int (exp->elts[pc + 2].longconst);
+                 pc += 4;
+               }
+           }
+       }
+      if (tem > 0)
+       {
+         LA_PRINT_STRING (stream, tempstr, nargs - 1, 0);
+         (*pos) = pc;
+       }
+      else
+       {
+         int is_chill = exp->language_defn->la_language == language_chill;
+         fputs_filtered (is_chill ? " [" : " {", stream);
+         for (tem = 0; tem < nargs; tem++)
+           {
+             if (tem != 0)
+               {
+                 fputs_filtered (", ", stream);
+               }
+             print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
+           }
+         fputs_filtered (is_chill ? "]" : "}", stream);
+       }
+      return;
+
+    case OP_LABELED:
+      tem = longest_to_int (exp->elts[pc + 1].longconst);
+      (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
+
+      if (exp->language_defn->la_language == language_chill)
+       {
+         fputs_filtered (".", stream);
+         fputs_filtered (&exp->elts[pc + 2].string, stream);
+         fputs_filtered (exp->elts[*pos].opcode == OP_LABELED ? ", "
+                         : ": ",
+                         stream);
+       }
+      else
+       {
+         /* Gcc support both these syntaxes.  Unsure which is preferred.  */
+#if 1
+         fputs_filtered (&exp->elts[pc + 2].string, stream);
+         fputs_filtered (": ", stream);
+#else
+         fputs_filtered (".", stream);
+         fputs_filtered (&exp->elts[pc + 2].string, stream);
+         fputs_filtered ("=", stream);
+#endif
+       }
+      print_subexp (exp, pos, stream, PREC_SUFFIX);
+      return;
+
     case TERNOP_COND:
       if ((int) prec > (int) PREC_COMMA)
        fputs_filtered ("(", stream);
@@ -170,9 +273,19 @@ print_subexp (exp, pos, stream, prec)
        fputs_filtered (")", stream);
       return;
 
+    case TERNOP_SLICE:
+    case TERNOP_SLICE_COUNT:
+      print_subexp (exp, pos, stream, PREC_SUFFIX);
+      fputs_filtered ("(", stream);
+      print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
+      fputs_filtered (opcode == TERNOP_SLICE ? " : " : " UP ", stream);
+      print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
+      fputs_filtered (")", stream);
+      return;
+
     case STRUCTOP_STRUCT:
       tem = longest_to_int (exp->elts[pc + 1].longconst);
-      (*pos) += 3 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
+      (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
       print_subexp (exp, pos, stream, PREC_SUFFIX);
       fputs_filtered (".", stream);
       fputs_filtered (&exp->elts[pc + 2].string, stream);
@@ -181,12 +294,25 @@ print_subexp (exp, pos, stream, prec)
     /* Will not occur for Modula-2 */
     case STRUCTOP_PTR:
       tem = longest_to_int (exp->elts[pc + 1].longconst);
-      (*pos) += 3 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
+      (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
       print_subexp (exp, pos, stream, PREC_SUFFIX);
       fputs_filtered ("->", stream);
       fputs_filtered (&exp->elts[pc + 2].string, stream);
       return;
 
+/* start-sanitize-gm */
+#ifdef GENERAL_MAGIC_HACKS
+    case STRUCTOP_FIELD:
+      tem = longest_to_int (exp->elts[pc + 1].longconst);
+      (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
+      print_subexp (exp, pos, stream, PREC_SUFFIX);
+      fputs_filtered ("@", stream);
+      fputs_filtered (&exp->elts[pc + 2].string, stream);
+      return;
+
+#endif /* GENERAL_MAGIC_HACKS */
+/* end-sanitize-gm */
+
     case BINOP_SUBSCRIPT:
       print_subexp (exp, pos, stream, PREC_SUFFIX);
       fputs_filtered ("[", stream);
@@ -253,6 +379,10 @@ print_subexp (exp, pos, stream, prec)
            op_str = op_print_tab[tem].string;
            break;
          }
+      if (op_print_tab[tem].opcode != opcode)
+       /* Not found; don't try to keep going because we don't know how
+          to interpret further elements.  */
+       error ("Invalid expression");
       break;
 
     /* C++ ops */
@@ -268,63 +398,23 @@ print_subexp (exp, pos, stream, prec)
       (*pos) += 2;
       nargs = longest_to_int (exp->elts[pc + 1].longconst);
       print_subexp (exp, pos, stream, PREC_SUFFIX);
-      fprintf (stream, " [");
+      fprintf_unfiltered (stream, " [");
       for (tem = 0; tem < nargs; tem++)
        {
          if (tem != 0)
-           fprintf (stream, ", ");
+           fprintf_unfiltered (stream, ", ");
          print_subexp (exp, pos, stream, PREC_ABOVE_COMMA);
        }
-      fprintf (stream, "]");
+      fprintf_unfiltered (stream, "]");
       return;
 
     case BINOP_VAL:
       (*pos)+=2;
-      fprintf(stream,"VAL(");
+      fprintf_unfiltered(stream,"VAL(");
       type_print(exp->elts[pc+1].type,"",stream,0);
-      fprintf(stream,",");
+      fprintf_unfiltered(stream,",");
       print_subexp(exp,pos,stream,PREC_PREFIX);
-      fprintf(stream,")");
-      return;
-
-    case UNOP_CAP:
-      print_simple_m2_func("CAP",exp,pos,stream);
-      return;
-
-    case UNOP_CHR:
-      print_simple_m2_func("CHR",exp,pos,stream);
-      return;
-
-    case UNOP_ORD:
-      print_simple_m2_func("ORD",exp,pos,stream);
-      return;
-      
-    case UNOP_ABS:
-      print_simple_m2_func("ABS",exp,pos,stream);
-      return;
-
-    case UNOP_FLOAT:
-      print_simple_m2_func("FLOAT",exp,pos,stream);
-      return;
-
-    case UNOP_HIGH:
-      print_simple_m2_func("HIGH",exp,pos,stream);
-      return;
-
-    case UNOP_MAX:
-      print_simple_m2_func("MAX",exp,pos,stream);
-      return;
-
-    case UNOP_MIN:
-      print_simple_m2_func("MIN",exp,pos,stream);
-      return;
-
-    case UNOP_ODD:
-      print_simple_m2_func("ODD",exp,pos,stream);
-      return;
-
-    case UNOP_TRUNC:
-      print_simple_m2_func("TRUNC",exp,pos,stream);
+      fprintf_unfiltered(stream,")");
       return;
       
     case BINOP_INCL:
@@ -343,15 +433,34 @@ print_subexp (exp, pos, stream, prec)
            assoc = op_print_tab[tem].right_assoc;
            break;
          }
+      if (op_print_tab[tem].opcode != opcode)
+       /* Not found; don't try to keep going because we don't know how
+          to interpret further elements.  For example, this happens
+          if opcode is OP_TYPE.  */
+       error ("Invalid expression");
    }
 
+  /* Note that PREC_BUILTIN will always emit parentheses. */
   if ((int) myprec < (int) prec)
     fputs_filtered ("(", stream);
   if ((int) opcode > (int) BINOP_END)
     {
-      /* Unary prefix operator.  */
-      fputs_filtered (op_str, stream);
-      print_subexp (exp, pos, stream, PREC_PREFIX);
+      if (assoc)
+       {
+         /* Unary postfix operator.  */
+         print_subexp (exp, pos, stream, PREC_SUFFIX);
+         fputs_filtered (op_str, stream);
+       }
+      else
+       {
+         /* Unary prefix operator.  */
+         fputs_filtered (op_str, stream);
+         if (myprec == PREC_BUILTIN_FUNCTION)
+           fputs_filtered ("(", stream);
+         print_subexp (exp, pos, stream, PREC_PREFIX);
+         if (myprec == PREC_BUILTIN_FUNCTION)
+           fputs_filtered (")", stream);
+       }
     }
   else
     {
@@ -379,23 +488,6 @@ print_subexp (exp, pos, stream, prec)
     fputs_filtered (")", stream);
 }
 
-/* Print out something of the form <s>(<arg>).
-   This is used to print out some builtin Modula-2
-   functions.
-   FIXME:  There is probably some way to get the precedence
-   rules to do this (print a unary operand with parens around it).  */
-static void
-print_simple_m2_func(s,exp,pos,stream)
-   char *s;
-   register struct expression *exp;
-   register int *pos;
-   FILE *stream;
-{
-   fprintf(stream,"%s(",s);
-   print_subexp(exp,pos,stream,PREC_PREFIX);
-   fprintf(stream,")");
-}
-   
 /* Return the operator corresponding to opcode OP as
    a string.   NULL indicates that the opcode was not found in the
    current language table.  */
@@ -421,7 +513,7 @@ op_string(op)
 void
 dump_expression (exp, stream, note)
      struct expression *exp;
-     FILE *stream;
+     GDB_FILE *stream;
      char *note;
 {
   int elt;
@@ -429,7 +521,9 @@ dump_expression (exp, stream, note)
   char *eltscan;
   int eltsize;
 
-  fprintf_filtered (stream, "Dump of expression @ 0x%x, %s:\n", exp, note);
+  fprintf_filtered (stream, "Dump of expression @ ");
+  gdb_print_address (exp, stream);
+  fprintf_filtered (stream, ", %s:\n", note);
   fprintf_filtered (stream, "\tLanguage %s, %d elements, %d bytes each.\n",
                    exp->language_defn->la_name, exp -> nelts,
                    sizeof (union exp_element));
@@ -447,6 +541,7 @@ dump_expression (exp, stream, note)
          case BINOP_MUL: opcode_name = "BINOP_MUL"; break;
          case BINOP_DIV: opcode_name = "BINOP_DIV"; break;
          case BINOP_REM: opcode_name = "BINOP_REM"; break;
+         case BINOP_MOD: opcode_name = "BINOP_MOD"; break;
          case BINOP_LSH: opcode_name = "BINOP_LSH"; break;
          case BINOP_RSH: opcode_name = "BINOP_RSH"; break;
          case BINOP_LOGICAL_AND: opcode_name = "BINOP_LOGICAL_AND"; break;
@@ -476,8 +571,11 @@ dump_expression (exp, stream, note)
          case BINOP_VAL: opcode_name = "BINOP_VAL"; break;
          case BINOP_INCL: opcode_name = "BINOP_INCL"; break;
          case BINOP_EXCL: opcode_name = "BINOP_EXCL"; break;
+         case BINOP_CONCAT: opcode_name = "BINOP_CONCAT"; break;
          case BINOP_END: opcode_name = "BINOP_END"; break;
          case TERNOP_COND: opcode_name = "TERNOP_COND"; break;
+         case TERNOP_SLICE: opcode_name = "TERNOP_SLICE"; break;
+         case TERNOP_SLICE_COUNT: opcode_name = "TERNOP_SLICE_COUNT"; break;
          case OP_LONG: opcode_name = "OP_LONG"; break;
          case OP_DOUBLE: opcode_name = "OP_DOUBLE"; break;
          case OP_VAR_VALUE: opcode_name = "OP_VAR_VALUE"; break;
@@ -486,6 +584,8 @@ dump_expression (exp, stream, note)
          case OP_INTERNALVAR: opcode_name = "OP_INTERNALVAR"; break;
          case OP_FUNCALL: opcode_name = "OP_FUNCALL"; break;
          case OP_STRING: opcode_name = "OP_STRING"; break;
+         case OP_BITSTRING: opcode_name = "OP_BITSTRING"; break;
+         case OP_ARRAY: opcode_name = "OP_ARRAY"; break;
          case UNOP_CAST: opcode_name = "UNOP_CAST"; break;
          case UNOP_MEMVAL: opcode_name = "UNOP_MEMVAL"; break;
          case UNOP_NEG: opcode_name = "UNOP_NEG"; break;
@@ -498,6 +598,9 @@ dump_expression (exp, stream, note)
          case UNOP_PREDECREMENT: opcode_name = "UNOP_PREDECREMENT"; break;
          case UNOP_POSTDECREMENT: opcode_name = "UNOP_POSTDECREMENT"; break;
          case UNOP_SIZEOF: opcode_name = "UNOP_SIZEOF"; break;
+         case UNOP_LOWER: opcode_name = "UNOP_LOWER"; break;
+         case UNOP_UPPER: opcode_name = "UNOP_UPPER"; break;
+         case UNOP_LENGTH: opcode_name = "UNOP_LENGTH"; break;
          case UNOP_PLUS: opcode_name = "UNOP_PLUS"; break;
          case UNOP_CAP: opcode_name = "UNOP_CAP"; break;
          case UNOP_CHR: opcode_name = "UNOP_CHR"; break;
@@ -513,13 +616,19 @@ dump_expression (exp, stream, note)
          case OP_M2_STRING: opcode_name = "OP_M2_STRING"; break;
          case STRUCTOP_STRUCT: opcode_name = "STRUCTOP_STRUCT"; break;
          case STRUCTOP_PTR: opcode_name = "STRUCTOP_PTR"; break;
+/* start-sanitize-gm */
+#ifdef GENERAL_MAGIC_HACKS
++        case STRUCTOP_FIELD: opcode_name = "STRUCTOP_FIELD"; break;
+#endif /* GENERAL_MAGIC_HACKS */
+/* end-sanitize-gm */
          case OP_THIS: opcode_name = "OP_THIS"; break;
          case OP_SCOPE: opcode_name = "OP_SCOPE"; break;
          case OP_TYPE: opcode_name = "OP_TYPE"; break;
+         case OP_LABELED: opcode_name = "OP_LABELED"; break;
        }
       fprintf_filtered (stream, "%20s  ", opcode_name);
       fprintf_filtered (stream,
-#if defined (LONG_LONG)
+#if defined (PRINTF_HAS_LONG_LONG)
                        "%ll16x  ",
 #else
                        "%l16x  ",
This page took 0.027736 seconds and 4 git commands to generate.