windows-nat: Cleanups in get_windows_debug_event
[deliverable/binutils-gdb.git] / gdb / c-exp.y
index 5d4cd8198a80fef7b335abf4fde281b9bef238b4..84f3a338bf88483bb031942a694a4e6a2c1c0af1 100644 (file)
@@ -1,5 +1,5 @@
 /* YACC parser for C expressions, for GDB.
-   Copyright (C) 1986-2013 Free Software Foundation, Inc.
+   Copyright (C) 1986-2015 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
    with include files (<malloc.h> and <stdlib.h> for example) just became
    too messy, particularly when such includes can be inserted at random
    times by the parser generator.  */
-   
+
 %{
 
 #include "defs.h"
-#include <string.h>
 #include <ctype.h>
 #include "expression.h"
 #include "value.h"
 #include "block.h"
 #include "cp-support.h"
 #include "dfp.h"
-#include "gdb_assert.h"
 #include "macroscope.h"
 #include "objc-lang.h"
 #include "typeprint.h"
 #include "cp-abi.h"
 
-#define parse_type builtin_type (parse_gdbarch)
+#define parse_type(ps) builtin_type (parse_gdbarch (ps))
 
 /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
    as well as gratuitiously global symbol names, so we can have multiple
 
 #define YYFPRINTF parser_fprintf
 
+/* The state of the parser, used internally when we are parsing the
+   expression.  */
+
+static struct parser_state *pstate = NULL;
+
 int yyparse (void);
 
 static int yylex (void);
 
 void yyerror (char *);
 
+static int type_aggregate_p (struct type *);
+
 %}
 
 /* Although the yacc "value" of an expression is not used,
@@ -151,7 +156,7 @@ void yyerror (char *);
     struct ttype tsym;
     struct symtoken ssym;
     int voidval;
-    struct block *bval;
+    const struct block *bval;
     enum exp_opcode opcode;
 
     struct stoken_vector svec;
@@ -159,18 +164,22 @@ void yyerror (char *);
 
     struct type_stack *type_stack;
 
-    struct objc_class_str class;
+    struct objc_class_str theclass;
   }
 
 %{
 /* YYSTYPE gets defined by %union */
-static int parse_number (const char *, int, int, YYSTYPE *);
+static int parse_number (struct parser_state *par_state,
+                        const char *, int, int, YYSTYPE *);
 static struct stoken operator_stoken (const char *);
 static void check_parameter_typelist (VEC (type_ptr) *);
-static void write_destructor_name (struct stoken);
+static void write_destructor_name (struct parser_state *par_state,
+                                  struct stoken);
 
+#ifdef YYBISON
 static void c_print_token (FILE *file, int type, YYSTYPE value);
 #define YYPRINT(FILE, TYPE, VALUE) c_print_token (FILE, TYPE, VALUE)
+#endif
 %}
 
 %type <voidval> exp exp1 type_exp start variable qualified_name lcurly
@@ -206,11 +215,11 @@ static void c_print_token (FILE *file, int type, YYSTYPE value);
 %token <ssym> UNKNOWN_CPP_NAME
 %token <voidval> COMPLETE
 %token <tsym> TYPENAME
-%token <class> CLASSNAME       /* ObjC Class name */
+%token <theclass> CLASSNAME    /* ObjC Class name */
 %type <sval> name
 %type <svec> string_exp
 %type <ssym> name_not_typename
-%type <tsym> typename
+%type <tsym> type_name
 
  /* This is like a '[' token, but is only generated when parsing
     Objective C.  This lets us reuse the same parser without
@@ -222,14 +231,14 @@ static void c_print_token (FILE *file, int type, YYSTYPE value);
    E.g. "c" when input_radix==16.  Depending on the parse, it will be
    turned into a name or into a number.  */
 
-%token <ssym> NAME_OR_INT 
+%token <ssym> NAME_OR_INT
 
 %token OPERATOR
 %token STRUCT CLASS UNION ENUM SIZEOF UNSIGNED COLONCOLON
 %token TEMPLATE
 %token ERROR
 %token NEW DELETE
-%type <sval> operator
+%type <sval> oper
 %token REINTERPRET_CAST DYNAMIC_CAST STATIC_CAST CONST_CAST
 %token ENTRY
 %token TYPEOF
@@ -266,7 +275,7 @@ static void c_print_token (FILE *file, int type, YYSTYPE value);
 %left '*' '/' '%'
 %right UNARY INCREMENT DECREMENT
 %right ARROW ARROW_STAR '.' DOT_STAR '[' OBJC_LBRAC '('
-%token <ssym> BLOCKNAME 
+%token <ssym> BLOCKNAME
 %token <bval> FILENAME
 %type <bval> block
 %left COLONCOLON
@@ -281,186 +290,186 @@ start   :       exp1
        ;
 
 type_exp:      type
-                       { write_exp_elt_opcode(OP_TYPE);
-                         write_exp_elt_type($1);
-                         write_exp_elt_opcode(OP_TYPE);}
+                       { write_exp_elt_opcode(pstate, OP_TYPE);
+                         write_exp_elt_type(pstate, $1);
+                         write_exp_elt_opcode(pstate, OP_TYPE);}
        |       TYPEOF '(' exp ')'
                        {
-                         write_exp_elt_opcode (OP_TYPEOF);
+                         write_exp_elt_opcode (pstate, OP_TYPEOF);
                        }
        |       TYPEOF '(' type ')'
                        {
-                         write_exp_elt_opcode (OP_TYPE);
-                         write_exp_elt_type ($3);
-                         write_exp_elt_opcode (OP_TYPE);
+                         write_exp_elt_opcode (pstate, OP_TYPE);
+                         write_exp_elt_type (pstate, $3);
+                         write_exp_elt_opcode (pstate, OP_TYPE);
                        }
        |       DECLTYPE '(' exp ')'
                        {
-                         write_exp_elt_opcode (OP_DECLTYPE);
+                         write_exp_elt_opcode (pstate, OP_DECLTYPE);
                        }
        ;
 
 /* Expressions, including the comma operator.  */
 exp1   :       exp
        |       exp1 ',' exp
-                       { write_exp_elt_opcode (BINOP_COMMA); }
+                       { write_exp_elt_opcode (pstate, BINOP_COMMA); }
        ;
 
 /* Expressions, not including the comma operator.  */
 exp    :       '*' exp    %prec UNARY
-                       { write_exp_elt_opcode (UNOP_IND); }
+                       { write_exp_elt_opcode (pstate, UNOP_IND); }
        ;
 
 exp    :       '&' exp    %prec UNARY
-                       { write_exp_elt_opcode (UNOP_ADDR); }
+                       { write_exp_elt_opcode (pstate, UNOP_ADDR); }
        ;
 
 exp    :       '-' exp    %prec UNARY
-                       { write_exp_elt_opcode (UNOP_NEG); }
+                       { write_exp_elt_opcode (pstate, UNOP_NEG); }
        ;
 
 exp    :       '+' exp    %prec UNARY
-                       { write_exp_elt_opcode (UNOP_PLUS); }
+                       { write_exp_elt_opcode (pstate, UNOP_PLUS); }
        ;
 
 exp    :       '!' exp    %prec UNARY
-                       { write_exp_elt_opcode (UNOP_LOGICAL_NOT); }
+                       { write_exp_elt_opcode (pstate, UNOP_LOGICAL_NOT); }
        ;
 
 exp    :       '~' exp    %prec UNARY
-                       { write_exp_elt_opcode (UNOP_COMPLEMENT); }
+                       { write_exp_elt_opcode (pstate, UNOP_COMPLEMENT); }
        ;
 
 exp    :       INCREMENT exp    %prec UNARY
-                       { write_exp_elt_opcode (UNOP_PREINCREMENT); }
+                       { write_exp_elt_opcode (pstate, UNOP_PREINCREMENT); }
        ;
 
 exp    :       DECREMENT exp    %prec UNARY
-                       { write_exp_elt_opcode (UNOP_PREDECREMENT); }
+                       { write_exp_elt_opcode (pstate, UNOP_PREDECREMENT); }
        ;
 
 exp    :       exp INCREMENT    %prec UNARY
-                       { write_exp_elt_opcode (UNOP_POSTINCREMENT); }
+                       { write_exp_elt_opcode (pstate, UNOP_POSTINCREMENT); }
        ;
 
 exp    :       exp DECREMENT    %prec UNARY
-                       { write_exp_elt_opcode (UNOP_POSTDECREMENT); }
+                       { write_exp_elt_opcode (pstate, UNOP_POSTDECREMENT); }
        ;
 
 exp    :       TYPEID '(' exp ')' %prec UNARY
-                       { write_exp_elt_opcode (OP_TYPEID); }
+                       { write_exp_elt_opcode (pstate, OP_TYPEID); }
        ;
 
 exp    :       TYPEID '(' type_exp ')' %prec UNARY
-                       { write_exp_elt_opcode (OP_TYPEID); }
+                       { write_exp_elt_opcode (pstate, OP_TYPEID); }
        ;
 
 exp    :       SIZEOF exp       %prec UNARY
-                       { write_exp_elt_opcode (UNOP_SIZEOF); }
+                       { write_exp_elt_opcode (pstate, UNOP_SIZEOF); }
        ;
 
 exp    :       exp ARROW name
-                       { write_exp_elt_opcode (STRUCTOP_PTR);
-                         write_exp_string ($3);
-                         write_exp_elt_opcode (STRUCTOP_PTR); }
+                       { write_exp_elt_opcode (pstate, STRUCTOP_PTR);
+                         write_exp_string (pstate, $3);
+                         write_exp_elt_opcode (pstate, STRUCTOP_PTR); }
        ;
 
 exp    :       exp ARROW name COMPLETE
-                       { mark_struct_expression ();
-                         write_exp_elt_opcode (STRUCTOP_PTR);
-                         write_exp_string ($3);
-                         write_exp_elt_opcode (STRUCTOP_PTR); }
+                       { mark_struct_expression (pstate);
+                         write_exp_elt_opcode (pstate, STRUCTOP_PTR);
+                         write_exp_string (pstate, $3);
+                         write_exp_elt_opcode (pstate, STRUCTOP_PTR); }
        ;
 
 exp    :       exp ARROW COMPLETE
                        { struct stoken s;
-                         mark_struct_expression ();
-                         write_exp_elt_opcode (STRUCTOP_PTR);
+                         mark_struct_expression (pstate);
+                         write_exp_elt_opcode (pstate, STRUCTOP_PTR);
                          s.ptr = "";
                          s.length = 0;
-                         write_exp_string (s);
-                         write_exp_elt_opcode (STRUCTOP_PTR); }
+                         write_exp_string (pstate, s);
+                         write_exp_elt_opcode (pstate, STRUCTOP_PTR); }
        ;
 
 exp    :       exp ARROW '~' name
-                       { write_exp_elt_opcode (STRUCTOP_PTR);
-                         write_destructor_name ($4);
-                         write_exp_elt_opcode (STRUCTOP_PTR); }
+                       { write_exp_elt_opcode (pstate, STRUCTOP_PTR);
+                         write_destructor_name (pstate, $4);
+                         write_exp_elt_opcode (pstate, STRUCTOP_PTR); }
        ;
 
 exp    :       exp ARROW '~' name COMPLETE
-                       { mark_struct_expression ();
-                         write_exp_elt_opcode (STRUCTOP_PTR);
-                         write_destructor_name ($4);
-                         write_exp_elt_opcode (STRUCTOP_PTR); }
+                       { mark_struct_expression (pstate);
+                         write_exp_elt_opcode (pstate, STRUCTOP_PTR);
+                         write_destructor_name (pstate, $4);
+                         write_exp_elt_opcode (pstate, STRUCTOP_PTR); }
        ;
 
 exp    :       exp ARROW qualified_name
                        { /* exp->type::name becomes exp->*(&type::name) */
                          /* Note: this doesn't work if name is a
                             static member!  FIXME */
-                         write_exp_elt_opcode (UNOP_ADDR);
-                         write_exp_elt_opcode (STRUCTOP_MPTR); }
+                         write_exp_elt_opcode (pstate, UNOP_ADDR);
+                         write_exp_elt_opcode (pstate, STRUCTOP_MPTR); }
        ;
 
 exp    :       exp ARROW_STAR exp
-                       { write_exp_elt_opcode (STRUCTOP_MPTR); }
+                       { write_exp_elt_opcode (pstate, STRUCTOP_MPTR); }
        ;
 
 exp    :       exp '.' name
-                       { write_exp_elt_opcode (STRUCTOP_STRUCT);
-                         write_exp_string ($3);
-                         write_exp_elt_opcode (STRUCTOP_STRUCT); }
+                       { write_exp_elt_opcode (pstate, STRUCTOP_STRUCT);
+                         write_exp_string (pstate, $3);
+                         write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); }
        ;
 
 exp    :       exp '.' name COMPLETE
-                       { mark_struct_expression ();
-                         write_exp_elt_opcode (STRUCTOP_STRUCT);
-                         write_exp_string ($3);
-                         write_exp_elt_opcode (STRUCTOP_STRUCT); }
+                       { mark_struct_expression (pstate);
+                         write_exp_elt_opcode (pstate, STRUCTOP_STRUCT);
+                         write_exp_string (pstate, $3);
+                         write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); }
        ;
 
 exp    :       exp '.' COMPLETE
                        { struct stoken s;
-                         mark_struct_expression ();
-                         write_exp_elt_opcode (STRUCTOP_STRUCT);
+                         mark_struct_expression (pstate);
+                         write_exp_elt_opcode (pstate, STRUCTOP_STRUCT);
                          s.ptr = "";
                          s.length = 0;
-                         write_exp_string (s);
-                         write_exp_elt_opcode (STRUCTOP_STRUCT); }
+                         write_exp_string (pstate, s);
+                         write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); }
        ;
 
 exp    :       exp '.' '~' name
-                       { write_exp_elt_opcode (STRUCTOP_STRUCT);
-                         write_destructor_name ($4);
-                         write_exp_elt_opcode (STRUCTOP_STRUCT); }
+                       { write_exp_elt_opcode (pstate, STRUCTOP_STRUCT);
+                         write_destructor_name (pstate, $4);
+                         write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); }
        ;
 
 exp    :       exp '.' '~' name COMPLETE
-                       { mark_struct_expression ();
-                         write_exp_elt_opcode (STRUCTOP_STRUCT);
-                         write_destructor_name ($4);
-                         write_exp_elt_opcode (STRUCTOP_STRUCT); }
+                       { mark_struct_expression (pstate);
+                         write_exp_elt_opcode (pstate, STRUCTOP_STRUCT);
+                         write_destructor_name (pstate, $4);
+                         write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); }
        ;
 
 exp    :       exp '.' qualified_name
                        { /* exp.type::name becomes exp.*(&type::name) */
                          /* Note: this doesn't work if name is a
                             static member!  FIXME */
-                         write_exp_elt_opcode (UNOP_ADDR);
-                         write_exp_elt_opcode (STRUCTOP_MEMBER); }
+                         write_exp_elt_opcode (pstate, UNOP_ADDR);
+                         write_exp_elt_opcode (pstate, STRUCTOP_MEMBER); }
        ;
 
 exp    :       exp DOT_STAR exp
-                       { write_exp_elt_opcode (STRUCTOP_MEMBER); }
+                       { write_exp_elt_opcode (pstate, STRUCTOP_MEMBER); }
        ;
 
 exp    :       exp '[' exp1 ']'
-                       { write_exp_elt_opcode (BINOP_SUBSCRIPT); }
+                       { write_exp_elt_opcode (pstate, BINOP_SUBSCRIPT); }
        ;
 
 exp    :       exp OBJC_LBRAC exp1 ']'
-                       { write_exp_elt_opcode (BINOP_SUBSCRIPT); }
+                       { write_exp_elt_opcode (pstate, BINOP_SUBSCRIPT); }
        ;
 
 /*
@@ -470,47 +479,49 @@ exp       :       exp OBJC_LBRAC exp1 ']'
 
 exp    :       OBJC_LBRAC TYPENAME
                        {
-                         CORE_ADDR class;
+                         CORE_ADDR theclass;
 
-                         class = lookup_objc_class (parse_gdbarch,
+                         theclass = lookup_objc_class (parse_gdbarch (pstate),
                                                     copy_name ($2.stoken));
-                         if (class == 0)
+                         if (theclass == 0)
                            error (_("%s is not an ObjC Class"),
                                   copy_name ($2.stoken));
-                         write_exp_elt_opcode (OP_LONG);
-                         write_exp_elt_type (parse_type->builtin_int);
-                         write_exp_elt_longcst ((LONGEST) class);
-                         write_exp_elt_opcode (OP_LONG);
+                         write_exp_elt_opcode (pstate, OP_LONG);
+                         write_exp_elt_type (pstate,
+                                           parse_type (pstate)->builtin_int);
+                         write_exp_elt_longcst (pstate, (LONGEST) theclass);
+                         write_exp_elt_opcode (pstate, OP_LONG);
                          start_msglist();
                        }
                msglist ']'
-                       { write_exp_elt_opcode (OP_OBJC_MSGCALL);
-                         end_msglist();
-                         write_exp_elt_opcode (OP_OBJC_MSGCALL);
+                       { write_exp_elt_opcode (pstate, OP_OBJC_MSGCALL);
+                         end_msglist (pstate);
+                         write_exp_elt_opcode (pstate, OP_OBJC_MSGCALL);
                        }
        ;
 
 exp    :       OBJC_LBRAC CLASSNAME
                        {
-                         write_exp_elt_opcode (OP_LONG);
-                         write_exp_elt_type (parse_type->builtin_int);
-                         write_exp_elt_longcst ((LONGEST) $2.class);
-                         write_exp_elt_opcode (OP_LONG);
+                         write_exp_elt_opcode (pstate, OP_LONG);
+                         write_exp_elt_type (pstate,
+                                           parse_type (pstate)->builtin_int);
+                         write_exp_elt_longcst (pstate, (LONGEST) $2.theclass);
+                         write_exp_elt_opcode (pstate, OP_LONG);
                          start_msglist();
                        }
                msglist ']'
-                       { write_exp_elt_opcode (OP_OBJC_MSGCALL);
-                         end_msglist();
-                         write_exp_elt_opcode (OP_OBJC_MSGCALL);
+                       { write_exp_elt_opcode (pstate, OP_OBJC_MSGCALL);
+                         end_msglist (pstate);
+                         write_exp_elt_opcode (pstate, OP_OBJC_MSGCALL);
                        }
        ;
 
 exp    :       OBJC_LBRAC exp
                        { start_msglist(); }
                msglist ']'
-                       { write_exp_elt_opcode (OP_OBJC_MSGCALL);
-                         end_msglist();
-                         write_exp_elt_opcode (OP_OBJC_MSGCALL);
+                       { write_exp_elt_opcode (pstate, OP_OBJC_MSGCALL);
+                         end_msglist (pstate);
+                         write_exp_elt_opcode (pstate, OP_OBJC_MSGCALL);
                        }
        ;
 
@@ -531,25 +542,28 @@ msgarg    :       name ':' exp
                        { add_msglist(0, 0);   }
        ;
 
-exp    :       exp '(' 
+exp    :       exp '('
                        /* This is to save the value of arglist_len
                           being accumulated by an outer function call.  */
                        { start_arglist (); }
                arglist ')'     %prec ARROW
-                       { write_exp_elt_opcode (OP_FUNCALL);
-                         write_exp_elt_longcst ((LONGEST) end_arglist ());
-                         write_exp_elt_opcode (OP_FUNCALL); }
+                       { write_exp_elt_opcode (pstate, OP_FUNCALL);
+                         write_exp_elt_longcst (pstate,
+                                                (LONGEST) end_arglist ());
+                         write_exp_elt_opcode (pstate, OP_FUNCALL); }
        ;
 
 exp    :       UNKNOWN_CPP_NAME '('
                        {
                          /* This could potentially be a an argument defined
                             lookup function (Koenig).  */
-                         write_exp_elt_opcode (OP_ADL_FUNC);
-                         write_exp_elt_block (expression_context_block);
-                         write_exp_elt_sym (NULL); /* Placeholder.  */
-                         write_exp_string ($1.stoken);
-                         write_exp_elt_opcode (OP_ADL_FUNC);
+                         write_exp_elt_opcode (pstate, OP_ADL_FUNC);
+                         write_exp_elt_block (pstate,
+                                              expression_context_block);
+                         write_exp_elt_sym (pstate,
+                                            NULL); /* Placeholder.  */
+                         write_exp_string (pstate, $1.stoken);
+                         write_exp_elt_opcode (pstate, OP_ADL_FUNC);
 
                        /* This is to save the value of arglist_len
                           being accumulated by an outer function call.  */
@@ -558,9 +572,10 @@ exp        :       UNKNOWN_CPP_NAME '('
                        }
                arglist ')'     %prec ARROW
                        {
-                         write_exp_elt_opcode (OP_FUNCALL);
-                         write_exp_elt_longcst ((LONGEST) end_arglist ());
-                         write_exp_elt_opcode (OP_FUNCALL);
+                         write_exp_elt_opcode (pstate, OP_FUNCALL);
+                         write_exp_elt_longcst (pstate,
+                                                (LONGEST) end_arglist ());
+                         write_exp_elt_opcode (pstate, OP_FUNCALL);
                        }
        ;
 
@@ -585,14 +600,14 @@ exp     :       exp '(' parameter_typelist ')' const_or_volatile
                          struct type *type_elt;
                          LONGEST len = VEC_length (type_ptr, type_list);
 
-                         write_exp_elt_opcode (TYPE_INSTANCE);
-                         write_exp_elt_longcst (len);
+                         write_exp_elt_opcode (pstate, TYPE_INSTANCE);
+                         write_exp_elt_longcst (pstate, len);
                          for (i = 0;
                               VEC_iterate (type_ptr, type_list, i, type_elt);
                               ++i)
-                           write_exp_elt_type (type_elt);
-                         write_exp_elt_longcst(len);
-                         write_exp_elt_opcode (TYPE_INSTANCE);
+                           write_exp_elt_type (pstate, type_elt);
+                         write_exp_elt_longcst(pstate, len);
+                         write_exp_elt_opcode (pstate, TYPE_INSTANCE);
                          VEC_free (type_ptr, type_list);
                        }
        ;
@@ -601,18 +616,18 @@ rcurly    :       '}'
                        { $$ = end_arglist () - 1; }
        ;
 exp    :       lcurly arglist rcurly   %prec ARROW
-                       { write_exp_elt_opcode (OP_ARRAY);
-                         write_exp_elt_longcst ((LONGEST) 0);
-                         write_exp_elt_longcst ((LONGEST) $3);
-                         write_exp_elt_opcode (OP_ARRAY); }
+                       { write_exp_elt_opcode (pstate, OP_ARRAY);
+                         write_exp_elt_longcst (pstate, (LONGEST) 0);
+                         write_exp_elt_longcst (pstate, (LONGEST) $3);
+                         write_exp_elt_opcode (pstate, OP_ARRAY); }
        ;
 
 exp    :       lcurly type_exp rcurly exp  %prec UNARY
-                       { write_exp_elt_opcode (UNOP_MEMVAL_TYPE); }
+                       { write_exp_elt_opcode (pstate, UNOP_MEMVAL_TYPE); }
        ;
 
 exp    :       '(' type_exp ')' exp  %prec UNARY
-                       { write_exp_elt_opcode (UNOP_CAST_TYPE); }
+                       { write_exp_elt_opcode (pstate, UNOP_CAST_TYPE); }
        ;
 
 exp    :       '(' exp1 ')'
@@ -622,100 +637,101 @@ exp     :       '(' exp1 ')'
 /* Binary operators in order of decreasing precedence.  */
 
 exp    :       exp '@' exp
-                       { write_exp_elt_opcode (BINOP_REPEAT); }
+                       { write_exp_elt_opcode (pstate, BINOP_REPEAT); }
        ;
 
 exp    :       exp '*' exp
-                       { write_exp_elt_opcode (BINOP_MUL); }
+                       { write_exp_elt_opcode (pstate, BINOP_MUL); }
        ;
 
 exp    :       exp '/' exp
-                       { write_exp_elt_opcode (BINOP_DIV); }
+                       { write_exp_elt_opcode (pstate, BINOP_DIV); }
        ;
 
 exp    :       exp '%' exp
-                       { write_exp_elt_opcode (BINOP_REM); }
+                       { write_exp_elt_opcode (pstate, BINOP_REM); }
        ;
 
 exp    :       exp '+' exp
-                       { write_exp_elt_opcode (BINOP_ADD); }
+                       { write_exp_elt_opcode (pstate, BINOP_ADD); }
        ;
 
 exp    :       exp '-' exp
-                       { write_exp_elt_opcode (BINOP_SUB); }
+                       { write_exp_elt_opcode (pstate, BINOP_SUB); }
        ;
 
 exp    :       exp LSH exp
-                       { write_exp_elt_opcode (BINOP_LSH); }
+                       { write_exp_elt_opcode (pstate, BINOP_LSH); }
        ;
 
 exp    :       exp RSH exp
-                       { write_exp_elt_opcode (BINOP_RSH); }
+                       { write_exp_elt_opcode (pstate, BINOP_RSH); }
        ;
 
 exp    :       exp EQUAL exp
-                       { write_exp_elt_opcode (BINOP_EQUAL); }
+                       { write_exp_elt_opcode (pstate, BINOP_EQUAL); }
        ;
 
 exp    :       exp NOTEQUAL exp
-                       { write_exp_elt_opcode (BINOP_NOTEQUAL); }
+                       { write_exp_elt_opcode (pstate, BINOP_NOTEQUAL); }
        ;
 
 exp    :       exp LEQ exp
-                       { write_exp_elt_opcode (BINOP_LEQ); }
+                       { write_exp_elt_opcode (pstate, BINOP_LEQ); }
        ;
 
 exp    :       exp GEQ exp
-                       { write_exp_elt_opcode (BINOP_GEQ); }
+                       { write_exp_elt_opcode (pstate, BINOP_GEQ); }
        ;
 
 exp    :       exp '<' exp
-                       { write_exp_elt_opcode (BINOP_LESS); }
+                       { write_exp_elt_opcode (pstate, BINOP_LESS); }
        ;
 
 exp    :       exp '>' exp
-                       { write_exp_elt_opcode (BINOP_GTR); }
+                       { write_exp_elt_opcode (pstate, BINOP_GTR); }
        ;
 
 exp    :       exp '&' exp
-                       { write_exp_elt_opcode (BINOP_BITWISE_AND); }
+                       { write_exp_elt_opcode (pstate, BINOP_BITWISE_AND); }
        ;
 
 exp    :       exp '^' exp
-                       { write_exp_elt_opcode (BINOP_BITWISE_XOR); }
+                       { write_exp_elt_opcode (pstate, BINOP_BITWISE_XOR); }
        ;
 
 exp    :       exp '|' exp
-                       { write_exp_elt_opcode (BINOP_BITWISE_IOR); }
+                       { write_exp_elt_opcode (pstate, BINOP_BITWISE_IOR); }
        ;
 
 exp    :       exp ANDAND exp
-                       { write_exp_elt_opcode (BINOP_LOGICAL_AND); }
+                       { write_exp_elt_opcode (pstate, BINOP_LOGICAL_AND); }
        ;
 
 exp    :       exp OROR exp
-                       { write_exp_elt_opcode (BINOP_LOGICAL_OR); }
+                       { write_exp_elt_opcode (pstate, BINOP_LOGICAL_OR); }
        ;
 
 exp    :       exp '?' exp ':' exp     %prec '?'
-                       { write_exp_elt_opcode (TERNOP_COND); }
+                       { write_exp_elt_opcode (pstate, TERNOP_COND); }
        ;
-                         
+
 exp    :       exp '=' exp
-                       { write_exp_elt_opcode (BINOP_ASSIGN); }
+                       { write_exp_elt_opcode (pstate, BINOP_ASSIGN); }
        ;
 
 exp    :       exp ASSIGN_MODIFY exp
-                       { write_exp_elt_opcode (BINOP_ASSIGN_MODIFY);
-                         write_exp_elt_opcode ($2);
-                         write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); }
+                       { write_exp_elt_opcode (pstate, BINOP_ASSIGN_MODIFY);
+                         write_exp_elt_opcode (pstate, $2);
+                         write_exp_elt_opcode (pstate,
+                                               BINOP_ASSIGN_MODIFY); }
        ;
 
 exp    :       INT
-                       { write_exp_elt_opcode (OP_LONG);
-                         write_exp_elt_type ($1.type);
-                         write_exp_elt_longcst ((LONGEST)($1.val));
-                         write_exp_elt_opcode (OP_LONG); }
+                       { write_exp_elt_opcode (pstate, OP_LONG);
+                         write_exp_elt_type (pstate, $1.type);
+                         write_exp_elt_longcst (pstate, (LONGEST) ($1.val));
+                         write_exp_elt_opcode (pstate, OP_LONG); }
        ;
 
 exp    :       CHAR
@@ -723,33 +739,35 @@ exp       :       CHAR
                          struct stoken_vector vec;
                          vec.len = 1;
                          vec.tokens = &$1;
-                         write_exp_string_vector ($1.type, &vec);
+                         write_exp_string_vector (pstate, $1.type, &vec);
                        }
        ;
 
 exp    :       NAME_OR_INT
                        { YYSTYPE val;
-                         parse_number ($1.stoken.ptr, $1.stoken.length, 0, &val);
-                         write_exp_elt_opcode (OP_LONG);
-                         write_exp_elt_type (val.typed_val_int.type);
-                         write_exp_elt_longcst ((LONGEST)val.typed_val_int.val);
-                         write_exp_elt_opcode (OP_LONG);
+                         parse_number (pstate, $1.stoken.ptr,
+                                       $1.stoken.length, 0, &val);
+                         write_exp_elt_opcode (pstate, OP_LONG);
+                         write_exp_elt_type (pstate, val.typed_val_int.type);
+                         write_exp_elt_longcst (pstate,
+                                           (LONGEST) val.typed_val_int.val);
+                         write_exp_elt_opcode (pstate, OP_LONG);
                        }
        ;
 
 
 exp    :       FLOAT
-                       { write_exp_elt_opcode (OP_DOUBLE);
-                         write_exp_elt_type ($1.type);
-                         write_exp_elt_dblcst ($1.dval);
-                         write_exp_elt_opcode (OP_DOUBLE); }
+                       { write_exp_elt_opcode (pstate, OP_DOUBLE);
+                         write_exp_elt_type (pstate, $1.type);
+                         write_exp_elt_dblcst (pstate, $1.dval);
+                         write_exp_elt_opcode (pstate, OP_DOUBLE); }
        ;
 
 exp    :       DECFLOAT
-                       { write_exp_elt_opcode (OP_DECFLOAT);
-                         write_exp_elt_type ($1.type);
-                         write_exp_elt_decfloatcst ($1.val);
-                         write_exp_elt_opcode (OP_DECFLOAT); }
+                       { write_exp_elt_opcode (pstate, OP_DECFLOAT);
+                         write_exp_elt_type (pstate, $1.type);
+                         write_exp_elt_decfloatcst (pstate, $1.val);
+                         write_exp_elt_opcode (pstate, OP_DECFLOAT); }
        ;
 
 exp    :       variable
@@ -757,43 +775,54 @@ exp       :       variable
 
 exp    :       VARIABLE
                        {
-                         write_dollar_variable ($1);
+                         write_dollar_variable (pstate, $1);
                        }
        ;
 
 exp    :       SELECTOR '(' name ')'
                        {
-                         write_exp_elt_opcode (OP_OBJC_SELECTOR);
-                         write_exp_string ($3);
-                         write_exp_elt_opcode (OP_OBJC_SELECTOR); }
+                         write_exp_elt_opcode (pstate, OP_OBJC_SELECTOR);
+                         write_exp_string (pstate, $3);
+                         write_exp_elt_opcode (pstate, OP_OBJC_SELECTOR); }
        ;
 
 exp    :       SIZEOF '(' type ')'     %prec UNARY
-                       { write_exp_elt_opcode (OP_LONG);
-                         write_exp_elt_type (lookup_signed_typename
-                                             (parse_language, parse_gdbarch,
+                       { struct type *type = $3;
+                         write_exp_elt_opcode (pstate, OP_LONG);
+                         write_exp_elt_type (pstate, lookup_signed_typename
+                                             (parse_language (pstate),
+                                              parse_gdbarch (pstate),
                                               "int"));
-                         CHECK_TYPEDEF ($3);
-                         write_exp_elt_longcst ((LONGEST) TYPE_LENGTH ($3));
-                         write_exp_elt_opcode (OP_LONG); }
+                         CHECK_TYPEDEF (type);
+
+                           /* $5.3.3/2 of the C++ Standard (n3290 draft)
+                              says of sizeof:  "When applied to a reference
+                              or a reference type, the result is the size of
+                              the referenced type."  */
+                         if (TYPE_CODE (type) == TYPE_CODE_REF)
+                           type = check_typedef (TYPE_TARGET_TYPE (type));
+                         write_exp_elt_longcst (pstate,
+                                                (LONGEST) TYPE_LENGTH (type));
+                         write_exp_elt_opcode (pstate, OP_LONG); }
        ;
 
 exp    :       REINTERPRET_CAST '<' type_exp '>' '(' exp ')' %prec UNARY
-                       { write_exp_elt_opcode (UNOP_REINTERPRET_CAST); }
+                       { write_exp_elt_opcode (pstate,
+                                               UNOP_REINTERPRET_CAST); }
        ;
 
 exp    :       STATIC_CAST '<' type_exp '>' '(' exp ')' %prec UNARY
-                       { write_exp_elt_opcode (UNOP_CAST_TYPE); }
+                       { write_exp_elt_opcode (pstate, UNOP_CAST_TYPE); }
        ;
 
 exp    :       DYNAMIC_CAST '<' type_exp '>' '(' exp ')' %prec UNARY
-                       { write_exp_elt_opcode (UNOP_DYNAMIC_CAST); }
+                       { write_exp_elt_opcode (pstate, UNOP_DYNAMIC_CAST); }
        ;
 
 exp    :       CONST_CAST '<' type_exp '>' '(' exp ')' %prec UNARY
                        { /* We could do more error checking here, but
                             it doesn't seem worthwhile.  */
-                         write_exp_elt_opcode (UNOP_CAST_TYPE); }
+                         write_exp_elt_opcode (pstate, UNOP_CAST_TYPE); }
        ;
 
 string_exp:
@@ -858,7 +887,7 @@ exp :       string_exp
                                }
                            }
 
-                         write_exp_string_vector (type, &$1);
+                         write_exp_string_vector (pstate, type, &$1);
                          for (i = 0; i < $1.len; ++i)
                            free ($1.tokens[i].ptr);
                          free ($1.tokens);
@@ -868,24 +897,26 @@ exp       :       string_exp
 exp     :      NSSTRING        /* ObjC NextStep NSString constant
                                 * of the form '@' '"' string '"'.
                                 */
-                       { write_exp_elt_opcode (OP_OBJC_NSSTRING);
-                         write_exp_string ($1);
-                         write_exp_elt_opcode (OP_OBJC_NSSTRING); }
+                       { write_exp_elt_opcode (pstate, OP_OBJC_NSSTRING);
+                         write_exp_string (pstate, $1);
+                         write_exp_elt_opcode (pstate, OP_OBJC_NSSTRING); }
        ;
 
 /* C++.  */
-exp     :       TRUEKEYWORD    
-                        { write_exp_elt_opcode (OP_LONG);
-                          write_exp_elt_type (parse_type->builtin_bool);
-                          write_exp_elt_longcst ((LONGEST) 1);
-                          write_exp_elt_opcode (OP_LONG); }
+exp     :       TRUEKEYWORD
+                        { write_exp_elt_opcode (pstate, OP_LONG);
+                          write_exp_elt_type (pstate,
+                                         parse_type (pstate)->builtin_bool);
+                          write_exp_elt_longcst (pstate, (LONGEST) 1);
+                          write_exp_elt_opcode (pstate, OP_LONG); }
        ;
 
-exp     :       FALSEKEYWORD   
-                        { write_exp_elt_opcode (OP_LONG);
-                          write_exp_elt_type (parse_type->builtin_bool);
-                          write_exp_elt_longcst ((LONGEST) 0);
-                          write_exp_elt_opcode (OP_LONG); }
+exp     :       FALSEKEYWORD
+                        { write_exp_elt_opcode (pstate, OP_LONG);
+                          write_exp_elt_type (pstate,
+                                         parse_type (pstate)->builtin_bool);
+                          write_exp_elt_longcst (pstate, (LONGEST) 0);
+                          write_exp_elt_opcode (pstate, OP_LONG); }
        ;
 
 /* end of C++.  */
@@ -923,9 +954,9 @@ variable:   name_not_typename ENTRY
                                     "parameters, not for \"%s\""),
                                   copy_name ($1.stoken));
 
-                         write_exp_elt_opcode (OP_VAR_ENTRY_VALUE);
-                         write_exp_elt_sym (sym);
-                         write_exp_elt_opcode (OP_VAR_ENTRY_VALUE);
+                         write_exp_elt_opcode (pstate, OP_VAR_ENTRY_VALUE);
+                         write_exp_elt_sym (pstate, sym);
+                         write_exp_elt_opcode (pstate, OP_VAR_ENTRY_VALUE);
                        }
        ;
 
@@ -944,27 +975,25 @@ variable: block COLONCOLON name
                                innermost_block = block_found;
                            }
 
-                         write_exp_elt_opcode (OP_VAR_VALUE);
+                         write_exp_elt_opcode (pstate, OP_VAR_VALUE);
                          /* block_found is set by lookup_symbol.  */
-                         write_exp_elt_block (block_found);
-                         write_exp_elt_sym (sym);
-                         write_exp_elt_opcode (OP_VAR_VALUE); }
+                         write_exp_elt_block (pstate, block_found);
+                         write_exp_elt_sym (pstate, sym);
+                         write_exp_elt_opcode (pstate, OP_VAR_VALUE); }
        ;
 
 qualified_name:        TYPENAME COLONCOLON name
                        {
                          struct type *type = $1.type;
                          CHECK_TYPEDEF (type);
-                         if (TYPE_CODE (type) != TYPE_CODE_STRUCT
-                             && TYPE_CODE (type) != TYPE_CODE_UNION
-                             && TYPE_CODE (type) != TYPE_CODE_NAMESPACE)
+                         if (!type_aggregate_p (type))
                            error (_("`%s' is not defined as an aggregate type."),
                                   TYPE_SAFE_NAME (type));
 
-                         write_exp_elt_opcode (OP_SCOPE);
-                         write_exp_elt_type (type);
-                         write_exp_string ($3);
-                         write_exp_elt_opcode (OP_SCOPE);
+                         write_exp_elt_opcode (pstate, OP_SCOPE);
+                         write_exp_elt_type (pstate, type);
+                         write_exp_string (pstate, $3);
+                         write_exp_elt_opcode (pstate, OP_SCOPE);
                        }
        |       TYPENAME COLONCOLON '~' name
                        {
@@ -973,9 +1002,7 @@ qualified_name:    TYPENAME COLONCOLON name
                          char *buf;
 
                          CHECK_TYPEDEF (type);
-                         if (TYPE_CODE (type) != TYPE_CODE_STRUCT
-                             && TYPE_CODE (type) != TYPE_CODE_UNION
-                             && TYPE_CODE (type) != TYPE_CODE_NAMESPACE)
+                         if (!type_aggregate_p (type))
                            error (_("`%s' is not defined as an aggregate type."),
                                   TYPE_SAFE_NAME (type));
                          buf = alloca ($4.length + 2);
@@ -987,10 +1014,10 @@ qualified_name:  TYPENAME COLONCOLON name
 
                          /* Check for valid destructor name.  */
                          destructor_name_p (tmp_token.ptr, $1.type);
-                         write_exp_elt_opcode (OP_SCOPE);
-                         write_exp_elt_type (type);
-                         write_exp_string (tmp_token);
-                         write_exp_elt_opcode (OP_SCOPE);
+                         write_exp_elt_opcode (pstate, OP_SCOPE);
+                         write_exp_elt_type (pstate, type);
+                         write_exp_string (pstate, tmp_token);
+                         write_exp_elt_opcode (pstate, OP_SCOPE);
                        }
        |       TYPENAME COLONCOLON name COLONCOLON name
                        {
@@ -1013,16 +1040,16 @@ variable:       qualified_name
                                           VAR_DOMAIN, NULL);
                          if (sym)
                            {
-                             write_exp_elt_opcode (OP_VAR_VALUE);
-                             write_exp_elt_block (NULL);
-                             write_exp_elt_sym (sym);
-                             write_exp_elt_opcode (OP_VAR_VALUE);
+                             write_exp_elt_opcode (pstate, OP_VAR_VALUE);
+                             write_exp_elt_block (pstate, NULL);
+                             write_exp_elt_sym (pstate, sym);
+                             write_exp_elt_opcode (pstate, OP_VAR_VALUE);
                              break;
                            }
 
                          msymbol = lookup_bound_minimal_symbol (name);
                          if (msymbol.minsym != NULL)
-                           write_exp_msymbol (msymbol);
+                           write_exp_msymbol (pstate, msymbol);
                          else if (!have_full_symbols () && !have_partial_symbols ())
                            error (_("No symbol table is loaded.  Use the \"file\" command."));
                          else
@@ -1038,18 +1065,18 @@ variable:       name_not_typename
                              if (symbol_read_needs_frame (sym))
                                {
                                  if (innermost_block == 0
-                                     || contained_in (block_found, 
+                                     || contained_in (block_found,
                                                       innermost_block))
                                    innermost_block = block_found;
                                }
 
-                             write_exp_elt_opcode (OP_VAR_VALUE);
+                             write_exp_elt_opcode (pstate, OP_VAR_VALUE);
                              /* We want to use the selected frame, not
                                 another more inner frame which happens to
                                 be in the same block.  */
-                             write_exp_elt_block (NULL);
-                             write_exp_elt_sym (sym);
-                             write_exp_elt_opcode (OP_VAR_VALUE);
+                             write_exp_elt_block (pstate, NULL);
+                             write_exp_elt_sym (pstate, sym);
+                             write_exp_elt_opcode (pstate, OP_VAR_VALUE);
                            }
                          else if ($1.is_a_field_of_this)
                            {
@@ -1060,11 +1087,11 @@ variable:       name_not_typename
                                  || contained_in (block_found,
                                                   innermost_block))
                                innermost_block = block_found;
-                             write_exp_elt_opcode (OP_THIS);
-                             write_exp_elt_opcode (OP_THIS);
-                             write_exp_elt_opcode (STRUCTOP_PTR);
-                             write_exp_string ($1.stoken);
-                             write_exp_elt_opcode (STRUCTOP_PTR);
+                             write_exp_elt_opcode (pstate, OP_THIS);
+                             write_exp_elt_opcode (pstate, OP_THIS);
+                             write_exp_elt_opcode (pstate, STRUCTOP_PTR);
+                             write_exp_string (pstate, $1.stoken);
+                             write_exp_elt_opcode (pstate, STRUCTOP_PTR);
                            }
                          else
                            {
@@ -1074,7 +1101,7 @@ variable: name_not_typename
                              msymbol =
                                lookup_bound_minimal_symbol (arg);
                              if (msymbol.minsym != NULL)
-                               write_exp_msymbol (msymbol);
+                               write_exp_msymbol (pstate, msymbol);
                              else if (!have_full_symbols () && !have_partial_symbols ())
                                error (_("No symbol table is loaded.  Use the \"file\" command."));
                              else
@@ -1085,7 +1112,7 @@ variable: name_not_typename
        ;
 
 space_identifier : '@' NAME
-               { insert_type_address_space (copy_name ($2.stoken)); }
+               { insert_type_address_space (pstate, copy_name ($2.stoken)); }
        ;
 
 const_or_volatile: const_or_volatile_noopt
@@ -1096,10 +1123,10 @@ cv_with_space_id : const_or_volatile space_identifier const_or_volatile
        ;
 
 const_or_volatile_or_space_identifier_noopt: cv_with_space_id
-       | const_or_volatile_noopt 
+       | const_or_volatile_noopt
        ;
 
-const_or_volatile_or_space_identifier: 
+const_or_volatile_or_space_identifier:
                const_or_volatile_or_space_identifier_noopt
        |
        ;
@@ -1108,7 +1135,7 @@ ptr_operator:
                ptr_operator '*'
                        { insert_type (tp_pointer); }
                const_or_volatile_or_space_identifier
-       |       '*' 
+       |       '*'
                        { insert_type (tp_pointer); }
                const_or_volatile_or_space_identifier
        |       '&'
@@ -1128,7 +1155,7 @@ ptr_operator_ts: ptr_operator
 
 abs_decl:      ptr_operator_ts direct_abs_decl
                        { $$ = append_type_stack ($2, $1); }
-       |       ptr_operator_ts 
+       |       ptr_operator_ts
        |       direct_abs_decl
        ;
 
@@ -1192,117 +1219,121 @@ typebase  /* Implements (approximately): (type-qualifier)* type-specifier */
        :       TYPENAME
                        { $$ = $1.type; }
        |       INT_KEYWORD
-                       { $$ = lookup_signed_typename (parse_language,
-                                                      parse_gdbarch,
+                       { $$ = lookup_signed_typename (parse_language (pstate),
+                                                      parse_gdbarch (pstate),
                                                       "int"); }
        |       LONG
-                       { $$ = lookup_signed_typename (parse_language,
-                                                      parse_gdbarch,
+                       { $$ = lookup_signed_typename (parse_language (pstate),
+                                                      parse_gdbarch (pstate),
                                                       "long"); }
        |       SHORT
-                       { $$ = lookup_signed_typename (parse_language,
-                                                      parse_gdbarch,
+                       { $$ = lookup_signed_typename (parse_language (pstate),
+                                                      parse_gdbarch (pstate),
                                                       "short"); }
        |       LONG INT_KEYWORD
-                       { $$ = lookup_signed_typename (parse_language,
-                                                      parse_gdbarch,
+                       { $$ = lookup_signed_typename (parse_language (pstate),
+                                                      parse_gdbarch (pstate),
                                                       "long"); }
        |       LONG SIGNED_KEYWORD INT_KEYWORD
-                       { $$ = lookup_signed_typename (parse_language,
-                                                      parse_gdbarch,
+                       { $$ = lookup_signed_typename (parse_language (pstate),
+                                                      parse_gdbarch (pstate),
                                                       "long"); }
        |       LONG SIGNED_KEYWORD
-                       { $$ = lookup_signed_typename (parse_language,
-                                                      parse_gdbarch,
+                       { $$ = lookup_signed_typename (parse_language (pstate),
+                                                      parse_gdbarch (pstate),
                                                       "long"); }
        |       SIGNED_KEYWORD LONG INT_KEYWORD
-                       { $$ = lookup_signed_typename (parse_language,
-                                                      parse_gdbarch,
+                       { $$ = lookup_signed_typename (parse_language (pstate),
+                                                      parse_gdbarch (pstate),
                                                       "long"); }
        |       UNSIGNED LONG INT_KEYWORD
-                       { $$ = lookup_unsigned_typename (parse_language,
-                                                        parse_gdbarch,
+                       { $$ = lookup_unsigned_typename (parse_language (pstate),
+                                                        parse_gdbarch (pstate),
                                                         "long"); }
        |       LONG UNSIGNED INT_KEYWORD
-                       { $$ = lookup_unsigned_typename (parse_language,
-                                                        parse_gdbarch,
+                       { $$ = lookup_unsigned_typename (parse_language (pstate),
+                                                        parse_gdbarch (pstate),
                                                         "long"); }
        |       LONG UNSIGNED
-                       { $$ = lookup_unsigned_typename (parse_language,
-                                                        parse_gdbarch,
+                       { $$ = lookup_unsigned_typename (parse_language (pstate),
+                                                        parse_gdbarch (pstate),
                                                         "long"); }
        |       LONG LONG
-                       { $$ = lookup_signed_typename (parse_language,
-                                                      parse_gdbarch,
+                       { $$ = lookup_signed_typename (parse_language (pstate),
+                                                      parse_gdbarch (pstate),
                                                       "long long"); }
        |       LONG LONG INT_KEYWORD
-                       { $$ = lookup_signed_typename (parse_language,
-                                                      parse_gdbarch,
+                       { $$ = lookup_signed_typename (parse_language (pstate),
+                                                      parse_gdbarch (pstate),
                                                       "long long"); }
        |       LONG LONG SIGNED_KEYWORD INT_KEYWORD
-                       { $$ = lookup_signed_typename (parse_language,
-                                                      parse_gdbarch,
+                       { $$ = lookup_signed_typename (parse_language (pstate),
+                                                      parse_gdbarch (pstate),
                                                       "long long"); }
        |       LONG LONG SIGNED_KEYWORD
-                       { $$ = lookup_signed_typename (parse_language,
-                                                      parse_gdbarch,
+                       { $$ = lookup_signed_typename (parse_language (pstate),
+                                                      parse_gdbarch (pstate),
                                                       "long long"); }
        |       SIGNED_KEYWORD LONG LONG
-                       { $$ = lookup_signed_typename (parse_language,
-                                                      parse_gdbarch,
+                       { $$ = lookup_signed_typename (parse_language (pstate),
+                                                      parse_gdbarch (pstate),
                                                       "long long"); }
        |       SIGNED_KEYWORD LONG LONG INT_KEYWORD
-                       { $$ = lookup_signed_typename (parse_language,
-                                                      parse_gdbarch,
+                       { $$ = lookup_signed_typename (parse_language (pstate),
+                                                      parse_gdbarch (pstate),
                                                       "long long"); }
        |       UNSIGNED LONG LONG
-                       { $$ = lookup_unsigned_typename (parse_language,
-                                                        parse_gdbarch,
+                       { $$ = lookup_unsigned_typename (parse_language (pstate),
+                                                        parse_gdbarch (pstate),
                                                         "long long"); }
        |       UNSIGNED LONG LONG INT_KEYWORD
-                       { $$ = lookup_unsigned_typename (parse_language,
-                                                        parse_gdbarch,
+                       { $$ = lookup_unsigned_typename (parse_language (pstate),
+                                                        parse_gdbarch (pstate),
                                                         "long long"); }
        |       LONG LONG UNSIGNED
-                       { $$ = lookup_unsigned_typename (parse_language,
-                                                        parse_gdbarch,
+                       { $$ = lookup_unsigned_typename (parse_language (pstate),
+                                                        parse_gdbarch (pstate),
                                                         "long long"); }
        |       LONG LONG UNSIGNED INT_KEYWORD
-                       { $$ = lookup_unsigned_typename (parse_language,
-                                                        parse_gdbarch,
+                       { $$ = lookup_unsigned_typename (parse_language (pstate),
+                                                        parse_gdbarch (pstate),
                                                         "long long"); }
        |       SHORT INT_KEYWORD
-                       { $$ = lookup_signed_typename (parse_language,
-                                                      parse_gdbarch,
+                       { $$ = lookup_signed_typename (parse_language (pstate),
+                                                      parse_gdbarch (pstate),
                                                       "short"); }
        |       SHORT SIGNED_KEYWORD INT_KEYWORD
-                       { $$ = lookup_signed_typename (parse_language,
-                                                      parse_gdbarch,
+                       { $$ = lookup_signed_typename (parse_language (pstate),
+                                                      parse_gdbarch (pstate),
                                                       "short"); }
        |       SHORT SIGNED_KEYWORD
-                       { $$ = lookup_signed_typename (parse_language,
-                                                      parse_gdbarch,
+                       { $$ = lookup_signed_typename (parse_language (pstate),
+                                                      parse_gdbarch (pstate),
                                                       "short"); }
        |       UNSIGNED SHORT INT_KEYWORD
-                       { $$ = lookup_unsigned_typename (parse_language,
-                                                        parse_gdbarch,
+                       { $$ = lookup_unsigned_typename (parse_language (pstate),
+                                                        parse_gdbarch (pstate),
                                                         "short"); }
-       |       SHORT UNSIGNED 
-                       { $$ = lookup_unsigned_typename (parse_language,
-                                                        parse_gdbarch,
+       |       SHORT UNSIGNED
+                       { $$ = lookup_unsigned_typename (parse_language (pstate),
+                                                        parse_gdbarch (pstate),
                                                         "short"); }
        |       SHORT UNSIGNED INT_KEYWORD
-                       { $$ = lookup_unsigned_typename (parse_language,
-                                                        parse_gdbarch,
+                       { $$ = lookup_unsigned_typename (parse_language (pstate),
+                                                        parse_gdbarch (pstate),
                                                         "short"); }
        |       DOUBLE_KEYWORD
-                       { $$ = lookup_typename (parse_language, parse_gdbarch,
-                                               "double", (struct block *) NULL,
+                       { $$ = lookup_typename (parse_language (pstate),
+                                               parse_gdbarch (pstate),
+                                               "double",
+                                               (struct block *) NULL,
                                                0); }
        |       LONG DOUBLE_KEYWORD
-                       { $$ = lookup_typename (parse_language, parse_gdbarch,
+                       { $$ = lookup_typename (parse_language (pstate),
+                                               parse_gdbarch (pstate),
                                                "long double",
-                                               (struct block *) NULL, 0); }
+                                               (struct block *) NULL,
+                                               0); }
        |       STRUCT name
                        { $$ = lookup_struct (copy_name ($2),
                                              expression_context_block); }
@@ -1322,12 +1353,12 @@ typebase  /* Implements (approximately): (type-qualifier)* type-specifier */
                                              expression_context_block); }
        |       CLASS COMPLETE
                        {
-                         mark_completion_tag (TYPE_CODE_CLASS, "", 0);
+                         mark_completion_tag (TYPE_CODE_STRUCT, "", 0);
                          $$ = NULL;
                        }
        |       CLASS name COMPLETE
                        {
-                         mark_completion_tag (TYPE_CODE_CLASS, $2.ptr,
+                         mark_completion_tag (TYPE_CODE_STRUCT, $2.ptr,
                                               $2.length);
                          $$ = NULL;
                        }
@@ -1359,58 +1390,58 @@ typebase  /* Implements (approximately): (type-qualifier)* type-specifier */
                                               $2.length);
                          $$ = NULL;
                        }
-       |       UNSIGNED typename
-                       { $$ = lookup_unsigned_typename (parse_language,
-                                                        parse_gdbarch,
+       |       UNSIGNED type_name
+                       { $$ = lookup_unsigned_typename (parse_language (pstate),
+                                                        parse_gdbarch (pstate),
                                                         TYPE_NAME($2.type)); }
        |       UNSIGNED
-                       { $$ = lookup_unsigned_typename (parse_language,
-                                                        parse_gdbarch,
+                       { $$ = lookup_unsigned_typename (parse_language (pstate),
+                                                        parse_gdbarch (pstate),
                                                         "int"); }
-       |       SIGNED_KEYWORD typename
-                       { $$ = lookup_signed_typename (parse_language,
-                                                      parse_gdbarch,
+       |       SIGNED_KEYWORD type_name
+                       { $$ = lookup_signed_typename (parse_language (pstate),
+                                                      parse_gdbarch (pstate),
                                                       TYPE_NAME($2.type)); }
        |       SIGNED_KEYWORD
-                       { $$ = lookup_signed_typename (parse_language,
-                                                      parse_gdbarch,
+                       { $$ = lookup_signed_typename (parse_language (pstate),
+                                                      parse_gdbarch (pstate),
                                                       "int"); }
                 /* It appears that this rule for templates is never
                    reduced; template recognition happens by lookahead
-                   in the token processing code in yylex. */         
+                   in the token processing code in yylex. */
        |       TEMPLATE name '<' type '>'
                        { $$ = lookup_template_type(copy_name($2), $4,
                                                    expression_context_block);
                        }
-       | const_or_volatile_or_space_identifier_noopt typebase 
+       | const_or_volatile_or_space_identifier_noopt typebase
                        { $$ = follow_types ($2); }
-       | typebase const_or_volatile_or_space_identifier_noopt 
+       | typebase const_or_volatile_or_space_identifier_noopt
                        { $$ = follow_types ($1); }
        ;
 
-typename:      TYPENAME
+type_name:     TYPENAME
        |       INT_KEYWORD
                {
                  $$.stoken.ptr = "int";
                  $$.stoken.length = 3;
-                 $$.type = lookup_signed_typename (parse_language,
-                                                   parse_gdbarch,
+                 $$.type = lookup_signed_typename (parse_language (pstate),
+                                                   parse_gdbarch (pstate),
                                                    "int");
                }
        |       LONG
                {
                  $$.stoken.ptr = "long";
                  $$.stoken.length = 4;
-                 $$.type = lookup_signed_typename (parse_language,
-                                                   parse_gdbarch,
+                 $$.type = lookup_signed_typename (parse_language (pstate),
+                                                   parse_gdbarch (pstate),
                                                    "long");
                }
        |       SHORT
                {
                  $$.stoken.ptr = "short";
                  $$.stoken.length = 5;
-                 $$.type = lookup_signed_typename (parse_language,
-                                                   parse_gdbarch,
+                 $$.type = lookup_signed_typename (parse_language (pstate),
+                                                   parse_gdbarch (pstate),
                                                    "short");
                }
        ;
@@ -1460,9 +1491,9 @@ const_and_volatile:       CONST_KEYWORD VOLATILE_KEYWORD
        |               VOLATILE_KEYWORD CONST_KEYWORD
        ;
 
-const_or_volatile_noopt:       const_and_volatile 
+const_or_volatile_noopt:       const_and_volatile
                        { insert_type (tp_const);
-                         insert_type (tp_volatile); 
+                         insert_type (tp_volatile);
                        }
        |               CONST_KEYWORD
                        { insert_type (tp_const); }
@@ -1470,7 +1501,7 @@ const_or_volatile_noopt:          const_and_volatile
                        { insert_type (tp_volatile); }
        ;
 
-operator:      OPERATOR NEW
+oper:  OPERATOR NEW
                        { $$ = operator_stoken (" new"); }
        |       OPERATOR DELETE
                        { $$ = operator_stoken (" delete"); }
@@ -1601,7 +1632,7 @@ name      :       NAME { $$ = $1.stoken; }
        |       TYPENAME { $$ = $1.stoken; }
        |       NAME_OR_INT  { $$ = $1.stoken; }
        |       UNKNOWN_CPP_NAME  { $$ = $1.stoken; }
-       |       operator { $$ = $1; }
+       |       oper { $$ = $1; }
        ;
 
 name_not_typename :    NAME
@@ -1613,7 +1644,7 @@ name_not_typename :       NAME
    context where only a name could occur, this might be useful.
        |       NAME_OR_INT
  */
-       |       operator
+       |       oper
                        {
                          struct field_of_this_result is_a_field_of_this;
 
@@ -1633,7 +1664,7 @@ name_not_typename :       NAME
 /* Like write_exp_string, but prepends a '~'.  */
 
 static void
-write_destructor_name (struct stoken token)
+write_destructor_name (struct parser_state *par_state, struct stoken token)
 {
   char *copy = alloca (token.length + 1);
 
@@ -1643,11 +1674,12 @@ write_destructor_name (struct stoken token)
   token.ptr = copy;
   ++token.length;
 
-  write_exp_string (token);
+  write_exp_string (par_state, token);
 }
 
 /* Returns a stoken of the operator name given by OP (which does not
-   include the string "operator").  */ 
+   include the string "operator").  */
+
 static struct stoken
 operator_stoken (const char *op)
 {
@@ -1666,6 +1698,18 @@ operator_stoken (const char *op)
   return st;
 };
 
+/* Return true if the type is aggregate-like.  */
+
+static int
+type_aggregate_p (struct type *type)
+{
+  return (TYPE_CODE (type) == TYPE_CODE_STRUCT
+         || TYPE_CODE (type) == TYPE_CODE_UNION
+         || TYPE_CODE (type) == TYPE_CODE_NAMESPACE
+         || (TYPE_CODE (type) == TYPE_CODE_ENUM
+             && TYPE_DECLARED_CLASS (type)));
+}
+
 /* Validate a parameter typelist.  */
 
 static void
@@ -1704,7 +1748,8 @@ check_parameter_typelist (VEC (type_ptr) *params)
 /*** Needs some error checking for the float case ***/
 
 static int
-parse_number (const char *buf, int len, int parsed_float, YYSTYPE *putithere)
+parse_number (struct parser_state *par_state,
+             const char *buf, int len, int parsed_float, YYSTYPE *putithere)
 {
   /* FIXME: Shouldn't these be unsigned?  We don't deal with negative values
      here, and we do kind of silly things like cast to unsigned.  */
@@ -1740,9 +1785,10 @@ parse_number (const char *buf, int len, int parsed_float, YYSTYPE *putithere)
        {
          p[len - 2] = '\0';
          putithere->typed_val_decfloat.type
-           = parse_type->builtin_decfloat;
+           = parse_type (par_state)->builtin_decfloat;
          decimal_from_string (putithere->typed_val_decfloat.val, 4,
-                              gdbarch_byte_order (parse_gdbarch), p);
+                              gdbarch_byte_order (parse_gdbarch (par_state)),
+                              p);
          p[len - 2] = 'd';
          return DECFLOAT;
        }
@@ -1751,9 +1797,10 @@ parse_number (const char *buf, int len, int parsed_float, YYSTYPE *putithere)
        {
          p[len - 2] = '\0';
          putithere->typed_val_decfloat.type
-           = parse_type->builtin_decdouble;
+           = parse_type (par_state)->builtin_decdouble;
          decimal_from_string (putithere->typed_val_decfloat.val, 8,
-                              gdbarch_byte_order (parse_gdbarch), p);
+                              gdbarch_byte_order (parse_gdbarch (par_state)),
+                              p);
          p[len - 2] = 'd';
          return DECFLOAT;
        }
@@ -1762,14 +1809,15 @@ parse_number (const char *buf, int len, int parsed_float, YYSTYPE *putithere)
        {
          p[len - 2] = '\0';
          putithere->typed_val_decfloat.type
-           = parse_type->builtin_declong;
+           = parse_type (par_state)->builtin_declong;
          decimal_from_string (putithere->typed_val_decfloat.val, 16,
-                              gdbarch_byte_order (parse_gdbarch), p);
+                              gdbarch_byte_order (parse_gdbarch (par_state)),
+                              p);
          p[len - 2] = 'd';
          return DECFLOAT;
        }
 
-      if (! parse_c_float (parse_gdbarch, p, len,
+      if (! parse_c_float (parse_gdbarch (par_state), p, len,
                           &putithere->typed_val_float.dval,
                           &putithere->typed_val_float.type))
        return ERROR;
@@ -1777,7 +1825,7 @@ parse_number (const char *buf, int len, int parsed_float, YYSTYPE *putithere)
     }
 
   /* Handle base-switching prefixes 0x, 0t, 0d, 0 */
-  if (p[0] == '0')
+  if (p[0] == '0' && len > 1)
     switch (p[1])
       {
       case 'x':
@@ -1885,9 +1933,10 @@ parse_number (const char *buf, int len, int parsed_float, YYSTYPE *putithere)
 
   un = (ULONGEST)n >> 2;
   if (long_p == 0
-      && (un >> (gdbarch_int_bit (parse_gdbarch) - 2)) == 0)
+      && (un >> (gdbarch_int_bit (parse_gdbarch (par_state)) - 2)) == 0)
     {
-      high_bit = ((ULONGEST)1) << (gdbarch_int_bit (parse_gdbarch) - 1);
+      high_bit
+       = ((ULONGEST)1) << (gdbarch_int_bit (parse_gdbarch (par_state)) - 1);
 
       /* A large decimal (not hex or octal) constant (between INT_MAX
         and UINT_MAX) is a long or unsigned long, according to ANSI,
@@ -1895,28 +1944,29 @@ parse_number (const char *buf, int len, int parsed_float, YYSTYPE *putithere)
         int.  This probably should be fixed.  GCC gives a warning on
         such constants.  */
 
-      unsigned_type = parse_type->builtin_unsigned_int;
-      signed_type = parse_type->builtin_int;
+      unsigned_type = parse_type (par_state)->builtin_unsigned_int;
+      signed_type = parse_type (par_state)->builtin_int;
     }
   else if (long_p <= 1
-          && (un >> (gdbarch_long_bit (parse_gdbarch) - 2)) == 0)
+          && (un >> (gdbarch_long_bit (parse_gdbarch (par_state)) - 2)) == 0)
     {
-      high_bit = ((ULONGEST)1) << (gdbarch_long_bit (parse_gdbarch) - 1);
-      unsigned_type = parse_type->builtin_unsigned_long;
-      signed_type = parse_type->builtin_long;
+      high_bit
+       = ((ULONGEST)1) << (gdbarch_long_bit (parse_gdbarch (par_state)) - 1);
+      unsigned_type = parse_type (par_state)->builtin_unsigned_long;
+      signed_type = parse_type (par_state)->builtin_long;
     }
   else
     {
       int shift;
-      if (sizeof (ULONGEST) * HOST_CHAR_BIT 
-         < gdbarch_long_long_bit (parse_gdbarch))
+      if (sizeof (ULONGEST) * HOST_CHAR_BIT
+         < gdbarch_long_long_bit (parse_gdbarch (par_state)))
        /* A long long does not fit in a LONGEST.  */
        shift = (sizeof (ULONGEST) * HOST_CHAR_BIT - 1);
       else
-       shift = (gdbarch_long_long_bit (parse_gdbarch) - 1);
+       shift = (gdbarch_long_long_bit (parse_gdbarch (par_state)) - 1);
       high_bit = (ULONGEST) 1 << shift;
-      unsigned_type = parse_type->builtin_unsigned_long_long;
-      signed_type = parse_type->builtin_long_long;
+      unsigned_type = parse_type (par_state)->builtin_unsigned_long_long;
+      signed_type = parse_type (par_state)->builtin_long_long;
     }
 
    putithere->typed_val_int.val = n;
@@ -1924,11 +1974,11 @@ parse_number (const char *buf, int len, int parsed_float, YYSTYPE *putithere)
    /* If the high bit of the worked out type is set then this number
       has to be unsigned. */
 
-   if (unsigned_p || (n & high_bit)) 
+   if (unsigned_p || (n & high_bit))
      {
        putithere->typed_val_int.type = unsigned_type;
      }
-   else 
+   else
      {
        putithere->typed_val_int.type = signed_type;
      }
@@ -2110,6 +2160,7 @@ c_parse_escape (const char **ptr, struct obstack *output)
    stored in VALUE.  This returns a token value, either STRING or
    CHAR, depending on what was parsed.  *HOST_CHARS is set to the
    number of host characters in the literal.  */
+
 static int
 parse_string_or_char (const char *tokptr, const char **outptr,
                      struct typed_stoken *value, int *host_chars)
@@ -2223,7 +2274,7 @@ enum token_flags
 
 struct token
 {
-  char *operator;
+  char *oper;
   int token;
   enum exp_opcode opcode;
   enum token_flags flags;
@@ -2359,15 +2410,13 @@ scan_macro_expansion (char *expansion)
   lexptr = copy;
 }
 
-
 static int
 scanning_macro_expansion (void)
 {
   return macro_original_text != 0;
 }
 
-
-static void 
+static void
 finished_macro_expansion (void)
 {
   /* There'd better be something to pop back to.  */
@@ -2378,7 +2427,6 @@ finished_macro_expansion (void)
   macro_original_text = 0;
 }
 
-
 static void
 scan_macro_cleanup (void *dummy)
 {
@@ -2415,7 +2463,7 @@ static int last_was_structop;
 /* Read one token, getting characters through lexptr.  */
 
 static int
-lex_one_token (int *is_quoted_name)
+lex_one_token (struct parser_state *par_state, int *is_quoted_name)
 {
   int c;
   int namelen;
@@ -2445,10 +2493,10 @@ lex_one_token (int *is_quoted_name)
   tokstart = lexptr;
   /* See if it is a special token of length 3.  */
   for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
-    if (strncmp (tokstart, tokentab3[i].operator, 3) == 0)
+    if (strncmp (tokstart, tokentab3[i].oper, 3) == 0)
       {
        if ((tokentab3[i].flags & FLAG_CXX) != 0
-           && parse_language->la_language != language_cplus)
+           && parse_language (par_state)->la_language != language_cplus)
          break;
 
        lexptr += 3;
@@ -2458,10 +2506,10 @@ lex_one_token (int *is_quoted_name)
 
   /* See if it is a special token of length 2.  */
   for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
-    if (strncmp (tokstart, tokentab2[i].operator, 2) == 0)
+    if (strncmp (tokstart, tokentab2[i].oper, 2) == 0)
       {
        if ((tokentab2[i].flags & FLAG_CXX) != 0
-           && parse_language->la_language != language_cplus)
+           && parse_language (par_state)->la_language != language_cplus)
          break;
 
        lexptr += 2;
@@ -2505,7 +2553,8 @@ lex_one_token (int *is_quoted_name)
     case '(':
       paren_depth++;
       lexptr++;
-      if (parse_language->la_language == language_objc && c == '[')
+      if (parse_language (par_state)->la_language == language_objc
+         && c == '[')
        return OBJC_LBRAC;
       return c;
 
@@ -2585,7 +2634,8 @@ lex_one_token (int *is_quoted_name)
                                  && (*p < 'A' || *p > 'Z')))
              break;
          }
-       toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval);
+       toktype = parse_number (par_state, tokstart, p - tokstart,
+                               got_dot|got_e, &yylval);
         if (toktype == ERROR)
          {
            char *err_copy = (char *) alloca (p - tokstart + 1);
@@ -2603,7 +2653,7 @@ lex_one_token (int *is_quoted_name)
        const char *p = &tokstart[1];
        size_t len = strlen ("entry");
 
-       if (parse_language->la_language == language_objc)
+       if (parse_language (par_state)->la_language == language_objc)
          {
            size_t len = strlen ("selector");
 
@@ -2703,7 +2753,6 @@ lex_one_token (int *is_quoted_name)
                 that we look ahead only when the '<' adjoins non-whitespace
                 characters; for comparison expressions, e.g. "a < b > c",
                 there must be spaces before the '<', etc. */
-               
              const char *p = find_template_name_end (tokstart + namelen);
 
              if (p)
@@ -2754,10 +2803,10 @@ lex_one_token (int *is_quoted_name)
   /* Catch specific keywords.  */
   copy = copy_name (yylval.sval);
   for (i = 0; i < sizeof ident_tokens / sizeof ident_tokens[0]; i++)
-    if (strcmp (copy, ident_tokens[i].operator) == 0)
+    if (strcmp (copy, ident_tokens[i].oper) == 0)
       {
        if ((ident_tokens[i].flags & FLAG_CXX) != 0
-           && parse_language->la_language != language_cplus)
+           && parse_language (par_state)->la_language != language_cplus)
          break;
 
        if ((ident_tokens[i].flags & FLAG_SHADOW) != 0)
@@ -2766,8 +2815,8 @@ lex_one_token (int *is_quoted_name)
 
            if (lookup_symbol (copy, expression_context_block,
                               VAR_DOMAIN,
-                              (parse_language->la_language == language_cplus
-                               ? &is_a_field_of_this
+                              (parse_language (par_state)->la_language
+                               == language_cplus ? &is_a_field_of_this
                                : NULL))
                != NULL)
              {
@@ -2819,8 +2868,10 @@ static struct obstack name_obstack;
    in which lookups start; this can be NULL to mean the global scope.
    IS_QUOTED_NAME is non-zero if the name token was originally quoted
    in single quotes.  */
+
 static int
-classify_name (const struct block *block, int is_quoted_name)
+classify_name (struct parser_state *par_state, const struct block *block,
+              int is_quoted_name)
 {
   struct symbol *sym;
   char *copy;
@@ -2832,8 +2883,8 @@ classify_name (const struct block *block, int is_quoted_name)
      we can refer to it unconditionally below.  */
   memset (&is_a_field_of_this, 0, sizeof (is_a_field_of_this));
 
-  sym = lookup_symbol (copy, block, VAR_DOMAIN, 
-                      parse_language->la_name_of_this
+  sym = lookup_symbol (copy, block, VAR_DOMAIN,
+                      parse_language (par_state)->la_name_of_this
                       ? &is_a_field_of_this : NULL);
 
   if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)
@@ -2876,7 +2927,7 @@ classify_name (const struct block *block, int is_quoted_name)
          symtab = lookup_symtab (copy);
          if (symtab)
            {
-             yylval.bval = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab),
+             yylval.bval = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (symtab),
                                               STATIC_BLOCK);
              return FILENAME;
            }
@@ -2889,22 +2940,16 @@ classify_name (const struct block *block, int is_quoted_name)
       return TYPENAME;
     }
 
-  yylval.tsym.type
-    = language_lookup_primitive_type_by_name (parse_language,
-                                             parse_gdbarch, copy);
-  if (yylval.tsym.type != NULL)
-    return TYPENAME;
-
   /* See if it's an ObjC classname.  */
-  if (parse_language->la_language == language_objc && !sym)
+  if (parse_language (par_state)->la_language == language_objc && !sym)
     {
-      CORE_ADDR Class = lookup_objc_class (parse_gdbarch, copy);
+      CORE_ADDR Class = lookup_objc_class (parse_gdbarch (par_state), copy);
       if (Class)
        {
-         yylval.class.class = Class;
+         yylval.theclass.theclass = Class;
          sym = lookup_struct_typedef (copy, expression_context_block, 1);
          if (sym)
-           yylval.class.type = SYMBOL_TYPE (sym);
+           yylval.theclass.type = SYMBOL_TYPE (sym);
          return CLASSNAME;
        }
     }
@@ -2917,7 +2962,8 @@ classify_name (const struct block *block, int is_quoted_name)
          || (copy[0] >= 'A' && copy[0] < 'A' + input_radix - 10)))
     {
       YYSTYPE newlval; /* Its value is ignored.  */
-      int hextype = parse_number (copy, yylval.sval.length, 0, &newlval);
+      int hextype = parse_number (par_state, copy, yylval.sval.length,
+                                 0, &newlval);
       if (hextype == INT)
        {
          yylval.ssym.sym = sym;
@@ -2931,9 +2977,9 @@ classify_name (const struct block *block, int is_quoted_name)
   yylval.ssym.is_a_field_of_this = is_a_field_of_this.type != NULL;
 
   if (sym == NULL
-      && parse_language->la_language == language_cplus
+      && parse_language (par_state)->la_language == language_cplus
       && is_a_field_of_this.type == NULL
-      && !lookup_minimal_symbol (copy, NULL, NULL))
+      && lookup_minimal_symbol (copy, NULL, NULL).minsym == NULL)
     return UNKNOWN_CPP_NAME;
 
   return NAME;
@@ -2944,33 +2990,58 @@ classify_name (const struct block *block, int is_quoted_name)
    NULL if this is the first component of a name.  */
 
 static int
-classify_inner_name (const struct block *block, struct type *context)
+classify_inner_name (struct parser_state *par_state,
+                    const struct block *block, struct type *context)
 {
   struct type *type;
   char *copy;
 
   if (context == NULL)
-    return classify_name (block, 0);
+    return classify_name (par_state, block, 0);
 
   type = check_typedef (context);
-  if (TYPE_CODE (type) != TYPE_CODE_STRUCT
-      && TYPE_CODE (type) != TYPE_CODE_UNION
-      && TYPE_CODE (type) != TYPE_CODE_NAMESPACE)
+  if (!type_aggregate_p (type))
     return ERROR;
 
   copy = copy_name (yylval.ssym.stoken);
   yylval.ssym.sym = cp_lookup_nested_symbol (type, copy, block);
+
+  /* If no symbol was found, search for a matching base class named
+     COPY.  This will allow users to enter qualified names of class members
+     relative to the `this' pointer.  */
   if (yylval.ssym.sym == NULL)
-    return ERROR;
+    {
+      struct type *base_type = cp_find_type_baseclass_by_name (type, copy);
+
+      if (base_type != NULL)
+       {
+         yylval.tsym.type = base_type;
+         return TYPENAME;
+       }
+
+      return ERROR;
+    }
 
   switch (SYMBOL_CLASS (yylval.ssym.sym))
     {
     case LOC_BLOCK:
     case LOC_LABEL:
+      /* cp_lookup_nested_symbol might have accidentally found a constructor
+        named COPY when we really wanted a base class of the same name.
+        Double-check this case by looking for a base class.  */
+      {
+       struct type *base_type = cp_find_type_baseclass_by_name (type, copy);
+
+       if (base_type != NULL)
+         {
+           yylval.tsym.type = base_type;
+           return TYPENAME;
+         }
+      }
       return ERROR;
 
     case LOC_TYPEDEF:
-      yylval.tsym.type = SYMBOL_TYPE (yylval.ssym.sym);;
+      yylval.tsym.type = SYMBOL_TYPE (yylval.ssym.sym);
       return TYPENAME;
 
     default:
@@ -2985,11 +3056,12 @@ classify_inner_name (const struct block *block, struct type *context)
    problem in our parsing approach, where the parser could not
    distinguish between qualified names and qualified types at the
    right point.
-   
+
    This approach is still not ideal, because it mishandles template
    types.  See the comment in lex_one_token for an example.  However,
    this is still an improvement over the earlier approach, and will
    suffice until we move to better parsing technology.  */
+
 static int
 yylex (void)
 {
@@ -3007,10 +3079,11 @@ yylex (void)
   /* Read the first token and decide what to do.  Most of the
      subsequent code is C++-only; but also depends on seeing a "::" or
      name-like token.  */
-  current.token = lex_one_token (&is_quoted_name);
+  current.token = lex_one_token (pstate, &is_quoted_name);
   if (current.token == NAME)
-    current.token = classify_name (expression_context_block, is_quoted_name);
-  if (parse_language->la_language != language_cplus
+    current.token = classify_name (pstate, expression_context_block,
+                                  is_quoted_name);
+  if (parse_language (pstate)->la_language != language_cplus
       || (current.token != TYPENAME && current.token != COLONCOLON
          && current.token != FILENAME))
     return current.token;
@@ -3026,7 +3099,7 @@ yylex (void)
 
       /* We ignore quoted names other than the very first one.
         Subsequent ones do not have any special meaning.  */
-      current.token = lex_one_token (&ignore);
+      current.token = lex_one_token (pstate, &ignore);
       current.value = yylval;
       VEC_safe_push (token_and_value, token_fifo, &current);
 
@@ -3076,7 +3149,8 @@ yylex (void)
          int classification;
 
          yylval = next->value;
-         classification = classify_inner_name (search_block, context_type);
+         classification = classify_inner_name (pstate, search_block,
+                                               context_type);
          /* We keep going until we either run out of names, or until
             we have a qualified name which is not a type.  */
          if (classification != TYPENAME && classification != NAME)
@@ -3100,7 +3174,7 @@ yylex (void)
          current.token = classification;
 
          last_was_coloncolon = 0;
-         
+
          if (classification == NAME)
            break;
 
@@ -3136,11 +3210,17 @@ yylex (void)
 }
 
 int
-c_parse (void)
+c_parse (struct parser_state *par_state)
 {
   int result;
-  struct cleanup *back_to = make_cleanup (free_current_contents,
-                                         &expression_macro_scope);
+  struct cleanup *back_to;
+
+  /* Setting up the parser state.  */
+  gdb_assert (par_state != NULL);
+  pstate = par_state;
+
+  back_to = make_cleanup (free_current_contents, &expression_macro_scope);
+  make_cleanup_clear_parser_state (&pstate);
 
   /* Set up the scope for macro expansion.  */
   expression_macro_scope = NULL;
@@ -3172,9 +3252,12 @@ c_parse (void)
 
   result = yyparse ();
   do_cleanups (back_to);
+
   return result;
 }
 
+#ifdef YYBISON
+
 /* This is called via the YYPRINT macro when parser debugging is
    enabled.  It prints a token's value.  */
 
@@ -3229,6 +3312,8 @@ c_print_token (FILE *file, int type, YYSTYPE value)
     }
 }
 
+#endif
+
 void
 yyerror (char *msg)
 {
This page took 0.0568 seconds and 4 git commands to generate.