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. gdb/testsuite * gdb.cp/casts.exp: Add tests for typeof and decltype. * gdb.cp/casts.cc (decltype): New function. (main): Use it.
This commit is contained in:
parent
274b54d7e2
commit
608b49672e
@ -1,3 +1,22 @@
|
||||
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.
|
||||
|
@ -2255,6 +2255,8 @@ gen_expr (struct expression *exp, union exp_element **pc,
|
||||
break;
|
||||
|
||||
case OP_TYPE:
|
||||
case OP_TYPEOF:
|
||||
case OP_DECLTYPE:
|
||||
error (_("Attempt to use a type name as an expression."));
|
||||
|
||||
default:
|
||||
|
@ -10162,6 +10162,8 @@ watchpoint_exp_is_const (const struct expression *exp)
|
||||
case OP_BITSTRING:
|
||||
case OP_ARRAY:
|
||||
case OP_TYPE:
|
||||
case OP_TYPEOF:
|
||||
case OP_DECLTYPE:
|
||||
case OP_NAME:
|
||||
case OP_OBJC_NSSTRING:
|
||||
|
||||
|
24
gdb/c-exp.y
24
gdb/c-exp.y
@ -219,6 +219,8 @@ static void check_parameter_typelist (VEC (type_ptr) *);
|
||||
%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. */
|
||||
@ -268,6 +270,20 @@ type_exp: type
|
||||
{ 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. */
|
||||
@ -2059,7 +2075,13 @@ static const struct token ident_tokens[] =
|
||||
{"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
|
||||
|
39
gdb/eval.c
39
gdb/eval.c
@ -2900,6 +2900,45 @@ evaluate_subexp_standard (struct type *expect_type,
|
||||
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
|
||||
|
@ -971,6 +971,12 @@ dump_subexp_body_standard (struct expression *exp,
|
||||
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:
|
||||
{
|
||||
|
@ -938,6 +938,8 @@ operator_length_standard (const struct expression *expr, int endpos,
|
||||
case UNOP_ODD:
|
||||
case UNOP_ORD:
|
||||
case UNOP_TRUNC:
|
||||
case OP_TYPEOF:
|
||||
case OP_DECLTYPE:
|
||||
oplen = 1;
|
||||
args = 1;
|
||||
break;
|
||||
|
@ -332,3 +332,12 @@ OP (OP_DECFLOAT)
|
||||
/* 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)
|
||||
|
@ -1,3 +1,9 @@
|
||||
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.
|
||||
|
@ -34,6 +34,14 @@ struct DoublyDerived : public VirtuallyDerived,
|
||||
{
|
||||
};
|
||||
|
||||
// Confuse a simpler approach.
|
||||
|
||||
double
|
||||
decltype(int x)
|
||||
{
|
||||
return x + 2.0;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
@ -48,5 +56,7 @@ main (int argc, char **argv)
|
||||
Alpha *ad = &derived;
|
||||
Alpha *add = &doublyderived;
|
||||
|
||||
double y = decltype(2);
|
||||
|
||||
return 0; /* breakpoint spot: casts.exp: 1 */
|
||||
}
|
||||
|
@ -107,6 +107,25 @@ gdb_test "print reinterpret_cast<void> (b)" "Invalid reinterpret_cast" \
|
||||
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\]+"
|
||||
|
@ -675,7 +675,9 @@ varobj_create (char *objname,
|
||||
}
|
||||
|
||||
/* 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"
|
||||
|
Loading…
x
Reference in New Issue
Block a user