3 //#define errstream stdout
4 #define errstream stderr
6 /*****************************************************************************
8 *****************************************************************************/
9 bool syntax_pattern (NormPtr p
, Token first
, ...)
13 for (;first
!= -1; first
= va_arg (ap
, Token
))
15 default: if (CODE
[p
++] != first
) return 0;
16 ncase VERIFY_symbol
: if (!issymbol (CODE
[p
++])) return 0;
17 ncase VERIFY_string
: if (!isvalue (CODE
[p
++])) return 0;
23 /*****************************************************************************
24 -- Expression long-jumps
25 If an exception is raised with expr_error, it longjmps
26 Some allocated token strings will not be freed.
27 We know that. And we prefer to leave it that way.
28 *****************************************************************************/
30 typedef struct except_stck_t
{
31 struct except_stck_t
*up
;
39 static except_stck
*bottom
;
41 void set_catch (jmp_buf *env
, NormPtr p
, Token
*t
, int level
)
43 except_stck
*e
= (except_stck
*) malloc (sizeof * e
);
48 e
->scope
= active_scope ();
49 e
->rlevel
= e
->elevel
= level
;
53 static void dothrow (int level
)
55 bottom
->rlevel
= level
;
56 longjmp (*bottom
->env
, 1);
61 except_stck
*e
= bottom
;
62 int rlevel
= e
->rlevel
;
63 int rethrow
= rlevel
&& rlevel
> e
->elevel
;
65 restore_scope (e
->scope
);
71 void raise_skip_function ()
76 #define EER "expression error: "
77 #define WARN "Warning: "
79 static void throw_it (bool noerror
)
82 char *MSG
= noerror
? WARN
: EER
;
84 if (!bottom
|| (bottom
->rlevel
&& !bottom
->up
))
85 parse_error (last_location
, "Fatal");
87 fprintf (errstream
, "%sin expression: ", MSG
);
88 for (i
= 0; bottom
->expression
[i
] != -1; i
++)
89 fprintf (errstream
, "%s ", expand (bottom
->expression
[i
]));
90 fprintf (errstream
, "\n%sWhich is located in file %s:%i\n", MSG
,
91 c_file_of (bottom
->location
), c_line_of (bottom
->location
));
92 if (in_function
) fprintf (stderr
, "%sin function %s();\n", MSG
, expand (in_function
));
95 if (debugflag
.PARSE_ERRORS_SEGFAULT
)
97 if (debugflag
.EXPR_ERRORS_FATAL
) exit (1);
103 void expr_error (char *description
)
105 fprintf (errstream
, EER
"%s\n", description
);
109 void expr_errort (char *description
, Token t
)
111 fprintf (errstream
, EER
"%s `%s'\n", description
, expand (t
));
115 void expr_errortt (char *description
, Token t1
, Token t2
)
117 fprintf (errstream
, EER
"%s `%s' `%s'\n", description
, expand (t1
), expand (t2
));
121 void expr_warn (char *description
)
123 fprintf (errstream
, WARN
"%s\n", description
);
127 void expr_warnt (char *description
, Token t
)
129 fprintf (errstream
, WARN
"%s `%s'\n", description
, expand (t
));
133 void expr_warntt (char *description
, Token t1
, Token t2
)
135 fprintf (errstream
, WARN
"%s `%s' `%s'\n", description
, expand (t1
), expand (t2
));
139 static intnode
*undeftree
;
141 void expr_error_undef (Token t
, int w
)
143 if (intfind (undeftree
, t
)) dothrow (0);
145 intadd (&undeftree
, t
, i
);
146 fprintf (errstream
, EER
"Un%s '%s'\n", w
? "declared function" : "defined object", expand (t
));
150 void parse_error (NormPtr i
, char *p
)
152 fprintf (errstream
, "%s:%i [Token %i]: %s\n", c_file_of(i
), c_line_of(i
), i
, p
);
155 fprintf (errstream
, " Somewhere in ### ");
156 for (; n
< i
+ 10 && CODE
[n
] != -1; n
++)
157 fprintf (errstream
, "%s ", expand (CODE
[n
]));
158 fprintf (errstream
, " ###\n");
160 if (debugflag
.PARSE_ERRORS_SEGFAULT
)
166 NormPtr last_location
;
169 void parse_error_tok (Token t
, char *p
)
171 char *tmp
= (char*) alloca (strlen (p
) + strlen (expand (t
)) + 8);
172 sprintf (tmp
, "%s : `%s'", p
, expand (t
));
173 parse_error (last_location
, tmp
);
176 void parse_error_cpp (char *p
)
178 fprintf (errstream
, "Cpp error near line %i: %s\n", line
, p
);
182 void parse_error_toktok (Token t1
, Token t2
, char *p
)
184 char *tmp
= (char*) alloca (strlen (p
) + strlen (expand (t1
)) + strlen (expand (t2
)) + 9);
185 sprintf (tmp
, "%s : `%s' `%s'", p
, expand (t1
), expand (t2
));
186 parse_error (last_location
, tmp
);
189 void parse_error_pt (NormPtr i
, Token t
, char *p
)
191 char *tmp
= (char*) alloca (strlen (p
) + strlen (expand (t
)) + 8);
192 sprintf (tmp
, "%s : `%s'", p
, expand (t
));
193 parse_error (i
, tmp
);
196 void parse_error_ll (char *p
)
198 parse_error (last_location
, p
);
201 void warning_tok (char *p
, Token t
)
203 fprintf (errstream
, "Warning %s:%i %s '%s'\n", c_file_of (last_location
),
204 c_line_of (last_location
), p
, expand (t
));
206 /*************************************************************
207 * print a type. debuging routine which shalln't be used at all
208 *************************************************************/
211 void debug_pr_type (typeID t
)
214 PRINTF ("type[%i]: ", t
);
215 int *tt
= open_typeID (t
);
216 PRINTF ("(%i)", tt
[0]);
217 for (i
= 1; tt
[i
] != -1; i
++)
218 if (tt
[i
] == '*' || tt
[i
] == '(' || tt
[i
] == '[')
219 PRINTF ("%c", tt
[i
]);
220 else PRINTF ("|%i|", tt
[i
]);
225 /******************************************************************************
227 ******************************************************************************/
229 void name_of_simple_type (Token
*s
, typeID t
)
232 switch (r
= dbase_of (t
)) {
233 default: sintprintf (s
, iRESERVED_struct (r
), name_of_struct (r
), -1);
234 #define Case(x,...) break; case x: sintprintf (s, __VA_ARGS__, -1);
235 Case (B_SCHAR
, RESERVED_char
);
236 Case (B_UCHAR
, RESERVED_unsigned
, RESERVED_char
);
237 Case (B_SSINT
, RESERVED_short
, RESERVED_int
);
238 Case (B_USINT
, RESERVED_unsigned
, RESERVED_short
, RESERVED_int
);
239 Case (B_SINT
, RESERVED_int
);
240 Case (B_UINT
, RESERVED_unsigned
, RESERVED_int
);
241 Case (B_SLONG
, RESERVED_long
);
242 Case (B_ULONG
, RESERVED_unsigned
, RESERVED_long
);
243 Case (B_SLLONG
, RESERVED_long
, RESERVED_long
);
244 Case (B_ULLONG
, RESERVED_unsigned
, RESERVED_long
, RESERVED_long
);
245 Case (B_FLOAT
, RESERVED_float
);
246 Case (B_DOUBLE
, RESERVED_double
);
247 Case (B_LDOUBLE
, RESERVED_long
, RESERVED_double
);
248 Case (B_VOID
, RESERVED_void
);
253 /******************************************************************************
255 ******************************************************************************/
257 /* integer/float promotion */
258 typeID
bt_promotion (typeID t
)
260 int *tt
= open_typeID (t
);
262 int *tn
= allocaint (intlen (tt
) + 1);
265 return enter_type (tn
);
267 if (tt
[0] >= 0 || tt
[1] != -1)
269 if (tt
[0] <= B_ULLONG
)
271 if (tt
[0] <= B_LDOUBLE
)
276 /* turn a type to pointer to type */
277 typeID
ptrup (typeID t
)
280 tt
= open_typeID (t
);
281 tn
= allocaint (intlen (tt
) + 2);
284 intcpy (tn
+ 2, tt
+ 1);
285 return enter_type (tn
);
288 /* the effect of pointer indirection */
289 typeID
ptrdown (typeID t
)
291 int *tt
= open_typeID (t
), *tn
;
292 if (tt
[1] != '*' && tt
[1] != '[')
293 expr_error ("* not applicable");
294 tn
= allocaint (intlen (tt
));
296 intcpy (tn
+ 1, tt
+ 2);
297 return enter_type (tn
);
300 /* base type of [...] */
301 typeID
elliptic_type (typeID t
)
303 if (!typeID_elliptic (t
))
305 int *tt
= open_typeID (t
), *tn
;
306 tn
= allocaint (intlen (tt
));
308 intcpy (tn
+ 1, tt
+ 2);
309 return enter_type (tn
);
312 /* given a function type return the return type */
313 typeID
funcreturn (typeID t
)
315 int *tt
= open_typeID (t
), *tn
, i
;
317 expr_error ("bug: request return type of no function");
318 for (i
= 2; tt
[i
] != INTERNAL_ARGEND
; i
++);
319 tn
= allocaint (intlen (&tt
[i
]) + 2);
321 intcpy (tn
+ 1, tt
+ i
+ 1);
322 return enter_type (tn
);
325 /* take a function type and add the first rec* argument */
326 typeID
makemember (typeID t
, recID r
)
328 int *tt
= open_typeID (t
), *tn
;
330 expr_error ("bug: request to makemember on no function");
331 tn
= allocaint (intlen (tt
) + 4);
334 tn
[2] = pthis_of_struct (r
);
335 intcpy (tn
+ 3, tt
+ 2);
336 return enter_type (tn
);
339 /* remove the reference boost */
340 typeID
dereference (typeID t
)
342 int *tt
= open_typeID (t
), *tn
;
343 if (tt
[0] < REFERENCE_BASE
)
345 tn
= allocaint (intlen (tt
) + 1);
347 tn
[0] -= REFERENCE_BOOST
;
348 return enter_type (tn
);
351 Token
*build_type (typeID t
, Token o
, Token ret
[])
354 if (is_reference (t
))
355 t
= ptrdown (dereference (t
));
357 Token tmp
[100], *dcls
= &tmp
[20], *dcle
= dcls
;
358 Token
*st
= open_typeID (t
);
373 if (b
) *dcls
-- = '(', *dcle
++ = ')', b
= 0;
374 *dcle
++ = '['; *dcle
++ = ']';
377 if (b
) *dcls
-- = '(', *dcle
++ = ')', b
= 0;
380 if (st
[i
] == B_ELLIPSIS
) {
384 if (st
[i
] == INTERNAL_ARGEND
) break;
386 intcpy (dcle
, build_type (st
[i
++], 0, arg
));
387 dcle
+= intlen (dcle
);
390 if (dcle
[-1] == ',') --dcle
;
394 default: PRINTF ("UNKNWOWN %i\n", st
[i
]);
401 if (ISSYMBOL (st
[0])) sintprintf (ret
, st
[0], -1);
402 else sintprintf (ret
, isunion (st
[0]) ? RESERVED_union
: iRESERVED_struct (st
[0]),
403 name_of_struct (st
[0]), -1);
404 else switch (st
[0]) {
405 case B_UCHAR
: sintprintf (ret
, RESERVED_unsigned
, RESERVED_char
, -1);
406 ncase B_SCHAR
: sintprintf (ret
, RESERVED_char
, -1);
407 ncase B_USINT
: sintprintf (ret
, RESERVED_unsigned
, RESERVED_short
, RESERVED_int
, -1);
408 ncase B_SSINT
: sintprintf (ret
, RESERVED_short
, RESERVED_int
, -1);
409 ncase B_UINT
: sintprintf (ret
, RESERVED_unsigned
, RESERVED_int
, -1);
410 ncase B_SINT
: sintprintf (ret
, RESERVED_int
, -1);
411 ncase B_ULONG
: sintprintf (ret
, RESERVED_unsigned
, RESERVED_long
, -1);
412 ncase B_SLONG
: sintprintf (ret
, RESERVED_long
, -1);
413 ncase B_ULLONG
: sintprintf (ret
, RESERVED_unsigned
, RESERVED_long
, RESERVED_long
, -1);
414 ncase B_SLLONG
: sintprintf (ret
, RESERVED_long
, RESERVED_long
, -1);
415 ncase B_FLOAT
: sintprintf (ret
, RESERVED_float
, -1);
416 ncase B_DOUBLE
: sintprintf (ret
, RESERVED_double
, -1);
417 ncase B_VOID
: sintprintf (ret
, RESERVED_void
, -1);
420 intcat (ret
, dcls
+ 1);
425 typeID
typeof_designator (typeID t
, Token d
[])
428 Token x
= internal_identifier1 ();
431 sintprintf (expr
, x
, ISTR (d
), -1);
432 expr
[intlen (expr
) - 1] = -1;
434 enter_local_obj (x
, t
);
435 parse_expression_string (intdup (expr
), &E
);
436 close_local_scope ();
438 if (!E
.ok
) return typeID_void
;
440 if (E
.newExpr
[0] == x
)
441 intcpy (d
, E
.newExpr
+ 1), intcatc (d
, '=');
447 /***************************************************************
449 ***************************************************************/
450 Token
isunary_overloadable (Token t
)
453 case '!': return RESERVED_oper_excl
;
454 case '*': return RESERVED_oper_star
;
455 case '+': return RESERVED_oper_plus
;
456 case '-': return RESERVED_oper_minus
;
457 case '~': return RESERVED_oper_thingy
;
458 case POINTSAT
: return RESERVED_oper_pointsat
;
459 case PLUSPLUS
: return RESERVED_oper_plusplus
;
460 case MINUSMINUS
: return RESERVED_oper_minusminus
;
465 Token
isbinary_overloadable (Token t
)
468 case '%': return RESERVED_oper_mod
;
469 case '|': return RESERVED_oper_or
;
470 case '&': return RESERVED_oper_and
;
471 case '^': return RESERVED_oper_xor
;
472 case LSH
: return RESERVED_oper_lsh
;
473 case RSH
: return RESERVED_oper_rsh
;
474 case '*': return RESERVED_oper_mul
;
475 case '/': return RESERVED_oper_div
;
476 case '>': return RESERVED_oper_gr
;
477 case '<': return RESERVED_oper_le
;
478 case '+': return RESERVED_oper_add
;
479 case '-': return RESERVED_oper_sub
;
480 case ',': return RESERVED_oper_comma
;
481 case '[': return RESERVED_oper_array
;
482 case OROR
: return RESERVED_oper_oror
;
483 case EQCMP
: return RESERVED_oper_eq
;
484 case GEQCMP
: return RESERVED_oper_greq
;
485 case LEQCMP
: return RESERVED_oper_leq
;
486 case NEQCMP
: return RESERVED_oper_neq
;
487 case ANDAND
: return RESERVED_oper_andand
;
488 case '=': return RESERVED_oper_assign
;
489 case ASSIGNA
: return RESERVED_oper_as_a
;
490 case ASSIGNS
: return RESERVED_oper_as_s
;
491 case ASSIGNM
: return RESERVED_oper_as_m
;
492 case ASSIGND
: return RESERVED_oper_as_d
;
493 case ASSIGNR
: return RESERVED_oper_as_r
;
494 case ASSIGNBA
: return RESERVED_oper_as_ba
;
495 case ASSIGNBX
: return RESERVED_oper_as_bx
;
496 case ASSIGNBO
: return RESERVED_oper_as_bo
;
497 case ASSIGNRS
: return RESERVED_oper_as_rs
;
498 case ASSIGNLS
: return RESERVED_oper_as_ls
;
503 Token
isunary_postfix_overloadable (Token t
)
506 case PLUSPLUS
: return RESERVED_oper_plusplusp
;
507 case MINUSMINUS
: return RESERVED_oper_minusminusp
;
511 /***************************************************************
513 ***************************************************************/
514 Token
include_sys_header_s (char *s
)
517 sprintf (tmp
, "\n#include <%s>\n", s
);
518 return new_symbol (strdup (tmp
));
520 Token
include_sys_header (Token t
)
523 strcpy (fn
, expand (t
) + 1);
524 fn
[strlen (fn
) - 1] = 0;
525 return include_sys_header_s (fn
);
527 /***************************************************************
529 ***************************************************************/
530 Token
alias_func (recID r
, Token f
)
533 //xmark_function_USED (FSP (r), f);
534 sprintf (tmp
, "__attribute__ ((alias (\"%s\")))", expand (f
));
535 return new_symbol (strdup (tmp
));
537 /***************************************************************
538 linkonce section text
539 ***************************************************************/
540 Token
linkonce_data (Token s
)
542 if (NoLinkonce
) return BLANKT
;
545 sprintf (tmp
, "__attribute__ ((__section__(\""SECTION_LINKONCE_DATA
"%s\")))",
547 return new_symbol (strdup (tmp
));
550 Token
linkonce_data_f (Token s
)
552 if (NoLinkonce
) return BLANKT
;
555 sprintf (tmp
, "__attribute__ ((__section__(\""SECTION_LINKONCE_DATA
"%s_%s\")))",
556 expand (in_function
), expand (s
));
557 return new_symbol (strdup (tmp
));
560 Token
linkonce_text (Token s
)
562 if (NoLinkonce
) return BLANKT
;
565 sprintf (tmp
, "__attribute__ ((__section__(\""SECTION_LINKONCE_TEXT
"%s\")))",
567 return new_symbol (strdup (tmp
));
570 Token
linkonce_rodata (Token s
)
572 if (NoLinkonce
) return BLANKT
;
575 sprintf (tmp
, "__attribute__ ((__section__(\""SECTION_LINKONCE_RODATA
"%s\")))",
577 return new_symbol (strdup (tmp
));
580 Token
cleanup_func (Token s
)
583 sprintf (tmp
, "__attribute__ ((cleanup(%s)))",
585 return new_symbol (strdup (tmp
));
588 Token
section_vtblz (Token t
)
591 sprintf (tmp
, "__attribute__ ((section (\".rodata.vtblz%s\")))", expand (t
));
592 return new_symbol (strdup (tmp
));
595 /***************************************************************
596 internal typeof 'expression'
597 ***************************************************************/
598 typeID
typeof_expression (NormPtr p
, int i
)
601 parse_expression (p
, &E
, i
);
602 if (!E
.ok
) parse_error (p
, "can't proceed after expression error");
606 /***************************************************************
607 This is used to do the -very useful- anonymous object
610 We are trying to determine wheter we have an object
611 declaration or a constructor call expression.
613 The check is lazy though. It will return true if
614 the code is DEFINITELLY an expression.
615 There are cases where it may or may not be.
616 Return false and let programmer make it obvious.
618 In a declaration valid characters are only
619 ( * ) [ ] const volatile
620 only one symbol and anything inside the[]
621 ***************************************************************/
623 bool is_expression (NormPtr p
)
625 NormPtr p2
= skip_parenthesis (++p
);
630 switch (t
= CODE
[p
++]) {
632 case RESERVED_volatile
:
636 case '[': p
= skip_brackets (p
);
641 if (nsym
) return true;
647 /******************************************************************************
648 As an exception to everything, __builtin_va_arg looks like a function,
649 but the second argument is a type. This breaks the entire parser
650 code. Adding a check to the parser for whether the function name
651 is "__builtin_va_arg", is not worth it.
653 This bogus here will replace the token string:
654 '__builtin_va_arg' '(' 'var' ',' 'type' ')'
655 With the pseudo value:
656 "__builtin_va_arg (var,type)"
658 which is internally treated as a constant value
660 ******************************************************************************/
662 #define strspcat(x, y) strcat (strcat (x, " "), y)
666 Token t
= Lookup_Symbol ("__builtin_va_arg");
674 for (p
= 0; CODE
[p
] != -1; p
++)
677 strcpy (tmpstr
, expand (t
));
678 if (CODE
[++p
] != '(') parse_error (p
, "__builtin_va_arg");
679 ps
= skip_parenthesis (p
+ 1);
681 strspcat (tmpstr
, expand (CODE
[p
++]));
682 CODE
[pe
++] = symi
+ c_nval
+ VALBASE
;
683 newsym
[symi
++] = strdup (tmpstr
);
686 while ((CODE
[pe
++] = CODE
[ps
++]) != -1);
688 add_extra_values (newsym
, symi
);