00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "config.h"
00026 #include "system.h"
00027 #include "cpplib.h"
00028 #include "cpphash.h"
00029 #ifdef SGI_MONGOOSE
00030
00031 #include "defaults.h"
00032 #endif
00033
00034 #define PART_PRECISION (sizeof (cpp_num_part) * CHAR_BIT)
00035 #define HALF_MASK (~(cpp_num_part) 0 >> (PART_PRECISION / 2))
00036 #define LOW_PART(num_part) (num_part & HALF_MASK)
00037 #define HIGH_PART(num_part) (num_part >> (PART_PRECISION / 2))
00038
00039 struct op
00040 {
00041 const cpp_token *token;
00042 cpp_num value;
00043 enum cpp_ttype op;
00044 };
00045
00046
00047 #define num_zerop(num) ((num.low | num.high) == 0)
00048 #define num_eq(num1, num2) (num1.low == num2.low && num1.high == num2.high)
00049 static bool num_positive PARAMS ((cpp_num, size_t));
00050 static bool num_greater_eq PARAMS ((cpp_num, cpp_num, size_t));
00051 static cpp_num num_trim PARAMS ((cpp_num, size_t));
00052 static cpp_num num_part_mul PARAMS ((cpp_num_part, cpp_num_part));
00053
00054 static cpp_num num_unary_op PARAMS ((cpp_reader *, cpp_num, enum cpp_ttype));
00055 static cpp_num num_binary_op PARAMS ((cpp_reader *, cpp_num, cpp_num,
00056 enum cpp_ttype));
00057 static cpp_num num_negate PARAMS ((cpp_num, size_t));
00058 static cpp_num num_bitwise_op PARAMS ((cpp_reader *, cpp_num, cpp_num,
00059 enum cpp_ttype));
00060 static cpp_num num_inequality_op PARAMS ((cpp_reader *, cpp_num, cpp_num,
00061 enum cpp_ttype));
00062 static cpp_num num_equality_op PARAMS ((cpp_reader *, cpp_num, cpp_num,
00063 enum cpp_ttype));
00064 static cpp_num num_mul PARAMS ((cpp_reader *, cpp_num, cpp_num));
00065 static cpp_num num_div_op PARAMS ((cpp_reader *, cpp_num, cpp_num,
00066 enum cpp_ttype));
00067 static cpp_num num_lshift PARAMS ((cpp_num, size_t, size_t));
00068 static cpp_num num_rshift PARAMS ((cpp_num, size_t, size_t));
00069
00070 static cpp_num append_digit PARAMS ((cpp_num, int, int, size_t));
00071 static cpp_num parse_defined PARAMS ((cpp_reader *));
00072 static cpp_num eval_token PARAMS ((cpp_reader *, const cpp_token *));
00073 static struct op *reduce PARAMS ((cpp_reader *, struct op *, enum cpp_ttype));
00074 static unsigned int interpret_float_suffix PARAMS ((const uchar *, size_t));
00075 static unsigned int interpret_int_suffix PARAMS ((const uchar *, size_t));
00076 static void check_promotion PARAMS ((cpp_reader *, const struct op *));
00077
00078
00079 #define CPP_UPLUS (CPP_LAST_CPP_OP + 1)
00080 #define CPP_UMINUS (CPP_LAST_CPP_OP + 2)
00081
00082
00083
00084 #define SYNTAX_ERROR(msgid) \
00085 do { cpp_error (pfile, DL_ERROR, msgid); goto syntax_error; } while(0)
00086 #define SYNTAX_ERROR2(msgid, arg) \
00087 do { cpp_error (pfile, DL_ERROR, msgid, arg); goto syntax_error; } while(0)
00088
00089
00090
00091
00092 static unsigned int
00093 interpret_float_suffix (s, len)
00094 const uchar *s;
00095 size_t len;
00096 {
00097 size_t f = 0, l = 0, i = 0;
00098
00099 while (len--)
00100 switch (s[len])
00101 {
00102 case 'f': case 'F': f++; break;
00103 case 'l': case 'L': l++; break;
00104 case 'i': case 'I':
00105 case 'j': case 'J': i++; break;
00106 default:
00107 return 0;
00108 }
00109
00110 if (f + l > 1 || i > 1)
00111 return 0;
00112
00113 return ((i ? CPP_N_IMAGINARY : 0)
00114 | (f ? CPP_N_SMALL :
00115 l ? CPP_N_LARGE : CPP_N_MEDIUM));
00116 }
00117
00118
00119
00120
00121 static unsigned int
00122 interpret_int_suffix (s, len)
00123 const uchar *s;
00124 size_t len;
00125 {
00126 size_t u, l, i;
00127
00128 u = l = i = 0;
00129
00130 while (len--)
00131 switch (s[len])
00132 {
00133 case 'u': case 'U': u++; break;
00134 case 'i': case 'I':
00135 case 'j': case 'J': i++; break;
00136 case 'l': case 'L': l++;
00137
00138 if (l == 2 && s[len] != s[len + 1])
00139 return 0;
00140 break;
00141 default:
00142 return 0;
00143 }
00144
00145 if (l > 2 || u > 1 || i > 1)
00146 return 0;
00147
00148 return ((i ? CPP_N_IMAGINARY : 0)
00149 | (u ? CPP_N_UNSIGNED : 0)
00150 | ((l == 0) ? CPP_N_SMALL
00151 : (l == 1) ? CPP_N_MEDIUM : CPP_N_LARGE));
00152 }
00153
00154
00155
00156
00157 unsigned int
00158 cpp_classify_number (pfile, token)
00159 cpp_reader *pfile;
00160 const cpp_token *token;
00161 {
00162 const uchar *str = token->val.str.text;
00163 const uchar *limit;
00164 unsigned int max_digit, result, radix;
00165 enum {NOT_FLOAT = 0, AFTER_POINT, AFTER_EXPON} float_flag;
00166
00167
00168
00169 if (token->val.str.len == 1)
00170 return CPP_N_INTEGER | CPP_N_SMALL | CPP_N_DECIMAL;
00171
00172 limit = str + token->val.str.len;
00173 float_flag = NOT_FLOAT;
00174 max_digit = 0;
00175 radix = 10;
00176
00177
00178 if (*str == '0')
00179 {
00180 radix = 8;
00181 str++;
00182
00183
00184 if ((*str == 'x' || *str == 'X') && ISXDIGIT (str[1]))
00185 {
00186 radix = 16;
00187 str++;
00188 }
00189 }
00190
00191
00192 for (;;)
00193 {
00194 unsigned int c = *str++;
00195
00196 if (ISDIGIT (c) || (ISXDIGIT (c) && radix == 16))
00197 {
00198 c = hex_value (c);
00199 if (c > max_digit)
00200 max_digit = c;
00201 }
00202 else if (c == '.')
00203 {
00204 if (float_flag == NOT_FLOAT)
00205 float_flag = AFTER_POINT;
00206 else
00207 SYNTAX_ERROR ("too many decimal points in number");
00208 }
00209 else if ((radix <= 10 && (c == 'e' || c == 'E'))
00210 || (radix == 16 && (c == 'p' || c == 'P')))
00211 {
00212 float_flag = AFTER_EXPON;
00213 break;
00214 }
00215 else
00216 {
00217
00218 str--;
00219 break;
00220 }
00221 }
00222
00223 if (float_flag != NOT_FLOAT && radix == 8)
00224 radix = 10;
00225
00226 if (max_digit >= radix)
00227 SYNTAX_ERROR2 ("invalid digit \"%c\" in octal constant", '0' + max_digit);
00228
00229 if (float_flag != NOT_FLOAT)
00230 {
00231 if (radix == 16 && CPP_PEDANTIC (pfile) && !CPP_OPTION (pfile, c99))
00232 cpp_error (pfile, DL_PEDWARN,
00233 "use of C99 hexadecimal floating constant");
00234
00235 if (float_flag == AFTER_EXPON)
00236 {
00237 if (*str == '+' || *str == '-')
00238 str++;
00239
00240
00241 if (!ISDIGIT (*str))
00242 SYNTAX_ERROR ("exponent has no digits");
00243
00244 do
00245 str++;
00246 while (ISDIGIT (*str));
00247 }
00248 else if (radix == 16)
00249 SYNTAX_ERROR ("hexadecimal floating constants require an exponent");
00250
00251 result = interpret_float_suffix (str, limit - str);
00252 if (result == 0)
00253 {
00254 cpp_error (pfile, DL_ERROR,
00255 "invalid suffix \"%.*s\" on floating constant",
00256 (int) (limit - str), str);
00257 return CPP_N_INVALID;
00258 }
00259
00260
00261 if (limit != str
00262 && CPP_WTRADITIONAL (pfile)
00263 && ! cpp_sys_macro_p (pfile))
00264 cpp_error (pfile, DL_WARNING,
00265 "traditional C rejects the \"%.*s\" suffix",
00266 (int) (limit - str), str);
00267
00268 result |= CPP_N_FLOATING;
00269 }
00270 else
00271 {
00272 result = interpret_int_suffix (str, limit - str);
00273 if (result == 0)
00274 {
00275 cpp_error (pfile, DL_ERROR,
00276 "invalid suffix \"%.*s\" on integer constant",
00277 (int) (limit - str), str);
00278 return CPP_N_INVALID;
00279 }
00280
00281
00282
00283 if (CPP_WTRADITIONAL (pfile) && ! cpp_sys_macro_p (pfile))
00284 {
00285 int u_or_i = (result & (CPP_N_UNSIGNED|CPP_N_IMAGINARY));
00286 int large = (result & CPP_N_WIDTH) == CPP_N_LARGE;
00287
00288 if (u_or_i || (large && CPP_OPTION (pfile, warn_long_long)))
00289 cpp_error (pfile, DL_WARNING,
00290 "traditional C rejects the \"%.*s\" suffix",
00291 (int) (limit - str), str);
00292 }
00293
00294 if ((result & CPP_N_WIDTH) == CPP_N_LARGE
00295 && ! CPP_OPTION (pfile, c99)
00296 && CPP_OPTION (pfile, warn_long_long))
00297 cpp_error (pfile, DL_PEDWARN, "use of C99 long long integer constant");
00298
00299 result |= CPP_N_INTEGER;
00300 }
00301
00302 if ((result & CPP_N_IMAGINARY) && CPP_PEDANTIC (pfile))
00303 cpp_error (pfile, DL_PEDWARN, "imaginary constants are a GCC extension");
00304
00305 if (radix == 10)
00306 result |= CPP_N_DECIMAL;
00307 else if (radix == 16)
00308 result |= CPP_N_HEX;
00309 else
00310 result |= CPP_N_OCTAL;
00311
00312 return result;
00313
00314 syntax_error:
00315 return CPP_N_INVALID;
00316 }
00317
00318
00319
00320
00321
00322
00323
00324 cpp_num
00325 cpp_interpret_integer (pfile, token, type)
00326 cpp_reader *pfile;
00327 const cpp_token *token;
00328 unsigned int type;
00329 {
00330 const uchar *p, *end;
00331 cpp_num result;
00332
00333 result.low = 0;
00334 result.high = 0;
00335 result.unsignedp = !!(type & CPP_N_UNSIGNED);
00336 result.overflow = false;
00337
00338 p = token->val.str.text;
00339 end = p + token->val.str.len;
00340
00341
00342 if (token->val.str.len == 1)
00343 result.low = p[0] - '0';
00344 else
00345 {
00346 cpp_num_part max;
00347 size_t precision = CPP_OPTION (pfile, precision);
00348 unsigned int base = 10, c = 0;
00349 bool overflow = false;
00350
00351 if ((type & CPP_N_RADIX) == CPP_N_OCTAL)
00352 {
00353 base = 8;
00354 p++;
00355 }
00356 else if ((type & CPP_N_RADIX) == CPP_N_HEX)
00357 {
00358 base = 16;
00359 p += 2;
00360 }
00361
00362
00363
00364 max = ~(cpp_num_part) 0;
00365 if (precision < PART_PRECISION)
00366 max >>= PART_PRECISION - precision;
00367 max = (max - base + 1) / base + 1;
00368
00369 for (; p < end; p++)
00370 {
00371 c = *p;
00372
00373 if (ISDIGIT (c) || (base == 16 && ISXDIGIT (c)))
00374 c = hex_value (c);
00375 else
00376 break;
00377
00378
00379 if (result.low < max)
00380 result.low = result.low * base + c;
00381 else
00382 {
00383 result = append_digit (result, c, base, precision);
00384 overflow |= result.overflow;
00385 max = 0;
00386 }
00387 }
00388
00389 if (overflow)
00390 cpp_error (pfile, DL_PEDWARN,
00391 "integer constant is too large for its type");
00392
00393
00394
00395
00396 else if (!result.unsignedp
00397 && !(CPP_OPTION (pfile, traditional)
00398 && pfile->state.in_directive)
00399 && !num_positive (result, precision))
00400 {
00401 if (base == 10)
00402 cpp_error (pfile, DL_WARNING,
00403 "integer constant is so large that it is unsigned");
00404 result.unsignedp = true;
00405 }
00406 }
00407
00408 return result;
00409 }
00410
00411
00412
00413 static cpp_num
00414 append_digit (num, digit, base, precision)
00415 cpp_num num;
00416 int digit, base;
00417 size_t precision;
00418 {
00419 cpp_num result;
00420 unsigned int shift = 3 + (base == 16);
00421 bool overflow;
00422 cpp_num_part add_high, add_low;
00423
00424
00425
00426 overflow = !!(num.high >> (PART_PRECISION - shift));
00427 result.high = num.high << shift;
00428 result.low = num.low << shift;
00429 result.high |= num.low >> (PART_PRECISION - shift);
00430
00431 if (base == 10)
00432 {
00433 add_low = num.low << 1;
00434 add_high = (num.high << 1) + (num.low >> (PART_PRECISION - 1));
00435 }
00436 else
00437 add_high = add_low = 0;
00438
00439 if (add_low + digit < add_low)
00440 add_high++;
00441 add_low += digit;
00442
00443 if (result.low + add_low < result.low)
00444 add_high++;
00445 if (result.high + add_high < result.high)
00446 overflow = true;
00447
00448 result.low += add_low;
00449 result.high += add_high;
00450
00451
00452
00453 num.low = result.low;
00454 num.high = result.high;
00455 result = num_trim (result, precision);
00456 if (!num_eq (result, num))
00457 overflow = true;
00458
00459 result.unsignedp = num.unsignedp;
00460 result.overflow = overflow;
00461 return result;
00462 }
00463
00464
00465 static cpp_num
00466 parse_defined (pfile)
00467 cpp_reader *pfile;
00468 {
00469 cpp_num result;
00470 int paren = 0;
00471 cpp_hashnode *node = 0;
00472 const cpp_token *token;
00473 cpp_context *initial_context = pfile->context;
00474
00475
00476 pfile->state.prevent_expansion++;
00477
00478 token = cpp_get_token (pfile);
00479 if (token->type == CPP_OPEN_PAREN)
00480 {
00481 paren = 1;
00482 token = cpp_get_token (pfile);
00483 }
00484
00485 if (token->type == CPP_NAME)
00486 {
00487 node = token->val.node;
00488 if (paren && cpp_get_token (pfile)->type != CPP_CLOSE_PAREN)
00489 {
00490 cpp_error (pfile, DL_ERROR, "missing ')' after \"defined\"");
00491 node = 0;
00492 }
00493 }
00494 else
00495 {
00496 cpp_error (pfile, DL_ERROR,
00497 "operator \"defined\" requires an identifier");
00498 if (token->flags & NAMED_OP)
00499 {
00500 cpp_token op;
00501
00502 op.flags = 0;
00503 op.type = token->type;
00504 cpp_error (pfile, DL_ERROR,
00505 "(\"%s\" is an alternative token for \"%s\" in C++)",
00506 cpp_token_as_text (pfile, token),
00507 cpp_token_as_text (pfile, &op));
00508 }
00509 }
00510
00511 if (node)
00512 {
00513 if (pfile->context != initial_context && CPP_PEDANTIC (pfile))
00514 cpp_error (pfile, DL_WARNING,
00515 "this use of \"defined\" may not be portable");
00516
00517 _cpp_mark_macro_used (node);
00518
00519
00520
00521 pfile->mi_ind_cmacro = node;
00522 }
00523
00524 pfile->state.prevent_expansion--;
00525
00526 result.unsignedp = false;
00527 result.high = 0;
00528 result.overflow = false;
00529 result.low = node && node->type == NT_MACRO;
00530 return result;
00531 }
00532
00533
00534
00535
00536 static cpp_num
00537 eval_token (pfile, token)
00538 cpp_reader *pfile;
00539 const cpp_token *token;
00540 {
00541 cpp_num result;
00542 unsigned int temp;
00543 int unsignedp = 0;
00544
00545 switch (token->type)
00546 {
00547 case CPP_NUMBER:
00548 temp = cpp_classify_number (pfile, token);
00549 switch (temp & CPP_N_CATEGORY)
00550 {
00551 case CPP_N_FLOATING:
00552 cpp_error (pfile, DL_ERROR,
00553 "floating constant in preprocessor expression");
00554 break;
00555 case CPP_N_INTEGER:
00556 if (!(temp & CPP_N_IMAGINARY))
00557 return cpp_interpret_integer (pfile, token, temp);
00558 cpp_error (pfile, DL_ERROR,
00559 "imaginary number in preprocessor expression");
00560 break;
00561
00562 case CPP_N_INVALID:
00563
00564 break;
00565 }
00566 result.high = result.low = 0;
00567 break;
00568
00569 case CPP_WCHAR:
00570 case CPP_CHAR:
00571 {
00572 cppchar_t cc = cpp_interpret_charconst (pfile, token,
00573 &temp, &unsignedp);
00574
00575 result.high = 0;
00576 result.low = cc;
00577
00578 if (!unsignedp && (cppchar_signed_t) cc < 0)
00579 {
00580 if (PART_PRECISION > BITS_PER_CPPCHAR_T)
00581 result.low |= ~(~(cpp_num_part) 0
00582 >> (PART_PRECISION - BITS_PER_CPPCHAR_T));
00583 result.high = ~(cpp_num_part) 0;
00584 result = num_trim (result, CPP_OPTION (pfile, precision));
00585 }
00586 }
00587 break;
00588
00589 case CPP_NAME:
00590 if (token->val.node == pfile->spec_nodes.n_defined)
00591 return parse_defined (pfile);
00592 else if (CPP_OPTION (pfile, cplusplus)
00593 && (token->val.node == pfile->spec_nodes.n_true
00594 || token->val.node == pfile->spec_nodes.n_false))
00595 {
00596 result.high = 0;
00597 result.low = (token->val.node == pfile->spec_nodes.n_true);
00598
00599
00600
00601 if (CPP_PEDANTIC (pfile)
00602 && ! cpp_defined (pfile, DSC("__bool_true_false_are_defined")))
00603 cpp_error (pfile, DL_PEDWARN,
00604 "ISO C++ does not permit \"%s\" in #if",
00605 NODE_NAME (token->val.node));
00606 }
00607 else
00608 {
00609 result.high = 0;
00610 result.low = 0;
00611 if (CPP_OPTION (pfile, warn_undef) && !pfile->state.skip_eval)
00612 cpp_error (pfile, DL_WARNING, "\"%s\" is not defined",
00613 NODE_NAME (token->val.node));
00614 }
00615 break;
00616
00617 default:
00618 _cpp_test_assertion (pfile, &temp);
00619 result.high = 0;
00620 result.low = temp;
00621 }
00622
00623 result.unsignedp = !!unsignedp;
00624 result.overflow = false;
00625 return result;
00626 }
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652 #define NO_L_OPERAND (1 << 0)
00653 #define LEFT_ASSOC (1 << 1)
00654 #define CHECK_PROMOTION (1 << 2)
00655
00656
00657
00658 static const struct operator
00659 {
00660 uchar prio;
00661 uchar flags;
00662 } optab[] =
00663 {
00664 {0, 0},
00665 {16, NO_L_OPERAND},
00666 {12, LEFT_ASSOC | CHECK_PROMOTION},
00667 {12, LEFT_ASSOC | CHECK_PROMOTION},
00668 {14, LEFT_ASSOC | CHECK_PROMOTION},
00669 {14, LEFT_ASSOC | CHECK_PROMOTION},
00670 {15, LEFT_ASSOC | CHECK_PROMOTION},
00671 {15, LEFT_ASSOC | CHECK_PROMOTION},
00672 {15, LEFT_ASSOC | CHECK_PROMOTION},
00673 {9, LEFT_ASSOC | CHECK_PROMOTION},
00674 {7, LEFT_ASSOC | CHECK_PROMOTION},
00675 {8, LEFT_ASSOC | CHECK_PROMOTION},
00676 {13, LEFT_ASSOC},
00677 {13, LEFT_ASSOC},
00678
00679 {10, LEFT_ASSOC | CHECK_PROMOTION},
00680 {10, LEFT_ASSOC | CHECK_PROMOTION},
00681
00682 {16, NO_L_OPERAND},
00683 {6, LEFT_ASSOC},
00684 {5, LEFT_ASSOC},
00685 {3, 0},
00686 {4, LEFT_ASSOC | CHECK_PROMOTION},
00687 {2, LEFT_ASSOC},
00688 {1, NO_L_OPERAND},
00689 {0, 0},
00690 {0, 0},
00691 {11, LEFT_ASSOC},
00692 {11, LEFT_ASSOC},
00693 {12, LEFT_ASSOC | CHECK_PROMOTION},
00694 {12, LEFT_ASSOC | CHECK_PROMOTION},
00695 {16, NO_L_OPERAND},
00696 {16, NO_L_OPERAND}
00697 };
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710 bool
00711 _cpp_parse_expr (pfile)
00712 cpp_reader *pfile;
00713 {
00714 struct op *top = pfile->op_stack;
00715 unsigned int lex_count;
00716 bool saw_leading_not, want_value = true;
00717
00718 pfile->state.skip_eval = 0;
00719
00720
00721 pfile->mi_ind_cmacro = 0;
00722 saw_leading_not = false;
00723 lex_count = 0;
00724
00725
00726 top->op = CPP_EOF;
00727
00728 for (;;)
00729 {
00730 struct op op;
00731
00732 lex_count++;
00733 op.token = cpp_get_token (pfile);
00734 op.op = op.token->type;
00735
00736 switch (op.op)
00737 {
00738
00739 case CPP_NUMBER:
00740 case CPP_CHAR:
00741 case CPP_WCHAR:
00742 case CPP_NAME:
00743 case CPP_HASH:
00744 if (!want_value)
00745 SYNTAX_ERROR2 ("missing binary operator before token \"%s\"",
00746 cpp_token_as_text (pfile, op.token));
00747 want_value = false;
00748 top->value = eval_token (pfile, op.token);
00749 continue;
00750
00751 case CPP_NOT:
00752 saw_leading_not = lex_count == 1;
00753 break;
00754 case CPP_PLUS:
00755 if (want_value)
00756 op.op = CPP_UPLUS;
00757 break;
00758 case CPP_MINUS:
00759 if (want_value)
00760 op.op = CPP_UMINUS;
00761 break;
00762 case CPP_OTHER:
00763 if (ISGRAPH (op.token->val.c))
00764 SYNTAX_ERROR2 ("invalid character '%c' in #if", op.token->val.c);
00765 else
00766 SYNTAX_ERROR2 ("invalid character '\\%03o' in #if",
00767 op.token->val.c);
00768
00769 default:
00770 if ((int) op.op <= (int) CPP_EQ || (int) op.op >= (int) CPP_PLUS_EQ)
00771 SYNTAX_ERROR2 ("token \"%s\" is not valid in preprocessor expressions",
00772 cpp_token_as_text (pfile, op.token));
00773 break;
00774 }
00775
00776
00777 if (optab[op.op].flags & NO_L_OPERAND)
00778 {
00779 if (!want_value)
00780 SYNTAX_ERROR2 ("missing binary operator before token \"%s\"",
00781 cpp_token_as_text (pfile, op.token));
00782 }
00783 else if (want_value)
00784 {
00785
00786
00787 if (op.op == CPP_CLOSE_PAREN)
00788 {
00789 if (top->op == CPP_OPEN_PAREN)
00790 SYNTAX_ERROR ("void expression between '(' and ')'");
00791 }
00792 else if (top->op == CPP_EOF)
00793 SYNTAX_ERROR ("#if with no expression");
00794 if (top->op != CPP_EOF && top->op != CPP_OPEN_PAREN)
00795 SYNTAX_ERROR2 ("operator '%s' has no right operand",
00796 cpp_token_as_text (pfile, top->token));
00797 }
00798
00799 top = reduce (pfile, top, op.op);
00800 if (!top)
00801 goto syntax_error;
00802
00803 if (op.op == CPP_EOF)
00804 break;
00805
00806 switch (op.op)
00807 {
00808 case CPP_CLOSE_PAREN:
00809 continue;
00810 case CPP_OR_OR:
00811 if (!num_zerop (top->value))
00812 pfile->state.skip_eval++;
00813 break;
00814 case CPP_AND_AND:
00815 case CPP_QUERY:
00816 if (num_zerop (top->value))
00817 pfile->state.skip_eval++;
00818 break;
00819 case CPP_COLON:
00820 if (top->op != CPP_QUERY)
00821 SYNTAX_ERROR (" ':' without preceding '?'");
00822 if (!num_zerop (top[-1].value))
00823 pfile->state.skip_eval++;
00824 else
00825 pfile->state.skip_eval--;
00826 default:
00827 break;
00828 }
00829
00830 want_value = true;
00831
00832
00833 if (++top == pfile->op_limit)
00834 top = _cpp_expand_op_stack (pfile);
00835
00836 top->op = op.op;
00837 top->token = op.token;
00838 }
00839
00840
00841
00842
00843 if (pfile->mi_ind_cmacro && !(saw_leading_not && lex_count == 3))
00844 pfile->mi_ind_cmacro = 0;
00845
00846 if (top != pfile->op_stack)
00847 {
00848 cpp_error (pfile, DL_ICE, "unbalanced stack in #if");
00849 syntax_error:
00850 return false;
00851 }
00852
00853 return !num_zerop (top->value);
00854 }
00855
00856
00857
00858
00859 static struct op *
00860 reduce (pfile, top, op)
00861 cpp_reader *pfile;
00862 struct op *top;
00863 enum cpp_ttype op;
00864 {
00865 unsigned int prio;
00866
00867 if (top->op <= CPP_EQ || top->op > CPP_LAST_CPP_OP + 2)
00868 {
00869 bad_op:
00870 cpp_error (pfile, DL_ICE, "impossible operator '%u'", top->op);
00871 return 0;
00872 }
00873
00874 if (op == CPP_OPEN_PAREN)
00875 return top;
00876
00877
00878
00879 prio = optab[op].prio - ((optab[op].flags & LEFT_ASSOC) != 0);
00880 while (prio < optab[top->op].prio)
00881 {
00882 if (CPP_OPTION (pfile, warn_num_sign_change)
00883 && optab[top->op].flags & CHECK_PROMOTION)
00884 check_promotion (pfile, top);
00885
00886 switch (top->op)
00887 {
00888 case CPP_UPLUS:
00889 case CPP_UMINUS:
00890 case CPP_NOT:
00891 case CPP_COMPL:
00892 top[-1].value = num_unary_op (pfile, top->value, top->op);
00893 break;
00894
00895 case CPP_PLUS:
00896 case CPP_MINUS:
00897 case CPP_RSHIFT:
00898 case CPP_LSHIFT:
00899 case CPP_MIN:
00900 case CPP_MAX:
00901 case CPP_COMMA:
00902 top[-1].value = num_binary_op (pfile, top[-1].value,
00903 top->value, top->op);
00904 break;
00905
00906 case CPP_GREATER:
00907 case CPP_LESS:
00908 case CPP_GREATER_EQ:
00909 case CPP_LESS_EQ:
00910 top[-1].value
00911 = num_inequality_op (pfile, top[-1].value, top->value, top->op);
00912 break;
00913
00914 case CPP_EQ_EQ:
00915 case CPP_NOT_EQ:
00916 top[-1].value
00917 = num_equality_op (pfile, top[-1].value, top->value, top->op);
00918 break;
00919
00920 case CPP_AND:
00921 case CPP_OR:
00922 case CPP_XOR:
00923 top[-1].value
00924 = num_bitwise_op (pfile, top[-1].value, top->value, top->op);
00925 break;
00926
00927 case CPP_MULT:
00928 top[-1].value = num_mul (pfile, top[-1].value, top->value);
00929 break;
00930
00931 case CPP_DIV:
00932 case CPP_MOD:
00933 top[-1].value = num_div_op (pfile, top[-1].value,
00934 top->value, top->op);
00935 break;
00936
00937 case CPP_OR_OR:
00938 top--;
00939 if (!num_zerop (top->value))
00940 pfile->state.skip_eval--;
00941 top->value.low = (!num_zerop (top->value)
00942 || !num_zerop (top[1].value));
00943 top->value.high = 0;
00944 top->value.unsignedp = false;
00945 top->value.overflow = false;
00946 continue;
00947
00948 case CPP_AND_AND:
00949 top--;
00950 if (num_zerop (top->value))
00951 pfile->state.skip_eval--;
00952 top->value.low = (!num_zerop (top->value)
00953 && !num_zerop (top[1].value));
00954 top->value.high = 0;
00955 top->value.unsignedp = false;
00956 top->value.overflow = false;
00957 continue;
00958
00959 case CPP_OPEN_PAREN:
00960 if (op != CPP_CLOSE_PAREN)
00961 {
00962 cpp_error (pfile, DL_ERROR, "missing ')' in expression");
00963 return 0;
00964 }
00965 top--;
00966 top->value = top[1].value;
00967 return top;
00968
00969 case CPP_COLON:
00970 top -= 2;
00971 if (!num_zerop (top->value))
00972 {
00973 pfile->state.skip_eval--;
00974 top->value = top[1].value;
00975 }
00976 else
00977 top->value = top[2].value;
00978 top->value.unsignedp = (top[1].value.unsignedp
00979 || top[2].value.unsignedp);
00980 continue;
00981
00982 case CPP_QUERY:
00983 cpp_error (pfile, DL_ERROR, "'?' without following ':'");
00984 return 0;
00985
00986 default:
00987 goto bad_op;
00988 }
00989
00990 top--;
00991 if (top->value.overflow && !pfile->state.skip_eval)
00992 cpp_error (pfile, DL_PEDWARN,
00993 "integer overflow in preprocessor expression");
00994 }
00995
00996 if (op == CPP_CLOSE_PAREN)
00997 {
00998 cpp_error (pfile, DL_ERROR, "missing '(' in expression");
00999 return 0;
01000 }
01001
01002 return top;
01003 }
01004
01005
01006 struct op *
01007 _cpp_expand_op_stack (pfile)
01008 cpp_reader *pfile;
01009 {
01010 size_t old_size = (size_t) (pfile->op_limit - pfile->op_stack);
01011 size_t new_size = old_size * 2 + 20;
01012
01013 pfile->op_stack = (struct op *) xrealloc (pfile->op_stack,
01014 new_size * sizeof (struct op));
01015 pfile->op_limit = pfile->op_stack + new_size;
01016
01017 return pfile->op_stack + old_size;
01018 }
01019
01020
01021
01022 static void
01023 check_promotion (pfile, op)
01024 cpp_reader *pfile;
01025 const struct op *op;
01026 {
01027 if (op->value.unsignedp == op[-1].value.unsignedp)
01028 return;
01029
01030 if (op->value.unsignedp)
01031 {
01032 if (!num_positive (op[-1].value, CPP_OPTION (pfile, precision)))
01033 cpp_error (pfile, DL_WARNING,
01034 "the left operand of \"%s\" changes sign when promoted",
01035 cpp_token_as_text (pfile, op->token));
01036 }
01037 else if (!num_positive (op->value, CPP_OPTION (pfile, precision)))
01038 cpp_error (pfile, DL_WARNING,
01039 "the right operand of \"%s\" changes sign when promoted",
01040 cpp_token_as_text (pfile, op->token));
01041 }
01042
01043
01044 static cpp_num
01045 num_trim (num, precision)
01046 cpp_num num;
01047 size_t precision;
01048 {
01049 if (precision > PART_PRECISION)
01050 {
01051 precision -= PART_PRECISION;
01052 if (precision < PART_PRECISION)
01053 num.high &= ((cpp_num_part) 1 << precision) - 1;
01054 }
01055 else
01056 {
01057 if (precision < PART_PRECISION)
01058 num.low &= ((cpp_num_part) 1 << precision) - 1;
01059 num.high = 0;
01060 }
01061
01062 return num;
01063 }
01064
01065
01066 static bool
01067 num_positive (num, precision)
01068 cpp_num num;
01069 size_t precision;
01070 {
01071 if (precision > PART_PRECISION)
01072 {
01073 precision -= PART_PRECISION;
01074 return (num.high & (cpp_num_part) 1 << (precision - 1)) == 0;
01075 }
01076
01077 return (num.low & (cpp_num_part) 1 << (precision - 1)) == 0;
01078 }
01079
01080
01081
01082 cpp_num
01083 cpp_num_sign_extend (num, precision)
01084 cpp_num num;
01085 size_t precision;
01086 {
01087 if (!num.unsignedp)
01088 {
01089 if (precision > PART_PRECISION)
01090 {
01091 precision -= PART_PRECISION;
01092 if (precision < PART_PRECISION
01093 && (num.high & (cpp_num_part) 1 << (precision - 1)))
01094 num.high |= ~(~(cpp_num_part) 0 >> (PART_PRECISION - precision));
01095 }
01096 else if (num.low & (cpp_num_part) 1 << (precision - 1))
01097 {
01098 if (precision < PART_PRECISION)
01099 num.low |= ~(~(cpp_num_part) 0 >> (PART_PRECISION - precision));
01100 num.high = ~(cpp_num_part) 0;
01101 }
01102 }
01103
01104 return num;
01105 }
01106
01107
01108 static cpp_num
01109 num_negate (num, precision)
01110 cpp_num num;
01111 size_t precision;
01112 {
01113 cpp_num copy;
01114
01115 copy = num;
01116 num.high = ~num.high;
01117 num.low = ~num.low;
01118 if (++num.low == 0)
01119 num.high++;
01120 num = num_trim (num, precision);
01121 num.overflow = (!num.unsignedp && num_eq (num, copy) && !num_zerop (num));
01122
01123 return num;
01124 }
01125
01126
01127 static bool
01128 num_greater_eq (pa, pb, precision)
01129 cpp_num pa, pb;
01130 size_t precision;
01131 {
01132 bool unsignedp;
01133
01134 unsignedp = pa.unsignedp || pb.unsignedp;
01135
01136 if (!unsignedp)
01137 {
01138
01139
01140 unsignedp = num_positive (pa, precision);
01141
01142 if (unsignedp != num_positive (pb, precision))
01143 return unsignedp;
01144
01145
01146 }
01147
01148 return (pa.high > pb.high) || (pa.high == pb.high && pa.low >= pb.low);
01149 }
01150
01151
01152 static cpp_num
01153 num_bitwise_op (pfile, lhs, rhs, op)
01154 cpp_reader *pfile ATTRIBUTE_UNUSED;
01155 cpp_num lhs, rhs;
01156 enum cpp_ttype op;
01157 {
01158 lhs.overflow = false;
01159 lhs.unsignedp = lhs.unsignedp || rhs.unsignedp;
01160
01161
01162
01163 if (op == CPP_AND)
01164 {
01165 lhs.low &= rhs.low;
01166 lhs.high &= rhs.high;
01167 }
01168 else if (op == CPP_OR)
01169 {
01170 lhs.low |= rhs.low;
01171 lhs.high |= rhs.high;
01172 }
01173 else
01174 {
01175 lhs.low ^= rhs.low;
01176 lhs.high ^= rhs.high;
01177 }
01178
01179 return lhs;
01180 }
01181
01182
01183 static cpp_num
01184 num_inequality_op (pfile, lhs, rhs, op)
01185 cpp_reader *pfile;
01186 cpp_num lhs, rhs;
01187 enum cpp_ttype op;
01188 {
01189 bool gte = num_greater_eq (lhs, rhs, CPP_OPTION (pfile, precision));
01190
01191 if (op == CPP_GREATER_EQ)
01192 lhs.low = gte;
01193 else if (op == CPP_LESS)
01194 lhs.low = !gte;
01195 else if (op == CPP_GREATER)
01196 lhs.low = gte && !num_eq (lhs, rhs);
01197 else
01198 lhs.low = !gte || num_eq (lhs, rhs);
01199
01200 lhs.high = 0;
01201 lhs.overflow = false;
01202 lhs.unsignedp = false;
01203 return lhs;
01204 }
01205
01206
01207 static cpp_num
01208 num_equality_op (pfile, lhs, rhs, op)
01209 cpp_reader *pfile ATTRIBUTE_UNUSED;
01210 cpp_num lhs, rhs;
01211 enum cpp_ttype op;
01212 {
01213
01214 bool eq = num_eq (lhs, rhs);
01215 if (op == CPP_NOT_EQ)
01216 eq = !eq;
01217 lhs.low = eq;
01218 lhs.high = 0;
01219 lhs.overflow = false;
01220 lhs.unsignedp = false;
01221 return lhs;
01222 }
01223
01224
01225 static cpp_num
01226 num_rshift (num, precision, n)
01227 cpp_num num;
01228 size_t precision, n;
01229 {
01230 cpp_num_part sign_mask;
01231
01232 if (num.unsignedp || num_positive (num, precision))
01233 sign_mask = 0;
01234 else
01235 sign_mask = ~(cpp_num_part) 0;
01236
01237 if (n >= precision)
01238 num.high = num.low = sign_mask;
01239 else
01240 {
01241
01242 if (precision < PART_PRECISION)
01243 num.high = sign_mask, num.low |= sign_mask << precision;
01244 else if (precision < 2 * PART_PRECISION)
01245 num.high |= sign_mask << (precision - PART_PRECISION);
01246
01247 if (n >= PART_PRECISION)
01248 {
01249 n -= PART_PRECISION;
01250 num.low = num.high;
01251 num.high = sign_mask;
01252 }
01253
01254 if (n)
01255 {
01256 num.low = (num.low >> n) | (num.high << (PART_PRECISION - n));
01257 num.high = (num.high >> n) | (sign_mask << (PART_PRECISION - n));
01258 }
01259 }
01260
01261 num = num_trim (num, precision);
01262 num.overflow = false;
01263 return num;
01264 }
01265
01266
01267 static cpp_num
01268 num_lshift (num, precision, n)
01269 cpp_num num;
01270 size_t precision, n;
01271 {
01272 if (n >= precision)
01273 {
01274 num.overflow = !num.unsignedp && !num_zerop (num);
01275 num.high = num.low = 0;
01276 }
01277 else
01278 {
01279 cpp_num orig, maybe_orig;
01280 size_t m = n;
01281
01282 orig = num;
01283 if (m >= PART_PRECISION)
01284 {
01285 m -= PART_PRECISION;
01286 num.high = num.low;
01287 num.low = 0;
01288 }
01289 if (m)
01290 {
01291 num.high = (num.high << m) | (num.low >> (PART_PRECISION - m));
01292 num.low <<= m;
01293 }
01294 num = num_trim (num, precision);
01295
01296 if (num.unsignedp)
01297 num.overflow = false;
01298 else
01299 {
01300 maybe_orig = num_rshift (num, precision, n);
01301 num.overflow = !num_eq (orig, maybe_orig);
01302 }
01303 }
01304
01305 return num;
01306 }
01307
01308
01309 static cpp_num
01310 num_unary_op (pfile, num, op)
01311 cpp_reader *pfile;
01312 cpp_num num;
01313 enum cpp_ttype op;
01314 {
01315 switch (op)
01316 {
01317 case CPP_UPLUS:
01318 if (CPP_WTRADITIONAL (pfile) && !pfile->state.skip_eval)
01319 cpp_error (pfile, DL_WARNING,
01320 "traditional C rejects the unary plus operator");
01321 num.overflow = false;
01322 break;
01323
01324 case CPP_UMINUS:
01325 num = num_negate (num, CPP_OPTION (pfile, precision));
01326 break;
01327
01328 case CPP_COMPL:
01329 num.high = ~num.high;
01330 num.low = ~num.low;
01331 num = num_trim (num, CPP_OPTION (pfile, precision));
01332 num.overflow = false;
01333 break;
01334
01335 default:
01336 num.low = num_zerop (num);
01337 num.high = 0;
01338 num.overflow = false;
01339 num.unsignedp = false;
01340 break;
01341 }
01342
01343 return num;
01344 }
01345
01346
01347 static cpp_num
01348 num_binary_op (pfile, lhs, rhs, op)
01349 cpp_reader *pfile;
01350 cpp_num lhs, rhs;
01351 enum cpp_ttype op;
01352 {
01353 cpp_num result;
01354 size_t precision = CPP_OPTION (pfile, precision);
01355 bool gte;
01356 size_t n;
01357
01358 switch (op)
01359 {
01360
01361 case CPP_LSHIFT:
01362 case CPP_RSHIFT:
01363 if (!rhs.unsignedp && !num_positive (rhs, precision))
01364 {
01365
01366 if (op == CPP_LSHIFT)
01367 op = CPP_RSHIFT;
01368 else
01369 op = CPP_LSHIFT;
01370 rhs = num_negate (rhs, precision);
01371 }
01372 if (rhs.high)
01373 n = ~0;
01374 else
01375 n = rhs.low;
01376 if (op == CPP_LSHIFT)
01377 lhs = num_lshift (lhs, precision, n);
01378 else
01379 lhs = num_rshift (lhs, precision, n);
01380 break;
01381
01382
01383 case CPP_MIN:
01384 case CPP_MAX:
01385 {
01386 bool unsignedp = lhs.unsignedp || rhs.unsignedp;
01387
01388 gte = num_greater_eq (lhs, rhs, precision);
01389 if (op == CPP_MIN)
01390 gte = !gte;
01391 if (!gte)
01392 lhs = rhs;
01393 lhs.unsignedp = unsignedp;
01394 }
01395 break;
01396
01397
01398 case CPP_MINUS:
01399 rhs = num_negate (rhs, precision);
01400 case CPP_PLUS:
01401 result.low = lhs.low + rhs.low;
01402 result.high = lhs.high + rhs.high;
01403 if (result.low < lhs.low)
01404 result.high++;
01405
01406 result = num_trim (result, precision);
01407 result.unsignedp = lhs.unsignedp || rhs.unsignedp;
01408 if (result.unsignedp)
01409 result.overflow = false;
01410 else
01411 {
01412 bool lhsp = num_positive (lhs, precision);
01413 result.overflow = (lhsp == num_positive (rhs, precision)
01414 && lhsp != num_positive (result, precision));
01415 }
01416 return result;
01417
01418
01419 default:
01420 if (CPP_PEDANTIC (pfile) && !pfile->state.skip_eval)
01421 cpp_error (pfile, DL_PEDWARN,
01422 "comma operator in operand of #if");
01423 lhs = rhs;
01424 break;
01425 }
01426
01427 return lhs;
01428 }
01429
01430
01431
01432 static cpp_num
01433 num_part_mul (lhs, rhs)
01434 cpp_num_part lhs, rhs;
01435 {
01436 cpp_num result;
01437 cpp_num_part middle[2], temp;
01438
01439 result.low = LOW_PART (lhs) * LOW_PART (rhs);
01440 result.high = HIGH_PART (lhs) * HIGH_PART (rhs);
01441
01442 middle[0] = LOW_PART (lhs) * HIGH_PART (rhs);
01443 middle[1] = HIGH_PART (lhs) * LOW_PART (rhs);
01444
01445 temp = result.low;
01446 result.low += LOW_PART (middle[0]) << (PART_PRECISION / 2);
01447 if (result.low < temp)
01448 result.high++;
01449
01450 temp = result.low;
01451 result.low += LOW_PART (middle[1]) << (PART_PRECISION / 2);
01452 if (result.low < temp)
01453 result.high++;
01454
01455 result.high += HIGH_PART (middle[0]);
01456 result.high += HIGH_PART (middle[1]);
01457 result.unsignedp = 1;
01458
01459 return result;
01460 }
01461
01462
01463 static cpp_num
01464 num_mul (pfile, lhs, rhs)
01465 cpp_reader *pfile;
01466 cpp_num lhs, rhs;
01467 {
01468 cpp_num result, temp;
01469 bool unsignedp = lhs.unsignedp || rhs.unsignedp;
01470 bool overflow, negate = false;
01471 size_t precision = CPP_OPTION (pfile, precision);
01472
01473
01474 if (!unsignedp)
01475 {
01476 if (!num_positive (lhs, precision))
01477 negate = !negate, lhs = num_negate (lhs, precision);
01478 if (!num_positive (rhs, precision))
01479 negate = !negate, rhs = num_negate (rhs, precision);
01480 }
01481
01482 overflow = lhs.high && rhs.high;
01483 result = num_part_mul (lhs.low, rhs.low);
01484
01485 temp = num_part_mul (lhs.high, rhs.low);
01486 result.high += temp.low;
01487 if (temp.high)
01488 overflow = true;
01489
01490 temp = num_part_mul (lhs.low, rhs.high);
01491 result.high += temp.low;
01492 if (temp.high)
01493 overflow = true;
01494
01495 temp.low = result.low, temp.high = result.high;
01496 result = num_trim (result, precision);
01497 if (!num_eq (result, temp))
01498 overflow = true;
01499
01500 if (negate)
01501 result = num_negate (result, precision);
01502
01503 if (unsignedp)
01504 result.overflow = false;
01505 else
01506 result.overflow = overflow || (num_positive (result, precision) ^ !negate
01507 && !num_zerop (result));
01508 result.unsignedp = unsignedp;
01509
01510 return result;
01511 }
01512
01513
01514
01515 static cpp_num
01516 num_div_op (pfile, lhs, rhs, op)
01517 cpp_reader *pfile;
01518 cpp_num lhs, rhs;
01519 enum cpp_ttype op;
01520 {
01521 cpp_num result, sub;
01522 cpp_num_part mask;
01523 bool unsignedp = lhs.unsignedp || rhs.unsignedp;
01524 bool negate = false, lhs_neg = false;
01525 size_t i, precision = CPP_OPTION (pfile, precision);
01526
01527
01528 if (!unsignedp)
01529 {
01530 if (!num_positive (lhs, precision))
01531 negate = !negate, lhs_neg = true, lhs = num_negate (lhs, precision);
01532 if (!num_positive (rhs, precision))
01533 negate = !negate, rhs = num_negate (rhs, precision);
01534 }
01535
01536
01537 if (rhs.high)
01538 {
01539 i = precision - 1;
01540 mask = (cpp_num_part) 1 << (i - PART_PRECISION);
01541 for (; ; i--, mask >>= 1)
01542 if (rhs.high & mask)
01543 break;
01544 }
01545 else if (rhs.low)
01546 {
01547 if (precision > PART_PRECISION)
01548 i = precision - PART_PRECISION - 1;
01549 else
01550 i = precision - 1;
01551 mask = (cpp_num_part) 1 << i;
01552 for (; ; i--, mask >>= 1)
01553 if (rhs.low & mask)
01554 break;
01555 }
01556 else
01557 {
01558 if (!pfile->state.skip_eval)
01559 cpp_error (pfile, DL_ERROR, "division by zero in #if");
01560 return lhs;
01561 }
01562
01563
01564
01565
01566
01567
01568 rhs.unsignedp = true;
01569 lhs.unsignedp = true;
01570 i = precision - i - 1;
01571 sub = num_lshift (rhs, precision, i);
01572
01573 result.high = result.low = 0;
01574 for (;;)
01575 {
01576 if (num_greater_eq (lhs, sub, precision))
01577 {
01578 lhs = num_binary_op (pfile, lhs, sub, CPP_MINUS);
01579 if (i >= PART_PRECISION)
01580 result.high |= (cpp_num_part) 1 << (i - PART_PRECISION);
01581 else
01582 result.low |= (cpp_num_part) 1 << i;
01583 }
01584 if (i-- == 0)
01585 break;
01586 sub.low = (sub.low >> 1) | (sub.high << (PART_PRECISION - 1));
01587 sub.high >>= 1;
01588 }
01589
01590
01591 if (op == CPP_DIV)
01592 {
01593 result.unsignedp = unsignedp;
01594 if (unsignedp)
01595 result.overflow = false;
01596 else
01597 {
01598 if (negate)
01599 result = num_negate (result, precision);
01600 result.overflow = num_positive (result, precision) ^ !negate;
01601 }
01602
01603 return result;
01604 }
01605
01606
01607 lhs.unsignedp = unsignedp;
01608 lhs.overflow = false;
01609 if (lhs_neg)
01610 lhs = num_negate (lhs, precision);
01611
01612 return lhs;
01613 }