* ax-gdb.c (gen_expr) <OP_TYPEOF, OP_DECLTYPE>: New cases.
* breakpoint.c (watchpoint_exp_is_const) <OP_TYPEOF,
OP_DECLTYPE>: New cases.
* c-exp.y (TYPEOF, DECLTYPE): New tokens.
(type_exp): Add new productions.
(ident_tokens): Add __typeof__, typeof, __typeof, __decltype,
and decltype.
* eval.c (evaluate_subexp_standard) <OP_TYPEOF, OP_DECLTYPE>:
New case.
* expprint.c (dump_subexp_body_standard) <OP_TYPEOF,
OP_DECLTYPE>: New case.
* parse.c (operator_length_standard) <OP_TYPEOF, OP_DECLTYPE>:
New case.
* std-operator.def (OP_TYPEOF, OP_DECLTYPE): New constants.
* varobj.c (varobj_create): Handle OP_TYPEOF, OP_DECLTYPE.
gdb/testsuite
* gdb.cp/casts.exp: Add tests for typeof and decltype.
* gdb.cp/casts.cc (decltype): New function.
(main): Use it.
+2012-07-19 Tom Tromey <tromey@redhat.com>
+
+ PR exp/13206:
+ * ax-gdb.c (gen_expr) <OP_TYPEOF, OP_DECLTYPE>: New cases.
+ * breakpoint.c (watchpoint_exp_is_const) <OP_TYPEOF,
+ OP_DECLTYPE>: New cases.
+ * c-exp.y (TYPEOF, DECLTYPE): New tokens.
+ (type_exp): Add new productions.
+ (ident_tokens): Add __typeof__, typeof, __typeof, __decltype,
+ and decltype.
+ * eval.c (evaluate_subexp_standard) <OP_TYPEOF, OP_DECLTYPE>:
+ New case.
+ * expprint.c (dump_subexp_body_standard) <OP_TYPEOF,
+ OP_DECLTYPE>: New case.
+ * parse.c (operator_length_standard) <OP_TYPEOF, OP_DECLTYPE>:
+ New case.
+ * std-operator.def (OP_TYPEOF, OP_DECLTYPE): New constants.
+ * varobj.c (varobj_create): Handle OP_TYPEOF, OP_DECLTYPE.
+
2012-07-19 Tom Tromey <tromey@redhat.com>
* c-exp.y (enum token_flags): New.
break;
case OP_TYPE:
+ case OP_TYPEOF:
+ case OP_DECLTYPE:
error (_("Attempt to use a type name as an expression."));
default:
case OP_BITSTRING:
case OP_ARRAY:
case OP_TYPE:
+ case OP_TYPEOF:
+ case OP_DECLTYPE:
case OP_NAME:
case OP_OBJC_NSSTRING:
%type <sval> operator
%token REINTERPRET_CAST DYNAMIC_CAST STATIC_CAST CONST_CAST
%token ENTRY
+%token TYPEOF
+%token DECLTYPE
/* Special type cases, put in to allow the parser to distinguish different
legal basetypes. */
{ write_exp_elt_opcode(OP_TYPE);
write_exp_elt_type($1);
write_exp_elt_opcode(OP_TYPE);}
+ | TYPEOF '(' exp ')'
+ {
+ write_exp_elt_opcode (OP_TYPEOF);
+ }
+ | TYPEOF '(' type ')'
+ {
+ write_exp_elt_opcode (OP_TYPE);
+ write_exp_elt_type ($3);
+ write_exp_elt_opcode (OP_TYPE);
+ }
+ | DECLTYPE '(' exp ')'
+ {
+ write_exp_elt_opcode (OP_DECLTYPE);
+ }
;
/* Expressions, including the comma operator. */
{"const_cast", CONST_CAST, OP_NULL, FLAG_CXX },
{"dynamic_cast", DYNAMIC_CAST, OP_NULL, FLAG_CXX },
{"static_cast", STATIC_CAST, OP_NULL, FLAG_CXX },
- {"reinterpret_cast", REINTERPRET_CAST, OP_NULL, FLAG_CXX }
+ {"reinterpret_cast", REINTERPRET_CAST, OP_NULL, FLAG_CXX },
+
+ {"__typeof__", TYPEOF, OP_TYPEOF, 0 },
+ {"__typeof", TYPEOF, OP_TYPEOF, 0 },
+ {"typeof", TYPEOF, OP_TYPEOF, FLAG_SHADOW },
+ {"__decltype", DECLTYPE, OP_DECLTYPE, FLAG_CXX },
+ {"decltype", DECLTYPE, OP_DECLTYPE, FLAG_CXX | FLAG_SHADOW }
};
/* When we find that lexptr (the global var defined in parse.c) is
else
error (_("Attempt to use a type name as an expression"));
+ case OP_TYPEOF:
+ case OP_DECLTYPE:
+ if (noside == EVAL_SKIP)
+ {
+ evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);
+ goto nosideret;
+ }
+ else if (noside == EVAL_AVOID_SIDE_EFFECTS)
+ {
+ enum exp_opcode sub_op = exp->elts[*pos].opcode;
+ struct value *result;
+
+ result = evaluate_subexp (NULL_TYPE, exp, pos,
+ EVAL_AVOID_SIDE_EFFECTS);
+
+ /* 'decltype' has special semantics for lvalues. */
+ if (op == OP_DECLTYPE
+ && (sub_op == BINOP_SUBSCRIPT
+ || sub_op == STRUCTOP_MEMBER
+ || sub_op == STRUCTOP_MPTR
+ || sub_op == UNOP_IND
+ || sub_op == STRUCTOP_STRUCT
+ || sub_op == STRUCTOP_PTR
+ || sub_op == OP_SCOPE))
+ {
+ struct type *type = value_type (result);
+
+ if (TYPE_CODE (check_typedef (type)) != TYPE_CODE_REF)
+ {
+ type = lookup_reference_type (type);
+ result = allocate_value (type);
+ }
+ }
+
+ return result;
+ }
+ else
+ error (_("Attempt to use a type as an expression"));
+
default:
/* Removing this case and compiling with gcc -Wall reveals that
a lot of cases are hitting this case. Some of these should
fprintf_filtered (stream, ")");
elt += 2;
break;
+ case OP_TYPEOF:
+ case OP_DECLTYPE:
+ fprintf_filtered (stream, "Typeof (");
+ elt = dump_subexp (exp, stream, elt);
+ fprintf_filtered (stream, ")");
+ break;
case STRUCTOP_STRUCT:
case STRUCTOP_PTR:
{
case UNOP_ODD:
case UNOP_ORD:
case UNOP_TRUNC:
+ case OP_TYPEOF:
+ case OP_DECLTYPE:
oplen = 1;
args = 1;
break;
/* OP_ADL_FUNC specifies that the function is to be looked up in an
Argument Dependent manner (Koenig lookup). */
OP (OP_ADL_FUNC)
+
+/* The typeof operator. This has one expression argument, which is
+ evaluated solely for its type. */
+OP (OP_TYPEOF)
+
+/* The decltype operator. This has one expression argument, which is
+ evaluated solely for its type. This is similar to typeof, but has
+ slight different semantics. */
+OP (OP_DECLTYPE)
+2012-07-19 Tom Tromey <tromey@redhat.com>
+
+ * gdb.cp/casts.exp: Add tests for typeof and decltype.
+ * gdb.cp/casts.cc (decltype): New function.
+ (main): Use it.
+
2012-07-19 Pedro Alves <palves@redhat.com>
* gdb.base/sigall.exp (signals): New list.
{
};
+// Confuse a simpler approach.
+
+double
+decltype(int x)
+{
+ return x + 2.0;
+}
+
int
main (int argc, char **argv)
{
Alpha *ad = &derived;
Alpha *add = &doublyderived;
+ double y = decltype(2);
+
return 0; /* breakpoint spot: casts.exp: 1 */
}
gdb_test "print reinterpret_cast<A &> (*b)" " = \\(A \\&\\) @$hex: {a = 42}" \
"reinterpret_cast to reference type"
+# Test that keyword shadowing works.
+
+gdb_test "whatis decltype(5)" " = double"
+
+# Basic tests using typeof.
+
+foreach opname {__typeof__ __typeof __decltype} {
+ gdb_test "print (${opname}(a)) (b)" " = \\(A \\*\\) $hex" \
+ "old-style cast using $opname"
+
+ gdb_test "print static_cast<${opname}(a)> (b)" " = \\(A \\*\\) $hex" \
+ "static_cast using $opname"
+
+ gdb_test "print reinterpret_cast<${opname}(a)> (b)" " = \\(A \\*\\) $hex" \
+ "reinterpret_cast using $opname"
+}
+
+gdb_test "whatis __decltype(*a)" "type = A \\&"
+
# Tests of dynamic_cast.
set nonzero_hex "0x\[0-9A-Fa-f\]\[0-9A-Fa-f\]+"
}
/* Don't allow variables to be created for types. */
- if (var->root->exp->elts[0].opcode == OP_TYPE)
+ if (var->root->exp->elts[0].opcode == OP_TYPE
+ || var->root->exp->elts[0].opcode == OP_TYPEOF
+ || var->root->exp->elts[0].opcode == OP_DECLTYPE)
{
do_cleanups (old_chain);
fprintf_unfiltered (gdb_stderr, "Attempt to use a type name"