* 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"