/* YACC parser for C expressions, for GDB.
- Copyright (C) 1986-2013 Free Software Foundation, Inc.
+ Copyright (C) 1986-2014 Free Software Foundation, Inc.
This file is part of GDB.
%{
#include "defs.h"
-#include "gdb_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,
struct ttype tsym;
struct symtoken ssym;
int voidval;
- struct block *bval;
+ const struct block *bval;
enum exp_opcode opcode;
struct stoken_vector svec;
%{
/* YYSTYPE gets defined by %union */
-static int parse_number (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
;
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); }
;
/*
{
CORE_ADDR class;
- class = lookup_objc_class (parse_gdbarch,
+ class = lookup_objc_class (parse_gdbarch (pstate),
copy_name ($2.stoken));
if (class == 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) class);
+ 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.class);
+ 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);
}
;
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. */
}
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);
}
;
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);
}
;
{ $$ = 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 ')'
/* 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
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
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:
}
}
- 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);
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); }
+ { 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); }
+ { 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++. */
"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);
}
;
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
{
struct type *type = $1.type;
struct stoken tmp_token;
+ 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));
-
- tmp_token.ptr = (char*) alloca ($4.length + 2);
+ buf = alloca ($4.length + 2);
+ tmp_token.ptr = buf;
tmp_token.length = $4.length + 1;
- tmp_token.ptr[0] = '~';
- memcpy (tmp_token.ptr+1, $4.ptr, $4.length);
- tmp_token.ptr[tmp_token.length] = 0;
+ buf[0] = '~';
+ memcpy (buf+1, $4.ptr, $4.length);
+ buf[tmp_token.length] = 0;
/* 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
{
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
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)
{
|| 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
{
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
;
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
: 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,
+ { $$ = 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); }
$$ = NULL;
}
| UNSIGNED typename
- { $$ = lookup_unsigned_typename (parse_language,
- parse_gdbarch,
+ { $$ = 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,
+ { $$ = 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
{
$$.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");
}
;
/* 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);
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
{
static const char *operator_string = "operator";
struct stoken st = { NULL, 0 };
+ char *buf;
+
st.length = strlen (operator_string) + strlen (op);
- st.ptr = malloc (st.length + 1);
- strcpy (st.ptr, operator_string);
- strcat (st.ptr, op);
+ buf = malloc (st.length + 1);
+ strcpy (buf, operator_string);
+ strcat (buf, op);
+ st.ptr = buf;
/* The toplevel (c_parse) will free the memory allocated here. */
- make_cleanup (free, st.ptr);
+ make_cleanup (free, buf);
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
/*** Needs some error checking for the float case ***/
static int
-parse_number (char *p, 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. */
ULONGEST high_bit;
struct type *signed_type;
struct type *unsigned_type;
+ char *p;
+
+ p = alloca (len);
+ memcpy (p, buf, len);
if (parsed_float)
{
{
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;
}
{
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;
}
{
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;
}
/* Handle base-switching prefixes 0x, 0t, 0d, 0 */
- if (p[0] == '0')
+ if (p[0] == '0' && len > 1)
switch (p[1])
{
case 'x':
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,
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))
+ < 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;
character was emitted, 0 otherwise. */
int
-c_parse_escape (char **ptr, struct obstack *output)
+c_parse_escape (const char **ptr, struct obstack *output)
{
- char *tokptr = *ptr;
+ const char *tokptr = *ptr;
int result = 1;
/* Some escape sequences undergo character set conversion. Those we
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 (char *tokptr, char **outptr, struct typed_stoken *value,
- int *host_chars)
+parse_string_or_char (const char *tokptr, const char **outptr,
+ struct typed_stoken *value, int *host_chars)
{
int quote;
enum c_string_type type;
we evaluate ADDRESS in the scope of the current frame, but we
evaluate CONDITION in the scope of the breakpoint's location. So
it's simply wrong to try to macro-expand the whole thing at once. */
-static char *macro_original_text;
+static const char *macro_original_text;
/* We save all intermediate macro expansions on this obstack for the
duration of a single parse. The expansion text may sometimes have
/* Read one token, getting characters through lexptr. */
static int
-lex_one_token (void)
+lex_one_token (struct parser_state *par_state, int *is_quoted_name)
{
int c;
int namelen;
unsigned int i;
- char *tokstart;
+ const char *tokstart;
int saw_structop = last_was_structop;
char *copy;
last_was_structop = 0;
+ *is_quoted_name = 0;
retry:
if (strncmp (tokstart, tokentab3[i].operator, 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;
if (strncmp (tokstart, tokentab2[i].operator, 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;
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;
{
/* It's a number. */
int got_dot = 0, got_e = 0, toktype;
- char *p = tokstart;
+ const char *p = tokstart;
int hex = input_radix > 10;
if (c == '0' && (p[1] == 'x' || p[1] == 'X'))
&& (*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);
case '@':
{
- char *p = &tokstart[1];
+ 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");
{
++tokstart;
namelen = lexptr - tokstart - 1;
+ *is_quoted_name = 1;
+
goto tryname;
}
else if (host_len > 1)
characters; for comparison expressions, e.g. "a < b > c",
there must be spaces before the '<', etc. */
- char * p = find_template_name_end (tokstart + namelen);
+ const char *p = find_template_name_end (tokstart + namelen);
+
if (p)
namelen = p - tokstart;
}
&& (tokstart[namelen] == ' ' || tokstart[namelen] == '\t')
&& ! scanning_macro_expansion ())
{
- char *p = tokstart + namelen + 1;
+ const char *p = tokstart + namelen + 1;
+
while (*p == ' ' || *p == '\t')
p++;
if (*p >= '0' && *p <= '9')
if (strcmp (copy, ident_tokens[i].operator) == 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)
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)
{
/* Classify a NAME token. The contents of the token are in `yylval'.
Updates yylval and returns the new token type. BLOCK is the block
- in which lookups start; this can be NULL to mean the global
- scope. */
+ 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)
+classify_name (struct parser_state *par_state, const struct block *block,
+ int is_quoted_name)
{
struct symbol *sym;
char *copy;
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
+ parse_language (par_state)->la_name_of_this
? &is_a_field_of_this : NULL);
if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)
}
else if (!sym)
{
- /* See if it's a file name. */
- struct symtab *symtab;
-
- symtab = lookup_symtab (copy);
- if (symtab)
- {
- yylval.bval = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
- return FILENAME;
- }
-
/* If we found a field of 'this', we might have erroneously
found a constructor where we wanted a type name. Handle this
case by noticing that we found a constructor and then look up
return TYPENAME;
}
}
+
+ /* If we found a field, then we want to prefer it over a
+ filename. However, if the name was quoted, then it is better
+ to check for a filename or a block, since this is the only
+ way the user has of requiring the extension to be used. */
+ if (is_a_field_of_this.type == NULL || is_quoted_name)
+ {
+ /* See if it's a file name. */
+ struct symtab *symtab;
+
+ symtab = lookup_symtab (copy);
+ if (symtab)
+ {
+ yylval.bval = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab),
+ STATIC_BLOCK);
+ return FILENAME;
+ }
+ }
}
if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
}
yylval.tsym.type
- = language_lookup_primitive_type_by_name (parse_language,
- parse_gdbarch, copy);
+ = language_lookup_primitive_type_by_name (parse_language (par_state),
+ parse_gdbarch (par_state),
+ 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;
|| (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;
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;
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);
+ 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 = 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 = find_type_baseclass_by_name (type, copy);
+
+ if (base_type != NULL)
+ {
+ yylval.tsym.type = base_type;
+ return TYPENAME;
+ }
+ }
return ERROR;
case LOC_TYPEDEF:
struct type *context_type = NULL;
int last_to_examine, next_to_examine, checkpoint;
const struct block *search_block;
+ int is_quoted_name;
if (popping && !VEC_empty (token_and_value, token_fifo))
goto do_pop;
/* 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 ();
+ current.token = lex_one_token (pstate, &is_quoted_name);
if (current.token == NAME)
- current.token = classify_name (expression_context_block);
- 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;
last_was_coloncolon = current.token == COLONCOLON;
while (1)
{
- current.token = lex_one_token ();
+ int ignore;
+
+ /* We ignore quoted names other than the very first one.
+ Subsequent ones do not have any special meaning. */
+ current.token = lex_one_token (pstate, &ignore);
current.value = yylval;
VEC_safe_push (token_and_value, token_fifo, ¤t);
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)
}
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;
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. */
}
}
+#endif
+
void
yyerror (char *msg)
{