198944Sobrien/* YACC parser for Pascal expressions, for GDB.
298944Sobrien   Copyright 2000
398944Sobrien   Free Software Foundation, Inc.
498944Sobrien
598944SobrienThis file is part of GDB.
698944Sobrien
798944SobrienThis program is free software; you can redistribute it and/or modify
898944Sobrienit under the terms of the GNU General Public License as published by
998944Sobrienthe Free Software Foundation; either version 2 of the License, or
1098944Sobrien(at your option) any later version.
1198944Sobrien
1298944SobrienThis program is distributed in the hope that it will be useful,
1398944Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of
1498944SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1598944SobrienGNU General Public License for more details.
1698944Sobrien
1798944SobrienYou should have received a copy of the GNU General Public License
1898944Sobrienalong with this program; if not, write to the Free Software
1998944SobrienFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
2098944Sobrien
2198944Sobrien/* This file is derived from c-exp.y */
2298944Sobrien
2398944Sobrien/* Parse a Pascal expression from text in a string,
2498944Sobrien   and return the result as a  struct expression  pointer.
2598944Sobrien   That structure contains arithmetic operations in reverse polish,
2698944Sobrien   with constants represented by operations that are followed by special data.
2798944Sobrien   See expression.h for the details of the format.
2898944Sobrien   What is important here is that it can be built up sequentially
2998944Sobrien   during the process of parsing; the lower levels of the tree always
3098944Sobrien   come first in the result.
3198944Sobrien
3298944Sobrien   Note that malloc's and realloc's in this file are transformed to
3398944Sobrien   xmalloc and xrealloc respectively by the same sed command in the
3498944Sobrien   makefile that remaps any other malloc/realloc inserted by the parser
3598944Sobrien   generator.  Doing this with #defines and trying to control the interaction
3698944Sobrien   with include files (<malloc.h> and <stdlib.h> for example) just became
3798944Sobrien   too messy, particularly when such includes can be inserted at random
3898944Sobrien   times by the parser generator.  */
3998944Sobrien
40130803Smarcel/* Known bugs or limitations:
4198944Sobrien    - pascal string operations are not supported at all.
4298944Sobrien    - there are some problems with boolean types.
4398944Sobrien    - Pascal type hexadecimal constants are not supported
4498944Sobrien      because they conflict with the internal variables format.
4598944Sobrien   Probably also lots of other problems, less well defined PM */
4698944Sobrien%{
4798944Sobrien
4898944Sobrien#include "defs.h"
4998944Sobrien#include "gdb_string.h"
5098944Sobrien#include <ctype.h>
5198944Sobrien#include "expression.h"
5298944Sobrien#include "value.h"
5398944Sobrien#include "parser-defs.h"
5498944Sobrien#include "language.h"
5598944Sobrien#include "p-lang.h"
5698944Sobrien#include "bfd.h" /* Required by objfiles.h.  */
5798944Sobrien#include "symfile.h" /* Required by objfiles.h.  */
5898944Sobrien#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
59130803Smarcel#include "block.h"
6098944Sobrien
6198944Sobrien/* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
6298944Sobrien   as well as gratuitiously global symbol names, so we can have multiple
6398944Sobrien   yacc generated parsers in gdb.  Note that these are only the variables
6498944Sobrien   produced by yacc.  If other parser generators (bison, byacc, etc) produce
6598944Sobrien   additional global names that conflict at link time, then those parser
6698944Sobrien   generators need to be fixed instead of adding those names to this list. */
6798944Sobrien
6898944Sobrien#define	yymaxdepth pascal_maxdepth
6998944Sobrien#define	yyparse	pascal_parse
7098944Sobrien#define	yylex	pascal_lex
7198944Sobrien#define	yyerror	pascal_error
7298944Sobrien#define	yylval	pascal_lval
7398944Sobrien#define	yychar	pascal_char
7498944Sobrien#define	yydebug	pascal_debug
7598944Sobrien#define	yypact	pascal_pact
7698944Sobrien#define	yyr1	pascal_r1
7798944Sobrien#define	yyr2	pascal_r2
7898944Sobrien#define	yydef	pascal_def
7998944Sobrien#define	yychk	pascal_chk
8098944Sobrien#define	yypgo	pascal_pgo
8198944Sobrien#define	yyact	pascal_act
8298944Sobrien#define	yyexca	pascal_exca
8398944Sobrien#define yyerrflag pascal_errflag
8498944Sobrien#define yynerrs	pascal_nerrs
8598944Sobrien#define	yyps	pascal_ps
8698944Sobrien#define	yypv	pascal_pv
8798944Sobrien#define	yys	pascal_s
8898944Sobrien#define	yy_yys	pascal_yys
8998944Sobrien#define	yystate	pascal_state
9098944Sobrien#define	yytmp	pascal_tmp
9198944Sobrien#define	yyv	pascal_v
9298944Sobrien#define	yy_yyv	pascal_yyv
9398944Sobrien#define	yyval	pascal_val
9498944Sobrien#define	yylloc	pascal_lloc
9598944Sobrien#define yyreds	pascal_reds		/* With YYDEBUG defined */
9698944Sobrien#define yytoks	pascal_toks		/* With YYDEBUG defined */
97130803Smarcel#define yyname	pascal_name		/* With YYDEBUG defined */
98130803Smarcel#define yyrule	pascal_rule		/* With YYDEBUG defined */
9998944Sobrien#define yylhs	pascal_yylhs
10098944Sobrien#define yylen	pascal_yylen
10198944Sobrien#define yydefred pascal_yydefred
10298944Sobrien#define yydgoto	pascal_yydgoto
10398944Sobrien#define yysindex pascal_yysindex
10498944Sobrien#define yyrindex pascal_yyrindex
10598944Sobrien#define yygindex pascal_yygindex
10698944Sobrien#define yytable	 pascal_yytable
10798944Sobrien#define yycheck	 pascal_yycheck
10898944Sobrien
10998944Sobrien#ifndef YYDEBUG
110130803Smarcel#define	YYDEBUG 1		/* Default to yydebug support */
11198944Sobrien#endif
11298944Sobrien
113130803Smarcel#define YYFPRINTF parser_fprintf
114130803Smarcel
11598944Sobrienint yyparse (void);
11698944Sobrien
11798944Sobrienstatic int yylex (void);
11898944Sobrien
11998944Sobrienvoid
12098944Sobrienyyerror (char *);
12198944Sobrien
12298944Sobrienstatic char * uptok (char *, int);
12398944Sobrien%}
12498944Sobrien
12598944Sobrien/* Although the yacc "value" of an expression is not used,
12698944Sobrien   since the result is stored in the structure being created,
12798944Sobrien   other node types do have values.  */
12898944Sobrien
12998944Sobrien%union
13098944Sobrien  {
13198944Sobrien    LONGEST lval;
13298944Sobrien    struct {
13398944Sobrien      LONGEST val;
13498944Sobrien      struct type *type;
13598944Sobrien    } typed_val_int;
13698944Sobrien    struct {
13798944Sobrien      DOUBLEST dval;
13898944Sobrien      struct type *type;
13998944Sobrien    } typed_val_float;
14098944Sobrien    struct symbol *sym;
14198944Sobrien    struct type *tval;
14298944Sobrien    struct stoken sval;
14398944Sobrien    struct ttype tsym;
14498944Sobrien    struct symtoken ssym;
14598944Sobrien    int voidval;
14698944Sobrien    struct block *bval;
14798944Sobrien    enum exp_opcode opcode;
14898944Sobrien    struct internalvar *ivar;
14998944Sobrien
15098944Sobrien    struct type **tvec;
15198944Sobrien    int *ivec;
15298944Sobrien  }
15398944Sobrien
15498944Sobrien%{
15598944Sobrien/* YYSTYPE gets defined by %union */
15698944Sobrienstatic int
15798944Sobrienparse_number (char *, int, int, YYSTYPE *);
158130803Smarcel
159130803Smarcelstatic struct type *current_type;
160130803Smarcel
161130803Smarcelstatic void push_current_type (void);
162130803Smarcelstatic void pop_current_type (void);
163130803Smarcelstatic int search_field;
16498944Sobrien%}
16598944Sobrien
166130803Smarcel%type <voidval> exp exp1 type_exp start normal_start variable qualified_name
16798944Sobrien%type <tval> type typebase
16898944Sobrien/* %type <bval> block */
16998944Sobrien
17098944Sobrien/* Fancy type parsing.  */
17198944Sobrien%type <tval> ptype
17298944Sobrien
17398944Sobrien%token <typed_val_int> INT
17498944Sobrien%token <typed_val_float> FLOAT
17598944Sobrien
17698944Sobrien/* Both NAME and TYPENAME tokens represent symbols in the input,
17798944Sobrien   and both convey their data as strings.
17898944Sobrien   But a TYPENAME is a string that happens to be defined as a typedef
17998944Sobrien   or builtin type name (such as int or char)
18098944Sobrien   and a NAME is any other symbol.
18198944Sobrien   Contexts where this distinction is not important can use the
18298944Sobrien   nonterminal "name", which matches either NAME or TYPENAME.  */
18398944Sobrien
184130803Smarcel%token <sval> STRING
185130803Smarcel%token <sval> FIELDNAME
18698944Sobrien%token <ssym> NAME /* BLOCKNAME defined below to give it higher precedence. */
18798944Sobrien%token <tsym> TYPENAME
18898944Sobrien%type <sval> name
18998944Sobrien%type <ssym> name_not_typename
19098944Sobrien
19198944Sobrien/* A NAME_OR_INT is a symbol which is not known in the symbol table,
19298944Sobrien   but which would parse as a valid number in the current input radix.
19398944Sobrien   E.g. "c" when input_radix==16.  Depending on the parse, it will be
19498944Sobrien   turned into a name or into a number.  */
19598944Sobrien
19698944Sobrien%token <ssym> NAME_OR_INT
19798944Sobrien
19898944Sobrien%token STRUCT CLASS SIZEOF COLONCOLON
19998944Sobrien%token ERROR
20098944Sobrien
20198944Sobrien/* Special type cases, put in to allow the parser to distinguish different
20298944Sobrien   legal basetypes.  */
20398944Sobrien
20498944Sobrien%token <voidval> VARIABLE
20598944Sobrien
20698944Sobrien
20798944Sobrien/* Object pascal */
20898944Sobrien%token THIS
209130803Smarcel%token <lval> TRUEKEYWORD FALSEKEYWORD
21098944Sobrien
21198944Sobrien%left ','
21298944Sobrien%left ABOVE_COMMA
21398944Sobrien%right ASSIGN
21498944Sobrien%left NOT
21598944Sobrien%left OR
21698944Sobrien%left XOR
21798944Sobrien%left ANDAND
21898944Sobrien%left '=' NOTEQUAL
21998944Sobrien%left '<' '>' LEQ GEQ
22098944Sobrien%left LSH RSH DIV MOD
22198944Sobrien%left '@'
22298944Sobrien%left '+' '-'
22398944Sobrien%left '*' '/'
22498944Sobrien%right UNARY INCREMENT DECREMENT
22598944Sobrien%right ARROW '.' '[' '('
226130803Smarcel%left '^'
22798944Sobrien%token <ssym> BLOCKNAME
22898944Sobrien%type <bval> block
22998944Sobrien%left COLONCOLON
23098944Sobrien
23198944Sobrien
23298944Sobrien%%
23398944Sobrien
234130803Smarcelstart   :	{ current_type = NULL;
235130803Smarcel		  search_field = 0;
236130803Smarcel		}
237130803Smarcel		normal_start {}
238130803Smarcel	;
239130803Smarcel
240130803Smarcelnormal_start	:
241130803Smarcel		exp1
24298944Sobrien	|	type_exp
24398944Sobrien	;
24498944Sobrien
24598944Sobrientype_exp:	type
24698944Sobrien			{ write_exp_elt_opcode(OP_TYPE);
24798944Sobrien			  write_exp_elt_type($1);
248130803Smarcel			  write_exp_elt_opcode(OP_TYPE);
249130803Smarcel			  current_type = $1; } ;
25098944Sobrien
25198944Sobrien/* Expressions, including the comma operator.  */
25298944Sobrienexp1	:	exp
25398944Sobrien	|	exp1 ',' exp
25498944Sobrien			{ write_exp_elt_opcode (BINOP_COMMA); }
25598944Sobrien	;
25698944Sobrien
25798944Sobrien/* Expressions, not including the comma operator.  */
25898944Sobrienexp	:	exp '^'   %prec UNARY
259130803Smarcel			{ write_exp_elt_opcode (UNOP_IND);
260130803Smarcel			  if (current_type)
261130803Smarcel			    current_type = TYPE_TARGET_TYPE (current_type); }
262130803Smarcel	;
26398944Sobrien
26498944Sobrienexp	:	'@' exp    %prec UNARY
265130803Smarcel			{ write_exp_elt_opcode (UNOP_ADDR);
266130803Smarcel			  if (current_type)
267130803Smarcel			    current_type = TYPE_POINTER_TYPE (current_type); }
268130803Smarcel	;
26998944Sobrien
27098944Sobrienexp	:	'-' exp    %prec UNARY
27198944Sobrien			{ write_exp_elt_opcode (UNOP_NEG); }
27298944Sobrien	;
27398944Sobrien
27498944Sobrienexp	:	NOT exp    %prec UNARY
27598944Sobrien			{ write_exp_elt_opcode (UNOP_LOGICAL_NOT); }
27698944Sobrien	;
27798944Sobrien
27898944Sobrienexp	:	INCREMENT '(' exp ')'   %prec UNARY
27998944Sobrien			{ write_exp_elt_opcode (UNOP_PREINCREMENT); }
28098944Sobrien	;
28198944Sobrien
28298944Sobrienexp	:	DECREMENT  '(' exp ')'   %prec UNARY
28398944Sobrien			{ write_exp_elt_opcode (UNOP_PREDECREMENT); }
28498944Sobrien	;
28598944Sobrien
286130803Smarcelexp	:	exp '.' { search_field = 1; }
287130803Smarcel		FIELDNAME
288130803Smarcel		/* name */
28998944Sobrien			{ write_exp_elt_opcode (STRUCTOP_STRUCT);
290130803Smarcel			  write_exp_string ($4);
291130803Smarcel			  write_exp_elt_opcode (STRUCTOP_STRUCT);
292130803Smarcel			  search_field = 0;
293130803Smarcel			  if (current_type)
294130803Smarcel			    { while (TYPE_CODE (current_type) == TYPE_CODE_PTR)
295130803Smarcel				current_type = TYPE_TARGET_TYPE (current_type);
296130803Smarcel			      current_type = lookup_struct_elt_type (
297130803Smarcel				current_type, $4.ptr, 0); };
298130803Smarcel			 } ;
299130803Smarcelexp	:	exp '['
300130803Smarcel			/* We need to save the current_type value */
301130803Smarcel			{ char *arrayname;
302130803Smarcel			  int arrayfieldindex;
303130803Smarcel			  arrayfieldindex = is_pascal_string_type (
304130803Smarcel				current_type, NULL, NULL,
305130803Smarcel				NULL, NULL, &arrayname);
306130803Smarcel			  if (arrayfieldindex)
307130803Smarcel			    {
308130803Smarcel			      struct stoken stringsval;
309130803Smarcel			      stringsval.ptr = alloca (strlen (arrayname) + 1);
310130803Smarcel			      stringsval.length = strlen (arrayname);
311130803Smarcel			      strcpy (stringsval.ptr, arrayname);
312130803Smarcel			      current_type = TYPE_FIELD_TYPE (current_type,
313130803Smarcel				arrayfieldindex - 1);
314130803Smarcel			      write_exp_elt_opcode (STRUCTOP_STRUCT);
315130803Smarcel			      write_exp_string (stringsval);
316130803Smarcel			      write_exp_elt_opcode (STRUCTOP_STRUCT);
317130803Smarcel			    }
318130803Smarcel			  push_current_type ();  }
319130803Smarcel		exp1 ']'
320130803Smarcel			{ pop_current_type ();
321130803Smarcel			  write_exp_elt_opcode (BINOP_SUBSCRIPT);
322130803Smarcel			  if (current_type)
323130803Smarcel			    current_type = TYPE_TARGET_TYPE (current_type); }
32498944Sobrien	;
32598944Sobrien
32698944Sobrienexp	:	exp '('
32798944Sobrien			/* This is to save the value of arglist_len
32898944Sobrien			   being accumulated by an outer function call.  */
329130803Smarcel			{ push_current_type ();
330130803Smarcel			  start_arglist (); }
33198944Sobrien		arglist ')'	%prec ARROW
33298944Sobrien			{ write_exp_elt_opcode (OP_FUNCALL);
33398944Sobrien			  write_exp_elt_longcst ((LONGEST) end_arglist ());
334130803Smarcel			  write_exp_elt_opcode (OP_FUNCALL);
335130803Smarcel			  pop_current_type (); }
33698944Sobrien	;
33798944Sobrien
33898944Sobrienarglist	:
33998944Sobrien         | exp
34098944Sobrien			{ arglist_len = 1; }
34198944Sobrien	 | arglist ',' exp   %prec ABOVE_COMMA
34298944Sobrien			{ arglist_len++; }
34398944Sobrien	;
34498944Sobrien
34598944Sobrienexp	:	type '(' exp ')' %prec UNARY
346130803Smarcel			{ if (current_type)
347130803Smarcel			    {
348130803Smarcel			      /* Allow automatic dereference of classes.  */
349130803Smarcel			      if ((TYPE_CODE (current_type) == TYPE_CODE_PTR)
350130803Smarcel				  && (TYPE_CODE (TYPE_TARGET_TYPE (current_type)) == TYPE_CODE_CLASS)
351130803Smarcel				  && (TYPE_CODE ($1) == TYPE_CODE_CLASS))
352130803Smarcel				write_exp_elt_opcode (UNOP_IND);
353130803Smarcel			    }
354130803Smarcel			  write_exp_elt_opcode (UNOP_CAST);
35598944Sobrien			  write_exp_elt_type ($1);
356130803Smarcel			  write_exp_elt_opcode (UNOP_CAST);
357130803Smarcel			  current_type = $1; }
35898944Sobrien	;
35998944Sobrien
36098944Sobrienexp	:	'(' exp1 ')'
36198944Sobrien			{ }
36298944Sobrien	;
36398944Sobrien
36498944Sobrien/* Binary operators in order of decreasing precedence.  */
36598944Sobrien
36698944Sobrienexp	:	exp '*' exp
36798944Sobrien			{ write_exp_elt_opcode (BINOP_MUL); }
36898944Sobrien	;
36998944Sobrien
37098944Sobrienexp	:	exp '/' exp
37198944Sobrien			{ write_exp_elt_opcode (BINOP_DIV); }
37298944Sobrien	;
37398944Sobrien
37498944Sobrienexp	:	exp DIV exp
37598944Sobrien			{ write_exp_elt_opcode (BINOP_INTDIV); }
37698944Sobrien	;
37798944Sobrien
37898944Sobrienexp	:	exp MOD exp
37998944Sobrien			{ write_exp_elt_opcode (BINOP_REM); }
38098944Sobrien	;
38198944Sobrien
38298944Sobrienexp	:	exp '+' exp
38398944Sobrien			{ write_exp_elt_opcode (BINOP_ADD); }
38498944Sobrien	;
38598944Sobrien
38698944Sobrienexp	:	exp '-' exp
38798944Sobrien			{ write_exp_elt_opcode (BINOP_SUB); }
38898944Sobrien	;
38998944Sobrien
39098944Sobrienexp	:	exp LSH exp
39198944Sobrien			{ write_exp_elt_opcode (BINOP_LSH); }
39298944Sobrien	;
39398944Sobrien
39498944Sobrienexp	:	exp RSH exp
39598944Sobrien			{ write_exp_elt_opcode (BINOP_RSH); }
39698944Sobrien	;
39798944Sobrien
39898944Sobrienexp	:	exp '=' exp
39998944Sobrien			{ write_exp_elt_opcode (BINOP_EQUAL); }
40098944Sobrien	;
40198944Sobrien
40298944Sobrienexp	:	exp NOTEQUAL exp
40398944Sobrien			{ write_exp_elt_opcode (BINOP_NOTEQUAL); }
40498944Sobrien	;
40598944Sobrien
40698944Sobrienexp	:	exp LEQ exp
40798944Sobrien			{ write_exp_elt_opcode (BINOP_LEQ); }
40898944Sobrien	;
40998944Sobrien
41098944Sobrienexp	:	exp GEQ exp
41198944Sobrien			{ write_exp_elt_opcode (BINOP_GEQ); }
41298944Sobrien	;
41398944Sobrien
41498944Sobrienexp	:	exp '<' exp
41598944Sobrien			{ write_exp_elt_opcode (BINOP_LESS); }
41698944Sobrien	;
41798944Sobrien
41898944Sobrienexp	:	exp '>' exp
41998944Sobrien			{ write_exp_elt_opcode (BINOP_GTR); }
42098944Sobrien	;
42198944Sobrien
42298944Sobrienexp	:	exp ANDAND exp
42398944Sobrien			{ write_exp_elt_opcode (BINOP_BITWISE_AND); }
42498944Sobrien	;
42598944Sobrien
42698944Sobrienexp	:	exp XOR exp
42798944Sobrien			{ write_exp_elt_opcode (BINOP_BITWISE_XOR); }
42898944Sobrien	;
42998944Sobrien
43098944Sobrienexp	:	exp OR exp
43198944Sobrien			{ write_exp_elt_opcode (BINOP_BITWISE_IOR); }
43298944Sobrien	;
43398944Sobrien
43498944Sobrienexp	:	exp ASSIGN exp
43598944Sobrien			{ write_exp_elt_opcode (BINOP_ASSIGN); }
43698944Sobrien	;
43798944Sobrien
438130803Smarcelexp	:	TRUEKEYWORD
43998944Sobrien			{ write_exp_elt_opcode (OP_BOOL);
44098944Sobrien			  write_exp_elt_longcst ((LONGEST) $1);
44198944Sobrien			  write_exp_elt_opcode (OP_BOOL); }
44298944Sobrien	;
44398944Sobrien
444130803Smarcelexp	:	FALSEKEYWORD
44598944Sobrien			{ write_exp_elt_opcode (OP_BOOL);
44698944Sobrien			  write_exp_elt_longcst ((LONGEST) $1);
44798944Sobrien			  write_exp_elt_opcode (OP_BOOL); }
44898944Sobrien	;
44998944Sobrien
45098944Sobrienexp	:	INT
45198944Sobrien			{ write_exp_elt_opcode (OP_LONG);
45298944Sobrien			  write_exp_elt_type ($1.type);
45398944Sobrien			  write_exp_elt_longcst ((LONGEST)($1.val));
45498944Sobrien			  write_exp_elt_opcode (OP_LONG); }
45598944Sobrien	;
45698944Sobrien
45798944Sobrienexp	:	NAME_OR_INT
45898944Sobrien			{ YYSTYPE val;
45998944Sobrien			  parse_number ($1.stoken.ptr, $1.stoken.length, 0, &val);
46098944Sobrien			  write_exp_elt_opcode (OP_LONG);
46198944Sobrien			  write_exp_elt_type (val.typed_val_int.type);
46298944Sobrien			  write_exp_elt_longcst ((LONGEST)val.typed_val_int.val);
46398944Sobrien			  write_exp_elt_opcode (OP_LONG);
46498944Sobrien			}
46598944Sobrien	;
46698944Sobrien
46798944Sobrien
46898944Sobrienexp	:	FLOAT
46998944Sobrien			{ write_exp_elt_opcode (OP_DOUBLE);
47098944Sobrien			  write_exp_elt_type ($1.type);
47198944Sobrien			  write_exp_elt_dblcst ($1.dval);
47298944Sobrien			  write_exp_elt_opcode (OP_DOUBLE); }
47398944Sobrien	;
47498944Sobrien
47598944Sobrienexp	:	variable
47698944Sobrien	;
47798944Sobrien
47898944Sobrienexp	:	VARIABLE
47998944Sobrien			/* Already written by write_dollar_variable. */
48098944Sobrien	;
48198944Sobrien
48298944Sobrienexp	:	SIZEOF '(' type ')'	%prec UNARY
48398944Sobrien			{ write_exp_elt_opcode (OP_LONG);
48498944Sobrien			  write_exp_elt_type (builtin_type_int);
48598944Sobrien			  CHECK_TYPEDEF ($3);
48698944Sobrien			  write_exp_elt_longcst ((LONGEST) TYPE_LENGTH ($3));
48798944Sobrien			  write_exp_elt_opcode (OP_LONG); }
48898944Sobrien	;
48998944Sobrien
49098944Sobrienexp	:	STRING
49198944Sobrien			{ /* C strings are converted into array constants with
49298944Sobrien			     an explicit null byte added at the end.  Thus
49398944Sobrien			     the array upper bound is the string length.
49498944Sobrien			     There is no such thing in C as a completely empty
49598944Sobrien			     string. */
49698944Sobrien			  char *sp = $1.ptr; int count = $1.length;
49798944Sobrien			  while (count-- > 0)
49898944Sobrien			    {
49998944Sobrien			      write_exp_elt_opcode (OP_LONG);
50098944Sobrien			      write_exp_elt_type (builtin_type_char);
50198944Sobrien			      write_exp_elt_longcst ((LONGEST)(*sp++));
50298944Sobrien			      write_exp_elt_opcode (OP_LONG);
50398944Sobrien			    }
50498944Sobrien			  write_exp_elt_opcode (OP_LONG);
50598944Sobrien			  write_exp_elt_type (builtin_type_char);
50698944Sobrien			  write_exp_elt_longcst ((LONGEST)'\0');
50798944Sobrien			  write_exp_elt_opcode (OP_LONG);
50898944Sobrien			  write_exp_elt_opcode (OP_ARRAY);
50998944Sobrien			  write_exp_elt_longcst ((LONGEST) 0);
51098944Sobrien			  write_exp_elt_longcst ((LONGEST) ($1.length));
51198944Sobrien			  write_exp_elt_opcode (OP_ARRAY); }
51298944Sobrien	;
51398944Sobrien
51498944Sobrien/* Object pascal  */
51598944Sobrienexp	:	THIS
516130803Smarcel			{
517130803Smarcel			  struct value * this_val;
518130803Smarcel			  struct type * this_type;
519130803Smarcel			  write_exp_elt_opcode (OP_THIS);
520130803Smarcel			  write_exp_elt_opcode (OP_THIS);
521130803Smarcel			  /* we need type of this */
522130803Smarcel			  this_val = value_of_this (0);
523130803Smarcel			  if (this_val)
524130803Smarcel			    this_type = this_val->type;
525130803Smarcel			  else
526130803Smarcel			    this_type = NULL;
527130803Smarcel			  if (this_type)
528130803Smarcel			    {
529130803Smarcel			      if (TYPE_CODE (this_type) == TYPE_CODE_PTR)
530130803Smarcel				{
531130803Smarcel				  this_type = TYPE_TARGET_TYPE (this_type);
532130803Smarcel				  write_exp_elt_opcode (UNOP_IND);
533130803Smarcel				}
534130803Smarcel			    }
535130803Smarcel
536130803Smarcel			  current_type = this_type;
537130803Smarcel			}
53898944Sobrien	;
53998944Sobrien
54098944Sobrien/* end of object pascal.  */
54198944Sobrien
54298944Sobrienblock	:	BLOCKNAME
54398944Sobrien			{
54498944Sobrien			  if ($1.sym != 0)
54598944Sobrien			      $$ = SYMBOL_BLOCK_VALUE ($1.sym);
54698944Sobrien			  else
54798944Sobrien			    {
54898944Sobrien			      struct symtab *tem =
54998944Sobrien				  lookup_symtab (copy_name ($1.stoken));
55098944Sobrien			      if (tem)
55198944Sobrien				$$ = BLOCKVECTOR_BLOCK (BLOCKVECTOR (tem), STATIC_BLOCK);
55298944Sobrien			      else
55398944Sobrien				error ("No file or function \"%s\".",
55498944Sobrien				       copy_name ($1.stoken));
55598944Sobrien			    }
55698944Sobrien			}
55798944Sobrien	;
55898944Sobrien
55998944Sobrienblock	:	block COLONCOLON name
56098944Sobrien			{ struct symbol *tem
56198944Sobrien			    = lookup_symbol (copy_name ($3), $1,
562130803Smarcel					     VAR_DOMAIN, (int *) NULL,
56398944Sobrien					     (struct symtab **) NULL);
56498944Sobrien			  if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK)
56598944Sobrien			    error ("No function \"%s\" in specified context.",
56698944Sobrien				   copy_name ($3));
56798944Sobrien			  $$ = SYMBOL_BLOCK_VALUE (tem); }
56898944Sobrien	;
56998944Sobrien
57098944Sobrienvariable:	block COLONCOLON name
57198944Sobrien			{ struct symbol *sym;
57298944Sobrien			  sym = lookup_symbol (copy_name ($3), $1,
573130803Smarcel					       VAR_DOMAIN, (int *) NULL,
57498944Sobrien					       (struct symtab **) NULL);
57598944Sobrien			  if (sym == 0)
57698944Sobrien			    error ("No symbol \"%s\" in specified context.",
57798944Sobrien				   copy_name ($3));
57898944Sobrien
57998944Sobrien			  write_exp_elt_opcode (OP_VAR_VALUE);
58098944Sobrien			  /* block_found is set by lookup_symbol.  */
58198944Sobrien			  write_exp_elt_block (block_found);
58298944Sobrien			  write_exp_elt_sym (sym);
58398944Sobrien			  write_exp_elt_opcode (OP_VAR_VALUE); }
58498944Sobrien	;
58598944Sobrien
58698944Sobrienqualified_name:	typebase COLONCOLON name
58798944Sobrien			{
58898944Sobrien			  struct type *type = $1;
58998944Sobrien			  if (TYPE_CODE (type) != TYPE_CODE_STRUCT
59098944Sobrien			      && TYPE_CODE (type) != TYPE_CODE_UNION)
59198944Sobrien			    error ("`%s' is not defined as an aggregate type.",
59298944Sobrien				   TYPE_NAME (type));
59398944Sobrien
59498944Sobrien			  write_exp_elt_opcode (OP_SCOPE);
59598944Sobrien			  write_exp_elt_type (type);
59698944Sobrien			  write_exp_string ($3);
59798944Sobrien			  write_exp_elt_opcode (OP_SCOPE);
59898944Sobrien			}
59998944Sobrien	;
60098944Sobrien
60198944Sobrienvariable:	qualified_name
60298944Sobrien	|	COLONCOLON name
60398944Sobrien			{
60498944Sobrien			  char *name = copy_name ($2);
60598944Sobrien			  struct symbol *sym;
60698944Sobrien			  struct minimal_symbol *msymbol;
60798944Sobrien
60898944Sobrien			  sym =
60998944Sobrien			    lookup_symbol (name, (const struct block *) NULL,
610130803Smarcel					   VAR_DOMAIN, (int *) NULL,
61198944Sobrien					   (struct symtab **) NULL);
61298944Sobrien			  if (sym)
61398944Sobrien			    {
61498944Sobrien			      write_exp_elt_opcode (OP_VAR_VALUE);
61598944Sobrien			      write_exp_elt_block (NULL);
61698944Sobrien			      write_exp_elt_sym (sym);
61798944Sobrien			      write_exp_elt_opcode (OP_VAR_VALUE);
61898944Sobrien			      break;
61998944Sobrien			    }
62098944Sobrien
62198944Sobrien			  msymbol = lookup_minimal_symbol (name, NULL, NULL);
62298944Sobrien			  if (msymbol != NULL)
62398944Sobrien			    {
62498944Sobrien			      write_exp_msymbol (msymbol,
62598944Sobrien						 lookup_function_type (builtin_type_int),
62698944Sobrien						 builtin_type_int);
62798944Sobrien			    }
62898944Sobrien			  else
62998944Sobrien			    if (!have_full_symbols () && !have_partial_symbols ())
63098944Sobrien			      error ("No symbol table is loaded.  Use the \"file\" command.");
63198944Sobrien			    else
63298944Sobrien			      error ("No symbol \"%s\" in current context.", name);
63398944Sobrien			}
63498944Sobrien	;
63598944Sobrien
63698944Sobrienvariable:	name_not_typename
63798944Sobrien			{ struct symbol *sym = $1.sym;
63898944Sobrien
63998944Sobrien			  if (sym)
64098944Sobrien			    {
64198944Sobrien			      if (symbol_read_needs_frame (sym))
64298944Sobrien				{
64398944Sobrien				  if (innermost_block == 0 ||
64498944Sobrien				      contained_in (block_found,
64598944Sobrien						    innermost_block))
64698944Sobrien				    innermost_block = block_found;
64798944Sobrien				}
64898944Sobrien
64998944Sobrien			      write_exp_elt_opcode (OP_VAR_VALUE);
65098944Sobrien			      /* We want to use the selected frame, not
65198944Sobrien				 another more inner frame which happens to
65298944Sobrien				 be in the same block.  */
65398944Sobrien			      write_exp_elt_block (NULL);
65498944Sobrien			      write_exp_elt_sym (sym);
65598944Sobrien			      write_exp_elt_opcode (OP_VAR_VALUE);
656130803Smarcel			      current_type = sym->type; }
65798944Sobrien			  else if ($1.is_a_field_of_this)
65898944Sobrien			    {
659130803Smarcel			      struct value * this_val;
660130803Smarcel			      struct type * this_type;
66198944Sobrien			      /* Object pascal: it hangs off of `this'.  Must
66298944Sobrien			         not inadvertently convert from a method call
66398944Sobrien				 to data ref.  */
66498944Sobrien			      if (innermost_block == 0 ||
66598944Sobrien				  contained_in (block_found, innermost_block))
66698944Sobrien				innermost_block = block_found;
66798944Sobrien			      write_exp_elt_opcode (OP_THIS);
66898944Sobrien			      write_exp_elt_opcode (OP_THIS);
66998944Sobrien			      write_exp_elt_opcode (STRUCTOP_PTR);
67098944Sobrien			      write_exp_string ($1.stoken);
67198944Sobrien			      write_exp_elt_opcode (STRUCTOP_PTR);
672130803Smarcel			      /* we need type of this */
673130803Smarcel			      this_val = value_of_this (0);
674130803Smarcel			      if (this_val)
675130803Smarcel				this_type = this_val->type;
676130803Smarcel			      else
677130803Smarcel				this_type = NULL;
678130803Smarcel			      if (this_type)
679130803Smarcel				current_type = lookup_struct_elt_type (
680130803Smarcel				  this_type,
681130803Smarcel				  copy_name ($1.stoken), 0);
682130803Smarcel			      else
683130803Smarcel				current_type = NULL;
68498944Sobrien			    }
68598944Sobrien			  else
68698944Sobrien			    {
68798944Sobrien			      struct minimal_symbol *msymbol;
688130803Smarcel			      char *arg = copy_name ($1.stoken);
68998944Sobrien
69098944Sobrien			      msymbol =
69198944Sobrien				lookup_minimal_symbol (arg, NULL, NULL);
69298944Sobrien			      if (msymbol != NULL)
69398944Sobrien				{
69498944Sobrien				  write_exp_msymbol (msymbol,
69598944Sobrien						     lookup_function_type (builtin_type_int),
69698944Sobrien						     builtin_type_int);
69798944Sobrien				}
69898944Sobrien			      else if (!have_full_symbols () && !have_partial_symbols ())
69998944Sobrien				error ("No symbol table is loaded.  Use the \"file\" command.");
70098944Sobrien			      else
70198944Sobrien				error ("No symbol \"%s\" in current context.",
70298944Sobrien				       copy_name ($1.stoken));
70398944Sobrien			    }
70498944Sobrien			}
70598944Sobrien	;
70698944Sobrien
70798944Sobrien
70898944Sobrienptype	:	typebase
70998944Sobrien	;
71098944Sobrien
71198944Sobrien/* We used to try to recognize more pointer to member types here, but
71298944Sobrien   that didn't work (shift/reduce conflicts meant that these rules never
71398944Sobrien   got executed).  The problem is that
71498944Sobrien     int (foo::bar::baz::bizzle)
71598944Sobrien   is a function type but
71698944Sobrien     int (foo::bar::baz::bizzle::*)
71798944Sobrien   is a pointer to member type.  Stroustrup loses again!  */
71898944Sobrien
71998944Sobrientype	:	ptype
72098944Sobrien	|	typebase COLONCOLON '*'
72198944Sobrien			{ $$ = lookup_member_type (builtin_type_int, $1); }
72298944Sobrien	;
72398944Sobrien
72498944Sobrientypebase  /* Implements (approximately): (type-qualifier)* type-specifier */
725130803Smarcel	:	'^' typebase
726130803Smarcel			{ $$ = lookup_pointer_type ($2); }
727130803Smarcel	|	TYPENAME
72898944Sobrien			{ $$ = $1.type; }
72998944Sobrien	|	STRUCT name
73098944Sobrien			{ $$ = lookup_struct (copy_name ($2),
73198944Sobrien					      expression_context_block); }
73298944Sobrien	|	CLASS name
73398944Sobrien			{ $$ = lookup_struct (copy_name ($2),
73498944Sobrien					      expression_context_block); }
73598944Sobrien	/* "const" and "volatile" are curently ignored.  A type qualifier
73698944Sobrien	   after the type is handled in the ptype rule.  I think these could
73798944Sobrien	   be too.  */
73898944Sobrien	;
73998944Sobrien
74098944Sobrienname	:	NAME { $$ = $1.stoken; }
74198944Sobrien	|	BLOCKNAME { $$ = $1.stoken; }
74298944Sobrien	|	TYPENAME { $$ = $1.stoken; }
74398944Sobrien	|	NAME_OR_INT  { $$ = $1.stoken; }
74498944Sobrien	;
74598944Sobrien
74698944Sobrienname_not_typename :	NAME
74798944Sobrien	|	BLOCKNAME
74898944Sobrien/* These would be useful if name_not_typename was useful, but it is just
74998944Sobrien   a fake for "variable", so these cause reduce/reduce conflicts because
75098944Sobrien   the parser can't tell whether NAME_OR_INT is a name_not_typename (=variable,
75198944Sobrien   =exp) or just an exp.  If name_not_typename was ever used in an lvalue
75298944Sobrien   context where only a name could occur, this might be useful.
75398944Sobrien  	|	NAME_OR_INT
75498944Sobrien */
75598944Sobrien	;
75698944Sobrien
75798944Sobrien%%
75898944Sobrien
75998944Sobrien/* Take care of parsing a number (anything that starts with a digit).
76098944Sobrien   Set yylval and return the token type; update lexptr.
76198944Sobrien   LEN is the number of characters in it.  */
76298944Sobrien
76398944Sobrien/*** Needs some error checking for the float case ***/
76498944Sobrien
76598944Sobrienstatic int
76698944Sobrienparse_number (p, len, parsed_float, putithere)
767130803Smarcel     char *p;
768130803Smarcel     int len;
76998944Sobrien     int parsed_float;
77098944Sobrien     YYSTYPE *putithere;
77198944Sobrien{
77298944Sobrien  /* FIXME: Shouldn't these be unsigned?  We don't deal with negative values
77398944Sobrien     here, and we do kind of silly things like cast to unsigned.  */
774130803Smarcel  LONGEST n = 0;
775130803Smarcel  LONGEST prevn = 0;
77698944Sobrien  ULONGEST un;
77798944Sobrien
778130803Smarcel  int i = 0;
779130803Smarcel  int c;
780130803Smarcel  int base = input_radix;
78198944Sobrien  int unsigned_p = 0;
78298944Sobrien
78398944Sobrien  /* Number of "L" suffixes encountered.  */
78498944Sobrien  int long_p = 0;
78598944Sobrien
78698944Sobrien  /* We have found a "L" or "U" suffix.  */
78798944Sobrien  int found_suffix = 0;
78898944Sobrien
78998944Sobrien  ULONGEST high_bit;
79098944Sobrien  struct type *signed_type;
79198944Sobrien  struct type *unsigned_type;
79298944Sobrien
79398944Sobrien  if (parsed_float)
79498944Sobrien    {
79598944Sobrien      /* It's a float since it contains a point or an exponent.  */
79698944Sobrien      char c;
79798944Sobrien      int num = 0;	/* number of tokens scanned by scanf */
79898944Sobrien      char saved_char = p[len];
79998944Sobrien
80098944Sobrien      p[len] = 0;	/* null-terminate the token */
80198944Sobrien      if (sizeof (putithere->typed_val_float.dval) <= sizeof (float))
80298944Sobrien	num = sscanf (p, "%g%c", (float *) &putithere->typed_val_float.dval,&c);
80398944Sobrien      else if (sizeof (putithere->typed_val_float.dval) <= sizeof (double))
80498944Sobrien	num = sscanf (p, "%lg%c", (double *) &putithere->typed_val_float.dval,&c);
80598944Sobrien      else
80698944Sobrien	{
80798944Sobrien#ifdef SCANF_HAS_LONG_DOUBLE
80898944Sobrien	  num = sscanf (p, "%Lg%c", &putithere->typed_val_float.dval,&c);
80998944Sobrien#else
81098944Sobrien	  /* Scan it into a double, then assign it to the long double.
81198944Sobrien	     This at least wins with values representable in the range
81298944Sobrien	     of doubles. */
81398944Sobrien	  double temp;
81498944Sobrien	  num = sscanf (p, "%lg%c", &temp,&c);
81598944Sobrien	  putithere->typed_val_float.dval = temp;
81698944Sobrien#endif
81798944Sobrien	}
81898944Sobrien      p[len] = saved_char;	/* restore the input stream */
81998944Sobrien      if (num != 1) 		/* check scanf found ONLY a float ... */
82098944Sobrien	return ERROR;
82198944Sobrien      /* See if it has `f' or `l' suffix (float or long double).  */
82298944Sobrien
82398944Sobrien      c = tolower (p[len - 1]);
82498944Sobrien
82598944Sobrien      if (c == 'f')
82698944Sobrien	putithere->typed_val_float.type = builtin_type_float;
82798944Sobrien      else if (c == 'l')
82898944Sobrien	putithere->typed_val_float.type = builtin_type_long_double;
82998944Sobrien      else if (isdigit (c) || c == '.')
83098944Sobrien	putithere->typed_val_float.type = builtin_type_double;
83198944Sobrien      else
83298944Sobrien	return ERROR;
83398944Sobrien
83498944Sobrien      return FLOAT;
83598944Sobrien    }
83698944Sobrien
83798944Sobrien  /* Handle base-switching prefixes 0x, 0t, 0d, 0 */
83898944Sobrien  if (p[0] == '0')
83998944Sobrien    switch (p[1])
84098944Sobrien      {
84198944Sobrien      case 'x':
84298944Sobrien      case 'X':
84398944Sobrien	if (len >= 3)
84498944Sobrien	  {
84598944Sobrien	    p += 2;
84698944Sobrien	    base = 16;
84798944Sobrien	    len -= 2;
84898944Sobrien	  }
84998944Sobrien	break;
85098944Sobrien
85198944Sobrien      case 't':
85298944Sobrien      case 'T':
85398944Sobrien      case 'd':
85498944Sobrien      case 'D':
85598944Sobrien	if (len >= 3)
85698944Sobrien	  {
85798944Sobrien	    p += 2;
85898944Sobrien	    base = 10;
85998944Sobrien	    len -= 2;
86098944Sobrien	  }
86198944Sobrien	break;
86298944Sobrien
86398944Sobrien      default:
86498944Sobrien	base = 8;
86598944Sobrien	break;
86698944Sobrien      }
86798944Sobrien
86898944Sobrien  while (len-- > 0)
86998944Sobrien    {
87098944Sobrien      c = *p++;
87198944Sobrien      if (c >= 'A' && c <= 'Z')
87298944Sobrien	c += 'a' - 'A';
87398944Sobrien      if (c != 'l' && c != 'u')
87498944Sobrien	n *= base;
87598944Sobrien      if (c >= '0' && c <= '9')
87698944Sobrien	{
87798944Sobrien	  if (found_suffix)
87898944Sobrien	    return ERROR;
87998944Sobrien	  n += i = c - '0';
88098944Sobrien	}
88198944Sobrien      else
88298944Sobrien	{
88398944Sobrien	  if (base > 10 && c >= 'a' && c <= 'f')
88498944Sobrien	    {
88598944Sobrien	      if (found_suffix)
88698944Sobrien		return ERROR;
88798944Sobrien	      n += i = c - 'a' + 10;
88898944Sobrien	    }
88998944Sobrien	  else if (c == 'l')
89098944Sobrien	    {
89198944Sobrien	      ++long_p;
89298944Sobrien	      found_suffix = 1;
89398944Sobrien	    }
89498944Sobrien	  else if (c == 'u')
89598944Sobrien	    {
89698944Sobrien	      unsigned_p = 1;
89798944Sobrien	      found_suffix = 1;
89898944Sobrien	    }
89998944Sobrien	  else
90098944Sobrien	    return ERROR;	/* Char not a digit */
90198944Sobrien	}
90298944Sobrien      if (i >= base)
90398944Sobrien	return ERROR;		/* Invalid digit in this base */
90498944Sobrien
90598944Sobrien      /* Portably test for overflow (only works for nonzero values, so make
90698944Sobrien	 a second check for zero).  FIXME: Can't we just make n and prevn
90798944Sobrien	 unsigned and avoid this?  */
90898944Sobrien      if (c != 'l' && c != 'u' && (prevn >= n) && n != 0)
90998944Sobrien	unsigned_p = 1;		/* Try something unsigned */
91098944Sobrien
91198944Sobrien      /* Portably test for unsigned overflow.
91298944Sobrien	 FIXME: This check is wrong; for example it doesn't find overflow
91398944Sobrien	 on 0x123456789 when LONGEST is 32 bits.  */
91498944Sobrien      if (c != 'l' && c != 'u' && n != 0)
91598944Sobrien	{
91698944Sobrien	  if ((unsigned_p && (ULONGEST) prevn >= (ULONGEST) n))
91798944Sobrien	    error ("Numeric constant too large.");
91898944Sobrien	}
91998944Sobrien      prevn = n;
92098944Sobrien    }
92198944Sobrien
92298944Sobrien  /* An integer constant is an int, a long, or a long long.  An L
92398944Sobrien     suffix forces it to be long; an LL suffix forces it to be long
92498944Sobrien     long.  If not forced to a larger size, it gets the first type of
92598944Sobrien     the above that it fits in.  To figure out whether it fits, we
92698944Sobrien     shift it right and see whether anything remains.  Note that we
92798944Sobrien     can't shift sizeof (LONGEST) * HOST_CHAR_BIT bits or more in one
92898944Sobrien     operation, because many compilers will warn about such a shift
92998944Sobrien     (which always produces a zero result).  Sometimes TARGET_INT_BIT
93098944Sobrien     or TARGET_LONG_BIT will be that big, sometimes not.  To deal with
93198944Sobrien     the case where it is we just always shift the value more than
93298944Sobrien     once, with fewer bits each time.  */
93398944Sobrien
93498944Sobrien  un = (ULONGEST)n >> 2;
93598944Sobrien  if (long_p == 0
93698944Sobrien      && (un >> (TARGET_INT_BIT - 2)) == 0)
93798944Sobrien    {
93898944Sobrien      high_bit = ((ULONGEST)1) << (TARGET_INT_BIT-1);
93998944Sobrien
94098944Sobrien      /* A large decimal (not hex or octal) constant (between INT_MAX
94198944Sobrien	 and UINT_MAX) is a long or unsigned long, according to ANSI,
94298944Sobrien	 never an unsigned int, but this code treats it as unsigned
94398944Sobrien	 int.  This probably should be fixed.  GCC gives a warning on
94498944Sobrien	 such constants.  */
94598944Sobrien
94698944Sobrien      unsigned_type = builtin_type_unsigned_int;
94798944Sobrien      signed_type = builtin_type_int;
94898944Sobrien    }
94998944Sobrien  else if (long_p <= 1
95098944Sobrien	   && (un >> (TARGET_LONG_BIT - 2)) == 0)
95198944Sobrien    {
95298944Sobrien      high_bit = ((ULONGEST)1) << (TARGET_LONG_BIT-1);
95398944Sobrien      unsigned_type = builtin_type_unsigned_long;
95498944Sobrien      signed_type = builtin_type_long;
95598944Sobrien    }
95698944Sobrien  else
95798944Sobrien    {
95898944Sobrien      int shift;
95998944Sobrien      if (sizeof (ULONGEST) * HOST_CHAR_BIT < TARGET_LONG_LONG_BIT)
96098944Sobrien	/* A long long does not fit in a LONGEST.  */
96198944Sobrien	shift = (sizeof (ULONGEST) * HOST_CHAR_BIT - 1);
96298944Sobrien      else
96398944Sobrien	shift = (TARGET_LONG_LONG_BIT - 1);
96498944Sobrien      high_bit = (ULONGEST) 1 << shift;
96598944Sobrien      unsigned_type = builtin_type_unsigned_long_long;
96698944Sobrien      signed_type = builtin_type_long_long;
96798944Sobrien    }
96898944Sobrien
96998944Sobrien   putithere->typed_val_int.val = n;
97098944Sobrien
97198944Sobrien   /* If the high bit of the worked out type is set then this number
97298944Sobrien      has to be unsigned. */
97398944Sobrien
97498944Sobrien   if (unsigned_p || (n & high_bit))
97598944Sobrien     {
97698944Sobrien       putithere->typed_val_int.type = unsigned_type;
97798944Sobrien     }
97898944Sobrien   else
97998944Sobrien     {
98098944Sobrien       putithere->typed_val_int.type = signed_type;
98198944Sobrien     }
98298944Sobrien
98398944Sobrien   return INT;
98498944Sobrien}
98598944Sobrien
986130803Smarcel
987130803Smarcelstruct type_push
988130803Smarcel{
989130803Smarcel  struct type *stored;
990130803Smarcel  struct type_push *next;
991130803Smarcel};
992130803Smarcel
993130803Smarcelstatic struct type_push *tp_top = NULL;
994130803Smarcel
995130803Smarcelstatic void
996130803Smarcelpush_current_type (void)
997130803Smarcel{
998130803Smarcel  struct type_push *tpnew;
999130803Smarcel  tpnew = (struct type_push *) malloc (sizeof (struct type_push));
1000130803Smarcel  tpnew->next = tp_top;
1001130803Smarcel  tpnew->stored = current_type;
1002130803Smarcel  current_type = NULL;
1003130803Smarcel  tp_top = tpnew;
1004130803Smarcel}
1005130803Smarcel
1006130803Smarcelstatic void
1007130803Smarcelpop_current_type (void)
1008130803Smarcel{
1009130803Smarcel  struct type_push *tp = tp_top;
1010130803Smarcel  if (tp)
1011130803Smarcel    {
1012130803Smarcel      current_type = tp->stored;
1013130803Smarcel      tp_top = tp->next;
1014130803Smarcel      xfree (tp);
1015130803Smarcel    }
1016130803Smarcel}
1017130803Smarcel
101898944Sobrienstruct token
101998944Sobrien{
102098944Sobrien  char *operator;
102198944Sobrien  int token;
102298944Sobrien  enum exp_opcode opcode;
102398944Sobrien};
102498944Sobrien
102598944Sobrienstatic const struct token tokentab3[] =
102698944Sobrien  {
102798944Sobrien    {"shr", RSH, BINOP_END},
102898944Sobrien    {"shl", LSH, BINOP_END},
102998944Sobrien    {"and", ANDAND, BINOP_END},
103098944Sobrien    {"div", DIV, BINOP_END},
103198944Sobrien    {"not", NOT, BINOP_END},
103298944Sobrien    {"mod", MOD, BINOP_END},
103398944Sobrien    {"inc", INCREMENT, BINOP_END},
103498944Sobrien    {"dec", DECREMENT, BINOP_END},
103598944Sobrien    {"xor", XOR, BINOP_END}
103698944Sobrien  };
103798944Sobrien
103898944Sobrienstatic const struct token tokentab2[] =
103998944Sobrien  {
104098944Sobrien    {"or", OR, BINOP_END},
104198944Sobrien    {"<>", NOTEQUAL, BINOP_END},
104298944Sobrien    {"<=", LEQ, BINOP_END},
104398944Sobrien    {">=", GEQ, BINOP_END},
1044130803Smarcel    {":=", ASSIGN, BINOP_END},
1045130803Smarcel    {"::", COLONCOLON, BINOP_END} };
104698944Sobrien
104798944Sobrien/* Allocate uppercased var */
104898944Sobrien/* make an uppercased copy of tokstart */
104998944Sobrienstatic char * uptok (tokstart, namelen)
105098944Sobrien  char *tokstart;
105198944Sobrien  int namelen;
105298944Sobrien{
105398944Sobrien  int i;
105498944Sobrien  char *uptokstart = (char *)malloc(namelen+1);
105598944Sobrien  for (i = 0;i <= namelen;i++)
105698944Sobrien    {
105798944Sobrien      if ((tokstart[i]>='a' && tokstart[i]<='z'))
105898944Sobrien        uptokstart[i] = tokstart[i]-('a'-'A');
105998944Sobrien      else
106098944Sobrien        uptokstart[i] = tokstart[i];
106198944Sobrien    }
106298944Sobrien  uptokstart[namelen]='\0';
106398944Sobrien  return uptokstart;
106498944Sobrien}
106598944Sobrien/* Read one token, getting characters through lexptr.  */
106698944Sobrien
106798944Sobrien
106898944Sobrienstatic int
106998944Sobrienyylex ()
107098944Sobrien{
107198944Sobrien  int c;
107298944Sobrien  int namelen;
107398944Sobrien  unsigned int i;
107498944Sobrien  char *tokstart;
107598944Sobrien  char *uptokstart;
107698944Sobrien  char *tokptr;
107798944Sobrien  char *p;
107898944Sobrien  int explen, tempbufindex;
107998944Sobrien  static char *tempbuf;
108098944Sobrien  static int tempbufsize;
108198944Sobrien
108298944Sobrien retry:
108398944Sobrien
1084130803Smarcel  prev_lexptr = lexptr;
1085130803Smarcel
108698944Sobrien  tokstart = lexptr;
108798944Sobrien  explen = strlen (lexptr);
108898944Sobrien  /* See if it is a special token of length 3.  */
108998944Sobrien  if (explen > 2)
109098944Sobrien    for (i = 0; i < sizeof (tokentab3) / sizeof (tokentab3[0]); i++)
109198944Sobrien      if (strncasecmp (tokstart, tokentab3[i].operator, 3) == 0
109298944Sobrien          && (!isalpha (tokentab3[i].operator[0]) || explen == 3
109398944Sobrien              || (!isalpha (tokstart[3]) && !isdigit (tokstart[3]) && tokstart[3] != '_')))
109498944Sobrien        {
109598944Sobrien          lexptr += 3;
109698944Sobrien          yylval.opcode = tokentab3[i].opcode;
109798944Sobrien          return tokentab3[i].token;
109898944Sobrien        }
109998944Sobrien
110098944Sobrien  /* See if it is a special token of length 2.  */
110198944Sobrien  if (explen > 1)
110298944Sobrien  for (i = 0; i < sizeof (tokentab2) / sizeof (tokentab2[0]); i++)
110398944Sobrien      if (strncasecmp (tokstart, tokentab2[i].operator, 2) == 0
110498944Sobrien          && (!isalpha (tokentab2[i].operator[0]) || explen == 2
110598944Sobrien              || (!isalpha (tokstart[2]) && !isdigit (tokstart[2]) && tokstart[2] != '_')))
110698944Sobrien        {
110798944Sobrien          lexptr += 2;
110898944Sobrien          yylval.opcode = tokentab2[i].opcode;
110998944Sobrien          return tokentab2[i].token;
111098944Sobrien        }
111198944Sobrien
111298944Sobrien  switch (c = *tokstart)
111398944Sobrien    {
111498944Sobrien    case 0:
111598944Sobrien      return 0;
111698944Sobrien
111798944Sobrien    case ' ':
111898944Sobrien    case '\t':
111998944Sobrien    case '\n':
112098944Sobrien      lexptr++;
112198944Sobrien      goto retry;
112298944Sobrien
112398944Sobrien    case '\'':
112498944Sobrien      /* We either have a character constant ('0' or '\177' for example)
112598944Sobrien	 or we have a quoted symbol reference ('foo(int,int)' in object pascal
112698944Sobrien	 for example). */
112798944Sobrien      lexptr++;
112898944Sobrien      c = *lexptr++;
112998944Sobrien      if (c == '\\')
113098944Sobrien	c = parse_escape (&lexptr);
113198944Sobrien      else if (c == '\'')
113298944Sobrien	error ("Empty character constant.");
113398944Sobrien
113498944Sobrien      yylval.typed_val_int.val = c;
113598944Sobrien      yylval.typed_val_int.type = builtin_type_char;
113698944Sobrien
113798944Sobrien      c = *lexptr++;
113898944Sobrien      if (c != '\'')
113998944Sobrien	{
114098944Sobrien	  namelen = skip_quoted (tokstart) - tokstart;
114198944Sobrien	  if (namelen > 2)
114298944Sobrien	    {
114398944Sobrien	      lexptr = tokstart + namelen;
114498944Sobrien	      if (lexptr[-1] != '\'')
114598944Sobrien		error ("Unmatched single quote.");
114698944Sobrien	      namelen -= 2;
114798944Sobrien              tokstart++;
114898944Sobrien              uptokstart = uptok(tokstart,namelen);
114998944Sobrien	      goto tryname;
115098944Sobrien	    }
115198944Sobrien	  error ("Invalid character constant.");
115298944Sobrien	}
115398944Sobrien      return INT;
115498944Sobrien
115598944Sobrien    case '(':
115698944Sobrien      paren_depth++;
115798944Sobrien      lexptr++;
115898944Sobrien      return c;
115998944Sobrien
116098944Sobrien    case ')':
116198944Sobrien      if (paren_depth == 0)
116298944Sobrien	return 0;
116398944Sobrien      paren_depth--;
116498944Sobrien      lexptr++;
116598944Sobrien      return c;
116698944Sobrien
116798944Sobrien    case ',':
116898944Sobrien      if (comma_terminates && paren_depth == 0)
116998944Sobrien	return 0;
117098944Sobrien      lexptr++;
117198944Sobrien      return c;
117298944Sobrien
117398944Sobrien    case '.':
117498944Sobrien      /* Might be a floating point number.  */
117598944Sobrien      if (lexptr[1] < '0' || lexptr[1] > '9')
117698944Sobrien	goto symbol;		/* Nope, must be a symbol. */
117798944Sobrien      /* FALL THRU into number case.  */
117898944Sobrien
117998944Sobrien    case '0':
118098944Sobrien    case '1':
118198944Sobrien    case '2':
118298944Sobrien    case '3':
118398944Sobrien    case '4':
118498944Sobrien    case '5':
118598944Sobrien    case '6':
118698944Sobrien    case '7':
118798944Sobrien    case '8':
118898944Sobrien    case '9':
118998944Sobrien      {
119098944Sobrien	/* It's a number.  */
119198944Sobrien	int got_dot = 0, got_e = 0, toktype;
1192130803Smarcel	char *p = tokstart;
119398944Sobrien	int hex = input_radix > 10;
119498944Sobrien
119598944Sobrien	if (c == '0' && (p[1] == 'x' || p[1] == 'X'))
119698944Sobrien	  {
119798944Sobrien	    p += 2;
119898944Sobrien	    hex = 1;
119998944Sobrien	  }
120098944Sobrien	else if (c == '0' && (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D'))
120198944Sobrien	  {
120298944Sobrien	    p += 2;
120398944Sobrien	    hex = 0;
120498944Sobrien	  }
120598944Sobrien
120698944Sobrien	for (;; ++p)
120798944Sobrien	  {
120898944Sobrien	    /* This test includes !hex because 'e' is a valid hex digit
120998944Sobrien	       and thus does not indicate a floating point number when
121098944Sobrien	       the radix is hex.  */
121198944Sobrien	    if (!hex && !got_e && (*p == 'e' || *p == 'E'))
121298944Sobrien	      got_dot = got_e = 1;
121398944Sobrien	    /* This test does not include !hex, because a '.' always indicates
121498944Sobrien	       a decimal floating point number regardless of the radix.  */
121598944Sobrien	    else if (!got_dot && *p == '.')
121698944Sobrien	      got_dot = 1;
121798944Sobrien	    else if (got_e && (p[-1] == 'e' || p[-1] == 'E')
121898944Sobrien		     && (*p == '-' || *p == '+'))
121998944Sobrien	      /* This is the sign of the exponent, not the end of the
122098944Sobrien		 number.  */
122198944Sobrien	      continue;
122298944Sobrien	    /* We will take any letters or digits.  parse_number will
122398944Sobrien	       complain if past the radix, or if L or U are not final.  */
122498944Sobrien	    else if ((*p < '0' || *p > '9')
122598944Sobrien		     && ((*p < 'a' || *p > 'z')
122698944Sobrien				  && (*p < 'A' || *p > 'Z')))
122798944Sobrien	      break;
122898944Sobrien	  }
122998944Sobrien	toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &yylval);
123098944Sobrien        if (toktype == ERROR)
123198944Sobrien	  {
123298944Sobrien	    char *err_copy = (char *) alloca (p - tokstart + 1);
123398944Sobrien
123498944Sobrien	    memcpy (err_copy, tokstart, p - tokstart);
123598944Sobrien	    err_copy[p - tokstart] = 0;
123698944Sobrien	    error ("Invalid number \"%s\".", err_copy);
123798944Sobrien	  }
123898944Sobrien	lexptr = p;
123998944Sobrien	return toktype;
124098944Sobrien      }
124198944Sobrien
124298944Sobrien    case '+':
124398944Sobrien    case '-':
124498944Sobrien    case '*':
124598944Sobrien    case '/':
124698944Sobrien    case '|':
124798944Sobrien    case '&':
124898944Sobrien    case '^':
124998944Sobrien    case '~':
125098944Sobrien    case '!':
125198944Sobrien    case '@':
125298944Sobrien    case '<':
125398944Sobrien    case '>':
125498944Sobrien    case '[':
125598944Sobrien    case ']':
125698944Sobrien    case '?':
125798944Sobrien    case ':':
125898944Sobrien    case '=':
125998944Sobrien    case '{':
126098944Sobrien    case '}':
126198944Sobrien    symbol:
126298944Sobrien      lexptr++;
126398944Sobrien      return c;
126498944Sobrien
126598944Sobrien    case '"':
126698944Sobrien
126798944Sobrien      /* Build the gdb internal form of the input string in tempbuf,
126898944Sobrien	 translating any standard C escape forms seen.  Note that the
126998944Sobrien	 buffer is null byte terminated *only* for the convenience of
127098944Sobrien	 debugging gdb itself and printing the buffer contents when
127198944Sobrien	 the buffer contains no embedded nulls.  Gdb does not depend
127298944Sobrien	 upon the buffer being null byte terminated, it uses the length
127398944Sobrien	 string instead.  This allows gdb to handle C strings (as well
127498944Sobrien	 as strings in other languages) with embedded null bytes */
127598944Sobrien
127698944Sobrien      tokptr = ++tokstart;
127798944Sobrien      tempbufindex = 0;
127898944Sobrien
127998944Sobrien      do {
128098944Sobrien	/* Grow the static temp buffer if necessary, including allocating
128198944Sobrien	   the first one on demand. */
128298944Sobrien	if (tempbufindex + 1 >= tempbufsize)
128398944Sobrien	  {
128498944Sobrien	    tempbuf = (char *) realloc (tempbuf, tempbufsize += 64);
128598944Sobrien	  }
1286130803Smarcel
128798944Sobrien	switch (*tokptr)
128898944Sobrien	  {
128998944Sobrien	  case '\0':
129098944Sobrien	  case '"':
129198944Sobrien	    /* Do nothing, loop will terminate. */
129298944Sobrien	    break;
129398944Sobrien	  case '\\':
129498944Sobrien	    tokptr++;
129598944Sobrien	    c = parse_escape (&tokptr);
129698944Sobrien	    if (c == -1)
129798944Sobrien	      {
129898944Sobrien		continue;
129998944Sobrien	      }
130098944Sobrien	    tempbuf[tempbufindex++] = c;
130198944Sobrien	    break;
130298944Sobrien	  default:
130398944Sobrien	    tempbuf[tempbufindex++] = *tokptr++;
130498944Sobrien	    break;
130598944Sobrien	  }
130698944Sobrien      } while ((*tokptr != '"') && (*tokptr != '\0'));
130798944Sobrien      if (*tokptr++ != '"')
130898944Sobrien	{
130998944Sobrien	  error ("Unterminated string in expression.");
131098944Sobrien	}
131198944Sobrien      tempbuf[tempbufindex] = '\0';	/* See note above */
131298944Sobrien      yylval.sval.ptr = tempbuf;
131398944Sobrien      yylval.sval.length = tempbufindex;
131498944Sobrien      lexptr = tokptr;
131598944Sobrien      return (STRING);
131698944Sobrien    }
131798944Sobrien
131898944Sobrien  if (!(c == '_' || c == '$'
131998944Sobrien	|| (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
132098944Sobrien    /* We must have come across a bad character (e.g. ';').  */
132198944Sobrien    error ("Invalid character '%c' in expression.", c);
132298944Sobrien
132398944Sobrien  /* It's a name.  See how long it is.  */
132498944Sobrien  namelen = 0;
132598944Sobrien  for (c = tokstart[namelen];
132698944Sobrien       (c == '_' || c == '$' || (c >= '0' && c <= '9')
132798944Sobrien	|| (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '<');)
132898944Sobrien    {
132998944Sobrien      /* Template parameter lists are part of the name.
133098944Sobrien	 FIXME: This mishandles `print $a<4&&$a>3'.  */
133198944Sobrien      if (c == '<')
133298944Sobrien	{
133398944Sobrien	  int i = namelen;
133498944Sobrien	  int nesting_level = 1;
133598944Sobrien	  while (tokstart[++i])
133698944Sobrien	    {
133798944Sobrien	      if (tokstart[i] == '<')
133898944Sobrien		nesting_level++;
133998944Sobrien	      else if (tokstart[i] == '>')
134098944Sobrien		{
134198944Sobrien		  if (--nesting_level == 0)
134298944Sobrien		    break;
134398944Sobrien		}
134498944Sobrien	    }
134598944Sobrien	  if (tokstart[i] == '>')
134698944Sobrien	    namelen = i;
134798944Sobrien	  else
134898944Sobrien	    break;
134998944Sobrien	}
135098944Sobrien
135198944Sobrien      /* do NOT uppercase internals because of registers !!! */
135298944Sobrien      c = tokstart[++namelen];
135398944Sobrien    }
135498944Sobrien
135598944Sobrien  uptokstart = uptok(tokstart,namelen);
135698944Sobrien
135798944Sobrien  /* The token "if" terminates the expression and is NOT
135898944Sobrien     removed from the input stream.  */
135998944Sobrien  if (namelen == 2 && uptokstart[0] == 'I' && uptokstart[1] == 'F')
136098944Sobrien    {
136198944Sobrien      return 0;
136298944Sobrien    }
136398944Sobrien
136498944Sobrien  lexptr += namelen;
136598944Sobrien
136698944Sobrien  tryname:
136798944Sobrien
136898944Sobrien  /* Catch specific keywords.  Should be done with a data structure.  */
136998944Sobrien  switch (namelen)
137098944Sobrien    {
137198944Sobrien    case 6:
1372130803Smarcel      if (DEPRECATED_STREQ (uptokstart, "OBJECT"))
137398944Sobrien	return CLASS;
1374130803Smarcel      if (DEPRECATED_STREQ (uptokstart, "RECORD"))
137598944Sobrien	return STRUCT;
1376130803Smarcel      if (DEPRECATED_STREQ (uptokstart, "SIZEOF"))
137798944Sobrien	return SIZEOF;
137898944Sobrien      break;
137998944Sobrien    case 5:
1380130803Smarcel      if (DEPRECATED_STREQ (uptokstart, "CLASS"))
138198944Sobrien	return CLASS;
1382130803Smarcel      if (DEPRECATED_STREQ (uptokstart, "FALSE"))
138398944Sobrien	{
138498944Sobrien          yylval.lval = 0;
1385130803Smarcel          return FALSEKEYWORD;
138698944Sobrien        }
138798944Sobrien      break;
138898944Sobrien    case 4:
1389130803Smarcel      if (DEPRECATED_STREQ (uptokstart, "TRUE"))
139098944Sobrien	{
139198944Sobrien          yylval.lval = 1;
1392130803Smarcel  	  return TRUEKEYWORD;
139398944Sobrien        }
1394130803Smarcel      if (DEPRECATED_STREQ (uptokstart, "SELF"))
139598944Sobrien        {
139698944Sobrien          /* here we search for 'this' like
139798944Sobrien             inserted in FPC stabs debug info */
1398130803Smarcel	  static const char this_name[] = "this";
139998944Sobrien
140098944Sobrien	  if (lookup_symbol (this_name, expression_context_block,
1401130803Smarcel			     VAR_DOMAIN, (int *) NULL,
140298944Sobrien			     (struct symtab **) NULL))
140398944Sobrien	    return THIS;
140498944Sobrien	}
140598944Sobrien      break;
140698944Sobrien    default:
140798944Sobrien      break;
140898944Sobrien    }
140998944Sobrien
141098944Sobrien  yylval.sval.ptr = tokstart;
141198944Sobrien  yylval.sval.length = namelen;
141298944Sobrien
141398944Sobrien  if (*tokstart == '$')
141498944Sobrien    {
141598944Sobrien      /* $ is the normal prefix for pascal hexadecimal values
141698944Sobrien        but this conflicts with the GDB use for debugger variables
141798944Sobrien        so in expression to enter hexadecimal values
141898944Sobrien        we still need to use C syntax with 0xff  */
141998944Sobrien      write_dollar_variable (yylval.sval);
142098944Sobrien      return VARIABLE;
142198944Sobrien    }
142298944Sobrien
142398944Sobrien  /* Use token-type BLOCKNAME for symbols that happen to be defined as
142498944Sobrien     functions or symtabs.  If this is not so, then ...
142598944Sobrien     Use token-type TYPENAME for symbols that happen to be defined
142698944Sobrien     currently as names of types; NAME for other symbols.
142798944Sobrien     The caller is not constrained to care about the distinction.  */
142898944Sobrien  {
142998944Sobrien    char *tmp = copy_name (yylval.sval);
143098944Sobrien    struct symbol *sym;
143198944Sobrien    int is_a_field_of_this = 0;
1432130803Smarcel    int is_a_field = 0;
143398944Sobrien    int hextype;
143498944Sobrien
1435130803Smarcel
1436130803Smarcel    if (search_field && current_type)
1437130803Smarcel      is_a_field = (lookup_struct_elt_type (current_type, tmp, 1) != NULL);
1438130803Smarcel    if (is_a_field)
1439130803Smarcel      sym = NULL;
1440130803Smarcel    else
1441130803Smarcel      sym = lookup_symbol (tmp, expression_context_block,
1442130803Smarcel			   VAR_DOMAIN,
1443130803Smarcel			   &is_a_field_of_this,
1444130803Smarcel			   (struct symtab **) NULL);
144598944Sobrien    /* second chance uppercased (as Free Pascal does).  */
1446130803Smarcel    if (!sym && !is_a_field_of_this && !is_a_field)
144798944Sobrien      {
144898944Sobrien       for (i = 0; i <= namelen; i++)
144998944Sobrien         {
145098944Sobrien           if ((tmp[i] >= 'a' && tmp[i] <= 'z'))
145198944Sobrien             tmp[i] -= ('a'-'A');
145298944Sobrien         }
1453130803Smarcel       if (search_field && current_type)
1454130803Smarcel	 is_a_field = (lookup_struct_elt_type (current_type, tmp, 1) != NULL);
1455130803Smarcel       if (is_a_field)
1456130803Smarcel	 sym = NULL;
1457130803Smarcel       else
1458130803Smarcel	 sym = lookup_symbol (tmp, expression_context_block,
1459130803Smarcel                        VAR_DOMAIN,
146098944Sobrien                        &is_a_field_of_this,
146198944Sobrien                        (struct symtab **) NULL);
1462130803Smarcel       if (sym || is_a_field_of_this || is_a_field)
146398944Sobrien         for (i = 0; i <= namelen; i++)
146498944Sobrien           {
146598944Sobrien             if ((tokstart[i] >= 'a' && tokstart[i] <= 'z'))
146698944Sobrien               tokstart[i] -= ('a'-'A');
146798944Sobrien           }
146898944Sobrien      }
146998944Sobrien    /* Third chance Capitalized (as GPC does).  */
1470130803Smarcel    if (!sym && !is_a_field_of_this && !is_a_field)
147198944Sobrien      {
147298944Sobrien       for (i = 0; i <= namelen; i++)
147398944Sobrien         {
147498944Sobrien           if (i == 0)
147598944Sobrien             {
147698944Sobrien              if ((tmp[i] >= 'a' && tmp[i] <= 'z'))
147798944Sobrien                tmp[i] -= ('a'-'A');
147898944Sobrien             }
147998944Sobrien           else
148098944Sobrien           if ((tmp[i] >= 'A' && tmp[i] <= 'Z'))
148198944Sobrien             tmp[i] -= ('A'-'a');
148298944Sobrien          }
1483130803Smarcel       if (search_field && current_type)
1484130803Smarcel	 is_a_field = (lookup_struct_elt_type (current_type, tmp, 1) != NULL);
1485130803Smarcel       if (is_a_field)
1486130803Smarcel	 sym = NULL;
1487130803Smarcel       else
1488130803Smarcel	 sym = lookup_symbol (tmp, expression_context_block,
1489130803Smarcel                         VAR_DOMAIN,
149098944Sobrien                         &is_a_field_of_this,
149198944Sobrien                         (struct symtab **) NULL);
1492130803Smarcel       if (sym || is_a_field_of_this || is_a_field)
149398944Sobrien          for (i = 0; i <= namelen; i++)
149498944Sobrien            {
149598944Sobrien              if (i == 0)
149698944Sobrien                {
149798944Sobrien                  if ((tokstart[i] >= 'a' && tokstart[i] <= 'z'))
149898944Sobrien                    tokstart[i] -= ('a'-'A');
149998944Sobrien                }
150098944Sobrien              else
150198944Sobrien                if ((tokstart[i] >= 'A' && tokstart[i] <= 'Z'))
150298944Sobrien                  tokstart[i] -= ('A'-'a');
150398944Sobrien            }
150498944Sobrien      }
1505130803Smarcel
1506130803Smarcel    if (is_a_field)
1507130803Smarcel      {
1508130803Smarcel	tempbuf = (char *) realloc (tempbuf, namelen + 1);
1509130803Smarcel	strncpy (tempbuf, tokstart, namelen); tempbuf [namelen] = 0;
1510130803Smarcel	yylval.sval.ptr = tempbuf;
1511130803Smarcel	yylval.sval.length = namelen;
1512130803Smarcel	return FIELDNAME;
1513130803Smarcel      }
151498944Sobrien    /* Call lookup_symtab, not lookup_partial_symtab, in case there are
151598944Sobrien       no psymtabs (coff, xcoff, or some future change to blow away the
151698944Sobrien       psymtabs once once symbols are read).  */
151798944Sobrien    if ((sym && SYMBOL_CLASS (sym) == LOC_BLOCK) ||
151898944Sobrien        lookup_symtab (tmp))
151998944Sobrien      {
152098944Sobrien	yylval.ssym.sym = sym;
152198944Sobrien	yylval.ssym.is_a_field_of_this = is_a_field_of_this;
152298944Sobrien	return BLOCKNAME;
152398944Sobrien      }
152498944Sobrien    if (sym && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
152598944Sobrien        {
152698944Sobrien#if 1
152798944Sobrien	  /* Despite the following flaw, we need to keep this code enabled.
152898944Sobrien	     Because we can get called from check_stub_method, if we don't
152998944Sobrien	     handle nested types then it screws many operations in any
153098944Sobrien	     program which uses nested types.  */
153198944Sobrien	  /* In "A::x", if x is a member function of A and there happens
153298944Sobrien	     to be a type (nested or not, since the stabs don't make that
153398944Sobrien	     distinction) named x, then this code incorrectly thinks we
153498944Sobrien	     are dealing with nested types rather than a member function.  */
153598944Sobrien
153698944Sobrien	  char *p;
153798944Sobrien	  char *namestart;
153898944Sobrien	  struct symbol *best_sym;
153998944Sobrien
154098944Sobrien	  /* Look ahead to detect nested types.  This probably should be
154198944Sobrien	     done in the grammar, but trying seemed to introduce a lot
154298944Sobrien	     of shift/reduce and reduce/reduce conflicts.  It's possible
154398944Sobrien	     that it could be done, though.  Or perhaps a non-grammar, but
154498944Sobrien	     less ad hoc, approach would work well.  */
154598944Sobrien
154698944Sobrien	  /* Since we do not currently have any way of distinguishing
154798944Sobrien	     a nested type from a non-nested one (the stabs don't tell
154898944Sobrien	     us whether a type is nested), we just ignore the
154998944Sobrien	     containing type.  */
155098944Sobrien
155198944Sobrien	  p = lexptr;
155298944Sobrien	  best_sym = sym;
155398944Sobrien	  while (1)
155498944Sobrien	    {
155598944Sobrien	      /* Skip whitespace.  */
155698944Sobrien	      while (*p == ' ' || *p == '\t' || *p == '\n')
155798944Sobrien		++p;
155898944Sobrien	      if (*p == ':' && p[1] == ':')
155998944Sobrien		{
156098944Sobrien		  /* Skip the `::'.  */
156198944Sobrien		  p += 2;
156298944Sobrien		  /* Skip whitespace.  */
156398944Sobrien		  while (*p == ' ' || *p == '\t' || *p == '\n')
156498944Sobrien		    ++p;
156598944Sobrien		  namestart = p;
156698944Sobrien		  while (*p == '_' || *p == '$' || (*p >= '0' && *p <= '9')
156798944Sobrien			 || (*p >= 'a' && *p <= 'z')
156898944Sobrien			 || (*p >= 'A' && *p <= 'Z'))
156998944Sobrien		    ++p;
157098944Sobrien		  if (p != namestart)
157198944Sobrien		    {
157298944Sobrien		      struct symbol *cur_sym;
157398944Sobrien		      /* As big as the whole rest of the expression, which is
157498944Sobrien			 at least big enough.  */
157598944Sobrien		      char *ncopy = alloca (strlen (tmp)+strlen (namestart)+3);
157698944Sobrien		      char *tmp1;
157798944Sobrien
157898944Sobrien		      tmp1 = ncopy;
157998944Sobrien		      memcpy (tmp1, tmp, strlen (tmp));
158098944Sobrien		      tmp1 += strlen (tmp);
158198944Sobrien		      memcpy (tmp1, "::", 2);
158298944Sobrien		      tmp1 += 2;
158398944Sobrien		      memcpy (tmp1, namestart, p - namestart);
158498944Sobrien		      tmp1[p - namestart] = '\0';
158598944Sobrien		      cur_sym = lookup_symbol (ncopy, expression_context_block,
1586130803Smarcel					       VAR_DOMAIN, (int *) NULL,
158798944Sobrien					       (struct symtab **) NULL);
158898944Sobrien		      if (cur_sym)
158998944Sobrien			{
159098944Sobrien			  if (SYMBOL_CLASS (cur_sym) == LOC_TYPEDEF)
159198944Sobrien			    {
159298944Sobrien			      best_sym = cur_sym;
159398944Sobrien			      lexptr = p;
159498944Sobrien			    }
159598944Sobrien			  else
159698944Sobrien			    break;
159798944Sobrien			}
159898944Sobrien		      else
159998944Sobrien			break;
160098944Sobrien		    }
160198944Sobrien		  else
160298944Sobrien		    break;
160398944Sobrien		}
160498944Sobrien	      else
160598944Sobrien		break;
160698944Sobrien	    }
160798944Sobrien
160898944Sobrien	  yylval.tsym.type = SYMBOL_TYPE (best_sym);
160998944Sobrien#else /* not 0 */
161098944Sobrien	  yylval.tsym.type = SYMBOL_TYPE (sym);
161198944Sobrien#endif /* not 0 */
161298944Sobrien	  return TYPENAME;
161398944Sobrien        }
161498944Sobrien    if ((yylval.tsym.type = lookup_primitive_typename (tmp)) != 0)
161598944Sobrien	return TYPENAME;
161698944Sobrien
161798944Sobrien    /* Input names that aren't symbols but ARE valid hex numbers,
161898944Sobrien       when the input radix permits them, can be names or numbers
161998944Sobrien       depending on the parse.  Note we support radixes > 16 here.  */
162098944Sobrien    if (!sym &&
162198944Sobrien        ((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10) ||
162298944Sobrien         (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10)))
162398944Sobrien      {
162498944Sobrien 	YYSTYPE newlval;	/* Its value is ignored.  */
162598944Sobrien	hextype = parse_number (tokstart, namelen, 0, &newlval);
162698944Sobrien	if (hextype == INT)
162798944Sobrien	  {
162898944Sobrien	    yylval.ssym.sym = sym;
162998944Sobrien	    yylval.ssym.is_a_field_of_this = is_a_field_of_this;
163098944Sobrien	    return NAME_OR_INT;
163198944Sobrien	  }
163298944Sobrien      }
163398944Sobrien
163498944Sobrien    free(uptokstart);
163598944Sobrien    /* Any other kind of symbol */
163698944Sobrien    yylval.ssym.sym = sym;
163798944Sobrien    yylval.ssym.is_a_field_of_this = is_a_field_of_this;
163898944Sobrien    return NAME;
163998944Sobrien  }
164098944Sobrien}
164198944Sobrien
164298944Sobrienvoid
164398944Sobrienyyerror (msg)
164498944Sobrien     char *msg;
164598944Sobrien{
1646130803Smarcel  if (prev_lexptr)
1647130803Smarcel    lexptr = prev_lexptr;
1648130803Smarcel
164998944Sobrien  error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
165098944Sobrien}
1651