1 /* 2 ** C declaration parser. 3 ** Copyright (C) 2005-2025 Mike Pall. See Copyright Notice below. 4 ** 5 ** This file contains derived work from LuaJIT's FFI C parser (uc_cparse.c). 6 ** 7 ** Modifications: 8 ** - Adapted VM interactions to use ucode's API (uc_vm_t, uc_value_t, etc.) 9 ** - Removed JIT-specific code and dependencies 10 ** - Adapted error handling to use ucode exceptions 11 ** 12 ** See NOTICE and ATTRIBUTION.md for complete attribution details. 13 */ 14 15 #include <ctype.h> 16 #include <ucode/vm.h> 17 #include "uc_ctype.h" 18 #include "uc_cparse.h" 19 20 #include "ucode/util.h" 21 22 /* 23 ** Important note: this is NOT a validating C parser! This is a minimal 24 ** C declaration parser, solely for use by the LuaJIT FFI. 25 ** 26 ** It ought to return correct results for properly formed C declarations, 27 ** but it may accept some invalid declarations, too (and return nonsense). 28 ** Also, it shows rather generic error messages to avoid unnecessary bloat. 29 ** If in doubt, please check the input against your favorite C compiler. 30 */ 31 32 /* Assertions disabled for production build. */ 33 #define uc_assertCP(c, ...) ((void)0) 34 35 /* Check if two function types are structurally equivalent. */ 36 static bool 37 ctype_func_is_equiv(CTState *cts, CType *ct1, CType *ct2) 38 { 39 CType *p1, *p2; 40 41 if (ct1->info != ct2->info || ct1->size != ct2->size) { 42 return false; 43 } 44 45 /* Compare parameter chains. */ 46 p1 = ctype_get(cts, ct1->sib); 47 p2 = ctype_get(cts, ct2->sib); 48 49 while (p1 && p2) { 50 /* Stop at non-field entries (end of parameters or attributes). */ 51 if (!ctype_isfield(p1->info) || !ctype_isfield(p2->info)) 52 break; 53 if (p1->info != p2->info || p1->size != p2->size) { 54 return false; 55 } 56 p1 = ctype_get(cts, p1->sib); 57 p2 = ctype_get(cts, p2->sib); 58 } 59 60 return (p1 == p2); 61 } 62 63 /* -- Miscellaneous ------------------------------------------------------- */ 64 65 /* Match string against a C literal. */ 66 #define cp_str_is(str, k) \ 67 (ucv_string_length(str) == sizeof(k) - 1 && !memcmp(ucv_string_get(str), k, sizeof(k) - 1)) 68 69 /* Check string against a linear list of matches. */ 70 int uc_cparse_case(uc_value_t *str, const char *match) 71 { 72 size_t len; 73 int n; 74 for (n = 0; (len = *match++); n++, match += len) 75 { 76 if (ucv_string_length(str) == len && !memcmp(match, ucv_string_get(str), len)) 77 return n; 78 } 79 return -1; 80 } 81 82 /* -- C lexer ------------------------------------------------------------- */ 83 84 /* C lexer token names. */ 85 static const char *const ctoknames[] = { 86 #define CTOKSTR(name, str) str, 87 CTOKDEF(CTOKSTR) 88 #undef CTOKSTR 89 NULL}; 90 91 /* Forward declaration. */ 92 static void cp_err(CPState *cp, const char *em); 93 94 static const char *cp_tok2str(CPState *cp, CPToken tok) 95 { 96 char *e; 97 uc_assertCP(tok < CTOK_FIRSTDECL, "bad CPToken %d", tok); 98 if (tok > CTOK_OFS) 99 return ctoknames[tok - CTOK_OFS - 1]; 100 else if (!iscntrl(tok)) 101 { 102 xasprintf(&e, "%c", tok); 103 return e; 104 } 105 else 106 { 107 xasprintf(&e, "char(%d)", tok); 108 return e; 109 } 110 } 111 112 /* End-of-line? */ 113 static UC_AINLINE int cp_iseol(CPChar c) 114 { 115 return (c == '\n' || c == '\r'); 116 } 117 118 /* Peek next raw character. */ 119 static UC_AINLINE CPChar cp_rawpeek(CPState *cp) 120 { 121 return (CPChar)(uint8_t)(*cp->p); 122 } 123 124 static UC_NOINLINE CPChar cp_get_bs(CPState *cp); 125 126 /* Get next character. */ 127 static UC_AINLINE CPChar cp_get(CPState *cp) 128 { 129 cp->c = (CPChar)(uint8_t)(*cp->p++); 130 if (UC_LIKELY(cp->c != '\\')) 131 return cp->c; 132 return cp_get_bs(cp); 133 } 134 135 /* Transparently skip backslash-escaped line breaks. */ 136 static UC_NOINLINE CPChar cp_get_bs(CPState *cp) 137 { 138 CPChar c2, c = cp_rawpeek(cp); 139 if (!cp_iseol(c)) 140 return cp->c; 141 cp->p++; 142 c2 = cp_rawpeek(cp); 143 if (cp_iseol(c2) && c2 != c) 144 cp->p++; 145 cp->linenumber++; 146 return cp_get(cp); 147 } 148 149 /* Save character in buffer. */ 150 static UC_AINLINE void cp_save(CPState *cp, CPChar c) 151 { 152 sprintbuf(&cp->pb, "%c", c); 153 } 154 155 /* Skip line break. Handles "\n", "\r", "\r\n" or "\n\r". */ 156 static void cp_newline(CPState *cp) 157 { 158 CPChar c = cp_rawpeek(cp); 159 if (cp_iseol(c) && c != cp->c) 160 cp->p++; 161 cp->linenumber++; 162 } 163 164 static void __attribute__((format(printf, 3, 0))) 165 cp_errmsg(CPState *cp, CPToken tok, const char *em, ...) 166 { 167 const char *tokstr; 168 char *s, *msg; 169 va_list argp; 170 171 if (cp->error) 172 return; 173 174 if (tok == 0) 175 { 176 tokstr = NULL; 177 } 178 else if (tok == CTOK_IDENT || tok == CTOK_INTEGER || tok == CTOK_STRING || 179 tok >= CTOK_FIRSTDECL) 180 { 181 if (cp->pb.bpos == 0) 182 cp_save(cp, '$'); 183 cp_save(cp, '\0'); 184 tokstr = cp->pb.buf; 185 } 186 else 187 { 188 tokstr = cp_tok2str(cp, tok); 189 } 190 va_start(argp, em); 191 xvasprintf(&msg, em, argp); 192 va_end(argp); 193 if (tokstr) 194 { 195 xasprintf(&s, "%s near '%s'", msg, tokstr); 196 free(msg); 197 msg = s; 198 } 199 if (cp->linenumber > 1) 200 { 201 xasprintf(&s, "%s at line %d", msg, cp->linenumber); 202 free(msg); 203 msg = s; 204 } 205 206 cp->error = msg; 207 } 208 209 static void cp_err_token(CPState *cp, CPToken tok) 210 { 211 cp_errmsg(cp, cp->tok, "'%s' expected", cp_tok2str(cp, tok)); 212 } 213 214 static void cp_err_badidx(CPState *cp, CType *ct) 215 { 216 uc_value_t *s = uc_ctype_repr(cp->uv_vm, ctype_typeid(cp->cts, ct), NULL); 217 cp_errmsg(cp, 0, "'%s' cannot be indexed", ucv_string_get(s)); 218 ucv_put(s); 219 } 220 221 static void cp_err(CPState *cp, const char *em) 222 { 223 cp_errmsg(cp, 0, "%s", em); 224 } 225 226 /* -- Main lexical scanner ------------------------------------------------ */ 227 228 static inline bool is_ident(uint8_t c) 229 { 230 return (c >= 48 && c <= 57) || 231 (c >= 65 && c <= 90) || 232 (c == '_') || 233 (c >= 97 && c <= 122) || 234 (c >= 128); 235 } 236 237 /* Parse number literal. Only handles int32_t/uint32_t right now. */ 238 static CPToken cp_number(CPState *cp) 239 { 240 unsigned long long val; 241 bool sign = false; 242 int base = 0; 243 char *s, *e; 244 245 do 246 { 247 cp_save(cp, cp->c); 248 } while (is_ident(cp_get(cp))); 249 250 cp_save(cp, '\0'); 251 252 s = cp->pb.buf; 253 254 while (isspace(*s)) 255 s++; 256 257 if (*s == '-') 258 { 259 sign = true; 260 s++; 261 } 262 else if (*s == '+') 263 { 264 s++; 265 } 266 267 if (*s == '') 268 { 269 switch (s[1] | 32) 270 { 271 case 'x': 272 base = 16; 273 s += 2; 274 break; 275 276 case 'o': 277 base = 8; 278 s += 2; 279 break; 280 281 case 'b': 282 base = 2; 283 s += 2; 284 break; 285 } 286 } 287 288 val = strtoull(s, &e, base); 289 290 /* handle potential suffix */ 291 if (!strcasecmp(e, "ull") || !strcasecmp(e, "llu")) 292 { 293 if (sizeof(unsigned long long) > sizeof(uint32_t) && !(cp->mode & CPARSE_MODE_SKIP)) 294 cp_errmsg(cp, CTOK_INTEGER, "malformed number"); 295 296 cp->val.id = CTID_UINT32; 297 e += 3; 298 } 299 else if (!strcasecmp(e, "ll")) 300 { 301 if (sizeof(long long) > sizeof(int32_t) && !(cp->mode & CPARSE_MODE_SKIP)) 302 cp_errmsg(cp, CTOK_INTEGER, "malformed number"); 303 304 cp->val.id = CTID_INT32; 305 e += 2; 306 } 307 else if (!strcasecmp(e, "ul") || !strcasecmp(e, "lu")) 308 { 309 if (sizeof(unsigned long) > sizeof(uint32_t) && !(cp->mode & CPARSE_MODE_SKIP)) 310 cp_errmsg(cp, CTOK_INTEGER, "malformed number"); 311 312 cp->val.id = CTID_UINT32; 313 e += 2; 314 } 315 else if ((*e | 32) == 'u') 316 { 317 cp->val.id = CTID_UINT32; 318 e++; 319 } 320 else if ((*e | 32) == 'l') 321 { 322 if (sizeof(long) > sizeof(int32_t) && !(cp->mode & CPARSE_MODE_SKIP)) 323 cp_errmsg(cp, CTOK_INTEGER, "malformed number"); 324 325 cp->val.id = CTID_INT32; 326 e++; 327 } 328 else if ((*e | 32) == 'i') 329 { 330 if (!(cp->mode & CPARSE_MODE_SKIP)) 331 cp_errmsg(cp, CTOK_INTEGER, "malformed number"); 332 333 e++; 334 } 335 else 336 { 337 cp->val.id = CTID_INT32; 338 } 339 340 while (isspace(*e)) 341 e++; 342 343 if (*e) 344 cp_errmsg(cp, CTOK_INTEGER, "malformed number"); 345 346 cp->val.u32 = sign ? (uint32_t)-val : (uint32_t)val; 347 return CTOK_INTEGER; 348 } 349 350 /* Parse identifier or keyword. */ 351 static CPToken cp_ident(CPState *cp) 352 { 353 do 354 { 355 cp_save(cp, cp->c); 356 } while (is_ident(cp_get(cp))); 357 ucv_put(cp->uv_str); 358 cp->uv_str = ucv_string_new(cp->pb.buf); 359 // cp->str = lj_buf_str(cp->L, &cp->sb); 360 cp->val.id = uc_ctype_getname(cp->cts, &cp->ct, cp->uv_str, cp->tmask); 361 362 if (ctype_type(cp->ct->info) == CT_KW) 363 return ctype_cid(cp->ct->info); 364 return CTOK_IDENT; 365 } 366 367 /* Parse parameter. */ 368 static CPToken cp_param(CPState *cp) 369 { 370 CPChar c = cp_get(cp); 371 // TValue *o = cp->param; 372 uc_value_t **uv = cp->uv_param; 373 if (is_ident(c) || c == '$') /* Reserve $xyz for future extensions. */ { 374 cp_errmsg(cp, c, "syntax error"); 375 return CTOK_EOF; 376 } 377 if (!uv || uv >= &cp->uv_vm->stack.entries[cp->uv_vm->stack.count]) { 378 cp_err(cp, "wrong number of type parameters"); 379 return CTOK_EOF; 380 } 381 cp->uv_param = uv + 1; 382 if (ucv_type(*uv) == UC_STRING) 383 { 384 ucv_put(cp->uv_str); 385 cp->uv_str = ucv_get(*uv); 386 cp->val.id = 0; 387 cp->ct = &cp->cts->vtab.entries[0]; 388 return CTOK_IDENT; 389 } 390 else if (ucv_type(*uv) == UC_INTEGER) 391 { 392 cp->val.i32 = (int32_t)ucv_int64_get(*uv); 393 cp->val.id = CTID_INT32; 394 return CTOK_INTEGER; 395 } 396 else 397 { 398 void *ctype = ucv_resource_dataptr(*uv, "ffi.ctype"); 399 if (!ctype) 400 cp_errmsg(cp, 0, "type parameter expected, got %s", ucv_typename(*uv)); 401 // lj_err_argtype(cp->L, (int)(o-cp->L->base)+1, "type parameter"); 402 cp->val.id = (CTypeID)(uintptr_t)ctype; 403 return '$'; 404 } 405 } 406 407 /* Parse string or character constant. */ 408 static CPToken cp_string(CPState *cp) 409 { 410 CPChar delim = cp->c; 411 cp_get(cp); 412 while (cp->c != delim) 413 { 414 CPChar c = cp->c; 415 if (c == '\0') { 416 cp_errmsg(cp, CTOK_EOF, "unfinished string"); 417 return CTOK_EOF; 418 } 419 if (c == '\\') 420 { 421 c = cp_get(cp); 422 switch (c) 423 { 424 case '\0': 425 cp_errmsg(cp, CTOK_EOF, "unfinished string"); 426 return CTOK_EOF; 427 case 'a': 428 c = '\a'; 429 break; 430 case 'b': 431 c = '\b'; 432 break; 433 case 'f': 434 c = '\f'; 435 break; 436 case 'n': 437 c = '\n'; 438 break; 439 case 'r': 440 c = '\r'; 441 break; 442 case 't': 443 c = '\t'; 444 break; 445 case 'v': 446 c = '\v'; 447 break; 448 case 'e': 449 c = 27; 450 break; 451 case 'x': 452 c = 0; 453 while (isxdigit(cp_get(cp))) 454 c = (c << 4) + (isdigit(cp->c) ? cp->c - '' : (cp->c & 15) + 9); 455 cp_save(cp, (c & 0xff)); 456 continue; 457 default: 458 if (isdigit(c)) 459 { 460 c -= ''; 461 if (isdigit(cp_get(cp))) 462 { 463 c = c * 8 + (cp->c - ''); 464 if (isdigit(cp_get(cp))) 465 { 466 c = c * 8 + (cp->c - ''); 467 cp_get(cp); 468 } 469 } 470 cp_save(cp, (c & 0xff)); 471 continue; 472 } 473 break; 474 } 475 } 476 cp_save(cp, c); 477 cp_get(cp); 478 } 479 cp_get(cp); 480 if (delim == '"') 481 { 482 // FIXME: consider ucv_stringbuf_new 483 ucv_put(cp->uv_str); 484 cp->uv_str = ucv_string_new(cp->pb.buf); 485 // cp->str = lj_buf_str(cp->L, &cp->sb); 486 return CTOK_STRING; 487 } 488 else 489 { 490 if (printbuf_length(&cp->pb) != 1) 491 cp_err_token(cp, '\''); 492 cp->val.i32 = (int32_t)(char)*cp->pb.buf; 493 cp->val.id = CTID_INT32; 494 return CTOK_INTEGER; 495 } 496 } 497 498 /* Skip C comment. */ 499 static void cp_comment_c(CPState *cp) 500 { 501 do 502 { 503 if (cp_get(cp) == '*') 504 { 505 do 506 { 507 if (cp_get(cp) == '/') 508 { 509 cp_get(cp); 510 return; 511 } 512 } while (cp->c == '*'); 513 } 514 if (cp_iseol(cp->c)) 515 cp_newline(cp); 516 } while (cp->c != '\0'); 517 } 518 519 /* Skip C++ comment. */ 520 static void cp_comment_cpp(CPState *cp) 521 { 522 while (!cp_iseol(cp_get(cp)) && cp->c != '\0') 523 ; 524 } 525 526 /* Lexical scanner for C. Only a minimal subset is implemented. */ 527 static CPToken cp_next_(CPState *cp) 528 { 529 //lj_buf_reset(&cp->sb); 530 if (cp->pb.buf) 531 printbuf_reset(&cp->pb); 532 533 for (;;) 534 { 535 if (is_ident(cp->c)) 536 return isdigit(cp->c) ? cp_number(cp) : cp_ident(cp); 537 switch (cp->c) 538 { 539 case '\n': 540 case '\r': 541 cp_newline(cp); /* fallthrough. */ 542 case ' ': 543 case '\t': 544 case '\v': 545 case '\f': 546 cp_get(cp); 547 break; 548 case '"': 549 case '\'': 550 return cp_string(cp); 551 case '/': 552 if (cp_get(cp) == '*') 553 cp_comment_c(cp); 554 else if (cp->c == '/') 555 cp_comment_cpp(cp); 556 else 557 return '/'; 558 break; 559 case '|': 560 if (cp_get(cp) != '|') 561 return '|'; 562 cp_get(cp); 563 return CTOK_OROR; 564 case '&': 565 if (cp_get(cp) != '&') 566 return '&'; 567 cp_get(cp); 568 return CTOK_ANDAND; 569 case '=': 570 if (cp_get(cp) != '=') 571 return '='; 572 cp_get(cp); 573 return CTOK_EQ; 574 case '!': 575 if (cp_get(cp) != '=') 576 return '!'; 577 cp_get(cp); 578 return CTOK_NE; 579 case '<': 580 if (cp_get(cp) == '=') 581 { 582 cp_get(cp); 583 return CTOK_LE; 584 } 585 else if (cp->c == '<') 586 { 587 cp_get(cp); 588 return CTOK_SHL; 589 } 590 return '<'; 591 case '>': 592 if (cp_get(cp) == '=') 593 { 594 cp_get(cp); 595 return CTOK_GE; 596 } 597 else if (cp->c == '>') 598 { 599 cp_get(cp); 600 return CTOK_SHR; 601 } 602 return '>'; 603 case '-': 604 if (cp_get(cp) != '>') 605 return '-'; 606 cp_get(cp); 607 return CTOK_DEREF; 608 case '$': 609 return cp_param(cp); 610 case '\0': 611 return CTOK_EOF; 612 default: 613 { 614 CPToken c = cp->c; 615 cp_get(cp); 616 return c; 617 } 618 } 619 } 620 } 621 622 static UC_NOINLINE CPToken cp_next(CPState *cp) 623 { 624 return (cp->tok = cp_next_(cp)); 625 } 626 627 /* -- C parser ------------------------------------------------------------ */ 628 629 /* Namespaces for resolving identifiers. */ 630 #define CPNS_DEFAULT \ 631 ((1u << CT_KW) | (1u << CT_TYPEDEF) | (1u << CT_FUNC) | (1u << CT_EXTERN) | (1u << CT_CONSTVAL)) 632 #define CPNS_STRUCT ((1u << CT_KW) | (1u << CT_STRUCT) | (1u << CT_ENUM)) 633 634 typedef CTypeID CPDeclIdx; /* Index into declaration stack. */ 635 typedef uint32_t CPscl; /* Storage class flags. */ 636 637 /* Type declaration context. */ 638 typedef struct CPDecl 639 { 640 CPDeclIdx top; /* Top of declaration stack. */ 641 CPDeclIdx pos; /* Insertion position in declaration chain. */ 642 CPDeclIdx specpos; /* Saved position for declaration specifier. */ 643 uint32_t mode; /* Declarator mode. */ 644 CPState *cp; /* C parser state. */ 645 CTypeID nameid; /* Existing typedef for declared identifier. */ 646 CTInfo attr; /* Attributes. */ 647 CTInfo fattr; /* Function attributes. */ 648 CTInfo specattr; /* Saved attributes. */ 649 CTInfo specfattr; /* Saved function attributes. */ 650 CTSize bits; /* Field size in bits (if any). */ 651 CType stack[CPARSE_MAX_DECLSTACK]; /* Type declaration stack. */ 652 uc_value_t *uv_name; 653 uc_value_t *uv_redir; 654 } CPDecl; 655 656 /* Forward declarations. */ 657 static CPscl cp_decl_spec(CPState *cp, CPDecl *decl, CPscl scl); 658 static void cp_declarator(CPState *cp, CPDecl *decl); 659 static CTypeID cp_decl_abstract(CPState *cp); 660 661 /* Initialize C parser state. Caller must set up: L, p, srcname, mode. */ 662 static void cp_init(CPState *cp) 663 { 664 cp->error = NULL; 665 cp->linenumber = 1; 666 cp->depth = 0; 667 cp->curpack = 0; 668 cp->packstack[0] = 255; 669 cp->pb.bpos = 0; 670 cp->pb.buf = 0; 671 cp->pb.size = 0; 672 cp->uv_str = NULL; 673 // lj_buf_init(cp->L, &cp->sb); 674 uc_assertCP(cp->p != NULL, "uninitialized cp->p"); 675 cp_get(cp); /* Read-ahead first char. */ 676 cp->tok = 0; 677 cp->tmask = CPNS_DEFAULT; 678 cp_next(cp); /* Read-ahead first token. */ 679 } 680 681 /* Cleanup C parser state. */ 682 static void cp_cleanup(CPState *cp) 683 { 684 // global_State *g = G(cp->L); 685 // lj_buf_free(g, &cp->sb); 686 ucv_put(cp->uv_str); 687 free(cp->pb.buf); 688 free(cp->error); 689 } 690 691 /* Check and consume optional token. */ 692 static int cp_opt(CPState *cp, CPToken tok) 693 { 694 if (cp->tok == tok) 695 { 696 cp_next(cp); 697 return 1; 698 } 699 return 0; 700 } 701 702 /* Check and consume token. */ 703 static void cp_check(CPState *cp, CPToken tok) 704 { 705 if (cp->tok != tok) 706 cp_err_token(cp, tok); 707 cp_next(cp); 708 } 709 710 /* Check if the next token may start a type declaration. */ 711 static int cp_istypedecl(CPState *cp) 712 { 713 if (cp->tok >= CTOK_FIRSTDECL && cp->tok <= CTOK_LASTDECL) 714 return 1; 715 if (cp->tok == CTOK_IDENT && ctype_istypedef(cp->ct->info)) 716 return 1; 717 if (cp->tok == '$') 718 return 1; 719 return 0; 720 } 721 722 /* -- Constant expression evaluator --------------------------------------- */ 723 724 /* Forward declarations. */ 725 static void cp_expr_unary(CPState *cp, CPValue *k); 726 static void cp_expr_sub(CPState *cp, CPValue *k, int pri); 727 728 /* Please note that type handling is very weak here. Most ops simply 729 ** assume integer operands. Accessors are only needed to compute types and 730 ** return synthetic values. The only purpose of the expression evaluator 731 ** is to compute the values of constant expressions one would typically 732 ** find in C header files. And again: this is NOT a validating C parser! 733 */ 734 735 /* Parse comma separated expression and return last result. */ 736 static void cp_expr_comma(CPState *cp, CPValue *k) 737 { 738 do 739 { 740 cp_expr_sub(cp, k, 0); 741 if (cp->error) 742 return; 743 } while (cp_opt(cp, ',')); 744 } 745 746 /* Parse sizeof/alignof operator. */ 747 static void cp_expr_sizeof(CPState *cp, CPValue *k, int wantsz) 748 { 749 CTSize sz; 750 CTInfo info; 751 if (cp_opt(cp, '(')) 752 { 753 if (cp_istypedecl(cp)) 754 k->id = cp_decl_abstract(cp); 755 else 756 cp_expr_comma(cp, k); 757 cp_check(cp, ')'); 758 } 759 else 760 { 761 cp_expr_unary(cp, k); 762 } 763 info = uc_ctype_info_raw(cp->cts, k->id, &sz); 764 if (wantsz) 765 { 766 if (sz != CTSIZE_INVALID) 767 k->u32 = sz; 768 else if (k->id != CTID_A_CCHAR) /* Special case for sizeof("string"). */ 769 { 770 cp_err(cp, "size of C type is unknown or too large"); 771 return; 772 } 773 } 774 else 775 { 776 k->u32 = 1u << ctype_align(info); 777 } 778 k->id = CTID_UINT32; /* Really size_t. */ 779 } 780 781 /* Parse prefix operators. */ 782 static void cp_expr_prefix(CPState *cp, CPValue *k) 783 { 784 if (cp->tok == CTOK_INTEGER) 785 { 786 *k = cp->val; 787 cp_next(cp); 788 } 789 else if (cp_opt(cp, '+')) 790 { 791 cp_expr_unary(cp, k); /* Nothing to do (well, integer promotion). */ 792 } 793 else if (cp_opt(cp, '-')) 794 { 795 cp_expr_unary(cp, k); 796 k->i32 = (int32_t)(~(uint32_t)k->i32 + 1); 797 } 798 else if (cp_opt(cp, '~')) 799 { 800 cp_expr_unary(cp, k); 801 k->i32 = ~k->i32; 802 } 803 else if (cp_opt(cp, '!')) 804 { 805 cp_expr_unary(cp, k); 806 k->i32 = !k->i32; 807 k->id = CTID_INT32; 808 } 809 else if (cp_opt(cp, '(')) 810 { 811 if (cp_istypedecl(cp)) 812 { /* Cast operator. */ 813 CTypeID id = cp_decl_abstract(cp); 814 cp_check(cp, ')'); 815 cp_expr_unary(cp, k); 816 k->id = id; /* No conversion performed. */ 817 } 818 else 819 { /* Sub-expression. */ 820 cp_expr_comma(cp, k); 821 cp_check(cp, ')'); 822 } 823 } 824 else if (cp_opt(cp, '*')) 825 { /* Indirection. */ 826 CType *ct; 827 cp_expr_unary(cp, k); 828 if (cp->error) 829 return; 830 ct = uc_ctype_rawref(cp->cts, k->id); 831 if (!ctype_ispointer(ct->info)) 832 { 833 cp_err_badidx(cp, ct); 834 return; 835 } 836 k->u32 = 0; 837 k->id = ctype_cid(ct->info); 838 } 839 else if (cp_opt(cp, '&')) 840 { /* Address operator. */ 841 cp_expr_unary(cp, k); 842 k->id = uc_ctype_intern(cp->cts, CTINFO(CT_PTR, CTALIGN_PTR + k->id), 843 CTSIZE_PTR); 844 } 845 else if (cp_opt(cp, CTOK_SIZEOF)) 846 { 847 cp_expr_sizeof(cp, k, 1); 848 } 849 else if (cp_opt(cp, CTOK_ALIGNOF)) 850 { 851 cp_expr_sizeof(cp, k, 0); 852 } 853 else if (cp->tok == CTOK_IDENT) 854 { 855 if (ctype_type(cp->ct->info) == CT_CONSTVAL) 856 { 857 k->u32 = cp->ct->size; 858 k->id = ctype_cid(cp->ct->info); 859 } 860 else if (ctype_type(cp->ct->info) == CT_EXTERN) 861 { 862 k->u32 = cp->val.id; 863 k->id = ctype_cid(cp->ct->info); 864 } 865 else if (ctype_type(cp->ct->info) == CT_FUNC) 866 { 867 k->u32 = cp->val.id; 868 k->id = cp->val.id; 869 } 870 else 871 { 872 goto err_expr; 873 } 874 cp_next(cp); 875 } 876 else if (cp->tok == CTOK_STRING) 877 { 878 CTSize sz = ucv_string_length(cp->uv_str); 879 while (cp_next(cp) == CTOK_STRING) 880 sz += ucv_string_length(cp->uv_str); 881 k->u32 = sz + 1; 882 k->id = CTID_A_CCHAR; 883 } 884 else 885 { 886 err_expr: 887 cp_errmsg(cp, cp->tok, "unexpected symbol"); 888 } 889 } 890 891 /* Parse postfix operators. */ 892 static void cp_expr_postfix(CPState *cp, CPValue *k) 893 { 894 for (;;) 895 { 896 CType *ct; 897 if (cp_opt(cp, '[')) 898 { /* Array/pointer index. */ 899 CPValue k2; 900 cp_expr_comma(cp, &k2); 901 ct = uc_ctype_rawref(cp->cts, k->id); 902 if (!ctype_ispointer(ct->info)) 903 { 904 ct = uc_ctype_rawref(cp->cts, k2.id); 905 if (!ctype_ispointer(ct->info)) { 906 cp_err_badidx(cp, ct); 907 return; 908 } 909 } 910 cp_check(cp, ']'); 911 k->u32 = 0; 912 } 913 else if (cp->tok == '.' || cp->tok == CTOK_DEREF) 914 { /* Struct deref. */ 915 CTSize ofs; 916 CType *fct; 917 ct = uc_ctype_rawref(cp->cts, k->id); 918 if (cp->tok == CTOK_DEREF) 919 { 920 if (!ctype_ispointer(ct->info)) { 921 cp_err_badidx(cp, ct); 922 return; 923 } 924 ct = uc_ctype_rawref(cp->cts, ctype_cid(ct->info)); 925 } 926 cp_next(cp); 927 if (cp->tok != CTOK_IDENT) { 928 cp_err_token(cp, CTOK_IDENT); 929 return; 930 } 931 if (!ctype_isstruct(ct->info) || ct->size == CTSIZE_INVALID || 932 !(fct = uc_ctype_getfield(cp->cts, ct, cp->uv_str, &ofs)) || 933 ctype_isbitfield(fct->info)) 934 { 935 uc_value_t *s = uc_ctype_repr(cp->uv_vm, ctype_typeid(cp->cts, ct), NULL); 936 cp_errmsg(cp, 0, "'%s' has no member named '%s'", ucv_string_get(s), ucv_string_get(cp->uv_str)); 937 ucv_put(s); 938 939 return; 940 } 941 ct = fct; 942 k->u32 = ctype_isconstval(ct->info) ? ct->size : 0; 943 cp_next(cp); 944 } 945 else 946 { 947 return; 948 } 949 k->id = ctype_cid(ct->info); 950 } 951 } 952 953 /* Parse infix operators. */ 954 static void cp_expr_infix(CPState *cp, CPValue *k, int pri) 955 { 956 CPValue k2; 957 k2.u32 = 0; 958 k2.id = 0; /* Silence the compiler. */ 959 for (;;) 960 { 961 switch (pri) 962 { 963 case 0: 964 if (cp_opt(cp, '?')) 965 { 966 CPValue k3; 967 cp_expr_comma(cp, &k2); /* Right-associative. */ 968 if (cp->error) 969 return; 970 cp_check(cp, ':'); 971 cp_expr_sub(cp, &k3, 0); 972 if (cp->error) 973 return; 974 k->u32 = k->u32 ? k2.u32 : k3.u32; 975 k->id = k2.id > k3.id ? k2.id : k3.id; 976 continue; 977 } 978 /* fallthrough */ 979 case 1: 980 if (cp_opt(cp, CTOK_OROR)) 981 { 982 cp_expr_sub(cp, &k2, 2); 983 if (cp->error) 984 return; 985 k->i32 = k->u32 || k2.u32; 986 k->id = CTID_INT32; 987 continue; 988 } 989 /* fallthrough */ 990 case 2: 991 if (cp_opt(cp, CTOK_ANDAND)) 992 { 993 cp_expr_sub(cp, &k2, 3); 994 if (cp->error) 995 return; 996 k->i32 = k->u32 && k2.u32; 997 k->id = CTID_INT32; 998 continue; 999 } 1000 /* fallthrough */ 1001 case 3: 1002 if (cp_opt(cp, '|')) 1003 { 1004 cp_expr_sub(cp, &k2, 4); 1005 if (cp->error) 1006 return; 1007 k->u32 = k->u32 | k2.u32; 1008 goto arith_result; 1009 } 1010 /* fallthrough */ 1011 case 4: 1012 if (cp_opt(cp, '^')) 1013 { 1014 cp_expr_sub(cp, &k2, 5); 1015 if (cp->error) 1016 return; 1017 k->u32 = k->u32 ^ k2.u32; 1018 goto arith_result; 1019 } 1020 /* fallthrough */ 1021 case 5: 1022 if (cp_opt(cp, '&')) 1023 { 1024 cp_expr_sub(cp, &k2, 6); 1025 if (cp->error) 1026 return; 1027 k->u32 = k->u32 & k2.u32; 1028 goto arith_result; 1029 } 1030 /* fallthrough */ 1031 case 6: 1032 if (cp_opt(cp, CTOK_EQ)) 1033 { 1034 cp_expr_sub(cp, &k2, 7); 1035 if (cp->error) 1036 return; 1037 k->i32 = k->u32 == k2.u32; 1038 k->id = CTID_INT32; 1039 continue; 1040 } 1041 else if (cp_opt(cp, CTOK_NE)) 1042 { 1043 cp_expr_sub(cp, &k2, 7); 1044 if (cp->error) 1045 return; 1046 k->i32 = k->u32 != k2.u32; 1047 k->id = CTID_INT32; 1048 continue; 1049 } 1050 /* fallthrough */ 1051 case 7: 1052 if (cp_opt(cp, '<')) 1053 { 1054 cp_expr_sub(cp, &k2, 8); 1055 if (cp->error) 1056 return; 1057 if (k->id == CTID_INT32 && k2.id == CTID_INT32) 1058 k->i32 = k->i32 < k2.i32; 1059 else 1060 k->i32 = k->u32 < k2.u32; 1061 k->id = CTID_INT32; 1062 continue; 1063 } 1064 else if (cp_opt(cp, '>')) 1065 { 1066 cp_expr_sub(cp, &k2, 8); 1067 if (cp->error) 1068 return; 1069 if (k->id == CTID_INT32 && k2.id == CTID_INT32) 1070 k->i32 = k->i32 > k2.i32; 1071 else 1072 k->i32 = k->u32 > k2.u32; 1073 k->id = CTID_INT32; 1074 continue; 1075 } 1076 else if (cp_opt(cp, CTOK_LE)) 1077 { 1078 cp_expr_sub(cp, &k2, 8); 1079 if (cp->error) 1080 return; 1081 if (k->id == CTID_INT32 && k2.id == CTID_INT32) 1082 k->i32 = k->i32 <= k2.i32; 1083 else 1084 k->i32 = k->u32 <= k2.u32; 1085 k->id = CTID_INT32; 1086 continue; 1087 } 1088 else if (cp_opt(cp, CTOK_GE)) 1089 { 1090 cp_expr_sub(cp, &k2, 8); 1091 if (cp->error) 1092 return; 1093 if (k->id == CTID_INT32 && k2.id == CTID_INT32) 1094 k->i32 = k->i32 >= k2.i32; 1095 else 1096 k->i32 = k->u32 >= k2.u32; 1097 k->id = CTID_INT32; 1098 continue; 1099 } 1100 /* fallthrough */ 1101 case 8: 1102 if (cp_opt(cp, CTOK_SHL)) 1103 { 1104 cp_expr_sub(cp, &k2, 9); 1105 if (cp->error) 1106 return; 1107 k->u32 = k->u32 << k2.u32; 1108 continue; 1109 } 1110 else if (cp_opt(cp, CTOK_SHR)) 1111 { 1112 cp_expr_sub(cp, &k2, 9); 1113 if (cp->error) 1114 return; 1115 if (k->id == CTID_INT32) 1116 k->i32 = k->i32 >> k2.i32; 1117 else 1118 k->u32 = k->u32 >> k2.u32; 1119 continue; 1120 } 1121 /* fallthrough */ 1122 case 9: 1123 if (cp_opt(cp, '+')) 1124 { 1125 cp_expr_sub(cp, &k2, 10); 1126 if (cp->error) 1127 return; 1128 k->u32 = k->u32 + k2.u32; 1129 arith_result: 1130 if (k2.id > k->id) 1131 k->id = k2.id; /* Trivial promotion to unsigned. */ 1132 continue; 1133 } 1134 else if (cp_opt(cp, '-')) 1135 { 1136 cp_expr_sub(cp, &k2, 10); 1137 if (cp->error) 1138 return; 1139 k->u32 = k->u32 - k2.u32; 1140 goto arith_result; 1141 } 1142 /* fallthrough */ 1143 case 10: 1144 if (cp_opt(cp, '*')) 1145 { 1146 cp_expr_unary(cp, &k2); 1147 if (cp->error) 1148 return; 1149 k->u32 = k->u32 * k2.u32; 1150 goto arith_result; 1151 } 1152 else if (cp_opt(cp, '/')) 1153 { 1154 cp_expr_unary(cp, &k2); 1155 if (cp->error) 1156 return; 1157 if (k2.id > k->id) 1158 k->id = k2.id; /* Trivial promotion to unsigned. */ 1159 if (k2.u32 == 0 || 1160 (k->id == CTID_INT32 && k->u32 == 0x80000000u && k2.i32 == -1)) 1161 { 1162 cp_err(cp, "invalid value"); 1163 return; 1164 } 1165 if (k->id == CTID_INT32) 1166 k->i32 = k->i32 / k2.i32; 1167 else 1168 k->u32 = k->u32 / k2.u32; 1169 continue; 1170 } 1171 else if (cp_opt(cp, '%')) 1172 { 1173 cp_expr_unary(cp, &k2); 1174 if (cp->error) 1175 return; 1176 if (k2.id > k->id) 1177 k->id = k2.id; /* Trivial promotion to unsigned. */ 1178 if (k2.u32 == 0 || 1179 (k->id == CTID_INT32 && k->u32 == 0x80000000u && k2.i32 == -1)) 1180 { 1181 cp_err(cp, "invalid value"); 1182 return; 1183 } 1184 if (k->id == CTID_INT32) 1185 k->i32 = k->i32 % k2.i32; 1186 else 1187 k->u32 = k->u32 % k2.u32; 1188 continue; 1189 } 1190 default: 1191 return; 1192 } 1193 } 1194 } 1195 1196 /* Parse and evaluate unary expression. */ 1197 static void cp_expr_unary(CPState *cp, CPValue *k) 1198 { 1199 if (++cp->depth > CPARSE_MAX_DECLDEPTH) 1200 { 1201 cp_err(cp, "chunk has too many syntax levels"); 1202 return; 1203 } 1204 cp_expr_prefix(cp, k); 1205 if (cp->error) 1206 return; 1207 cp_expr_postfix(cp, k); 1208 cp->depth--; 1209 } 1210 1211 /* Parse and evaluate sub-expression. */ 1212 static void cp_expr_sub(CPState *cp, CPValue *k, int pri) 1213 { 1214 cp_expr_unary(cp, k); 1215 if (cp->error) 1216 return; 1217 cp_expr_infix(cp, k, pri); 1218 } 1219 1220 /* Parse constant integer expression. */ 1221 static void cp_expr_kint(CPState *cp, CPValue *k) 1222 { 1223 CType *ct; 1224 cp_expr_sub(cp, k, 0); 1225 if (cp->error) 1226 return; 1227 ct = ctype_raw(cp->cts, k->id); 1228 if (!ctype_isinteger(ct->info)) 1229 { 1230 cp_err(cp, "invalid value"); 1231 return; 1232 } 1233 } 1234 1235 /* Parse (non-negative) size expression. */ 1236 static CTSize cp_expr_ksize(CPState *cp) 1237 { 1238 CPValue k; 1239 cp_expr_kint(cp, &k); 1240 if (cp->error) 1241 return CTSIZE_INVALID; 1242 if (k.u32 >= 0x80000000u) 1243 { 1244 cp_err(cp, "size of C type is unknown or too large"); 1245 return CTSIZE_INVALID; 1246 } 1247 return k.u32; 1248 } 1249 1250 /* -- Type declaration stack management ----------------------------------- */ 1251 1252 /* Add declaration element behind the insertion position. */ 1253 static CPDeclIdx cp_add(CPDecl *decl, CTInfo info, CTSize size) 1254 { 1255 CPDeclIdx top = decl->top; 1256 if (top >= CPARSE_MAX_DECLSTACK) 1257 { 1258 cp_err(decl->cp, "chunk has too many syntax levels"); 1259 return 0; 1260 } 1261 decl->stack[top].info = info; 1262 decl->stack[top].size = size; 1263 decl->stack[top].sib = 0; 1264 decl->stack[top].uv_name = NULL; 1265 // setgcrefnull(decl->stack[top].name); 1266 decl->stack[top].next = decl->stack[decl->pos].next; 1267 decl->stack[decl->pos].next = (CTypeID1)top; 1268 decl->top = top + 1; 1269 return top; 1270 } 1271 1272 /* Push declaration element before the insertion position. */ 1273 static CPDeclIdx cp_push(CPDecl *decl, CTInfo info, CTSize size) 1274 { 1275 return (decl->pos = cp_add(decl, info, size)); 1276 } 1277 1278 /* Push or merge attributes. */ 1279 static void cp_push_attributes(CPDecl *decl) 1280 { 1281 CType *ct = &decl->stack[decl->pos]; 1282 if (ctype_isfunc(ct->info)) 1283 { /* Ok to modify in-place. */ 1284 #if UC_TARGET_X86 1285 if ((decl->fattr & CTFP_CCONV)) 1286 ct->info = (ct->info & (CTMASK_NUM | CTF_VARARG | CTMASK_CID)) + 1287 (decl->fattr & ~CTMASK_CID); 1288 #endif 1289 } 1290 else 1291 { 1292 if ((decl->attr & CTFP_ALIGNED) && !(decl->mode & CPARSE_MODE_FIELD)) 1293 cp_push(decl, CTINFO(CT_ATTRIB, CTATTRIB(CTA_ALIGN)), 1294 ctype_align(decl->attr)); 1295 } 1296 } 1297 1298 /* Push unrolled type to declaration stack and merge qualifiers. */ 1299 static void cp_push_type(CPDecl *decl, CTypeID id) 1300 { 1301 CType *ct = ctype_get(decl->cp->cts, id); 1302 CTInfo info = ct->info; 1303 CTSize size = ct->size; 1304 switch (ctype_type(info)) 1305 { 1306 case CT_STRUCT: 1307 case CT_ENUM: 1308 cp_push(decl, CTINFO(CT_TYPEDEF, id), 0); /* Don't copy unique types. */ 1309 if ((decl->attr & CTF_QUAL)) 1310 { /* Push unmerged qualifiers. */ 1311 cp_push(decl, CTINFO(CT_ATTRIB, CTATTRIB(CTA_QUAL)), 1312 (decl->attr & CTF_QUAL)); 1313 decl->attr &= ~CTF_QUAL; 1314 } 1315 break; 1316 case CT_ATTRIB: 1317 if (ctype_isxattrib(info, CTA_QUAL)) 1318 decl->attr &= ~size; /* Remove redundant qualifiers. */ 1319 cp_push_type(decl, ctype_cid(info)); /* Unroll. */ 1320 cp_push(decl, info & ~CTMASK_CID, size); /* Copy type. */ 1321 break; 1322 case CT_ARRAY: 1323 if ((ct->info & (CTF_VECTOR | CTF_COMPLEX))) 1324 { 1325 info |= (decl->attr & CTF_QUAL); 1326 decl->attr &= ~CTF_QUAL; 1327 } 1328 cp_push_type(decl, ctype_cid(info)); /* Unroll. */ 1329 cp_push(decl, info & ~CTMASK_CID, size); /* Copy type. */ 1330 decl->stack[decl->pos].sib = 1; /* Mark as already checked and sized. */ 1331 /* Note: this is not copied to the ct->sib in the C type table. */ 1332 break; 1333 case CT_FUNC: 1334 /* Copy type, link parameters (shared). */ 1335 decl->stack[cp_push(decl, info, size)].sib = ct->sib; 1336 break; 1337 default: 1338 /* Copy type, merge common qualifiers. */ 1339 cp_push(decl, info | (decl->attr & CTF_QUAL), size); 1340 decl->attr &= ~CTF_QUAL; 1341 break; 1342 } 1343 } 1344 1345 /* Consume the declaration element chain and intern the C type. */ 1346 static CTypeID cp_decl_intern(CPState *cp, CPDecl *decl) 1347 { 1348 CTypeID id = 0; 1349 CPDeclIdx idx = 0; 1350 CTSize csize = CTSIZE_INVALID; 1351 CTSize cinfo = 0; 1352 do 1353 { 1354 CType *ct = &decl->stack[idx]; 1355 CTInfo info = ct->info; 1356 CTInfo size = ct->size; 1357 /* The cid is already part of info for copies of pointers/functions. */ 1358 idx = ct->next; 1359 if (ctype_istypedef(info)) 1360 { 1361 uc_assertCP(id == 0, "typedef not at toplevel"); 1362 id = ctype_cid(info); 1363 /* Always refetch info/size, since struct/enum may have been completed. */ 1364 cinfo = ctype_get(cp->cts, id)->info; 1365 csize = ctype_get(cp->cts, id)->size; 1366 uc_assertCP(ctype_isstruct(cinfo) || ctype_isenum(cinfo), 1367 "typedef of bad type"); 1368 } 1369 else if (ctype_isfunc(info)) 1370 { /* Intern function. */ 1371 CType *fct; 1372 CTypeID fid; 1373 CTypeID sib; 1374 if (id) 1375 { 1376 CType *refct = ctype_raw(cp->cts, id); 1377 /* Reject function or refarray return types. */ 1378 if (ctype_isfunc(refct->info) || ctype_isrefarray(refct->info)) { 1379 cp_err(cp, "invalid C type"); 1380 return 0; 1381 } 1382 } 1383 /* No intervening attributes allowed, skip forward. */ 1384 while (idx) 1385 { 1386 CType *ctn = &decl->stack[idx]; 1387 if (!ctype_isattrib(ctn->info)) 1388 break; 1389 idx = ctn->next; /* Skip attribute. */ 1390 } 1391 sib = ct->sib; /* Next line may reallocate the C type table. */ 1392 fid = uc_ctype_new(cp->cts, &fct); 1393 csize = CTSIZE_INVALID; 1394 fct->info = cinfo = info + id; 1395 fct->size = size; 1396 fct->sib = sib; 1397 id = fid; 1398 } 1399 else if (ctype_isattrib(info)) 1400 { 1401 if (ctype_isxattrib(info, CTA_QUAL)) 1402 cinfo |= size; 1403 else if (ctype_isxattrib(info, CTA_ALIGN)) 1404 CTF_INSERT(cinfo, ALIGN, size); 1405 id = uc_ctype_intern(cp->cts, info + id, size); 1406 /* Inherit csize/cinfo from original type. */ 1407 } 1408 else 1409 { 1410 if (ctype_isnum(info)) 1411 { /* Handle mode/vector-size attributes. */ 1412 uc_assertCP(id == 0, "number not at toplevel"); 1413 if (!(info & CTF_BOOL)) 1414 { 1415 CTSize msize = ctype_msizeP(decl->attr); 1416 CTSize vsize = ctype_vsizeP(decl->attr); 1417 if (msize && (!(info & CTF_FP) || (msize == 4 || msize == 8))) 1418 { 1419 CTSize malign = uc_fls(msize); 1420 if (malign > 4) 1421 malign = 4; /* Limit alignment. */ 1422 CTF_INSERT(info, ALIGN, malign); 1423 size = msize; /* Override size via mode. */ 1424 } 1425 if (vsize) 1426 { /* Vector size set? */ 1427 CTSize esize = uc_fls(size); 1428 if (vsize >= esize) 1429 { 1430 /* Intern the element type first. */ 1431 id = uc_ctype_intern(cp->cts, info, size); 1432 /* Then create a vector (array) with vsize alignment. */ 1433 size = (1u << vsize); 1434 if (vsize > 4) 1435 vsize = 4; /* Limit alignment. */ 1436 if (ctype_align(info) > vsize) 1437 vsize = ctype_align(info); 1438 info = CTINFO(CT_ARRAY, (info & CTF_QUAL) + CTF_VECTOR + 1439 CTALIGN(vsize)); 1440 } 1441 } 1442 } 1443 } 1444 else if (ctype_isptr(info)) 1445 { 1446 /* Reject pointer/ref to ref. */ 1447 if (id && ctype_isref(ctype_raw(cp->cts, id)->info)) { 1448 cp_err(cp, "invalid C type"); 1449 return 0; 1450 } 1451 if (ctype_isref(info)) 1452 { 1453 info &= ~CTF_VOLATILE; /* Refs are always const, never volatile. */ 1454 /* No intervening attributes allowed, skip forward. */ 1455 while (idx) 1456 { 1457 CType *ctn = &decl->stack[idx]; 1458 if (!ctype_isattrib(ctn->info)) 1459 break; 1460 idx = ctn->next; /* Skip attribute. */ 1461 } 1462 } 1463 } 1464 else if (ctype_isarray(info)) 1465 { /* Check for valid array size etc. */ 1466 if (ct->sib == 0) 1467 { /* Only check/size arrays not copied by unroll. */ 1468 if (ctype_isref(cinfo)) /* Reject arrays of refs. */ { 1469 cp_err(cp, "invalid C type"); 1470 return 0; 1471 } 1472 /* Reject VLS or unknown-sized types. */ 1473 if (ctype_isvltype(cinfo) || csize == CTSIZE_INVALID) { 1474 cp_err(cp, "size of C type is unknown or too large"); 1475 return 0; 1476 } 1477 /* a[] and a[?] keep their invalid size. */ 1478 if (size != CTSIZE_INVALID) 1479 { 1480 uint64_t xsz = (uint64_t)size * csize; 1481 if (xsz >= 0x80000000u) { 1482 cp_err(cp, "size of C type is unknown or too large"); 1483 return 0; 1484 } 1485 size = (CTSize)xsz; 1486 } 1487 } 1488 if ((cinfo & CTF_ALIGN) > (info & CTF_ALIGN)) /* Find max. align. */ 1489 info = (info & ~CTF_ALIGN) | (cinfo & CTF_ALIGN); 1490 info |= (cinfo & CTF_QUAL); /* Inherit qual. */ 1491 } 1492 else 1493 { 1494 uc_assertCP(ctype_isvoid(info), "bad ctype %08x", info); 1495 } 1496 csize = size; 1497 cinfo = info + id; 1498 id = uc_ctype_intern(cp->cts, info + id, size); 1499 } 1500 } while (idx); 1501 return id; 1502 } 1503 1504 /* -- C declaration parser ------------------------------------------------ */ 1505 1506 /* Reset declaration state to declaration specifier. */ 1507 static void cp_decl_reset(CPDecl *decl) 1508 { 1509 ucv_put(decl->uv_name); 1510 ucv_put(decl->uv_redir); 1511 1512 decl->pos = decl->specpos; 1513 decl->top = decl->specpos + 1; 1514 decl->stack[decl->specpos].next = 0; 1515 decl->attr = decl->specattr; 1516 decl->fattr = decl->specfattr; 1517 decl->uv_name = NULL; 1518 decl->uv_redir = NULL; 1519 } 1520 1521 /* Parse constant initializer. */ 1522 /* NYI: FP constants and strings as initializers. */ 1523 static CTypeID cp_decl_constinit(CPState *cp, CType **ctp, CTypeID ctypeid) 1524 { 1525 CType *ctt = ctype_get(cp->cts, ctypeid); 1526 CTInfo info; 1527 CTSize size; 1528 CPValue k; 1529 CTypeID constid; 1530 while (ctype_isattrib(ctt->info)) 1531 { /* Skip attributes. */ 1532 ctypeid = ctype_cid(ctt->info); /* Update ID, too. */ 1533 ctt = ctype_get(cp->cts, ctypeid); 1534 } 1535 info = ctt->info; 1536 size = ctt->size; 1537 if (!ctype_isinteger(info) || !(info & CTF_CONST) || size > 4) 1538 { 1539 cp_err(cp, "invalid C type"); 1540 return 0; 1541 } 1542 cp_check(cp, '='); 1543 if (cp->error) 1544 return 0; 1545 cp_expr_sub(cp, &k, 0); 1546 if (cp->error) 1547 return 0; 1548 constid = uc_ctype_new(cp->cts, ctp); 1549 (*ctp)->info = CTINFO(CT_CONSTVAL, CTF_CONST | ctypeid); 1550 k.u32 <<= 8 * (4 - size); 1551 if ((info & CTF_UNSIGNED)) 1552 k.u32 >>= 8 * (4 - size); 1553 else 1554 k.u32 = (uint32_t)((int32_t)k.u32 >> 8 * (4 - size)); 1555 (*ctp)->size = k.u32; 1556 return constid; 1557 } 1558 1559 /* Parse size in parentheses as part of attribute. */ 1560 static CTSize cp_decl_sizeattr(CPState *cp) 1561 { 1562 CTSize sz; 1563 uint32_t oldtmask = cp->tmask; 1564 cp->tmask = CPNS_DEFAULT; /* Required for expression evaluator. */ 1565 cp_check(cp, '('); 1566 if (cp->error) 1567 return 0; 1568 sz = cp_expr_ksize(cp); 1569 if (cp->error) 1570 return 0; 1571 cp->tmask = oldtmask; 1572 cp_check(cp, ')'); 1573 if (cp->error) 1574 return 0; 1575 return sz; 1576 } 1577 1578 /* Parse alignment attribute. */ 1579 static void cp_decl_align(CPState *cp, CPDecl *decl) 1580 { 1581 CTSize al = 4; /* Unspecified alignment is 16 bytes. */ 1582 if (cp->tok == '(') 1583 { 1584 al = cp_decl_sizeattr(cp); 1585 if (cp->error) 1586 return; 1587 al = al ? uc_fls(al) : 0; 1588 } 1589 CTF_INSERT(decl->attr, ALIGN, al); 1590 decl->attr |= CTFP_ALIGNED; 1591 } 1592 1593 /* Parse GCC asm("name") redirect. */ 1594 static void cp_decl_asm(CPState *cp, unused CPDecl *decl) 1595 { 1596 cp_next(cp); 1597 if (cp->error) 1598 return; 1599 cp_check(cp, '('); 1600 if (cp->error) 1601 return; 1602 if (cp->tok == CTOK_STRING) 1603 { 1604 uc_stringbuf_t *buf = ucv_stringbuf_new(); 1605 // GCstr *str = cp->str; 1606 ucv_stringbuf_addstr(buf, ucv_string_get(cp->uv_str), ucv_string_length(cp->uv_str)); 1607 while (cp_next(cp) == CTOK_STRING) 1608 { 1609 if (cp->error) 1610 return; 1611 ucv_stringbuf_addstr(buf, ucv_string_get(cp->uv_str), ucv_string_length(cp->uv_str)); 1612 } 1613 decl->uv_redir = ucv_stringbuf_finish(buf); 1614 } 1615 cp_check(cp, ')'); 1616 if (cp->error) 1617 return; 1618 } 1619 1620 /* Parse GCC __attribute__((mode(...))). */ 1621 static void cp_decl_mode(CPState *cp, CPDecl *decl) 1622 { 1623 cp_check(cp, '('); 1624 if (cp->tok == CTOK_IDENT) 1625 { 1626 const char *s = ucv_string_get(cp->uv_str); 1627 CTSize sz = 0, vlen = 0; 1628 if (s[0] == '_' && s[1] == '_') 1629 s += 2; 1630 if (*s == 'V') 1631 { 1632 s++; 1633 vlen = *s++ - ''; 1634 if (*s >= '' && *s <= '9') 1635 vlen = vlen * 10 + (*s++ - ''); 1636 } 1637 switch (*s++) 1638 { 1639 case 'Q': 1640 sz = 1; 1641 break; 1642 case 'H': 1643 sz = 2; 1644 break; 1645 case 'S': 1646 sz = 4; 1647 break; 1648 case 'D': 1649 sz = 8; 1650 break; 1651 case 'T': 1652 sz = 16; 1653 break; 1654 case 'O': 1655 sz = 32; 1656 break; 1657 default: 1658 goto bad_size; 1659 } 1660 if (*s == 'I' || *s == 'F') 1661 { 1662 CTF_INSERT(decl->attr, MSIZEP, sz); 1663 if (vlen) 1664 CTF_INSERT(decl->attr, VSIZEP, uc_fls(vlen * sz)); 1665 } 1666 bad_size: 1667 cp_next(cp); 1668 } 1669 cp_check(cp, ')'); 1670 } 1671 1672 /* Parse GCC __attribute__((...)). */ 1673 static void cp_decl_gccattribute(CPState *cp, CPDecl *decl) 1674 { 1675 cp_next(cp); 1676 if (cp->error) 1677 return; 1678 cp_check(cp, '('); 1679 if (cp->error) 1680 return; 1681 cp_check(cp, '('); 1682 if (cp->error) 1683 return; 1684 while (cp->tok != ')') 1685 { 1686 if (cp->tok == CTOK_IDENT) 1687 { 1688 uc_value_t *attrstr = ucv_get(cp->uv_str); 1689 cp_next(cp); 1690 if (cp->error) 1691 return; 1692 switch (uc_cparse_case(attrstr, 1693 "\007aligned" 1694 "\013__aligned__" 1695 "\006packed" 1696 "\012__packed__" 1697 "\004mode" 1698 "\010__mode__" 1699 "\013vector_size" 1700 "\017__vector_size__" 1701 #if UC_TARGET_X86 1702 "\007regparm" 1703 "\013__regparm__" 1704 "\005cdecl" 1705 "\011__cdecl__" 1706 "\010thiscall" 1707 "\014__thiscall__" 1708 "\010fastcall" 1709 "\014__fastcall__" 1710 "\007stdcall" 1711 "\013__stdcall__" 1712 "\012sseregparm" 1713 "\016__sseregparm__" 1714 #endif 1715 )) 1716 { 1717 case 0: 1718 case 1: /* aligned */ 1719 cp_decl_align(cp, decl); 1720 break; 1721 case 2: 1722 case 3: /* packed */ 1723 decl->attr |= CTFP_PACKED; 1724 break; 1725 case 4: 1726 case 5: /* mode */ 1727 cp_decl_mode(cp, decl); 1728 break; 1729 case 6: 1730 case 7: /* vector_size */ 1731 { 1732 CTSize vsize = cp_decl_sizeattr(cp); 1733 if (vsize) 1734 CTF_INSERT(decl->attr, VSIZEP, uc_fls(vsize)); 1735 } 1736 break; 1737 #if UC_TARGET_X86 1738 case 8: 1739 case 9: /* regparm */ 1740 CTF_INSERT(decl->fattr, REGPARM, cp_decl_sizeattr(cp)); 1741 decl->fattr |= CTFP_CCONV; 1742 break; 1743 case 10: 1744 case 11: /* cdecl */ 1745 CTF_INSERT(decl->fattr, CCONV, CTCC_CDECL); 1746 decl->fattr |= CTFP_CCONV; 1747 break; 1748 case 12: 1749 case 13: /* thiscall */ 1750 CTF_INSERT(decl->fattr, CCONV, CTCC_THISCALL); 1751 decl->fattr |= CTFP_CCONV; 1752 break; 1753 case 14: 1754 case 15: /* fastcall */ 1755 CTF_INSERT(decl->fattr, CCONV, CTCC_FASTCALL); 1756 decl->fattr |= CTFP_CCONV; 1757 break; 1758 case 16: 1759 case 17: /* stdcall */ 1760 CTF_INSERT(decl->fattr, CCONV, CTCC_STDCALL); 1761 decl->fattr |= CTFP_CCONV; 1762 break; 1763 case 18: 1764 case 19: /* sseregparm */ 1765 decl->fattr |= CTF_SSEREGPARM; 1766 decl->fattr |= CTFP_CCONV; 1767 break; 1768 #endif 1769 default: /* Skip all other attributes. */ 1770 ucv_put(attrstr); 1771 goto skip_attr; 1772 } 1773 ucv_put(attrstr); 1774 } 1775 else if (cp->tok >= CTOK_FIRSTDECL) 1776 { /* For __attribute((const)) etc. */ 1777 cp_next(cp); 1778 skip_attr: 1779 if (cp_opt(cp, '(')) 1780 { 1781 while (cp->tok != ')' && cp->tok != CTOK_EOF) 1782 { 1783 cp_next(cp); 1784 if (cp->error) 1785 return; 1786 } 1787 cp_check(cp, ')'); 1788 if (cp->error) 1789 return; 1790 } 1791 } 1792 else 1793 { 1794 break; 1795 } 1796 if (!cp_opt(cp, ',')) 1797 break; 1798 } 1799 cp_check(cp, ')'); 1800 if (cp->error) 1801 return; 1802 cp_check(cp, ')'); 1803 if (cp->error) 1804 return; 1805 } 1806 1807 /* Parse MSVC __declspec(...). */ 1808 static void cp_decl_msvcattribute(CPState *cp, CPDecl *decl) 1809 { 1810 cp_next(cp); 1811 if (cp->error) 1812 return; 1813 cp_check(cp, '('); 1814 if (cp->error) 1815 return; 1816 while (cp->tok == CTOK_IDENT) 1817 { 1818 uc_value_t *attrstr = ucv_get(cp->uv_str); 1819 cp_next(cp); 1820 if (cp->error) 1821 return; 1822 if (cp_str_is(attrstr, "align")) 1823 { 1824 cp_decl_align(cp, decl); 1825 if (cp->error) 1826 return; 1827 } 1828 else 1829 { /* Ignore all other attributes. */ 1830 if (cp_opt(cp, '(')) 1831 { 1832 while (cp->tok != ')' && cp->tok != CTOK_EOF) 1833 { 1834 cp_next(cp); 1835 if (cp->error) 1836 return; 1837 } 1838 cp_check(cp, ')'); 1839 if (cp->error) 1840 return; 1841 } 1842 } 1843 ucv_put(attrstr); 1844 } 1845 cp_check(cp, ')'); 1846 if (cp->error) 1847 return; 1848 } 1849 1850 /* Parse declaration attributes (and common qualifiers). */ 1851 static void cp_decl_attributes(CPState *cp, CPDecl *decl) 1852 { 1853 for (;;) 1854 { 1855 switch (cp->tok) 1856 { 1857 case CTOK_CONST: 1858 decl->attr |= CTF_CONST; 1859 break; 1860 case CTOK_VOLATILE: 1861 decl->attr |= CTF_VOLATILE; 1862 break; 1863 case CTOK_RESTRICT: 1864 break; /* Ignore. */ 1865 case CTOK_EXTENSION: 1866 break; /* Ignore. */ 1867 case CTOK_ATTRIBUTE: 1868 cp_decl_gccattribute(cp, decl); 1869 if (cp->error) 1870 return; 1871 continue; 1872 case CTOK_ASM: 1873 cp_decl_asm(cp, decl); 1874 if (cp->error) 1875 return; 1876 continue; 1877 case CTOK_DECLSPEC: 1878 cp_decl_msvcattribute(cp, decl); 1879 if (cp->error) 1880 return; 1881 continue; 1882 case CTOK_CCDECL: 1883 #if UC_TARGET_X86 1884 CTF_INSERT(decl->fattr, CCONV, cp->ct->size); 1885 decl->fattr |= CTFP_CCONV; 1886 #endif 1887 break; 1888 case CTOK_PTRSZ: 1889 #if UC_64 1890 CTF_INSERT(decl->attr, MSIZEP, cp->ct->size); 1891 #endif 1892 break; 1893 default: 1894 return; 1895 } 1896 cp_next(cp); 1897 } 1898 } 1899 1900 /* Parse struct/union/enum name. */ 1901 static CTypeID cp_struct_name(CPState *cp, CPDecl *sdecl, CTInfo info) 1902 { 1903 CTypeID sid; 1904 CType *ct; 1905 cp->tmask = CPNS_STRUCT; 1906 cp_next(cp); 1907 cp_decl_attributes(cp, sdecl); 1908 cp->tmask = CPNS_DEFAULT; 1909 if (cp->tok != '{') 1910 { 1911 if (cp->tok != CTOK_IDENT) 1912 cp_err_token(cp, CTOK_IDENT); 1913 if (cp->val.id) 1914 { /* Name of existing struct/union/enum. */ 1915 sid = cp->val.id; 1916 ct = cp->ct; 1917 if ((ct->info ^ info) & (CTMASK_NUM | CTF_UNION)) /* Wrong type. */ 1918 cp_errmsg(cp, 0, "attempt to redefine '%s'", ucv_string_get(ct->uv_name)); 1919 } 1920 else 1921 { /* Create named, incomplete struct/union/enum. */ 1922 if ((cp->mode & CPARSE_MODE_NOIMPLICIT)) 1923 cp_errmsg(cp, 0, "undeclared or implicit tag '%s'", ucv_string_get(cp->uv_str)); 1924 sid = uc_ctype_new(cp->cts, &ct); 1925 ct->info = info; 1926 ct->size = CTSIZE_INVALID; 1927 ctype_setname(ct, cp->uv_str); 1928 uc_ctype_addname(cp->cts, ct, sid); 1929 } 1930 cp_next(cp); 1931 } 1932 else 1933 { /* Create anonymous, incomplete struct/union/enum. */ 1934 sid = uc_ctype_new(cp->cts, &ct); 1935 ct->info = info; 1936 ct->size = CTSIZE_INVALID; 1937 } 1938 if (cp->tok == '{') 1939 { 1940 if (ct->size != CTSIZE_INVALID || ct->sib) 1941 cp_errmsg(cp, 0, "attempt to redefine '%s'", ucv_string_get(ct->uv_name)); 1942 ct->sib = 1; /* Indicate the type is currently being defined. */ 1943 } 1944 return sid; 1945 } 1946 1947 /* Determine field alignment. */ 1948 static CTSize cp_field_align(unused CPState *cp, unused CType *ct, CTInfo info) 1949 { 1950 CTSize align = ctype_align(info); 1951 #if (UC_TARGET_X86 && !UC_ABI_WIN) || (UC_TARGET_ARM && __APPLE__) 1952 /* The SYSV i386 and iOS ABIs limit alignment of non-vector fields to 2^2. */ 1953 if (align > 2 && !(info & CTFP_ALIGNED)) 1954 { 1955 if (ctype_isarray(info) && !(info & CTF_VECTOR)) 1956 { 1957 do 1958 { 1959 ct = ctype_rawchild(cp->cts, ct); 1960 info = ct->info; 1961 } while (ctype_isarray(info) && !(info & CTF_VECTOR)); 1962 } 1963 if (ctype_isnum(info) || ctype_isenum(info)) 1964 align = 2; 1965 } 1966 #endif 1967 return align; 1968 } 1969 1970 /* Layout struct/union fields. */ 1971 static void cp_struct_layout(CPState *cp, CTypeID sid, CTInfo sattr) 1972 { 1973 CTSize bofs = 0, bmaxofs = 0; /* Bit offset and max. bit offset. */ 1974 CTSize maxalign = ctype_align(sattr); 1975 CType *sct = ctype_get(cp->cts, sid); 1976 CTInfo sinfo = sct->info; 1977 CTypeID fieldid = sct->sib; 1978 while (fieldid) 1979 { 1980 CType *ct = ctype_get(cp->cts, fieldid); 1981 CTInfo attr = ct->size; /* Field declaration attributes (temp.). */ 1982 1983 if (ctype_isfield(ct->info) || 1984 (ctype_isxattrib(ct->info, CTA_SUBTYPE) && attr)) 1985 { 1986 CTSize align, amask; /* Alignment (pow2) and alignment mask (bits). */ 1987 CTSize sz; 1988 CTInfo info = uc_ctype_info(cp->cts, ctype_cid(ct->info), &sz); 1989 CTSize bsz, csz = 8 * sz; /* Field size and container size (in bits). */ 1990 sinfo |= (info & (CTF_QUAL | CTF_VLA)); /* Merge pseudo-qualifiers. */ 1991 1992 /* Check for size overflow and determine alignment. */ 1993 if (sz >= 0x20000000u || bofs + csz < bofs || (info & CTF_VLA)) 1994 { 1995 if (!(sz == CTSIZE_INVALID && ctype_isarray(info) && 1996 !(sinfo & CTF_UNION))) { 1997 cp_err(cp, "size of C type is unknown or too large"); 1998 return; 1999 } 2000 csz = sz = 0; /* Treat a[] and a[?] as zero-sized. */ 2001 } 2002 align = cp_field_align(cp, ct, info); 2003 if (((attr | sattr) & CTFP_PACKED) || 2004 ((attr & CTFP_ALIGNED) && ctype_align(attr) > align)) 2005 align = ctype_align(attr); 2006 if (cp->packstack[cp->curpack] < align) 2007 align = cp->packstack[cp->curpack]; 2008 if (align > maxalign) 2009 maxalign = align; 2010 amask = (8u << align) - 1; 2011 2012 bsz = ctype_bitcsz(ct->info); /* Bitfield size (temp.). */ 2013 if (bsz == CTBSZ_FIELD || !ctype_isfield(ct->info)) 2014 { 2015 bsz = csz; /* Regular fields or subtypes always fill the container. */ 2016 bofs = (bofs + amask) & ~amask; /* Start new aligned field. */ 2017 ct->size = (bofs >> 3); /* Store field offset. */ 2018 } 2019 else 2020 { /* Bitfield. */ 2021 if (bsz == 0 || (attr & CTFP_ALIGNED) || 2022 (!((attr | sattr) & CTFP_PACKED) && (bofs & amask) + bsz > csz)) 2023 bofs = (bofs + amask) & ~amask; /* Start new aligned field. */ 2024 2025 /* Prefer regular field over bitfield. */ 2026 if (bsz == csz && (bofs & amask) == 0) 2027 { 2028 ct->info = CTINFO(CT_FIELD, ctype_cid(ct->info)); 2029 ct->size = (bofs >> 3); /* Store field offset. */ 2030 } 2031 else 2032 { 2033 ct->info = CTINFO(CT_BITFIELD, 2034 (info & (CTF_QUAL | CTF_UNSIGNED | CTF_BOOL)) + 2035 (csz << (CTSHIFT_BITCSZ - 3)) + (bsz << CTSHIFT_BITBSZ)); 2036 #if UC_BE 2037 ct->info += ((csz - (bofs & (csz - 1)) - bsz) << CTSHIFT_BITPOS); 2038 #else 2039 ct->info += ((bofs & (csz - 1)) << CTSHIFT_BITPOS); 2040 #endif 2041 ct->size = ((bofs & ~(csz - 1)) >> 3); /* Store container offset. */ 2042 } 2043 } 2044 2045 /* Determine next offset or max. offset. */ 2046 if ((sinfo & CTF_UNION)) 2047 { 2048 if (bsz > bmaxofs) 2049 bmaxofs = bsz; 2050 } 2051 else 2052 { 2053 bofs += bsz; 2054 } 2055 } /* All other fields in the chain are already set up. */ 2056 2057 fieldid = ct->sib; 2058 } 2059 2060 /* Complete struct/union. */ 2061 sct->info = sinfo + CTALIGN(maxalign); 2062 bofs = (sinfo & CTF_UNION) ? bmaxofs : bofs; 2063 maxalign = (8u << maxalign) - 1; 2064 sct->size = (((bofs + maxalign) & ~maxalign) >> 3); 2065 } 2066 2067 /* Parse struct/union declaration. */ 2068 static CTypeID cp_decl_struct(CPState *cp, CPDecl *sdecl, CTInfo sinfo) 2069 { 2070 CTypeID sid = cp_struct_name(cp, sdecl, sinfo); 2071 if (cp->error) 2072 return 0; 2073 if (cp_opt(cp, '{')) 2074 { /* Struct/union definition. */ 2075 CTypeID lastid = sid; 2076 int lastdecl = 0; 2077 while (cp->tok != '}') 2078 { 2079 CPDecl decl = { 0 }; 2080 CPscl scl = cp_decl_spec(cp, &decl, CDF_STATIC); 2081 if (cp->error) 2082 return 0; 2083 decl.mode = scl ? CPARSE_MODE_DIRECT : CPARSE_MODE_DIRECT | CPARSE_MODE_ABSTRACT | CPARSE_MODE_FIELD; 2084 2085 for (;;) 2086 { 2087 CTypeID ctypeid; 2088 2089 if (lastdecl) 2090 { 2091 cp_err_token(cp, '}'); 2092 return 0; 2093 } 2094 2095 /* Parse field declarator. */ 2096 decl.bits = CTSIZE_INVALID; 2097 cp_declarator(cp, &decl); 2098 if (cp->error) 2099 return 0; 2100 ctypeid = cp_decl_intern(cp, &decl); 2101 if (cp->error) 2102 return 0; 2103 2104 if ((scl & CDF_STATIC)) 2105 { /* Static constant in struct namespace. */ 2106 CType *ct; 2107 CTypeID fieldid = cp_decl_constinit(cp, &ct, ctypeid); 2108 if (cp->error) 2109 return 0; 2110 ctype_get(cp->cts, lastid)->sib = fieldid; 2111 lastid = fieldid; 2112 ctype_setname(ct, decl.uv_name); 2113 } 2114 else 2115 { 2116 CTSize bsz = CTBSZ_FIELD; /* Temp. for layout phase. */ 2117 CType *ct; 2118 CTypeID fieldid = uc_ctype_new(cp->cts, &ct); /* Do this first. */ 2119 CType *tct = ctype_raw(cp->cts, ctypeid); 2120 2121 if (decl.bits == CTSIZE_INVALID) 2122 { /* Regular field. */ 2123 if (ctype_isarray(tct->info) && tct->size == CTSIZE_INVALID) 2124 lastdecl = 1; /* a[] or a[?] must be the last declared field. */ 2125 2126 /* Accept transparent struct/union/enum. */ 2127 if (!decl.uv_name) 2128 { 2129 if (!((ctype_isstruct(tct->info) && !(tct->info & CTF_VLA)) || 2130 ctype_isenum(tct->info))) 2131 { 2132 cp_err_token(cp, CTOK_IDENT); 2133 return 0; 2134 } 2135 ct->info = CTINFO(CT_ATTRIB, CTATTRIB(CTA_SUBTYPE) + ctypeid); 2136 ct->size = ctype_isstruct(tct->info) ? (decl.attr | 0x80000000u) : 0; /* For layout phase. */ 2137 goto add_field; 2138 } 2139 } 2140 else 2141 { /* Bitfield. */ 2142 bsz = decl.bits; 2143 if (!ctype_isinteger_or_bool(tct->info) || 2144 (bsz == 0 && decl.uv_name) || 8 * tct->size > CTBSZ_MAX || 2145 bsz > ((tct->info & CTF_BOOL) ? 1 : 8 * tct->size)) 2146 { 2147 cp_errmsg(cp, ':', "invalid value"); 2148 return 0; 2149 } 2150 } 2151 2152 /* Create temporary field for layout phase. */ 2153 ct->info = CTINFO(CT_FIELD, ctypeid + (bsz << CTSHIFT_BITCSZ)); 2154 ct->size = decl.attr; 2155 if (decl.uv_name) 2156 ctype_setname(ct, decl.uv_name); 2157 2158 add_field: 2159 ctype_get(cp->cts, lastid)->sib = fieldid; 2160 lastid = fieldid; 2161 } 2162 cp_decl_reset(&decl); 2163 if (!cp_opt(cp, ',')) 2164 break; 2165 } 2166 cp_check(cp, ';'); 2167 if (cp->error) 2168 return 0; 2169 } 2170 cp_check(cp, '}'); 2171 if (cp->error) 2172 return 0; 2173 ctype_get(cp->cts, lastid)->sib = 0; /* Drop sib = 1 for empty structs. */ 2174 cp_decl_attributes(cp, sdecl); /* Layout phase needs postfix attributes. */ 2175 if (cp->error) 2176 return 0; 2177 cp_struct_layout(cp, sid, sdecl->attr); 2178 } 2179 return sid; 2180 } 2181 2182 /* Parse enum declaration. */ 2183 static CTypeID cp_decl_enum(CPState *cp, CPDecl *sdecl) 2184 { 2185 CTypeID eid = cp_struct_name(cp, sdecl, CTINFO(CT_ENUM, CTID_VOID)); 2186 if (cp->error) 2187 return 0; 2188 CTInfo einfo = CTINFO(CT_ENUM, CTALIGN(2) + CTID_UINT32); 2189 CTSize esize = 4; /* Only 32 bit enums are supported. */ 2190 if (cp_opt(cp, '{')) 2191 { /* Enum definition. */ 2192 CPValue k; 2193 CTypeID lastid = eid; 2194 k.u32 = 0; 2195 k.id = CTID_INT32; 2196 do 2197 { 2198 uc_value_t *name = ucv_get(cp->uv_str); 2199 if (cp->tok != CTOK_IDENT) 2200 { 2201 cp_err_token(cp, CTOK_IDENT); 2202 return 0; 2203 } 2204 if (cp->val.id) 2205 { 2206 cp_errmsg(cp, 0, "attempt to redefine '%s'", ucv_string_get(name)); 2207 return 0; 2208 } 2209 cp_next(cp); 2210 if (cp_opt(cp, '=')) 2211 { 2212 cp_expr_kint(cp, &k); 2213 if (cp->error) 2214 return 0; 2215 if (k.id == CTID_UINT32) 2216 { 2217 /* C99 says that enum constants are always (signed) integers. 2218 ** But since unsigned constants like 0x80000000 are quite common, 2219 ** those are left as uint32_t. 2220 */ 2221 if (k.i32 >= 0) 2222 k.id = CTID_INT32; 2223 } 2224 else 2225 { 2226 /* OTOH it's common practice and even mandated by some ABIs 2227 ** that the enum type itself is unsigned, unless there are any 2228 ** negative constants. 2229 */ 2230 k.id = CTID_INT32; 2231 if (k.i32 < 0) 2232 einfo = CTINFO(CT_ENUM, CTALIGN(2) + CTID_INT32); 2233 } 2234 } 2235 /* Add named enum constant. */ 2236 { 2237 CType *ct; 2238 CTypeID constid = uc_ctype_new(cp->cts, &ct); 2239 ctype_get(cp->cts, lastid)->sib = constid; 2240 lastid = constid; 2241 ctype_setname(ct, name); 2242 ct->info = CTINFO(CT_CONSTVAL, CTF_CONST | k.id); 2243 ct->size = k.u32++; 2244 if (k.u32 == 0x80000000u) 2245 k.id = CTID_UINT32; 2246 uc_ctype_addname(cp->cts, ct, constid); 2247 } 2248 ucv_put(name); 2249 if (!cp_opt(cp, ',')) 2250 break; 2251 } while (cp->tok != '}'); /* Trailing ',' is ok. */ 2252 cp_check(cp, '}'); 2253 if (cp->error) 2254 return 0; 2255 /* Complete enum. */ 2256 ctype_get(cp->cts, eid)->info = einfo; 2257 ctype_get(cp->cts, eid)->size = esize; 2258 } 2259 return eid; 2260 } 2261 2262 /* Parse declaration specifiers. */ 2263 static CPscl cp_decl_spec(CPState *cp, CPDecl *decl, CPscl scl) 2264 { 2265 uint32_t cds = 0, sz = 0; 2266 CTypeID tdef = 0; 2267 2268 decl->cp = cp; 2269 decl->mode = cp->mode; 2270 decl->uv_name = NULL; 2271 decl->uv_redir = NULL; 2272 decl->attr = 0; 2273 decl->fattr = 0; 2274 decl->pos = decl->top = 0; 2275 decl->stack[0].next = 0; 2276 2277 for (;;) 2278 { /* Parse basic types. */ 2279 cp_decl_attributes(cp, decl); 2280 if (cp->error) 2281 return 0; 2282 if (cp->tok >= CTOK_FIRSTDECL && cp->tok <= CTOK_LASTDECLFLAG) 2283 { 2284 uint32_t cbit; 2285 if (cp->ct->size) 2286 { 2287 if (sz) 2288 goto end_decl; 2289 sz = cp->ct->size; 2290 } 2291 cbit = (1u << (cp->tok - CTOK_FIRSTDECL)); 2292 cds = cds | cbit | ((cbit & cds & CDF_LONG) << 1); 2293 if (cp->tok >= CTOK_FIRSTSCL) 2294 { 2295 if (!(scl & cbit)) 2296 { 2297 cp_errmsg(cp, cp->tok, "bad storage class"); 2298 return 0; 2299 } 2300 } 2301 else if (tdef) 2302 { 2303 goto end_decl; 2304 } 2305 cp_next(cp); 2306 continue; 2307 } 2308 if (sz || tdef || 2309 (cds & (CDF_SHORT | CDF_LONG | CDF_SIGNED | CDF_UNSIGNED | CDF_COMPLEX))) 2310 break; 2311 switch (cp->tok) 2312 { 2313 case CTOK_STRUCT: 2314 tdef = cp_decl_struct(cp, decl, CTINFO(CT_STRUCT, 0)); 2315 if (cp->error) 2316 return 0; 2317 continue; 2318 case CTOK_UNION: 2319 tdef = cp_decl_struct(cp, decl, CTINFO(CT_STRUCT, CTF_UNION)); 2320 if (cp->error) 2321 return 0; 2322 continue; 2323 case CTOK_ENUM: 2324 tdef = cp_decl_enum(cp, decl); 2325 if (cp->error) 2326 return 0; 2327 continue; 2328 case CTOK_IDENT: 2329 if (ctype_istypedef(cp->ct->info)) 2330 { 2331 tdef = ctype_cid(cp->ct->info); /* Get typedef. */ 2332 cp_next(cp); 2333 continue; 2334 } 2335 break; 2336 case '$': 2337 tdef = cp->val.id; 2338 cp_next(cp); 2339 continue; 2340 default: 2341 break; 2342 } 2343 break; 2344 } 2345 end_decl: 2346 2347 if ((cds & CDF_COMPLEX)) /* Use predefined complex types. */ 2348 tdef = sz == 4 ? CTID_COMPLEX_FLOAT : CTID_COMPLEX_DOUBLE; 2349 2350 if (tdef) 2351 { 2352 cp_push_type(decl, tdef); 2353 } 2354 else if ((cds & CDF_VOID)) 2355 { 2356 cp_push(decl, CTINFO(CT_VOID, (decl->attr & CTF_QUAL)), CTSIZE_INVALID); 2357 decl->attr &= ~CTF_QUAL; 2358 } 2359 else 2360 { 2361 /* Determine type info and size. */ 2362 CTInfo info = CTINFO(CT_NUM, (cds & CDF_UNSIGNED) ? CTF_UNSIGNED : 0); 2363 if ((cds & CDF_BOOL)) 2364 { 2365 if ((cds & ~(CDF_SCL | CDF_BOOL | CDF_INT | CDF_SIGNED | CDF_UNSIGNED))) 2366 { 2367 cp_errmsg(cp, 0, "invalid C type"); 2368 return 0; 2369 } 2370 info |= CTF_BOOL; 2371 if (!(cds & CDF_SIGNED)) 2372 info |= CTF_UNSIGNED; 2373 if (!sz) 2374 { 2375 sz = 1; 2376 } 2377 } 2378 else if ((cds & CDF_FP)) 2379 { 2380 info = CTINFO(CT_NUM, CTF_FP); 2381 if ((cds & CDF_LONG)) 2382 sz = sizeof(long double); 2383 } 2384 else if ((cds & CDF_CHAR)) 2385 { 2386 if ((cds & (CDF_CHAR | CDF_SIGNED | CDF_UNSIGNED)) == CDF_CHAR) 2387 info |= CTF_UCHAR; /* Handle platforms where char is unsigned. */ 2388 } 2389 else if ((cds & CDF_SHORT)) 2390 { 2391 sz = sizeof(short); 2392 } 2393 else if ((cds & CDF_LONGLONG)) 2394 { 2395 sz = 8; 2396 } 2397 else if ((cds & CDF_LONG)) 2398 { 2399 info |= CTF_LONG; 2400 sz = sizeof(long); 2401 } 2402 else if (!sz) 2403 { 2404 if (!(cds & (CDF_SIGNED | CDF_UNSIGNED))) 2405 { 2406 cp_errmsg(cp, cp->tok, "declaration specifier expected"); 2407 return 0; 2408 } 2409 sz = sizeof(int); 2410 } 2411 uc_assertCP(sz != 0, "basic ctype with zero size"); 2412 info += CTALIGN(uc_fls(sz)); /* Use natural alignment. */ 2413 info += (decl->attr & CTF_QUAL); /* Merge qualifiers. */ 2414 cp_push(decl, info, sz); 2415 decl->attr &= ~CTF_QUAL; 2416 } 2417 decl->specpos = decl->pos; 2418 decl->specattr = decl->attr; 2419 decl->specfattr = decl->fattr; 2420 return (cds & CDF_SCL); /* Return storage class. */ 2421 } 2422 2423 /* Parse array declaration. */ 2424 static void cp_decl_array(CPState *cp, CPDecl *decl) 2425 { 2426 CTInfo info = CTINFO(CT_ARRAY, 0); 2427 CTSize nelem = CTSIZE_INVALID; /* Default size for a[] or a[?]. */ 2428 cp_decl_attributes(cp, decl); 2429 if (cp->error) 2430 return; 2431 if (cp_opt(cp, '?')) 2432 info |= CTF_VLA; /* Create variable-length array a[?]. */ 2433 else if (cp->tok != ']') 2434 { 2435 nelem = cp_expr_ksize(cp); 2436 if (cp->error) 2437 return; 2438 } 2439 cp_check(cp, ']'); 2440 cp_add(decl, info, nelem); 2441 } 2442 2443 /* Parse function declaration. */ 2444 static void cp_decl_func(CPState *cp, CPDecl *fdecl) 2445 { 2446 CTSize nargs = 0; 2447 CTInfo info = CTINFO(CT_FUNC, 0); 2448 CTypeID lastid = 0, anchor = 0; 2449 if (cp->tok != ')') 2450 { 2451 do 2452 { 2453 CPDecl decl = {0}; 2454 CTypeID ctypeid, fieldid; 2455 CType *ct; 2456 if (cp_opt(cp, '.')) 2457 { /* Vararg function. */ 2458 cp_check(cp, '.'); /* Workaround for the minimalistic lexer. */ 2459 cp_check(cp, '.'); 2460 info |= CTF_VARARG; 2461 break; 2462 } 2463 cp_decl_spec(cp, &decl, CDF_REGISTER); 2464 if (cp->error) 2465 return; 2466 decl.mode = CPARSE_MODE_DIRECT | CPARSE_MODE_ABSTRACT; 2467 cp_declarator(cp, &decl); 2468 if (cp->error) 2469 return; 2470 ctypeid = cp_decl_intern(cp, &decl); 2471 if (cp->error) 2472 return; 2473 ct = ctype_raw(cp->cts, ctypeid); 2474 if (ctype_isvoid(ct->info)) 2475 break; 2476 else if (ctype_isrefarray(ct->info)) 2477 ctypeid = uc_ctype_intern(cp->cts, 2478 CTINFO(CT_PTR, CTALIGN_PTR | ctype_cid(ct->info)), CTSIZE_PTR); 2479 else if (ctype_isfunc(ct->info)) 2480 ctypeid = uc_ctype_intern(cp->cts, 2481 CTINFO(CT_PTR, CTALIGN_PTR | ctypeid), CTSIZE_PTR); 2482 /* Add new parameter. */ 2483 fieldid = uc_ctype_new(cp->cts, &ct); 2484 if (anchor) 2485 ctype_get(cp->cts, lastid)->sib = fieldid; 2486 else 2487 anchor = fieldid; 2488 lastid = fieldid; 2489 if (decl.uv_name) 2490 ctype_setname(ct, decl.uv_name); 2491 ct->info = CTINFO(CT_FIELD, ctypeid); 2492 ct->size = nargs++; 2493 cp_decl_reset(&decl); 2494 } while (cp_opt(cp, ',')); 2495 } 2496 cp_check(cp, ')'); 2497 if (cp->error) 2498 return; 2499 if (cp_opt(cp, '{')) 2500 { /* Skip function definition. */ 2501 int level = 1; 2502 cp->mode |= CPARSE_MODE_SKIP; 2503 for (;;) 2504 { 2505 if (cp->tok == '{') 2506 level++; 2507 else if (cp->tok == '}' && --level == 0) 2508 break; 2509 else if (cp->tok == CTOK_EOF) { 2510 cp_err_token(cp, '}'); 2511 return; 2512 } 2513 cp_next(cp); 2514 } 2515 cp->mode &= ~CPARSE_MODE_SKIP; 2516 cp->tok = ';'; /* Ok for cp_decl_multi(), error in cp_decl_single(). */ 2517 } 2518 info |= (fdecl->fattr & ~CTMASK_CID); 2519 fdecl->fattr = 0; 2520 fdecl->stack[cp_add(fdecl, info, nargs)].sib = anchor; 2521 } 2522 2523 /* Parse declarator. */ 2524 static void cp_declarator(CPState *cp, CPDecl *decl) 2525 { 2526 if (++cp->depth > CPARSE_MAX_DECLDEPTH) 2527 { 2528 cp_err(cp, "chunk has too many syntax levels"); 2529 return; 2530 } 2531 2532 for (;;) 2533 { /* Head of declarator. */ 2534 if (cp_opt(cp, '*')) 2535 { /* Pointer. */ 2536 CTSize sz; 2537 CTInfo info; 2538 cp_decl_attributes(cp, decl); 2539 if (cp->error) 2540 return; 2541 sz = CTSIZE_PTR; 2542 info = CTINFO(CT_PTR, CTALIGN_PTR); 2543 #if UC_64 2544 if (ctype_msizeP(decl->attr) == 4) 2545 { 2546 sz = 4; 2547 info = CTINFO(CT_PTR, CTALIGN(2)); 2548 } 2549 #endif 2550 info += (decl->attr & (CTF_QUAL | CTF_REF)); 2551 decl->attr &= ~(CTF_QUAL | (CTMASK_MSIZEP << CTSHIFT_MSIZEP)); 2552 cp_push(decl, info, sz); 2553 } 2554 else if (cp_opt(cp, '&') || cp_opt(cp, CTOK_ANDAND)) 2555 { /* Reference. */ 2556 decl->attr &= ~(CTF_QUAL | (CTMASK_MSIZEP << CTSHIFT_MSIZEP)); 2557 cp_push(decl, CTINFO_REF(0), CTSIZE_PTR); 2558 } 2559 else 2560 { 2561 break; 2562 } 2563 } 2564 2565 if (cp_opt(cp, '(')) 2566 { /* Inner declarator. */ 2567 CPDeclIdx pos; 2568 cp_decl_attributes(cp, decl); 2569 if (cp->error) 2570 return; 2571 /* Resolve ambiguity between inner declarator and 1st function parameter. */ 2572 if ((decl->mode & CPARSE_MODE_ABSTRACT) && 2573 (cp->tok == ')' || cp_istypedecl(cp))) 2574 goto func_decl; 2575 pos = decl->pos; 2576 cp_declarator(cp, decl); 2577 if (cp->error) 2578 return; 2579 cp_check(cp, ')'); 2580 if (cp->error) 2581 return; 2582 decl->pos = pos; 2583 } 2584 else if (cp->tok == CTOK_IDENT) 2585 { /* Direct declarator. */ 2586 if (!(decl->mode & CPARSE_MODE_DIRECT)) 2587 { 2588 cp_err_token(cp, CTOK_EOF); 2589 return; 2590 } 2591 decl->uv_name = ucv_get(cp->uv_str); 2592 decl->nameid = cp->val.id; 2593 cp_next(cp); 2594 } 2595 else 2596 { /* Abstract declarator. */ 2597 if (!(decl->mode & CPARSE_MODE_ABSTRACT)) 2598 { 2599 cp_err_token(cp, CTOK_IDENT); 2600 return; 2601 } 2602 } 2603 2604 for (;;) 2605 { /* Tail of declarator. */ 2606 if (cp_opt(cp, '[')) 2607 { /* Array. */ 2608 cp_decl_array(cp, decl); 2609 if (cp->error) 2610 return; 2611 } 2612 else if (cp_opt(cp, '(')) 2613 { /* Function. */ 2614 func_decl: 2615 cp_decl_func(cp, decl); 2616 if (cp->error) 2617 return; 2618 } 2619 else 2620 { 2621 break; 2622 } 2623 } 2624 2625 if ((decl->mode & CPARSE_MODE_FIELD) && cp_opt(cp, ':')) /* Field width. */ 2626 { 2627 decl->bits = cp_expr_ksize(cp); 2628 if (cp->error) 2629 return; 2630 } 2631 2632 /* Process postfix attributes. */ 2633 cp_decl_attributes(cp, decl); 2634 if (cp->error) 2635 return; 2636 cp_push_attributes(decl); 2637 2638 cp->depth--; 2639 } 2640 2641 /* Parse an abstract type declaration and return it's C type ID. */ 2642 static CTypeID cp_decl_abstract(CPState *cp) 2643 { 2644 CPDecl decl = {0}; 2645 cp_decl_spec(cp, &decl, 0); 2646 if (cp->error) 2647 return 0; 2648 decl.mode = CPARSE_MODE_ABSTRACT; 2649 cp_declarator(cp, &decl); 2650 if (cp->error) 2651 return 0; 2652 CTypeID rv = cp_decl_intern(cp, &decl); 2653 if (cp->error) 2654 return 0; 2655 cp_decl_reset(&decl); 2656 return rv; 2657 } 2658 2659 /* Handle pragmas. */ 2660 static void cp_pragma(CPState *cp, size_t pragmaline) 2661 { 2662 cp_next(cp); 2663 if (cp->error) 2664 return; 2665 if (cp->tok == CTOK_IDENT && cp_str_is(cp->uv_str, "pack")) 2666 { 2667 cp_next(cp); 2668 if (cp->error) 2669 return; 2670 cp_check(cp, '('); 2671 if (cp->error) 2672 return; 2673 if (cp->tok == CTOK_IDENT) 2674 { 2675 if (cp_str_is(cp->uv_str, "push")) 2676 { 2677 if (cp->curpack < CPARSE_MAX_PACKSTACK - 1) 2678 { 2679 cp->packstack[cp->curpack + 1] = cp->packstack[cp->curpack]; 2680 cp->curpack++; 2681 } 2682 else 2683 { 2684 cp_errmsg(cp, cp->tok, "chunk has too many syntax levels"); 2685 return; 2686 } 2687 } 2688 else if (cp_str_is(cp->uv_str, "pop")) 2689 { 2690 if (cp->curpack > 0) 2691 cp->curpack--; 2692 } 2693 else 2694 { 2695 cp_errmsg(cp, cp->tok, "unexpected symbol"); 2696 return; 2697 } 2698 cp_next(cp); 2699 if (cp->error) 2700 return; 2701 if (!cp_opt(cp, ',')) 2702 goto end_pack; 2703 } 2704 if (cp->tok == CTOK_INTEGER) 2705 { 2706 cp->packstack[cp->curpack] = cp->val.u32 ? uc_fls(cp->val.u32) : 0; 2707 cp_next(cp); 2708 if (cp->error) 2709 return; 2710 } 2711 else 2712 { 2713 cp->packstack[cp->curpack] = 255; 2714 } 2715 end_pack: 2716 cp_check(cp, ')'); 2717 if (cp->error) 2718 return; 2719 } 2720 else 2721 { /* Ignore all other pragmas. */ 2722 while (cp->tok != CTOK_EOF && cp->linenumber == pragmaline) 2723 cp_next(cp); 2724 } 2725 } 2726 2727 /* Handle line number. */ 2728 static void cp_line(CPState *cp, size_t hashline) 2729 { 2730 size_t newline = cp->val.u32; 2731 /* TODO: Handle file name and include it in error messages. */ 2732 while (cp->tok != CTOK_EOF && cp->linenumber == hashline) 2733 { 2734 cp_next(cp); 2735 if (cp->error) 2736 return; 2737 } 2738 cp->linenumber = newline; 2739 } 2740 2741 /* Parse multiple C declarations of types or extern identifiers. */ 2742 static void cp_decl_multi(CPState *cp) 2743 { 2744 int first = 1; 2745 while (cp->tok != CTOK_EOF) 2746 { 2747 CPDecl decl = {0}; 2748 CPscl scl; 2749 if (cp_opt(cp, ';')) 2750 { /* Skip empty statements. */ 2751 first = 0; 2752 continue; 2753 } 2754 if (cp->tok == '#') 2755 { /* Workaround, since we have no preprocessor, yet. */ 2756 size_t hashline = cp->linenumber; 2757 CPToken tok = cp_next(cp); 2758 if (cp->error) 2759 return; 2760 if (tok == CTOK_INTEGER) 2761 { 2762 cp_line(cp, hashline); 2763 if (cp->error) 2764 return; 2765 continue; 2766 } 2767 else if (tok == CTOK_IDENT && cp_str_is(cp->uv_str, "line")) 2768 { 2769 if (cp_next(cp) != CTOK_INTEGER) { 2770 cp_err_token(cp, tok); 2771 return; 2772 } 2773 cp_line(cp, hashline); 2774 if (cp->error) 2775 return; 2776 continue; 2777 } 2778 else if (tok == CTOK_IDENT && cp_str_is(cp->uv_str, "pragma")) 2779 { 2780 cp_pragma(cp, hashline); 2781 if (cp->error) 2782 return; 2783 continue; 2784 } 2785 else 2786 { 2787 cp_errmsg(cp, cp->tok, "unexpected symbol"); 2788 return; 2789 } 2790 } 2791 scl = cp_decl_spec(cp, &decl, CDF_TYPEDEF | CDF_EXTERN | CDF_STATIC); 2792 if (cp->error) 2793 return; 2794 if ((cp->tok == ';' || cp->tok == CTOK_EOF) && 2795 ctype_istypedef(decl.stack[0].info)) 2796 { 2797 CTInfo info = ctype_rawchild(cp->cts, &decl.stack[0])->info; 2798 if (ctype_isstruct(info) || ctype_isenum(info)) 2799 goto decl_end; /* Accept empty declaration of struct/union/enum. */ 2800 } 2801 for (;;) 2802 { 2803 CTypeID ctypeid; 2804 cp_declarator(cp, &decl); 2805 if (cp->error) 2806 return; 2807 ctypeid = cp_decl_intern(cp, &decl); 2808 if (cp->error) 2809 return; 2810 if (decl.uv_name) 2811 { 2812 if (decl.nameid) 2813 { /* Redeclaration detected - check compatibility. */ 2814 CType *existing_ct = ctype_get(cp->cts, decl.nameid); 2815 CType *new_ct = ctype_get(cp->cts, ctypeid); 2816 2817 /* Skip extern and attributes to get the actual function type. */ 2818 CType *existing_func = existing_ct; 2819 while (ctype_isextern(existing_func->info) || ctype_isattrib(existing_func->info)) 2820 existing_func = ctype_rawchild(cp->cts, existing_func); 2821 2822 /* Unwrap CT_FUNC if needed. */ 2823 CType *new_func = new_ct; 2824 if (ctype_isptr(new_ct->info)) 2825 new_func = ctype_rawchild(cp->cts, new_ct); 2826 2827 if (ctype_isfunc(existing_func->info) && ctype_isfunc(new_func->info) && 2828 ctype_func_is_equiv(cp->cts, existing_func, new_func)) 2829 { /* Compatible: reuse existing type. */ 2830 if (!existing_ct->uv_name) 2831 ctype_setname(existing_ct, decl.uv_name); 2832 ctypeid = decl.nameid; /* Use existing ID */ 2833 cp->val.id = ctypeid; /* Update parser state */ 2834 /* Add to hash table with the name. */ 2835 uc_ctype_addname(cp->cts, existing_ct, ctypeid); 2836 /* Record function type ID if func_ids vector is provided */ 2837 if (cp->func_ids && (ctype_isfunc(existing_ct->info) || 2838 (ctype_isextern(existing_ct->info) && ctype_isfunc(ctype_get(cp->cts, ctype_cid(existing_ct->info))->info)))) { 2839 uc_vector_push(cp->func_ids, ctypeid); 2840 } 2841 } 2842 else 2843 { /* Incompatible redeclaration. */ 2844 cp_errmsg(cp, 0, "redeclaration of '%s' as different type", 2845 ucv_string_get(decl.uv_name)); 2846 } 2847 } 2848 else 2849 { /* New declaration. */ 2850 CType *ct; 2851 CTypeID id; 2852 if ((scl & CDF_TYPEDEF)) 2853 { /* Create new typedef. */ 2854 id = uc_ctype_new(cp->cts, &ct); 2855 ct->info = CTINFO(CT_TYPEDEF, ctypeid); 2856 goto noredir; 2857 } 2858 else if (ctype_isfunc(ctype_get(cp->cts, ctypeid)->info)) 2859 { 2860 /* Treat both static and extern function declarations as extern. */ 2861 ct = ctype_get(cp->cts, ctypeid); 2862 /* We always get new anonymous functions (typedefs are copied). */ 2863 uc_assertCP(ct->uv_name == NULL, "unexpected named function"); 2864 id = ctypeid; /* Just name it. */ 2865 } 2866 else if ((scl & CDF_STATIC)) 2867 { /* Accept static constants. */ 2868 id = cp_decl_constinit(cp, &ct, ctypeid); 2869 goto noredir; 2870 } 2871 else 2872 { /* External references have extern or no storage class. */ 2873 id = uc_ctype_new(cp->cts, &ct); 2874 ct->info = CTINFO(CT_EXTERN, ctypeid); 2875 } 2876 if (decl.uv_redir) 2877 { /* Add attribute for redirected symbol name. */ 2878 CType *cta; 2879 CTypeID aid = uc_ctype_new(cp->cts, &cta); 2880 ct = ctype_get(cp->cts, id); /* Table may have been reallocated. */ 2881 cta->info = CTINFO(CT_ATTRIB, CTATTRIB(CTA_REDIR)); 2882 cta->sib = ct->sib; 2883 ct->sib = aid; 2884 ctype_setname(cta, decl.uv_redir); 2885 } 2886 noredir: 2887 ctype_setname(ct, decl.uv_name); 2888 uc_ctype_addname(cp->cts, ct, id); 2889 2890 /* Record function type ID if func_ids vector is provided */ 2891 if (cp->func_ids && (ctype_isfunc(ct->info) || 2892 (ctype_isextern(ct->info) && ctype_isfunc(ctype_get(cp->cts, ctype_cid(ct->info))->info)))) { 2893 uc_vector_push(cp->func_ids, id); 2894 } 2895 } 2896 } 2897 cp_decl_reset(&decl); 2898 if (!cp_opt(cp, ',')) 2899 break; 2900 } 2901 decl_end: 2902 if (cp->tok == CTOK_EOF && first) 2903 break; /* May omit ';' for 1 decl. */ 2904 first = 0; 2905 cp_check(cp, ';'); 2906 } 2907 } 2908 2909 /* Parse a single C type declaration. */ 2910 static void cp_decl_single(CPState *cp) 2911 { 2912 CPDecl decl = {0}; 2913 cp_decl_spec(cp, &decl, 0); 2914 if (cp->error) 2915 return; 2916 cp_declarator(cp, &decl); 2917 if (cp->error) 2918 return; 2919 cp->val.id = cp_decl_intern(cp, &decl); 2920 if (cp->error) 2921 return; 2922 2923 CTypeID ctypeid = cp->val.id; 2924 2925 if (decl.uv_name) 2926 { 2927 if (decl.nameid) 2928 { /* Redeclaration detected - check compatibility. */ 2929 CType *existing_ct = ctype_get(cp->cts, decl.nameid); 2930 CType *new_ct = ctype_get(cp->cts, ctypeid); 2931 2932 /* Skip extern and attributes to get the actual function type. */ 2933 CType *existing_func = existing_ct; 2934 while (ctype_isextern(existing_func->info) || ctype_isattrib(existing_func->info)) 2935 existing_func = ctype_rawchild(cp->cts, existing_func); 2936 2937 /* Unwrap CT_PTR if needed. */ 2938 CType *new_func = new_ct; 2939 if (ctype_isptr(new_ct->info)) 2940 new_func = ctype_rawchild(cp->cts, new_ct); 2941 2942 if (ctype_isfunc(existing_func->info) && ctype_isfunc(new_func->info) && 2943 ctype_func_is_equiv(cp->cts, existing_func, new_func)) 2944 { /* Compatible: reuse existing type. */ 2945 if (!existing_ct->uv_name) 2946 ctype_setname(existing_ct, decl.uv_name); 2947 ctypeid = decl.nameid; /* Use existing ID */ 2948 cp->val.id = ctypeid; /* Update parser state */ 2949 /* Add to hash table with the name. */ 2950 uc_ctype_addname(cp->cts, existing_ct, ctypeid); 2951 } 2952 else 2953 { /* Incompatible redeclaration. */ 2954 cp_errmsg(cp, 0, "redeclaration of '%s' as different type", 2955 ucv_string_get(decl.uv_name)); 2956 } 2957 } 2958 else 2959 { /* New declaration. */ 2960 CType *ct; 2961 CTypeID id; 2962 2963 /* Treat both static and extern function declarations as extern. */ 2964 ct = ctype_get(cp->cts, ctypeid); 2965 /* We always get new anonymous functions (typedefs are copied). */ 2966 uc_assertCP(ct->uv_name == NULL, "unexpected named function"); 2967 id = ctypeid; /* Just name it. */ 2968 2969 if (ctype_isfunc(ct->info) && decl.uv_redir) 2970 { /* Add attribute for redirected symbol name. */ 2971 CType *cta; 2972 CTypeID aid = uc_ctype_new(cp->cts, &cta); 2973 ct = ctype_get(cp->cts, id); /* Table may have been reallocated. */ 2974 cta->info = CTINFO(CT_ATTRIB, CTATTRIB(CTA_REDIR)); 2975 cta->sib = ct->sib; 2976 ct->sib = aid; 2977 ctype_setname(cta, decl.uv_redir); 2978 } 2979 2980 ctype_setname(ct, decl.uv_name); 2981 uc_ctype_addname(cp->cts, ct, id); 2982 } 2983 } 2984 2985 cp_decl_reset(&decl); 2986 2987 if (cp->tok != CTOK_EOF) 2988 cp_err_token(cp, CTOK_EOF); 2989 } 2990 2991 /* ------------------------------------------------------------------------ */ 2992 2993 /* C parser. */ 2994 bool uc_cparse(CPState *cp) 2995 { 2996 bool rv = true; 2997 2998 cp_init(cp); 2999 3000 if ((cp->mode & CPARSE_MODE_MULTI)) 3001 cp_decl_multi(cp); 3002 else 3003 cp_decl_single(cp); 3004 3005 if (cp->uv_param && cp->uv_param != &cp->uv_vm->stack.entries[cp->uv_vm->stack.count]) 3006 cp_err(cp, "wrong number of type parameters"); 3007 3008 uc_assertCP(cp->depth == 0, "unbalanced cparser declaration depth"); 3009 3010 if (cp->error) { 3011 uc_vm_raise_exception(cp->cts->vm, EXCEPTION_SYNTAX, 3012 "invalid C type: %s", cp->error); 3013 3014 rv = false; 3015 } 3016 3017 cp_cleanup(cp); 3018 3019 return rv; 3020 } 3021
This page was automatically generated by LXR 0.3.1. • OpenWrt