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