Hi,

based on the GCC libcc1 plugin GDB will implement GDB command 'compile print'
equivalent to default 'print' but evaluating the expression by GCC:
        https://github.com/tromey/gdb/tree/pmuldoon/compile/print

It is currently done by compiling a .c->.o file and checking its DWARF for the
type and size of the resulting object to print.

But GDB features a useful custom expression operator '@':
        https://sourceware.org/gdb/onlinedocs/gdb/Arrays.html

I have problems implementing '@' into GCC, could you suggest at which place
should I call build_array_type_nelts()?  Or is it the right way at all?

Testing it on a sample code - it should return 2:
        int a[]={1,2,3};int main(void){ return (*a@3)[1]; }

Proper overloading of '@' to keep it working for ObjC and/or enabling '@' only
for libcc1 I find currently off-topic.

With both c_fully_fold_internal() and gimplify_modify_expr_rhs() hooks #if 0-ed
(as they are in the attached patch) GCC crashes on infinite loop:
        <-gimplify_expr<-gimplify_modify_expr<-gimplify_expr<-gimplify_stmt<-
        <-gimplify_and_add<-internal_get_tmp_var<-get_formal_tmp_var<-



Thanks,
Jan
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 8c23e09..69fa054 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -1289,6 +1289,25 @@ c_fully_fold_internal (tree expr, bool in_init, bool 
*maybe_const_operands,
       ret = fold (ret);
       goto out;
 
+#if 0 // it would crash at array_ref_low_bound()'s first line
+    case ATSIGN_EXPR:
+      orig_op0 = op0 = TREE_OPERAND (expr, 0);
+      orig_op1 = op1 = TREE_OPERAND (expr, 1);
+#if 0 // not needed
+      op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
+                                  maybe_const_itself);
+      STRIP_TYPE_NOPS (op0);
+      op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
+                                  maybe_const_itself);
+      STRIP_TYPE_NOPS (op1);
+#endif
+      ret = build_array_type_nelts (TREE_TYPE (op0), tree_to_uhwi (op1));
+#if 0 // not needed
+      ret = fold (ret);
+#endif
+      goto out;
+#endif
+
     case COMPOUND_EXPR:
     case MODIFY_EXPR:
     case PREDECREMENT_EXPR:
@@ -4078,6 +4097,8 @@ binary_op_error (location_t location, enum tree_code code,
       opname = "||"; break;
     case BIT_XOR_EXPR:
       opname = "^"; break;
+    case ATSIGN_EXPR:
+      opname = "@"; break;
     default:
       gcc_unreachable ();
     }
diff --git a/gcc/c-family/c-lex.c b/gcc/c-family/c-lex.c
index bb55be8..ad8b82f 100644
--- a/gcc/c-family/c-lex.c
+++ b/gcc/c-family/c-lex.c
@@ -468,6 +468,8 @@ c_lex_with_flags (tree *value, location_t *loc, unsigned 
char *cpp_flags,
       break;
 
     case CPP_ATSIGN:
+      *value = NULL_TREE;
+      break;
       /* An @ may give the next token special significance in Objective-C.  */
       if (c_dialect_objc ())
        {
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index ceb9e1a..5d5a0a8 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -1173,6 +1173,7 @@ enum c_parser_prec {
   PREC_EQ,
   PREC_REL,
   PREC_SHIFT,
+  PREC_ATSIGN,
   PREC_ADD,
   PREC_MULT,
   NUM_PRECS
@@ -6283,6 +6284,10 @@ c_parser_binary_expression (c_parser *parser, struct 
c_expr *after,
          oprec = PREC_ADD;
          ocode = MINUS_EXPR;
          break;
+       case CPP_ATSIGN:
+         oprec = PREC_ATSIGN;
+         ocode = ATSIGN_EXPR;
+         break;
        case CPP_LSHIFT:
          oprec = PREC_SHIFT;
          ocode = LSHIFT_EXPR;
@@ -7082,6 +7087,10 @@ c_parser_postfix_expression (c_parser *parser)
   expr.original_type = NULL;
   switch (c_parser_peek_token (parser)->type)
     {
+    case CPP_ATSIGN:
+      error_at (loc, "gdbjit hit");
+      expr.value = error_mark_node;
+      break;
     case CPP_NUMBER:
       expr.value = c_parser_peek_token (parser)->value;
       loc = c_parser_peek_token (parser)->location;
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index a3a9c77..0c2f1f9 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -10949,6 +10949,14 @@ build_binary_op (location_t location, enum tree_code 
code,
        maybe_warn_bool_compare (location, code, orig_op0, orig_op1);
       break;
 
+    case ATSIGN_EXPR:
+      if (TREE_CODE (orig_op1) == INTEGER_CST)
+       {
+         result_type = build_array_type_nelts (type0, tree_to_uhwi (orig_op1));
+         converted = 1;
+       }
+      break;
+
     default:
       gcc_unreachable ();
     }
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index d822913..b4027dc 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -4418,6 +4418,12 @@ gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, 
tree *to_p,
                return GS_OK;
              }
          }
+         break;
+       
+#if 0 // it would get hit
+       case ATSIGN_EXPR:
+         gcc_unreachable ();
+#endif
 
        default:
          break;
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index d7c049f..cf00457 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -2037,6 +2037,7 @@ dump_generic_node (pretty_printer *pp, tree node, int 
spc, int flags,
     case LTGT_EXPR:
     case ORDERED_EXPR:
     case UNORDERED_EXPR:
+    case ATSIGN_EXPR:
       {
        const char *op = op_symbol (node);
        op0 = TREE_OPERAND (node, 0);
@@ -3432,6 +3433,9 @@ op_symbol_code (enum tree_code code)
     case MIN_EXPR:
       return "min";
 
+    case ATSIGN_EXPR:
+      return "@";
+
     default:
       return "<<< ??? >>>";
     }
diff --git a/gcc/tree.def b/gcc/tree.def
index b4b4164..a2d28ce 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -669,6 +669,9 @@ DEFTREECODE (PLUS_EXPR, "plus_expr", tcc_binary, 2)
 DEFTREECODE (MINUS_EXPR, "minus_expr", tcc_binary, 2)
 DEFTREECODE (MULT_EXPR, "mult_expr", tcc_binary, 2)
 
+/* GDB '@' operator.  */
+DEFTREECODE (ATSIGN_EXPR, "atsign_expr", tcc_binary, 2)
+
 /* Pointer addition.  The first operand is always a pointer and the
    second operand is an integer of type sizetype.  */
 DEFTREECODE (POINTER_PLUS_EXPR, "pointer_plus_expr", tcc_binary, 2)

Reply via email to