]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/ada-lex.l
* coff-rs6000.c (rs6000coff_vec): Add initializer for
[thirdparty/binutils-gdb.git] / gdb / ada-lex.l
CommitLineData
14f9c5c9 1/* FLEX lexer for Ada expressions, for GDB.
4c4b4cd2 2 Copyright (C) 1994, 1997, 1998, 2000, 2001, 2002, 2003
14f9c5c9
AS
3 Free Software Foundation, Inc.
4
5This file is part of GDB.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2 of the License, or
10(at your option) any later version.
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with this program; if not, write to the Free Software
19Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21/*----------------------------------------------------------------------*/
22
23/* The converted version of this file is to be included in ada-exp.y, */
24/* the Ada parser for gdb. The function yylex obtains characters from */
25/* the global pointer lexptr. It returns a syntactic category for */
26/* each successive token and places a semantic value into yylval */
27/* (ada-lval), defined by the parser. */
28
14f9c5c9
AS
29DIG [0-9]
30NUM10 ({DIG}({DIG}|_)*)
31HEXDIG [0-9a-f]
32NUM16 ({HEXDIG}({HEXDIG}|_)*)
33OCTDIG [0-7]
34LETTER [a-z_]
35ID ({LETTER}({LETTER}|{DIG})*|"<"{LETTER}({LETTER}|{DIG})*">")
36WHITE [ \t\n]
37TICK ("'"{WHITE}*)
38GRAPHIC [a-z0-9 #&'()*+,-./:;<>=_|!$%?@\[\]\\^`{}~]
39OPER ([-+*/=<>&]|"<="|">="|"**"|"/="|"and"|"or"|"xor"|"not"|"mod"|"rem"|"abs")
40
41EXP (e[+-]{NUM10})
42POSEXP (e"+"?{NUM10})
43
44%{
4c4b4cd2 45
14f9c5c9
AS
46#define NUMERAL_WIDTH 256
47#define LONGEST_SIGN ((ULONGEST) 1 << (sizeof(LONGEST) * HOST_CHAR_BIT - 1))
48
4c4b4cd2
PH
49/* Temporary staging for numeric literals. */
50static char numbuf[NUMERAL_WIDTH];
51 static void canonicalizeNumeral (char *s1, const char *);
52static int processInt (const char *, const char *, const char *);
53static int processReal (const char *);
54static int processId (const char *, int);
55static int processAttribute (const char *);
56static int find_dot_all (const char *);
14f9c5c9
AS
57
58#undef YY_DECL
4c4b4cd2 59#define YY_DECL static int yylex ( void )
14f9c5c9
AS
60
61#undef YY_INPUT
62#define YY_INPUT(BUF, RESULT, MAX_SIZE) \
63 if ( *lexptr == '\000' ) \
64 (RESULT) = YY_NULL; \
65 else \
66 { \
67 *(BUF) = *lexptr; \
68 (RESULT) = 1; \
69 lexptr += 1; \
70 }
71
72static char *tempbuf = NULL;
73static int tempbufsize = 0;
74static int tempbuf_len;
4c4b4cd2 75static struct block *left_block_context;
14f9c5c9
AS
76
77static void resize_tempbuf (unsigned int);
78
4c4b4cd2 79static void block_lookup (char *, char *);
14f9c5c9 80
4c4b4cd2 81static int name_lookup (char *, char *, int *, int);
14f9c5c9 82
4c4b4cd2 83static int find_dot_all (const char *);
14f9c5c9
AS
84
85%}
86
7dc1ef8d
PH
87%option case-insensitive interactive nodefault
88
14f9c5c9
AS
89%s IN_STRING BEFORE_QUAL_QUOTE
90
91%%
92
93{WHITE} { }
94
95"--".* { yyterminate(); }
96
4c4b4cd2
PH
97{NUM10}{POSEXP} {
98 canonicalizeNumeral (numbuf, yytext);
14f9c5c9
AS
99 return processInt (NULL, numbuf, strrchr(numbuf, 'e')+1);
100 }
101
4c4b4cd2
PH
102{NUM10} {
103 canonicalizeNumeral (numbuf, yytext);
14f9c5c9
AS
104 return processInt (NULL, numbuf, NULL);
105 }
106
107{NUM10}"#"{HEXDIG}({HEXDIG}|_)*"#"{POSEXP} {
108 canonicalizeNumeral (numbuf, yytext);
109 return processInt (numbuf,
4c4b4cd2 110 strchr (numbuf, '#') + 1,
14f9c5c9
AS
111 strrchr(numbuf, '#') + 1);
112 }
113
114{NUM10}"#"{HEXDIG}({HEXDIG}|_)*"#" {
115 canonicalizeNumeral (numbuf, yytext);
116 return processInt (numbuf, strchr (numbuf, '#') + 1, NULL);
117 }
118
119"0x"{HEXDIG}+ {
120 canonicalizeNumeral (numbuf, yytext+2);
121 return processInt ("16#", numbuf, NULL);
122 }
123
124
125{NUM10}"."{NUM10}{EXP} {
4c4b4cd2 126 canonicalizeNumeral (numbuf, yytext);
14f9c5c9
AS
127 return processReal (numbuf);
128 }
129
130{NUM10}"."{NUM10} {
4c4b4cd2 131 canonicalizeNumeral (numbuf, yytext);
14f9c5c9
AS
132 return processReal (numbuf);
133 }
134
135{NUM10}"#"{NUM16}"."{NUM16}"#"{EXP} {
136 error ("Based real literals not implemented yet.");
137 }
138
139{NUM10}"#"{NUM16}"."{NUM16}"#" {
140 error ("Based real literals not implemented yet.");
141 }
142
143<INITIAL>"'"({GRAPHIC}|\")"'" {
72d5681a 144 yylval.typed_val.type = type_char ();
14f9c5c9
AS
145 yylval.typed_val.val = yytext[1];
146 return CHARLIT;
147 }
148
149<INITIAL>"'[\""{HEXDIG}{2}"\"]'" {
150 int v;
72d5681a 151 yylval.typed_val.type = type_char ();
14f9c5c9
AS
152 sscanf (yytext+3, "%2x", &v);
153 yylval.typed_val.val = v;
154 return CHARLIT;
155 }
156
157\"{OPER}\"/{WHITE}*"(" { return processId (yytext, yyleng); }
158
4c4b4cd2 159<INITIAL>\" {
14f9c5c9
AS
160 tempbuf_len = 0;
161 BEGIN IN_STRING;
162 }
163
164<IN_STRING>{GRAPHIC}*\" {
165 resize_tempbuf (yyleng+tempbuf_len);
166 strncpy (tempbuf+tempbuf_len, yytext, yyleng-1);
167 tempbuf_len += yyleng-1;
168 yylval.sval.ptr = tempbuf;
169 yylval.sval.length = tempbuf_len;
170 BEGIN INITIAL;
171 return STRING;
172 }
173
174<IN_STRING>{GRAPHIC}*"[\""{HEXDIG}{2}"\"]" {
175 int n;
176 resize_tempbuf (yyleng-5+tempbuf_len+1);
177 strncpy (tempbuf+tempbuf_len, yytext, yyleng-6);
178 sscanf(yytext+yyleng-4, "%2x", &n);
179 tempbuf[yyleng-6+tempbuf_len] = (char) n;
180 tempbuf_len += yyleng-5;
181 }
182
183<IN_STRING>{GRAPHIC}*"[\"\"\"]" {
184 int n;
185 resize_tempbuf (yyleng-4+tempbuf_len+1);
186 strncpy (tempbuf+tempbuf_len, yytext, yyleng-6);
187 tempbuf[yyleng-5+tempbuf_len] = '"';
188 tempbuf_len += yyleng-4;
189 }
190
4c4b4cd2
PH
191if {
192 while (*lexptr != 'i' && *lexptr != 'I')
193 lexptr -= 1;
194 yyrestart(NULL);
14f9c5c9
AS
195 return 0;
196 }
197
198 /* ADA KEYWORDS */
199
200abs { return ABS; }
201and { return _AND_; }
202else { return ELSE; }
203in { return IN; }
204mod { return MOD; }
205new { return NEW; }
206not { return NOT; }
207null { return NULL_PTR; }
208or { return OR; }
209rem { return REM; }
210then { return THEN; }
211xor { return XOR; }
212
213 /* ATTRIBUTES */
214
215{TICK}[a-zA-Z][a-zA-Z]+ { return processAttribute (yytext+1); }
216
217 /* PUNCTUATION */
218
219"=>" { return ARROW; }
220".." { return DOTDOT; }
221"**" { return STARSTAR; }
222":=" { return ASSIGN; }
223"/=" { return NOTEQUAL; }
224"<=" { return LEQ; }
225">=" { return GEQ; }
226
227<BEFORE_QUAL_QUOTE>"'" { BEGIN INITIAL; return '\''; }
228
229[-&*+./:<>=|;\[\]] { return yytext[0]; }
230
231"," { if (paren_depth == 0 && comma_terminates)
232 {
233 lexptr -= 1;
234 yyrestart(NULL);
235 return 0;
236 }
4c4b4cd2 237 else
14f9c5c9
AS
238 return ',';
239 }
240
241"(" { paren_depth += 1; return '('; }
4c4b4cd2 242")" { if (paren_depth == 0)
14f9c5c9
AS
243 {
244 lexptr -= 1;
245 yyrestart(NULL);
246 return 0;
247 }
4c4b4cd2 248 else
14f9c5c9 249 {
4c4b4cd2 250 paren_depth -= 1;
14f9c5c9
AS
251 return ')';
252 }
253 }
254
255"."{WHITE}*all { return DOT_ALL; }
256
4c4b4cd2 257"."{WHITE}*{ID} {
14f9c5c9 258 processId (yytext+1, yyleng-1);
4c4b4cd2 259 return DOT_ID;
14f9c5c9
AS
260 }
261
4c4b4cd2 262{ID}({WHITE}*"."{WHITE}*({ID}|\"{OPER}\"))*(" "*"'")? {
14f9c5c9
AS
263 int all_posn = find_dot_all (yytext);
264 int token_type, segments, k;
265 int quote_follows;
266
4c4b4cd2 267 if (all_posn == -1 && yytext[yyleng-1] == '\'')
14f9c5c9
AS
268 {
269 quote_follows = 1;
4c4b4cd2
PH
270 do {
271 yyless (yyleng-1);
14f9c5c9
AS
272 } while (yytext[yyleng-1] == ' ');
273 }
274 else
4c4b4cd2
PH
275 quote_follows = 0;
276
14f9c5c9
AS
277 if (all_posn >= 0)
278 yyless (all_posn);
279 processId(yytext, yyleng);
4c4b4cd2
PH
280 segments = name_lookup (ada_encode (yylval.ssym.stoken.ptr),
281 yylval.ssym.stoken.ptr,
282 &token_type,
283 MAX_RENAMING_CHAIN_LENGTH);
14f9c5c9
AS
284 left_block_context = NULL;
285 for (k = yyleng; segments > 0 && k > 0; k -= 1)
286 {
287 if (yytext[k-1] == '.')
288 segments -= 1;
289 quote_follows = 0;
290 }
291 if (k <= 0)
292 error ("confused by name %s", yytext);
293 yyless (k);
4c4b4cd2 294 if (quote_follows)
14f9c5c9
AS
295 BEGIN BEFORE_QUAL_QUOTE;
296 return token_type;
297 }
298
299 /* GDB EXPRESSION CONSTRUCTS */
300
301
302"'"[^']+"'"{WHITE}*:: {
303 processId(yytext, yyleng-2);
304 block_lookup (yylval.ssym.stoken.ptr, yylval.ssym.stoken.ptr);
305 return BLOCKNAME;
306 }
307
4c4b4cd2 308{ID}({WHITE}*"."{WHITE}*({ID}|\"{OPER}\"))*{WHITE}*:: {
14f9c5c9 309 processId(yytext, yyleng-2);
4c4b4cd2 310 block_lookup (ada_encode (yylval.ssym.stoken.ptr),
14f9c5c9
AS
311 yylval.ssym.stoken.ptr);
312 return BLOCKNAME;
313 }
314
315[{}@] { return yytext[0]; }
316
14f9c5c9
AS
317 /* REGISTERS AND GDB CONVENIENCE VARIABLES */
318
4c4b4cd2 319"$"({LETTER}|{DIG}|"$")* {
14f9c5c9
AS
320 yylval.sval.ptr = yytext;
321 yylval.sval.length = yyleng;
4c4b4cd2 322 return SPECIAL_VARIABLE;
14f9c5c9
AS
323 }
324
325 /* CATCH-ALL ERROR CASE */
326
327. { error ("Invalid character '%s' in expression.", yytext); }
328%%
329
330#include <ctype.h>
19c1ef65 331#include "gdb_string.h"
14f9c5c9
AS
332
333/* Initialize the lexer for processing new expression */
334void
4c4b4cd2 335lexer_init (FILE *inp)
14f9c5c9
AS
336{
337 BEGIN INITIAL;
338 yyrestart (inp);
339}
340
341
4c4b4cd2 342/* Make sure that tempbuf points at an array at least N characters long. */
14f9c5c9
AS
343
344static void
4c4b4cd2 345resize_tempbuf (unsigned int n)
14f9c5c9
AS
346{
347 if (tempbufsize < n)
348 {
349 tempbufsize = (n+63) & ~63;
23485554 350 tempbuf = (char *) realloc (tempbuf, tempbufsize);
14f9c5c9
AS
351 }
352}
4c4b4cd2
PH
353
354/* Copy S2 to S1, removing all underscores, and downcasing all letters. */
14f9c5c9
AS
355
356static void
4c4b4cd2 357canonicalizeNumeral (char *s1, const char *s2)
14f9c5c9 358{
4c4b4cd2 359 for (; *s2 != '\000'; s2 += 1)
14f9c5c9
AS
360 {
361 if (*s2 != '_')
362 {
363 *s1 = tolower(*s2);
364 s1 += 1;
365 }
366 }
367 s1[0] = '\000';
368}
369
370#define HIGH_BYTE_POSN ((sizeof (ULONGEST) - 1) * HOST_CHAR_BIT)
371
4c4b4cd2 372/* True (non-zero) iff DIGIT is a valid digit in radix BASE,
14f9c5c9
AS
373 where 2 <= BASE <= 16. */
374
375static int
4c4b4cd2 376is_digit_in_base (unsigned char digit, int base)
14f9c5c9
AS
377{
378 if (!isxdigit (digit))
379 return 0;
380 if (base <= 10)
381 return (isdigit (digit) && digit < base + '0');
4c4b4cd2 382 else
14f9c5c9
AS
383 return (isdigit (digit) || tolower (digit) < base - 10 + 'a');
384}
385
386static int
4c4b4cd2 387digit_to_int (unsigned char c)
14f9c5c9
AS
388{
389 if (isdigit (c))
390 return c - '0';
391 else
392 return tolower (c) - 'a' + 10;
393}
394
4c4b4cd2 395/* As for strtoul, but for ULONGEST results. */
14f9c5c9 396ULONGEST
4c4b4cd2 397strtoulst (const char *num, const char **trailer, int base)
14f9c5c9
AS
398{
399 unsigned int high_part;
400 ULONGEST result;
401 int i;
402 unsigned char lim;
403
404 if (base < 2 || base > 16)
405 {
406 errno = EINVAL;
407 return 0;
408 }
409 lim = base - 1 + '0';
410
411 result = high_part = 0;
412 for (i = 0; is_digit_in_base (num[i], base); i += 1)
413 {
414 result = result*base + digit_to_int (num[i]);
415 high_part = high_part*base + (unsigned int) (result >> HIGH_BYTE_POSN);
416 result &= ((ULONGEST) 1 << HIGH_BYTE_POSN) - 1;
4c4b4cd2 417 if (high_part > 0xff)
14f9c5c9
AS
418 {
419 errno = ERANGE;
420 result = high_part = 0;
421 break;
422 }
423 }
424
425 if (trailer != NULL)
426 *trailer = &num[i];
427
428 return result + ((ULONGEST) high_part << HIGH_BYTE_POSN);
429}
430
431
432
433/* Interprets the prefix of NUM that consists of digits of the given BASE
434 as an integer of that BASE, with the string EXP as an exponent.
435 Puts value in yylval, and returns INT, if the string is valid. Causes
4c4b4cd2
PH
436 an error if the number is improperly formated. BASE, if NULL, defaults
437 to "10", and EXP to "1". The EXP does not contain a leading 'e' or 'E'. */
14f9c5c9
AS
438
439static int
4c4b4cd2 440processInt (const char *base0, const char *num0, const char *exp0)
14f9c5c9
AS
441{
442 ULONGEST result;
443 long exp;
444 int base;
445
4c4b4cd2 446 char *trailer;
14f9c5c9
AS
447
448 if (base0 == NULL)
449 base = 10;
450 else
4c4b4cd2
PH
451 {
452 base = strtol (base0, (char **) NULL, 10);
14f9c5c9
AS
453 if (base < 2 || base > 16)
454 error ("Invalid base: %d.", base);
455 }
456
457 if (exp0 == NULL)
458 exp = 0;
459 else
4c4b4cd2 460 exp = strtol(exp0, (char **) NULL, 10);
14f9c5c9
AS
461
462 errno = 0;
4c4b4cd2 463 result = strtoulst (num0, (const char **) &trailer, base);
14f9c5c9
AS
464 if (errno == ERANGE)
465 error ("Integer literal out of range");
466 if (isxdigit(*trailer))
467 error ("Invalid digit `%c' in based literal", *trailer);
468
4c4b4cd2 469 while (exp > 0)
14f9c5c9
AS
470 {
471 if (result > (ULONG_MAX / base))
472 error ("Integer literal out of range");
473 result *= base;
474 exp -= 1;
475 }
4c4b4cd2 476
14f9c5c9 477 if ((result >> (TARGET_INT_BIT-1)) == 0)
72d5681a 478 yylval.typed_val.type = type_int ();
14f9c5c9 479 else if ((result >> (TARGET_LONG_BIT-1)) == 0)
72d5681a 480 yylval.typed_val.type = type_long ();
14f9c5c9
AS
481 else if (((result >> (TARGET_LONG_BIT-1)) >> 1) == 0)
482 {
483 /* We have a number representable as an unsigned integer quantity.
4c4b4cd2 484 For consistency with the C treatment, we will treat it as an
14f9c5c9 485 anonymous modular (unsigned) quantity. Alas, the types are such
4c4b4cd2 486 that we need to store .val as a signed quantity. Sorry
14f9c5c9
AS
487 for the mess, but C doesn't officially guarantee that a simple
488 assignment does the trick (no, it doesn't; read the reference manual).
489 */
490 yylval.typed_val.type = builtin_type_unsigned_long;
491 if (result & LONGEST_SIGN)
4c4b4cd2
PH
492 yylval.typed_val.val =
493 (LONGEST) (result & ~LONGEST_SIGN)
14f9c5c9
AS
494 - (LONGEST_SIGN>>1) - (LONGEST_SIGN>>1);
495 else
496 yylval.typed_val.val = (LONGEST) result;
497 return INT;
498 }
4c4b4cd2 499 else
72d5681a 500 yylval.typed_val.type = type_long_long ();
14f9c5c9
AS
501
502 yylval.typed_val.val = (LONGEST) result;
503 return INT;
504}
505
4c4b4cd2
PH
506#if defined (PRINTF_HAS_LONG_DOUBLE)
507# undef PRINTF_HAS_LONG_DOUBLE
508# define PRINTF_HAS_LONG_DOUBLE 1
509#else
510# define PRINTF_HAS_LONG_DOUBLE 0
511#endif
512
14f9c5c9 513static int
4c4b4cd2 514processReal (const char *num0)
14f9c5c9 515{
4c4b4cd2
PH
516#if defined (PRINTF_HAS_LONG_DOUBLE)
517 if (sizeof (DOUBLEST) > sizeof (double))
518 sscanf (num0, "%Lg", &yylval.typed_val_float.dval);
14f9c5c9 519 else
4c4b4cd2 520#endif
14f9c5c9 521 {
14f9c5c9
AS
522 double temp;
523 sscanf (num0, "%lg", &temp);
524 yylval.typed_val_float.dval = temp;
14f9c5c9
AS
525 }
526
72d5681a 527 yylval.typed_val_float.type = type_float ();
14f9c5c9 528 if (sizeof(DOUBLEST) >= TARGET_DOUBLE_BIT / TARGET_CHAR_BIT)
72d5681a 529 yylval.typed_val_float.type = type_double ();
14f9c5c9 530 if (sizeof(DOUBLEST) >= TARGET_LONG_DOUBLE_BIT / TARGET_CHAR_BIT)
72d5681a 531 yylval.typed_val_float.type = type_long_double ();
14f9c5c9
AS
532
533 return FLOAT;
534}
535
536static int
4c4b4cd2 537processId (const char *name0, int len)
14f9c5c9 538{
4c4b4cd2 539 char *name = obstack_alloc (&temp_parse_space, len + 11);
14f9c5c9 540 int i0, i;
4c4b4cd2 541
14f9c5c9
AS
542 while (len > 0 && isspace (name0[len-1]))
543 len -= 1;
544 i = i0 = 0;
4c4b4cd2 545 while (i0 < len)
14f9c5c9
AS
546 {
547 if (isalnum (name0[i0]))
548 {
549 name[i] = tolower (name0[i0]);
550 i += 1; i0 += 1;
551 }
4c4b4cd2 552 else switch (name0[i0])
14f9c5c9
AS
553 {
554 default:
555 name[i] = name0[i0];
556 i += 1; i0 += 1;
557 break;
558 case ' ': case '\t':
559 i0 += 1;
560 break;
561 case '\'':
562 i0 += 1;
563 while (i0 < len && name0[i0] != '\'')
564 {
565 name[i] = name0[i0];
566 i += 1; i0 += 1;
567 }
568 i0 += 1;
569 break;
570 case '<':
571 i0 += 1;
572 while (i0 < len && name0[i0] != '>')
573 {
574 name[i] = name0[i0];
575 i += 1; i0 += 1;
576 }
577 i0 += 1;
578 break;
579 }
580 }
581 name[i] = '\000';
582
583 yylval.ssym.sym = NULL;
584 yylval.ssym.stoken.ptr = name;
585 yylval.ssym.stoken.length = i;
586 return NAME;
587}
588
4c4b4cd2
PH
589static void
590block_lookup (char *name, char *err_name)
14f9c5c9 591{
4c4b4cd2 592 struct ada_symbol_info *syms;
14f9c5c9
AS
593 int nsyms;
594 struct symtab *symtab;
595 nsyms = ada_lookup_symbol_list (name, left_block_context,
4c4b4cd2 596 VAR_DOMAIN, &syms);
14f9c5c9 597 if (left_block_context == NULL &&
4c4b4cd2 598 (nsyms == 0 || SYMBOL_CLASS (syms[0].sym) != LOC_BLOCK))
14f9c5c9
AS
599 symtab = lookup_symtab (name);
600 else
601 symtab = NULL;
602
603 if (symtab != NULL)
604 left_block_context = yylval.bval =
605 BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
4c4b4cd2 606 else if (nsyms == 0 || SYMBOL_CLASS (syms[0].sym) != LOC_BLOCK)
14f9c5c9
AS
607 {
608 if (left_block_context == NULL)
609 error ("No file or function \"%s\".", err_name);
610 else
611 error ("No function \"%s\" in specified context.", err_name);
612 }
4c4b4cd2 613 else
14f9c5c9 614 {
4c4b4cd2 615 left_block_context = yylval.bval = SYMBOL_BLOCK_VALUE (syms[0].sym);
14f9c5c9
AS
616 if (nsyms > 1)
617 warning ("Function name \"%s\" ambiguous here", err_name);
618 }
619}
620
4c4b4cd2 621/* Look up NAME0 (assumed to be encoded) as a name in VAR_DOMAIN,
14f9c5c9 622 setting *TOKEN_TYPE to NAME or TYPENAME, depending on what is
4c4b4cd2 623 found. Try first the entire name, then the name without the last
14f9c5c9 624 segment (i.e., after the last .id), etc., and return the number of
4c4b4cd2
PH
625 segments that had to be removed to get a match. Try only the full
626 name if it starts with "standard__". Calls error if no
14f9c5c9 627 matches are found, using ERR_NAME in any error message. When
4c4b4cd2
PH
628 exactly one symbol match is found, it is placed in yylval. When
629 the symbol is a renaming, follow at most DEPTH steps to find the
630 ultimate definition; cause error if depth exceeded. */
631
14f9c5c9 632static int
4c4b4cd2 633name_lookup (char *name0, char *err_name, int *token_type, int depth)
14f9c5c9 634{
4c4b4cd2
PH
635 struct ada_symbol_info *syms;
636 struct type *type;
14f9c5c9 637 int len0 = strlen (name0);
4c4b4cd2 638 char *name = obsavestring (name0, len0, &temp_parse_space);
14f9c5c9
AS
639 int nsyms;
640 int segments;
4c4b4cd2
PH
641
642 if (depth <= 0)
643 error ("Could not find renamed symbol \"%s\"", err_name);
644
14f9c5c9
AS
645 yylval.ssym.stoken.ptr = name;
646 yylval.ssym.stoken.length = strlen (name);
647 for (segments = 0; ; segments += 1)
648 {
4c4b4cd2 649 struct type *preferred_type;
14f9c5c9
AS
650 int i, preferred_index;
651
4c4b4cd2
PH
652 if (left_block_context == NULL)
653 nsyms = ada_lookup_symbol_list (name, expression_context_block,
654 VAR_DOMAIN, &syms);
14f9c5c9 655 else
4c4b4cd2
PH
656 nsyms = ada_lookup_symbol_list (name, left_block_context,
657 VAR_DOMAIN, &syms);
658
659
660 /* Check for a type renaming. */
14f9c5c9 661
4c4b4cd2
PH
662 if (nsyms == 1 && !ada_is_object_renaming (syms[0].sym))
663 {
664 struct symbol *renaming_sym =
665 ada_find_renaming_symbol (SYMBOL_LINKAGE_NAME (syms[0].sym),
666 syms[0].block);
667
668 if (renaming_sym != NULL)
669 syms[0].sym = renaming_sym;
670 }
671
672 /* Check for a type definition. */
14f9c5c9
AS
673
674 /* Look for a symbol that doesn't denote void. This is (I think) a */
4c4b4cd2 675 /* temporary kludge to get around problems in GNAT output. */
14f9c5c9
AS
676 preferred_index = -1; preferred_type = NULL;
677 for (i = 0; i < nsyms; i += 1)
4c4b4cd2 678 switch (SYMBOL_CLASS (syms[i].sym))
14f9c5c9
AS
679 {
680 case LOC_TYPEDEF:
4c4b4cd2 681 if (ada_prefer_type (SYMBOL_TYPE (syms[i].sym), preferred_type))
14f9c5c9
AS
682 {
683 preferred_index = i;
4c4b4cd2 684 preferred_type = SYMBOL_TYPE (syms[i].sym);
14f9c5c9
AS
685 }
686 break;
687 case LOC_REGISTER:
688 case LOC_ARG:
689 case LOC_REF_ARG:
690 case LOC_REGPARM:
691 case LOC_REGPARM_ADDR:
692 case LOC_LOCAL:
693 case LOC_LOCAL_ARG:
694 case LOC_BASEREG:
695 case LOC_BASEREG_ARG:
4c4b4cd2
PH
696 case LOC_COMPUTED:
697 case LOC_COMPUTED_ARG:
14f9c5c9
AS
698 goto NotType;
699 default:
700 break;
701 }
702 if (preferred_type != NULL)
703 {
4c4b4cd2
PH
704 if (TYPE_CODE (preferred_type) == TYPE_CODE_VOID)
705 error ("`%s' matches only void type name(s)",
706 ada_decode (name));
707 else if (ada_is_object_renaming (syms[preferred_index].sym))
14f9c5c9 708 {
4c4b4cd2 709 yylval.ssym.sym = syms[preferred_index].sym;
14f9c5c9
AS
710 *token_type = OBJECT_RENAMING;
711 return segments;
4c4b4cd2
PH
712 }
713 else if (ada_renaming_type (SYMBOL_TYPE (syms[preferred_index].sym))
14f9c5c9
AS
714 != NULL)
715 {
716 int result;
4c4b4cd2
PH
717 char *renaming
718 = ada_simple_renamed_entity (syms[preferred_index].sym);
719 char *new_name
720 = (char *) obstack_alloc (&temp_parse_space,
721 strlen (renaming) + len0
722 - yylval.ssym.stoken.length + 1);
14f9c5c9 723 strcpy (new_name, renaming);
19c1ef65 724 xfree (renaming);
14f9c5c9 725 strcat (new_name, name0 + yylval.ssym.stoken.length);
4c4b4cd2
PH
726 result = name_lookup (new_name, err_name, token_type, depth - 1);
727 if (result > segments)
14f9c5c9
AS
728 error ("Confused by renamed symbol.");
729 return result;
730 }
731 else if (segments == 0)
732 {
733 yylval.tval = preferred_type;
734 *token_type = TYPENAME;
735 return 0;
4c4b4cd2 736 }
14f9c5c9
AS
737 }
738
739 if (segments == 0)
740 {
54a5b07d
AC
741 type = language_lookup_primitive_type_by_name (current_language,
742 current_gdbarch,
743 name);
4c4b4cd2 744 if (type == NULL && strcmp ("system__address", name) == 0)
72d5681a 745 type = type_system_address ();
14f9c5c9
AS
746 if (type != NULL)
747 {
4c4b4cd2
PH
748 /* First check to see if we have a regular definition of this
749 type that just didn't happen to have been read yet. */
750 int ntypes;
751 struct symbol *sym;
752 char *expanded_name =
753 (char *) alloca (strlen (name) + sizeof ("standard__"));
754 strcpy (expanded_name, "standard__");
755 strcat (expanded_name, name);
756 sym = ada_lookup_symbol (expanded_name, NULL,
757 VAR_DOMAIN, NULL, NULL);
758 if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
759 type = SYMBOL_TYPE (sym);
760
14f9c5c9
AS
761 yylval.tval = type;
762 *token_type = TYPENAME;
763 return 0;
764 }
765 }
766
767 NotType:
4c4b4cd2 768 if (nsyms == 1)
14f9c5c9
AS
769 {
770 *token_type = NAME;
4c4b4cd2 771 yylval.ssym.sym = syms[0].sym;
14f9c5c9 772 yylval.ssym.msym = NULL;
4c4b4cd2 773 yylval.ssym.block = syms[0].block;
14f9c5c9
AS
774 return segments;
775 }
776 else if (nsyms == 0) {
777 int i;
4c4b4cd2 778 yylval.ssym.msym = ada_lookup_simple_minsym (name);
14f9c5c9
AS
779 if (yylval.ssym.msym != NULL)
780 {
781 yylval.ssym.sym = NULL;
782 yylval.ssym.block = NULL;
783 *token_type = NAME;
784 return segments;
785 }
786
4c4b4cd2
PH
787 if (segments == 0
788 && strncmp (name, "standard__", sizeof ("standard__") - 1) == 0)
789 error ("No definition of \"%s\" found.", err_name);
790
14f9c5c9
AS
791 for (i = yylval.ssym.stoken.length - 1; i > 0; i -= 1)
792 {
793 if (name[i] == '.')
4c4b4cd2 794 {
14f9c5c9
AS
795 name[i] = '\0';
796 yylval.ssym.stoken.length = i;
797 break;
798 }
799 else if (name[i] == '_' && name[i-1] == '_')
800 {
801 i -= 1;
802 name[i] = '\0';
803 yylval.ssym.stoken.length = i;
804 break;
805 }
806 }
4c4b4cd2 807 if (i <= 0)
14f9c5c9
AS
808 {
809 if (!have_full_symbols () && !have_partial_symbols ()
810 && left_block_context == NULL)
811 error ("No symbol table is loaded. Use the \"file\" command.");
812 if (left_block_context == NULL)
4c4b4cd2 813 error ("No definition of \"%s\" in current context.",
14f9c5c9
AS
814 err_name);
815 else
4c4b4cd2 816 error ("No definition of \"%s\" in specified context.",
14f9c5c9
AS
817 err_name);
818 }
819 }
4c4b4cd2 820 else
14f9c5c9
AS
821 {
822 *token_type = NAME;
823 yylval.ssym.sym = NULL;
824 yylval.ssym.msym = NULL;
825 if (left_block_context == NULL)
826 yylval.ssym.block = expression_context_block;
827 else
828 yylval.ssym.block = left_block_context;
829 return segments;
830 }
831 }
832}
833
834/* Returns the position within STR of the '.' in a
4c4b4cd2 835 '.{WHITE}*all' component of a dotted name, or -1 if there is none. */
14f9c5c9 836static int
4c4b4cd2 837find_dot_all (const char *str)
14f9c5c9
AS
838{
839 int i;
840 for (i = 0; str[i] != '\000'; i += 1)
841 {
842 if (str[i] == '.')
843 {
844 int i0 = i;
4c4b4cd2 845 do
14f9c5c9
AS
846 i += 1;
847 while (isspace (str[i]));
848 if (strcmp (str+i, "all") == 0
849 && ! isalnum (str[i+3]) && str[i+3] != '_')
850 return i0;
851 }
852 }
853 return -1;
4c4b4cd2 854}
14f9c5c9
AS
855
856/* Returns non-zero iff string SUBSEQ matches a subsequence of STR, ignoring
4c4b4cd2 857 case. */
14f9c5c9
AS
858
859static int
4c4b4cd2 860subseqMatch (const char *subseq, const char *str)
14f9c5c9
AS
861{
862 if (subseq[0] == '\0')
863 return 1;
864 else if (str[0] == '\0')
865 return 0;
866 else if (tolower (subseq[0]) == tolower (str[0]))
867 return subseqMatch (subseq+1, str+1) || subseqMatch (subseq, str+1);
868 else
869 return subseqMatch (subseq, str+1);
870}
14f9c5c9 871
4c4b4cd2
PH
872
873static struct { const char *name; int code; }
14f9c5c9
AS
874attributes[] = {
875 { "address", TICK_ADDRESS },
876 { "unchecked_access", TICK_ACCESS },
877 { "unrestricted_access", TICK_ACCESS },
878 { "access", TICK_ACCESS },
879 { "first", TICK_FIRST },
880 { "last", TICK_LAST },
881 { "length", TICK_LENGTH },
882 { "max", TICK_MAX },
883 { "min", TICK_MIN },
884 { "modulus", TICK_MODULUS },
885 { "pos", TICK_POS },
886 { "range", TICK_RANGE },
887 { "size", TICK_SIZE },
888 { "tag", TICK_TAG },
889 { "val", TICK_VAL },
890 { NULL, -1 }
891};
892
893/* Return the syntactic code corresponding to the attribute name or
894 abbreviation STR. */
895
896static int
4c4b4cd2 897processAttribute (const char *str)
14f9c5c9
AS
898{
899 int i, k;
900
901 for (i = 0; attributes[i].code != -1; i += 1)
902 if (strcasecmp (str, attributes[i].name) == 0)
903 return attributes[i].code;
904
905 for (i = 0, k = -1; attributes[i].code != -1; i += 1)
4c4b4cd2 906 if (subseqMatch (str, attributes[i].name))
14f9c5c9
AS
907 {
908 if (k == -1)
909 k = i;
4c4b4cd2 910 else
14f9c5c9
AS
911 error ("ambiguous attribute name: `%s'", str);
912 }
913 if (k == -1)
914 error ("unrecognized attribute: `%s'", str);
915
916 return attributes[k].code;
917}
918
919int
4c4b4cd2 920yywrap(void)
14f9c5c9
AS
921{
922 return 1;
923}
23485554
PH
924
925/* Dummy definition to suppress warnings about unused static definitions. */
926typedef void (*dummy_function) ();
927dummy_function ada_flex_use[] =
928{
929 (dummy_function) yyrealloc, (dummy_function) yyunput
930};