diff mbox

[patchv2] libcc1: '@' GDB array operator

Message ID 20150531131942.GA7227@host1.jankratochvil.net
State New
Headers show

Commit Message

Jan Kratochvil May 31, 2015, 1:19 p.m. UTC
gcc/c-family/
2015-03-27  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* c-common.c (c_fully_fold_internal, binary_op_error): Add ATSIGN_EXPR.
	* c-lex.c (c_lex_with_flags): Add ATSIGN_EXPR.

gcc/c/
2015-03-27  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* c-parser.c (enum c_parser_prec): Add PREC_ATSIGN.
	(c_parser_binary_expression): Add CPP_ATSIGN.
	* c-typeck.c (build_binary_op): Add ATSIGN_EXPR.

gcc/
2015-03-27  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* tree-pretty-print.c (dump_generic_node, op_symbol_code): Add
	ATSIGN_EXPR.
	* tree.def: Add ATSIGN_EXPR.
---
 gcc/c-family/c-common.c | 21 +++++++++++++++++++++
 gcc/c-family/c-lex.c    |  5 ++++-
 gcc/c/c-parser.c        | 11 +++++++++++
 gcc/c/c-typeck.c        | 13 +++++++++++++
 gcc/tree-pretty-print.c |  4 ++++
 gcc/tree.def            |  3 +++
 6 files changed, 56 insertions(+), 1 deletion(-)
diff mbox

Patch

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 36c984c..5d4f20f 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -1299,6 +1299,25 @@  c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
       ret = fold (ret);
       goto out;
 
+    case ATSIGN_EXPR:
+      op0 = TREE_OPERAND (expr, 0);
+      op1 = TREE_OPERAND (expr, 1);
+      op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands,
+				   maybe_const_itself, for_int_const);
+      STRIP_TYPE_NOPS (op0);
+      op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands,
+				   maybe_const_itself, for_int_const);
+      STRIP_TYPE_NOPS (op1);
+      op1 = decl_constant_value_for_optimization (op1);
+      ret = op0;
+      TREE_TYPE (ret) = build_array_type_nelts (TREE_TYPE (op0),
+						tree_to_uhwi (op1));
+      TREE_READONLY (ret) = TREE_READONLY (expr);
+      TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (expr);
+      TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr);
+      ret = fold (ret);
+      goto out;
+
     case COMPOUND_EXPR:
     case MODIFY_EXPR:
     case PREDECREMENT_EXPR:
@@ -4287,6 +4306,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 85775014..a918fae 100644
--- a/gcc/c-family/c-lex.c
+++ b/gcc/c-family/c-lex.c
@@ -515,7 +515,10 @@  c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
 	  break;
 	}
 
-      /* FALLTHROUGH */
+      /* Create ATSIGN_EXPR for GDB.  */
+      *value = NULL_TREE;
+      break;
+
     case CPP_HASH:
     case CPP_PASTE:
       {
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 965b4b9..08219b9 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
@@ -6329,6 +6330,16 @@  c_parser_binary_expression (c_parser *parser, struct c_expr *after,
 	  oprec = PREC_ADD;
 	  ocode = MINUS_EXPR;
 	  break;
+	case CPP_ATSIGN:
+	  if (!c_binding_oracle)
+	    {
+	      error_at (c_parser_peek_token (parser)->location,
+			"stray %qs in program", "@");
+	      goto out;
+	    }
+	  oprec = PREC_ATSIGN;
+	  ocode = ATSIGN_EXPR;
+	  break;
 	case CPP_LSHIFT:
 	  oprec = PREC_SHIFT;
 	  ocode = LSHIFT_EXPR;
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index f55d4c6..8d28993 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -10977,6 +10977,19 @@  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;
+	}
+      /* Otherwise it would look unclear:
+	 error: invalid operands to binary @ (have ‘int’ and ‘int’)  */
+      error_at (location,
+		"second parameter of operator %<@%> requires constant integer");
+      return error_mark_node;
+
     default:
       gcc_unreachable ();
     }
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index cf875c8..59391eb 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 56580af..eb871fd 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -674,6 +674,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 '@' to create array types.  */
+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)