]>
Commit | Line | Data |
---|---|---|
b0699dad | 1 | /* Parse C expressions for cpplib. |
525bc95d | 2 | Copyright (C) 1987, 92, 94, 95, 97, 98, 1999, 2000 Free Software Foundation. |
7f2935c7 PB |
3 | |
4 | This program is free software; you can redistribute it and/or modify it | |
5 | under the terms of the GNU General Public License as published by the | |
6 | Free Software Foundation; either version 2, or (at your option) any | |
7 | later version. | |
8 | ||
9 | This program is distributed in the hope that it will be useful, | |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | GNU General Public License for more details. | |
13 | ||
14 | You should have received a copy of the GNU General Public License | |
15 | along with this program; if not, write to the Free Software | |
940d9d63 RK |
16 | Foundation, 59 Temple Place - Suite 330, |
17 | Boston, MA 02111-1307, USA. | |
7f2935c7 PB |
18 | |
19 | In other words, you are welcome to use, share and improve this program. | |
20 | You are forbidden to forbid anyone else to use, share and improve | |
21 | what you give them. Help stamp out software-hoarding! | |
22 | ||
0f41302f | 23 | Written by Per Bothner 1994. */ |
7f2935c7 PB |
24 | |
25 | /* Parse a C expression from text in a string */ | |
26 | ||
27 | #include "config.h" | |
b04cd507 | 28 | #include "system.h" |
487a6e06 | 29 | #include "cpplib.h" |
88ae23e7 | 30 | #include "cpphash.h" |
7f2935c7 | 31 | |
7f2935c7 PB |
32 | #ifndef CHAR_TYPE_SIZE |
33 | #define CHAR_TYPE_SIZE BITS_PER_UNIT | |
34 | #endif | |
35 | ||
36 | #ifndef INT_TYPE_SIZE | |
37 | #define INT_TYPE_SIZE BITS_PER_WORD | |
38 | #endif | |
39 | ||
40 | #ifndef LONG_TYPE_SIZE | |
41 | #define LONG_TYPE_SIZE BITS_PER_WORD | |
42 | #endif | |
43 | ||
44 | #ifndef WCHAR_TYPE_SIZE | |
45 | #define WCHAR_TYPE_SIZE INT_TYPE_SIZE | |
46 | #endif | |
47 | ||
48 | #ifndef MAX_CHAR_TYPE_SIZE | |
49 | #define MAX_CHAR_TYPE_SIZE CHAR_TYPE_SIZE | |
50 | #endif | |
51 | ||
52 | #ifndef MAX_INT_TYPE_SIZE | |
53 | #define MAX_INT_TYPE_SIZE INT_TYPE_SIZE | |
54 | #endif | |
55 | ||
56 | #ifndef MAX_LONG_TYPE_SIZE | |
57 | #define MAX_LONG_TYPE_SIZE LONG_TYPE_SIZE | |
58 | #endif | |
59 | ||
60 | #ifndef MAX_WCHAR_TYPE_SIZE | |
61 | #define MAX_WCHAR_TYPE_SIZE WCHAR_TYPE_SIZE | |
62 | #endif | |
63 | ||
e915b770 | 64 | #define MAX_CHAR_TYPE_MASK (MAX_CHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \ |
b22ef131 NB |
65 | ? (~(~(HOST_WIDEST_INT) 0 << MAX_CHAR_TYPE_SIZE)) \ |
66 | : ~ (HOST_WIDEST_INT) 0) | |
f1a86df6 | 67 | |
e915b770 | 68 | #define MAX_WCHAR_TYPE_MASK (MAX_WCHAR_TYPE_SIZE < HOST_BITS_PER_WIDEST_INT \ |
b0699dad | 69 | ? ~(~(HOST_WIDEST_INT) 0 << MAX_WCHAR_TYPE_SIZE) \ |
e915b770 | 70 | : ~ (HOST_WIDEST_INT) 0) |
f1a86df6 | 71 | |
7f2935c7 PB |
72 | /* Yield nonzero if adding two numbers with A's and B's signs can yield a |
73 | number with SUM's sign, where A, B, and SUM are all C integers. */ | |
74 | #define possible_sum_sign(a, b, sum) ((((a) ^ (b)) | ~ ((a) ^ (sum))) < 0) | |
75 | ||
7c3bb1de NB |
76 | typedef short op_t; |
77 | ||
b04cd507 | 78 | static void integer_overflow PARAMS ((cpp_reader *)); |
b0699dad | 79 | static HOST_WIDEST_INT left_shift PARAMS ((cpp_reader *, HOST_WIDEST_INT, |
e23c0ba3 ZW |
80 | unsigned int, |
81 | unsigned HOST_WIDEST_INT)); | |
b0699dad | 82 | static HOST_WIDEST_INT right_shift PARAMS ((cpp_reader *, HOST_WIDEST_INT, |
e23c0ba3 ZW |
83 | unsigned int, |
84 | unsigned HOST_WIDEST_INT)); | |
b0699dad ZW |
85 | static struct operation parse_number PARAMS ((cpp_reader *, U_CHAR *, |
86 | U_CHAR *)); | |
87 | static struct operation parse_charconst PARAMS ((cpp_reader *, U_CHAR *, | |
88 | U_CHAR *)); | |
ba412f14 | 89 | static struct operation parse_defined PARAMS ((cpp_reader *)); |
b0699dad ZW |
90 | static HOST_WIDEST_INT parse_escape PARAMS ((cpp_reader *, U_CHAR **, |
91 | HOST_WIDEST_INT)); | |
92 | static struct operation lex PARAMS ((cpp_reader *, int)); | |
b22ef131 | 93 | static const char * op_to_str PARAMS ((op_t, char *)); |
7f2935c7 PB |
94 | |
95 | #define ERROR 299 | |
96 | #define OROR 300 | |
97 | #define ANDAND 301 | |
98 | #define EQUAL 302 | |
99 | #define NOTEQUAL 303 | |
100 | #define LEQ 304 | |
101 | #define GEQ 305 | |
102 | #define LSH 306 | |
103 | #define RSH 307 | |
104 | #define NAME 308 | |
105 | #define INT 309 | |
106 | #define CHAR 310 | |
4063b943 | 107 | #define FINISHED 311 |
7f2935c7 | 108 | |
b0699dad ZW |
109 | struct operation |
110 | { | |
7c3bb1de | 111 | op_t op; |
4063b943 | 112 | U_CHAR prio; /* Priority of op. */ |
e23c0ba3 | 113 | U_CHAR flags; |
4063b943 NB |
114 | U_CHAR unsignedp; /* True if value should be treated as unsigned. */ |
115 | HOST_WIDEST_INT value; /* The value logically "right" of op. */ | |
7f2935c7 | 116 | }; |
7f2935c7 | 117 | |
f13eb63a ZW |
118 | /* Parse and convert an integer for #if. Accepts decimal, hex, or octal |
119 | with or without size suffixes. */ | |
7f2935c7 | 120 | |
f13eb63a ZW |
121 | static struct operation |
122 | parse_number (pfile, start, end) | |
7f2935c7 | 123 | cpp_reader *pfile; |
f13eb63a ZW |
124 | U_CHAR *start; |
125 | U_CHAR *end; | |
7f2935c7 PB |
126 | { |
127 | struct operation op; | |
f13eb63a ZW |
128 | U_CHAR *p = start; |
129 | int c; | |
e915b770 | 130 | unsigned HOST_WIDEST_INT n = 0, nd, MAX_over_base; |
f13eb63a ZW |
131 | int base = 10; |
132 | int overflow = 0; | |
133 | int digit, largest_digit = 0; | |
7f2935c7 PB |
134 | int spec_long = 0; |
135 | ||
136 | op.unsignedp = 0; | |
137 | ||
f13eb63a ZW |
138 | if (p[0] == '0') |
139 | { | |
140 | if (end - start >= 3 && (p[1] == 'x' || p[1] == 'X')) | |
141 | { | |
142 | p += 2; | |
143 | base = 16; | |
144 | } | |
145 | else | |
146 | { | |
147 | p += 1; | |
148 | base = 8; | |
149 | } | |
7f2935c7 PB |
150 | } |
151 | ||
0f41302f | 152 | /* Some buggy compilers (e.g. MPW C) seem to need both casts. */ |
e915b770 KG |
153 | MAX_over_base = (((unsigned HOST_WIDEST_INT) -1) |
154 | / ((unsigned HOST_WIDEST_INT) base)); | |
7f2935c7 | 155 | |
f13eb63a ZW |
156 | while (p < end) |
157 | { | |
158 | c = *p++; | |
159 | ||
160 | if (c >= '0' && c <= '9') | |
161 | digit = c - '0'; | |
b22ef131 NB |
162 | /* FIXME: assumes ASCII */ |
163 | else if (base == 16 && c >= 'a' && c <= 'f') | |
f13eb63a ZW |
164 | digit = c - 'a' + 10; |
165 | else if (base == 16 && c >= 'A' && c <= 'F') | |
166 | digit = c - 'A' + 10; | |
167 | else if (c == '.') | |
168 | { | |
169 | /* It's a float since it contains a point. */ | |
170 | cpp_error (pfile, | |
b22ef131 | 171 | "floating point numbers are not allowed in #if expressions"); |
f13eb63a ZW |
172 | goto error; |
173 | } | |
174 | else | |
175 | { | |
176 | /* `l' means long, and `u' means unsigned. */ | |
177 | for (;;) | |
178 | { | |
179 | if (c == 'l' || c == 'L') | |
180 | spec_long++; | |
181 | else if (c == 'u' || c == 'U') | |
182 | op.unsignedp++; | |
183 | else | |
184 | { | |
b22ef131 NB |
185 | /* Decrement p here so that the error for an invalid |
186 | number will be generated below in the case where | |
187 | this is the last character in the buffer. */ | |
f13eb63a ZW |
188 | p--; |
189 | break; | |
190 | } | |
191 | if (p == end) | |
192 | break; | |
193 | c = *p++; | |
194 | } | |
195 | /* Don't look for any more digits after the suffixes. */ | |
7f2935c7 | 196 | break; |
f13eb63a ZW |
197 | } |
198 | ||
199 | if (largest_digit < digit) | |
200 | largest_digit = digit; | |
201 | nd = n * base + digit; | |
202 | overflow |= MAX_over_base < n || nd < n; | |
203 | n = nd; | |
7f2935c7 | 204 | } |
7f2935c7 | 205 | |
f13eb63a | 206 | if (p != end) |
7f2935c7 | 207 | { |
f13eb63a ZW |
208 | cpp_error (pfile, "invalid number in #if expression"); |
209 | goto error; | |
7f2935c7 | 210 | } |
ae79697b | 211 | else if (spec_long > (CPP_OPTION (pfile, c89) ? 1 : 2)) |
f13eb63a | 212 | { |
b22ef131 | 213 | cpp_error (pfile, "too many 'l' suffixes in integer constant"); |
f13eb63a ZW |
214 | goto error; |
215 | } | |
216 | else if (op.unsignedp > 1) | |
217 | { | |
b22ef131 | 218 | cpp_error (pfile, "too many 'u' suffixes in integer constant"); |
f13eb63a ZW |
219 | goto error; |
220 | } | |
221 | ||
7f2935c7 | 222 | if (base <= largest_digit) |
b22ef131 NB |
223 | cpp_pedwarn (pfile, |
224 | "integer constant contains digits beyond the radix"); | |
7f2935c7 PB |
225 | |
226 | if (overflow) | |
7c4033ff | 227 | cpp_pedwarn (pfile, "integer constant out of range"); |
7f2935c7 PB |
228 | |
229 | /* If too big to be signed, consider it unsigned. */ | |
e915b770 | 230 | else if ((HOST_WIDEST_INT) n < 0 && ! op.unsignedp) |
7f2935c7 PB |
231 | { |
232 | if (base == 10) | |
f13eb63a ZW |
233 | cpp_warning (pfile, |
234 | "integer constant is so large that it is unsigned"); | |
7f2935c7 PB |
235 | op.unsignedp = 1; |
236 | } | |
237 | ||
238 | op.value = n; | |
239 | op.op = INT; | |
240 | return op; | |
f13eb63a ZW |
241 | |
242 | error: | |
243 | op.op = ERROR; | |
244 | return op; | |
7f2935c7 PB |
245 | } |
246 | ||
f13eb63a ZW |
247 | /* Parse and convert a character constant for #if. Understands backslash |
248 | escapes (\n, \031) and multibyte characters (if so configured). */ | |
249 | static struct operation | |
250 | parse_charconst (pfile, start, end) | |
251 | cpp_reader *pfile; | |
252 | U_CHAR *start; | |
253 | U_CHAR *end; | |
254 | { | |
255 | struct operation op; | |
e915b770 | 256 | HOST_WIDEST_INT result = 0; |
f13eb63a ZW |
257 | int num_chars = 0; |
258 | int num_bits; | |
259 | unsigned int width = MAX_CHAR_TYPE_SIZE, mask = MAX_CHAR_TYPE_MASK; | |
260 | int max_chars; | |
261 | U_CHAR *ptr = start; | |
262 | ||
099a9dd0 | 263 | int c = -1; |
f13eb63a ZW |
264 | |
265 | if (*ptr == 'L') | |
266 | { | |
267 | ++ptr; | |
268 | width = MAX_WCHAR_TYPE_SIZE, mask = MAX_WCHAR_TYPE_MASK; | |
269 | } | |
270 | max_chars = MAX_LONG_TYPE_SIZE / width; | |
271 | ||
272 | ++ptr; /* skip initial quote */ | |
273 | ||
274 | while (ptr < end) | |
275 | { | |
f13eb63a | 276 | c = *ptr++; |
f13eb63a ZW |
277 | if (c == '\'' || c == '\0') |
278 | break; | |
279 | else if (c == '\\') | |
280 | { | |
b0699dad | 281 | c = parse_escape (pfile, &ptr, mask); |
f13eb63a ZW |
282 | if (width < HOST_BITS_PER_INT |
283 | && (unsigned int) c >= (unsigned int)(1 << width)) | |
b22ef131 NB |
284 | cpp_pedwarn (pfile, |
285 | "escape sequence out of range for character"); | |
f13eb63a ZW |
286 | } |
287 | ||
288 | /* Merge character into result; ignore excess chars. */ | |
289 | if (++num_chars <= max_chars) | |
290 | { | |
291 | if (width < HOST_BITS_PER_INT) | |
292 | result = (result << width) | (c & ((1 << width) - 1)); | |
293 | else | |
294 | result = c; | |
295 | } | |
296 | } | |
297 | ||
298 | if (num_chars == 0) | |
299 | { | |
300 | cpp_error (pfile, "empty character constant"); | |
301 | goto error; | |
302 | } | |
303 | else if (c != '\'') | |
304 | { | |
305 | /* cpp_get_token has already emitted an error if !traditional. */ | |
306 | if (! CPP_TRADITIONAL (pfile)) | |
307 | cpp_error (pfile, "malformatted character constant"); | |
308 | goto error; | |
309 | } | |
310 | else if (num_chars > max_chars) | |
311 | { | |
312 | cpp_error (pfile, "character constant too long"); | |
313 | goto error; | |
314 | } | |
315 | else if (num_chars != 1 && ! CPP_TRADITIONAL (pfile)) | |
316 | cpp_warning (pfile, "multi-character character constant"); | |
317 | ||
318 | /* If char type is signed, sign-extend the constant. */ | |
319 | num_bits = num_chars * width; | |
320 | ||
cf4ed945 ZW |
321 | if (cpp_defined (pfile, (const U_CHAR *)"__CHAR_UNSIGNED__", |
322 | sizeof ("__CHAR_UNSIGNED__")-1) | |
f13eb63a | 323 | || ((result >> (num_bits - 1)) & 1) == 0) |
ca261cb4 KG |
324 | op.value = result & ((unsigned HOST_WIDEST_INT) ~0 |
325 | >> (HOST_BITS_PER_WIDEST_INT - num_bits)); | |
f13eb63a | 326 | else |
ca261cb4 KG |
327 | op.value = result | ~((unsigned HOST_WIDEST_INT) ~0 |
328 | >> (HOST_BITS_PER_WIDEST_INT - num_bits)); | |
f13eb63a ZW |
329 | |
330 | /* This is always a signed type. */ | |
331 | op.unsignedp = 0; | |
332 | op.op = CHAR; | |
333 | return op; | |
334 | ||
335 | error: | |
336 | op.op = ERROR; | |
337 | return op; | |
338 | } | |
339 | ||
ba412f14 ZW |
340 | static struct operation |
341 | parse_defined (pfile) | |
342 | cpp_reader *pfile; | |
343 | { | |
344 | int paren = 0, len; | |
345 | U_CHAR *tok; | |
346 | enum cpp_token token; | |
347 | struct operation op; | |
348 | long old_written = CPP_WRITTEN (pfile); | |
349 | ||
350 | op.unsignedp = 0; | |
351 | op.op = INT; | |
352 | ||
353 | pfile->no_macro_expand++; | |
45b966db | 354 | token = _cpp_get_directive_token (pfile); |
ba412f14 ZW |
355 | if (token == CPP_LPAREN) |
356 | { | |
357 | paren++; | |
358 | CPP_SET_WRITTEN (pfile, old_written); | |
45b966db | 359 | token = _cpp_get_directive_token (pfile); |
ba412f14 ZW |
360 | } |
361 | ||
362 | if (token != CPP_NAME) | |
363 | goto oops; | |
364 | ||
365 | tok = pfile->token_buffer + old_written; | |
366 | len = CPP_PWRITTEN (pfile) - tok; | |
367 | op.value = cpp_defined (pfile, tok, len); | |
368 | ||
369 | if (paren) | |
370 | { | |
45b966db | 371 | if (_cpp_get_directive_token (pfile) != CPP_RPAREN) |
ba412f14 ZW |
372 | goto oops; |
373 | } | |
374 | CPP_SET_WRITTEN (pfile, old_written); | |
375 | pfile->no_macro_expand--; | |
376 | return op; | |
377 | ||
378 | oops: | |
379 | CPP_SET_WRITTEN (pfile, old_written); | |
380 | pfile->no_macro_expand--; | |
b22ef131 | 381 | cpp_error (pfile, "'defined' without an identifier"); |
ba412f14 ZW |
382 | |
383 | op.op = ERROR; | |
384 | return op; | |
385 | } | |
386 | ||
7c3bb1de NB |
387 | struct token |
388 | { | |
bcc5cac9 | 389 | const char *operator; |
7c3bb1de | 390 | op_t token; |
7f2935c7 PB |
391 | }; |
392 | ||
7c3bb1de NB |
393 | static const struct token tokentab2[] = |
394 | { | |
7f2935c7 PB |
395 | {"&&", ANDAND}, |
396 | {"||", OROR}, | |
397 | {"<<", LSH}, | |
398 | {">>", RSH}, | |
399 | {"==", EQUAL}, | |
400 | {"!=", NOTEQUAL}, | |
401 | {"<=", LEQ}, | |
402 | {">=", GEQ}, | |
403 | {"++", ERROR}, | |
404 | {"--", ERROR}, | |
405 | {NULL, ERROR} | |
406 | }; | |
407 | ||
0f41302f | 408 | /* Read one token. */ |
7f2935c7 | 409 | |
6de1e2a9 | 410 | static struct operation |
b0699dad | 411 | lex (pfile, skip_evaluation) |
52529158 | 412 | cpp_reader *pfile; |
c9666c01 | 413 | int skip_evaluation; |
7f2935c7 | 414 | { |
455d2586 | 415 | const struct token *toktab; |
7f2935c7 PB |
416 | enum cpp_token token; |
417 | struct operation op; | |
418 | U_CHAR *tok_start, *tok_end; | |
cf4ed945 | 419 | long old_written; |
7f2935c7 | 420 | |
1519594d | 421 | old_written = CPP_WRITTEN (pfile); |
45b966db | 422 | token = _cpp_get_directive_token (pfile); |
7f2935c7 | 423 | |
7f2935c7 PB |
424 | tok_start = pfile->token_buffer + old_written; |
425 | tok_end = CPP_PWRITTEN (pfile); | |
cf4ed945 | 426 | CPP_SET_WRITTEN (pfile, old_written); |
7f2935c7 | 427 | switch (token) |
ba412f14 | 428 | { |
0f41302f | 429 | case CPP_EOF: /* Should not happen ... */ |
a4a315ef | 430 | case CPP_VSPACE: |
7f2935c7 PB |
431 | op.op = 0; |
432 | return op; | |
7f2935c7 | 433 | case CPP_NUMBER: |
f13eb63a | 434 | return parse_number (pfile, tok_start, tok_end); |
7f2935c7 | 435 | case CPP_STRING: |
525bc95d | 436 | case CPP_WSTRING: |
b22ef131 NB |
437 | cpp_error (pfile, |
438 | "string constants are not allowed in #if expressions"); | |
7f2935c7 PB |
439 | op.op = ERROR; |
440 | return op; | |
525bc95d | 441 | |
7f2935c7 | 442 | case CPP_CHAR: |
525bc95d | 443 | case CPP_WCHAR: |
f13eb63a | 444 | return parse_charconst (pfile, tok_start, tok_end); |
7f2935c7 PB |
445 | |
446 | case CPP_NAME: | |
ba412f14 ZW |
447 | if (!strcmp (tok_start, "defined")) |
448 | return parse_defined (pfile); | |
449 | ||
f13eb63a ZW |
450 | op.op = INT; |
451 | op.unsignedp = 0; | |
452 | op.value = 0; | |
5dfa4da1 | 453 | |
ae79697b | 454 | if (CPP_OPTION (pfile, warn_undef) && !skip_evaluation) |
b22ef131 | 455 | cpp_warning (pfile, "'%.*s' is not defined", |
ba412f14 | 456 | (int) (tok_end - tok_start), tok_start); |
5dfa4da1 ZW |
457 | return op; |
458 | ||
ba412f14 ZW |
459 | case CPP_ASSERTION: |
460 | op.op = INT; | |
461 | op.unsignedp = 0; | |
462 | op.value = cpp_defined (pfile, tok_start, tok_end - tok_start); | |
f13eb63a | 463 | return op; |
7f2935c7 PB |
464 | |
465 | case CPP_OTHER: | |
466 | /* See if it is a special token of length 2. */ | |
467 | if (tok_start + 2 == tok_end) | |
468 | { | |
469 | for (toktab = tokentab2; toktab->operator != NULL; toktab++) | |
470 | if (tok_start[0] == toktab->operator[0] | |
471 | && tok_start[1] == toktab->operator[1]) | |
472 | break; | |
473 | if (toktab->token == ERROR) | |
b22ef131 | 474 | cpp_error (pfile, "'%s' not allowed in operand of #if", |
ab87f8c8 | 475 | tok_start); |
7f2935c7 PB |
476 | op.op = toktab->token; |
477 | return op; | |
478 | } | |
479 | /* fall through */ | |
480 | default: | |
481 | op.op = *tok_start; | |
482 | return op; | |
483 | } | |
484 | } | |
485 | ||
b22ef131 NB |
486 | /* Convert an operator ID to a string. BUFF is a buffer at least 5 |
487 | characters long which might be used to store the string. */ | |
488 | /* XXX FIXME: Remove BUFF when new lexer is implemented. */ | |
7c3bb1de | 489 | static const char * |
b22ef131 | 490 | op_to_str (op, buff) |
7c3bb1de | 491 | op_t op; |
b22ef131 | 492 | char *buff; |
7c3bb1de | 493 | { |
7c3bb1de NB |
494 | const struct token *toktab; |
495 | ||
496 | /* See if it is a special token of length 2. */ | |
497 | for (toktab = tokentab2; toktab->operator != NULL; toktab++) | |
498 | if (op == toktab->token) | |
499 | return toktab->operator; | |
500 | ||
501 | if (ISGRAPH (op)) | |
b22ef131 | 502 | sprintf (buff, "%c", (int) op); |
7c3bb1de | 503 | else |
b22ef131 NB |
504 | sprintf (buff, "\\%03o", (int) op); |
505 | return buff; | |
7c3bb1de | 506 | } |
7f2935c7 PB |
507 | |
508 | /* Parse a C escape sequence. STRING_PTR points to a variable | |
509 | containing a pointer to the string to parse. That pointer | |
510 | is updated past the characters we use. The value of the | |
511 | escape sequence is returned. | |
512 | ||
513 | A negative value means the sequence \ newline was seen, | |
514 | which is supposed to be equivalent to nothing at all. | |
515 | ||
516 | If \ is followed by a null character, we return a negative | |
517 | value and leave the string pointer pointing at the null character. | |
518 | ||
519 | If \ is followed by 000, we return 0 and leave the string pointer | |
520 | after the zeros. A value of 0 does not mean end of string. */ | |
521 | ||
a2c8e144 | 522 | static HOST_WIDEST_INT |
b0699dad | 523 | parse_escape (pfile, string_ptr, result_mask) |
7f2935c7 | 524 | cpp_reader *pfile; |
a2c8e144 | 525 | U_CHAR **string_ptr; |
e915b770 | 526 | HOST_WIDEST_INT result_mask; |
7f2935c7 PB |
527 | { |
528 | register int c = *(*string_ptr)++; | |
529 | switch (c) | |
530 | { | |
531 | case 'a': | |
532 | return TARGET_BELL; | |
533 | case 'b': | |
534 | return TARGET_BS; | |
535 | case 'e': | |
536 | case 'E': | |
ae79697b | 537 | if (CPP_PEDANTIC (pfile)) |
b22ef131 | 538 | cpp_pedwarn (pfile, "non-ANSI-standard escape sequence, '\\%c'", c); |
f3ad1f9c | 539 | return TARGET_ESC; |
7f2935c7 PB |
540 | case 'f': |
541 | return TARGET_FF; | |
542 | case 'n': | |
543 | return TARGET_NEWLINE; | |
544 | case 'r': | |
545 | return TARGET_CR; | |
546 | case 't': | |
547 | return TARGET_TAB; | |
548 | case 'v': | |
549 | return TARGET_VT; | |
550 | case '\n': | |
551 | return -2; | |
552 | case 0: | |
553 | (*string_ptr)--; | |
554 | return 0; | |
555 | ||
556 | case '0': | |
557 | case '1': | |
558 | case '2': | |
559 | case '3': | |
560 | case '4': | |
561 | case '5': | |
562 | case '6': | |
563 | case '7': | |
564 | { | |
e915b770 | 565 | register HOST_WIDEST_INT i = c - '0'; |
7f2935c7 PB |
566 | register int count = 0; |
567 | while (++count < 3) | |
568 | { | |
569 | c = *(*string_ptr)++; | |
570 | if (c >= '0' && c <= '7') | |
571 | i = (i << 3) + c - '0'; | |
572 | else | |
573 | { | |
574 | (*string_ptr)--; | |
575 | break; | |
576 | } | |
577 | } | |
f1a86df6 | 578 | if (i != (i & result_mask)) |
7f2935c7 | 579 | { |
f1a86df6 ZW |
580 | i &= result_mask; |
581 | cpp_pedwarn (pfile, "octal escape sequence out of range"); | |
7f2935c7 PB |
582 | } |
583 | return i; | |
584 | } | |
585 | case 'x': | |
586 | { | |
e915b770 | 587 | register unsigned HOST_WIDEST_INT i = 0, overflow = 0; |
f1a86df6 | 588 | register int digits_found = 0, digit; |
7f2935c7 PB |
589 | for (;;) |
590 | { | |
591 | c = *(*string_ptr)++; | |
592 | if (c >= '0' && c <= '9') | |
593 | digit = c - '0'; | |
594 | else if (c >= 'a' && c <= 'f') | |
595 | digit = c - 'a' + 10; | |
596 | else if (c >= 'A' && c <= 'F') | |
597 | digit = c - 'A' + 10; | |
598 | else | |
599 | { | |
600 | (*string_ptr)--; | |
601 | break; | |
602 | } | |
603 | overflow |= i ^ (i << 4 >> 4); | |
604 | i = (i << 4) + digit; | |
605 | digits_found = 1; | |
606 | } | |
607 | if (!digits_found) | |
608 | cpp_error (pfile, "\\x used with no following hex digits"); | |
f1a86df6 | 609 | if (overflow | (i != (i & result_mask))) |
7f2935c7 | 610 | { |
f1a86df6 ZW |
611 | i &= result_mask; |
612 | cpp_pedwarn (pfile, "hex escape sequence out of range"); | |
7f2935c7 PB |
613 | } |
614 | return i; | |
615 | } | |
616 | default: | |
617 | return c; | |
618 | } | |
619 | } | |
620 | ||
621 | static void | |
622 | integer_overflow (pfile) | |
623 | cpp_reader *pfile; | |
624 | { | |
625 | if (CPP_PEDANTIC (pfile)) | |
626 | cpp_pedwarn (pfile, "integer overflow in preprocessor expression"); | |
627 | } | |
628 | ||
ca261cb4 | 629 | static HOST_WIDEST_INT |
7f2935c7 PB |
630 | left_shift (pfile, a, unsignedp, b) |
631 | cpp_reader *pfile; | |
ca261cb4 | 632 | HOST_WIDEST_INT a; |
e23c0ba3 | 633 | unsigned int unsignedp; |
ca261cb4 | 634 | unsigned HOST_WIDEST_INT b; |
7f2935c7 | 635 | { |
ca261cb4 | 636 | if (b >= HOST_BITS_PER_WIDEST_INT) |
7f2935c7 PB |
637 | { |
638 | if (! unsignedp && a != 0) | |
639 | integer_overflow (pfile); | |
640 | return 0; | |
641 | } | |
642 | else if (unsignedp) | |
ca261cb4 | 643 | return (unsigned HOST_WIDEST_INT) a << b; |
7f2935c7 PB |
644 | else |
645 | { | |
ca261cb4 | 646 | HOST_WIDEST_INT l = a << b; |
7f2935c7 PB |
647 | if (l >> b != a) |
648 | integer_overflow (pfile); | |
649 | return l; | |
650 | } | |
651 | } | |
652 | ||
ca261cb4 | 653 | static HOST_WIDEST_INT |
7f2935c7 | 654 | right_shift (pfile, a, unsignedp, b) |
d6f4ec51 | 655 | cpp_reader *pfile ATTRIBUTE_UNUSED; |
ca261cb4 | 656 | HOST_WIDEST_INT a; |
e23c0ba3 | 657 | unsigned int unsignedp; |
ca261cb4 | 658 | unsigned HOST_WIDEST_INT b; |
7f2935c7 | 659 | { |
ca261cb4 KG |
660 | if (b >= HOST_BITS_PER_WIDEST_INT) |
661 | return unsignedp ? 0 : a >> (HOST_BITS_PER_WIDEST_INT - 1); | |
7f2935c7 | 662 | else if (unsignedp) |
ca261cb4 | 663 | return (unsigned HOST_WIDEST_INT) a >> b; |
7f2935c7 PB |
664 | else |
665 | return a >> b; | |
666 | } | |
667 | \f | |
4063b943 | 668 | /* Operator precedence and flags table. |
dbac4aff NB |
669 | |
670 | After an operator is returned from the lexer, if it has priority less | |
671 | than or equal to the operator on the top of the stack, we reduce the | |
4063b943 NB |
672 | stack by one operator and repeat the test. Since equal priorities |
673 | reduce, this is naturally left-associative. | |
dbac4aff NB |
674 | |
675 | We handle right-associative operators by clearing the lower bit of all | |
676 | left-associative operators, and setting it for right-associative ones. | |
4063b943 NB |
677 | After the reduction phase of a new operator, just before it is pushed |
678 | onto the stack, its RIGHT_ASSOC bit is cleared. The effect is that | |
679 | during the reduction phase, the current right-associative operator has | |
680 | a priority one greater than any other operator of otherwise equal | |
681 | precedence that has been pushed on the top of the stack. This avoids | |
682 | a reduction pass, and effectively makes the logic right-associative. | |
dbac4aff NB |
683 | |
684 | The remaining cases are '(' and ')'. We handle '(' by skipping the | |
685 | reduction phase completely. ')' is given lower priority than | |
686 | everything else, including '(', effectively forcing a reduction of the | |
4063b943 NB |
687 | parenthesised expression. If there is no matching '(', the stack will |
688 | be reduced all the way to the beginning, exiting the parser in the | |
689 | same way as the ultra-low priority end-of-expression dummy operator. | |
690 | The exit code checks to see if the operator that caused it is ')', and | |
691 | if so outputs an appropriate error message. | |
692 | ||
693 | The parser assumes all shifted operators require a right operand | |
694 | unless the flag NO_R_OPERAND is set, and similarly for NO_L_OPERAND. | |
695 | These semantics are automatically checked, any extra semantics need to | |
696 | be handled with operator-specific code. */ | |
697 | ||
698 | #define FLAG_BITS 8 | |
699 | #define FLAG_MASK ((1 << FLAG_BITS) - 1) | |
700 | #define PRIO_SHIFT (FLAG_BITS + 1) | |
701 | #define EXTRACT_PRIO(cnst) (cnst >> FLAG_BITS) | |
702 | #define EXTRACT_FLAGS(cnst) (cnst & FLAG_MASK) | |
703 | ||
704 | /* Flags. */ | |
705 | #define HAVE_VALUE (1 << 0) | |
706 | #define NO_L_OPERAND (1 << 1) | |
707 | #define NO_R_OPERAND (1 << 2) | |
708 | #define SHORT_CIRCUIT (1 << 3) | |
709 | ||
710 | /* Priority and flag combinations. */ | |
711 | #define RIGHT_ASSOC (1 << FLAG_BITS) | |
712 | #define FORCE_REDUCE_PRIO (0 << PRIO_SHIFT) | |
713 | #define CLOSE_PAREN_PRIO (1 << PRIO_SHIFT) | |
714 | #define OPEN_PAREN_PRIO ((2 << PRIO_SHIFT) | NO_L_OPERAND) | |
715 | #define COMMA_PRIO (3 << PRIO_SHIFT) | |
716 | #define COND_PRIO ((4 << PRIO_SHIFT) | RIGHT_ASSOC | SHORT_CIRCUIT) | |
717 | #define COLON_PRIO ((5 << PRIO_SHIFT) | SHORT_CIRCUIT) | |
718 | #define OROR_PRIO ((6 << PRIO_SHIFT) | SHORT_CIRCUIT) | |
719 | #define ANDAND_PRIO ((7 << PRIO_SHIFT) | SHORT_CIRCUIT) | |
720 | #define OR_PRIO (8 << PRIO_SHIFT) | |
721 | #define XOR_PRIO (9 << PRIO_SHIFT) | |
722 | #define AND_PRIO (10 << PRIO_SHIFT) | |
723 | #define EQUAL_PRIO (11 << PRIO_SHIFT) | |
724 | #define LESS_PRIO (12 << PRIO_SHIFT) | |
725 | #define SHIFT_PRIO (13 << PRIO_SHIFT) | |
726 | #define PLUS_PRIO (14 << PRIO_SHIFT) | |
727 | #define MUL_PRIO (15 << PRIO_SHIFT) | |
728 | #define UNARY_PRIO ((16 << PRIO_SHIFT) | RIGHT_ASSOC | NO_L_OPERAND) | |
eba30526 | 729 | |
7f2935c7 | 730 | #define COMPARE(OP) \ |
4063b943 | 731 | top->unsignedp = 0; \ |
b22ef131 | 732 | top->value = (unsigned1 | unsigned2) \ |
4063b943 NB |
733 | ? (unsigned HOST_WIDEST_INT) v1 OP (unsigned HOST_WIDEST_INT) v2 \ |
734 | : (v1 OP v2) | |
735 | #define EQUALITY(OP) \ | |
736 | top->value = v1 OP v2; \ | |
737 | top->unsignedp = 0; | |
dbac4aff | 738 | #define LOGICAL(OP) \ |
4063b943 | 739 | top->value = v1 OP v2; \ |
b22ef131 NB |
740 | top->unsignedp = unsigned1 | unsigned2; |
741 | ||
742 | /* With -O2, gcc appears to produce nice code, moving the error | |
743 | message load and subsequent jump completely out of the main path. */ | |
744 | #define CPP_ICE(msgid) \ | |
745 | do { cpp_ice (pfile, msgid); goto syntax_error; } while(0) | |
746 | #define SYNTAX_ERROR(msgid) \ | |
747 | do { cpp_error (pfile, msgid); goto syntax_error; } while(0) | |
748 | #define SYNTAX_ERROR2(msgid, arg) \ | |
749 | do { cpp_error (pfile, msgid, arg); goto syntax_error; } while(0) | |
7f2935c7 PB |
750 | |
751 | /* Parse and evaluate a C expression, reading from PFILE. | |
88ae23e7 | 752 | Returns the truth value of the expression. */ |
7f2935c7 | 753 | |
88ae23e7 | 754 | int |
b0699dad | 755 | _cpp_parse_expr (pfile) |
7f2935c7 PB |
756 | cpp_reader *pfile; |
757 | { | |
4063b943 NB |
758 | /* The implementation is an operator precedence parser, i.e. a |
759 | bottom-up parser, using a stack for not-yet-reduced tokens. | |
7f2935c7 PB |
760 | |
761 | The stack base is 'stack', and the current stack pointer is 'top'. | |
762 | There is a stack element for each operator (only), | |
763 | and the most recently pushed operator is 'top->op'. | |
764 | An operand (value) is stored in the 'value' field of the stack | |
765 | element of the operator that precedes it. | |
766 | In that case the 'flags' field has the HAVE_VALUE flag set. */ | |
767 | ||
768 | #define INIT_STACK_SIZE 20 | |
769 | struct operation init_stack[INIT_STACK_SIZE]; | |
770 | struct operation *stack = init_stack; | |
771 | struct operation *limit = stack + INIT_STACK_SIZE; | |
4063b943 | 772 | register struct operation *top = stack + 1; |
45b966db | 773 | long old_written = CPP_WRITTEN (pfile); |
4063b943 | 774 | int skip_evaluation = 0; |
45b966db | 775 | int result; |
b22ef131 | 776 | char buff[5]; |
7f2935c7 | 777 | |
45b966db | 778 | pfile->parsing_if_directive++; |
4063b943 NB |
779 | /* We've finished when we try to reduce this. */ |
780 | top->op = FINISHED; | |
781 | /* Nifty way to catch missing '('. */ | |
782 | top->prio = EXTRACT_PRIO(CLOSE_PAREN_PRIO); | |
783 | /* Avoid missing right operand checks. */ | |
784 | top->flags = NO_R_OPERAND; | |
785 | ||
7f2935c7 PB |
786 | for (;;) |
787 | { | |
dbac4aff | 788 | unsigned int prio; |
4063b943 | 789 | unsigned int flags; |
7f2935c7 | 790 | struct operation op; |
7f2935c7 PB |
791 | |
792 | /* Read a token */ | |
9ee70313 | 793 | op = lex (pfile, skip_evaluation); |
7f2935c7 | 794 | |
4063b943 NB |
795 | /* If the token is an operand, push its value and get next |
796 | token. If it is an operator, get its priority and flags, and | |
797 | try to reduce the expression on the stack. */ | |
7f2935c7 PB |
798 | switch (op.op) |
799 | { | |
800 | case NAME: | |
b22ef131 | 801 | CPP_ICE ("lex returns a NAME"); |
9ee70313 NB |
802 | case ERROR: |
803 | goto syntax_error; | |
bfab56e7 ZW |
804 | case '#': |
805 | /* We get '#' when get_directive_token hits a syntactically | |
806 | invalid assertion predicate. _cpp_parse_assertion has | |
807 | already issued an error. */ | |
808 | goto syntax_error; | |
9ee70313 | 809 | default: |
b22ef131 | 810 | SYNTAX_ERROR ("invalid character in #if"); |
9ee70313 | 811 | |
b22ef131 | 812 | push_immediate: |
4063b943 NB |
813 | case INT: |
814 | case CHAR: | |
9ee70313 | 815 | /* Push a value onto the stack. */ |
cf4ed945 | 816 | if (top->flags & HAVE_VALUE) |
b22ef131 | 817 | SYNTAX_ERROR ("missing binary operator"); |
9ee70313 NB |
818 | top->value = op.value; |
819 | top->unsignedp = op.unsignedp; | |
820 | top->flags |= HAVE_VALUE; | |
821 | continue; | |
822 | ||
4063b943 NB |
823 | case '+': |
824 | case '-': prio = PLUS_PRIO; if (top->flags & HAVE_VALUE) break; | |
825 | /* else unary; fall through */ | |
826 | case '!': | |
827 | case '~': prio = UNARY_PRIO; break; | |
dbac4aff NB |
828 | |
829 | case '*': | |
830 | case '/': | |
831 | case '%': prio = MUL_PRIO; break; | |
832 | case '<': | |
833 | case '>': | |
834 | case LEQ: | |
835 | case GEQ: prio = LESS_PRIO; break; | |
836 | case NOTEQUAL: | |
837 | case EQUAL: prio = EQUAL_PRIO; break; | |
838 | case LSH: | |
839 | case RSH: prio = SHIFT_PRIO; break; | |
840 | case '&': prio = AND_PRIO; break; | |
841 | case '^': prio = XOR_PRIO; break; | |
842 | case '|': prio = OR_PRIO; break; | |
843 | case ANDAND: prio = ANDAND_PRIO; break; | |
844 | case OROR: prio = OROR_PRIO; break; | |
845 | case ',': prio = COMMA_PRIO; break; | |
4063b943 NB |
846 | case '(': prio = OPEN_PAREN_PRIO; break; |
847 | case ')': prio = CLOSE_PAREN_PRIO; break; | |
848 | case ':': prio = COLON_PRIO; break; | |
849 | case '?': prio = COND_PRIO; break; | |
850 | case 0: prio = FORCE_REDUCE_PRIO; break; | |
7f2935c7 | 851 | } |
7f2935c7 | 852 | |
4063b943 NB |
853 | /* Separate the operator's code into priority and flags. */ |
854 | flags = EXTRACT_FLAGS(prio); | |
855 | prio = EXTRACT_PRIO(prio); | |
856 | if (op.op == '(') | |
857 | goto skip_reduction; | |
cf4ed945 | 858 | |
dbac4aff NB |
859 | /* Check for reductions. Then push the operator. */ |
860 | while (prio <= top->prio) | |
7f2935c7 | 861 | { |
4063b943 NB |
862 | HOST_WIDEST_INT v1, v2; |
863 | unsigned int unsigned1, unsigned2; | |
864 | ||
865 | /* Most operators that can appear on the stack require a | |
866 | right operand. Check this before trying to reduce. */ | |
867 | if ((top->flags & (HAVE_VALUE | NO_R_OPERAND)) == 0) | |
7f2935c7 | 868 | { |
4063b943 | 869 | if (top->op == '(') |
b22ef131 | 870 | SYNTAX_ERROR ("void expression between '(' and ')'"); |
4063b943 | 871 | else |
b22ef131 NB |
872 | SYNTAX_ERROR2 ("operator '%s' has no right operand", |
873 | op_to_str (top->op, buff)); | |
7f2935c7 | 874 | } |
4063b943 NB |
875 | |
876 | unsigned2 = top->unsignedp, v2 = top->value; | |
877 | top--; | |
878 | unsigned1 = top->unsignedp, v1 = top->value; | |
879 | ||
880 | /* Now set top->value = (top[1].op)(v1, v2); */ | |
7f2935c7 PB |
881 | switch (top[1].op) |
882 | { | |
883 | case '+': | |
884 | if (!(top->flags & HAVE_VALUE)) | |
885 | { /* Unary '+' */ | |
886 | top->value = v2; | |
887 | top->unsignedp = unsigned2; | |
888 | top->flags |= HAVE_VALUE; | |
889 | } | |
890 | else | |
891 | { | |
892 | top->value = v1 + v2; | |
b22ef131 | 893 | top->unsignedp = unsigned1 | unsigned2; |
a4a315ef | 894 | if (! top->unsignedp && ! skip_evaluation |
7f2935c7 PB |
895 | && ! possible_sum_sign (v1, v2, top->value)) |
896 | integer_overflow (pfile); | |
897 | } | |
898 | break; | |
899 | case '-': | |
52529158 | 900 | if (!(top->flags & HAVE_VALUE)) |
7f2935c7 PB |
901 | { /* Unary '-' */ |
902 | top->value = - v2; | |
4063b943 NB |
903 | if (!skip_evaluation && (top->value & v2) < 0 |
904 | && !unsigned2) | |
7f2935c7 PB |
905 | integer_overflow (pfile); |
906 | top->unsignedp = unsigned2; | |
907 | top->flags |= HAVE_VALUE; | |
908 | } | |
909 | else | |
910 | { /* Binary '-' */ | |
911 | top->value = v1 - v2; | |
b22ef131 | 912 | top->unsignedp = unsigned1 | unsigned2; |
52529158 | 913 | if (! top->unsignedp && ! skip_evaluation |
7f2935c7 PB |
914 | && ! possible_sum_sign (top->value, v2, v1)) |
915 | integer_overflow (pfile); | |
916 | } | |
917 | break; | |
918 | case '*': | |
b22ef131 | 919 | top->unsignedp = unsigned1 | unsigned2; |
7f2935c7 | 920 | if (top->unsignedp) |
ca261cb4 | 921 | top->value = (unsigned HOST_WIDEST_INT) v1 * v2; |
a4a315ef | 922 | else if (!skip_evaluation) |
7f2935c7 PB |
923 | { |
924 | top->value = v1 * v2; | |
4063b943 NB |
925 | if (v1 && (top->value / v1 != v2 |
926 | || (top->value & v1 & v2) < 0)) | |
7f2935c7 PB |
927 | integer_overflow (pfile); |
928 | } | |
929 | break; | |
930 | case '/': | |
4063b943 | 931 | case '%': |
a4a315ef PB |
932 | if (skip_evaluation) |
933 | break; | |
7f2935c7 | 934 | if (v2 == 0) |
b22ef131 NB |
935 | SYNTAX_ERROR ("division by zero in #if"); |
936 | top->unsignedp = unsigned1 | unsigned2; | |
4063b943 | 937 | if (top[1].op == '/') |
7f2935c7 | 938 | { |
4063b943 NB |
939 | if (top->unsignedp) |
940 | top->value = (unsigned HOST_WIDEST_INT) v1 / v2; | |
941 | else | |
942 | { | |
943 | top->value = v1 / v2; | |
944 | if ((top->value & v1 & v2) < 0) | |
945 | integer_overflow (pfile); | |
946 | } | |
7f2935c7 | 947 | } |
4063b943 | 948 | else |
7f2935c7 | 949 | { |
4063b943 NB |
950 | if (top->unsignedp) |
951 | top->value = (unsigned HOST_WIDEST_INT) v1 % v2; | |
952 | else | |
953 | top->value = v1 % v2; | |
7f2935c7 | 954 | } |
7f2935c7 PB |
955 | break; |
956 | case '!': | |
7f2935c7 PB |
957 | top->value = ! v2; |
958 | top->unsignedp = 0; | |
959 | top->flags |= HAVE_VALUE; | |
960 | break; | |
961 | case '~': | |
7f2935c7 PB |
962 | top->value = ~ v2; |
963 | top->unsignedp = unsigned2; | |
964 | top->flags |= HAVE_VALUE; | |
965 | break; | |
966 | case '<': COMPARE(<); break; | |
967 | case '>': COMPARE(>); break; | |
4063b943 NB |
968 | case LEQ: COMPARE(<=); break; |
969 | case GEQ: COMPARE(>=); break; | |
970 | case EQUAL: EQUALITY(==); break; | |
971 | case NOTEQUAL: EQUALITY(!=); break; | |
7f2935c7 | 972 | case LSH: |
a4a315ef PB |
973 | if (skip_evaluation) |
974 | break; | |
7f2935c7 PB |
975 | top->unsignedp = unsigned1; |
976 | if (v2 < 0 && ! unsigned2) | |
977 | top->value = right_shift (pfile, v1, unsigned1, -v2); | |
978 | else | |
979 | top->value = left_shift (pfile, v1, unsigned1, v2); | |
980 | break; | |
981 | case RSH: | |
a4a315ef PB |
982 | if (skip_evaluation) |
983 | break; | |
7f2935c7 PB |
984 | top->unsignedp = unsigned1; |
985 | if (v2 < 0 && ! unsigned2) | |
986 | top->value = left_shift (pfile, v1, unsigned1, -v2); | |
987 | else | |
988 | top->value = right_shift (pfile, v1, unsigned1, v2); | |
989 | break; | |
7f2935c7 PB |
990 | case '&': LOGICAL(&); break; |
991 | case '^': LOGICAL(^); break; | |
992 | case '|': LOGICAL(|); break; | |
993 | case ANDAND: | |
a4a315ef PB |
994 | top->value = v1 && v2; top->unsignedp = 0; |
995 | if (!v1) skip_evaluation--; | |
996 | break; | |
7f2935c7 | 997 | case OROR: |
a4a315ef PB |
998 | top->value = v1 || v2; top->unsignedp = 0; |
999 | if (v1) skip_evaluation--; | |
1000 | break; | |
7f2935c7 PB |
1001 | case ',': |
1002 | if (CPP_PEDANTIC (pfile)) | |
b22ef131 | 1003 | cpp_pedwarn (pfile, "comma operator in operand of #if"); |
7f2935c7 PB |
1004 | top->value = v2; |
1005 | top->unsignedp = unsigned2; | |
1006 | break; | |
9ee70313 | 1007 | case '?': |
b22ef131 | 1008 | SYNTAX_ERROR ("syntax error '?' without following ':'"); |
7f2935c7 PB |
1009 | case ':': |
1010 | if (top[0].op != '?') | |
b22ef131 | 1011 | SYNTAX_ERROR ("syntax error ':' without preceding '?'"); |
4063b943 NB |
1012 | top--; |
1013 | if (top->value) skip_evaluation--; | |
1014 | top->value = top->value ? v1 : v2; | |
b22ef131 | 1015 | top->unsignedp = unsigned1 | unsigned2; |
7f2935c7 | 1016 | break; |
9ee70313 NB |
1017 | case '(': |
1018 | if (op.op != ')') | |
b22ef131 | 1019 | SYNTAX_ERROR ("missing ')' in expression"); |
9ee70313 NB |
1020 | op.value = v2; |
1021 | op.unsignedp = unsigned2; | |
1022 | goto push_immediate; | |
7f2935c7 | 1023 | default: |
b22ef131 NB |
1024 | SYNTAX_ERROR2 ("unimplemented operator '%s'", |
1025 | op_to_str (top[1].op, buff)); | |
4063b943 NB |
1026 | case FINISHED: |
1027 | /* Reducing this dummy operator indicates we've finished. */ | |
1028 | if (op.op == ')') | |
b22ef131 | 1029 | SYNTAX_ERROR ("missing '(' in expression"); |
4063b943 | 1030 | goto done; |
7f2935c7 PB |
1031 | } |
1032 | } | |
9ee70313 | 1033 | |
4063b943 NB |
1034 | /* Handle short-circuit evaluations. */ |
1035 | if (flags & SHORT_CIRCUIT) | |
1036 | switch (op.op) | |
1037 | { | |
1038 | case OROR: if (top->value) skip_evaluation++; break; | |
1039 | case ANDAND: | |
1040 | case '?': if (!top->value) skip_evaluation++; break; | |
1041 | case ':': | |
1042 | if (top[-1].value) /* Was '?' condition true? */ | |
1043 | skip_evaluation++; | |
1044 | else | |
1045 | skip_evaluation--; | |
1046 | } | |
9ee70313 NB |
1047 | |
1048 | skip_reduction: | |
4063b943 | 1049 | /* Check we have a left operand iff we need one. */ |
b22ef131 | 1050 | if (flags & NO_L_OPERAND) |
4063b943 | 1051 | { |
b22ef131 NB |
1052 | if (top->flags & HAVE_VALUE) |
1053 | SYNTAX_ERROR2 ("missing binary operator before '%s'", | |
1054 | op_to_str (op.op, buff)); | |
1055 | } | |
1056 | else | |
1057 | { | |
1058 | if (!(top->flags & HAVE_VALUE)) | |
1059 | SYNTAX_ERROR2 ("operator '%s' has no left operand", | |
1060 | op_to_str (op.op, buff)); | |
4063b943 NB |
1061 | } |
1062 | ||
0f41302f | 1063 | /* Check for and handle stack overflow. */ |
9ee70313 | 1064 | top++; |
7f2935c7 PB |
1065 | if (top == limit) |
1066 | { | |
1067 | struct operation *new_stack; | |
0f41302f | 1068 | int old_size = (char *) limit - (char *) stack; |
7f2935c7 PB |
1069 | int new_size = 2 * old_size; |
1070 | if (stack != init_stack) | |
0f41302f | 1071 | new_stack = (struct operation *) xrealloc (stack, new_size); |
7f2935c7 PB |
1072 | else |
1073 | { | |
0f41302f | 1074 | new_stack = (struct operation *) xmalloc (new_size); |
b0699dad | 1075 | memcpy (new_stack, stack, old_size); |
7f2935c7 PB |
1076 | } |
1077 | stack = new_stack; | |
0f41302f MS |
1078 | top = (struct operation *) ((char *) new_stack + old_size); |
1079 | limit = (struct operation *) ((char *) new_stack + new_size); | |
7f2935c7 PB |
1080 | } |
1081 | ||
1082 | top->flags = flags; | |
4063b943 | 1083 | top->prio = prio & ~EXTRACT_PRIO(RIGHT_ASSOC); |
7f2935c7 PB |
1084 | top->op = op.op; |
1085 | } | |
9ee70313 | 1086 | |
4063b943 NB |
1087 | done: |
1088 | result = (top[1].value != 0); | |
9ee70313 | 1089 | if (top != stack) |
b22ef131 | 1090 | CPP_ICE ("unbalanced stack in #if expression"); |
4063b943 NB |
1091 | else if (!(top[1].flags & HAVE_VALUE)) |
1092 | { | |
b22ef131 | 1093 | SYNTAX_ERROR ("#if with no expression"); |
4063b943 NB |
1094 | syntax_error: |
1095 | _cpp_skip_rest_of_line (pfile); | |
1096 | result = 0; /* Return 0 on syntax error. */ | |
1097 | } | |
9ee70313 | 1098 | |
4063b943 | 1099 | /* Free dynamic stack if we allocated one. */ |
7f2935c7 PB |
1100 | if (stack != init_stack) |
1101 | free (stack); | |
4063b943 NB |
1102 | pfile->parsing_if_directive--; |
1103 | CPP_SET_WRITTEN (pfile, old_written); | |
45b966db | 1104 | return result; |
7f2935c7 | 1105 | } |