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