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