1 /* Parser for C and Objective-C. 2 Copyright (C) 1987-2019 Free Software Foundation, Inc. 3 4 Parser actions based on the old Bison parser; structure somewhat 5 influenced by and fragments based on the C++ parser. 6 7 This file is part of GCC. 8 9 GCC is free software; you can redistribute it and/or modify it under 10 the terms of the GNU General Public License as published by the Free 11 Software Foundation; either version 3, or (at your option) any later 12 version. 13 14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 15 WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with GCC; see the file COPYING3. If not see 21 <http://www.gnu.org/licenses/>. */ 22 23 /* TODO: 24 25 Make sure all relevant comments, and all relevant code from all 26 actions, brought over from old parser. Verify exact correspondence 27 of syntax accepted. 28 29 Add testcases covering every input symbol in every state in old and 30 new parsers. 31 32 Include full syntax for GNU C, including erroneous cases accepted 33 with error messages, in syntax productions in comments. 34 35 Make more diagnostics in the front end generally take an explicit 36 location rather than implicitly using input_location. */ 37 38 #include "config.h" 39 #define INCLUDE_UNIQUE_PTR 40 #include "system.h" 41 #include "coretypes.h" 42 #include "target.h" 43 #include "function.h" 44 #include "c-tree.h" 45 #include "timevar.h" 46 #include "stringpool.h" 47 #include "cgraph.h" 48 #include "attribs.h" 49 #include "stor-layout.h" 50 #include "varasm.h" 51 #include "trans-mem.h" 52 #include "c-family/c-pragma.h" 53 #include "c-lang.h" 54 #include "c-family/c-objc.h" 55 #include "plugin.h" 56 #include "omp-general.h" 57 #include "omp-offload.h" 58 #include "builtins.h" 59 #include "gomp-constants.h" 60 #include "c-family/c-indentation.h" 61 #include "gimple-expr.h" 62 #include "context.h" 63 #include "gcc-rich-location.h" 64 #include "c-parser.h" 65 #include "gimple-parser.h" 66 #include "read-rtl-function.h" 67 #include "run-rtl-passes.h" 68 #include "intl.h" 69 #include "c-family/name-hint.h" 70 #include "tree-iterator.h" 71 #include "memmodel.h" 72 73 /* We need to walk over decls with incomplete struct/union/enum types 74 after parsing the whole translation unit. 75 In finish_decl(), if the decl is static, has incomplete 76 struct/union/enum type, it is appeneded to incomplete_record_decls. 77 In c_parser_translation_unit(), we iterate over incomplete_record_decls 78 and report error if any of the decls are still incomplete. */ 79 80 vec<tree> incomplete_record_decls; 81 82 void 83 set_c_expr_source_range (c_expr *expr, 84 location_t start, location_t finish) 85 { 86 expr->src_range.m_start = start; 87 expr->src_range.m_finish = finish; 88 if (expr->value) 89 set_source_range (expr->value, start, finish); 90 } 91 92 void 93 set_c_expr_source_range (c_expr *expr, 94 source_range src_range) 95 { 96 expr->src_range = src_range; 97 if (expr->value) 98 set_source_range (expr->value, src_range); 99 } 100 101 102 /* Initialization routine for this file. */ 103 104 void 105 c_parse_init (void) 106 { 107 /* The only initialization required is of the reserved word 108 identifiers. */ 109 unsigned int i; 110 tree id; 111 int mask = 0; 112 113 /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in 114 the c_token structure. */ 115 gcc_assert (RID_MAX <= 255); 116 117 mask |= D_CXXONLY; 118 if (!flag_isoc99) 119 mask |= D_C99; 120 if (flag_no_asm) 121 { 122 mask |= D_ASM | D_EXT; 123 if (!flag_isoc99) 124 mask |= D_EXT89; 125 } 126 if (!c_dialect_objc ()) 127 mask |= D_OBJC | D_CXX_OBJC; 128 129 ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX); 130 for (i = 0; i < num_c_common_reswords; i++) 131 { 132 /* If a keyword is disabled, do not enter it into the table 133 and so create a canonical spelling that isn't a keyword. */ 134 if (c_common_reswords[i].disable & mask) 135 { 136 if (warn_cxx_compat 137 && (c_common_reswords[i].disable & D_CXXWARN)) 138 { 139 id = get_identifier (c_common_reswords[i].word); 140 C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN); 141 C_IS_RESERVED_WORD (id) = 1; 142 } 143 continue; 144 } 145 146 id = get_identifier (c_common_reswords[i].word); 147 C_SET_RID_CODE (id, c_common_reswords[i].rid); 148 C_IS_RESERVED_WORD (id) = 1; 149 ridpointers [(int) c_common_reswords[i].rid] = id; 150 } 151 152 for (i = 0; i < NUM_INT_N_ENTS; i++) 153 { 154 /* We always create the symbols but they aren't always supported. */ 155 char name[50]; 156 sprintf (name, "__int%d", int_n_data[i].bitsize); 157 id = get_identifier (name); 158 C_SET_RID_CODE (id, RID_FIRST_INT_N + i); 159 C_IS_RESERVED_WORD (id) = 1; 160 } 161 } 162 163 /* A parser structure recording information about the state and 164 context of parsing. Includes lexer information with up to two 165 tokens of look-ahead; more are not needed for C. */ 166 struct GTY(()) c_parser { 167 /* The look-ahead tokens. */ 168 c_token * GTY((skip)) tokens; 169 /* Buffer for look-ahead tokens. */ 170 c_token tokens_buf[4]; 171 /* How many look-ahead tokens are available (0 - 4, or 172 more if parsing from pre-lexed tokens). */ 173 unsigned int tokens_avail; 174 /* True if a syntax error is being recovered from; false otherwise. 175 c_parser_error sets this flag. It should clear this flag when 176 enough tokens have been consumed to recover from the error. */ 177 BOOL_BITFIELD error : 1; 178 /* True if we're processing a pragma, and shouldn't automatically 179 consume CPP_PRAGMA_EOL. */ 180 BOOL_BITFIELD in_pragma : 1; 181 /* True if we're parsing the outermost block of an if statement. */ 182 BOOL_BITFIELD in_if_block : 1; 183 /* True if we want to lex an untranslated string. */ 184 BOOL_BITFIELD lex_untranslated_string : 1; 185 186 /* Objective-C specific parser/lexer information. */ 187 188 /* True if we are in a context where the Objective-C "PQ" keywords 189 are considered keywords. */ 190 BOOL_BITFIELD objc_pq_context : 1; 191 /* True if we are parsing a (potential) Objective-C foreach 192 statement. This is set to true after we parsed 'for (' and while 193 we wait for 'in' or ';' to decide if it's a standard C for loop or an 194 Objective-C foreach loop. */ 195 BOOL_BITFIELD objc_could_be_foreach_context : 1; 196 /* The following flag is needed to contextualize Objective-C lexical 197 analysis. In some cases (e.g., 'int NSObject;'), it is 198 undesirable to bind an identifier to an Objective-C class, even 199 if a class with that name exists. */ 200 BOOL_BITFIELD objc_need_raw_identifier : 1; 201 /* Nonzero if we're processing a __transaction statement. The value 202 is 1 | TM_STMT_ATTR_*. */ 203 unsigned int in_transaction : 4; 204 /* True if we are in a context where the Objective-C "Property attribute" 205 keywords are valid. */ 206 BOOL_BITFIELD objc_property_attr_context : 1; 207 208 /* Location of the last consumed token. */ 209 location_t last_token_location; 210 }; 211 212 /* Return a pointer to the Nth token in PARSERs tokens_buf. */ 213 214 c_token * 215 c_parser_tokens_buf (c_parser *parser, unsigned n) 216 { 217 return &parser->tokens_buf[n]; 218 } 219 220 /* Return the error state of PARSER. */ 221 222 bool 223 c_parser_error (c_parser *parser) 224 { 225 return parser->error; 226 } 227 228 /* Set the error state of PARSER to ERR. */ 229 230 void 231 c_parser_set_error (c_parser *parser, bool err) 232 { 233 parser->error = err; 234 } 235 236 237 /* The actual parser and external interface. ??? Does this need to be 238 garbage-collected? */ 239 240 static GTY (()) c_parser *the_parser; 241 242 /* Read in and lex a single token, storing it in *TOKEN. */ 243 244 static void 245 c_lex_one_token (c_parser *parser, c_token *token) 246 { 247 timevar_push (TV_LEX); 248 249 token->type = c_lex_with_flags (&token->value, &token->location, 250 &token->flags, 251 (parser->lex_untranslated_string 252 ? C_LEX_STRING_NO_TRANSLATE : 0)); 253 token->id_kind = C_ID_NONE; 254 token->keyword = RID_MAX; 255 token->pragma_kind = PRAGMA_NONE; 256 257 switch (token->type) 258 { 259 case CPP_NAME: 260 { 261 tree decl; 262 263 bool objc_force_identifier = parser->objc_need_raw_identifier; 264 if (c_dialect_objc ()) 265 parser->objc_need_raw_identifier = false; 266 267 if (C_IS_RESERVED_WORD (token->value)) 268 { 269 enum rid rid_code = C_RID_CODE (token->value); 270 271 if (rid_code == RID_CXX_COMPAT_WARN) 272 { 273 warning_at (token->location, 274 OPT_Wc___compat, 275 "identifier %qE conflicts with C++ keyword", 276 token->value); 277 } 278 else if (rid_code >= RID_FIRST_ADDR_SPACE 279 && rid_code <= RID_LAST_ADDR_SPACE) 280 { 281 addr_space_t as; 282 as = (addr_space_t) (rid_code - RID_FIRST_ADDR_SPACE); 283 targetm.addr_space.diagnose_usage (as, token->location); 284 token->id_kind = C_ID_ADDRSPACE; 285 token->keyword = rid_code; 286 break; 287 } 288 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code)) 289 { 290 /* We found an Objective-C "pq" keyword (in, out, 291 inout, bycopy, byref, oneway). They need special 292 care because the interpretation depends on the 293 context. */ 294 if (parser->objc_pq_context) 295 { 296 token->type = CPP_KEYWORD; 297 token->keyword = rid_code; 298 break; 299 } 300 else if (parser->objc_could_be_foreach_context 301 && rid_code == RID_IN) 302 { 303 /* We are in Objective-C, inside a (potential) 304 foreach context (which means after having 305 parsed 'for (', but before having parsed ';'), 306 and we found 'in'. We consider it the keyword 307 which terminates the declaration at the 308 beginning of a foreach-statement. Note that 309 this means you can't use 'in' for anything else 310 in that context; in particular, in Objective-C 311 you can't use 'in' as the name of the running 312 variable in a C for loop. We could potentially 313 try to add code here to disambiguate, but it 314 seems a reasonable limitation. */ 315 token->type = CPP_KEYWORD; 316 token->keyword = rid_code; 317 break; 318 } 319 /* Else, "pq" keywords outside of the "pq" context are 320 not keywords, and we fall through to the code for 321 normal tokens. */ 322 } 323 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code)) 324 { 325 /* We found an Objective-C "property attribute" 326 keyword (getter, setter, readonly, etc). These are 327 only valid in the property context. */ 328 if (parser->objc_property_attr_context) 329 { 330 token->type = CPP_KEYWORD; 331 token->keyword = rid_code; 332 break; 333 } 334 /* Else they are not special keywords. 335 */ 336 } 337 else if (c_dialect_objc () 338 && (OBJC_IS_AT_KEYWORD (rid_code) 339 || OBJC_IS_CXX_KEYWORD (rid_code))) 340 { 341 /* We found one of the Objective-C "@" keywords (defs, 342 selector, synchronized, etc) or one of the 343 Objective-C "cxx" keywords (class, private, 344 protected, public, try, catch, throw) without a 345 preceding '@' sign. Do nothing and fall through to 346 the code for normal tokens (in C++ we would still 347 consider the CXX ones keywords, but not in C). */ 348 ; 349 } 350 else 351 { 352 token->type = CPP_KEYWORD; 353 token->keyword = rid_code; 354 break; 355 } 356 } 357 358 decl = lookup_name (token->value); 359 if (decl) 360 { 361 if (TREE_CODE (decl) == TYPE_DECL) 362 { 363 token->id_kind = C_ID_TYPENAME; 364 break; 365 } 366 } 367 else if (c_dialect_objc ()) 368 { 369 tree objc_interface_decl = objc_is_class_name (token->value); 370 /* Objective-C class names are in the same namespace as 371 variables and typedefs, and hence are shadowed by local 372 declarations. */ 373 if (objc_interface_decl 374 && (!objc_force_identifier || global_bindings_p ())) 375 { 376 token->value = objc_interface_decl; 377 token->id_kind = C_ID_CLASSNAME; 378 break; 379 } 380 } 381 token->id_kind = C_ID_ID; 382 } 383 break; 384 case CPP_AT_NAME: 385 /* This only happens in Objective-C; it must be a keyword. */ 386 token->type = CPP_KEYWORD; 387 switch (C_RID_CODE (token->value)) 388 { 389 /* Replace 'class' with '@class', 'private' with '@private', 390 etc. This prevents confusion with the C++ keyword 391 'class', and makes the tokens consistent with other 392 Objective-C 'AT' keywords. For example '@class' is 393 reported as RID_AT_CLASS which is consistent with 394 '@synchronized', which is reported as 395 RID_AT_SYNCHRONIZED. 396 */ 397 case RID_CLASS: token->keyword = RID_AT_CLASS; break; 398 case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break; 399 case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break; 400 case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break; 401 case RID_THROW: token->keyword = RID_AT_THROW; break; 402 case RID_TRY: token->keyword = RID_AT_TRY; break; 403 case RID_CATCH: token->keyword = RID_AT_CATCH; break; 404 case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break; 405 default: token->keyword = C_RID_CODE (token->value); 406 } 407 break; 408 case CPP_COLON: 409 case CPP_COMMA: 410 case CPP_CLOSE_PAREN: 411 case CPP_SEMICOLON: 412 /* These tokens may affect the interpretation of any identifiers 413 following, if doing Objective-C. */ 414 if (c_dialect_objc ()) 415 parser->objc_need_raw_identifier = false; 416 break; 417 case CPP_PRAGMA: 418 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */ 419 token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value); 420 token->value = NULL; 421 break; 422 default: 423 break; 424 } 425 timevar_pop (TV_LEX); 426 } 427 428 /* Return a pointer to the next token from PARSER, reading it in if 429 necessary. */ 430 431 c_token * 432 c_parser_peek_token (c_parser *parser) 433 { 434 if (parser->tokens_avail == 0) 435 { 436 c_lex_one_token (parser, &parser->tokens[0]); 437 parser->tokens_avail = 1; 438 } 439 return &parser->tokens[0]; 440 } 441 442 /* Return a pointer to the next-but-one token from PARSER, reading it 443 in if necessary. The next token is already read in. */ 444 445 c_token * 446 c_parser_peek_2nd_token (c_parser *parser) 447 { 448 if (parser->tokens_avail >= 2) 449 return &parser->tokens[1]; 450 gcc_assert (parser->tokens_avail == 1); 451 gcc_assert (parser->tokens[0].type != CPP_EOF); 452 gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL); 453 c_lex_one_token (parser, &parser->tokens[1]); 454 parser->tokens_avail = 2; 455 return &parser->tokens[1]; 456 } 457 458 /* Return a pointer to the Nth token from PARSER, reading it 459 in if necessary. The N-1th token is already read in. */ 460 461 c_token * 462 c_parser_peek_nth_token (c_parser *parser, unsigned int n) 463 { 464 /* N is 1-based, not zero-based. */ 465 gcc_assert (n > 0); 466 467 if (parser->tokens_avail >= n) 468 return &parser->tokens[n - 1]; 469 gcc_assert (parser->tokens_avail == n - 1); 470 c_lex_one_token (parser, &parser->tokens[n - 1]); 471 parser->tokens_avail = n; 472 return &parser->tokens[n - 1]; 473 } 474 475 bool 476 c_keyword_starts_typename (enum rid keyword) 477 { 478 switch (keyword) 479 { 480 case RID_UNSIGNED: 481 case RID_LONG: 482 case RID_SHORT: 483 case RID_SIGNED: 484 case RID_COMPLEX: 485 case RID_INT: 486 case RID_CHAR: 487 case RID_FLOAT: 488 case RID_DOUBLE: 489 case RID_VOID: 490 case RID_DFLOAT32: 491 case RID_DFLOAT64: 492 case RID_DFLOAT128: 493 CASE_RID_FLOATN_NX: 494 case RID_BOOL: 495 case RID_ENUM: 496 case RID_STRUCT: 497 case RID_UNION: 498 case RID_TYPEOF: 499 case RID_CONST: 500 case RID_ATOMIC: 501 case RID_VOLATILE: 502 case RID_RESTRICT: 503 case RID_ATTRIBUTE: 504 case RID_FRACT: 505 case RID_ACCUM: 506 case RID_SAT: 507 case RID_AUTO_TYPE: 508 case RID_ALIGNAS: 509 return true; 510 default: 511 if (keyword >= RID_FIRST_INT_N 512 && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS 513 && int_n_enabled_p[keyword - RID_FIRST_INT_N]) 514 return true; 515 return false; 516 } 517 } 518 519 /* Return true if TOKEN can start a type name, 520 false otherwise. */ 521 bool 522 c_token_starts_typename (c_token *token) 523 { 524 switch (token->type) 525 { 526 case CPP_NAME: 527 switch (token->id_kind) 528 { 529 case C_ID_ID: 530 return false; 531 case C_ID_ADDRSPACE: 532 return true; 533 case C_ID_TYPENAME: 534 return true; 535 case C_ID_CLASSNAME: 536 gcc_assert (c_dialect_objc ()); 537 return true; 538 default: 539 gcc_unreachable (); 540 } 541 case CPP_KEYWORD: 542 return c_keyword_starts_typename (token->keyword); 543 case CPP_LESS: 544 if (c_dialect_objc ()) 545 return true; 546 return false; 547 default: 548 return false; 549 } 550 } 551 552 /* Return true if the next token from PARSER can start a type name, 553 false otherwise. LA specifies how to do lookahead in order to 554 detect unknown type names. If unsure, pick CLA_PREFER_ID. */ 555 556 static inline bool 557 c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la) 558 { 559 c_token *token = c_parser_peek_token (parser); 560 if (c_token_starts_typename (token)) 561 return true; 562 563 /* Try a bit harder to detect an unknown typename. */ 564 if (la != cla_prefer_id 565 && token->type == CPP_NAME 566 && token->id_kind == C_ID_ID 567 568 /* Do not try too hard when we could have "object in array". */ 569 && !parser->objc_could_be_foreach_context 570 571 && (la == cla_prefer_type 572 || c_parser_peek_2nd_token (parser)->type == CPP_NAME 573 || c_parser_peek_2nd_token (parser)->type == CPP_MULT) 574 575 /* Only unknown identifiers. */ 576 && !lookup_name (token->value)) 577 return true; 578 579 return false; 580 } 581 582 /* Return true if TOKEN is a type qualifier, false otherwise. */ 583 static bool 584 c_token_is_qualifier (c_token *token) 585 { 586 switch (token->type) 587 { 588 case CPP_NAME: 589 switch (token->id_kind) 590 { 591 case C_ID_ADDRSPACE: 592 return true; 593 default: 594 return false; 595 } 596 case CPP_KEYWORD: 597 switch (token->keyword) 598 { 599 case RID_CONST: 600 case RID_VOLATILE: 601 case RID_RESTRICT: 602 case RID_ATTRIBUTE: 603 case RID_ATOMIC: 604 return true; 605 default: 606 return false; 607 } 608 case CPP_LESS: 609 return false; 610 default: 611 gcc_unreachable (); 612 } 613 } 614 615 /* Return true if the next token from PARSER is a type qualifier, 616 false otherwise. */ 617 static inline bool 618 c_parser_next_token_is_qualifier (c_parser *parser) 619 { 620 c_token *token = c_parser_peek_token (parser); 621 return c_token_is_qualifier (token); 622 } 623 624 /* Return true if TOKEN can start declaration specifiers, false 625 otherwise. */ 626 static bool 627 c_token_starts_declspecs (c_token *token) 628 { 629 switch (token->type) 630 { 631 case CPP_NAME: 632 switch (token->id_kind) 633 { 634 case C_ID_ID: 635 return false; 636 case C_ID_ADDRSPACE: 637 return true; 638 case C_ID_TYPENAME: 639 return true; 640 case C_ID_CLASSNAME: 641 gcc_assert (c_dialect_objc ()); 642 return true; 643 default: 644 gcc_unreachable (); 645 } 646 case CPP_KEYWORD: 647 switch (token->keyword) 648 { 649 case RID_STATIC: 650 case RID_EXTERN: 651 case RID_REGISTER: 652 case RID_TYPEDEF: 653 case RID_INLINE: 654 case RID_NORETURN: 655 case RID_AUTO: 656 case RID_THREAD: 657 case RID_UNSIGNED: 658 case RID_LONG: 659 case RID_SHORT: 660 case RID_SIGNED: 661 case RID_COMPLEX: 662 case RID_INT: 663 case RID_CHAR: 664 case RID_FLOAT: 665 case RID_DOUBLE: 666 case RID_VOID: 667 case RID_DFLOAT32: 668 case RID_DFLOAT64: 669 case RID_DFLOAT128: 670 CASE_RID_FLOATN_NX: 671 case RID_BOOL: 672 case RID_ENUM: 673 case RID_STRUCT: 674 case RID_UNION: 675 case RID_TYPEOF: 676 case RID_CONST: 677 case RID_VOLATILE: 678 case RID_RESTRICT: 679 case RID_ATTRIBUTE: 680 case RID_FRACT: 681 case RID_ACCUM: 682 case RID_SAT: 683 case RID_ALIGNAS: 684 case RID_ATOMIC: 685 case RID_AUTO_TYPE: 686 return true; 687 default: 688 if (token->keyword >= RID_FIRST_INT_N 689 && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS 690 && int_n_enabled_p[token->keyword - RID_FIRST_INT_N]) 691 return true; 692 return false; 693 } 694 case CPP_LESS: 695 if (c_dialect_objc ()) 696 return true; 697 return false; 698 default: 699 return false; 700 } 701 } 702 703 704 /* Return true if TOKEN can start declaration specifiers or a static 705 assertion, false otherwise. */ 706 static bool 707 c_token_starts_declaration (c_token *token) 708 { 709 if (c_token_starts_declspecs (token) 710 || token->keyword == RID_STATIC_ASSERT) 711 return true; 712 else 713 return false; 714 } 715 716 /* Return true if the next token from PARSER can start declaration 717 specifiers, false otherwise. */ 718 bool 719 c_parser_next_token_starts_declspecs (c_parser *parser) 720 { 721 c_token *token = c_parser_peek_token (parser); 722 723 /* In Objective-C, a classname normally starts a declspecs unless it 724 is immediately followed by a dot. In that case, it is the 725 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the 726 setter/getter on the class. c_token_starts_declspecs() can't 727 differentiate between the two cases because it only checks the 728 current token, so we have a special check here. */ 729 if (c_dialect_objc () 730 && token->type == CPP_NAME 731 && token->id_kind == C_ID_CLASSNAME 732 && c_parser_peek_2nd_token (parser)->type == CPP_DOT) 733 return false; 734 735 return c_token_starts_declspecs (token); 736 } 737 738 /* Return true if the next tokens from PARSER can start declaration 739 specifiers or a static assertion, false otherwise. */ 740 bool 741 c_parser_next_tokens_start_declaration (c_parser *parser) 742 { 743 c_token *token = c_parser_peek_token (parser); 744 745 /* Same as above. */ 746 if (c_dialect_objc () 747 && token->type == CPP_NAME 748 && token->id_kind == C_ID_CLASSNAME 749 && c_parser_peek_2nd_token (parser)->type == CPP_DOT) 750 return false; 751 752 /* Labels do not start declarations. */ 753 if (token->type == CPP_NAME 754 && c_parser_peek_2nd_token (parser)->type == CPP_COLON) 755 return false; 756 757 if (c_token_starts_declaration (token)) 758 return true; 759 760 if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl)) 761 return true; 762 763 return false; 764 } 765 766 /* Consume the next token from PARSER. */ 767 768 void 769 c_parser_consume_token (c_parser *parser) 770 { 771 gcc_assert (parser->tokens_avail >= 1); 772 gcc_assert (parser->tokens[0].type != CPP_EOF); 773 gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL); 774 gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA); 775 parser->last_token_location = parser->tokens[0].location; 776 if (parser->tokens != &parser->tokens_buf[0]) 777 parser->tokens++; 778 else if (parser->tokens_avail == 2) 779 parser->tokens[0] = parser->tokens[1]; 780 parser->tokens_avail--; 781 } 782 783 /* Expect the current token to be a #pragma. Consume it and remember 784 that we've begun parsing a pragma. */ 785 786 static void 787 c_parser_consume_pragma (c_parser *parser) 788 { 789 gcc_assert (!parser->in_pragma); 790 gcc_assert (parser->tokens_avail >= 1); 791 gcc_assert (parser->tokens[0].type == CPP_PRAGMA); 792 if (parser->tokens != &parser->tokens_buf[0]) 793 parser->tokens++; 794 else if (parser->tokens_avail == 2) 795 parser->tokens[0] = parser->tokens[1]; 796 parser->tokens_avail--; 797 parser->in_pragma = true; 798 } 799 800 /* Update the global input_location from TOKEN. */ 801 static inline void 802 c_parser_set_source_position_from_token (c_token *token) 803 { 804 if (token->type != CPP_EOF) 805 { 806 input_location = token->location; 807 } 808 } 809 810 /* Helper function for c_parser_error. 811 Having peeked a token of kind TOK1_KIND that might signify 812 a conflict marker, peek successor tokens to determine 813 if we actually do have a conflict marker. 814 Specifically, we consider a run of 7 '<', '=' or '>' characters 815 at the start of a line as a conflict marker. 816 These come through the lexer as three pairs and a single, 817 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<'). 818 If it returns true, *OUT_LOC is written to with the location/range 819 of the marker. */ 820 821 static bool 822 c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind, 823 location_t *out_loc) 824 { 825 c_token *token2 = c_parser_peek_2nd_token (parser); 826 if (token2->type != tok1_kind) 827 return false; 828 c_token *token3 = c_parser_peek_nth_token (parser, 3); 829 if (token3->type != tok1_kind) 830 return false; 831 c_token *token4 = c_parser_peek_nth_token (parser, 4); 832 if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind)) 833 return false; 834 835 /* It must be at the start of the line. */ 836 location_t start_loc = c_parser_peek_token (parser)->location; 837 if (LOCATION_COLUMN (start_loc) != 1) 838 return false; 839 840 /* We have a conflict marker. Construct a location of the form: 841 <<<<<<< 842 ^~~~~~~ 843 with start == caret, finishing at the end of the marker. */ 844 location_t finish_loc = get_finish (token4->location); 845 *out_loc = make_location (start_loc, start_loc, finish_loc); 846 847 return true; 848 } 849 850 /* Issue a diagnostic of the form 851 FILE:LINE: MESSAGE before TOKEN 852 where TOKEN is the next token in the input stream of PARSER. 853 MESSAGE (specified by the caller) is usually of the form "expected 854 OTHER-TOKEN". 855 856 Use RICHLOC as the location of the diagnostic. 857 858 Do not issue a diagnostic if still recovering from an error. 859 860 Return true iff an error was actually emitted. 861 862 ??? This is taken from the C++ parser, but building up messages in 863 this way is not i18n-friendly and some other approach should be 864 used. */ 865 866 static bool 867 c_parser_error_richloc (c_parser *parser, const char *gmsgid, 868 rich_location *richloc) 869 { 870 c_token *token = c_parser_peek_token (parser); 871 if (parser->error) 872 return false; 873 parser->error = true; 874 if (!gmsgid) 875 return false; 876 877 /* If this is actually a conflict marker, report it as such. */ 878 if (token->type == CPP_LSHIFT 879 || token->type == CPP_RSHIFT 880 || token->type == CPP_EQ_EQ) 881 { 882 location_t loc; 883 if (c_parser_peek_conflict_marker (parser, token->type, &loc)) 884 { 885 error_at (loc, "version control conflict marker in file"); 886 return true; 887 } 888 } 889 890 c_parse_error (gmsgid, 891 /* Because c_parse_error does not understand 892 CPP_KEYWORD, keywords are treated like 893 identifiers. */ 894 (token->type == CPP_KEYWORD ? CPP_NAME : token->type), 895 /* ??? The C parser does not save the cpp flags of a 896 token, we need to pass 0 here and we will not get 897 the source spelling of some tokens but rather the 898 canonical spelling. */ 899 token->value, /*flags=*/0, richloc); 900 return true; 901 } 902 903 /* As c_parser_error_richloc, but issue the message at the 904 location of PARSER's next token, or at input_location 905 if the next token is EOF. */ 906 907 bool 908 c_parser_error (c_parser *parser, const char *gmsgid) 909 { 910 c_token *token = c_parser_peek_token (parser); 911 c_parser_set_source_position_from_token (token); 912 rich_location richloc (line_table, input_location); 913 return c_parser_error_richloc (parser, gmsgid, &richloc); 914 } 915 916 /* Some tokens naturally come in pairs e.g.'(' and ')'. 917 This class is for tracking such a matching pair of symbols. 918 In particular, it tracks the location of the first token, 919 so that if the second token is missing, we can highlight the 920 location of the first token when notifying the user about the 921 problem. */ 922 923 template <typename traits_t> 924 class token_pair 925 { 926 public: 927 /* token_pair's ctor. */ 928 token_pair () : m_open_loc (UNKNOWN_LOCATION) {} 929 930 /* If the next token is the opening symbol for this pair, consume it and 931 return true. 932 Otherwise, issue an error and return false. 933 In either case, record the location of the opening token. */ 934 935 bool require_open (c_parser *parser) 936 { 937 c_token *token = c_parser_peek_token (parser); 938 if (token) 939 m_open_loc = token->location; 940 941 return c_parser_require (parser, traits_t::open_token_type, 942 traits_t::open_gmsgid); 943 } 944 945 /* Consume the next token from PARSER, recording its location as 946 that of the opening token within the pair. */ 947 948 void consume_open (c_parser *parser) 949 { 950 c_token *token = c_parser_peek_token (parser); 951 gcc_assert (token->type == traits_t::open_token_type); 952 m_open_loc = token->location; 953 c_parser_consume_token (parser); 954 } 955 956 /* If the next token is the closing symbol for this pair, consume it 957 and return true. 958 Otherwise, issue an error, highlighting the location of the 959 corresponding opening token, and return false. */ 960 961 bool require_close (c_parser *parser) const 962 { 963 return c_parser_require (parser, traits_t::close_token_type, 964 traits_t::close_gmsgid, m_open_loc); 965 } 966 967 /* Like token_pair::require_close, except that tokens will be skipped 968 until the desired token is found. An error message is still produced 969 if the next token is not as expected. */ 970 971 void skip_until_found_close (c_parser *parser) const 972 { 973 c_parser_skip_until_found (parser, traits_t::close_token_type, 974 traits_t::close_gmsgid, m_open_loc); 975 } 976 977 private: 978 location_t m_open_loc; 979 }; 980 981 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */ 982 983 struct matching_paren_traits 984 { 985 static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN; 986 static const char * const open_gmsgid; 987 static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN; 988 static const char * const close_gmsgid; 989 }; 990 991 const char * const matching_paren_traits::open_gmsgid = "expected %<(%>"; 992 const char * const matching_paren_traits::close_gmsgid = "expected %<)%>"; 993 994 /* "matching_parens" is a token_pair<T> class for tracking matching 995 pairs of parentheses. */ 996 997 typedef token_pair<matching_paren_traits> matching_parens; 998 999 /* Traits for token_pair<T> for tracking matching pairs of braces. */ 1000 1001 struct matching_brace_traits 1002 { 1003 static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE; 1004 static const char * const open_gmsgid; 1005 static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE; 1006 static const char * const close_gmsgid; 1007 }; 1008 1009 const char * const matching_brace_traits::open_gmsgid = "expected %<{%>"; 1010 const char * const matching_brace_traits::close_gmsgid = "expected %<}%>"; 1011 1012 /* "matching_braces" is a token_pair<T> class for tracking matching 1013 pairs of braces. */ 1014 1015 typedef token_pair<matching_brace_traits> matching_braces; 1016 1017 /* Get a description of the matching symbol to TYPE e.g. "(" for 1018 CPP_CLOSE_PAREN. */ 1019 1020 static const char * 1021 get_matching_symbol (enum cpp_ttype type) 1022 { 1023 switch (type) 1024 { 1025 default: 1026 gcc_unreachable (); 1027 return ""; 1028 case CPP_CLOSE_PAREN: 1029 return "("; 1030 case CPP_CLOSE_BRACE: 1031 return "{"; 1032 } 1033 } 1034 1035 /* If the next token is of the indicated TYPE, consume it. Otherwise, 1036 issue the error MSGID. If MSGID is NULL then a message has already 1037 been produced and no message will be produced this time. Returns 1038 true if found, false otherwise. 1039 1040 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it 1041 within any error as the location of an "opening" token matching 1042 the close token TYPE (e.g. the location of the '(' when TYPE is 1043 CPP_CLOSE_PAREN). 1044 1045 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly 1046 one type (e.g. "expected %<)%>") and thus it may be reasonable to 1047 attempt to generate a fix-it hint for the problem. 1048 Otherwise msgid describes multiple token types (e.g. 1049 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to 1050 generate a fix-it hint. */ 1051 1052 bool 1053 c_parser_require (c_parser *parser, 1054 enum cpp_ttype type, 1055 const char *msgid, 1056 location_t matching_location, 1057 bool type_is_unique) 1058 { 1059 if (c_parser_next_token_is (parser, type)) 1060 { 1061 c_parser_consume_token (parser); 1062 return true; 1063 } 1064 else 1065 { 1066 location_t next_token_loc = c_parser_peek_token (parser)->location; 1067 gcc_rich_location richloc (next_token_loc); 1068 1069 /* Potentially supply a fix-it hint, suggesting to add the 1070 missing token immediately after the *previous* token. 1071 This may move the primary location within richloc. */ 1072 if (!parser->error && type_is_unique) 1073 maybe_suggest_missing_token_insertion (&richloc, type, 1074 parser->last_token_location); 1075 1076 /* If matching_location != UNKNOWN_LOCATION, highlight it. 1077 Attempt to consolidate diagnostics by printing it as a 1078 secondary range within the main diagnostic. */ 1079 bool added_matching_location = false; 1080 if (matching_location != UNKNOWN_LOCATION) 1081 added_matching_location 1082 = richloc.add_location_if_nearby (matching_location); 1083 1084 if (c_parser_error_richloc (parser, msgid, &richloc)) 1085 /* If we weren't able to consolidate matching_location, then 1086 print it as a secondary diagnostic. */ 1087 if (matching_location != UNKNOWN_LOCATION && !added_matching_location) 1088 inform (matching_location, "to match this %qs", 1089 get_matching_symbol (type)); 1090 1091 return false; 1092 } 1093 } 1094 1095 /* If the next token is the indicated keyword, consume it. Otherwise, 1096 issue the error MSGID. Returns true if found, false otherwise. */ 1097 1098 static bool 1099 c_parser_require_keyword (c_parser *parser, 1100 enum rid keyword, 1101 const char *msgid) 1102 { 1103 if (c_parser_next_token_is_keyword (parser, keyword)) 1104 { 1105 c_parser_consume_token (parser); 1106 return true; 1107 } 1108 else 1109 { 1110 c_parser_error (parser, msgid); 1111 return false; 1112 } 1113 } 1114 1115 /* Like c_parser_require, except that tokens will be skipped until the 1116 desired token is found. An error message is still produced if the 1117 next token is not as expected. If MSGID is NULL then a message has 1118 already been produced and no message will be produced this 1119 time. 1120 1121 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it 1122 within any error as the location of an "opening" token matching 1123 the close token TYPE (e.g. the location of the '(' when TYPE is 1124 CPP_CLOSE_PAREN). */ 1125 1126 void 1127 c_parser_skip_until_found (c_parser *parser, 1128 enum cpp_ttype type, 1129 const char *msgid, 1130 location_t matching_location) 1131 { 1132 unsigned nesting_depth = 0; 1133 1134 if (c_parser_require (parser, type, msgid, matching_location)) 1135 return; 1136 1137 /* Skip tokens until the desired token is found. */ 1138 while (true) 1139 { 1140 /* Peek at the next token. */ 1141 c_token *token = c_parser_peek_token (parser); 1142 /* If we've reached the token we want, consume it and stop. */ 1143 if (token->type == type && !nesting_depth) 1144 { 1145 c_parser_consume_token (parser); 1146 break; 1147 } 1148 1149 /* If we've run out of tokens, stop. */ 1150 if (token->type == CPP_EOF) 1151 return; 1152 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma) 1153 return; 1154 if (token->type == CPP_OPEN_BRACE 1155 || token->type == CPP_OPEN_PAREN 1156 || token->type == CPP_OPEN_SQUARE) 1157 ++nesting_depth; 1158 else if (token->type == CPP_CLOSE_BRACE 1159 || token->type == CPP_CLOSE_PAREN 1160 || token->type == CPP_CLOSE_SQUARE) 1161 { 1162 if (nesting_depth-- == 0) 1163 break; 1164 } 1165 /* Consume this token. */ 1166 c_parser_consume_token (parser); 1167 } 1168 parser->error = false; 1169 } 1170 1171 /* Skip tokens until the end of a parameter is found, but do not 1172 consume the comma, semicolon or closing delimiter. */ 1173 1174 static void 1175 c_parser_skip_to_end_of_parameter (c_parser *parser) 1176 { 1177 unsigned nesting_depth = 0; 1178 1179 while (true) 1180 { 1181 c_token *token = c_parser_peek_token (parser); 1182 if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON) 1183 && !nesting_depth) 1184 break; 1185 /* If we've run out of tokens, stop. */ 1186 if (token->type == CPP_EOF) 1187 return; 1188 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma) 1189 return; 1190 if (token->type == CPP_OPEN_BRACE 1191 || token->type == CPP_OPEN_PAREN 1192 || token->type == CPP_OPEN_SQUARE) 1193 ++nesting_depth; 1194 else if (token->type == CPP_CLOSE_BRACE 1195 || token->type == CPP_CLOSE_PAREN 1196 || token->type == CPP_CLOSE_SQUARE) 1197 { 1198 if (nesting_depth-- == 0) 1199 break; 1200 } 1201 /* Consume this token. */ 1202 c_parser_consume_token (parser); 1203 } 1204 parser->error = false; 1205 } 1206 1207 /* Expect to be at the end of the pragma directive and consume an 1208 end of line marker. */ 1209 1210 static void 1211 c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true) 1212 { 1213 gcc_assert (parser->in_pragma); 1214 parser->in_pragma = false; 1215 1216 if (error_if_not_eol && c_parser_peek_token (parser)->type != CPP_PRAGMA_EOL) 1217 c_parser_error (parser, "expected end of line"); 1218 1219 cpp_ttype token_type; 1220 do 1221 { 1222 c_token *token = c_parser_peek_token (parser); 1223 token_type = token->type; 1224 if (token_type == CPP_EOF) 1225 break; 1226 c_parser_consume_token (parser); 1227 } 1228 while (token_type != CPP_PRAGMA_EOL); 1229 1230 parser->error = false; 1231 } 1232 1233 /* Skip tokens until we have consumed an entire block, or until we 1234 have consumed a non-nested ';'. */ 1235 1236 static void 1237 c_parser_skip_to_end_of_block_or_statement (c_parser *parser) 1238 { 1239 unsigned nesting_depth = 0; 1240 bool save_error = parser->error; 1241 1242 while (true) 1243 { 1244 c_token *token; 1245 1246 /* Peek at the next token. */ 1247 token = c_parser_peek_token (parser); 1248 1249 switch (token->type) 1250 { 1251 case CPP_EOF: 1252 return; 1253 1254 case CPP_PRAGMA_EOL: 1255 if (parser->in_pragma) 1256 return; 1257 break; 1258 1259 case CPP_SEMICOLON: 1260 /* If the next token is a ';', we have reached the 1261 end of the statement. */ 1262 if (!nesting_depth) 1263 { 1264 /* Consume the ';'. */ 1265 c_parser_consume_token (parser); 1266 goto finished; 1267 } 1268 break; 1269 1270 case CPP_CLOSE_BRACE: 1271 /* If the next token is a non-nested '}', then we have 1272 reached the end of the current block. */ 1273 if (nesting_depth == 0 || --nesting_depth == 0) 1274 { 1275 c_parser_consume_token (parser); 1276 goto finished; 1277 } 1278 break; 1279 1280 case CPP_OPEN_BRACE: 1281 /* If it the next token is a '{', then we are entering a new 1282 block. Consume the entire block. */ 1283 ++nesting_depth; 1284 break; 1285 1286 case CPP_PRAGMA: 1287 /* If we see a pragma, consume the whole thing at once. We 1288 have some safeguards against consuming pragmas willy-nilly. 1289 Normally, we'd expect to be here with parser->error set, 1290 which disables these safeguards. But it's possible to get 1291 here for secondary error recovery, after parser->error has 1292 been cleared. */ 1293 c_parser_consume_pragma (parser); 1294 c_parser_skip_to_pragma_eol (parser); 1295 parser->error = save_error; 1296 continue; 1297 1298 default: 1299 break; 1300 } 1301 1302 c_parser_consume_token (parser); 1303 } 1304 1305 finished: 1306 parser->error = false; 1307 } 1308 1309 /* CPP's options (initialized by c-opts.c). */ 1310 extern cpp_options *cpp_opts; 1311 1312 /* Save the warning flags which are controlled by __extension__. */ 1313 1314 static inline int 1315 disable_extension_diagnostics (void) 1316 { 1317 int ret = (pedantic 1318 | (warn_pointer_arith << 1) 1319 | (warn_traditional << 2) 1320 | (flag_iso << 3) 1321 | (warn_long_long << 4) 1322 | (warn_cxx_compat << 5) 1323 | (warn_overlength_strings << 6) 1324 /* warn_c90_c99_compat has three states: -1/0/1, so we must 1325 play tricks to properly restore it. */ 1326 | ((warn_c90_c99_compat == 1) << 7) 1327 | ((warn_c90_c99_compat == -1) << 8) 1328 /* Similarly for warn_c99_c11_compat. */ 1329 | ((warn_c99_c11_compat == 1) << 9) 1330 | ((warn_c99_c11_compat == -1) << 10) 1331 /* Similarly for warn_c11_c2x_compat. */ 1332 | ((warn_c11_c2x_compat == 1) << 11) 1333 | ((warn_c11_c2x_compat == -1) << 12) 1334 ); 1335 cpp_opts->cpp_pedantic = pedantic = 0; 1336 warn_pointer_arith = 0; 1337 cpp_opts->cpp_warn_traditional = warn_traditional = 0; 1338 flag_iso = 0; 1339 cpp_opts->cpp_warn_long_long = warn_long_long = 0; 1340 warn_cxx_compat = 0; 1341 warn_overlength_strings = 0; 1342 warn_c90_c99_compat = 0; 1343 warn_c99_c11_compat = 0; 1344 warn_c11_c2x_compat = 0; 1345 return ret; 1346 } 1347 1348 /* Restore the warning flags which are controlled by __extension__. 1349 FLAGS is the return value from disable_extension_diagnostics. */ 1350 1351 static inline void 1352 restore_extension_diagnostics (int flags) 1353 { 1354 cpp_opts->cpp_pedantic = pedantic = flags & 1; 1355 warn_pointer_arith = (flags >> 1) & 1; 1356 cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1; 1357 flag_iso = (flags >> 3) & 1; 1358 cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1; 1359 warn_cxx_compat = (flags >> 5) & 1; 1360 warn_overlength_strings = (flags >> 6) & 1; 1361 /* See above for why is this needed. */ 1362 warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0); 1363 warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0); 1364 warn_c11_c2x_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0); 1365 } 1366 1367 /* Helper data structure for parsing #pragma acc routine. */ 1368 struct oacc_routine_data { 1369 bool error_seen; /* Set if error has been reported. */ 1370 bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */ 1371 tree clauses; 1372 location_t loc; 1373 }; 1374 1375 static void c_parser_external_declaration (c_parser *); 1376 static void c_parser_asm_definition (c_parser *); 1377 static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool, 1378 bool, bool, tree *, vec<c_token>, 1379 struct oacc_routine_data * = NULL, 1380 bool * = NULL); 1381 static void c_parser_static_assert_declaration_no_semi (c_parser *); 1382 static void c_parser_static_assert_declaration (c_parser *); 1383 static struct c_typespec c_parser_enum_specifier (c_parser *); 1384 static struct c_typespec c_parser_struct_or_union_specifier (c_parser *); 1385 static tree c_parser_struct_declaration (c_parser *); 1386 static struct c_typespec c_parser_typeof_specifier (c_parser *); 1387 static tree c_parser_alignas_specifier (c_parser *); 1388 static struct c_declarator *c_parser_direct_declarator (c_parser *, bool, 1389 c_dtr_syn, bool *); 1390 static struct c_declarator *c_parser_direct_declarator_inner (c_parser *, 1391 bool, 1392 struct c_declarator *); 1393 static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree); 1394 static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree, 1395 tree); 1396 static struct c_parm *c_parser_parameter_declaration (c_parser *, tree); 1397 static tree c_parser_simple_asm_expr (c_parser *); 1398 static tree c_parser_attributes (c_parser *); 1399 static struct c_expr c_parser_initializer (c_parser *); 1400 static struct c_expr c_parser_braced_init (c_parser *, tree, bool, 1401 struct obstack *); 1402 static void c_parser_initelt (c_parser *, struct obstack *); 1403 static void c_parser_initval (c_parser *, struct c_expr *, 1404 struct obstack *); 1405 static tree c_parser_compound_statement (c_parser *); 1406 static void c_parser_compound_statement_nostart (c_parser *); 1407 static void c_parser_label (c_parser *); 1408 static void c_parser_statement (c_parser *, bool *, location_t * = NULL); 1409 static void c_parser_statement_after_labels (c_parser *, bool *, 1410 vec<tree> * = NULL); 1411 static tree c_parser_c99_block_statement (c_parser *, bool *, 1412 location_t * = NULL); 1413 static void c_parser_if_statement (c_parser *, bool *, vec<tree> *); 1414 static void c_parser_switch_statement (c_parser *, bool *); 1415 static void c_parser_while_statement (c_parser *, bool, unsigned short, bool *); 1416 static void c_parser_do_statement (c_parser *, bool, unsigned short); 1417 static void c_parser_for_statement (c_parser *, bool, unsigned short, bool *); 1418 static tree c_parser_asm_statement (c_parser *); 1419 static tree c_parser_asm_operands (c_parser *); 1420 static tree c_parser_asm_goto_operands (c_parser *); 1421 static tree c_parser_asm_clobbers (c_parser *); 1422 static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *, 1423 tree = NULL_TREE); 1424 static struct c_expr c_parser_conditional_expression (c_parser *, 1425 struct c_expr *, tree); 1426 static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *, 1427 tree); 1428 static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *); 1429 static struct c_expr c_parser_unary_expression (c_parser *); 1430 static struct c_expr c_parser_sizeof_expression (c_parser *); 1431 static struct c_expr c_parser_alignof_expression (c_parser *); 1432 static struct c_expr c_parser_postfix_expression (c_parser *); 1433 static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *, 1434 struct c_type_name *, 1435 location_t); 1436 static struct c_expr c_parser_postfix_expression_after_primary (c_parser *, 1437 location_t loc, 1438 struct c_expr); 1439 static tree c_parser_transaction (c_parser *, enum rid); 1440 static struct c_expr c_parser_transaction_expression (c_parser *, enum rid); 1441 static tree c_parser_transaction_cancel (c_parser *); 1442 static struct c_expr c_parser_expression (c_parser *); 1443 static struct c_expr c_parser_expression_conv (c_parser *); 1444 static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool, 1445 vec<tree, va_gc> **, location_t *, 1446 tree *, vec<location_t> *, 1447 unsigned int * = NULL); 1448 static struct c_expr c_parser_has_attribute_expression (c_parser *); 1449 1450 static void c_parser_oacc_declare (c_parser *); 1451 static void c_parser_oacc_enter_exit_data (c_parser *, bool); 1452 static void c_parser_oacc_update (c_parser *); 1453 static void c_parser_omp_construct (c_parser *, bool *); 1454 static void c_parser_omp_threadprivate (c_parser *); 1455 static void c_parser_omp_barrier (c_parser *); 1456 static void c_parser_omp_depobj (c_parser *); 1457 static void c_parser_omp_flush (c_parser *); 1458 static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code, 1459 tree, tree *, bool *); 1460 static void c_parser_omp_taskwait (c_parser *); 1461 static void c_parser_omp_taskyield (c_parser *); 1462 static void c_parser_omp_cancel (c_parser *); 1463 1464 enum pragma_context { pragma_external, pragma_struct, pragma_param, 1465 pragma_stmt, pragma_compound }; 1466 static bool c_parser_pragma (c_parser *, enum pragma_context, bool *); 1467 static void c_parser_omp_cancellation_point (c_parser *, enum pragma_context); 1468 static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *); 1469 static void c_parser_omp_end_declare_target (c_parser *); 1470 static void c_parser_omp_declare (c_parser *, enum pragma_context); 1471 static void c_parser_omp_requires (c_parser *); 1472 static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *); 1473 static void c_parser_oacc_routine (c_parser *, enum pragma_context); 1474 1475 /* These Objective-C parser functions are only ever called when 1476 compiling Objective-C. */ 1477 static void c_parser_objc_class_definition (c_parser *, tree); 1478 static void c_parser_objc_class_instance_variables (c_parser *); 1479 static void c_parser_objc_class_declaration (c_parser *); 1480 static void c_parser_objc_alias_declaration (c_parser *); 1481 static void c_parser_objc_protocol_definition (c_parser *, tree); 1482 static bool c_parser_objc_method_type (c_parser *); 1483 static void c_parser_objc_method_definition (c_parser *); 1484 static void c_parser_objc_methodprotolist (c_parser *); 1485 static void c_parser_objc_methodproto (c_parser *); 1486 static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *); 1487 static tree c_parser_objc_type_name (c_parser *); 1488 static tree c_parser_objc_protocol_refs (c_parser *); 1489 static void c_parser_objc_try_catch_finally_statement (c_parser *); 1490 static void c_parser_objc_synchronized_statement (c_parser *); 1491 static tree c_parser_objc_selector (c_parser *); 1492 static tree c_parser_objc_selector_arg (c_parser *); 1493 static tree c_parser_objc_receiver (c_parser *); 1494 static tree c_parser_objc_message_args (c_parser *); 1495 static tree c_parser_objc_keywordexpr (c_parser *); 1496 static void c_parser_objc_at_property_declaration (c_parser *); 1497 static void c_parser_objc_at_synthesize_declaration (c_parser *); 1498 static void c_parser_objc_at_dynamic_declaration (c_parser *); 1499 static bool c_parser_objc_diagnose_bad_element_prefix 1500 (c_parser *, struct c_declspecs *); 1501 1502 static void c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass); 1503 1504 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9). 1505 1506 translation-unit: 1507 external-declarations 1508 1509 external-declarations: 1510 external-declaration 1511 external-declarations external-declaration 1512 1513 GNU extensions: 1514 1515 translation-unit: 1516 empty 1517 */ 1518 1519 static void 1520 c_parser_translation_unit (c_parser *parser) 1521 { 1522 if (c_parser_next_token_is (parser, CPP_EOF)) 1523 { 1524 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic, 1525 "ISO C forbids an empty translation unit"); 1526 } 1527 else 1528 { 1529 void *obstack_position = obstack_alloc (&parser_obstack, 0); 1530 mark_valid_location_for_stdc_pragma (false); 1531 do 1532 { 1533 ggc_collect (); 1534 c_parser_external_declaration (parser); 1535 obstack_free (&parser_obstack, obstack_position); 1536 } 1537 while (c_parser_next_token_is_not (parser, CPP_EOF)); 1538 } 1539 1540 unsigned int i; 1541 tree decl; 1542 FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl) 1543 if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node) 1544 error ("storage size of %q+D isn%'t known", decl); 1545 } 1546 1547 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9). 1548 1549 external-declaration: 1550 function-definition 1551 declaration 1552 1553 GNU extensions: 1554 1555 external-declaration: 1556 asm-definition 1557 ; 1558 __extension__ external-declaration 1559 1560 Objective-C: 1561 1562 external-declaration: 1563 objc-class-definition 1564 objc-class-declaration 1565 objc-alias-declaration 1566 objc-protocol-definition 1567 objc-method-definition 1568 @end 1569 */ 1570 1571 static void 1572 c_parser_external_declaration (c_parser *parser) 1573 { 1574 int ext; 1575 switch (c_parser_peek_token (parser)->type) 1576 { 1577 case CPP_KEYWORD: 1578 switch (c_parser_peek_token (parser)->keyword) 1579 { 1580 case RID_EXTENSION: 1581 ext = disable_extension_diagnostics (); 1582 c_parser_consume_token (parser); 1583 c_parser_external_declaration (parser); 1584 restore_extension_diagnostics (ext); 1585 break; 1586 case RID_ASM: 1587 c_parser_asm_definition (parser); 1588 break; 1589 case RID_AT_INTERFACE: 1590 case RID_AT_IMPLEMENTATION: 1591 gcc_assert (c_dialect_objc ()); 1592 c_parser_objc_class_definition (parser, NULL_TREE); 1593 break; 1594 case RID_AT_CLASS: 1595 gcc_assert (c_dialect_objc ()); 1596 c_parser_objc_class_declaration (parser); 1597 break; 1598 case RID_AT_ALIAS: 1599 gcc_assert (c_dialect_objc ()); 1600 c_parser_objc_alias_declaration (parser); 1601 break; 1602 case RID_AT_PROTOCOL: 1603 gcc_assert (c_dialect_objc ()); 1604 c_parser_objc_protocol_definition (parser, NULL_TREE); 1605 break; 1606 case RID_AT_PROPERTY: 1607 gcc_assert (c_dialect_objc ()); 1608 c_parser_objc_at_property_declaration (parser); 1609 break; 1610 case RID_AT_SYNTHESIZE: 1611 gcc_assert (c_dialect_objc ()); 1612 c_parser_objc_at_synthesize_declaration (parser); 1613 break; 1614 case RID_AT_DYNAMIC: 1615 gcc_assert (c_dialect_objc ()); 1616 c_parser_objc_at_dynamic_declaration (parser); 1617 break; 1618 case RID_AT_END: 1619 gcc_assert (c_dialect_objc ()); 1620 c_parser_consume_token (parser); 1621 objc_finish_implementation (); 1622 break; 1623 default: 1624 goto decl_or_fndef; 1625 } 1626 break; 1627 case CPP_SEMICOLON: 1628 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic, 1629 "ISO C does not allow extra %<;%> outside of a function"); 1630 c_parser_consume_token (parser); 1631 break; 1632 case CPP_PRAGMA: 1633 mark_valid_location_for_stdc_pragma (true); 1634 c_parser_pragma (parser, pragma_external, NULL); 1635 mark_valid_location_for_stdc_pragma (false); 1636 break; 1637 case CPP_PLUS: 1638 case CPP_MINUS: 1639 if (c_dialect_objc ()) 1640 { 1641 c_parser_objc_method_definition (parser); 1642 break; 1643 } 1644 /* Else fall through, and yield a syntax error trying to parse 1645 as a declaration or function definition. */ 1646 /* FALLTHRU */ 1647 default: 1648 decl_or_fndef: 1649 /* A declaration or a function definition (or, in Objective-C, 1650 an @interface or @protocol with prefix attributes). We can 1651 only tell which after parsing the declaration specifiers, if 1652 any, and the first declarator. */ 1653 c_parser_declaration_or_fndef (parser, true, true, true, false, true, 1654 NULL, vNULL); 1655 break; 1656 } 1657 } 1658 1659 static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token>); 1660 static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool); 1661 1662 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */ 1663 1664 static void 1665 add_debug_begin_stmt (location_t loc) 1666 { 1667 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */ 1668 if (!MAY_HAVE_DEBUG_MARKER_STMTS || !building_stmt_list_p ()) 1669 return; 1670 1671 tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node); 1672 SET_EXPR_LOCATION (stmt, loc); 1673 add_stmt (stmt); 1674 } 1675 1676 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99 1677 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition 1678 is accepted; otherwise (old-style parameter declarations) only other 1679 declarations are accepted. If STATIC_ASSERT_OK is true, a static 1680 assertion is accepted; otherwise (old-style parameter declarations) 1681 it is not. If NESTED is true, we are inside a function or parsing 1682 old-style parameter declarations; any functions encountered are 1683 nested functions and declaration specifiers are required; otherwise 1684 we are at top level and functions are normal functions and 1685 declaration specifiers may be optional. If EMPTY_OK is true, empty 1686 declarations are OK (subject to all other constraints); otherwise 1687 (old-style parameter declarations) they are diagnosed. If 1688 START_ATTR_OK is true, the declaration specifiers may start with 1689 attributes; otherwise they may not. 1690 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed 1691 declaration when parsing an Objective-C foreach statement. 1692 FALLTHRU_ATTR_P is used to signal whether this function parsed 1693 "__attribute__((fallthrough));". 1694 1695 declaration: 1696 declaration-specifiers init-declarator-list[opt] ; 1697 static_assert-declaration 1698 1699 function-definition: 1700 declaration-specifiers[opt] declarator declaration-list[opt] 1701 compound-statement 1702 1703 declaration-list: 1704 declaration 1705 declaration-list declaration 1706 1707 init-declarator-list: 1708 init-declarator 1709 init-declarator-list , init-declarator 1710 1711 init-declarator: 1712 declarator simple-asm-expr[opt] attributes[opt] 1713 declarator simple-asm-expr[opt] attributes[opt] = initializer 1714 1715 GNU extensions: 1716 1717 nested-function-definition: 1718 declaration-specifiers declarator declaration-list[opt] 1719 compound-statement 1720 1721 attribute ; 1722 1723 Objective-C: 1724 attributes objc-class-definition 1725 attributes objc-category-definition 1726 attributes objc-protocol-definition 1727 1728 The simple-asm-expr and attributes are GNU extensions. 1729 1730 This function does not handle __extension__; that is handled in its 1731 callers. ??? Following the old parser, __extension__ may start 1732 external declarations, declarations in functions and declarations 1733 at the start of "for" loops, but not old-style parameter 1734 declarations. 1735 1736 C99 requires declaration specifiers in a function definition; the 1737 absence is diagnosed through the diagnosis of implicit int. In GNU 1738 C we also allow but diagnose declarations without declaration 1739 specifiers, but only at top level (elsewhere they conflict with 1740 other syntax). 1741 1742 In Objective-C, declarations of the looping variable in a foreach 1743 statement are exceptionally terminated by 'in' (for example, 'for 1744 (NSObject *object in array) { ... }'). 1745 1746 OpenMP: 1747 1748 declaration: 1749 threadprivate-directive 1750 1751 GIMPLE: 1752 1753 gimple-function-definition: 1754 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator 1755 declaration-list[opt] compound-statement 1756 1757 rtl-function-definition: 1758 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator 1759 declaration-list[opt] compound-statement */ 1760 1761 static void 1762 c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, 1763 bool static_assert_ok, bool empty_ok, 1764 bool nested, bool start_attr_ok, 1765 tree *objc_foreach_object_declaration, 1766 vec<c_token> omp_declare_simd_clauses, 1767 struct oacc_routine_data *oacc_routine_data, 1768 bool *fallthru_attr_p) 1769 { 1770 struct c_declspecs *specs; 1771 tree prefix_attrs; 1772 tree all_prefix_attrs; 1773 bool diagnosed_no_specs = false; 1774 location_t here = c_parser_peek_token (parser)->location; 1775 1776 add_debug_begin_stmt (c_parser_peek_token (parser)->location); 1777 1778 if (static_assert_ok 1779 && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT)) 1780 { 1781 c_parser_static_assert_declaration (parser); 1782 return; 1783 } 1784 specs = build_null_declspecs (); 1785 1786 /* Try to detect an unknown type name when we have "A B" or "A *B". */ 1787 if (c_parser_peek_token (parser)->type == CPP_NAME 1788 && c_parser_peek_token (parser)->id_kind == C_ID_ID 1789 && (c_parser_peek_2nd_token (parser)->type == CPP_NAME 1790 || c_parser_peek_2nd_token (parser)->type == CPP_MULT) 1791 && (!nested || !lookup_name (c_parser_peek_token (parser)->value))) 1792 { 1793 tree name = c_parser_peek_token (parser)->value; 1794 1795 /* Issue a warning about NAME being an unknown type name, perhaps 1796 with some kind of hint. 1797 If the user forgot a "struct" etc, suggest inserting 1798 it. Otherwise, attempt to look for misspellings. */ 1799 gcc_rich_location richloc (here); 1800 if (tag_exists_p (RECORD_TYPE, name)) 1801 { 1802 /* This is not C++ with its implicit typedef. */ 1803 richloc.add_fixit_insert_before ("struct "); 1804 error_at (&richloc, 1805 "unknown type name %qE;" 1806 " use %<struct%> keyword to refer to the type", 1807 name); 1808 } 1809 else if (tag_exists_p (UNION_TYPE, name)) 1810 { 1811 richloc.add_fixit_insert_before ("union "); 1812 error_at (&richloc, 1813 "unknown type name %qE;" 1814 " use %<union%> keyword to refer to the type", 1815 name); 1816 } 1817 else if (tag_exists_p (ENUMERAL_TYPE, name)) 1818 { 1819 richloc.add_fixit_insert_before ("enum "); 1820 error_at (&richloc, 1821 "unknown type name %qE;" 1822 " use %<enum%> keyword to refer to the type", 1823 name); 1824 } 1825 else 1826 { 1827 auto_diagnostic_group d; 1828 name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME, 1829 here); 1830 if (const char *suggestion = hint.suggestion ()) 1831 { 1832 richloc.add_fixit_replace (suggestion); 1833 error_at (&richloc, 1834 "unknown type name %qE; did you mean %qs?", 1835 name, suggestion); 1836 } 1837 else 1838 error_at (here, "unknown type name %qE", name); 1839 } 1840 1841 /* Parse declspecs normally to get a correct pointer type, but avoid 1842 a further "fails to be a type name" error. Refuse nested functions 1843 since it is not how the user likely wants us to recover. */ 1844 c_parser_peek_token (parser)->type = CPP_KEYWORD; 1845 c_parser_peek_token (parser)->keyword = RID_VOID; 1846 c_parser_peek_token (parser)->value = error_mark_node; 1847 fndef_ok = !nested; 1848 } 1849 1850 c_parser_declspecs (parser, specs, true, true, start_attr_ok, 1851 true, true, cla_nonabstract_decl); 1852 if (parser->error) 1853 { 1854 c_parser_skip_to_end_of_block_or_statement (parser); 1855 return; 1856 } 1857 if (nested && !specs->declspecs_seen_p) 1858 { 1859 c_parser_error (parser, "expected declaration specifiers"); 1860 c_parser_skip_to_end_of_block_or_statement (parser); 1861 return; 1862 } 1863 1864 finish_declspecs (specs); 1865 bool auto_type_p = specs->typespec_word == cts_auto_type; 1866 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 1867 { 1868 if (auto_type_p) 1869 error_at (here, "%<__auto_type%> in empty declaration"); 1870 else if (specs->typespec_kind == ctsk_none 1871 && attribute_fallthrough_p (specs->attrs)) 1872 { 1873 if (fallthru_attr_p != NULL) 1874 *fallthru_attr_p = true; 1875 tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH, 1876 void_type_node, 0); 1877 add_stmt (fn); 1878 } 1879 else if (empty_ok) 1880 shadow_tag (specs); 1881 else 1882 { 1883 shadow_tag_warned (specs, 1); 1884 pedwarn (here, 0, "empty declaration"); 1885 } 1886 c_parser_consume_token (parser); 1887 if (oacc_routine_data) 1888 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false); 1889 return; 1890 } 1891 1892 /* Provide better error recovery. Note that a type name here is usually 1893 better diagnosed as a redeclaration. */ 1894 if (empty_ok 1895 && specs->typespec_kind == ctsk_tagdef 1896 && c_parser_next_token_starts_declspecs (parser) 1897 && !c_parser_next_token_is (parser, CPP_NAME)) 1898 { 1899 c_parser_error (parser, "expected %<;%>, identifier or %<(%>"); 1900 parser->error = false; 1901 shadow_tag_warned (specs, 1); 1902 return; 1903 } 1904 else if (c_dialect_objc () && !auto_type_p) 1905 { 1906 /* Prefix attributes are an error on method decls. */ 1907 switch (c_parser_peek_token (parser)->type) 1908 { 1909 case CPP_PLUS: 1910 case CPP_MINUS: 1911 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs)) 1912 return; 1913 if (specs->attrs) 1914 { 1915 warning_at (c_parser_peek_token (parser)->location, 1916 OPT_Wattributes, 1917 "prefix attributes are ignored for methods"); 1918 specs->attrs = NULL_TREE; 1919 } 1920 if (fndef_ok) 1921 c_parser_objc_method_definition (parser); 1922 else 1923 c_parser_objc_methodproto (parser); 1924 return; 1925 break; 1926 default: 1927 break; 1928 } 1929 /* This is where we parse 'attributes @interface ...', 1930 'attributes @implementation ...', 'attributes @protocol ...' 1931 (where attributes could be, for example, __attribute__ 1932 ((deprecated)). 1933 */ 1934 switch (c_parser_peek_token (parser)->keyword) 1935 { 1936 case RID_AT_INTERFACE: 1937 { 1938 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs)) 1939 return; 1940 c_parser_objc_class_definition (parser, specs->attrs); 1941 return; 1942 } 1943 break; 1944 case RID_AT_IMPLEMENTATION: 1945 { 1946 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs)) 1947 return; 1948 if (specs->attrs) 1949 { 1950 warning_at (c_parser_peek_token (parser)->location, 1951 OPT_Wattributes, 1952 "prefix attributes are ignored for implementations"); 1953 specs->attrs = NULL_TREE; 1954 } 1955 c_parser_objc_class_definition (parser, NULL_TREE); 1956 return; 1957 } 1958 break; 1959 case RID_AT_PROTOCOL: 1960 { 1961 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs)) 1962 return; 1963 c_parser_objc_protocol_definition (parser, specs->attrs); 1964 return; 1965 } 1966 break; 1967 case RID_AT_ALIAS: 1968 case RID_AT_CLASS: 1969 case RID_AT_END: 1970 case RID_AT_PROPERTY: 1971 if (specs->attrs) 1972 { 1973 c_parser_error (parser, "unexpected attribute"); 1974 specs->attrs = NULL; 1975 } 1976 break; 1977 default: 1978 break; 1979 } 1980 } 1981 else if (attribute_fallthrough_p (specs->attrs)) 1982 warning_at (here, OPT_Wattributes, 1983 "%<fallthrough%> attribute not followed by %<;%>"); 1984 1985 pending_xref_error (); 1986 prefix_attrs = specs->attrs; 1987 all_prefix_attrs = prefix_attrs; 1988 specs->attrs = NULL_TREE; 1989 while (true) 1990 { 1991 struct c_declarator *declarator; 1992 bool dummy = false; 1993 timevar_id_t tv; 1994 tree fnbody = NULL_TREE; 1995 /* Declaring either one or more declarators (in which case we 1996 should diagnose if there were no declaration specifiers) or a 1997 function definition (in which case the diagnostic for 1998 implicit int suffices). */ 1999 declarator = c_parser_declarator (parser, 2000 specs->typespec_kind != ctsk_none, 2001 C_DTR_NORMAL, &dummy); 2002 if (declarator == NULL) 2003 { 2004 if (omp_declare_simd_clauses.exists ()) 2005 c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE, 2006 omp_declare_simd_clauses); 2007 if (oacc_routine_data) 2008 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false); 2009 c_parser_skip_to_end_of_block_or_statement (parser); 2010 return; 2011 } 2012 if (auto_type_p && declarator->kind != cdk_id) 2013 { 2014 error_at (here, 2015 "%<__auto_type%> requires a plain identifier" 2016 " as declarator"); 2017 c_parser_skip_to_end_of_block_or_statement (parser); 2018 return; 2019 } 2020 if (c_parser_next_token_is (parser, CPP_EQ) 2021 || c_parser_next_token_is (parser, CPP_COMMA) 2022 || c_parser_next_token_is (parser, CPP_SEMICOLON) 2023 || c_parser_next_token_is_keyword (parser, RID_ASM) 2024 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE) 2025 || c_parser_next_token_is_keyword (parser, RID_IN)) 2026 { 2027 tree asm_name = NULL_TREE; 2028 tree postfix_attrs = NULL_TREE; 2029 if (!diagnosed_no_specs && !specs->declspecs_seen_p) 2030 { 2031 diagnosed_no_specs = true; 2032 pedwarn (here, 0, "data definition has no type or storage class"); 2033 } 2034 /* Having seen a data definition, there cannot now be a 2035 function definition. */ 2036 fndef_ok = false; 2037 if (c_parser_next_token_is_keyword (parser, RID_ASM)) 2038 asm_name = c_parser_simple_asm_expr (parser); 2039 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 2040 { 2041 postfix_attrs = c_parser_attributes (parser); 2042 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 2043 { 2044 /* This means there is an attribute specifier after 2045 the declarator in a function definition. Provide 2046 some more information for the user. */ 2047 error_at (here, "attributes should be specified before the " 2048 "declarator in a function definition"); 2049 c_parser_skip_to_end_of_block_or_statement (parser); 2050 return; 2051 } 2052 } 2053 if (c_parser_next_token_is (parser, CPP_EQ)) 2054 { 2055 tree d; 2056 struct c_expr init; 2057 location_t init_loc; 2058 c_parser_consume_token (parser); 2059 if (auto_type_p) 2060 { 2061 init_loc = c_parser_peek_token (parser)->location; 2062 rich_location richloc (line_table, init_loc); 2063 start_init (NULL_TREE, asm_name, global_bindings_p (), &richloc); 2064 /* A parameter is initialized, which is invalid. Don't 2065 attempt to instrument the initializer. */ 2066 int flag_sanitize_save = flag_sanitize; 2067 if (nested && !empty_ok) 2068 flag_sanitize = 0; 2069 init = c_parser_expr_no_commas (parser, NULL); 2070 flag_sanitize = flag_sanitize_save; 2071 if (TREE_CODE (init.value) == COMPONENT_REF 2072 && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1))) 2073 error_at (here, 2074 "%<__auto_type%> used with a bit-field" 2075 " initializer"); 2076 init = convert_lvalue_to_rvalue (init_loc, init, true, true); 2077 tree init_type = TREE_TYPE (init.value); 2078 /* As with typeof, remove all qualifiers from atomic types. */ 2079 if (init_type != error_mark_node && TYPE_ATOMIC (init_type)) 2080 init_type 2081 = c_build_qualified_type (init_type, TYPE_UNQUALIFIED); 2082 bool vm_type = variably_modified_type_p (init_type, 2083 NULL_TREE); 2084 if (vm_type) 2085 init.value = save_expr (init.value); 2086 finish_init (); 2087 specs->typespec_kind = ctsk_typeof; 2088 specs->locations[cdw_typedef] = init_loc; 2089 specs->typedef_p = true; 2090 specs->type = init_type; 2091 if (vm_type) 2092 { 2093 bool maybe_const = true; 2094 tree type_expr = c_fully_fold (init.value, false, 2095 &maybe_const); 2096 specs->expr_const_operands &= maybe_const; 2097 if (specs->expr) 2098 specs->expr = build2 (COMPOUND_EXPR, 2099 TREE_TYPE (type_expr), 2100 specs->expr, type_expr); 2101 else 2102 specs->expr = type_expr; 2103 } 2104 d = start_decl (declarator, specs, true, 2105 chainon (postfix_attrs, all_prefix_attrs)); 2106 if (!d) 2107 d = error_mark_node; 2108 if (omp_declare_simd_clauses.exists ()) 2109 c_finish_omp_declare_simd (parser, d, NULL_TREE, 2110 omp_declare_simd_clauses); 2111 } 2112 else 2113 { 2114 /* The declaration of the variable is in effect while 2115 its initializer is parsed. */ 2116 d = start_decl (declarator, specs, true, 2117 chainon (postfix_attrs, all_prefix_attrs)); 2118 if (!d) 2119 d = error_mark_node; 2120 if (omp_declare_simd_clauses.exists ()) 2121 c_finish_omp_declare_simd (parser, d, NULL_TREE, 2122 omp_declare_simd_clauses); 2123 init_loc = c_parser_peek_token (parser)->location; 2124 rich_location richloc (line_table, init_loc); 2125 start_init (d, asm_name, global_bindings_p (), &richloc); 2126 /* A parameter is initialized, which is invalid. Don't 2127 attempt to instrument the initializer. */ 2128 int flag_sanitize_save = flag_sanitize; 2129 if (TREE_CODE (d) == PARM_DECL) 2130 flag_sanitize = 0; 2131 init = c_parser_initializer (parser); 2132 flag_sanitize = flag_sanitize_save; 2133 finish_init (); 2134 } 2135 if (oacc_routine_data) 2136 c_finish_oacc_routine (oacc_routine_data, d, false); 2137 if (d != error_mark_node) 2138 { 2139 maybe_warn_string_init (init_loc, TREE_TYPE (d), init); 2140 finish_decl (d, init_loc, init.value, 2141 init.original_type, asm_name); 2142 } 2143 } 2144 else 2145 { 2146 if (auto_type_p) 2147 { 2148 error_at (here, 2149 "%<__auto_type%> requires an initialized " 2150 "data declaration"); 2151 c_parser_skip_to_end_of_block_or_statement (parser); 2152 return; 2153 } 2154 tree d = start_decl (declarator, specs, false, 2155 chainon (postfix_attrs, 2156 all_prefix_attrs)); 2157 if (d 2158 && TREE_CODE (d) == FUNCTION_DECL 2159 && declarator->kind == cdk_function 2160 && DECL_ARGUMENTS (d) == NULL_TREE 2161 && DECL_INITIAL (d) == NULL_TREE) 2162 DECL_ARGUMENTS (d) = declarator->u.arg_info->parms; 2163 if (omp_declare_simd_clauses.exists ()) 2164 { 2165 tree parms = NULL_TREE; 2166 if (d && TREE_CODE (d) == FUNCTION_DECL) 2167 { 2168 struct c_declarator *ce = declarator; 2169 while (ce != NULL) 2170 if (ce->kind == cdk_function) 2171 { 2172 parms = ce->u.arg_info->parms; 2173 break; 2174 } 2175 else 2176 ce = ce->declarator; 2177 } 2178 if (parms) 2179 temp_store_parm_decls (d, parms); 2180 c_finish_omp_declare_simd (parser, d, parms, 2181 omp_declare_simd_clauses); 2182 if (parms) 2183 temp_pop_parm_decls (); 2184 } 2185 if (oacc_routine_data) 2186 c_finish_oacc_routine (oacc_routine_data, d, false); 2187 if (d) 2188 finish_decl (d, UNKNOWN_LOCATION, NULL_TREE, 2189 NULL_TREE, asm_name); 2190 2191 if (c_parser_next_token_is_keyword (parser, RID_IN)) 2192 { 2193 if (d) 2194 *objc_foreach_object_declaration = d; 2195 else 2196 *objc_foreach_object_declaration = error_mark_node; 2197 } 2198 } 2199 if (c_parser_next_token_is (parser, CPP_COMMA)) 2200 { 2201 if (auto_type_p) 2202 { 2203 error_at (here, 2204 "%<__auto_type%> may only be used with" 2205 " a single declarator"); 2206 c_parser_skip_to_end_of_block_or_statement (parser); 2207 return; 2208 } 2209 c_parser_consume_token (parser); 2210 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 2211 all_prefix_attrs = chainon (c_parser_attributes (parser), 2212 prefix_attrs); 2213 else 2214 all_prefix_attrs = prefix_attrs; 2215 continue; 2216 } 2217 else if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 2218 { 2219 c_parser_consume_token (parser); 2220 return; 2221 } 2222 else if (c_parser_next_token_is_keyword (parser, RID_IN)) 2223 { 2224 /* This can only happen in Objective-C: we found the 2225 'in' that terminates the declaration inside an 2226 Objective-C foreach statement. Do not consume the 2227 token, so that the caller can use it to determine 2228 that this indeed is a foreach context. */ 2229 return; 2230 } 2231 else 2232 { 2233 c_parser_error (parser, "expected %<,%> or %<;%>"); 2234 c_parser_skip_to_end_of_block_or_statement (parser); 2235 return; 2236 } 2237 } 2238 else if (auto_type_p) 2239 { 2240 error_at (here, 2241 "%<__auto_type%> requires an initialized data declaration"); 2242 c_parser_skip_to_end_of_block_or_statement (parser); 2243 return; 2244 } 2245 else if (!fndef_ok) 2246 { 2247 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, " 2248 "%<asm%> or %<__attribute__%>"); 2249 c_parser_skip_to_end_of_block_or_statement (parser); 2250 return; 2251 } 2252 /* Function definition (nested or otherwise). */ 2253 if (nested) 2254 { 2255 pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions"); 2256 c_push_function_context (); 2257 } 2258 if (!start_function (specs, declarator, all_prefix_attrs)) 2259 { 2260 /* At this point we've consumed: 2261 declaration-specifiers declarator 2262 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON, 2263 RID_ASM, RID_ATTRIBUTE, or RID_IN, 2264 but the 2265 declaration-specifiers declarator 2266 aren't grokkable as a function definition, so we have 2267 an error. */ 2268 gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON)); 2269 if (c_parser_next_token_starts_declspecs (parser)) 2270 { 2271 /* If we have 2272 declaration-specifiers declarator decl-specs 2273 then assume we have a missing semicolon, which would 2274 give us: 2275 declaration-specifiers declarator decl-specs 2276 ^ 2277 ; 2278 <~~~~~~~~~ declaration ~~~~~~~~~~> 2279 Use c_parser_require to get an error with a fix-it hint. */ 2280 c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"); 2281 parser->error = false; 2282 } 2283 else 2284 { 2285 /* This can appear in many cases looking nothing like a 2286 function definition, so we don't give a more specific 2287 error suggesting there was one. */ 2288 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> " 2289 "or %<__attribute__%>"); 2290 } 2291 if (nested) 2292 c_pop_function_context (); 2293 break; 2294 } 2295 2296 if (DECL_DECLARED_INLINE_P (current_function_decl)) 2297 tv = TV_PARSE_INLINE; 2298 else 2299 tv = TV_PARSE_FUNC; 2300 auto_timevar at (g_timer, tv); 2301 2302 /* Parse old-style parameter declarations. ??? Attributes are 2303 not allowed to start declaration specifiers here because of a 2304 syntax conflict between a function declaration with attribute 2305 suffix and a function definition with an attribute prefix on 2306 first old-style parameter declaration. Following the old 2307 parser, they are not accepted on subsequent old-style 2308 parameter declarations either. However, there is no 2309 ambiguity after the first declaration, nor indeed on the 2310 first as long as we don't allow postfix attributes after a 2311 declarator with a nonempty identifier list in a definition; 2312 and postfix attributes have never been accepted here in 2313 function definitions either. */ 2314 while (c_parser_next_token_is_not (parser, CPP_EOF) 2315 && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE)) 2316 c_parser_declaration_or_fndef (parser, false, false, false, 2317 true, false, NULL, vNULL); 2318 store_parm_decls (); 2319 if (omp_declare_simd_clauses.exists ()) 2320 c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE, 2321 omp_declare_simd_clauses); 2322 if (oacc_routine_data) 2323 c_finish_oacc_routine (oacc_routine_data, current_function_decl, true); 2324 DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus 2325 = c_parser_peek_token (parser)->location; 2326 2327 /* If the definition was marked with __RTL, use the RTL parser now, 2328 consuming the function body. */ 2329 if (specs->declspec_il == cdil_rtl) 2330 { 2331 c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass); 2332 2333 /* Normally, store_parm_decls sets next_is_function_body, 2334 anticipating a function body. We need a push_scope/pop_scope 2335 pair to flush out this state, or subsequent function parsing 2336 will go wrong. */ 2337 push_scope (); 2338 pop_scope (); 2339 2340 finish_function (); 2341 return; 2342 } 2343 /* If the definition was marked with __GIMPLE then parse the 2344 function body as GIMPLE. */ 2345 else if (specs->declspec_il != cdil_none) 2346 { 2347 bool saved = in_late_binary_op; 2348 in_late_binary_op = true; 2349 c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass, 2350 specs->declspec_il); 2351 in_late_binary_op = saved; 2352 } 2353 else 2354 fnbody = c_parser_compound_statement (parser); 2355 tree fndecl = current_function_decl; 2356 if (nested) 2357 { 2358 tree decl = current_function_decl; 2359 /* Mark nested functions as needing static-chain initially. 2360 lower_nested_functions will recompute it but the 2361 DECL_STATIC_CHAIN flag is also used before that happens, 2362 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */ 2363 DECL_STATIC_CHAIN (decl) = 1; 2364 add_stmt (fnbody); 2365 finish_function (); 2366 c_pop_function_context (); 2367 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl)); 2368 } 2369 else 2370 { 2371 if (fnbody) 2372 add_stmt (fnbody); 2373 finish_function (); 2374 } 2375 /* Get rid of the empty stmt list for GIMPLE/RTL. */ 2376 if (specs->declspec_il != cdil_none) 2377 DECL_SAVED_TREE (fndecl) = NULL_TREE; 2378 2379 break; 2380 } 2381 } 2382 2383 /* Parse an asm-definition (asm() outside a function body). This is a 2384 GNU extension. 2385 2386 asm-definition: 2387 simple-asm-expr ; 2388 */ 2389 2390 static void 2391 c_parser_asm_definition (c_parser *parser) 2392 { 2393 tree asm_str = c_parser_simple_asm_expr (parser); 2394 if (asm_str) 2395 symtab->finalize_toplevel_asm (asm_str); 2396 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 2397 } 2398 2399 /* Parse a static assertion (C11 6.7.10). 2400 2401 static_assert-declaration: 2402 static_assert-declaration-no-semi ; 2403 */ 2404 2405 static void 2406 c_parser_static_assert_declaration (c_parser *parser) 2407 { 2408 c_parser_static_assert_declaration_no_semi (parser); 2409 if (parser->error 2410 || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>")) 2411 c_parser_skip_to_end_of_block_or_statement (parser); 2412 } 2413 2414 /* Parse a static assertion (C11 6.7.10), without the trailing 2415 semicolon. 2416 2417 static_assert-declaration-no-semi: 2418 _Static_assert ( constant-expression , string-literal ) 2419 2420 C2X: 2421 static_assert-declaration-no-semi: 2422 _Static_assert ( constant-expression ) 2423 */ 2424 2425 static void 2426 c_parser_static_assert_declaration_no_semi (c_parser *parser) 2427 { 2428 location_t assert_loc, value_loc; 2429 tree value; 2430 tree string = NULL_TREE; 2431 2432 gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT)); 2433 assert_loc = c_parser_peek_token (parser)->location; 2434 if (flag_isoc99) 2435 pedwarn_c99 (assert_loc, OPT_Wpedantic, 2436 "ISO C99 does not support %<_Static_assert%>"); 2437 else 2438 pedwarn_c99 (assert_loc, OPT_Wpedantic, 2439 "ISO C90 does not support %<_Static_assert%>"); 2440 c_parser_consume_token (parser); 2441 matching_parens parens; 2442 if (!parens.require_open (parser)) 2443 return; 2444 location_t value_tok_loc = c_parser_peek_token (parser)->location; 2445 value = c_parser_expr_no_commas (parser, NULL).value; 2446 value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc); 2447 parser->lex_untranslated_string = true; 2448 if (c_parser_next_token_is (parser, CPP_COMMA)) 2449 { 2450 c_parser_consume_token (parser); 2451 switch (c_parser_peek_token (parser)->type) 2452 { 2453 case CPP_STRING: 2454 case CPP_STRING16: 2455 case CPP_STRING32: 2456 case CPP_WSTRING: 2457 case CPP_UTF8STRING: 2458 string = c_parser_peek_token (parser)->value; 2459 c_parser_consume_token (parser); 2460 parser->lex_untranslated_string = false; 2461 break; 2462 default: 2463 c_parser_error (parser, "expected string literal"); 2464 parser->lex_untranslated_string = false; 2465 return; 2466 } 2467 } 2468 else if (flag_isoc11) 2469 /* If pedantic for pre-C11, the use of _Static_assert itself will 2470 have been diagnosed, so do not also diagnose the use of this 2471 new C2X feature of _Static_assert. */ 2472 pedwarn_c11 (assert_loc, OPT_Wpedantic, 2473 "ISO C11 does not support omitting the string in " 2474 "%<_Static_assert%>"); 2475 parens.require_close (parser); 2476 2477 if (!INTEGRAL_TYPE_P (TREE_TYPE (value))) 2478 { 2479 error_at (value_loc, "expression in static assertion is not an integer"); 2480 return; 2481 } 2482 if (TREE_CODE (value) != INTEGER_CST) 2483 { 2484 value = c_fully_fold (value, false, NULL); 2485 /* Strip no-op conversions. */ 2486 STRIP_TYPE_NOPS (value); 2487 if (TREE_CODE (value) == INTEGER_CST) 2488 pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion " 2489 "is not an integer constant expression"); 2490 } 2491 if (TREE_CODE (value) != INTEGER_CST) 2492 { 2493 error_at (value_loc, "expression in static assertion is not constant"); 2494 return; 2495 } 2496 constant_expression_warning (value); 2497 if (integer_zerop (value)) 2498 { 2499 if (string) 2500 error_at (assert_loc, "static assertion failed: %E", string); 2501 else 2502 error_at (assert_loc, "static assertion failed"); 2503 } 2504 } 2505 2506 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99 2507 6.7, C11 6.7), adding them to SPECS (which may already include some). 2508 Storage class specifiers are accepted iff SCSPEC_OK; type 2509 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are 2510 accepted iff ALIGNSPEC_OK; attributes are accepted at the start 2511 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. 2512 2513 declaration-specifiers: 2514 storage-class-specifier declaration-specifiers[opt] 2515 type-specifier declaration-specifiers[opt] 2516 type-qualifier declaration-specifiers[opt] 2517 function-specifier declaration-specifiers[opt] 2518 alignment-specifier declaration-specifiers[opt] 2519 2520 Function specifiers (inline) are from C99, and are currently 2521 handled as storage class specifiers, as is __thread. Alignment 2522 specifiers are from C11. 2523 2524 C90 6.5.1, C99 6.7.1, C11 6.7.1: 2525 storage-class-specifier: 2526 typedef 2527 extern 2528 static 2529 auto 2530 register 2531 _Thread_local 2532 2533 (_Thread_local is new in C11.) 2534 2535 C99 6.7.4, C11 6.7.4: 2536 function-specifier: 2537 inline 2538 _Noreturn 2539 2540 (_Noreturn is new in C11.) 2541 2542 C90 6.5.2, C99 6.7.2, C11 6.7.2: 2543 type-specifier: 2544 void 2545 char 2546 short 2547 int 2548 long 2549 float 2550 double 2551 signed 2552 unsigned 2553 _Bool 2554 _Complex 2555 [_Imaginary removed in C99 TC2] 2556 struct-or-union-specifier 2557 enum-specifier 2558 typedef-name 2559 atomic-type-specifier 2560 2561 (_Bool and _Complex are new in C99.) 2562 (atomic-type-specifier is new in C11.) 2563 2564 C90 6.5.3, C99 6.7.3, C11 6.7.3: 2565 2566 type-qualifier: 2567 const 2568 restrict 2569 volatile 2570 address-space-qualifier 2571 _Atomic 2572 2573 (restrict is new in C99.) 2574 (_Atomic is new in C11.) 2575 2576 GNU extensions: 2577 2578 declaration-specifiers: 2579 attributes declaration-specifiers[opt] 2580 2581 type-qualifier: 2582 address-space 2583 2584 address-space: 2585 identifier recognized by the target 2586 2587 storage-class-specifier: 2588 __thread 2589 2590 type-specifier: 2591 typeof-specifier 2592 __auto_type 2593 __intN 2594 _Decimal32 2595 _Decimal64 2596 _Decimal128 2597 _Fract 2598 _Accum 2599 _Sat 2600 2601 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037: 2602 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf) 2603 2604 atomic-type-specifier 2605 _Atomic ( type-name ) 2606 2607 Objective-C: 2608 2609 type-specifier: 2610 class-name objc-protocol-refs[opt] 2611 typedef-name objc-protocol-refs 2612 objc-protocol-refs 2613 */ 2614 2615 void 2616 c_parser_declspecs (c_parser *parser, struct c_declspecs *specs, 2617 bool scspec_ok, bool typespec_ok, bool start_attr_ok, 2618 bool alignspec_ok, bool auto_type_ok, 2619 enum c_lookahead_kind la) 2620 { 2621 bool attrs_ok = start_attr_ok; 2622 bool seen_type = specs->typespec_kind != ctsk_none; 2623 2624 if (!typespec_ok) 2625 gcc_assert (la == cla_prefer_id); 2626 2627 while (c_parser_next_token_is (parser, CPP_NAME) 2628 || c_parser_next_token_is (parser, CPP_KEYWORD) 2629 || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS))) 2630 { 2631 struct c_typespec t; 2632 tree attrs; 2633 tree align; 2634 location_t loc = c_parser_peek_token (parser)->location; 2635 2636 /* If we cannot accept a type, exit if the next token must start 2637 one. Also, if we already have seen a tagged definition, 2638 a typename would be an error anyway and likely the user 2639 has simply forgotten a semicolon, so we exit. */ 2640 if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef) 2641 && c_parser_next_tokens_start_typename (parser, la) 2642 && !c_parser_next_token_is_qualifier (parser) 2643 && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS)) 2644 break; 2645 2646 if (c_parser_next_token_is (parser, CPP_NAME)) 2647 { 2648 c_token *name_token = c_parser_peek_token (parser); 2649 tree value = name_token->value; 2650 c_id_kind kind = name_token->id_kind; 2651 2652 if (kind == C_ID_ADDRSPACE) 2653 { 2654 addr_space_t as 2655 = name_token->keyword - RID_FIRST_ADDR_SPACE; 2656 declspecs_add_addrspace (name_token->location, specs, as); 2657 c_parser_consume_token (parser); 2658 attrs_ok = true; 2659 continue; 2660 } 2661 2662 gcc_assert (!c_parser_next_token_is_qualifier (parser)); 2663 2664 /* If we cannot accept a type, and the next token must start one, 2665 exit. Do the same if we already have seen a tagged definition, 2666 since it would be an error anyway and likely the user has simply 2667 forgotten a semicolon. */ 2668 if (seen_type || !c_parser_next_tokens_start_typename (parser, la)) 2669 break; 2670 2671 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or 2672 a C_ID_CLASSNAME. */ 2673 c_parser_consume_token (parser); 2674 seen_type = true; 2675 attrs_ok = true; 2676 if (kind == C_ID_ID) 2677 { 2678 error_at (loc, "unknown type name %qE", value); 2679 t.kind = ctsk_typedef; 2680 t.spec = error_mark_node; 2681 } 2682 else if (kind == C_ID_TYPENAME 2683 && (!c_dialect_objc () 2684 || c_parser_next_token_is_not (parser, CPP_LESS))) 2685 { 2686 t.kind = ctsk_typedef; 2687 /* For a typedef name, record the meaning, not the name. 2688 In case of 'foo foo, bar;'. */ 2689 t.spec = lookup_name (value); 2690 } 2691 else 2692 { 2693 tree proto = NULL_TREE; 2694 gcc_assert (c_dialect_objc ()); 2695 t.kind = ctsk_objc; 2696 if (c_parser_next_token_is (parser, CPP_LESS)) 2697 proto = c_parser_objc_protocol_refs (parser); 2698 t.spec = objc_get_protocol_qualified_type (value, proto); 2699 } 2700 t.expr = NULL_TREE; 2701 t.expr_const_operands = true; 2702 declspecs_add_type (name_token->location, specs, t); 2703 continue; 2704 } 2705 if (c_parser_next_token_is (parser, CPP_LESS)) 2706 { 2707 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" - 2708 nisse@lysator.liu.se. */ 2709 tree proto; 2710 gcc_assert (c_dialect_objc ()); 2711 if (!typespec_ok || seen_type) 2712 break; 2713 proto = c_parser_objc_protocol_refs (parser); 2714 t.kind = ctsk_objc; 2715 t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto); 2716 t.expr = NULL_TREE; 2717 t.expr_const_operands = true; 2718 declspecs_add_type (loc, specs, t); 2719 continue; 2720 } 2721 gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD)); 2722 switch (c_parser_peek_token (parser)->keyword) 2723 { 2724 case RID_STATIC: 2725 case RID_EXTERN: 2726 case RID_REGISTER: 2727 case RID_TYPEDEF: 2728 case RID_INLINE: 2729 case RID_NORETURN: 2730 case RID_AUTO: 2731 case RID_THREAD: 2732 if (!scspec_ok) 2733 goto out; 2734 attrs_ok = true; 2735 /* TODO: Distinguish between function specifiers (inline, noreturn) 2736 and storage class specifiers, either here or in 2737 declspecs_add_scspec. */ 2738 declspecs_add_scspec (loc, specs, 2739 c_parser_peek_token (parser)->value); 2740 c_parser_consume_token (parser); 2741 break; 2742 case RID_AUTO_TYPE: 2743 if (!auto_type_ok) 2744 goto out; 2745 /* Fall through. */ 2746 case RID_UNSIGNED: 2747 case RID_LONG: 2748 case RID_SHORT: 2749 case RID_SIGNED: 2750 case RID_COMPLEX: 2751 case RID_INT: 2752 case RID_CHAR: 2753 case RID_FLOAT: 2754 case RID_DOUBLE: 2755 case RID_VOID: 2756 case RID_DFLOAT32: 2757 case RID_DFLOAT64: 2758 case RID_DFLOAT128: 2759 CASE_RID_FLOATN_NX: 2760 case RID_BOOL: 2761 case RID_FRACT: 2762 case RID_ACCUM: 2763 case RID_SAT: 2764 case RID_INT_N_0: 2765 case RID_INT_N_1: 2766 case RID_INT_N_2: 2767 case RID_INT_N_3: 2768 if (!typespec_ok) 2769 goto out; 2770 attrs_ok = true; 2771 seen_type = true; 2772 if (c_dialect_objc ()) 2773 parser->objc_need_raw_identifier = true; 2774 t.kind = ctsk_resword; 2775 t.spec = c_parser_peek_token (parser)->value; 2776 t.expr = NULL_TREE; 2777 t.expr_const_operands = true; 2778 declspecs_add_type (loc, specs, t); 2779 c_parser_consume_token (parser); 2780 break; 2781 case RID_ENUM: 2782 if (!typespec_ok) 2783 goto out; 2784 attrs_ok = true; 2785 seen_type = true; 2786 t = c_parser_enum_specifier (parser); 2787 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec); 2788 declspecs_add_type (loc, specs, t); 2789 break; 2790 case RID_STRUCT: 2791 case RID_UNION: 2792 if (!typespec_ok) 2793 goto out; 2794 attrs_ok = true; 2795 seen_type = true; 2796 t = c_parser_struct_or_union_specifier (parser); 2797 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec); 2798 declspecs_add_type (loc, specs, t); 2799 break; 2800 case RID_TYPEOF: 2801 /* ??? The old parser rejected typeof after other type 2802 specifiers, but is a syntax error the best way of 2803 handling this? */ 2804 if (!typespec_ok || seen_type) 2805 goto out; 2806 attrs_ok = true; 2807 seen_type = true; 2808 t = c_parser_typeof_specifier (parser); 2809 declspecs_add_type (loc, specs, t); 2810 break; 2811 case RID_ATOMIC: 2812 /* C parser handling of Objective-C constructs needs 2813 checking for correct lvalue-to-rvalue conversions, and 2814 the code in build_modify_expr handling various 2815 Objective-C cases, and that in build_unary_op handling 2816 Objective-C cases for increment / decrement, also needs 2817 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types 2818 and objc_types_are_equivalent may also need updates. */ 2819 if (c_dialect_objc ()) 2820 sorry ("%<_Atomic%> in Objective-C"); 2821 if (flag_isoc99) 2822 pedwarn_c99 (loc, OPT_Wpedantic, 2823 "ISO C99 does not support the %<_Atomic%> qualifier"); 2824 else 2825 pedwarn_c99 (loc, OPT_Wpedantic, 2826 "ISO C90 does not support the %<_Atomic%> qualifier"); 2827 attrs_ok = true; 2828 tree value; 2829 value = c_parser_peek_token (parser)->value; 2830 c_parser_consume_token (parser); 2831 if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 2832 { 2833 /* _Atomic ( type-name ). */ 2834 seen_type = true; 2835 c_parser_consume_token (parser); 2836 struct c_type_name *type = c_parser_type_name (parser); 2837 t.kind = ctsk_typeof; 2838 t.spec = error_mark_node; 2839 t.expr = NULL_TREE; 2840 t.expr_const_operands = true; 2841 if (type != NULL) 2842 t.spec = groktypename (type, &t.expr, 2843 &t.expr_const_operands); 2844 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 2845 "expected %<)%>"); 2846 if (t.spec != error_mark_node) 2847 { 2848 if (TREE_CODE (t.spec) == ARRAY_TYPE) 2849 error_at (loc, "%<_Atomic%>-qualified array type"); 2850 else if (TREE_CODE (t.spec) == FUNCTION_TYPE) 2851 error_at (loc, "%<_Atomic%>-qualified function type"); 2852 else if (TYPE_QUALS (t.spec) != TYPE_UNQUALIFIED) 2853 error_at (loc, "%<_Atomic%> applied to a qualified type"); 2854 else 2855 t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC); 2856 } 2857 declspecs_add_type (loc, specs, t); 2858 } 2859 else 2860 declspecs_add_qual (loc, specs, value); 2861 break; 2862 case RID_CONST: 2863 case RID_VOLATILE: 2864 case RID_RESTRICT: 2865 attrs_ok = true; 2866 declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value); 2867 c_parser_consume_token (parser); 2868 break; 2869 case RID_ATTRIBUTE: 2870 if (!attrs_ok) 2871 goto out; 2872 attrs = c_parser_attributes (parser); 2873 declspecs_add_attrs (loc, specs, attrs); 2874 break; 2875 case RID_ALIGNAS: 2876 if (!alignspec_ok) 2877 goto out; 2878 align = c_parser_alignas_specifier (parser); 2879 declspecs_add_alignas (loc, specs, align); 2880 break; 2881 case RID_GIMPLE: 2882 if (! flag_gimple) 2883 error_at (loc, "%<__GIMPLE%> only valid with %<-fgimple%>"); 2884 c_parser_consume_token (parser); 2885 specs->declspec_il = cdil_gimple; 2886 specs->locations[cdw_gimple] = loc; 2887 c_parser_gimple_or_rtl_pass_list (parser, specs); 2888 break; 2889 case RID_RTL: 2890 c_parser_consume_token (parser); 2891 specs->declspec_il = cdil_rtl; 2892 specs->locations[cdw_rtl] = loc; 2893 c_parser_gimple_or_rtl_pass_list (parser, specs); 2894 break; 2895 default: 2896 goto out; 2897 } 2898 } 2899 out: ; 2900 } 2901 2902 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2). 2903 2904 enum-specifier: 2905 enum attributes[opt] identifier[opt] { enumerator-list } attributes[opt] 2906 enum attributes[opt] identifier[opt] { enumerator-list , } attributes[opt] 2907 enum attributes[opt] identifier 2908 2909 The form with trailing comma is new in C99. The forms with 2910 attributes are GNU extensions. In GNU C, we accept any expression 2911 without commas in the syntax (assignment expressions, not just 2912 conditional expressions); assignment expressions will be diagnosed 2913 as non-constant. 2914 2915 enumerator-list: 2916 enumerator 2917 enumerator-list , enumerator 2918 2919 enumerator: 2920 enumeration-constant 2921 enumeration-constant = constant-expression 2922 2923 GNU Extensions: 2924 2925 enumerator: 2926 enumeration-constant attributes[opt] 2927 enumeration-constant attributes[opt] = constant-expression 2928 2929 */ 2930 2931 static struct c_typespec 2932 c_parser_enum_specifier (c_parser *parser) 2933 { 2934 struct c_typespec ret; 2935 tree attrs; 2936 tree ident = NULL_TREE; 2937 location_t enum_loc; 2938 location_t ident_loc = UNKNOWN_LOCATION; /* Quiet warning. */ 2939 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM)); 2940 c_parser_consume_token (parser); 2941 attrs = c_parser_attributes (parser); 2942 enum_loc = c_parser_peek_token (parser)->location; 2943 /* Set the location in case we create a decl now. */ 2944 c_parser_set_source_position_from_token (c_parser_peek_token (parser)); 2945 if (c_parser_next_token_is (parser, CPP_NAME)) 2946 { 2947 ident = c_parser_peek_token (parser)->value; 2948 ident_loc = c_parser_peek_token (parser)->location; 2949 enum_loc = ident_loc; 2950 c_parser_consume_token (parser); 2951 } 2952 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 2953 { 2954 /* Parse an enum definition. */ 2955 struct c_enum_contents the_enum; 2956 tree type; 2957 tree postfix_attrs; 2958 /* We chain the enumerators in reverse order, then put them in 2959 forward order at the end. */ 2960 tree values; 2961 timevar_push (TV_PARSE_ENUM); 2962 type = start_enum (enum_loc, &the_enum, ident); 2963 values = NULL_TREE; 2964 c_parser_consume_token (parser); 2965 while (true) 2966 { 2967 tree enum_id; 2968 tree enum_value; 2969 tree enum_decl; 2970 bool seen_comma; 2971 c_token *token; 2972 location_t comma_loc = UNKNOWN_LOCATION; /* Quiet warning. */ 2973 location_t decl_loc, value_loc; 2974 if (c_parser_next_token_is_not (parser, CPP_NAME)) 2975 { 2976 /* Give a nicer error for "enum {}". */ 2977 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE) 2978 && !parser->error) 2979 { 2980 error_at (c_parser_peek_token (parser)->location, 2981 "empty enum is invalid"); 2982 parser->error = true; 2983 } 2984 else 2985 c_parser_error (parser, "expected identifier"); 2986 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL); 2987 values = error_mark_node; 2988 break; 2989 } 2990 token = c_parser_peek_token (parser); 2991 enum_id = token->value; 2992 /* Set the location in case we create a decl now. */ 2993 c_parser_set_source_position_from_token (token); 2994 decl_loc = value_loc = token->location; 2995 c_parser_consume_token (parser); 2996 /* Parse any specified attributes. */ 2997 tree enum_attrs = c_parser_attributes (parser); 2998 if (c_parser_next_token_is (parser, CPP_EQ)) 2999 { 3000 c_parser_consume_token (parser); 3001 value_loc = c_parser_peek_token (parser)->location; 3002 enum_value = c_parser_expr_no_commas (parser, NULL).value; 3003 } 3004 else 3005 enum_value = NULL_TREE; 3006 enum_decl = build_enumerator (decl_loc, value_loc, 3007 &the_enum, enum_id, enum_value); 3008 if (enum_attrs) 3009 decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0); 3010 TREE_CHAIN (enum_decl) = values; 3011 values = enum_decl; 3012 seen_comma = false; 3013 if (c_parser_next_token_is (parser, CPP_COMMA)) 3014 { 3015 comma_loc = c_parser_peek_token (parser)->location; 3016 seen_comma = true; 3017 c_parser_consume_token (parser); 3018 } 3019 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 3020 { 3021 if (seen_comma) 3022 pedwarn_c90 (comma_loc, OPT_Wpedantic, 3023 "comma at end of enumerator list"); 3024 c_parser_consume_token (parser); 3025 break; 3026 } 3027 if (!seen_comma) 3028 { 3029 c_parser_error (parser, "expected %<,%> or %<}%>"); 3030 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL); 3031 values = error_mark_node; 3032 break; 3033 } 3034 } 3035 postfix_attrs = c_parser_attributes (parser); 3036 ret.spec = finish_enum (type, nreverse (values), 3037 chainon (attrs, postfix_attrs)); 3038 ret.kind = ctsk_tagdef; 3039 ret.expr = NULL_TREE; 3040 ret.expr_const_operands = true; 3041 timevar_pop (TV_PARSE_ENUM); 3042 return ret; 3043 } 3044 else if (!ident) 3045 { 3046 c_parser_error (parser, "expected %<{%>"); 3047 ret.spec = error_mark_node; 3048 ret.kind = ctsk_tagref; 3049 ret.expr = NULL_TREE; 3050 ret.expr_const_operands = true; 3051 return ret; 3052 } 3053 ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident); 3054 /* In ISO C, enumerated types can be referred to only if already 3055 defined. */ 3056 if (pedantic && !COMPLETE_TYPE_P (ret.spec)) 3057 { 3058 gcc_assert (ident); 3059 pedwarn (enum_loc, OPT_Wpedantic, 3060 "ISO C forbids forward references to %<enum%> types"); 3061 } 3062 return ret; 3063 } 3064 3065 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1). 3066 3067 struct-or-union-specifier: 3068 struct-or-union attributes[opt] identifier[opt] 3069 { struct-contents } attributes[opt] 3070 struct-or-union attributes[opt] identifier 3071 3072 struct-contents: 3073 struct-declaration-list 3074 3075 struct-declaration-list: 3076 struct-declaration ; 3077 struct-declaration-list struct-declaration ; 3078 3079 GNU extensions: 3080 3081 struct-contents: 3082 empty 3083 struct-declaration 3084 struct-declaration-list struct-declaration 3085 3086 struct-declaration-list: 3087 struct-declaration-list ; 3088 ; 3089 3090 (Note that in the syntax here, unlike that in ISO C, the semicolons 3091 are included here rather than in struct-declaration, in order to 3092 describe the syntax with extra semicolons and missing semicolon at 3093 end.) 3094 3095 Objective-C: 3096 3097 struct-declaration-list: 3098 @defs ( class-name ) 3099 3100 (Note this does not include a trailing semicolon, but can be 3101 followed by further declarations, and gets a pedwarn-if-pedantic 3102 when followed by a semicolon.) */ 3103 3104 static struct c_typespec 3105 c_parser_struct_or_union_specifier (c_parser *parser) 3106 { 3107 struct c_typespec ret; 3108 tree attrs; 3109 tree ident = NULL_TREE; 3110 location_t struct_loc; 3111 location_t ident_loc = UNKNOWN_LOCATION; 3112 enum tree_code code; 3113 switch (c_parser_peek_token (parser)->keyword) 3114 { 3115 case RID_STRUCT: 3116 code = RECORD_TYPE; 3117 break; 3118 case RID_UNION: 3119 code = UNION_TYPE; 3120 break; 3121 default: 3122 gcc_unreachable (); 3123 } 3124 struct_loc = c_parser_peek_token (parser)->location; 3125 c_parser_consume_token (parser); 3126 attrs = c_parser_attributes (parser); 3127 3128 /* Set the location in case we create a decl now. */ 3129 c_parser_set_source_position_from_token (c_parser_peek_token (parser)); 3130 3131 if (c_parser_next_token_is (parser, CPP_NAME)) 3132 { 3133 ident = c_parser_peek_token (parser)->value; 3134 ident_loc = c_parser_peek_token (parser)->location; 3135 struct_loc = ident_loc; 3136 c_parser_consume_token (parser); 3137 } 3138 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 3139 { 3140 /* Parse a struct or union definition. Start the scope of the 3141 tag before parsing components. */ 3142 struct c_struct_parse_info *struct_info; 3143 tree type = start_struct (struct_loc, code, ident, &struct_info); 3144 tree postfix_attrs; 3145 /* We chain the components in reverse order, then put them in 3146 forward order at the end. Each struct-declaration may 3147 declare multiple components (comma-separated), so we must use 3148 chainon to join them, although when parsing each 3149 struct-declaration we can use TREE_CHAIN directly. 3150 3151 The theory behind all this is that there will be more 3152 semicolon separated fields than comma separated fields, and 3153 so we'll be minimizing the number of node traversals required 3154 by chainon. */ 3155 tree contents; 3156 timevar_push (TV_PARSE_STRUCT); 3157 contents = NULL_TREE; 3158 c_parser_consume_token (parser); 3159 /* Handle the Objective-C @defs construct, 3160 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */ 3161 if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS)) 3162 { 3163 tree name; 3164 gcc_assert (c_dialect_objc ()); 3165 c_parser_consume_token (parser); 3166 matching_parens parens; 3167 if (!parens.require_open (parser)) 3168 goto end_at_defs; 3169 if (c_parser_next_token_is (parser, CPP_NAME) 3170 && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME) 3171 { 3172 name = c_parser_peek_token (parser)->value; 3173 c_parser_consume_token (parser); 3174 } 3175 else 3176 { 3177 c_parser_error (parser, "expected class name"); 3178 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 3179 goto end_at_defs; 3180 } 3181 parens.skip_until_found_close (parser); 3182 contents = nreverse (objc_get_class_ivars (name)); 3183 } 3184 end_at_defs: 3185 /* Parse the struct-declarations and semicolons. Problems with 3186 semicolons are diagnosed here; empty structures are diagnosed 3187 elsewhere. */ 3188 while (true) 3189 { 3190 tree decls; 3191 /* Parse any stray semicolon. */ 3192 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 3193 { 3194 location_t semicolon_loc 3195 = c_parser_peek_token (parser)->location; 3196 gcc_rich_location richloc (semicolon_loc); 3197 richloc.add_fixit_remove (); 3198 pedwarn (&richloc, OPT_Wpedantic, 3199 "extra semicolon in struct or union specified"); 3200 c_parser_consume_token (parser); 3201 continue; 3202 } 3203 /* Stop if at the end of the struct or union contents. */ 3204 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 3205 { 3206 c_parser_consume_token (parser); 3207 break; 3208 } 3209 /* Accept #pragmas at struct scope. */ 3210 if (c_parser_next_token_is (parser, CPP_PRAGMA)) 3211 { 3212 c_parser_pragma (parser, pragma_struct, NULL); 3213 continue; 3214 } 3215 /* Parse some comma-separated declarations, but not the 3216 trailing semicolon if any. */ 3217 decls = c_parser_struct_declaration (parser); 3218 contents = chainon (decls, contents); 3219 /* If no semicolon follows, either we have a parse error or 3220 are at the end of the struct or union and should 3221 pedwarn. */ 3222 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 3223 c_parser_consume_token (parser); 3224 else 3225 { 3226 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 3227 pedwarn (c_parser_peek_token (parser)->location, 0, 3228 "no semicolon at end of struct or union"); 3229 else if (parser->error 3230 || !c_parser_next_token_starts_declspecs (parser)) 3231 { 3232 c_parser_error (parser, "expected %<;%>"); 3233 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL); 3234 break; 3235 } 3236 3237 /* If we come here, we have already emitted an error 3238 for an expected `;', identifier or `(', and we also 3239 recovered already. Go on with the next field. */ 3240 } 3241 } 3242 postfix_attrs = c_parser_attributes (parser); 3243 ret.spec = finish_struct (struct_loc, type, nreverse (contents), 3244 chainon (attrs, postfix_attrs), struct_info); 3245 ret.kind = ctsk_tagdef; 3246 ret.expr = NULL_TREE; 3247 ret.expr_const_operands = true; 3248 timevar_pop (TV_PARSE_STRUCT); 3249 return ret; 3250 } 3251 else if (!ident) 3252 { 3253 c_parser_error (parser, "expected %<{%>"); 3254 ret.spec = error_mark_node; 3255 ret.kind = ctsk_tagref; 3256 ret.expr = NULL_TREE; 3257 ret.expr_const_operands = true; 3258 return ret; 3259 } 3260 ret = parser_xref_tag (ident_loc, code, ident); 3261 return ret; 3262 } 3263 3264 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1), 3265 *without* the trailing semicolon. 3266 3267 struct-declaration: 3268 specifier-qualifier-list struct-declarator-list 3269 static_assert-declaration-no-semi 3270 3271 specifier-qualifier-list: 3272 type-specifier specifier-qualifier-list[opt] 3273 type-qualifier specifier-qualifier-list[opt] 3274 alignment-specifier specifier-qualifier-list[opt] 3275 attributes specifier-qualifier-list[opt] 3276 3277 struct-declarator-list: 3278 struct-declarator 3279 struct-declarator-list , attributes[opt] struct-declarator 3280 3281 struct-declarator: 3282 declarator attributes[opt] 3283 declarator[opt] : constant-expression attributes[opt] 3284 3285 GNU extensions: 3286 3287 struct-declaration: 3288 __extension__ struct-declaration 3289 specifier-qualifier-list 3290 3291 Unlike the ISO C syntax, semicolons are handled elsewhere. The use 3292 of attributes where shown is a GNU extension. In GNU C, we accept 3293 any expression without commas in the syntax (assignment 3294 expressions, not just conditional expressions); assignment 3295 expressions will be diagnosed as non-constant. */ 3296 3297 static tree 3298 c_parser_struct_declaration (c_parser *parser) 3299 { 3300 struct c_declspecs *specs; 3301 tree prefix_attrs; 3302 tree all_prefix_attrs; 3303 tree decls; 3304 location_t decl_loc; 3305 if (c_parser_next_token_is_keyword (parser, RID_EXTENSION)) 3306 { 3307 int ext; 3308 tree decl; 3309 ext = disable_extension_diagnostics (); 3310 c_parser_consume_token (parser); 3311 decl = c_parser_struct_declaration (parser); 3312 restore_extension_diagnostics (ext); 3313 return decl; 3314 } 3315 if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT)) 3316 { 3317 c_parser_static_assert_declaration_no_semi (parser); 3318 return NULL_TREE; 3319 } 3320 specs = build_null_declspecs (); 3321 decl_loc = c_parser_peek_token (parser)->location; 3322 /* Strictly by the standard, we shouldn't allow _Alignas here, 3323 but it appears to have been intended to allow it there, so 3324 we're keeping it as it is until WG14 reaches a conclusion 3325 of N1731. 3326 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */ 3327 c_parser_declspecs (parser, specs, false, true, true, 3328 true, false, cla_nonabstract_decl); 3329 if (parser->error) 3330 return NULL_TREE; 3331 if (!specs->declspecs_seen_p) 3332 { 3333 c_parser_error (parser, "expected specifier-qualifier-list"); 3334 return NULL_TREE; 3335 } 3336 finish_declspecs (specs); 3337 if (c_parser_next_token_is (parser, CPP_SEMICOLON) 3338 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 3339 { 3340 tree ret; 3341 if (specs->typespec_kind == ctsk_none) 3342 { 3343 pedwarn (decl_loc, OPT_Wpedantic, 3344 "ISO C forbids member declarations with no members"); 3345 shadow_tag_warned (specs, pedantic); 3346 ret = NULL_TREE; 3347 } 3348 else 3349 { 3350 /* Support for unnamed structs or unions as members of 3351 structs or unions (which is [a] useful and [b] supports 3352 MS P-SDK). */ 3353 tree attrs = NULL; 3354 3355 ret = grokfield (c_parser_peek_token (parser)->location, 3356 build_id_declarator (NULL_TREE), specs, 3357 NULL_TREE, &attrs); 3358 if (ret) 3359 decl_attributes (&ret, attrs, 0); 3360 } 3361 return ret; 3362 } 3363 3364 /* Provide better error recovery. Note that a type name here is valid, 3365 and will be treated as a field name. */ 3366 if (specs->typespec_kind == ctsk_tagdef 3367 && TREE_CODE (specs->type) != ENUMERAL_TYPE 3368 && c_parser_next_token_starts_declspecs (parser) 3369 && !c_parser_next_token_is (parser, CPP_NAME)) 3370 { 3371 c_parser_error (parser, "expected %<;%>, identifier or %<(%>"); 3372 parser->error = false; 3373 return NULL_TREE; 3374 } 3375 3376 pending_xref_error (); 3377 prefix_attrs = specs->attrs; 3378 all_prefix_attrs = prefix_attrs; 3379 specs->attrs = NULL_TREE; 3380 decls = NULL_TREE; 3381 while (true) 3382 { 3383 /* Declaring one or more declarators or un-named bit-fields. */ 3384 struct c_declarator *declarator; 3385 bool dummy = false; 3386 if (c_parser_next_token_is (parser, CPP_COLON)) 3387 declarator = build_id_declarator (NULL_TREE); 3388 else 3389 declarator = c_parser_declarator (parser, 3390 specs->typespec_kind != ctsk_none, 3391 C_DTR_NORMAL, &dummy); 3392 if (declarator == NULL) 3393 { 3394 c_parser_skip_to_end_of_block_or_statement (parser); 3395 break; 3396 } 3397 if (c_parser_next_token_is (parser, CPP_COLON) 3398 || c_parser_next_token_is (parser, CPP_COMMA) 3399 || c_parser_next_token_is (parser, CPP_SEMICOLON) 3400 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE) 3401 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 3402 { 3403 tree postfix_attrs = NULL_TREE; 3404 tree width = NULL_TREE; 3405 tree d; 3406 if (c_parser_next_token_is (parser, CPP_COLON)) 3407 { 3408 c_parser_consume_token (parser); 3409 width = c_parser_expr_no_commas (parser, NULL).value; 3410 } 3411 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 3412 postfix_attrs = c_parser_attributes (parser); 3413 d = grokfield (c_parser_peek_token (parser)->location, 3414 declarator, specs, width, &all_prefix_attrs); 3415 decl_attributes (&d, chainon (postfix_attrs, 3416 all_prefix_attrs), 0); 3417 DECL_CHAIN (d) = decls; 3418 decls = d; 3419 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 3420 all_prefix_attrs = chainon (c_parser_attributes (parser), 3421 prefix_attrs); 3422 else 3423 all_prefix_attrs = prefix_attrs; 3424 if (c_parser_next_token_is (parser, CPP_COMMA)) 3425 c_parser_consume_token (parser); 3426 else if (c_parser_next_token_is (parser, CPP_SEMICOLON) 3427 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 3428 { 3429 /* Semicolon consumed in caller. */ 3430 break; 3431 } 3432 else 3433 { 3434 c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>"); 3435 break; 3436 } 3437 } 3438 else 3439 { 3440 c_parser_error (parser, 3441 "expected %<:%>, %<,%>, %<;%>, %<}%> or " 3442 "%<__attribute__%>"); 3443 break; 3444 } 3445 } 3446 return decls; 3447 } 3448 3449 /* Parse a typeof specifier (a GNU extension). 3450 3451 typeof-specifier: 3452 typeof ( expression ) 3453 typeof ( type-name ) 3454 */ 3455 3456 static struct c_typespec 3457 c_parser_typeof_specifier (c_parser *parser) 3458 { 3459 struct c_typespec ret; 3460 ret.kind = ctsk_typeof; 3461 ret.spec = error_mark_node; 3462 ret.expr = NULL_TREE; 3463 ret.expr_const_operands = true; 3464 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF)); 3465 c_parser_consume_token (parser); 3466 c_inhibit_evaluation_warnings++; 3467 in_typeof++; 3468 matching_parens parens; 3469 if (!parens.require_open (parser)) 3470 { 3471 c_inhibit_evaluation_warnings--; 3472 in_typeof--; 3473 return ret; 3474 } 3475 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id)) 3476 { 3477 struct c_type_name *type = c_parser_type_name (parser); 3478 c_inhibit_evaluation_warnings--; 3479 in_typeof--; 3480 if (type != NULL) 3481 { 3482 ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands); 3483 pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE)); 3484 } 3485 } 3486 else 3487 { 3488 bool was_vm; 3489 location_t here = c_parser_peek_token (parser)->location; 3490 struct c_expr expr = c_parser_expression (parser); 3491 c_inhibit_evaluation_warnings--; 3492 in_typeof--; 3493 if (TREE_CODE (expr.value) == COMPONENT_REF 3494 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1))) 3495 error_at (here, "%<typeof%> applied to a bit-field"); 3496 mark_exp_read (expr.value); 3497 ret.spec = TREE_TYPE (expr.value); 3498 was_vm = variably_modified_type_p (ret.spec, NULL_TREE); 3499 /* This is returned with the type so that when the type is 3500 evaluated, this can be evaluated. */ 3501 if (was_vm) 3502 ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands); 3503 pop_maybe_used (was_vm); 3504 /* For use in macros such as those in <stdatomic.h>, remove all 3505 qualifiers from atomic types. (const can be an issue for more macros 3506 using typeof than just the <stdatomic.h> ones.) */ 3507 if (ret.spec != error_mark_node && TYPE_ATOMIC (ret.spec)) 3508 ret.spec = c_build_qualified_type (ret.spec, TYPE_UNQUALIFIED); 3509 } 3510 parens.skip_until_found_close (parser); 3511 return ret; 3512 } 3513 3514 /* Parse an alignment-specifier. 3515 3516 C11 6.7.5: 3517 3518 alignment-specifier: 3519 _Alignas ( type-name ) 3520 _Alignas ( constant-expression ) 3521 */ 3522 3523 static tree 3524 c_parser_alignas_specifier (c_parser * parser) 3525 { 3526 tree ret = error_mark_node; 3527 location_t loc = c_parser_peek_token (parser)->location; 3528 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS)); 3529 c_parser_consume_token (parser); 3530 if (flag_isoc99) 3531 pedwarn_c99 (loc, OPT_Wpedantic, 3532 "ISO C99 does not support %<_Alignas%>"); 3533 else 3534 pedwarn_c99 (loc, OPT_Wpedantic, 3535 "ISO C90 does not support %<_Alignas%>"); 3536 matching_parens parens; 3537 if (!parens.require_open (parser)) 3538 return ret; 3539 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id)) 3540 { 3541 struct c_type_name *type = c_parser_type_name (parser); 3542 if (type != NULL) 3543 ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL), 3544 false, true, 1); 3545 } 3546 else 3547 ret = c_parser_expr_no_commas (parser, NULL).value; 3548 parens.skip_until_found_close (parser); 3549 return ret; 3550 } 3551 3552 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4, 3553 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then 3554 a typedef name may be redeclared; otherwise it may not. KIND 3555 indicates which kind of declarator is wanted. Returns a valid 3556 declarator except in the case of a syntax error in which case NULL is 3557 returned. *SEEN_ID is set to true if an identifier being declared is 3558 seen; this is used to diagnose bad forms of abstract array declarators 3559 and to determine whether an identifier list is syntactically permitted. 3560 3561 declarator: 3562 pointer[opt] direct-declarator 3563 3564 direct-declarator: 3565 identifier 3566 ( attributes[opt] declarator ) 3567 direct-declarator array-declarator 3568 direct-declarator ( parameter-type-list ) 3569 direct-declarator ( identifier-list[opt] ) 3570 3571 pointer: 3572 * type-qualifier-list[opt] 3573 * type-qualifier-list[opt] pointer 3574 3575 type-qualifier-list: 3576 type-qualifier 3577 attributes 3578 type-qualifier-list type-qualifier 3579 type-qualifier-list attributes 3580 3581 array-declarator: 3582 [ type-qualifier-list[opt] assignment-expression[opt] ] 3583 [ static type-qualifier-list[opt] assignment-expression ] 3584 [ type-qualifier-list static assignment-expression ] 3585 [ type-qualifier-list[opt] * ] 3586 3587 parameter-type-list: 3588 parameter-list 3589 parameter-list , ... 3590 3591 parameter-list: 3592 parameter-declaration 3593 parameter-list , parameter-declaration 3594 3595 parameter-declaration: 3596 declaration-specifiers declarator attributes[opt] 3597 declaration-specifiers abstract-declarator[opt] attributes[opt] 3598 3599 identifier-list: 3600 identifier 3601 identifier-list , identifier 3602 3603 abstract-declarator: 3604 pointer 3605 pointer[opt] direct-abstract-declarator 3606 3607 direct-abstract-declarator: 3608 ( attributes[opt] abstract-declarator ) 3609 direct-abstract-declarator[opt] array-declarator 3610 direct-abstract-declarator[opt] ( parameter-type-list[opt] ) 3611 3612 GNU extensions: 3613 3614 direct-declarator: 3615 direct-declarator ( parameter-forward-declarations 3616 parameter-type-list[opt] ) 3617 3618 direct-abstract-declarator: 3619 direct-abstract-declarator[opt] ( parameter-forward-declarations 3620 parameter-type-list[opt] ) 3621 3622 parameter-forward-declarations: 3623 parameter-list ; 3624 parameter-forward-declarations parameter-list ; 3625 3626 The uses of attributes shown above are GNU extensions. 3627 3628 Some forms of array declarator are not included in C99 in the 3629 syntax for abstract declarators; these are disallowed elsewhere. 3630 This may be a defect (DR#289). 3631 3632 This function also accepts an omitted abstract declarator as being 3633 an abstract declarator, although not part of the formal syntax. */ 3634 3635 struct c_declarator * 3636 c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind, 3637 bool *seen_id) 3638 { 3639 /* Parse any initial pointer part. */ 3640 if (c_parser_next_token_is (parser, CPP_MULT)) 3641 { 3642 struct c_declspecs *quals_attrs = build_null_declspecs (); 3643 struct c_declarator *inner; 3644 c_parser_consume_token (parser); 3645 c_parser_declspecs (parser, quals_attrs, false, false, true, 3646 false, false, cla_prefer_id); 3647 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id); 3648 if (inner == NULL) 3649 return NULL; 3650 else 3651 return make_pointer_declarator (quals_attrs, inner); 3652 } 3653 /* Now we have a direct declarator, direct abstract declarator or 3654 nothing (which counts as a direct abstract declarator here). */ 3655 return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id); 3656 } 3657 3658 /* Parse a direct declarator or direct abstract declarator; arguments 3659 as c_parser_declarator. */ 3660 3661 static struct c_declarator * 3662 c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind, 3663 bool *seen_id) 3664 { 3665 /* The direct declarator must start with an identifier (possibly 3666 omitted) or a parenthesized declarator (possibly abstract). In 3667 an ordinary declarator, initial parentheses must start a 3668 parenthesized declarator. In an abstract declarator or parameter 3669 declarator, they could start a parenthesized declarator or a 3670 parameter list. To tell which, the open parenthesis and any 3671 following attributes must be read. If a declaration specifier 3672 follows, then it is a parameter list; if the specifier is a 3673 typedef name, there might be an ambiguity about redeclaring it, 3674 which is resolved in the direction of treating it as a typedef 3675 name. If a close parenthesis follows, it is also an empty 3676 parameter list, as the syntax does not permit empty abstract 3677 declarators. Otherwise, it is a parenthesized declarator (in 3678 which case the analysis may be repeated inside it, recursively). 3679 3680 ??? There is an ambiguity in a parameter declaration "int 3681 (__attribute__((foo)) x)", where x is not a typedef name: it 3682 could be an abstract declarator for a function, or declare x with 3683 parentheses. The proper resolution of this ambiguity needs 3684 documenting. At present we follow an accident of the old 3685 parser's implementation, whereby the first parameter must have 3686 some declaration specifiers other than just attributes. Thus as 3687 a parameter declaration it is treated as a parenthesized 3688 parameter named x, and as an abstract declarator it is 3689 rejected. 3690 3691 ??? Also following the old parser, attributes inside an empty 3692 parameter list are ignored, making it a list not yielding a 3693 prototype, rather than giving an error or making it have one 3694 parameter with implicit type int. 3695 3696 ??? Also following the old parser, typedef names may be 3697 redeclared in declarators, but not Objective-C class names. */ 3698 3699 if (kind != C_DTR_ABSTRACT 3700 && c_parser_next_token_is (parser, CPP_NAME) 3701 && ((type_seen_p 3702 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME 3703 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)) 3704 || c_parser_peek_token (parser)->id_kind == C_ID_ID)) 3705 { 3706 struct c_declarator *inner 3707 = build_id_declarator (c_parser_peek_token (parser)->value); 3708 *seen_id = true; 3709 inner->id_loc = c_parser_peek_token (parser)->location; 3710 c_parser_consume_token (parser); 3711 return c_parser_direct_declarator_inner (parser, *seen_id, inner); 3712 } 3713 3714 if (kind != C_DTR_NORMAL 3715 && c_parser_next_token_is (parser, CPP_OPEN_SQUARE)) 3716 { 3717 struct c_declarator *inner = build_id_declarator (NULL_TREE); 3718 inner->id_loc = c_parser_peek_token (parser)->location; 3719 return c_parser_direct_declarator_inner (parser, *seen_id, inner); 3720 } 3721 3722 /* Either we are at the end of an abstract declarator, or we have 3723 parentheses. */ 3724 3725 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 3726 { 3727 tree attrs; 3728 struct c_declarator *inner; 3729 c_parser_consume_token (parser); 3730 attrs = c_parser_attributes (parser); 3731 if (kind != C_DTR_NORMAL 3732 && (c_parser_next_token_starts_declspecs (parser) 3733 || c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) 3734 { 3735 struct c_arg_info *args 3736 = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL, 3737 attrs); 3738 if (args == NULL) 3739 return NULL; 3740 else 3741 { 3742 inner 3743 = build_function_declarator (args, 3744 build_id_declarator (NULL_TREE)); 3745 return c_parser_direct_declarator_inner (parser, *seen_id, 3746 inner); 3747 } 3748 } 3749 /* A parenthesized declarator. */ 3750 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id); 3751 if (inner != NULL && attrs != NULL) 3752 inner = build_attrs_declarator (attrs, inner); 3753 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 3754 { 3755 c_parser_consume_token (parser); 3756 if (inner == NULL) 3757 return NULL; 3758 else 3759 return c_parser_direct_declarator_inner (parser, *seen_id, inner); 3760 } 3761 else 3762 { 3763 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 3764 "expected %<)%>"); 3765 return NULL; 3766 } 3767 } 3768 else 3769 { 3770 if (kind == C_DTR_NORMAL) 3771 { 3772 c_parser_error (parser, "expected identifier or %<(%>"); 3773 return NULL; 3774 } 3775 else 3776 return build_id_declarator (NULL_TREE); 3777 } 3778 } 3779 3780 /* Parse part of a direct declarator or direct abstract declarator, 3781 given that some (in INNER) has already been parsed; ID_PRESENT is 3782 true if an identifier is present, false for an abstract 3783 declarator. */ 3784 3785 static struct c_declarator * 3786 c_parser_direct_declarator_inner (c_parser *parser, bool id_present, 3787 struct c_declarator *inner) 3788 { 3789 /* Parse a sequence of array declarators and parameter lists. */ 3790 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)) 3791 { 3792 location_t brace_loc = c_parser_peek_token (parser)->location; 3793 struct c_declarator *declarator; 3794 struct c_declspecs *quals_attrs = build_null_declspecs (); 3795 bool static_seen; 3796 bool star_seen; 3797 struct c_expr dimen; 3798 dimen.value = NULL_TREE; 3799 dimen.original_code = ERROR_MARK; 3800 dimen.original_type = NULL_TREE; 3801 c_parser_consume_token (parser); 3802 c_parser_declspecs (parser, quals_attrs, false, false, true, 3803 false, false, cla_prefer_id); 3804 static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC); 3805 if (static_seen) 3806 c_parser_consume_token (parser); 3807 if (static_seen && !quals_attrs->declspecs_seen_p) 3808 c_parser_declspecs (parser, quals_attrs, false, false, true, 3809 false, false, cla_prefer_id); 3810 if (!quals_attrs->declspecs_seen_p) 3811 quals_attrs = NULL; 3812 /* If "static" is present, there must be an array dimension. 3813 Otherwise, there may be a dimension, "*", or no 3814 dimension. */ 3815 if (static_seen) 3816 { 3817 star_seen = false; 3818 dimen = c_parser_expr_no_commas (parser, NULL); 3819 } 3820 else 3821 { 3822 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) 3823 { 3824 dimen.value = NULL_TREE; 3825 star_seen = false; 3826 } 3827 else if (c_parser_next_token_is (parser, CPP_MULT)) 3828 { 3829 if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE) 3830 { 3831 dimen.value = NULL_TREE; 3832 star_seen = true; 3833 c_parser_consume_token (parser); 3834 } 3835 else 3836 { 3837 star_seen = false; 3838 dimen = c_parser_expr_no_commas (parser, NULL); 3839 } 3840 } 3841 else 3842 { 3843 star_seen = false; 3844 dimen = c_parser_expr_no_commas (parser, NULL); 3845 } 3846 } 3847 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) 3848 c_parser_consume_token (parser); 3849 else 3850 { 3851 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, 3852 "expected %<]%>"); 3853 return NULL; 3854 } 3855 if (dimen.value) 3856 dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true); 3857 declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs, 3858 static_seen, star_seen); 3859 if (declarator == NULL) 3860 return NULL; 3861 inner = set_array_declarator_inner (declarator, inner); 3862 return c_parser_direct_declarator_inner (parser, id_present, inner); 3863 } 3864 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 3865 { 3866 tree attrs; 3867 struct c_arg_info *args; 3868 c_parser_consume_token (parser); 3869 attrs = c_parser_attributes (parser); 3870 args = c_parser_parms_declarator (parser, id_present, attrs); 3871 if (args == NULL) 3872 return NULL; 3873 else 3874 { 3875 inner = build_function_declarator (args, inner); 3876 return c_parser_direct_declarator_inner (parser, id_present, inner); 3877 } 3878 } 3879 return inner; 3880 } 3881 3882 /* Parse a parameter list or identifier list, including the closing 3883 parenthesis but not the opening one. ATTRS are the attributes at 3884 the start of the list. ID_LIST_OK is true if an identifier list is 3885 acceptable; such a list must not have attributes at the start. */ 3886 3887 static struct c_arg_info * 3888 c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs) 3889 { 3890 push_scope (); 3891 declare_parm_level (); 3892 /* If the list starts with an identifier, it is an identifier list. 3893 Otherwise, it is either a prototype list or an empty list. */ 3894 if (id_list_ok 3895 && !attrs 3896 && c_parser_next_token_is (parser, CPP_NAME) 3897 && c_parser_peek_token (parser)->id_kind == C_ID_ID 3898 3899 /* Look ahead to detect typos in type names. */ 3900 && c_parser_peek_2nd_token (parser)->type != CPP_NAME 3901 && c_parser_peek_2nd_token (parser)->type != CPP_MULT 3902 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN 3903 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE 3904 && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD) 3905 { 3906 tree list = NULL_TREE, *nextp = &list; 3907 while (c_parser_next_token_is (parser, CPP_NAME) 3908 && c_parser_peek_token (parser)->id_kind == C_ID_ID) 3909 { 3910 *nextp = build_tree_list (NULL_TREE, 3911 c_parser_peek_token (parser)->value); 3912 nextp = & TREE_CHAIN (*nextp); 3913 c_parser_consume_token (parser); 3914 if (c_parser_next_token_is_not (parser, CPP_COMMA)) 3915 break; 3916 c_parser_consume_token (parser); 3917 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 3918 { 3919 c_parser_error (parser, "expected identifier"); 3920 break; 3921 } 3922 } 3923 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 3924 { 3925 struct c_arg_info *ret = build_arg_info (); 3926 ret->types = list; 3927 c_parser_consume_token (parser); 3928 pop_scope (); 3929 return ret; 3930 } 3931 else 3932 { 3933 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 3934 "expected %<)%>"); 3935 pop_scope (); 3936 return NULL; 3937 } 3938 } 3939 else 3940 { 3941 struct c_arg_info *ret = c_parser_parms_list_declarator (parser, attrs, 3942 NULL); 3943 pop_scope (); 3944 return ret; 3945 } 3946 } 3947 3948 /* Parse a parameter list (possibly empty), including the closing 3949 parenthesis but not the opening one. ATTRS are the attributes at 3950 the start of the list. EXPR is NULL or an expression that needs to 3951 be evaluated for the side effects of array size expressions in the 3952 parameters. */ 3953 3954 static struct c_arg_info * 3955 c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr) 3956 { 3957 bool bad_parm = false; 3958 3959 /* ??? Following the old parser, forward parameter declarations may 3960 use abstract declarators, and if no real parameter declarations 3961 follow the forward declarations then this is not diagnosed. Also 3962 note as above that attributes are ignored as the only contents of 3963 the parentheses, or as the only contents after forward 3964 declarations. */ 3965 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 3966 { 3967 struct c_arg_info *ret = build_arg_info (); 3968 c_parser_consume_token (parser); 3969 return ret; 3970 } 3971 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) 3972 { 3973 struct c_arg_info *ret = build_arg_info (); 3974 3975 if (flag_allow_parameterless_variadic_functions) 3976 { 3977 /* F (...) is allowed. */ 3978 ret->types = NULL_TREE; 3979 } 3980 else 3981 { 3982 /* Suppress -Wold-style-definition for this case. */ 3983 ret->types = error_mark_node; 3984 error_at (c_parser_peek_token (parser)->location, 3985 "ISO C requires a named argument before %<...%>"); 3986 } 3987 c_parser_consume_token (parser); 3988 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 3989 { 3990 c_parser_consume_token (parser); 3991 return ret; 3992 } 3993 else 3994 { 3995 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 3996 "expected %<)%>"); 3997 return NULL; 3998 } 3999 } 4000 /* Nonempty list of parameters, either terminated with semicolon 4001 (forward declarations; recurse) or with close parenthesis (normal 4002 function) or with ", ... )" (variadic function). */ 4003 while (true) 4004 { 4005 /* Parse a parameter. */ 4006 struct c_parm *parm = c_parser_parameter_declaration (parser, attrs); 4007 attrs = NULL_TREE; 4008 if (parm == NULL) 4009 bad_parm = true; 4010 else 4011 push_parm_decl (parm, &expr); 4012 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 4013 { 4014 tree new_attrs; 4015 c_parser_consume_token (parser); 4016 mark_forward_parm_decls (); 4017 new_attrs = c_parser_attributes (parser); 4018 return c_parser_parms_list_declarator (parser, new_attrs, expr); 4019 } 4020 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 4021 { 4022 c_parser_consume_token (parser); 4023 if (bad_parm) 4024 return NULL; 4025 else 4026 return get_parm_info (false, expr); 4027 } 4028 if (!c_parser_require (parser, CPP_COMMA, 4029 "expected %<;%>, %<,%> or %<)%>", 4030 UNKNOWN_LOCATION, false)) 4031 { 4032 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 4033 return NULL; 4034 } 4035 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) 4036 { 4037 c_parser_consume_token (parser); 4038 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 4039 { 4040 c_parser_consume_token (parser); 4041 if (bad_parm) 4042 return NULL; 4043 else 4044 return get_parm_info (true, expr); 4045 } 4046 else 4047 { 4048 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 4049 "expected %<)%>"); 4050 return NULL; 4051 } 4052 } 4053 } 4054 } 4055 4056 /* Parse a parameter declaration. ATTRS are the attributes at the 4057 start of the declaration if it is the first parameter. */ 4058 4059 static struct c_parm * 4060 c_parser_parameter_declaration (c_parser *parser, tree attrs) 4061 { 4062 struct c_declspecs *specs; 4063 struct c_declarator *declarator; 4064 tree prefix_attrs; 4065 tree postfix_attrs = NULL_TREE; 4066 bool dummy = false; 4067 4068 /* Accept #pragmas between parameter declarations. */ 4069 while (c_parser_next_token_is (parser, CPP_PRAGMA)) 4070 c_parser_pragma (parser, pragma_param, NULL); 4071 4072 if (!c_parser_next_token_starts_declspecs (parser)) 4073 { 4074 c_token *token = c_parser_peek_token (parser); 4075 if (parser->error) 4076 return NULL; 4077 c_parser_set_source_position_from_token (token); 4078 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type)) 4079 { 4080 auto_diagnostic_group d; 4081 name_hint hint = lookup_name_fuzzy (token->value, 4082 FUZZY_LOOKUP_TYPENAME, 4083 token->location); 4084 if (const char *suggestion = hint.suggestion ()) 4085 { 4086 gcc_rich_location richloc (token->location); 4087 richloc.add_fixit_replace (suggestion); 4088 error_at (&richloc, 4089 "unknown type name %qE; did you mean %qs?", 4090 token->value, suggestion); 4091 } 4092 else 4093 error_at (token->location, "unknown type name %qE", token->value); 4094 parser->error = true; 4095 } 4096 /* ??? In some Objective-C cases '...' isn't applicable so there 4097 should be a different message. */ 4098 else 4099 c_parser_error (parser, 4100 "expected declaration specifiers or %<...%>"); 4101 c_parser_skip_to_end_of_parameter (parser); 4102 return NULL; 4103 } 4104 4105 location_t start_loc = c_parser_peek_token (parser)->location; 4106 4107 specs = build_null_declspecs (); 4108 if (attrs) 4109 { 4110 declspecs_add_attrs (input_location, specs, attrs); 4111 attrs = NULL_TREE; 4112 } 4113 c_parser_declspecs (parser, specs, true, true, true, true, false, 4114 cla_nonabstract_decl); 4115 finish_declspecs (specs); 4116 pending_xref_error (); 4117 prefix_attrs = specs->attrs; 4118 specs->attrs = NULL_TREE; 4119 declarator = c_parser_declarator (parser, 4120 specs->typespec_kind != ctsk_none, 4121 C_DTR_PARM, &dummy); 4122 if (declarator == NULL) 4123 { 4124 c_parser_skip_until_found (parser, CPP_COMMA, NULL); 4125 return NULL; 4126 } 4127 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 4128 postfix_attrs = c_parser_attributes (parser); 4129 4130 /* Generate a location for the parameter, ranging from the start of the 4131 initial token to the end of the final token. 4132 4133 If we have a identifier, then use it for the caret location, e.g. 4134 4135 extern int callee (int one, int (*two)(int, int), float three); 4136 ~~~~~~^~~~~~~~~~~~~~ 4137 4138 otherwise, reuse the start location for the caret location e.g.: 4139 4140 extern int callee (int one, int (*)(int, int), float three); 4141 ^~~~~~~~~~~~~~~~~ 4142 */ 4143 location_t end_loc = parser->last_token_location; 4144 4145 /* Find any cdk_id declarator; determine if we have an identifier. */ 4146 c_declarator *id_declarator = declarator; 4147 while (id_declarator && id_declarator->kind != cdk_id) 4148 id_declarator = id_declarator->declarator; 4149 location_t caret_loc = (id_declarator->u.id 4150 ? id_declarator->id_loc 4151 : start_loc); 4152 location_t param_loc = make_location (caret_loc, start_loc, end_loc); 4153 4154 return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs), 4155 declarator, param_loc); 4156 } 4157 4158 /* Parse a string literal in an asm expression. It should not be 4159 translated, and wide string literals are an error although 4160 permitted by the syntax. This is a GNU extension. 4161 4162 asm-string-literal: 4163 string-literal 4164 4165 ??? At present, following the old parser, the caller needs to have 4166 set lex_untranslated_string to 1. It would be better to follow the 4167 C++ parser rather than using this kludge. */ 4168 4169 static tree 4170 c_parser_asm_string_literal (c_parser *parser) 4171 { 4172 tree str; 4173 int save_flag = warn_overlength_strings; 4174 warn_overlength_strings = 0; 4175 if (c_parser_next_token_is (parser, CPP_STRING)) 4176 { 4177 str = c_parser_peek_token (parser)->value; 4178 c_parser_consume_token (parser); 4179 } 4180 else if (c_parser_next_token_is (parser, CPP_WSTRING)) 4181 { 4182 error_at (c_parser_peek_token (parser)->location, 4183 "wide string literal in %<asm%>"); 4184 str = build_string (1, ""); 4185 c_parser_consume_token (parser); 4186 } 4187 else 4188 { 4189 c_parser_error (parser, "expected string literal"); 4190 str = NULL_TREE; 4191 } 4192 warn_overlength_strings = save_flag; 4193 return str; 4194 } 4195 4196 /* Parse a simple asm expression. This is used in restricted 4197 contexts, where a full expression with inputs and outputs does not 4198 make sense. This is a GNU extension. 4199 4200 simple-asm-expr: 4201 asm ( asm-string-literal ) 4202 */ 4203 4204 static tree 4205 c_parser_simple_asm_expr (c_parser *parser) 4206 { 4207 tree str; 4208 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM)); 4209 /* ??? Follow the C++ parser rather than using the 4210 lex_untranslated_string kludge. */ 4211 parser->lex_untranslated_string = true; 4212 c_parser_consume_token (parser); 4213 matching_parens parens; 4214 if (!parens.require_open (parser)) 4215 { 4216 parser->lex_untranslated_string = false; 4217 return NULL_TREE; 4218 } 4219 str = c_parser_asm_string_literal (parser); 4220 parser->lex_untranslated_string = false; 4221 if (!parens.require_close (parser)) 4222 { 4223 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 4224 return NULL_TREE; 4225 } 4226 return str; 4227 } 4228 4229 static tree 4230 c_parser_attribute_any_word (c_parser *parser) 4231 { 4232 tree attr_name = NULL_TREE; 4233 4234 if (c_parser_next_token_is (parser, CPP_KEYWORD)) 4235 { 4236 /* ??? See comment above about what keywords are accepted here. */ 4237 bool ok; 4238 switch (c_parser_peek_token (parser)->keyword) 4239 { 4240 case RID_STATIC: 4241 case RID_UNSIGNED: 4242 case RID_LONG: 4243 case RID_CONST: 4244 case RID_EXTERN: 4245 case RID_REGISTER: 4246 case RID_TYPEDEF: 4247 case RID_SHORT: 4248 case RID_INLINE: 4249 case RID_NORETURN: 4250 case RID_VOLATILE: 4251 case RID_SIGNED: 4252 case RID_AUTO: 4253 case RID_RESTRICT: 4254 case RID_COMPLEX: 4255 case RID_THREAD: 4256 case RID_INT: 4257 case RID_CHAR: 4258 case RID_FLOAT: 4259 case RID_DOUBLE: 4260 case RID_VOID: 4261 case RID_DFLOAT32: 4262 case RID_DFLOAT64: 4263 case RID_DFLOAT128: 4264 CASE_RID_FLOATN_NX: 4265 case RID_BOOL: 4266 case RID_FRACT: 4267 case RID_ACCUM: 4268 case RID_SAT: 4269 case RID_TRANSACTION_ATOMIC: 4270 case RID_TRANSACTION_CANCEL: 4271 case RID_ATOMIC: 4272 case RID_AUTO_TYPE: 4273 case RID_INT_N_0: 4274 case RID_INT_N_1: 4275 case RID_INT_N_2: 4276 case RID_INT_N_3: 4277 ok = true; 4278 break; 4279 default: 4280 ok = false; 4281 break; 4282 } 4283 if (!ok) 4284 return NULL_TREE; 4285 4286 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */ 4287 attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword]; 4288 } 4289 else if (c_parser_next_token_is (parser, CPP_NAME)) 4290 attr_name = c_parser_peek_token (parser)->value; 4291 4292 return attr_name; 4293 } 4294 4295 /* Parse (possibly empty) attributes. This is a GNU extension. 4296 4297 attributes: 4298 empty 4299 attributes attribute 4300 4301 attribute: 4302 __attribute__ ( ( attribute-list ) ) 4303 4304 attribute-list: 4305 attrib 4306 attribute_list , attrib 4307 4308 attrib: 4309 empty 4310 any-word 4311 any-word ( identifier ) 4312 any-word ( identifier , nonempty-expr-list ) 4313 any-word ( expr-list ) 4314 4315 where the "identifier" must not be declared as a type, and 4316 "any-word" may be any identifier (including one declared as a 4317 type), a reserved word storage class specifier, type specifier or 4318 type qualifier. ??? This still leaves out most reserved keywords 4319 (following the old parser), shouldn't we include them, and why not 4320 allow identifiers declared as types to start the arguments? 4321 When EXPECT_COMMA is true, expect the attribute to be preceded 4322 by a comma and fail if it isn't. 4323 When EMPTY_OK is true, allow and consume any number of consecutive 4324 commas with no attributes in between. */ 4325 4326 static tree 4327 c_parser_attribute (c_parser *parser, tree attrs, 4328 bool expect_comma = false, bool empty_ok = true) 4329 { 4330 bool comma_first = c_parser_next_token_is (parser, CPP_COMMA); 4331 if (!comma_first 4332 && !c_parser_next_token_is (parser, CPP_NAME) 4333 && !c_parser_next_token_is (parser, CPP_KEYWORD)) 4334 return NULL_TREE; 4335 4336 while (c_parser_next_token_is (parser, CPP_COMMA)) 4337 { 4338 c_parser_consume_token (parser); 4339 if (!empty_ok) 4340 return attrs; 4341 } 4342 4343 tree attr_name = c_parser_attribute_any_word (parser); 4344 if (attr_name == NULL_TREE) 4345 return NULL_TREE; 4346 4347 attr_name = canonicalize_attr_name (attr_name); 4348 c_parser_consume_token (parser); 4349 4350 tree attr; 4351 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN)) 4352 { 4353 if (expect_comma && !comma_first) 4354 { 4355 /* A comma is missing between the last attribute on the chain 4356 and this one. */ 4357 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 4358 "expected %<)%>"); 4359 return error_mark_node; 4360 } 4361 attr = build_tree_list (attr_name, NULL_TREE); 4362 /* Add this attribute to the list. */ 4363 attrs = chainon (attrs, attr); 4364 return attrs; 4365 } 4366 c_parser_consume_token (parser); 4367 4368 vec<tree, va_gc> *expr_list; 4369 tree attr_args; 4370 /* Parse the attribute contents. If they start with an 4371 identifier which is followed by a comma or close 4372 parenthesis, then the arguments start with that 4373 identifier; otherwise they are an expression list. 4374 In objective-c the identifier may be a classname. */ 4375 if (c_parser_next_token_is (parser, CPP_NAME) 4376 && (c_parser_peek_token (parser)->id_kind == C_ID_ID 4377 || (c_dialect_objc () 4378 && c_parser_peek_token (parser)->id_kind 4379 == C_ID_CLASSNAME)) 4380 && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA) 4381 || (c_parser_peek_2nd_token (parser)->type 4382 == CPP_CLOSE_PAREN)) 4383 && (attribute_takes_identifier_p (attr_name) 4384 || (c_dialect_objc () 4385 && c_parser_peek_token (parser)->id_kind 4386 == C_ID_CLASSNAME))) 4387 { 4388 tree arg1 = c_parser_peek_token (parser)->value; 4389 c_parser_consume_token (parser); 4390 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 4391 attr_args = build_tree_list (NULL_TREE, arg1); 4392 else 4393 { 4394 tree tree_list; 4395 c_parser_consume_token (parser); 4396 expr_list = c_parser_expr_list (parser, false, true, 4397 NULL, NULL, NULL, NULL); 4398 tree_list = build_tree_list_vec (expr_list); 4399 attr_args = tree_cons (NULL_TREE, arg1, tree_list); 4400 release_tree_vector (expr_list); 4401 } 4402 } 4403 else 4404 { 4405 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 4406 attr_args = NULL_TREE; 4407 else 4408 { 4409 expr_list = c_parser_expr_list (parser, false, true, 4410 NULL, NULL, NULL, NULL); 4411 attr_args = build_tree_list_vec (expr_list); 4412 release_tree_vector (expr_list); 4413 } 4414 } 4415 4416 attr = build_tree_list (attr_name, attr_args); 4417 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 4418 c_parser_consume_token (parser); 4419 else 4420 { 4421 parser->lex_untranslated_string = false; 4422 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 4423 "expected %<)%>"); 4424 return error_mark_node; 4425 } 4426 4427 if (expect_comma && !comma_first) 4428 { 4429 /* A comma is missing between the last attribute on the chain 4430 and this one. */ 4431 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 4432 "expected %<)%>"); 4433 return error_mark_node; 4434 } 4435 4436 /* Add this attribute to the list. */ 4437 attrs = chainon (attrs, attr); 4438 return attrs; 4439 } 4440 4441 static tree 4442 c_parser_attributes (c_parser *parser) 4443 { 4444 tree attrs = NULL_TREE; 4445 while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 4446 { 4447 /* ??? Follow the C++ parser rather than using the 4448 lex_untranslated_string kludge. */ 4449 parser->lex_untranslated_string = true; 4450 /* Consume the `__attribute__' keyword. */ 4451 c_parser_consume_token (parser); 4452 /* Look for the two `(' tokens. */ 4453 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 4454 { 4455 parser->lex_untranslated_string = false; 4456 return attrs; 4457 } 4458 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 4459 { 4460 parser->lex_untranslated_string = false; 4461 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 4462 return attrs; 4463 } 4464 /* Parse the attribute list. Require a comma between successive 4465 (possibly empty) attributes. */ 4466 for (bool expect_comma = false; ; expect_comma = true) 4467 { 4468 /* Parse a single attribute. */ 4469 tree attr = c_parser_attribute (parser, attrs, expect_comma); 4470 if (attr == error_mark_node) 4471 return attrs; 4472 if (!attr) 4473 break; 4474 attrs = attr; 4475 } 4476 4477 /* Look for the two `)' tokens. */ 4478 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 4479 c_parser_consume_token (parser); 4480 else 4481 { 4482 parser->lex_untranslated_string = false; 4483 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 4484 "expected %<)%>"); 4485 return attrs; 4486 } 4487 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 4488 c_parser_consume_token (parser); 4489 else 4490 { 4491 parser->lex_untranslated_string = false; 4492 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 4493 "expected %<)%>"); 4494 return attrs; 4495 } 4496 parser->lex_untranslated_string = false; 4497 } 4498 4499 return attrs; 4500 } 4501 4502 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK 4503 says whether alignment specifiers are OK (only in cases that might 4504 be the type name of a compound literal). 4505 4506 type-name: 4507 specifier-qualifier-list abstract-declarator[opt] 4508 */ 4509 4510 struct c_type_name * 4511 c_parser_type_name (c_parser *parser, bool alignas_ok) 4512 { 4513 struct c_declspecs *specs = build_null_declspecs (); 4514 struct c_declarator *declarator; 4515 struct c_type_name *ret; 4516 bool dummy = false; 4517 c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false, 4518 cla_prefer_type); 4519 if (!specs->declspecs_seen_p) 4520 { 4521 c_parser_error (parser, "expected specifier-qualifier-list"); 4522 return NULL; 4523 } 4524 if (specs->type != error_mark_node) 4525 { 4526 pending_xref_error (); 4527 finish_declspecs (specs); 4528 } 4529 declarator = c_parser_declarator (parser, 4530 specs->typespec_kind != ctsk_none, 4531 C_DTR_ABSTRACT, &dummy); 4532 if (declarator == NULL) 4533 return NULL; 4534 ret = XOBNEW (&parser_obstack, struct c_type_name); 4535 ret->specs = specs; 4536 ret->declarator = declarator; 4537 return ret; 4538 } 4539 4540 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9). 4541 4542 initializer: 4543 assignment-expression 4544 { initializer-list } 4545 { initializer-list , } 4546 4547 initializer-list: 4548 designation[opt] initializer 4549 initializer-list , designation[opt] initializer 4550 4551 designation: 4552 designator-list = 4553 4554 designator-list: 4555 designator 4556 designator-list designator 4557 4558 designator: 4559 array-designator 4560 . identifier 4561 4562 array-designator: 4563 [ constant-expression ] 4564 4565 GNU extensions: 4566 4567 initializer: 4568 { } 4569 4570 designation: 4571 array-designator 4572 identifier : 4573 4574 array-designator: 4575 [ constant-expression ... constant-expression ] 4576 4577 Any expression without commas is accepted in the syntax for the 4578 constant-expressions, with non-constant expressions rejected later. 4579 4580 This function is only used for top-level initializers; for nested 4581 ones, see c_parser_initval. */ 4582 4583 static struct c_expr 4584 c_parser_initializer (c_parser *parser) 4585 { 4586 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 4587 return c_parser_braced_init (parser, NULL_TREE, false, NULL); 4588 else 4589 { 4590 struct c_expr ret; 4591 location_t loc = c_parser_peek_token (parser)->location; 4592 ret = c_parser_expr_no_commas (parser, NULL); 4593 if (TREE_CODE (ret.value) != STRING_CST 4594 && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR) 4595 ret = convert_lvalue_to_rvalue (loc, ret, true, true); 4596 return ret; 4597 } 4598 } 4599 4600 /* The location of the last comma within the current initializer list, 4601 or UNKNOWN_LOCATION if not within one. */ 4602 4603 location_t last_init_list_comma; 4604 4605 /* Parse a braced initializer list. TYPE is the type specified for a 4606 compound literal, and NULL_TREE for other initializers and for 4607 nested braced lists. NESTED_P is true for nested braced lists, 4608 false for the list of a compound literal or the list that is the 4609 top-level initializer in a declaration. */ 4610 4611 static struct c_expr 4612 c_parser_braced_init (c_parser *parser, tree type, bool nested_p, 4613 struct obstack *outer_obstack) 4614 { 4615 struct c_expr ret; 4616 struct obstack braced_init_obstack; 4617 location_t brace_loc = c_parser_peek_token (parser)->location; 4618 gcc_obstack_init (&braced_init_obstack); 4619 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE)); 4620 matching_braces braces; 4621 braces.consume_open (parser); 4622 if (nested_p) 4623 { 4624 finish_implicit_inits (brace_loc, outer_obstack); 4625 push_init_level (brace_loc, 0, &braced_init_obstack); 4626 } 4627 else 4628 really_start_incremental_init (type); 4629 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 4630 { 4631 pedwarn (brace_loc, OPT_Wpedantic, "ISO C forbids empty initializer braces"); 4632 } 4633 else 4634 { 4635 /* Parse a non-empty initializer list, possibly with a trailing 4636 comma. */ 4637 while (true) 4638 { 4639 c_parser_initelt (parser, &braced_init_obstack); 4640 if (parser->error) 4641 break; 4642 if (c_parser_next_token_is (parser, CPP_COMMA)) 4643 { 4644 last_init_list_comma = c_parser_peek_token (parser)->location; 4645 c_parser_consume_token (parser); 4646 } 4647 else 4648 break; 4649 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 4650 break; 4651 } 4652 } 4653 c_token *next_tok = c_parser_peek_token (parser); 4654 if (next_tok->type != CPP_CLOSE_BRACE) 4655 { 4656 ret.set_error (); 4657 ret.original_code = ERROR_MARK; 4658 ret.original_type = NULL; 4659 braces.skip_until_found_close (parser); 4660 pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma); 4661 obstack_free (&braced_init_obstack, NULL); 4662 return ret; 4663 } 4664 location_t close_loc = next_tok->location; 4665 c_parser_consume_token (parser); 4666 ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc); 4667 obstack_free (&braced_init_obstack, NULL); 4668 set_c_expr_source_range (&ret, brace_loc, close_loc); 4669 return ret; 4670 } 4671 4672 /* Parse a nested initializer, including designators. */ 4673 4674 static void 4675 c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack) 4676 { 4677 /* Parse any designator or designator list. A single array 4678 designator may have the subsequent "=" omitted in GNU C, but a 4679 longer list or a structure member designator may not. */ 4680 if (c_parser_next_token_is (parser, CPP_NAME) 4681 && c_parser_peek_2nd_token (parser)->type == CPP_COLON) 4682 { 4683 /* Old-style structure member designator. */ 4684 set_init_label (c_parser_peek_token (parser)->location, 4685 c_parser_peek_token (parser)->value, 4686 c_parser_peek_token (parser)->location, 4687 braced_init_obstack); 4688 /* Use the colon as the error location. */ 4689 pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic, 4690 "obsolete use of designated initializer with %<:%>"); 4691 c_parser_consume_token (parser); 4692 c_parser_consume_token (parser); 4693 } 4694 else 4695 { 4696 /* des_seen is 0 if there have been no designators, 1 if there 4697 has been a single array designator and 2 otherwise. */ 4698 int des_seen = 0; 4699 /* Location of a designator. */ 4700 location_t des_loc = UNKNOWN_LOCATION; /* Quiet warning. */ 4701 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE) 4702 || c_parser_next_token_is (parser, CPP_DOT)) 4703 { 4704 int des_prev = des_seen; 4705 if (!des_seen) 4706 des_loc = c_parser_peek_token (parser)->location; 4707 if (des_seen < 2) 4708 des_seen++; 4709 if (c_parser_next_token_is (parser, CPP_DOT)) 4710 { 4711 des_seen = 2; 4712 c_parser_consume_token (parser); 4713 if (c_parser_next_token_is (parser, CPP_NAME)) 4714 { 4715 set_init_label (des_loc, c_parser_peek_token (parser)->value, 4716 c_parser_peek_token (parser)->location, 4717 braced_init_obstack); 4718 c_parser_consume_token (parser); 4719 } 4720 else 4721 { 4722 struct c_expr init; 4723 init.set_error (); 4724 init.original_code = ERROR_MARK; 4725 init.original_type = NULL; 4726 c_parser_error (parser, "expected identifier"); 4727 c_parser_skip_until_found (parser, CPP_COMMA, NULL); 4728 process_init_element (input_location, init, false, 4729 braced_init_obstack); 4730 return; 4731 } 4732 } 4733 else 4734 { 4735 tree first, second; 4736 location_t ellipsis_loc = UNKNOWN_LOCATION; /* Quiet warning. */ 4737 location_t array_index_loc = UNKNOWN_LOCATION; 4738 /* ??? Following the old parser, [ objc-receiver 4739 objc-message-args ] is accepted as an initializer, 4740 being distinguished from a designator by what follows 4741 the first assignment expression inside the square 4742 brackets, but after a first array designator a 4743 subsequent square bracket is for Objective-C taken to 4744 start an expression, using the obsolete form of 4745 designated initializer without '=', rather than 4746 possibly being a second level of designation: in LALR 4747 terms, the '[' is shifted rather than reducing 4748 designator to designator-list. */ 4749 if (des_prev == 1 && c_dialect_objc ()) 4750 { 4751 des_seen = des_prev; 4752 break; 4753 } 4754 if (des_prev == 0 && c_dialect_objc ()) 4755 { 4756 /* This might be an array designator or an 4757 Objective-C message expression. If the former, 4758 continue parsing here; if the latter, parse the 4759 remainder of the initializer given the starting 4760 primary-expression. ??? It might make sense to 4761 distinguish when des_prev == 1 as well; see 4762 previous comment. */ 4763 tree rec, args; 4764 struct c_expr mexpr; 4765 c_parser_consume_token (parser); 4766 if (c_parser_peek_token (parser)->type == CPP_NAME 4767 && ((c_parser_peek_token (parser)->id_kind 4768 == C_ID_TYPENAME) 4769 || (c_parser_peek_token (parser)->id_kind 4770 == C_ID_CLASSNAME))) 4771 { 4772 /* Type name receiver. */ 4773 tree id = c_parser_peek_token (parser)->value; 4774 c_parser_consume_token (parser); 4775 rec = objc_get_class_reference (id); 4776 goto parse_message_args; 4777 } 4778 first = c_parser_expr_no_commas (parser, NULL).value; 4779 mark_exp_read (first); 4780 if (c_parser_next_token_is (parser, CPP_ELLIPSIS) 4781 || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) 4782 goto array_desig_after_first; 4783 /* Expression receiver. So far only one part 4784 without commas has been parsed; there might be 4785 more of the expression. */ 4786 rec = first; 4787 while (c_parser_next_token_is (parser, CPP_COMMA)) 4788 { 4789 struct c_expr next; 4790 location_t comma_loc, exp_loc; 4791 comma_loc = c_parser_peek_token (parser)->location; 4792 c_parser_consume_token (parser); 4793 exp_loc = c_parser_peek_token (parser)->location; 4794 next = c_parser_expr_no_commas (parser, NULL); 4795 next = convert_lvalue_to_rvalue (exp_loc, next, 4796 true, true); 4797 rec = build_compound_expr (comma_loc, rec, next.value); 4798 } 4799 parse_message_args: 4800 /* Now parse the objc-message-args. */ 4801 args = c_parser_objc_message_args (parser); 4802 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, 4803 "expected %<]%>"); 4804 mexpr.value 4805 = objc_build_message_expr (rec, args); 4806 mexpr.original_code = ERROR_MARK; 4807 mexpr.original_type = NULL; 4808 /* Now parse and process the remainder of the 4809 initializer, starting with this message 4810 expression as a primary-expression. */ 4811 c_parser_initval (parser, &mexpr, braced_init_obstack); 4812 return; 4813 } 4814 c_parser_consume_token (parser); 4815 array_index_loc = c_parser_peek_token (parser)->location; 4816 first = c_parser_expr_no_commas (parser, NULL).value; 4817 mark_exp_read (first); 4818 array_desig_after_first: 4819 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) 4820 { 4821 ellipsis_loc = c_parser_peek_token (parser)->location; 4822 c_parser_consume_token (parser); 4823 second = c_parser_expr_no_commas (parser, NULL).value; 4824 mark_exp_read (second); 4825 } 4826 else 4827 second = NULL_TREE; 4828 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) 4829 { 4830 c_parser_consume_token (parser); 4831 set_init_index (array_index_loc, first, second, 4832 braced_init_obstack); 4833 if (second) 4834 pedwarn (ellipsis_loc, OPT_Wpedantic, 4835 "ISO C forbids specifying range of elements to initialize"); 4836 } 4837 else 4838 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, 4839 "expected %<]%>"); 4840 } 4841 } 4842 if (des_seen >= 1) 4843 { 4844 if (c_parser_next_token_is (parser, CPP_EQ)) 4845 { 4846 pedwarn_c90 (des_loc, OPT_Wpedantic, 4847 "ISO C90 forbids specifying subobject " 4848 "to initialize"); 4849 c_parser_consume_token (parser); 4850 } 4851 else 4852 { 4853 if (des_seen == 1) 4854 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic, 4855 "obsolete use of designated initializer without %<=%>"); 4856 else 4857 { 4858 struct c_expr init; 4859 init.set_error (); 4860 init.original_code = ERROR_MARK; 4861 init.original_type = NULL; 4862 c_parser_error (parser, "expected %<=%>"); 4863 c_parser_skip_until_found (parser, CPP_COMMA, NULL); 4864 process_init_element (input_location, init, false, 4865 braced_init_obstack); 4866 return; 4867 } 4868 } 4869 } 4870 } 4871 c_parser_initval (parser, NULL, braced_init_obstack); 4872 } 4873 4874 /* Parse a nested initializer; as c_parser_initializer but parses 4875 initializers within braced lists, after any designators have been 4876 applied. If AFTER is not NULL then it is an Objective-C message 4877 expression which is the primary-expression starting the 4878 initializer. */ 4879 4880 static void 4881 c_parser_initval (c_parser *parser, struct c_expr *after, 4882 struct obstack * braced_init_obstack) 4883 { 4884 struct c_expr init; 4885 gcc_assert (!after || c_dialect_objc ()); 4886 location_t loc = c_parser_peek_token (parser)->location; 4887 4888 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after) 4889 init = c_parser_braced_init (parser, NULL_TREE, true, 4890 braced_init_obstack); 4891 else 4892 { 4893 init = c_parser_expr_no_commas (parser, after); 4894 if (init.value != NULL_TREE 4895 && TREE_CODE (init.value) != STRING_CST 4896 && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR) 4897 init = convert_lvalue_to_rvalue (loc, init, true, true); 4898 } 4899 process_init_element (loc, init, false, braced_init_obstack); 4900 } 4901 4902 /* Parse a compound statement (possibly a function body) (C90 6.6.2, 4903 C99 6.8.2, C11 6.8.2). 4904 4905 compound-statement: 4906 { block-item-list[opt] } 4907 { label-declarations block-item-list } 4908 4909 block-item-list: 4910 block-item 4911 block-item-list block-item 4912 4913 block-item: 4914 nested-declaration 4915 statement 4916 4917 nested-declaration: 4918 declaration 4919 4920 GNU extensions: 4921 4922 compound-statement: 4923 { label-declarations block-item-list } 4924 4925 nested-declaration: 4926 __extension__ nested-declaration 4927 nested-function-definition 4928 4929 label-declarations: 4930 label-declaration 4931 label-declarations label-declaration 4932 4933 label-declaration: 4934 __label__ identifier-list ; 4935 4936 Allowing the mixing of declarations and code is new in C99. The 4937 GNU syntax also permits (not shown above) labels at the end of 4938 compound statements, which yield an error. We don't allow labels 4939 on declarations; this might seem like a natural extension, but 4940 there would be a conflict between attributes on the label and 4941 prefix attributes on the declaration. ??? The syntax follows the 4942 old parser in requiring something after label declarations. 4943 Although they are erroneous if the labels declared aren't defined, 4944 is it useful for the syntax to be this way? 4945 4946 OpenACC: 4947 4948 block-item: 4949 openacc-directive 4950 4951 openacc-directive: 4952 update-directive 4953 4954 OpenMP: 4955 4956 block-item: 4957 openmp-directive 4958 4959 openmp-directive: 4960 barrier-directive 4961 flush-directive 4962 taskwait-directive 4963 taskyield-directive 4964 cancel-directive 4965 cancellation-point-directive */ 4966 4967 static tree 4968 c_parser_compound_statement (c_parser *parser) 4969 { 4970 tree stmt; 4971 location_t brace_loc; 4972 brace_loc = c_parser_peek_token (parser)->location; 4973 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) 4974 { 4975 /* Ensure a scope is entered and left anyway to avoid confusion 4976 if we have just prepared to enter a function body. */ 4977 stmt = c_begin_compound_stmt (true); 4978 c_end_compound_stmt (brace_loc, stmt, true); 4979 return error_mark_node; 4980 } 4981 stmt = c_begin_compound_stmt (true); 4982 c_parser_compound_statement_nostart (parser); 4983 4984 return c_end_compound_stmt (brace_loc, stmt, true); 4985 } 4986 4987 /* Parse a compound statement except for the opening brace. This is 4988 used for parsing both compound statements and statement expressions 4989 (which follow different paths to handling the opening). */ 4990 4991 static void 4992 c_parser_compound_statement_nostart (c_parser *parser) 4993 { 4994 bool last_stmt = false; 4995 bool last_label = false; 4996 bool save_valid_for_pragma = valid_location_for_stdc_pragma_p (); 4997 location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */ 4998 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 4999 { 5000 add_debug_begin_stmt (c_parser_peek_token (parser)->location); 5001 c_parser_consume_token (parser); 5002 return; 5003 } 5004 mark_valid_location_for_stdc_pragma (true); 5005 if (c_parser_next_token_is_keyword (parser, RID_LABEL)) 5006 { 5007 /* Read zero or more forward-declarations for labels that nested 5008 functions can jump to. */ 5009 mark_valid_location_for_stdc_pragma (false); 5010 while (c_parser_next_token_is_keyword (parser, RID_LABEL)) 5011 { 5012 label_loc = c_parser_peek_token (parser)->location; 5013 c_parser_consume_token (parser); 5014 /* Any identifiers, including those declared as type names, 5015 are OK here. */ 5016 while (true) 5017 { 5018 tree label; 5019 if (c_parser_next_token_is_not (parser, CPP_NAME)) 5020 { 5021 c_parser_error (parser, "expected identifier"); 5022 break; 5023 } 5024 label 5025 = declare_label (c_parser_peek_token (parser)->value); 5026 C_DECLARED_LABEL_FLAG (label) = 1; 5027 add_stmt (build_stmt (label_loc, DECL_EXPR, label)); 5028 c_parser_consume_token (parser); 5029 if (c_parser_next_token_is (parser, CPP_COMMA)) 5030 c_parser_consume_token (parser); 5031 else 5032 break; 5033 } 5034 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 5035 } 5036 pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations"); 5037 } 5038 /* We must now have at least one statement, label or declaration. */ 5039 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 5040 { 5041 mark_valid_location_for_stdc_pragma (save_valid_for_pragma); 5042 c_parser_error (parser, "expected declaration or statement"); 5043 c_parser_consume_token (parser); 5044 return; 5045 } 5046 while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE)) 5047 { 5048 location_t loc = c_parser_peek_token (parser)->location; 5049 loc = expansion_point_location_if_in_system_header (loc); 5050 if (c_parser_next_token_is_keyword (parser, RID_CASE) 5051 || c_parser_next_token_is_keyword (parser, RID_DEFAULT) 5052 || (c_parser_next_token_is (parser, CPP_NAME) 5053 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) 5054 { 5055 if (c_parser_next_token_is_keyword (parser, RID_CASE)) 5056 label_loc = c_parser_peek_2nd_token (parser)->location; 5057 else 5058 label_loc = c_parser_peek_token (parser)->location; 5059 last_label = true; 5060 last_stmt = false; 5061 mark_valid_location_for_stdc_pragma (false); 5062 c_parser_label (parser); 5063 } 5064 else if (!last_label 5065 && c_parser_next_tokens_start_declaration (parser)) 5066 { 5067 last_label = false; 5068 mark_valid_location_for_stdc_pragma (false); 5069 bool fallthru_attr_p = false; 5070 c_parser_declaration_or_fndef (parser, true, true, true, true, 5071 true, NULL, vNULL, NULL, 5072 &fallthru_attr_p); 5073 if (last_stmt && !fallthru_attr_p) 5074 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement, 5075 "ISO C90 forbids mixed declarations and code"); 5076 last_stmt = fallthru_attr_p; 5077 } 5078 else if (!last_label 5079 && c_parser_next_token_is_keyword (parser, RID_EXTENSION)) 5080 { 5081 /* __extension__ can start a declaration, but is also an 5082 unary operator that can start an expression. Consume all 5083 but the last of a possible series of __extension__ to 5084 determine which. */ 5085 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD 5086 && (c_parser_peek_2nd_token (parser)->keyword 5087 == RID_EXTENSION)) 5088 c_parser_consume_token (parser); 5089 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser))) 5090 { 5091 int ext; 5092 ext = disable_extension_diagnostics (); 5093 c_parser_consume_token (parser); 5094 last_label = false; 5095 mark_valid_location_for_stdc_pragma (false); 5096 c_parser_declaration_or_fndef (parser, true, true, true, true, 5097 true, NULL, vNULL); 5098 /* Following the old parser, __extension__ does not 5099 disable this diagnostic. */ 5100 restore_extension_diagnostics (ext); 5101 if (last_stmt) 5102 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement, 5103 "ISO C90 forbids mixed declarations and code"); 5104 last_stmt = false; 5105 } 5106 else 5107 goto statement; 5108 } 5109 else if (c_parser_next_token_is (parser, CPP_PRAGMA)) 5110 { 5111 /* External pragmas, and some omp pragmas, are not associated 5112 with regular c code, and so are not to be considered statements 5113 syntactically. This ensures that the user doesn't put them 5114 places that would turn into syntax errors if the directive 5115 were ignored. */ 5116 if (c_parser_pragma (parser, 5117 last_label ? pragma_stmt : pragma_compound, 5118 NULL)) 5119 last_label = false, last_stmt = true; 5120 } 5121 else if (c_parser_next_token_is (parser, CPP_EOF)) 5122 { 5123 mark_valid_location_for_stdc_pragma (save_valid_for_pragma); 5124 c_parser_error (parser, "expected declaration or statement"); 5125 return; 5126 } 5127 else if (c_parser_next_token_is_keyword (parser, RID_ELSE)) 5128 { 5129 if (parser->in_if_block) 5130 { 5131 mark_valid_location_for_stdc_pragma (save_valid_for_pragma); 5132 error_at (loc, "expected %<}%> before %<else%>"); 5133 return; 5134 } 5135 else 5136 { 5137 error_at (loc, "%<else%> without a previous %<if%>"); 5138 c_parser_consume_token (parser); 5139 continue; 5140 } 5141 } 5142 else 5143 { 5144 statement: 5145 last_label = false; 5146 last_stmt = true; 5147 mark_valid_location_for_stdc_pragma (false); 5148 c_parser_statement_after_labels (parser, NULL); 5149 } 5150 5151 parser->error = false; 5152 } 5153 if (last_label) 5154 error_at (label_loc, "label at end of compound statement"); 5155 c_parser_consume_token (parser); 5156 /* Restore the value we started with. */ 5157 mark_valid_location_for_stdc_pragma (save_valid_for_pragma); 5158 } 5159 5160 /* Parse all consecutive labels. */ 5161 5162 static void 5163 c_parser_all_labels (c_parser *parser) 5164 { 5165 while (c_parser_next_token_is_keyword (parser, RID_CASE) 5166 || c_parser_next_token_is_keyword (parser, RID_DEFAULT) 5167 || (c_parser_next_token_is (parser, CPP_NAME) 5168 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) 5169 c_parser_label (parser); 5170 } 5171 5172 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1). 5173 5174 label: 5175 identifier : attributes[opt] 5176 case constant-expression : 5177 default : 5178 5179 GNU extensions: 5180 5181 label: 5182 case constant-expression ... constant-expression : 5183 5184 The use of attributes on labels is a GNU extension. The syntax in 5185 GNU C accepts any expressions without commas, non-constant 5186 expressions being rejected later. */ 5187 5188 static void 5189 c_parser_label (c_parser *parser) 5190 { 5191 location_t loc1 = c_parser_peek_token (parser)->location; 5192 tree label = NULL_TREE; 5193 5194 /* Remember whether this case or a user-defined label is allowed to fall 5195 through to. */ 5196 bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH; 5197 5198 if (c_parser_next_token_is_keyword (parser, RID_CASE)) 5199 { 5200 tree exp1, exp2; 5201 c_parser_consume_token (parser); 5202 exp1 = c_parser_expr_no_commas (parser, NULL).value; 5203 if (c_parser_next_token_is (parser, CPP_COLON)) 5204 { 5205 c_parser_consume_token (parser); 5206 label = do_case (loc1, exp1, NULL_TREE); 5207 } 5208 else if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) 5209 { 5210 c_parser_consume_token (parser); 5211 exp2 = c_parser_expr_no_commas (parser, NULL).value; 5212 if (c_parser_require (parser, CPP_COLON, "expected %<:%>")) 5213 label = do_case (loc1, exp1, exp2); 5214 } 5215 else 5216 c_parser_error (parser, "expected %<:%> or %<...%>"); 5217 } 5218 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)) 5219 { 5220 c_parser_consume_token (parser); 5221 if (c_parser_require (parser, CPP_COLON, "expected %<:%>")) 5222 label = do_case (loc1, NULL_TREE, NULL_TREE); 5223 } 5224 else 5225 { 5226 tree name = c_parser_peek_token (parser)->value; 5227 tree tlab; 5228 tree attrs; 5229 location_t loc2 = c_parser_peek_token (parser)->location; 5230 gcc_assert (c_parser_next_token_is (parser, CPP_NAME)); 5231 c_parser_consume_token (parser); 5232 gcc_assert (c_parser_next_token_is (parser, CPP_COLON)); 5233 c_parser_consume_token (parser); 5234 attrs = c_parser_attributes (parser); 5235 tlab = define_label (loc2, name); 5236 if (tlab) 5237 { 5238 decl_attributes (&tlab, attrs, 0); 5239 label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab)); 5240 } 5241 } 5242 if (label) 5243 { 5244 if (TREE_CODE (label) == LABEL_EXPR) 5245 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p; 5246 else 5247 FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p; 5248 5249 /* Allow '__attribute__((fallthrough));'. */ 5250 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 5251 { 5252 location_t loc = c_parser_peek_token (parser)->location; 5253 tree attrs = c_parser_attributes (parser); 5254 if (attribute_fallthrough_p (attrs)) 5255 { 5256 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 5257 { 5258 tree fn = build_call_expr_internal_loc (loc, 5259 IFN_FALLTHROUGH, 5260 void_type_node, 0); 5261 add_stmt (fn); 5262 } 5263 else 5264 warning_at (loc, OPT_Wattributes, "%<fallthrough%> attribute " 5265 "not followed by %<;%>"); 5266 } 5267 else if (attrs != NULL_TREE) 5268 warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>" 5269 " can be applied to a null statement"); 5270 } 5271 if (c_parser_next_tokens_start_declaration (parser)) 5272 { 5273 error_at (c_parser_peek_token (parser)->location, 5274 "a label can only be part of a statement and " 5275 "a declaration is not a statement"); 5276 c_parser_declaration_or_fndef (parser, /*fndef_ok*/ false, 5277 /*static_assert_ok*/ true, 5278 /*empty_ok*/ true, /*nested*/ true, 5279 /*start_attr_ok*/ true, NULL, 5280 vNULL); 5281 } 5282 } 5283 } 5284 5285 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8). 5286 5287 statement: 5288 labeled-statement 5289 compound-statement 5290 expression-statement 5291 selection-statement 5292 iteration-statement 5293 jump-statement 5294 5295 labeled-statement: 5296 label statement 5297 5298 expression-statement: 5299 expression[opt] ; 5300 5301 selection-statement: 5302 if-statement 5303 switch-statement 5304 5305 iteration-statement: 5306 while-statement 5307 do-statement 5308 for-statement 5309 5310 jump-statement: 5311 goto identifier ; 5312 continue ; 5313 break ; 5314 return expression[opt] ; 5315 5316 GNU extensions: 5317 5318 statement: 5319 asm-statement 5320 5321 jump-statement: 5322 goto * expression ; 5323 5324 expression-statement: 5325 attributes ; 5326 5327 Objective-C: 5328 5329 statement: 5330 objc-throw-statement 5331 objc-try-catch-statement 5332 objc-synchronized-statement 5333 5334 objc-throw-statement: 5335 @throw expression ; 5336 @throw ; 5337 5338 OpenACC: 5339 5340 statement: 5341 openacc-construct 5342 5343 openacc-construct: 5344 parallel-construct 5345 kernels-construct 5346 data-construct 5347 loop-construct 5348 5349 parallel-construct: 5350 parallel-directive structured-block 5351 5352 kernels-construct: 5353 kernels-directive structured-block 5354 5355 data-construct: 5356 data-directive structured-block 5357 5358 loop-construct: 5359 loop-directive structured-block 5360 5361 OpenMP: 5362 5363 statement: 5364 openmp-construct 5365 5366 openmp-construct: 5367 parallel-construct 5368 for-construct 5369 simd-construct 5370 for-simd-construct 5371 sections-construct 5372 single-construct 5373 parallel-for-construct 5374 parallel-for-simd-construct 5375 parallel-sections-construct 5376 master-construct 5377 critical-construct 5378 atomic-construct 5379 ordered-construct 5380 5381 parallel-construct: 5382 parallel-directive structured-block 5383 5384 for-construct: 5385 for-directive iteration-statement 5386 5387 simd-construct: 5388 simd-directive iteration-statements 5389 5390 for-simd-construct: 5391 for-simd-directive iteration-statements 5392 5393 sections-construct: 5394 sections-directive section-scope 5395 5396 single-construct: 5397 single-directive structured-block 5398 5399 parallel-for-construct: 5400 parallel-for-directive iteration-statement 5401 5402 parallel-for-simd-construct: 5403 parallel-for-simd-directive iteration-statement 5404 5405 parallel-sections-construct: 5406 parallel-sections-directive section-scope 5407 5408 master-construct: 5409 master-directive structured-block 5410 5411 critical-construct: 5412 critical-directive structured-block 5413 5414 atomic-construct: 5415 atomic-directive expression-statement 5416 5417 ordered-construct: 5418 ordered-directive structured-block 5419 5420 Transactional Memory: 5421 5422 statement: 5423 transaction-statement 5424 transaction-cancel-statement 5425 5426 IF_P is used to track whether there's a (possibly labeled) if statement 5427 which is not enclosed in braces and has an else clause. This is used to 5428 implement -Wparentheses. */ 5429 5430 static void 5431 c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels) 5432 { 5433 c_parser_all_labels (parser); 5434 if (loc_after_labels) 5435 *loc_after_labels = c_parser_peek_token (parser)->location; 5436 c_parser_statement_after_labels (parser, if_p, NULL); 5437 } 5438 5439 /* Parse a statement, other than a labeled statement. CHAIN is a vector 5440 of if-else-if conditions. 5441 5442 IF_P is used to track whether there's a (possibly labeled) if statement 5443 which is not enclosed in braces and has an else clause. This is used to 5444 implement -Wparentheses. */ 5445 5446 static void 5447 c_parser_statement_after_labels (c_parser *parser, bool *if_p, 5448 vec<tree> *chain) 5449 { 5450 location_t loc = c_parser_peek_token (parser)->location; 5451 tree stmt = NULL_TREE; 5452 bool in_if_block = parser->in_if_block; 5453 parser->in_if_block = false; 5454 if (if_p != NULL) 5455 *if_p = false; 5456 5457 if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE) 5458 add_debug_begin_stmt (loc); 5459 5460 switch (c_parser_peek_token (parser)->type) 5461 { 5462 case CPP_OPEN_BRACE: 5463 add_stmt (c_parser_compound_statement (parser)); 5464 break; 5465 case CPP_KEYWORD: 5466 switch (c_parser_peek_token (parser)->keyword) 5467 { 5468 case RID_IF: 5469 c_parser_if_statement (parser, if_p, chain); 5470 break; 5471 case RID_SWITCH: 5472 c_parser_switch_statement (parser, if_p); 5473 break; 5474 case RID_WHILE: 5475 c_parser_while_statement (parser, false, 0, if_p); 5476 break; 5477 case RID_DO: 5478 c_parser_do_statement (parser, 0, false); 5479 break; 5480 case RID_FOR: 5481 c_parser_for_statement (parser, false, 0, if_p); 5482 break; 5483 case RID_GOTO: 5484 c_parser_consume_token (parser); 5485 if (c_parser_next_token_is (parser, CPP_NAME)) 5486 { 5487 stmt = c_finish_goto_label (loc, 5488 c_parser_peek_token (parser)->value); 5489 c_parser_consume_token (parser); 5490 } 5491 else if (c_parser_next_token_is (parser, CPP_MULT)) 5492 { 5493 struct c_expr val; 5494 5495 c_parser_consume_token (parser); 5496 val = c_parser_expression (parser); 5497 val = convert_lvalue_to_rvalue (loc, val, false, true); 5498 stmt = c_finish_goto_ptr (loc, val.value); 5499 } 5500 else 5501 c_parser_error (parser, "expected identifier or %<*%>"); 5502 goto expect_semicolon; 5503 case RID_CONTINUE: 5504 c_parser_consume_token (parser); 5505 stmt = c_finish_bc_stmt (loc, &c_cont_label, false); 5506 goto expect_semicolon; 5507 case RID_BREAK: 5508 c_parser_consume_token (parser); 5509 stmt = c_finish_bc_stmt (loc, &c_break_label, true); 5510 goto expect_semicolon; 5511 case RID_RETURN: 5512 c_parser_consume_token (parser); 5513 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 5514 { 5515 stmt = c_finish_return (loc, NULL_TREE, NULL_TREE); 5516 c_parser_consume_token (parser); 5517 } 5518 else 5519 { 5520 location_t xloc = c_parser_peek_token (parser)->location; 5521 struct c_expr expr = c_parser_expression_conv (parser); 5522 mark_exp_read (expr.value); 5523 stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc), 5524 expr.value, expr.original_type); 5525 goto expect_semicolon; 5526 } 5527 break; 5528 case RID_ASM: 5529 stmt = c_parser_asm_statement (parser); 5530 break; 5531 case RID_TRANSACTION_ATOMIC: 5532 case RID_TRANSACTION_RELAXED: 5533 stmt = c_parser_transaction (parser, 5534 c_parser_peek_token (parser)->keyword); 5535 break; 5536 case RID_TRANSACTION_CANCEL: 5537 stmt = c_parser_transaction_cancel (parser); 5538 goto expect_semicolon; 5539 case RID_AT_THROW: 5540 gcc_assert (c_dialect_objc ()); 5541 c_parser_consume_token (parser); 5542 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 5543 { 5544 stmt = objc_build_throw_stmt (loc, NULL_TREE); 5545 c_parser_consume_token (parser); 5546 } 5547 else 5548 { 5549 struct c_expr expr = c_parser_expression (parser); 5550 expr = convert_lvalue_to_rvalue (loc, expr, false, false); 5551 expr.value = c_fully_fold (expr.value, false, NULL); 5552 stmt = objc_build_throw_stmt (loc, expr.value); 5553 goto expect_semicolon; 5554 } 5555 break; 5556 case RID_AT_TRY: 5557 gcc_assert (c_dialect_objc ()); 5558 c_parser_objc_try_catch_finally_statement (parser); 5559 break; 5560 case RID_AT_SYNCHRONIZED: 5561 gcc_assert (c_dialect_objc ()); 5562 c_parser_objc_synchronized_statement (parser); 5563 break; 5564 case RID_ATTRIBUTE: 5565 { 5566 /* Allow '__attribute__((fallthrough));'. */ 5567 tree attrs = c_parser_attributes (parser); 5568 if (attribute_fallthrough_p (attrs)) 5569 { 5570 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 5571 { 5572 tree fn = build_call_expr_internal_loc (loc, 5573 IFN_FALLTHROUGH, 5574 void_type_node, 0); 5575 add_stmt (fn); 5576 /* Eat the ';'. */ 5577 c_parser_consume_token (parser); 5578 } 5579 else 5580 warning_at (loc, OPT_Wattributes, 5581 "%<fallthrough%> attribute not followed " 5582 "by %<;%>"); 5583 } 5584 else if (attrs != NULL_TREE) 5585 warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>" 5586 " can be applied to a null statement"); 5587 break; 5588 } 5589 default: 5590 goto expr_stmt; 5591 } 5592 break; 5593 case CPP_SEMICOLON: 5594 c_parser_consume_token (parser); 5595 break; 5596 case CPP_CLOSE_PAREN: 5597 case CPP_CLOSE_SQUARE: 5598 /* Avoid infinite loop in error recovery: 5599 c_parser_skip_until_found stops at a closing nesting 5600 delimiter without consuming it, but here we need to consume 5601 it to proceed further. */ 5602 c_parser_error (parser, "expected statement"); 5603 c_parser_consume_token (parser); 5604 break; 5605 case CPP_PRAGMA: 5606 c_parser_pragma (parser, pragma_stmt, if_p); 5607 break; 5608 default: 5609 expr_stmt: 5610 stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value); 5611 expect_semicolon: 5612 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 5613 break; 5614 } 5615 /* Two cases cannot and do not have line numbers associated: If stmt 5616 is degenerate, such as "2;", then stmt is an INTEGER_CST, which 5617 cannot hold line numbers. But that's OK because the statement 5618 will either be changed to a MODIFY_EXPR during gimplification of 5619 the statement expr, or discarded. If stmt was compound, but 5620 without new variables, we will have skipped the creation of a 5621 BIND and will have a bare STATEMENT_LIST. But that's OK because 5622 (recursively) all of the component statements should already have 5623 line numbers assigned. ??? Can we discard no-op statements 5624 earlier? */ 5625 if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION) 5626 protected_set_expr_location (stmt, loc); 5627 5628 parser->in_if_block = in_if_block; 5629 } 5630 5631 /* Parse the condition from an if, do, while or for statements. */ 5632 5633 static tree 5634 c_parser_condition (c_parser *parser) 5635 { 5636 location_t loc = c_parser_peek_token (parser)->location; 5637 tree cond; 5638 cond = c_parser_expression_conv (parser).value; 5639 cond = c_objc_common_truthvalue_conversion (loc, cond); 5640 cond = c_fully_fold (cond, false, NULL); 5641 if (warn_sequence_point) 5642 verify_sequence_points (cond); 5643 return cond; 5644 } 5645 5646 /* Parse a parenthesized condition from an if, do or while statement. 5647 5648 condition: 5649 ( expression ) 5650 */ 5651 static tree 5652 c_parser_paren_condition (c_parser *parser) 5653 { 5654 tree cond; 5655 matching_parens parens; 5656 if (!parens.require_open (parser)) 5657 return error_mark_node; 5658 cond = c_parser_condition (parser); 5659 parens.skip_until_found_close (parser); 5660 return cond; 5661 } 5662 5663 /* Parse a statement which is a block in C99. 5664 5665 IF_P is used to track whether there's a (possibly labeled) if statement 5666 which is not enclosed in braces and has an else clause. This is used to 5667 implement -Wparentheses. */ 5668 5669 static tree 5670 c_parser_c99_block_statement (c_parser *parser, bool *if_p, 5671 location_t *loc_after_labels) 5672 { 5673 tree block = c_begin_compound_stmt (flag_isoc99); 5674 location_t loc = c_parser_peek_token (parser)->location; 5675 c_parser_statement (parser, if_p, loc_after_labels); 5676 return c_end_compound_stmt (loc, block, flag_isoc99); 5677 } 5678 5679 /* Parse the body of an if statement. This is just parsing a 5680 statement but (a) it is a block in C99, (b) we track whether the 5681 body is an if statement for the sake of -Wparentheses warnings, (c) 5682 we handle an empty body specially for the sake of -Wempty-body 5683 warnings, and (d) we call parser_compound_statement directly 5684 because c_parser_statement_after_labels resets 5685 parser->in_if_block. 5686 5687 IF_P is used to track whether there's a (possibly labeled) if statement 5688 which is not enclosed in braces and has an else clause. This is used to 5689 implement -Wparentheses. */ 5690 5691 static tree 5692 c_parser_if_body (c_parser *parser, bool *if_p, 5693 const token_indent_info &if_tinfo) 5694 { 5695 tree block = c_begin_compound_stmt (flag_isoc99); 5696 location_t body_loc = c_parser_peek_token (parser)->location; 5697 location_t body_loc_after_labels = UNKNOWN_LOCATION; 5698 token_indent_info body_tinfo 5699 = get_token_indent_info (c_parser_peek_token (parser)); 5700 5701 c_parser_all_labels (parser); 5702 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 5703 { 5704 location_t loc = c_parser_peek_token (parser)->location; 5705 add_stmt (build_empty_stmt (loc)); 5706 c_parser_consume_token (parser); 5707 if (!c_parser_next_token_is_keyword (parser, RID_ELSE)) 5708 warning_at (loc, OPT_Wempty_body, 5709 "suggest braces around empty body in an %<if%> statement"); 5710 } 5711 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 5712 add_stmt (c_parser_compound_statement (parser)); 5713 else 5714 { 5715 body_loc_after_labels = c_parser_peek_token (parser)->location; 5716 c_parser_statement_after_labels (parser, if_p); 5717 } 5718 5719 token_indent_info next_tinfo 5720 = get_token_indent_info (c_parser_peek_token (parser)); 5721 warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo); 5722 if (body_loc_after_labels != UNKNOWN_LOCATION 5723 && next_tinfo.type != CPP_SEMICOLON) 5724 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location, 5725 if_tinfo.location, RID_IF); 5726 5727 return c_end_compound_stmt (body_loc, block, flag_isoc99); 5728 } 5729 5730 /* Parse the else body of an if statement. This is just parsing a 5731 statement but (a) it is a block in C99, (b) we handle an empty body 5732 specially for the sake of -Wempty-body warnings. CHAIN is a vector 5733 of if-else-if conditions. */ 5734 5735 static tree 5736 c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo, 5737 vec<tree> *chain) 5738 { 5739 location_t body_loc = c_parser_peek_token (parser)->location; 5740 tree block = c_begin_compound_stmt (flag_isoc99); 5741 token_indent_info body_tinfo 5742 = get_token_indent_info (c_parser_peek_token (parser)); 5743 location_t body_loc_after_labels = UNKNOWN_LOCATION; 5744 5745 c_parser_all_labels (parser); 5746 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 5747 { 5748 location_t loc = c_parser_peek_token (parser)->location; 5749 warning_at (loc, 5750 OPT_Wempty_body, 5751 "suggest braces around empty body in an %<else%> statement"); 5752 add_stmt (build_empty_stmt (loc)); 5753 c_parser_consume_token (parser); 5754 } 5755 else 5756 { 5757 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 5758 body_loc_after_labels = c_parser_peek_token (parser)->location; 5759 c_parser_statement_after_labels (parser, NULL, chain); 5760 } 5761 5762 token_indent_info next_tinfo 5763 = get_token_indent_info (c_parser_peek_token (parser)); 5764 warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo); 5765 if (body_loc_after_labels != UNKNOWN_LOCATION 5766 && next_tinfo.type != CPP_SEMICOLON) 5767 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location, 5768 else_tinfo.location, RID_ELSE); 5769 5770 return c_end_compound_stmt (body_loc, block, flag_isoc99); 5771 } 5772 5773 /* We might need to reclassify any previously-lexed identifier, e.g. 5774 when we've left a for loop with an if-statement without else in the 5775 body - we might have used a wrong scope for the token. See PR67784. */ 5776 5777 static void 5778 c_parser_maybe_reclassify_token (c_parser *parser) 5779 { 5780 if (c_parser_next_token_is (parser, CPP_NAME)) 5781 { 5782 c_token *token = c_parser_peek_token (parser); 5783 5784 if (token->id_kind != C_ID_CLASSNAME) 5785 { 5786 tree decl = lookup_name (token->value); 5787 5788 token->id_kind = C_ID_ID; 5789 if (decl) 5790 { 5791 if (TREE_CODE (decl) == TYPE_DECL) 5792 token->id_kind = C_ID_TYPENAME; 5793 } 5794 else if (c_dialect_objc ()) 5795 { 5796 tree objc_interface_decl = objc_is_class_name (token->value); 5797 /* Objective-C class names are in the same namespace as 5798 variables and typedefs, and hence are shadowed by local 5799 declarations. */ 5800 if (objc_interface_decl) 5801 { 5802 token->value = objc_interface_decl; 5803 token->id_kind = C_ID_CLASSNAME; 5804 } 5805 } 5806 } 5807 } 5808 } 5809 5810 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4). 5811 5812 if-statement: 5813 if ( expression ) statement 5814 if ( expression ) statement else statement 5815 5816 CHAIN is a vector of if-else-if conditions. 5817 IF_P is used to track whether there's a (possibly labeled) if statement 5818 which is not enclosed in braces and has an else clause. This is used to 5819 implement -Wparentheses. */ 5820 5821 static void 5822 c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain) 5823 { 5824 tree block; 5825 location_t loc; 5826 tree cond; 5827 bool nested_if = false; 5828 tree first_body, second_body; 5829 bool in_if_block; 5830 5831 gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF)); 5832 token_indent_info if_tinfo 5833 = get_token_indent_info (c_parser_peek_token (parser)); 5834 c_parser_consume_token (parser); 5835 block = c_begin_compound_stmt (flag_isoc99); 5836 loc = c_parser_peek_token (parser)->location; 5837 cond = c_parser_paren_condition (parser); 5838 in_if_block = parser->in_if_block; 5839 parser->in_if_block = true; 5840 first_body = c_parser_if_body (parser, &nested_if, if_tinfo); 5841 parser->in_if_block = in_if_block; 5842 5843 if (warn_duplicated_cond) 5844 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain); 5845 5846 if (c_parser_next_token_is_keyword (parser, RID_ELSE)) 5847 { 5848 token_indent_info else_tinfo 5849 = get_token_indent_info (c_parser_peek_token (parser)); 5850 c_parser_consume_token (parser); 5851 if (warn_duplicated_cond) 5852 { 5853 if (c_parser_next_token_is_keyword (parser, RID_IF) 5854 && chain == NULL) 5855 { 5856 /* We've got "if (COND) else if (COND2)". Start the 5857 condition chain and add COND as the first element. */ 5858 chain = new vec<tree> (); 5859 if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond)) 5860 chain->safe_push (cond); 5861 } 5862 else if (!c_parser_next_token_is_keyword (parser, RID_IF)) 5863 { 5864 /* This is if-else without subsequent if. Zap the condition 5865 chain; we would have already warned at this point. */ 5866 delete chain; 5867 chain = NULL; 5868 } 5869 } 5870 second_body = c_parser_else_body (parser, else_tinfo, chain); 5871 /* Set IF_P to true to indicate that this if statement has an 5872 else clause. This may trigger the Wparentheses warning 5873 below when we get back up to the parent if statement. */ 5874 if (if_p != NULL) 5875 *if_p = true; 5876 } 5877 else 5878 { 5879 second_body = NULL_TREE; 5880 5881 /* Diagnose an ambiguous else if if-then-else is nested inside 5882 if-then. */ 5883 if (nested_if) 5884 warning_at (loc, OPT_Wdangling_else, 5885 "suggest explicit braces to avoid ambiguous %<else%>"); 5886 5887 if (warn_duplicated_cond) 5888 { 5889 /* This if statement does not have an else clause. We don't 5890 need the condition chain anymore. */ 5891 delete chain; 5892 chain = NULL; 5893 } 5894 } 5895 c_finish_if_stmt (loc, cond, first_body, second_body); 5896 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99)); 5897 5898 c_parser_maybe_reclassify_token (parser); 5899 } 5900 5901 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4). 5902 5903 switch-statement: 5904 switch (expression) statement 5905 */ 5906 5907 static void 5908 c_parser_switch_statement (c_parser *parser, bool *if_p) 5909 { 5910 struct c_expr ce; 5911 tree block, expr, body, save_break; 5912 location_t switch_loc = c_parser_peek_token (parser)->location; 5913 location_t switch_cond_loc; 5914 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH)); 5915 c_parser_consume_token (parser); 5916 block = c_begin_compound_stmt (flag_isoc99); 5917 bool explicit_cast_p = false; 5918 matching_parens parens; 5919 if (parens.require_open (parser)) 5920 { 5921 switch_cond_loc = c_parser_peek_token (parser)->location; 5922 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN) 5923 && c_token_starts_typename (c_parser_peek_2nd_token (parser))) 5924 explicit_cast_p = true; 5925 ce = c_parser_expression (parser); 5926 ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, false); 5927 expr = ce.value; 5928 /* ??? expr has no valid location? */ 5929 parens.skip_until_found_close (parser); 5930 } 5931 else 5932 { 5933 switch_cond_loc = UNKNOWN_LOCATION; 5934 expr = error_mark_node; 5935 ce.original_type = error_mark_node; 5936 } 5937 c_start_case (switch_loc, switch_cond_loc, expr, explicit_cast_p); 5938 save_break = c_break_label; 5939 c_break_label = NULL_TREE; 5940 location_t loc_after_labels; 5941 bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE; 5942 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels); 5943 location_t next_loc = c_parser_peek_token (parser)->location; 5944 if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON) 5945 warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc, 5946 RID_SWITCH); 5947 if (c_break_label) 5948 { 5949 location_t here = c_parser_peek_token (parser)->location; 5950 tree t = build1 (LABEL_EXPR, void_type_node, c_break_label); 5951 SET_EXPR_LOCATION (t, here); 5952 SWITCH_BREAK_LABEL_P (c_break_label) = 1; 5953 append_to_statement_list_force (t, &body); 5954 } 5955 c_finish_case (body, ce.original_type); 5956 c_break_label = save_break; 5957 add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99)); 5958 c_parser_maybe_reclassify_token (parser); 5959 } 5960 5961 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5). 5962 5963 while-statement: 5964 while (expression) statement 5965 5966 IF_P is used to track whether there's a (possibly labeled) if statement 5967 which is not enclosed in braces and has an else clause. This is used to 5968 implement -Wparentheses. */ 5969 5970 static void 5971 c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll, 5972 bool *if_p) 5973 { 5974 tree block, cond, body, save_break, save_cont; 5975 location_t loc; 5976 gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE)); 5977 token_indent_info while_tinfo 5978 = get_token_indent_info (c_parser_peek_token (parser)); 5979 c_parser_consume_token (parser); 5980 block = c_begin_compound_stmt (flag_isoc99); 5981 loc = c_parser_peek_token (parser)->location; 5982 cond = c_parser_paren_condition (parser); 5983 if (ivdep && cond != error_mark_node) 5984 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, 5985 build_int_cst (integer_type_node, 5986 annot_expr_ivdep_kind), 5987 integer_zero_node); 5988 if (unroll && cond != error_mark_node) 5989 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, 5990 build_int_cst (integer_type_node, 5991 annot_expr_unroll_kind), 5992 build_int_cst (integer_type_node, unroll)); 5993 save_break = c_break_label; 5994 c_break_label = NULL_TREE; 5995 save_cont = c_cont_label; 5996 c_cont_label = NULL_TREE; 5997 5998 token_indent_info body_tinfo 5999 = get_token_indent_info (c_parser_peek_token (parser)); 6000 6001 location_t loc_after_labels; 6002 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE); 6003 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels); 6004 c_finish_loop (loc, loc, cond, UNKNOWN_LOCATION, NULL, body, 6005 c_break_label, c_cont_label, true); 6006 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99)); 6007 c_parser_maybe_reclassify_token (parser); 6008 6009 token_indent_info next_tinfo 6010 = get_token_indent_info (c_parser_peek_token (parser)); 6011 warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo); 6012 6013 if (next_tinfo.type != CPP_SEMICOLON && !open_brace) 6014 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location, 6015 while_tinfo.location, RID_WHILE); 6016 6017 c_break_label = save_break; 6018 c_cont_label = save_cont; 6019 } 6020 6021 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5). 6022 6023 do-statement: 6024 do statement while ( expression ) ; 6025 */ 6026 6027 static void 6028 c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll) 6029 { 6030 tree block, cond, body, save_break, save_cont, new_break, new_cont; 6031 location_t loc; 6032 gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO)); 6033 c_parser_consume_token (parser); 6034 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 6035 warning_at (c_parser_peek_token (parser)->location, 6036 OPT_Wempty_body, 6037 "suggest braces around empty body in %<do%> statement"); 6038 block = c_begin_compound_stmt (flag_isoc99); 6039 loc = c_parser_peek_token (parser)->location; 6040 save_break = c_break_label; 6041 c_break_label = NULL_TREE; 6042 save_cont = c_cont_label; 6043 c_cont_label = NULL_TREE; 6044 body = c_parser_c99_block_statement (parser, NULL); 6045 c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>"); 6046 new_break = c_break_label; 6047 c_break_label = save_break; 6048 new_cont = c_cont_label; 6049 c_cont_label = save_cont; 6050 location_t cond_loc = c_parser_peek_token (parser)->location; 6051 cond = c_parser_paren_condition (parser); 6052 if (ivdep && cond != error_mark_node) 6053 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, 6054 build_int_cst (integer_type_node, 6055 annot_expr_ivdep_kind), 6056 integer_zero_node); 6057 if (unroll && cond != error_mark_node) 6058 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, 6059 build_int_cst (integer_type_node, 6060 annot_expr_unroll_kind), 6061 build_int_cst (integer_type_node, unroll)); 6062 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>")) 6063 c_parser_skip_to_end_of_block_or_statement (parser); 6064 c_finish_loop (loc, cond_loc, cond, UNKNOWN_LOCATION, NULL, body, 6065 new_break, new_cont, false); 6066 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99)); 6067 } 6068 6069 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5). 6070 6071 for-statement: 6072 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement 6073 for ( nested-declaration expression[opt] ; expression[opt] ) statement 6074 6075 The form with a declaration is new in C99. 6076 6077 ??? In accordance with the old parser, the declaration may be a 6078 nested function, which is then rejected in check_for_loop_decls, 6079 but does it make any sense for this to be included in the grammar? 6080 Note in particular that the nested function does not include a 6081 trailing ';', whereas the "declaration" production includes one. 6082 Also, can we reject bad declarations earlier and cheaper than 6083 check_for_loop_decls? 6084 6085 In Objective-C, there are two additional variants: 6086 6087 foreach-statement: 6088 for ( expression in expresssion ) statement 6089 for ( declaration in expression ) statement 6090 6091 This is inconsistent with C, because the second variant is allowed 6092 even if c99 is not enabled. 6093 6094 The rest of the comment documents these Objective-C foreach-statement. 6095 6096 Here is the canonical example of the first variant: 6097 for (object in array) { do something with object } 6098 we call the first expression ("object") the "object_expression" and 6099 the second expression ("array") the "collection_expression". 6100 object_expression must be an lvalue of type "id" (a generic Objective-C 6101 object) because the loop works by assigning to object_expression the 6102 various objects from the collection_expression. collection_expression 6103 must evaluate to something of type "id" which responds to the method 6104 countByEnumeratingWithState:objects:count:. 6105 6106 The canonical example of the second variant is: 6107 for (id object in array) { do something with object } 6108 which is completely equivalent to 6109 { 6110 id object; 6111 for (object in array) { do something with object } 6112 } 6113 Note that initizializing 'object' in some way (eg, "for ((object = 6114 xxx) in array) { do something with object }") is possibly 6115 technically valid, but completely pointless as 'object' will be 6116 assigned to something else as soon as the loop starts. We should 6117 most likely reject it (TODO). 6118 6119 The beginning of the Objective-C foreach-statement looks exactly 6120 like the beginning of the for-statement, and we can tell it is a 6121 foreach-statement only because the initial declaration or 6122 expression is terminated by 'in' instead of ';'. 6123 6124 IF_P is used to track whether there's a (possibly labeled) if statement 6125 which is not enclosed in braces and has an else clause. This is used to 6126 implement -Wparentheses. */ 6127 6128 static void 6129 c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll, 6130 bool *if_p) 6131 { 6132 tree block, cond, incr, save_break, save_cont, body; 6133 /* The following are only used when parsing an ObjC foreach statement. */ 6134 tree object_expression; 6135 /* Silence the bogus uninitialized warning. */ 6136 tree collection_expression = NULL; 6137 location_t loc = c_parser_peek_token (parser)->location; 6138 location_t for_loc = loc; 6139 location_t cond_loc = UNKNOWN_LOCATION; 6140 location_t incr_loc = UNKNOWN_LOCATION; 6141 bool is_foreach_statement = false; 6142 gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR)); 6143 token_indent_info for_tinfo 6144 = get_token_indent_info (c_parser_peek_token (parser)); 6145 c_parser_consume_token (parser); 6146 /* Open a compound statement in Objective-C as well, just in case this is 6147 as foreach expression. */ 6148 block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ()); 6149 cond = error_mark_node; 6150 incr = error_mark_node; 6151 matching_parens parens; 6152 if (parens.require_open (parser)) 6153 { 6154 /* Parse the initialization declaration or expression. */ 6155 object_expression = error_mark_node; 6156 parser->objc_could_be_foreach_context = c_dialect_objc (); 6157 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 6158 { 6159 parser->objc_could_be_foreach_context = false; 6160 c_parser_consume_token (parser); 6161 c_finish_expr_stmt (loc, NULL_TREE); 6162 } 6163 else if (c_parser_next_tokens_start_declaration (parser)) 6164 { 6165 c_parser_declaration_or_fndef (parser, true, true, true, true, true, 6166 &object_expression, vNULL); 6167 parser->objc_could_be_foreach_context = false; 6168 6169 if (c_parser_next_token_is_keyword (parser, RID_IN)) 6170 { 6171 c_parser_consume_token (parser); 6172 is_foreach_statement = true; 6173 if (check_for_loop_decls (for_loc, true) == NULL_TREE) 6174 c_parser_error (parser, "multiple iterating variables in " 6175 "fast enumeration"); 6176 } 6177 else 6178 check_for_loop_decls (for_loc, flag_isoc99); 6179 } 6180 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION)) 6181 { 6182 /* __extension__ can start a declaration, but is also an 6183 unary operator that can start an expression. Consume all 6184 but the last of a possible series of __extension__ to 6185 determine which. */ 6186 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD 6187 && (c_parser_peek_2nd_token (parser)->keyword 6188 == RID_EXTENSION)) 6189 c_parser_consume_token (parser); 6190 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser))) 6191 { 6192 int ext; 6193 ext = disable_extension_diagnostics (); 6194 c_parser_consume_token (parser); 6195 c_parser_declaration_or_fndef (parser, true, true, true, true, 6196 true, &object_expression, vNULL); 6197 parser->objc_could_be_foreach_context = false; 6198 6199 restore_extension_diagnostics (ext); 6200 if (c_parser_next_token_is_keyword (parser, RID_IN)) 6201 { 6202 c_parser_consume_token (parser); 6203 is_foreach_statement = true; 6204 if (check_for_loop_decls (for_loc, true) == NULL_TREE) 6205 c_parser_error (parser, "multiple iterating variables in " 6206 "fast enumeration"); 6207 } 6208 else 6209 check_for_loop_decls (for_loc, flag_isoc99); 6210 } 6211 else 6212 goto init_expr; 6213 } 6214 else 6215 { 6216 init_expr: 6217 { 6218 struct c_expr ce; 6219 tree init_expression; 6220 ce = c_parser_expression (parser); 6221 init_expression = ce.value; 6222 parser->objc_could_be_foreach_context = false; 6223 if (c_parser_next_token_is_keyword (parser, RID_IN)) 6224 { 6225 c_parser_consume_token (parser); 6226 is_foreach_statement = true; 6227 if (! lvalue_p (init_expression)) 6228 c_parser_error (parser, "invalid iterating variable in " 6229 "fast enumeration"); 6230 object_expression 6231 = c_fully_fold (init_expression, false, NULL); 6232 } 6233 else 6234 { 6235 ce = convert_lvalue_to_rvalue (loc, ce, true, false); 6236 init_expression = ce.value; 6237 c_finish_expr_stmt (loc, init_expression); 6238 c_parser_skip_until_found (parser, CPP_SEMICOLON, 6239 "expected %<;%>"); 6240 } 6241 } 6242 } 6243 /* Parse the loop condition. In the case of a foreach 6244 statement, there is no loop condition. */ 6245 gcc_assert (!parser->objc_could_be_foreach_context); 6246 if (!is_foreach_statement) 6247 { 6248 cond_loc = c_parser_peek_token (parser)->location; 6249 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 6250 { 6251 if (ivdep) 6252 { 6253 c_parser_error (parser, "missing loop condition in loop " 6254 "with %<GCC ivdep%> pragma"); 6255 cond = error_mark_node; 6256 } 6257 else if (unroll) 6258 { 6259 c_parser_error (parser, "missing loop condition in loop " 6260 "with %<GCC unroll%> pragma"); 6261 cond = error_mark_node; 6262 } 6263 else 6264 { 6265 c_parser_consume_token (parser); 6266 cond = NULL_TREE; 6267 } 6268 } 6269 else 6270 { 6271 cond = c_parser_condition (parser); 6272 c_parser_skip_until_found (parser, CPP_SEMICOLON, 6273 "expected %<;%>"); 6274 } 6275 if (ivdep && cond != error_mark_node) 6276 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, 6277 build_int_cst (integer_type_node, 6278 annot_expr_ivdep_kind), 6279 integer_zero_node); 6280 if (unroll && cond != error_mark_node) 6281 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, 6282 build_int_cst (integer_type_node, 6283 annot_expr_unroll_kind), 6284 build_int_cst (integer_type_node, unroll)); 6285 } 6286 /* Parse the increment expression (the third expression in a 6287 for-statement). In the case of a foreach-statement, this is 6288 the expression that follows the 'in'. */ 6289 loc = incr_loc = c_parser_peek_token (parser)->location; 6290 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 6291 { 6292 if (is_foreach_statement) 6293 { 6294 c_parser_error (parser, 6295 "missing collection in fast enumeration"); 6296 collection_expression = error_mark_node; 6297 } 6298 else 6299 incr = c_process_expr_stmt (loc, NULL_TREE); 6300 } 6301 else 6302 { 6303 if (is_foreach_statement) 6304 collection_expression 6305 = c_fully_fold (c_parser_expression (parser).value, false, NULL); 6306 else 6307 { 6308 struct c_expr ce = c_parser_expression (parser); 6309 ce = convert_lvalue_to_rvalue (loc, ce, true, false); 6310 incr = c_process_expr_stmt (loc, ce.value); 6311 } 6312 } 6313 parens.skip_until_found_close (parser); 6314 } 6315 save_break = c_break_label; 6316 c_break_label = NULL_TREE; 6317 save_cont = c_cont_label; 6318 c_cont_label = NULL_TREE; 6319 6320 token_indent_info body_tinfo 6321 = get_token_indent_info (c_parser_peek_token (parser)); 6322 6323 location_t loc_after_labels; 6324 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE); 6325 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels); 6326 6327 if (is_foreach_statement) 6328 objc_finish_foreach_loop (for_loc, object_expression, 6329 collection_expression, body, c_break_label, 6330 c_cont_label); 6331 else 6332 c_finish_loop (for_loc, cond_loc, cond, incr_loc, incr, body, 6333 c_break_label, c_cont_label, true); 6334 add_stmt (c_end_compound_stmt (for_loc, block, 6335 flag_isoc99 || c_dialect_objc ())); 6336 c_parser_maybe_reclassify_token (parser); 6337 6338 token_indent_info next_tinfo 6339 = get_token_indent_info (c_parser_peek_token (parser)); 6340 warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo); 6341 6342 if (next_tinfo.type != CPP_SEMICOLON && !open_brace) 6343 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location, 6344 for_tinfo.location, RID_FOR); 6345 6346 c_break_label = save_break; 6347 c_cont_label = save_cont; 6348 } 6349 6350 /* Parse an asm statement, a GNU extension. This is a full-blown asm 6351 statement with inputs, outputs, clobbers, and volatile, inline, and goto 6352 tags allowed. 6353 6354 asm-qualifier: 6355 volatile 6356 inline 6357 goto 6358 6359 asm-qualifier-list: 6360 asm-qualifier-list asm-qualifier 6361 asm-qualifier 6362 6363 asm-statement: 6364 asm asm-qualifier-list[opt] ( asm-argument ) ; 6365 6366 asm-argument: 6367 asm-string-literal 6368 asm-string-literal : asm-operands[opt] 6369 asm-string-literal : asm-operands[opt] : asm-operands[opt] 6370 asm-string-literal : asm-operands[opt] : asm-operands[opt] \ 6371 : asm-clobbers[opt] 6372 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \ 6373 : asm-goto-operands 6374 6375 The form with asm-goto-operands is valid if and only if the 6376 asm-qualifier-list contains goto, and is the only allowed form in that case. 6377 Duplicate asm-qualifiers are not allowed. */ 6378 6379 static tree 6380 c_parser_asm_statement (c_parser *parser) 6381 { 6382 tree str, outputs, inputs, clobbers, labels, ret; 6383 bool simple; 6384 location_t asm_loc = c_parser_peek_token (parser)->location; 6385 int section, nsections; 6386 6387 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM)); 6388 c_parser_consume_token (parser); 6389 6390 /* Handle the asm-qualifier-list. */ 6391 location_t volatile_loc = UNKNOWN_LOCATION; 6392 location_t inline_loc = UNKNOWN_LOCATION; 6393 location_t goto_loc = UNKNOWN_LOCATION; 6394 for (;;) 6395 { 6396 c_token *token = c_parser_peek_token (parser); 6397 location_t loc = token->location; 6398 switch (token->keyword) 6399 { 6400 case RID_VOLATILE: 6401 if (volatile_loc) 6402 { 6403 error_at (loc, "duplicate asm qualifier %qE", token->value); 6404 inform (volatile_loc, "first seen here"); 6405 } 6406 else 6407 volatile_loc = loc; 6408 c_parser_consume_token (parser); 6409 continue; 6410 6411 case RID_INLINE: 6412 if (inline_loc) 6413 { 6414 error_at (loc, "duplicate asm qualifier %qE", token->value); 6415 inform (inline_loc, "first seen here"); 6416 } 6417 else 6418 inline_loc = loc; 6419 c_parser_consume_token (parser); 6420 continue; 6421 6422 case RID_GOTO: 6423 if (goto_loc) 6424 { 6425 error_at (loc, "duplicate asm qualifier %qE", token->value); 6426 inform (goto_loc, "first seen here"); 6427 } 6428 else 6429 goto_loc = loc; 6430 c_parser_consume_token (parser); 6431 continue; 6432 6433 case RID_CONST: 6434 case RID_RESTRICT: 6435 error_at (loc, "%qE is not an asm qualifier", token->value); 6436 c_parser_consume_token (parser); 6437 continue; 6438 6439 default: 6440 break; 6441 } 6442 break; 6443 } 6444 6445 bool is_volatile = (volatile_loc != UNKNOWN_LOCATION); 6446 bool is_inline = (inline_loc != UNKNOWN_LOCATION); 6447 bool is_goto = (goto_loc != UNKNOWN_LOCATION); 6448 6449 /* ??? Follow the C++ parser rather than using the 6450 lex_untranslated_string kludge. */ 6451 parser->lex_untranslated_string = true; 6452 ret = NULL; 6453 6454 matching_parens parens; 6455 if (!parens.require_open (parser)) 6456 goto error; 6457 6458 str = c_parser_asm_string_literal (parser); 6459 if (str == NULL_TREE) 6460 goto error_close_paren; 6461 6462 simple = true; 6463 outputs = NULL_TREE; 6464 inputs = NULL_TREE; 6465 clobbers = NULL_TREE; 6466 labels = NULL_TREE; 6467 6468 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto) 6469 goto done_asm; 6470 6471 /* Parse each colon-delimited section of operands. */ 6472 nsections = 3 + is_goto; 6473 for (section = 0; section < nsections; ++section) 6474 { 6475 if (!c_parser_require (parser, CPP_COLON, 6476 is_goto 6477 ? G_("expected %<:%>") 6478 : G_("expected %<:%> or %<)%>"), 6479 UNKNOWN_LOCATION, is_goto)) 6480 goto error_close_paren; 6481 6482 /* Once past any colon, we're no longer a simple asm. */ 6483 simple = false; 6484 6485 if ((!c_parser_next_token_is (parser, CPP_COLON) 6486 && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 6487 || section == 3) 6488 switch (section) 6489 { 6490 case 0: 6491 /* For asm goto, we don't allow output operands, but reserve 6492 the slot for a future extension that does allow them. */ 6493 if (!is_goto) 6494 outputs = c_parser_asm_operands (parser); 6495 break; 6496 case 1: 6497 inputs = c_parser_asm_operands (parser); 6498 break; 6499 case 2: 6500 clobbers = c_parser_asm_clobbers (parser); 6501 break; 6502 case 3: 6503 labels = c_parser_asm_goto_operands (parser); 6504 break; 6505 default: 6506 gcc_unreachable (); 6507 } 6508 6509 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto) 6510 goto done_asm; 6511 } 6512 6513 done_asm: 6514 if (!parens.require_close (parser)) 6515 { 6516 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 6517 goto error; 6518 } 6519 6520 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>")) 6521 c_parser_skip_to_end_of_block_or_statement (parser); 6522 6523 ret = build_asm_stmt (is_volatile, 6524 build_asm_expr (asm_loc, str, outputs, inputs, 6525 clobbers, labels, simple, is_inline)); 6526 6527 error: 6528 parser->lex_untranslated_string = false; 6529 return ret; 6530 6531 error_close_paren: 6532 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 6533 goto error; 6534 } 6535 6536 /* Parse asm operands, a GNU extension. 6537 6538 asm-operands: 6539 asm-operand 6540 asm-operands , asm-operand 6541 6542 asm-operand: 6543 asm-string-literal ( expression ) 6544 [ identifier ] asm-string-literal ( expression ) 6545 */ 6546 6547 static tree 6548 c_parser_asm_operands (c_parser *parser) 6549 { 6550 tree list = NULL_TREE; 6551 while (true) 6552 { 6553 tree name, str; 6554 struct c_expr expr; 6555 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)) 6556 { 6557 c_parser_consume_token (parser); 6558 if (c_parser_next_token_is (parser, CPP_NAME)) 6559 { 6560 tree id = c_parser_peek_token (parser)->value; 6561 c_parser_consume_token (parser); 6562 name = build_string (IDENTIFIER_LENGTH (id), 6563 IDENTIFIER_POINTER (id)); 6564 } 6565 else 6566 { 6567 c_parser_error (parser, "expected identifier"); 6568 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL); 6569 return NULL_TREE; 6570 } 6571 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, 6572 "expected %<]%>"); 6573 } 6574 else 6575 name = NULL_TREE; 6576 str = c_parser_asm_string_literal (parser); 6577 if (str == NULL_TREE) 6578 return NULL_TREE; 6579 parser->lex_untranslated_string = false; 6580 matching_parens parens; 6581 if (!parens.require_open (parser)) 6582 { 6583 parser->lex_untranslated_string = true; 6584 return NULL_TREE; 6585 } 6586 expr = c_parser_expression (parser); 6587 mark_exp_read (expr.value); 6588 parser->lex_untranslated_string = true; 6589 if (!parens.require_close (parser)) 6590 { 6591 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 6592 return NULL_TREE; 6593 } 6594 list = chainon (list, build_tree_list (build_tree_list (name, str), 6595 expr.value)); 6596 if (c_parser_next_token_is (parser, CPP_COMMA)) 6597 c_parser_consume_token (parser); 6598 else 6599 break; 6600 } 6601 return list; 6602 } 6603 6604 /* Parse asm clobbers, a GNU extension. 6605 6606 asm-clobbers: 6607 asm-string-literal 6608 asm-clobbers , asm-string-literal 6609 */ 6610 6611 static tree 6612 c_parser_asm_clobbers (c_parser *parser) 6613 { 6614 tree list = NULL_TREE; 6615 while (true) 6616 { 6617 tree str = c_parser_asm_string_literal (parser); 6618 if (str) 6619 list = tree_cons (NULL_TREE, str, list); 6620 else 6621 return NULL_TREE; 6622 if (c_parser_next_token_is (parser, CPP_COMMA)) 6623 c_parser_consume_token (parser); 6624 else 6625 break; 6626 } 6627 return list; 6628 } 6629 6630 /* Parse asm goto labels, a GNU extension. 6631 6632 asm-goto-operands: 6633 identifier 6634 asm-goto-operands , identifier 6635 */ 6636 6637 static tree 6638 c_parser_asm_goto_operands (c_parser *parser) 6639 { 6640 tree list = NULL_TREE; 6641 while (true) 6642 { 6643 tree name, label; 6644 6645 if (c_parser_next_token_is (parser, CPP_NAME)) 6646 { 6647 c_token *tok = c_parser_peek_token (parser); 6648 name = tok->value; 6649 label = lookup_label_for_goto (tok->location, name); 6650 c_parser_consume_token (parser); 6651 TREE_USED (label) = 1; 6652 } 6653 else 6654 { 6655 c_parser_error (parser, "expected identifier"); 6656 return NULL_TREE; 6657 } 6658 6659 name = build_string (IDENTIFIER_LENGTH (name), 6660 IDENTIFIER_POINTER (name)); 6661 list = tree_cons (name, label, list); 6662 if (c_parser_next_token_is (parser, CPP_COMMA)) 6663 c_parser_consume_token (parser); 6664 else 6665 return nreverse (list); 6666 } 6667 } 6668 6669 /* Parse an expression other than a compound expression; that is, an 6670 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If 6671 AFTER is not NULL then it is an Objective-C message expression which 6672 is the primary-expression starting the expression as an initializer. 6673 6674 assignment-expression: 6675 conditional-expression 6676 unary-expression assignment-operator assignment-expression 6677 6678 assignment-operator: one of 6679 = *= /= %= += -= <<= >>= &= ^= |= 6680 6681 In GNU C we accept any conditional expression on the LHS and 6682 diagnose the invalid lvalue rather than producing a syntax 6683 error. */ 6684 6685 static struct c_expr 6686 c_parser_expr_no_commas (c_parser *parser, struct c_expr *after, 6687 tree omp_atomic_lhs) 6688 { 6689 struct c_expr lhs, rhs, ret; 6690 enum tree_code code; 6691 location_t op_location, exp_location; 6692 gcc_assert (!after || c_dialect_objc ()); 6693 lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs); 6694 op_location = c_parser_peek_token (parser)->location; 6695 switch (c_parser_peek_token (parser)->type) 6696 { 6697 case CPP_EQ: 6698 code = NOP_EXPR; 6699 break; 6700 case CPP_MULT_EQ: 6701 code = MULT_EXPR; 6702 break; 6703 case CPP_DIV_EQ: 6704 code = TRUNC_DIV_EXPR; 6705 break; 6706 case CPP_MOD_EQ: 6707 code = TRUNC_MOD_EXPR; 6708 break; 6709 case CPP_PLUS_EQ: 6710 code = PLUS_EXPR; 6711 break; 6712 case CPP_MINUS_EQ: 6713 code = MINUS_EXPR; 6714 break; 6715 case CPP_LSHIFT_EQ: 6716 code = LSHIFT_EXPR; 6717 break; 6718 case CPP_RSHIFT_EQ: 6719 code = RSHIFT_EXPR; 6720 break; 6721 case CPP_AND_EQ: 6722 code = BIT_AND_EXPR; 6723 break; 6724 case CPP_XOR_EQ: 6725 code = BIT_XOR_EXPR; 6726 break; 6727 case CPP_OR_EQ: 6728 code = BIT_IOR_EXPR; 6729 break; 6730 default: 6731 return lhs; 6732 } 6733 c_parser_consume_token (parser); 6734 exp_location = c_parser_peek_token (parser)->location; 6735 rhs = c_parser_expr_no_commas (parser, NULL); 6736 rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true); 6737 6738 ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type, 6739 code, exp_location, rhs.value, 6740 rhs.original_type); 6741 set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ()); 6742 if (code == NOP_EXPR) 6743 ret.original_code = MODIFY_EXPR; 6744 else 6745 { 6746 TREE_NO_WARNING (ret.value) = 1; 6747 ret.original_code = ERROR_MARK; 6748 } 6749 ret.original_type = NULL; 6750 return ret; 6751 } 6752 6753 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If 6754 AFTER is not NULL then it is an Objective-C message expression which is 6755 the primary-expression starting the expression as an initializer. 6756 6757 conditional-expression: 6758 logical-OR-expression 6759 logical-OR-expression ? expression : conditional-expression 6760 6761 GNU extensions: 6762 6763 conditional-expression: 6764 logical-OR-expression ? : conditional-expression 6765 */ 6766 6767 static struct c_expr 6768 c_parser_conditional_expression (c_parser *parser, struct c_expr *after, 6769 tree omp_atomic_lhs) 6770 { 6771 struct c_expr cond, exp1, exp2, ret; 6772 location_t start, cond_loc, colon_loc; 6773 6774 gcc_assert (!after || c_dialect_objc ()); 6775 6776 cond = c_parser_binary_expression (parser, after, omp_atomic_lhs); 6777 6778 if (c_parser_next_token_is_not (parser, CPP_QUERY)) 6779 return cond; 6780 if (cond.value != error_mark_node) 6781 start = cond.get_start (); 6782 else 6783 start = UNKNOWN_LOCATION; 6784 cond_loc = c_parser_peek_token (parser)->location; 6785 cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true); 6786 c_parser_consume_token (parser); 6787 if (c_parser_next_token_is (parser, CPP_COLON)) 6788 { 6789 tree eptype = NULL_TREE; 6790 6791 location_t middle_loc = c_parser_peek_token (parser)->location; 6792 pedwarn (middle_loc, OPT_Wpedantic, 6793 "ISO C forbids omitting the middle term of a ?: expression"); 6794 if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR) 6795 { 6796 eptype = TREE_TYPE (cond.value); 6797 cond.value = TREE_OPERAND (cond.value, 0); 6798 } 6799 tree e = cond.value; 6800 while (TREE_CODE (e) == COMPOUND_EXPR) 6801 e = TREE_OPERAND (e, 1); 6802 warn_for_omitted_condop (middle_loc, e); 6803 /* Make sure first operand is calculated only once. */ 6804 exp1.value = save_expr (default_conversion (cond.value)); 6805 if (eptype) 6806 exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value); 6807 exp1.original_type = NULL; 6808 exp1.src_range = cond.src_range; 6809 cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value); 6810 c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node; 6811 } 6812 else 6813 { 6814 cond.value 6815 = c_objc_common_truthvalue_conversion 6816 (cond_loc, default_conversion (cond.value)); 6817 c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node; 6818 exp1 = c_parser_expression_conv (parser); 6819 mark_exp_read (exp1.value); 6820 c_inhibit_evaluation_warnings += 6821 ((cond.value == truthvalue_true_node) 6822 - (cond.value == truthvalue_false_node)); 6823 } 6824 6825 colon_loc = c_parser_peek_token (parser)->location; 6826 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 6827 { 6828 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node; 6829 ret.set_error (); 6830 ret.original_code = ERROR_MARK; 6831 ret.original_type = NULL; 6832 return ret; 6833 } 6834 { 6835 location_t exp2_loc = c_parser_peek_token (parser)->location; 6836 exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE); 6837 exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true); 6838 } 6839 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node; 6840 location_t loc1 = make_location (exp1.get_start (), exp1.src_range); 6841 location_t loc2 = make_location (exp2.get_start (), exp2.src_range); 6842 ret.value = build_conditional_expr (colon_loc, cond.value, 6843 cond.original_code == C_MAYBE_CONST_EXPR, 6844 exp1.value, exp1.original_type, loc1, 6845 exp2.value, exp2.original_type, loc2); 6846 ret.original_code = ERROR_MARK; 6847 if (exp1.value == error_mark_node || exp2.value == error_mark_node) 6848 ret.original_type = NULL; 6849 else 6850 { 6851 tree t1, t2; 6852 6853 /* If both sides are enum type, the default conversion will have 6854 made the type of the result be an integer type. We want to 6855 remember the enum types we started with. */ 6856 t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value); 6857 t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value); 6858 ret.original_type = ((t1 != error_mark_node 6859 && t2 != error_mark_node 6860 && (TYPE_MAIN_VARIANT (t1) 6861 == TYPE_MAIN_VARIANT (t2))) 6862 ? t1 6863 : NULL); 6864 } 6865 set_c_expr_source_range (&ret, start, exp2.get_finish ()); 6866 return ret; 6867 } 6868 6869 /* Parse a binary expression; that is, a logical-OR-expression (C90 6870 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not 6871 NULL then it is an Objective-C message expression which is the 6872 primary-expression starting the expression as an initializer. 6873 6874 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic, 6875 when it should be the unfolded lhs. In a valid OpenMP source, 6876 one of the operands of the toplevel binary expression must be equal 6877 to it. In that case, just return a build2 created binary operation 6878 rather than result of parser_build_binary_op. 6879 6880 multiplicative-expression: 6881 cast-expression 6882 multiplicative-expression * cast-expression 6883 multiplicative-expression / cast-expression 6884 multiplicative-expression % cast-expression 6885 6886 additive-expression: 6887 multiplicative-expression 6888 additive-expression + multiplicative-expression 6889 additive-expression - multiplicative-expression 6890 6891 shift-expression: 6892 additive-expression 6893 shift-expression << additive-expression 6894 shift-expression >> additive-expression 6895 6896 relational-expression: 6897 shift-expression 6898 relational-expression < shift-expression 6899 relational-expression > shift-expression 6900 relational-expression <= shift-expression 6901 relational-expression >= shift-expression 6902 6903 equality-expression: 6904 relational-expression 6905 equality-expression == relational-expression 6906 equality-expression != relational-expression 6907 6908 AND-expression: 6909 equality-expression 6910 AND-expression & equality-expression 6911 6912 exclusive-OR-expression: 6913 AND-expression 6914 exclusive-OR-expression ^ AND-expression 6915 6916 inclusive-OR-expression: 6917 exclusive-OR-expression 6918 inclusive-OR-expression | exclusive-OR-expression 6919 6920 logical-AND-expression: 6921 inclusive-OR-expression 6922 logical-AND-expression && inclusive-OR-expression 6923 6924 logical-OR-expression: 6925 logical-AND-expression 6926 logical-OR-expression || logical-AND-expression 6927 */ 6928 6929 static struct c_expr 6930 c_parser_binary_expression (c_parser *parser, struct c_expr *after, 6931 tree omp_atomic_lhs) 6932 { 6933 /* A binary expression is parsed using operator-precedence parsing, 6934 with the operands being cast expressions. All the binary 6935 operators are left-associative. Thus a binary expression is of 6936 form: 6937 6938 E0 op1 E1 op2 E2 ... 6939 6940 which we represent on a stack. On the stack, the precedence 6941 levels are strictly increasing. When a new operator is 6942 encountered of higher precedence than that at the top of the 6943 stack, it is pushed; its LHS is the top expression, and its RHS 6944 is everything parsed until it is popped. When a new operator is 6945 encountered with precedence less than or equal to that at the top 6946 of the stack, triples E[i-1] op[i] E[i] are popped and replaced 6947 by the result of the operation until the operator at the top of 6948 the stack has lower precedence than the new operator or there is 6949 only one element on the stack; then the top expression is the LHS 6950 of the new operator. In the case of logical AND and OR 6951 expressions, we also need to adjust c_inhibit_evaluation_warnings 6952 as appropriate when the operators are pushed and popped. */ 6953 6954 struct { 6955 /* The expression at this stack level. */ 6956 struct c_expr expr; 6957 /* The precedence of the operator on its left, PREC_NONE at the 6958 bottom of the stack. */ 6959 enum c_parser_prec prec; 6960 /* The operation on its left. */ 6961 enum tree_code op; 6962 /* The source location of this operation. */ 6963 location_t loc; 6964 /* The sizeof argument if expr.original_code == SIZEOF_EXPR. */ 6965 tree sizeof_arg; 6966 } stack[NUM_PRECS]; 6967 int sp; 6968 /* Location of the binary operator. */ 6969 location_t binary_loc = UNKNOWN_LOCATION; /* Quiet warning. */ 6970 #define POP \ 6971 do { \ 6972 switch (stack[sp].op) \ 6973 { \ 6974 case TRUTH_ANDIF_EXPR: \ 6975 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \ 6976 == truthvalue_false_node); \ 6977 break; \ 6978 case TRUTH_ORIF_EXPR: \ 6979 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \ 6980 == truthvalue_true_node); \ 6981 break; \ 6982 case TRUNC_DIV_EXPR: \ 6983 if (stack[sp - 1].expr.original_code == SIZEOF_EXPR \ 6984 && stack[sp].expr.original_code == SIZEOF_EXPR) \ 6985 { \ 6986 tree type0 = stack[sp - 1].sizeof_arg; \ 6987 tree type1 = stack[sp].sizeof_arg; \ 6988 tree first_arg = type0; \ 6989 if (!TYPE_P (type0)) \ 6990 type0 = TREE_TYPE (type0); \ 6991 if (!TYPE_P (type1)) \ 6992 type1 = TREE_TYPE (type1); \ 6993 if (POINTER_TYPE_P (type0) \ 6994 && comptypes (TREE_TYPE (type0), type1) \ 6995 && !(TREE_CODE (first_arg) == PARM_DECL \ 6996 && C_ARRAY_PARAMETER (first_arg) \ 6997 && warn_sizeof_array_argument)) \ 6998 { \ 6999 auto_diagnostic_group d; \ 7000 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \ 7001 "division %<sizeof (%T) / sizeof (%T)%> " \ 7002 "does not compute the number of array " \ 7003 "elements", \ 7004 type0, type1)) \ 7005 if (DECL_P (first_arg)) \ 7006 inform (DECL_SOURCE_LOCATION (first_arg), \ 7007 "first %<sizeof%> operand was declared here"); \ 7008 } \ 7009 } \ 7010 break; \ 7011 default: \ 7012 break; \ 7013 } \ 7014 stack[sp - 1].expr \ 7015 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \ 7016 stack[sp - 1].expr, true, true); \ 7017 stack[sp].expr \ 7018 = convert_lvalue_to_rvalue (stack[sp].loc, \ 7019 stack[sp].expr, true, true); \ 7020 if (__builtin_expect (omp_atomic_lhs != NULL_TREE, 0) && sp == 1 \ 7021 && c_parser_peek_token (parser)->type == CPP_SEMICOLON \ 7022 && ((1 << stack[sp].prec) \ 7023 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) | (1 << PREC_BITAND) \ 7024 | (1 << PREC_SHIFT) | (1 << PREC_ADD) | (1 << PREC_MULT))) \ 7025 && stack[sp].op != TRUNC_MOD_EXPR \ 7026 && stack[0].expr.value != error_mark_node \ 7027 && stack[1].expr.value != error_mark_node \ 7028 && (c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \ 7029 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs))) \ 7030 stack[0].expr.value \ 7031 = build2 (stack[1].op, TREE_TYPE (stack[0].expr.value), \ 7032 stack[0].expr.value, stack[1].expr.value); \ 7033 else \ 7034 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \ 7035 stack[sp].op, \ 7036 stack[sp - 1].expr, \ 7037 stack[sp].expr); \ 7038 sp--; \ 7039 } while (0) 7040 gcc_assert (!after || c_dialect_objc ()); 7041 stack[0].loc = c_parser_peek_token (parser)->location; 7042 stack[0].expr = c_parser_cast_expression (parser, after); 7043 stack[0].prec = PREC_NONE; 7044 stack[0].sizeof_arg = c_last_sizeof_arg; 7045 sp = 0; 7046 while (true) 7047 { 7048 enum c_parser_prec oprec; 7049 enum tree_code ocode; 7050 source_range src_range; 7051 if (parser->error) 7052 goto out; 7053 switch (c_parser_peek_token (parser)->type) 7054 { 7055 case CPP_MULT: 7056 oprec = PREC_MULT; 7057 ocode = MULT_EXPR; 7058 break; 7059 case CPP_DIV: 7060 oprec = PREC_MULT; 7061 ocode = TRUNC_DIV_EXPR; 7062 break; 7063 case CPP_MOD: 7064 oprec = PREC_MULT; 7065 ocode = TRUNC_MOD_EXPR; 7066 break; 7067 case CPP_PLUS: 7068 oprec = PREC_ADD; 7069 ocode = PLUS_EXPR; 7070 break; 7071 case CPP_MINUS: 7072 oprec = PREC_ADD; 7073 ocode = MINUS_EXPR; 7074 break; 7075 case CPP_LSHIFT: 7076 oprec = PREC_SHIFT; 7077 ocode = LSHIFT_EXPR; 7078 break; 7079 case CPP_RSHIFT: 7080 oprec = PREC_SHIFT; 7081 ocode = RSHIFT_EXPR; 7082 break; 7083 case CPP_LESS: 7084 oprec = PREC_REL; 7085 ocode = LT_EXPR; 7086 break; 7087 case CPP_GREATER: 7088 oprec = PREC_REL; 7089 ocode = GT_EXPR; 7090 break; 7091 case CPP_LESS_EQ: 7092 oprec = PREC_REL; 7093 ocode = LE_EXPR; 7094 break; 7095 case CPP_GREATER_EQ: 7096 oprec = PREC_REL; 7097 ocode = GE_EXPR; 7098 break; 7099 case CPP_EQ_EQ: 7100 oprec = PREC_EQ; 7101 ocode = EQ_EXPR; 7102 break; 7103 case CPP_NOT_EQ: 7104 oprec = PREC_EQ; 7105 ocode = NE_EXPR; 7106 break; 7107 case CPP_AND: 7108 oprec = PREC_BITAND; 7109 ocode = BIT_AND_EXPR; 7110 break; 7111 case CPP_XOR: 7112 oprec = PREC_BITXOR; 7113 ocode = BIT_XOR_EXPR; 7114 break; 7115 case CPP_OR: 7116 oprec = PREC_BITOR; 7117 ocode = BIT_IOR_EXPR; 7118 break; 7119 case CPP_AND_AND: 7120 oprec = PREC_LOGAND; 7121 ocode = TRUTH_ANDIF_EXPR; 7122 break; 7123 case CPP_OR_OR: 7124 oprec = PREC_LOGOR; 7125 ocode = TRUTH_ORIF_EXPR; 7126 break; 7127 default: 7128 /* Not a binary operator, so end of the binary 7129 expression. */ 7130 goto out; 7131 } 7132 binary_loc = c_parser_peek_token (parser)->location; 7133 while (oprec <= stack[sp].prec) 7134 POP; 7135 c_parser_consume_token (parser); 7136 switch (ocode) 7137 { 7138 case TRUTH_ANDIF_EXPR: 7139 src_range = stack[sp].expr.src_range; 7140 stack[sp].expr 7141 = convert_lvalue_to_rvalue (stack[sp].loc, 7142 stack[sp].expr, true, true); 7143 stack[sp].expr.value = c_objc_common_truthvalue_conversion 7144 (stack[sp].loc, default_conversion (stack[sp].expr.value)); 7145 c_inhibit_evaluation_warnings += (stack[sp].expr.value 7146 == truthvalue_false_node); 7147 set_c_expr_source_range (&stack[sp].expr, src_range); 7148 break; 7149 case TRUTH_ORIF_EXPR: 7150 src_range = stack[sp].expr.src_range; 7151 stack[sp].expr 7152 = convert_lvalue_to_rvalue (stack[sp].loc, 7153 stack[sp].expr, true, true); 7154 stack[sp].expr.value = c_objc_common_truthvalue_conversion 7155 (stack[sp].loc, default_conversion (stack[sp].expr.value)); 7156 c_inhibit_evaluation_warnings += (stack[sp].expr.value 7157 == truthvalue_true_node); 7158 set_c_expr_source_range (&stack[sp].expr, src_range); 7159 break; 7160 default: 7161 break; 7162 } 7163 sp++; 7164 stack[sp].loc = binary_loc; 7165 stack[sp].expr = c_parser_cast_expression (parser, NULL); 7166 stack[sp].prec = oprec; 7167 stack[sp].op = ocode; 7168 stack[sp].sizeof_arg = c_last_sizeof_arg; 7169 } 7170 out: 7171 while (sp > 0) 7172 POP; 7173 return stack[0].expr; 7174 #undef POP 7175 } 7176 7177 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER 7178 is not NULL then it is an Objective-C message expression which is the 7179 primary-expression starting the expression as an initializer. 7180 7181 cast-expression: 7182 unary-expression 7183 ( type-name ) unary-expression 7184 */ 7185 7186 static struct c_expr 7187 c_parser_cast_expression (c_parser *parser, struct c_expr *after) 7188 { 7189 location_t cast_loc = c_parser_peek_token (parser)->location; 7190 gcc_assert (!after || c_dialect_objc ()); 7191 if (after) 7192 return c_parser_postfix_expression_after_primary (parser, 7193 cast_loc, *after); 7194 /* If the expression begins with a parenthesized type name, it may 7195 be either a cast or a compound literal; we need to see whether 7196 the next character is '{' to tell the difference. If not, it is 7197 an unary expression. Full detection of unknown typenames here 7198 would require a 3-token lookahead. */ 7199 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN) 7200 && c_token_starts_typename (c_parser_peek_2nd_token (parser))) 7201 { 7202 struct c_type_name *type_name; 7203 struct c_expr ret; 7204 struct c_expr expr; 7205 matching_parens parens; 7206 parens.consume_open (parser); 7207 type_name = c_parser_type_name (parser, true); 7208 parens.skip_until_found_close (parser); 7209 if (type_name == NULL) 7210 { 7211 ret.set_error (); 7212 ret.original_code = ERROR_MARK; 7213 ret.original_type = NULL; 7214 return ret; 7215 } 7216 7217 /* Save casted types in the function's used types hash table. */ 7218 used_types_insert (type_name->specs->type); 7219 7220 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 7221 return c_parser_postfix_expression_after_paren_type (parser, type_name, 7222 cast_loc); 7223 if (type_name->specs->alignas_p) 7224 error_at (type_name->specs->locations[cdw_alignas], 7225 "alignment specified for type name in cast"); 7226 { 7227 location_t expr_loc = c_parser_peek_token (parser)->location; 7228 expr = c_parser_cast_expression (parser, NULL); 7229 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true); 7230 } 7231 ret.value = c_cast_expr (cast_loc, type_name, expr.value); 7232 if (ret.value && expr.value) 7233 set_c_expr_source_range (&ret, cast_loc, expr.get_finish ()); 7234 ret.original_code = ERROR_MARK; 7235 ret.original_type = NULL; 7236 return ret; 7237 } 7238 else 7239 return c_parser_unary_expression (parser); 7240 } 7241 7242 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3). 7243 7244 unary-expression: 7245 postfix-expression 7246 ++ unary-expression 7247 -- unary-expression 7248 unary-operator cast-expression 7249 sizeof unary-expression 7250 sizeof ( type-name ) 7251 7252 unary-operator: one of 7253 & * + - ~ ! 7254 7255 GNU extensions: 7256 7257 unary-expression: 7258 __alignof__ unary-expression 7259 __alignof__ ( type-name ) 7260 && identifier 7261 7262 (C11 permits _Alignof with type names only.) 7263 7264 unary-operator: one of 7265 __extension__ __real__ __imag__ 7266 7267 Transactional Memory: 7268 7269 unary-expression: 7270 transaction-expression 7271 7272 In addition, the GNU syntax treats ++ and -- as unary operators, so 7273 they may be applied to cast expressions with errors for non-lvalues 7274 given later. */ 7275 7276 static struct c_expr 7277 c_parser_unary_expression (c_parser *parser) 7278 { 7279 int ext; 7280 struct c_expr ret, op; 7281 location_t op_loc = c_parser_peek_token (parser)->location; 7282 location_t exp_loc; 7283 location_t finish; 7284 ret.original_code = ERROR_MARK; 7285 ret.original_type = NULL; 7286 switch (c_parser_peek_token (parser)->type) 7287 { 7288 case CPP_PLUS_PLUS: 7289 c_parser_consume_token (parser); 7290 exp_loc = c_parser_peek_token (parser)->location; 7291 op = c_parser_cast_expression (parser, NULL); 7292 7293 op = default_function_array_read_conversion (exp_loc, op); 7294 return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op); 7295 case CPP_MINUS_MINUS: 7296 c_parser_consume_token (parser); 7297 exp_loc = c_parser_peek_token (parser)->location; 7298 op = c_parser_cast_expression (parser, NULL); 7299 7300 op = default_function_array_read_conversion (exp_loc, op); 7301 return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op); 7302 case CPP_AND: 7303 c_parser_consume_token (parser); 7304 op = c_parser_cast_expression (parser, NULL); 7305 mark_exp_read (op.value); 7306 return parser_build_unary_op (op_loc, ADDR_EXPR, op); 7307 case CPP_MULT: 7308 { 7309 c_parser_consume_token (parser); 7310 exp_loc = c_parser_peek_token (parser)->location; 7311 op = c_parser_cast_expression (parser, NULL); 7312 finish = op.get_finish (); 7313 op = convert_lvalue_to_rvalue (exp_loc, op, true, true); 7314 location_t combined_loc = make_location (op_loc, op_loc, finish); 7315 ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR); 7316 ret.src_range.m_start = op_loc; 7317 ret.src_range.m_finish = finish; 7318 return ret; 7319 } 7320 case CPP_PLUS: 7321 if (!c_dialect_objc () && !in_system_header_at (input_location)) 7322 warning_at (op_loc, 7323 OPT_Wtraditional, 7324 "traditional C rejects the unary plus operator"); 7325 c_parser_consume_token (parser); 7326 exp_loc = c_parser_peek_token (parser)->location; 7327 op = c_parser_cast_expression (parser, NULL); 7328 op = convert_lvalue_to_rvalue (exp_loc, op, true, true); 7329 return parser_build_unary_op (op_loc, CONVERT_EXPR, op); 7330 case CPP_MINUS: 7331 c_parser_consume_token (parser); 7332 exp_loc = c_parser_peek_token (parser)->location; 7333 op = c_parser_cast_expression (parser, NULL); 7334 op = convert_lvalue_to_rvalue (exp_loc, op, true, true); 7335 return parser_build_unary_op (op_loc, NEGATE_EXPR, op); 7336 case CPP_COMPL: 7337 c_parser_consume_token (parser); 7338 exp_loc = c_parser_peek_token (parser)->location; 7339 op = c_parser_cast_expression (parser, NULL); 7340 op = convert_lvalue_to_rvalue (exp_loc, op, true, true); 7341 return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op); 7342 case CPP_NOT: 7343 c_parser_consume_token (parser); 7344 exp_loc = c_parser_peek_token (parser)->location; 7345 op = c_parser_cast_expression (parser, NULL); 7346 op = convert_lvalue_to_rvalue (exp_loc, op, true, true); 7347 return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op); 7348 case CPP_AND_AND: 7349 /* Refer to the address of a label as a pointer. */ 7350 c_parser_consume_token (parser); 7351 if (c_parser_next_token_is (parser, CPP_NAME)) 7352 { 7353 ret.value = finish_label_address_expr 7354 (c_parser_peek_token (parser)->value, op_loc); 7355 set_c_expr_source_range (&ret, op_loc, 7356 c_parser_peek_token (parser)->get_finish ()); 7357 c_parser_consume_token (parser); 7358 } 7359 else 7360 { 7361 c_parser_error (parser, "expected identifier"); 7362 ret.set_error (); 7363 } 7364 return ret; 7365 case CPP_KEYWORD: 7366 switch (c_parser_peek_token (parser)->keyword) 7367 { 7368 case RID_SIZEOF: 7369 return c_parser_sizeof_expression (parser); 7370 case RID_ALIGNOF: 7371 return c_parser_alignof_expression (parser); 7372 case RID_BUILTIN_HAS_ATTRIBUTE: 7373 return c_parser_has_attribute_expression (parser); 7374 case RID_EXTENSION: 7375 c_parser_consume_token (parser); 7376 ext = disable_extension_diagnostics (); 7377 ret = c_parser_cast_expression (parser, NULL); 7378 restore_extension_diagnostics (ext); 7379 return ret; 7380 case RID_REALPART: 7381 c_parser_consume_token (parser); 7382 exp_loc = c_parser_peek_token (parser)->location; 7383 op = c_parser_cast_expression (parser, NULL); 7384 op = default_function_array_conversion (exp_loc, op); 7385 return parser_build_unary_op (op_loc, REALPART_EXPR, op); 7386 case RID_IMAGPART: 7387 c_parser_consume_token (parser); 7388 exp_loc = c_parser_peek_token (parser)->location; 7389 op = c_parser_cast_expression (parser, NULL); 7390 op = default_function_array_conversion (exp_loc, op); 7391 return parser_build_unary_op (op_loc, IMAGPART_EXPR, op); 7392 case RID_TRANSACTION_ATOMIC: 7393 case RID_TRANSACTION_RELAXED: 7394 return c_parser_transaction_expression (parser, 7395 c_parser_peek_token (parser)->keyword); 7396 default: 7397 return c_parser_postfix_expression (parser); 7398 } 7399 default: 7400 return c_parser_postfix_expression (parser); 7401 } 7402 } 7403 7404 /* Parse a sizeof expression. */ 7405 7406 static struct c_expr 7407 c_parser_sizeof_expression (c_parser *parser) 7408 { 7409 struct c_expr expr; 7410 struct c_expr result; 7411 location_t expr_loc; 7412 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF)); 7413 7414 location_t start; 7415 location_t finish = UNKNOWN_LOCATION; 7416 7417 start = c_parser_peek_token (parser)->location; 7418 7419 c_parser_consume_token (parser); 7420 c_inhibit_evaluation_warnings++; 7421 in_sizeof++; 7422 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN) 7423 && c_token_starts_typename (c_parser_peek_2nd_token (parser))) 7424 { 7425 /* Either sizeof ( type-name ) or sizeof unary-expression 7426 starting with a compound literal. */ 7427 struct c_type_name *type_name; 7428 matching_parens parens; 7429 parens.consume_open (parser); 7430 expr_loc = c_parser_peek_token (parser)->location; 7431 type_name = c_parser_type_name (parser, true); 7432 parens.skip_until_found_close (parser); 7433 finish = parser->tokens_buf[0].location; 7434 if (type_name == NULL) 7435 { 7436 struct c_expr ret; 7437 c_inhibit_evaluation_warnings--; 7438 in_sizeof--; 7439 ret.set_error (); 7440 ret.original_code = ERROR_MARK; 7441 ret.original_type = NULL; 7442 return ret; 7443 } 7444 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 7445 { 7446 expr = c_parser_postfix_expression_after_paren_type (parser, 7447 type_name, 7448 expr_loc); 7449 finish = expr.get_finish (); 7450 goto sizeof_expr; 7451 } 7452 /* sizeof ( type-name ). */ 7453 if (type_name->specs->alignas_p) 7454 error_at (type_name->specs->locations[cdw_alignas], 7455 "alignment specified for type name in %<sizeof%>"); 7456 c_inhibit_evaluation_warnings--; 7457 in_sizeof--; 7458 result = c_expr_sizeof_type (expr_loc, type_name); 7459 } 7460 else 7461 { 7462 expr_loc = c_parser_peek_token (parser)->location; 7463 expr = c_parser_unary_expression (parser); 7464 finish = expr.get_finish (); 7465 sizeof_expr: 7466 c_inhibit_evaluation_warnings--; 7467 in_sizeof--; 7468 mark_exp_read (expr.value); 7469 if (TREE_CODE (expr.value) == COMPONENT_REF 7470 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1))) 7471 error_at (expr_loc, "%<sizeof%> applied to a bit-field"); 7472 result = c_expr_sizeof_expr (expr_loc, expr); 7473 } 7474 if (finish == UNKNOWN_LOCATION) 7475 finish = start; 7476 set_c_expr_source_range (&result, start, finish); 7477 return result; 7478 } 7479 7480 /* Parse an alignof expression. */ 7481 7482 static struct c_expr 7483 c_parser_alignof_expression (c_parser *parser) 7484 { 7485 struct c_expr expr; 7486 location_t start_loc = c_parser_peek_token (parser)->location; 7487 location_t end_loc; 7488 tree alignof_spelling = c_parser_peek_token (parser)->value; 7489 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF)); 7490 bool is_c11_alignof = strcmp (IDENTIFIER_POINTER (alignof_spelling), 7491 "_Alignof") == 0; 7492 /* A diagnostic is not required for the use of this identifier in 7493 the implementation namespace; only diagnose it for the C11 7494 spelling because of existing code using the other spellings. */ 7495 if (is_c11_alignof) 7496 { 7497 if (flag_isoc99) 7498 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE", 7499 alignof_spelling); 7500 else 7501 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE", 7502 alignof_spelling); 7503 } 7504 c_parser_consume_token (parser); 7505 c_inhibit_evaluation_warnings++; 7506 in_alignof++; 7507 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN) 7508 && c_token_starts_typename (c_parser_peek_2nd_token (parser))) 7509 { 7510 /* Either __alignof__ ( type-name ) or __alignof__ 7511 unary-expression starting with a compound literal. */ 7512 location_t loc; 7513 struct c_type_name *type_name; 7514 struct c_expr ret; 7515 matching_parens parens; 7516 parens.consume_open (parser); 7517 loc = c_parser_peek_token (parser)->location; 7518 type_name = c_parser_type_name (parser, true); 7519 end_loc = c_parser_peek_token (parser)->location; 7520 parens.skip_until_found_close (parser); 7521 if (type_name == NULL) 7522 { 7523 struct c_expr ret; 7524 c_inhibit_evaluation_warnings--; 7525 in_alignof--; 7526 ret.set_error (); 7527 ret.original_code = ERROR_MARK; 7528 ret.original_type = NULL; 7529 return ret; 7530 } 7531 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 7532 { 7533 expr = c_parser_postfix_expression_after_paren_type (parser, 7534 type_name, 7535 loc); 7536 goto alignof_expr; 7537 } 7538 /* alignof ( type-name ). */ 7539 if (type_name->specs->alignas_p) 7540 error_at (type_name->specs->locations[cdw_alignas], 7541 "alignment specified for type name in %qE", 7542 alignof_spelling); 7543 c_inhibit_evaluation_warnings--; 7544 in_alignof--; 7545 ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name, 7546 NULL, NULL), 7547 false, is_c11_alignof, 1); 7548 ret.original_code = ERROR_MARK; 7549 ret.original_type = NULL; 7550 set_c_expr_source_range (&ret, start_loc, end_loc); 7551 return ret; 7552 } 7553 else 7554 { 7555 struct c_expr ret; 7556 expr = c_parser_unary_expression (parser); 7557 end_loc = expr.src_range.m_finish; 7558 alignof_expr: 7559 mark_exp_read (expr.value); 7560 c_inhibit_evaluation_warnings--; 7561 in_alignof--; 7562 if (is_c11_alignof) 7563 pedwarn (start_loc, 7564 OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>", 7565 alignof_spelling); 7566 ret.value = c_alignof_expr (start_loc, expr.value); 7567 ret.original_code = ERROR_MARK; 7568 ret.original_type = NULL; 7569 set_c_expr_source_range (&ret, start_loc, end_loc); 7570 return ret; 7571 } 7572 } 7573 7574 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec) 7575 expression. */ 7576 7577 static struct c_expr 7578 c_parser_has_attribute_expression (c_parser *parser) 7579 { 7580 gcc_assert (c_parser_next_token_is_keyword (parser, 7581 RID_BUILTIN_HAS_ATTRIBUTE)); 7582 c_parser_consume_token (parser); 7583 7584 c_inhibit_evaluation_warnings++; 7585 7586 matching_parens parens; 7587 if (!parens.require_open (parser)) 7588 { 7589 c_inhibit_evaluation_warnings--; 7590 in_typeof--; 7591 7592 struct c_expr result; 7593 result.set_error (); 7594 result.original_code = ERROR_MARK; 7595 result.original_type = NULL; 7596 return result; 7597 } 7598 7599 /* Treat the type argument the same way as in typeof for the purposes 7600 of warnings. FIXME: Generalize this so the warning refers to 7601 __builtin_has_attribute rather than typeof. */ 7602 in_typeof++; 7603 7604 /* The first operand: one of DECL, EXPR, or TYPE. */ 7605 tree oper = NULL_TREE; 7606 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id)) 7607 { 7608 struct c_type_name *tname = c_parser_type_name (parser); 7609 in_typeof--; 7610 if (tname) 7611 { 7612 oper = groktypename (tname, NULL, NULL); 7613 pop_maybe_used (variably_modified_type_p (oper, NULL_TREE)); 7614 } 7615 } 7616 else 7617 { 7618 struct c_expr cexpr = c_parser_expr_no_commas (parser, NULL); 7619 c_inhibit_evaluation_warnings--; 7620 in_typeof--; 7621 if (cexpr.value != error_mark_node) 7622 { 7623 mark_exp_read (cexpr.value); 7624 oper = cexpr.value; 7625 tree etype = TREE_TYPE (oper); 7626 bool was_vm = variably_modified_type_p (etype, NULL_TREE); 7627 /* This is returned with the type so that when the type is 7628 evaluated, this can be evaluated. */ 7629 if (was_vm) 7630 oper = c_fully_fold (oper, false, NULL); 7631 pop_maybe_used (was_vm); 7632 } 7633 } 7634 7635 struct c_expr result; 7636 result.original_code = ERROR_MARK; 7637 result.original_type = NULL; 7638 7639 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) 7640 { 7641 /* Consume the closing parenthesis if that's the next token 7642 in the likely case the built-in was invoked with fewer 7643 than two arguments. */ 7644 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 7645 c_parser_consume_token (parser); 7646 c_inhibit_evaluation_warnings--; 7647 result.set_error (); 7648 return result; 7649 } 7650 7651 parser->lex_untranslated_string = true; 7652 7653 location_t atloc = c_parser_peek_token (parser)->location; 7654 /* Parse a single attribute. Require no leading comma and do not 7655 allow empty attributes. */ 7656 tree attr = c_parser_attribute (parser, NULL_TREE, false, false); 7657 7658 parser->lex_untranslated_string = false; 7659 7660 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 7661 c_parser_consume_token (parser); 7662 else 7663 { 7664 c_parser_error (parser, "expected identifier"); 7665 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 7666 7667 result.set_error (); 7668 return result; 7669 } 7670 7671 if (!attr) 7672 { 7673 error_at (atloc, "expected identifier"); 7674 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 7675 "expected %<)%>"); 7676 result.set_error (); 7677 return result; 7678 } 7679 7680 result.original_code = INTEGER_CST; 7681 result.original_type = boolean_type_node; 7682 7683 if (has_attribute (atloc, oper, attr, default_conversion)) 7684 result.value = boolean_true_node; 7685 else 7686 result.value = boolean_false_node; 7687 7688 return result; 7689 } 7690 7691 /* Helper function to read arguments of builtins which are interfaces 7692 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and 7693 others. The name of the builtin is passed using BNAME parameter. 7694 Function returns true if there were no errors while parsing and 7695 stores the arguments in CEXPR_LIST. If it returns true, 7696 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing 7697 parenthesis. */ 7698 static bool 7699 c_parser_get_builtin_args (c_parser *parser, const char *bname, 7700 vec<c_expr_t, va_gc> **ret_cexpr_list, 7701 bool choose_expr_p, 7702 location_t *out_close_paren_loc) 7703 { 7704 location_t loc = c_parser_peek_token (parser)->location; 7705 vec<c_expr_t, va_gc> *cexpr_list; 7706 c_expr_t expr; 7707 bool saved_force_folding_builtin_constant_p; 7708 7709 *ret_cexpr_list = NULL; 7710 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN)) 7711 { 7712 error_at (loc, "cannot take address of %qs", bname); 7713 return false; 7714 } 7715 7716 c_parser_consume_token (parser); 7717 7718 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 7719 { 7720 *out_close_paren_loc = c_parser_peek_token (parser)->location; 7721 c_parser_consume_token (parser); 7722 return true; 7723 } 7724 7725 saved_force_folding_builtin_constant_p 7726 = force_folding_builtin_constant_p; 7727 force_folding_builtin_constant_p |= choose_expr_p; 7728 expr = c_parser_expr_no_commas (parser, NULL); 7729 force_folding_builtin_constant_p 7730 = saved_force_folding_builtin_constant_p; 7731 vec_alloc (cexpr_list, 1); 7732 vec_safe_push (cexpr_list, expr); 7733 while (c_parser_next_token_is (parser, CPP_COMMA)) 7734 { 7735 c_parser_consume_token (parser); 7736 expr = c_parser_expr_no_commas (parser, NULL); 7737 vec_safe_push (cexpr_list, expr); 7738 } 7739 7740 *out_close_paren_loc = c_parser_peek_token (parser)->location; 7741 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) 7742 return false; 7743 7744 *ret_cexpr_list = cexpr_list; 7745 return true; 7746 } 7747 7748 /* This represents a single generic-association. */ 7749 7750 struct c_generic_association 7751 { 7752 /* The location of the starting token of the type. */ 7753 location_t type_location; 7754 /* The association's type, or NULL_TREE for 'default'. */ 7755 tree type; 7756 /* The association's expression. */ 7757 struct c_expr expression; 7758 }; 7759 7760 /* Parse a generic-selection. (C11 6.5.1.1). 7761 7762 generic-selection: 7763 _Generic ( assignment-expression , generic-assoc-list ) 7764 7765 generic-assoc-list: 7766 generic-association 7767 generic-assoc-list , generic-association 7768 7769 generic-association: 7770 type-name : assignment-expression 7771 default : assignment-expression 7772 */ 7773 7774 static struct c_expr 7775 c_parser_generic_selection (c_parser *parser) 7776 { 7777 struct c_expr selector, error_expr; 7778 tree selector_type; 7779 struct c_generic_association matched_assoc; 7780 bool match_found = false; 7781 location_t generic_loc, selector_loc; 7782 7783 error_expr.original_code = ERROR_MARK; 7784 error_expr.original_type = NULL; 7785 error_expr.set_error (); 7786 matched_assoc.type_location = UNKNOWN_LOCATION; 7787 matched_assoc.type = NULL_TREE; 7788 matched_assoc.expression = error_expr; 7789 7790 gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC)); 7791 generic_loc = c_parser_peek_token (parser)->location; 7792 c_parser_consume_token (parser); 7793 if (flag_isoc99) 7794 pedwarn_c99 (generic_loc, OPT_Wpedantic, 7795 "ISO C99 does not support %<_Generic%>"); 7796 else 7797 pedwarn_c99 (generic_loc, OPT_Wpedantic, 7798 "ISO C90 does not support %<_Generic%>"); 7799 7800 matching_parens parens; 7801 if (!parens.require_open (parser)) 7802 return error_expr; 7803 7804 c_inhibit_evaluation_warnings++; 7805 selector_loc = c_parser_peek_token (parser)->location; 7806 selector = c_parser_expr_no_commas (parser, NULL); 7807 selector = default_function_array_conversion (selector_loc, selector); 7808 c_inhibit_evaluation_warnings--; 7809 7810 if (selector.value == error_mark_node) 7811 { 7812 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 7813 return selector; 7814 } 7815 selector_type = TREE_TYPE (selector.value); 7816 /* In ISO C terms, rvalues (including the controlling expression of 7817 _Generic) do not have qualified types. */ 7818 if (TREE_CODE (selector_type) != ARRAY_TYPE) 7819 selector_type = TYPE_MAIN_VARIANT (selector_type); 7820 /* In ISO C terms, _Noreturn is not part of the type of expressions 7821 such as &abort, but in GCC it is represented internally as a type 7822 qualifier. */ 7823 if (FUNCTION_POINTER_TYPE_P (selector_type) 7824 && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED) 7825 selector_type 7826 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type))); 7827 7828 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) 7829 { 7830 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 7831 return error_expr; 7832 } 7833 7834 auto_vec<c_generic_association> associations; 7835 while (1) 7836 { 7837 struct c_generic_association assoc, *iter; 7838 unsigned int ix; 7839 c_token *token = c_parser_peek_token (parser); 7840 7841 assoc.type_location = token->location; 7842 if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT) 7843 { 7844 c_parser_consume_token (parser); 7845 assoc.type = NULL_TREE; 7846 } 7847 else 7848 { 7849 struct c_type_name *type_name; 7850 7851 type_name = c_parser_type_name (parser); 7852 if (type_name == NULL) 7853 { 7854 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 7855 return error_expr; 7856 } 7857 assoc.type = groktypename (type_name, NULL, NULL); 7858 if (assoc.type == error_mark_node) 7859 { 7860 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 7861 return error_expr; 7862 } 7863 7864 if (TREE_CODE (assoc.type) == FUNCTION_TYPE) 7865 error_at (assoc.type_location, 7866 "%<_Generic%> association has function type"); 7867 else if (!COMPLETE_TYPE_P (assoc.type)) 7868 error_at (assoc.type_location, 7869 "%<_Generic%> association has incomplete type"); 7870 7871 if (variably_modified_type_p (assoc.type, NULL_TREE)) 7872 error_at (assoc.type_location, 7873 "%<_Generic%> association has " 7874 "variable length type"); 7875 } 7876 7877 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 7878 { 7879 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 7880 return error_expr; 7881 } 7882 7883 assoc.expression = c_parser_expr_no_commas (parser, NULL); 7884 if (assoc.expression.value == error_mark_node) 7885 { 7886 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 7887 return error_expr; 7888 } 7889 7890 for (ix = 0; associations.iterate (ix, &iter); ++ix) 7891 { 7892 if (assoc.type == NULL_TREE) 7893 { 7894 if (iter->type == NULL_TREE) 7895 { 7896 error_at (assoc.type_location, 7897 "duplicate %<default%> case in %<_Generic%>"); 7898 inform (iter->type_location, "original %<default%> is here"); 7899 } 7900 } 7901 else if (iter->type != NULL_TREE) 7902 { 7903 if (comptypes (assoc.type, iter->type)) 7904 { 7905 error_at (assoc.type_location, 7906 "%<_Generic%> specifies two compatible types"); 7907 inform (iter->type_location, "compatible type is here"); 7908 } 7909 } 7910 } 7911 7912 if (assoc.type == NULL_TREE) 7913 { 7914 if (!match_found) 7915 { 7916 matched_assoc = assoc; 7917 match_found = true; 7918 } 7919 } 7920 else if (comptypes (assoc.type, selector_type)) 7921 { 7922 if (!match_found || matched_assoc.type == NULL_TREE) 7923 { 7924 matched_assoc = assoc; 7925 match_found = true; 7926 } 7927 else 7928 { 7929 error_at (assoc.type_location, 7930 "%<_Generic%> selector matches multiple associations"); 7931 inform (matched_assoc.type_location, 7932 "other match is here"); 7933 } 7934 } 7935 7936 associations.safe_push (assoc); 7937 7938 if (c_parser_peek_token (parser)->type != CPP_COMMA) 7939 break; 7940 c_parser_consume_token (parser); 7941 } 7942 7943 if (!parens.require_close (parser)) 7944 { 7945 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 7946 return error_expr; 7947 } 7948 7949 if (!match_found) 7950 { 7951 error_at (selector_loc, "%<_Generic%> selector of type %qT is not " 7952 "compatible with any association", 7953 selector_type); 7954 return error_expr; 7955 } 7956 7957 return matched_assoc.expression; 7958 } 7959 7960 /* Check the validity of a function pointer argument *EXPR (argument 7961 position POS) to __builtin_tgmath. Return the number of function 7962 arguments if possibly valid; return 0 having reported an error if 7963 not valid. */ 7964 7965 static unsigned int 7966 check_tgmath_function (c_expr *expr, unsigned int pos) 7967 { 7968 tree type = TREE_TYPE (expr->value); 7969 if (!FUNCTION_POINTER_TYPE_P (type)) 7970 { 7971 error_at (expr->get_location (), 7972 "argument %u of %<__builtin_tgmath%> is not a function pointer", 7973 pos); 7974 return 0; 7975 } 7976 type = TREE_TYPE (type); 7977 if (!prototype_p (type)) 7978 { 7979 error_at (expr->get_location (), 7980 "argument %u of %<__builtin_tgmath%> is unprototyped", pos); 7981 return 0; 7982 } 7983 if (stdarg_p (type)) 7984 { 7985 error_at (expr->get_location (), 7986 "argument %u of %<__builtin_tgmath%> has variable arguments", 7987 pos); 7988 return 0; 7989 } 7990 unsigned int nargs = 0; 7991 function_args_iterator iter; 7992 tree t; 7993 FOREACH_FUNCTION_ARGS (type, t, iter) 7994 { 7995 if (t == void_type_node) 7996 break; 7997 nargs++; 7998 } 7999 if (nargs == 0) 8000 { 8001 error_at (expr->get_location (), 8002 "argument %u of %<__builtin_tgmath%> has no arguments", pos); 8003 return 0; 8004 } 8005 return nargs; 8006 } 8007 8008 /* Ways in which a parameter or return value of a type-generic macro 8009 may vary between the different functions the macro may call. */ 8010 enum tgmath_parm_kind 8011 { 8012 tgmath_fixed, tgmath_real, tgmath_complex 8013 }; 8014 8015 /* Helper function for c_parser_postfix_expression. Parse predefined 8016 identifiers. */ 8017 8018 static struct c_expr 8019 c_parser_predefined_identifier (c_parser *parser) 8020 { 8021 location_t loc = c_parser_peek_token (parser)->location; 8022 switch (c_parser_peek_token (parser)->keyword) 8023 { 8024 case RID_FUNCTION_NAME: 8025 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined " 8026 "identifier", "__FUNCTION__"); 8027 break; 8028 case RID_PRETTY_FUNCTION_NAME: 8029 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined " 8030 "identifier", "__PRETTY_FUNCTION__"); 8031 break; 8032 case RID_C99_FUNCTION_NAME: 8033 pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support " 8034 "%<__func__%> predefined identifier"); 8035 break; 8036 default: 8037 gcc_unreachable (); 8038 } 8039 8040 struct c_expr expr; 8041 expr.original_code = ERROR_MARK; 8042 expr.original_type = NULL; 8043 expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword, 8044 c_parser_peek_token (parser)->value); 8045 set_c_expr_source_range (&expr, loc, loc); 8046 c_parser_consume_token (parser); 8047 return expr; 8048 } 8049 8050 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2, 8051 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to 8052 call c_parser_postfix_expression_after_paren_type on encountering them. 8053 8054 postfix-expression: 8055 primary-expression 8056 postfix-expression [ expression ] 8057 postfix-expression ( argument-expression-list[opt] ) 8058 postfix-expression . identifier 8059 postfix-expression -> identifier 8060 postfix-expression ++ 8061 postfix-expression -- 8062 ( type-name ) { initializer-list } 8063 ( type-name ) { initializer-list , } 8064 8065 argument-expression-list: 8066 argument-expression 8067 argument-expression-list , argument-expression 8068 8069 primary-expression: 8070 identifier 8071 constant 8072 string-literal 8073 ( expression ) 8074 generic-selection 8075 8076 GNU extensions: 8077 8078 primary-expression: 8079 __func__ 8080 (treated as a keyword in GNU C) 8081 __FUNCTION__ 8082 __PRETTY_FUNCTION__ 8083 ( compound-statement ) 8084 __builtin_va_arg ( assignment-expression , type-name ) 8085 __builtin_offsetof ( type-name , offsetof-member-designator ) 8086 __builtin_choose_expr ( assignment-expression , 8087 assignment-expression , 8088 assignment-expression ) 8089 __builtin_types_compatible_p ( type-name , type-name ) 8090 __builtin_tgmath ( expr-list ) 8091 __builtin_complex ( assignment-expression , assignment-expression ) 8092 __builtin_shuffle ( assignment-expression , assignment-expression ) 8093 __builtin_shuffle ( assignment-expression , 8094 assignment-expression , 8095 assignment-expression, ) 8096 __builtin_convertvector ( assignment-expression , type-name ) 8097 8098 offsetof-member-designator: 8099 identifier 8100 offsetof-member-designator . identifier 8101 offsetof-member-designator [ expression ] 8102 8103 Objective-C: 8104 8105 primary-expression: 8106 [ objc-receiver objc-message-args ] 8107 @selector ( objc-selector-arg ) 8108 @protocol ( identifier ) 8109 @encode ( type-name ) 8110 objc-string-literal 8111 Classname . identifier 8112 */ 8113 8114 static struct c_expr 8115 c_parser_postfix_expression (c_parser *parser) 8116 { 8117 struct c_expr expr, e1; 8118 struct c_type_name *t1, *t2; 8119 location_t loc = c_parser_peek_token (parser)->location; 8120 source_range tok_range = c_parser_peek_token (parser)->get_range (); 8121 expr.original_code = ERROR_MARK; 8122 expr.original_type = NULL; 8123 switch (c_parser_peek_token (parser)->type) 8124 { 8125 case CPP_NUMBER: 8126 expr.value = c_parser_peek_token (parser)->value; 8127 set_c_expr_source_range (&expr, tok_range); 8128 loc = c_parser_peek_token (parser)->location; 8129 c_parser_consume_token (parser); 8130 if (TREE_CODE (expr.value) == FIXED_CST 8131 && !targetm.fixed_point_supported_p ()) 8132 { 8133 error_at (loc, "fixed-point types not supported for this target"); 8134 expr.set_error (); 8135 } 8136 break; 8137 case CPP_CHAR: 8138 case CPP_CHAR16: 8139 case CPP_CHAR32: 8140 case CPP_WCHAR: 8141 expr.value = c_parser_peek_token (parser)->value; 8142 /* For the purpose of warning when a pointer is compared with 8143 a zero character constant. */ 8144 expr.original_type = char_type_node; 8145 set_c_expr_source_range (&expr, tok_range); 8146 c_parser_consume_token (parser); 8147 break; 8148 case CPP_STRING: 8149 case CPP_STRING16: 8150 case CPP_STRING32: 8151 case CPP_WSTRING: 8152 case CPP_UTF8STRING: 8153 expr.value = c_parser_peek_token (parser)->value; 8154 set_c_expr_source_range (&expr, tok_range); 8155 expr.original_code = STRING_CST; 8156 c_parser_consume_token (parser); 8157 break; 8158 case CPP_OBJC_STRING: 8159 gcc_assert (c_dialect_objc ()); 8160 expr.value 8161 = objc_build_string_object (c_parser_peek_token (parser)->value); 8162 set_c_expr_source_range (&expr, tok_range); 8163 c_parser_consume_token (parser); 8164 break; 8165 case CPP_NAME: 8166 switch (c_parser_peek_token (parser)->id_kind) 8167 { 8168 case C_ID_ID: 8169 { 8170 tree id = c_parser_peek_token (parser)->value; 8171 c_parser_consume_token (parser); 8172 expr.value = build_external_ref (loc, id, 8173 (c_parser_peek_token (parser)->type 8174 == CPP_OPEN_PAREN), 8175 &expr.original_type); 8176 set_c_expr_source_range (&expr, tok_range); 8177 break; 8178 } 8179 case C_ID_CLASSNAME: 8180 { 8181 /* Here we parse the Objective-C 2.0 Class.name dot 8182 syntax. */ 8183 tree class_name = c_parser_peek_token (parser)->value; 8184 tree component; 8185 c_parser_consume_token (parser); 8186 gcc_assert (c_dialect_objc ()); 8187 if (!c_parser_require (parser, CPP_DOT, "expected %<.%>")) 8188 { 8189 expr.set_error (); 8190 break; 8191 } 8192 if (c_parser_next_token_is_not (parser, CPP_NAME)) 8193 { 8194 c_parser_error (parser, "expected identifier"); 8195 expr.set_error (); 8196 break; 8197 } 8198 c_token *component_tok = c_parser_peek_token (parser); 8199 component = component_tok->value; 8200 location_t end_loc = component_tok->get_finish (); 8201 c_parser_consume_token (parser); 8202 expr.value = objc_build_class_component_ref (class_name, 8203 component); 8204 set_c_expr_source_range (&expr, loc, end_loc); 8205 break; 8206 } 8207 default: 8208 c_parser_error (parser, "expected expression"); 8209 expr.set_error (); 8210 break; 8211 } 8212 break; 8213 case CPP_OPEN_PAREN: 8214 /* A parenthesized expression, statement expression or compound 8215 literal. */ 8216 if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE) 8217 { 8218 /* A statement expression. */ 8219 tree stmt; 8220 location_t brace_loc; 8221 c_parser_consume_token (parser); 8222 brace_loc = c_parser_peek_token (parser)->location; 8223 c_parser_consume_token (parser); 8224 /* If we've not yet started the current function's statement list, 8225 or we're in the parameter scope of an old-style function 8226 declaration, statement expressions are not allowed. */ 8227 if (!building_stmt_list_p () || old_style_parameter_scope ()) 8228 { 8229 error_at (loc, "braced-group within expression allowed " 8230 "only inside a function"); 8231 parser->error = true; 8232 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL); 8233 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 8234 expr.set_error (); 8235 break; 8236 } 8237 stmt = c_begin_stmt_expr (); 8238 c_parser_compound_statement_nostart (parser); 8239 location_t close_loc = c_parser_peek_token (parser)->location; 8240 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 8241 "expected %<)%>"); 8242 pedwarn (loc, OPT_Wpedantic, 8243 "ISO C forbids braced-groups within expressions"); 8244 expr.value = c_finish_stmt_expr (brace_loc, stmt); 8245 set_c_expr_source_range (&expr, loc, close_loc); 8246 mark_exp_read (expr.value); 8247 } 8248 else 8249 { 8250 /* A parenthesized expression. */ 8251 location_t loc_open_paren = c_parser_peek_token (parser)->location; 8252 c_parser_consume_token (parser); 8253 expr = c_parser_expression (parser); 8254 if (TREE_CODE (expr.value) == MODIFY_EXPR) 8255 TREE_NO_WARNING (expr.value) = 1; 8256 if (expr.original_code != C_MAYBE_CONST_EXPR 8257 && expr.original_code != SIZEOF_EXPR) 8258 expr.original_code = ERROR_MARK; 8259 /* Don't change EXPR.ORIGINAL_TYPE. */ 8260 location_t loc_close_paren = c_parser_peek_token (parser)->location; 8261 set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren); 8262 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 8263 "expected %<)%>", loc_open_paren); 8264 } 8265 break; 8266 case CPP_KEYWORD: 8267 switch (c_parser_peek_token (parser)->keyword) 8268 { 8269 case RID_FUNCTION_NAME: 8270 case RID_PRETTY_FUNCTION_NAME: 8271 case RID_C99_FUNCTION_NAME: 8272 expr = c_parser_predefined_identifier (parser); 8273 break; 8274 case RID_VA_ARG: 8275 { 8276 location_t start_loc = loc; 8277 c_parser_consume_token (parser); 8278 matching_parens parens; 8279 if (!parens.require_open (parser)) 8280 { 8281 expr.set_error (); 8282 break; 8283 } 8284 e1 = c_parser_expr_no_commas (parser, NULL); 8285 mark_exp_read (e1.value); 8286 e1.value = c_fully_fold (e1.value, false, NULL); 8287 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) 8288 { 8289 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 8290 expr.set_error (); 8291 break; 8292 } 8293 loc = c_parser_peek_token (parser)->location; 8294 t1 = c_parser_type_name (parser); 8295 location_t end_loc = c_parser_peek_token (parser)->get_finish (); 8296 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 8297 "expected %<)%>"); 8298 if (t1 == NULL) 8299 { 8300 expr.set_error (); 8301 } 8302 else 8303 { 8304 tree type_expr = NULL_TREE; 8305 expr.value = c_build_va_arg (start_loc, e1.value, loc, 8306 groktypename (t1, &type_expr, NULL)); 8307 if (type_expr) 8308 { 8309 expr.value = build2 (C_MAYBE_CONST_EXPR, 8310 TREE_TYPE (expr.value), type_expr, 8311 expr.value); 8312 C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true; 8313 } 8314 set_c_expr_source_range (&expr, start_loc, end_loc); 8315 } 8316 } 8317 break; 8318 case RID_OFFSETOF: 8319 { 8320 c_parser_consume_token (parser); 8321 matching_parens parens; 8322 if (!parens.require_open (parser)) 8323 { 8324 expr.set_error (); 8325 break; 8326 } 8327 t1 = c_parser_type_name (parser); 8328 if (t1 == NULL) 8329 parser->error = true; 8330 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) 8331 gcc_assert (parser->error); 8332 if (parser->error) 8333 { 8334 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 8335 expr.set_error (); 8336 break; 8337 } 8338 tree type = groktypename (t1, NULL, NULL); 8339 tree offsetof_ref; 8340 if (type == error_mark_node) 8341 offsetof_ref = error_mark_node; 8342 else 8343 { 8344 offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node); 8345 SET_EXPR_LOCATION (offsetof_ref, loc); 8346 } 8347 /* Parse the second argument to __builtin_offsetof. We 8348 must have one identifier, and beyond that we want to 8349 accept sub structure and sub array references. */ 8350 if (c_parser_next_token_is (parser, CPP_NAME)) 8351 { 8352 c_token *comp_tok = c_parser_peek_token (parser); 8353 offsetof_ref = build_component_ref 8354 (loc, offsetof_ref, comp_tok->value, comp_tok->location); 8355 c_parser_consume_token (parser); 8356 while (c_parser_next_token_is (parser, CPP_DOT) 8357 || c_parser_next_token_is (parser, 8358 CPP_OPEN_SQUARE) 8359 || c_parser_next_token_is (parser, 8360 CPP_DEREF)) 8361 { 8362 if (c_parser_next_token_is (parser, CPP_DEREF)) 8363 { 8364 loc = c_parser_peek_token (parser)->location; 8365 offsetof_ref = build_array_ref (loc, 8366 offsetof_ref, 8367 integer_zero_node); 8368 goto do_dot; 8369 } 8370 else if (c_parser_next_token_is (parser, CPP_DOT)) 8371 { 8372 do_dot: 8373 c_parser_consume_token (parser); 8374 if (c_parser_next_token_is_not (parser, 8375 CPP_NAME)) 8376 { 8377 c_parser_error (parser, "expected identifier"); 8378 break; 8379 } 8380 c_token *comp_tok = c_parser_peek_token (parser); 8381 offsetof_ref = build_component_ref 8382 (loc, offsetof_ref, comp_tok->value, 8383 comp_tok->location); 8384 c_parser_consume_token (parser); 8385 } 8386 else 8387 { 8388 struct c_expr ce; 8389 tree idx; 8390 loc = c_parser_peek_token (parser)->location; 8391 c_parser_consume_token (parser); 8392 ce = c_parser_expression (parser); 8393 ce = convert_lvalue_to_rvalue (loc, ce, false, false); 8394 idx = ce.value; 8395 idx = c_fully_fold (idx, false, NULL); 8396 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, 8397 "expected %<]%>"); 8398 offsetof_ref = build_array_ref (loc, offsetof_ref, idx); 8399 } 8400 } 8401 } 8402 else 8403 c_parser_error (parser, "expected identifier"); 8404 location_t end_loc = c_parser_peek_token (parser)->get_finish (); 8405 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 8406 "expected %<)%>"); 8407 expr.value = fold_offsetof (offsetof_ref); 8408 set_c_expr_source_range (&expr, loc, end_loc); 8409 } 8410 break; 8411 case RID_CHOOSE_EXPR: 8412 { 8413 vec<c_expr_t, va_gc> *cexpr_list; 8414 c_expr_t *e1_p, *e2_p, *e3_p; 8415 tree c; 8416 location_t close_paren_loc; 8417 8418 c_parser_consume_token (parser); 8419 if (!c_parser_get_builtin_args (parser, 8420 "__builtin_choose_expr", 8421 &cexpr_list, true, 8422 &close_paren_loc)) 8423 { 8424 expr.set_error (); 8425 break; 8426 } 8427 8428 if (vec_safe_length (cexpr_list) != 3) 8429 { 8430 error_at (loc, "wrong number of arguments to " 8431 "%<__builtin_choose_expr%>"); 8432 expr.set_error (); 8433 break; 8434 } 8435 8436 e1_p = &(*cexpr_list)[0]; 8437 e2_p = &(*cexpr_list)[1]; 8438 e3_p = &(*cexpr_list)[2]; 8439 8440 c = e1_p->value; 8441 mark_exp_read (e2_p->value); 8442 mark_exp_read (e3_p->value); 8443 if (TREE_CODE (c) != INTEGER_CST 8444 || !INTEGRAL_TYPE_P (TREE_TYPE (c))) 8445 error_at (loc, 8446 "first argument to %<__builtin_choose_expr%> not" 8447 " a constant"); 8448 constant_expression_warning (c); 8449 expr = integer_zerop (c) ? *e3_p : *e2_p; 8450 set_c_expr_source_range (&expr, loc, close_paren_loc); 8451 break; 8452 } 8453 case RID_TYPES_COMPATIBLE_P: 8454 { 8455 c_parser_consume_token (parser); 8456 matching_parens parens; 8457 if (!parens.require_open (parser)) 8458 { 8459 expr.set_error (); 8460 break; 8461 } 8462 t1 = c_parser_type_name (parser); 8463 if (t1 == NULL) 8464 { 8465 expr.set_error (); 8466 break; 8467 } 8468 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) 8469 { 8470 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 8471 expr.set_error (); 8472 break; 8473 } 8474 t2 = c_parser_type_name (parser); 8475 if (t2 == NULL) 8476 { 8477 expr.set_error (); 8478 break; 8479 } 8480 location_t close_paren_loc = c_parser_peek_token (parser)->location; 8481 parens.skip_until_found_close (parser); 8482 tree e1, e2; 8483 e1 = groktypename (t1, NULL, NULL); 8484 e2 = groktypename (t2, NULL, NULL); 8485 if (e1 == error_mark_node || e2 == error_mark_node) 8486 { 8487 expr.set_error (); 8488 break; 8489 } 8490 8491 e1 = TYPE_MAIN_VARIANT (e1); 8492 e2 = TYPE_MAIN_VARIANT (e2); 8493 8494 expr.value 8495 = comptypes (e1, e2) ? integer_one_node : integer_zero_node; 8496 set_c_expr_source_range (&expr, loc, close_paren_loc); 8497 } 8498 break; 8499 case RID_BUILTIN_TGMATH: 8500 { 8501 vec<c_expr_t, va_gc> *cexpr_list; 8502 location_t close_paren_loc; 8503 8504 c_parser_consume_token (parser); 8505 if (!c_parser_get_builtin_args (parser, 8506 "__builtin_tgmath", 8507 &cexpr_list, false, 8508 &close_paren_loc)) 8509 { 8510 expr.set_error (); 8511 break; 8512 } 8513 8514 if (vec_safe_length (cexpr_list) < 3) 8515 { 8516 error_at (loc, "too few arguments to %<__builtin_tgmath%>"); 8517 expr.set_error (); 8518 break; 8519 } 8520 8521 unsigned int i; 8522 c_expr_t *p; 8523 FOR_EACH_VEC_ELT (*cexpr_list, i, p) 8524 *p = convert_lvalue_to_rvalue (loc, *p, true, true); 8525 unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1); 8526 if (nargs == 0) 8527 { 8528 expr.set_error (); 8529 break; 8530 } 8531 if (vec_safe_length (cexpr_list) < nargs) 8532 { 8533 error_at (loc, "too few arguments to %<__builtin_tgmath%>"); 8534 expr.set_error (); 8535 break; 8536 } 8537 unsigned int num_functions = vec_safe_length (cexpr_list) - nargs; 8538 if (num_functions < 2) 8539 { 8540 error_at (loc, "too few arguments to %<__builtin_tgmath%>"); 8541 expr.set_error (); 8542 break; 8543 } 8544 8545 /* The first NUM_FUNCTIONS expressions are the function 8546 pointers. The remaining NARGS expressions are the 8547 arguments that are to be passed to one of those 8548 functions, chosen following <tgmath.h> rules. */ 8549 for (unsigned int j = 1; j < num_functions; j++) 8550 { 8551 unsigned int this_nargs 8552 = check_tgmath_function (&(*cexpr_list)[j], j + 1); 8553 if (this_nargs == 0) 8554 { 8555 expr.set_error (); 8556 goto out; 8557 } 8558 if (this_nargs != nargs) 8559 { 8560 error_at ((*cexpr_list)[j].get_location (), 8561 "argument %u of %<__builtin_tgmath%> has " 8562 "wrong number of arguments", j + 1); 8563 expr.set_error (); 8564 goto out; 8565 } 8566 } 8567 8568 /* The functions all have the same number of arguments. 8569 Determine whether arguments and return types vary in 8570 ways permitted for <tgmath.h> functions. */ 8571 /* The first entry in each of these vectors is for the 8572 return type, subsequent entries for parameter 8573 types. */ 8574 auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1); 8575 auto_vec<tree> parm_first (nargs + 1); 8576 auto_vec<bool> parm_complex (nargs + 1); 8577 auto_vec<bool> parm_varies (nargs + 1); 8578 tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value)); 8579 tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type)); 8580 parm_first.quick_push (first_ret); 8581 parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE); 8582 parm_varies.quick_push (false); 8583 function_args_iterator iter; 8584 tree t; 8585 unsigned int argpos; 8586 FOREACH_FUNCTION_ARGS (first_type, t, iter) 8587 { 8588 if (t == void_type_node) 8589 break; 8590 parm_first.quick_push (TYPE_MAIN_VARIANT (t)); 8591 parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE); 8592 parm_varies.quick_push (false); 8593 } 8594 for (unsigned int j = 1; j < num_functions; j++) 8595 { 8596 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value)); 8597 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type)); 8598 if (ret != parm_first[0]) 8599 { 8600 parm_varies[0] = true; 8601 if (!SCALAR_FLOAT_TYPE_P (parm_first[0]) 8602 && !COMPLEX_FLOAT_TYPE_P (parm_first[0])) 8603 { 8604 error_at ((*cexpr_list)[0].get_location (), 8605 "invalid type-generic return type for " 8606 "argument %u of %<__builtin_tgmath%>", 8607 1); 8608 expr.set_error (); 8609 goto out; 8610 } 8611 if (!SCALAR_FLOAT_TYPE_P (ret) 8612 && !COMPLEX_FLOAT_TYPE_P (ret)) 8613 { 8614 error_at ((*cexpr_list)[j].get_location (), 8615 "invalid type-generic return type for " 8616 "argument %u of %<__builtin_tgmath%>", 8617 j + 1); 8618 expr.set_error (); 8619 goto out; 8620 } 8621 } 8622 if (TREE_CODE (ret) == COMPLEX_TYPE) 8623 parm_complex[0] = true; 8624 argpos = 1; 8625 FOREACH_FUNCTION_ARGS (type, t, iter) 8626 { 8627 if (t == void_type_node) 8628 break; 8629 t = TYPE_MAIN_VARIANT (t); 8630 if (t != parm_first[argpos]) 8631 { 8632 parm_varies[argpos] = true; 8633 if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos]) 8634 && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos])) 8635 { 8636 error_at ((*cexpr_list)[0].get_location (), 8637 "invalid type-generic type for " 8638 "argument %u of argument %u of " 8639 "%<__builtin_tgmath%>", argpos, 1); 8640 expr.set_error (); 8641 goto out; 8642 } 8643 if (!SCALAR_FLOAT_TYPE_P (t) 8644 && !COMPLEX_FLOAT_TYPE_P (t)) 8645 { 8646 error_at ((*cexpr_list)[j].get_location (), 8647 "invalid type-generic type for " 8648 "argument %u of argument %u of " 8649 "%<__builtin_tgmath%>", argpos, j + 1); 8650 expr.set_error (); 8651 goto out; 8652 } 8653 } 8654 if (TREE_CODE (t) == COMPLEX_TYPE) 8655 parm_complex[argpos] = true; 8656 argpos++; 8657 } 8658 } 8659 enum tgmath_parm_kind max_variation = tgmath_fixed; 8660 for (unsigned int j = 0; j <= nargs; j++) 8661 { 8662 enum tgmath_parm_kind this_kind; 8663 if (parm_varies[j]) 8664 { 8665 if (parm_complex[j]) 8666 max_variation = this_kind = tgmath_complex; 8667 else 8668 { 8669 this_kind = tgmath_real; 8670 if (max_variation != tgmath_complex) 8671 max_variation = tgmath_real; 8672 } 8673 } 8674 else 8675 this_kind = tgmath_fixed; 8676 parm_kind.quick_push (this_kind); 8677 } 8678 if (max_variation == tgmath_fixed) 8679 { 8680 error_at (loc, "function arguments of %<__builtin_tgmath%> " 8681 "all have the same type"); 8682 expr.set_error (); 8683 break; 8684 } 8685 8686 /* Identify a parameter (not the return type) that varies, 8687 including with complex types if any variation includes 8688 complex types; there must be at least one such 8689 parameter. */ 8690 unsigned int tgarg = 0; 8691 for (unsigned int j = 1; j <= nargs; j++) 8692 if (parm_kind[j] == max_variation) 8693 { 8694 tgarg = j; 8695 break; 8696 } 8697 if (tgarg == 0) 8698 { 8699 error_at (loc, "function arguments of %<__builtin_tgmath%> " 8700 "lack type-generic parameter"); 8701 expr.set_error (); 8702 break; 8703 } 8704 8705 /* Determine the type of the relevant parameter for each 8706 function. */ 8707 auto_vec<tree> tg_type (num_functions); 8708 for (unsigned int j = 0; j < num_functions; j++) 8709 { 8710 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value)); 8711 argpos = 1; 8712 FOREACH_FUNCTION_ARGS (type, t, iter) 8713 { 8714 if (argpos == tgarg) 8715 { 8716 tg_type.quick_push (TYPE_MAIN_VARIANT (t)); 8717 break; 8718 } 8719 argpos++; 8720 } 8721 } 8722 8723 /* Verify that the corresponding types are different for 8724 all the listed functions. Also determine whether all 8725 the types are complex, whether all the types are 8726 standard or binary, and whether all the types are 8727 decimal. */ 8728 bool all_complex = true; 8729 bool all_binary = true; 8730 bool all_decimal = true; 8731 hash_set<tree> tg_types; 8732 FOR_EACH_VEC_ELT (tg_type, i, t) 8733 { 8734 if (TREE_CODE (t) == COMPLEX_TYPE) 8735 all_decimal = false; 8736 else 8737 { 8738 all_complex = false; 8739 if (DECIMAL_FLOAT_TYPE_P (t)) 8740 all_binary = false; 8741 else 8742 all_decimal = false; 8743 } 8744 if (tg_types.add (t)) 8745 { 8746 error_at ((*cexpr_list)[i].get_location (), 8747 "duplicate type-generic parameter type for " 8748 "function argument %u of %<__builtin_tgmath%>", 8749 i + 1); 8750 expr.set_error (); 8751 goto out; 8752 } 8753 } 8754 8755 /* Verify that other parameters and the return type whose 8756 types vary have their types varying in the correct 8757 way. */ 8758 for (unsigned int j = 0; j < num_functions; j++) 8759 { 8760 tree exp_type = tg_type[j]; 8761 tree exp_real_type = exp_type; 8762 if (TREE_CODE (exp_type) == COMPLEX_TYPE) 8763 exp_real_type = TREE_TYPE (exp_type); 8764 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value)); 8765 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type)); 8766 if ((parm_kind[0] == tgmath_complex && ret != exp_type) 8767 || (parm_kind[0] == tgmath_real && ret != exp_real_type)) 8768 { 8769 error_at ((*cexpr_list)[j].get_location (), 8770 "bad return type for function argument %u " 8771 "of %<__builtin_tgmath%>", j + 1); 8772 expr.set_error (); 8773 goto out; 8774 } 8775 argpos = 1; 8776 FOREACH_FUNCTION_ARGS (type, t, iter) 8777 { 8778 if (t == void_type_node) 8779 break; 8780 t = TYPE_MAIN_VARIANT (t); 8781 if ((parm_kind[argpos] == tgmath_complex 8782 && t != exp_type) 8783 || (parm_kind[argpos] == tgmath_real 8784 && t != exp_real_type)) 8785 { 8786 error_at ((*cexpr_list)[j].get_location (), 8787 "bad type for argument %u of " 8788 "function argument %u of " 8789 "%<__builtin_tgmath%>", argpos, j + 1); 8790 expr.set_error (); 8791 goto out; 8792 } 8793 argpos++; 8794 } 8795 } 8796 8797 /* The functions listed are a valid set of functions for a 8798 <tgmath.h> macro to select between. Identify the 8799 matching function, if any. First, the argument types 8800 must be combined following <tgmath.h> rules. Integer 8801 types are treated as _Decimal64 if any type-generic 8802 argument is decimal, or if the only alternatives for 8803 type-generic arguments are of decimal types, and are 8804 otherwise treated as double (or _Complex double for 8805 complex integer types, or _Float64 or _Complex _Float64 8806 if all the return types are the same _FloatN or 8807 _FloatNx type). After that adjustment, types are 8808 combined following the usual arithmetic conversions. 8809 If the function only accepts complex arguments, a 8810 complex type is produced. */ 8811 bool arg_complex = all_complex; 8812 bool arg_binary = all_binary; 8813 bool arg_int_decimal = all_decimal; 8814 for (unsigned int j = 1; j <= nargs; j++) 8815 { 8816 if (parm_kind[j] == tgmath_fixed) 8817 continue; 8818 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1]; 8819 tree type = TREE_TYPE (ce->value); 8820 if (!INTEGRAL_TYPE_P (type) 8821 && !SCALAR_FLOAT_TYPE_P (type) 8822 && TREE_CODE (type) != COMPLEX_TYPE) 8823 { 8824 error_at (ce->get_location (), 8825 "invalid type of argument %u of type-generic " 8826 "function", j); 8827 expr.set_error (); 8828 goto out; 8829 } 8830 if (DECIMAL_FLOAT_TYPE_P (type)) 8831 { 8832 arg_int_decimal = true; 8833 if (all_complex) 8834 { 8835 error_at (ce->get_location (), 8836 "decimal floating-point argument %u to " 8837 "complex-only type-generic function", j); 8838 expr.set_error (); 8839 goto out; 8840 } 8841 else if (all_binary) 8842 { 8843 error_at (ce->get_location (), 8844 "decimal floating-point argument %u to " 8845 "binary-only type-generic function", j); 8846 expr.set_error (); 8847 goto out; 8848 } 8849 else if (arg_complex) 8850 { 8851 error_at (ce->get_location (), 8852 "both complex and decimal floating-point " 8853 "arguments to type-generic function"); 8854 expr.set_error (); 8855 goto out; 8856 } 8857 else if (arg_binary) 8858 { 8859 error_at (ce->get_location (), 8860 "both binary and decimal floating-point " 8861 "arguments to type-generic function"); 8862 expr.set_error (); 8863 goto out; 8864 } 8865 } 8866 else if (TREE_CODE (type) == COMPLEX_TYPE) 8867 { 8868 arg_complex = true; 8869 if (COMPLEX_FLOAT_TYPE_P (type)) 8870 arg_binary = true; 8871 if (all_decimal) 8872 { 8873 error_at (ce->get_location (), 8874 "complex argument %u to " 8875 "decimal-only type-generic function", j); 8876 expr.set_error (); 8877 goto out; 8878 } 8879 else if (arg_int_decimal) 8880 { 8881 error_at (ce->get_location (), 8882 "both complex and decimal floating-point " 8883 "arguments to type-generic function"); 8884 expr.set_error (); 8885 goto out; 8886 } 8887 } 8888 else if (SCALAR_FLOAT_TYPE_P (type)) 8889 { 8890 arg_binary = true; 8891 if (all_decimal) 8892 { 8893 error_at (ce->get_location (), 8894 "binary argument %u to " 8895 "decimal-only type-generic function", j); 8896 expr.set_error (); 8897 goto out; 8898 } 8899 else if (arg_int_decimal) 8900 { 8901 error_at (ce->get_location (), 8902 "both binary and decimal floating-point " 8903 "arguments to type-generic function"); 8904 expr.set_error (); 8905 goto out; 8906 } 8907 } 8908 } 8909 /* For a macro rounding its result to a narrower type, map 8910 integer types to _Float64 not double if the return type 8911 is a _FloatN or _FloatNx type. */ 8912 bool arg_int_float64 = false; 8913 if (parm_kind[0] == tgmath_fixed 8914 && SCALAR_FLOAT_TYPE_P (parm_first[0]) 8915 && float64_type_node != NULL_TREE) 8916 for (unsigned int j = 0; j < NUM_FLOATN_NX_TYPES; j++) 8917 if (parm_first[0] == FLOATN_TYPE_NODE (j)) 8918 { 8919 arg_int_float64 = true; 8920 break; 8921 } 8922 tree arg_real = NULL_TREE; 8923 for (unsigned int j = 1; j <= nargs; j++) 8924 { 8925 if (parm_kind[j] == tgmath_fixed) 8926 continue; 8927 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1]; 8928 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value)); 8929 if (TREE_CODE (type) == COMPLEX_TYPE) 8930 type = TREE_TYPE (type); 8931 if (INTEGRAL_TYPE_P (type)) 8932 type = (arg_int_decimal 8933 ? dfloat64_type_node 8934 : arg_int_float64 8935 ? float64_type_node 8936 : double_type_node); 8937 if (arg_real == NULL_TREE) 8938 arg_real = type; 8939 else 8940 arg_real = common_type (arg_real, type); 8941 if (arg_real == error_mark_node) 8942 { 8943 expr.set_error (); 8944 goto out; 8945 } 8946 } 8947 tree arg_type = (arg_complex 8948 ? build_complex_type (arg_real) 8949 : arg_real); 8950 8951 /* Look for a function to call with type-generic parameter 8952 type ARG_TYPE. */ 8953 c_expr_t *fn = NULL; 8954 for (unsigned int j = 0; j < num_functions; j++) 8955 { 8956 if (tg_type[j] == arg_type) 8957 { 8958 fn = &(*cexpr_list)[j]; 8959 break; 8960 } 8961 } 8962 if (fn == NULL 8963 && parm_kind[0] == tgmath_fixed 8964 && SCALAR_FLOAT_TYPE_P (parm_first[0])) 8965 { 8966 /* Presume this is a macro that rounds its result to a 8967 narrower type, and look for the first function with 8968 at least the range and precision of the argument 8969 type. */ 8970 for (unsigned int j = 0; j < num_functions; j++) 8971 { 8972 if (arg_complex 8973 != (TREE_CODE (tg_type[j]) == COMPLEX_TYPE)) 8974 continue; 8975 tree real_tg_type = (arg_complex 8976 ? TREE_TYPE (tg_type[j]) 8977 : tg_type[j]); 8978 if (DECIMAL_FLOAT_TYPE_P (arg_real) 8979 != DECIMAL_FLOAT_TYPE_P (real_tg_type)) 8980 continue; 8981 scalar_float_mode arg_mode 8982 = SCALAR_FLOAT_TYPE_MODE (arg_real); 8983 scalar_float_mode tg_mode 8984 = SCALAR_FLOAT_TYPE_MODE (real_tg_type); 8985 const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode); 8986 const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode); 8987 if (arg_fmt->b == tg_fmt->b 8988 && arg_fmt->p <= tg_fmt->p 8989 && arg_fmt->emax <= tg_fmt->emax 8990 && (arg_fmt->emin - arg_fmt->p 8991 >= tg_fmt->emin - tg_fmt->p)) 8992 { 8993 fn = &(*cexpr_list)[j]; 8994 break; 8995 } 8996 } 8997 } 8998 if (fn == NULL) 8999 { 9000 error_at (loc, "no matching function for type-generic call"); 9001 expr.set_error (); 9002 break; 9003 } 9004 9005 /* Construct a call to FN. */ 9006 vec<tree, va_gc> *args; 9007 vec_alloc (args, nargs); 9008 vec<tree, va_gc> *origtypes; 9009 vec_alloc (origtypes, nargs); 9010 auto_vec<location_t> arg_loc (nargs); 9011 for (unsigned int j = 0; j < nargs; j++) 9012 { 9013 c_expr_t *ce = &(*cexpr_list)[num_functions + j]; 9014 args->quick_push (ce->value); 9015 arg_loc.quick_push (ce->get_location ()); 9016 origtypes->quick_push (ce->original_type); 9017 } 9018 expr.value = c_build_function_call_vec (loc, arg_loc, fn->value, 9019 args, origtypes); 9020 set_c_expr_source_range (&expr, loc, close_paren_loc); 9021 break; 9022 } 9023 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN: 9024 { 9025 vec<c_expr_t, va_gc> *cexpr_list; 9026 c_expr_t *e2_p; 9027 tree chain_value; 9028 location_t close_paren_loc; 9029 9030 c_parser_consume_token (parser); 9031 if (!c_parser_get_builtin_args (parser, 9032 "__builtin_call_with_static_chain", 9033 &cexpr_list, false, 9034 &close_paren_loc)) 9035 { 9036 expr.set_error (); 9037 break; 9038 } 9039 if (vec_safe_length (cexpr_list) != 2) 9040 { 9041 error_at (loc, "wrong number of arguments to " 9042 "%<__builtin_call_with_static_chain%>"); 9043 expr.set_error (); 9044 break; 9045 } 9046 9047 expr = (*cexpr_list)[0]; 9048 e2_p = &(*cexpr_list)[1]; 9049 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true); 9050 chain_value = e2_p->value; 9051 mark_exp_read (chain_value); 9052 9053 if (TREE_CODE (expr.value) != CALL_EXPR) 9054 error_at (loc, "first argument to " 9055 "%<__builtin_call_with_static_chain%> " 9056 "must be a call expression"); 9057 else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE) 9058 error_at (loc, "second argument to " 9059 "%<__builtin_call_with_static_chain%> " 9060 "must be a pointer type"); 9061 else 9062 CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value; 9063 set_c_expr_source_range (&expr, loc, close_paren_loc); 9064 break; 9065 } 9066 case RID_BUILTIN_COMPLEX: 9067 { 9068 vec<c_expr_t, va_gc> *cexpr_list; 9069 c_expr_t *e1_p, *e2_p; 9070 location_t close_paren_loc; 9071 9072 c_parser_consume_token (parser); 9073 if (!c_parser_get_builtin_args (parser, 9074 "__builtin_complex", 9075 &cexpr_list, false, 9076 &close_paren_loc)) 9077 { 9078 expr.set_error (); 9079 break; 9080 } 9081 9082 if (vec_safe_length (cexpr_list) != 2) 9083 { 9084 error_at (loc, "wrong number of arguments to " 9085 "%<__builtin_complex%>"); 9086 expr.set_error (); 9087 break; 9088 } 9089 9090 e1_p = &(*cexpr_list)[0]; 9091 e2_p = &(*cexpr_list)[1]; 9092 9093 *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true); 9094 if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR) 9095 e1_p->value = convert (TREE_TYPE (e1_p->value), 9096 TREE_OPERAND (e1_p->value, 0)); 9097 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true); 9098 if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR) 9099 e2_p->value = convert (TREE_TYPE (e2_p->value), 9100 TREE_OPERAND (e2_p->value, 0)); 9101 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value)) 9102 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value)) 9103 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)) 9104 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))) 9105 { 9106 error_at (loc, "%<__builtin_complex%> operand " 9107 "not of real binary floating-point type"); 9108 expr.set_error (); 9109 break; 9110 } 9111 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value)) 9112 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value))) 9113 { 9114 error_at (loc, 9115 "%<__builtin_complex%> operands of different types"); 9116 expr.set_error (); 9117 break; 9118 } 9119 pedwarn_c90 (loc, OPT_Wpedantic, 9120 "ISO C90 does not support complex types"); 9121 expr.value = build2_loc (loc, COMPLEX_EXPR, 9122 build_complex_type 9123 (TYPE_MAIN_VARIANT 9124 (TREE_TYPE (e1_p->value))), 9125 e1_p->value, e2_p->value); 9126 set_c_expr_source_range (&expr, loc, close_paren_loc); 9127 break; 9128 } 9129 case RID_BUILTIN_SHUFFLE: 9130 { 9131 vec<c_expr_t, va_gc> *cexpr_list; 9132 unsigned int i; 9133 c_expr_t *p; 9134 location_t close_paren_loc; 9135 9136 c_parser_consume_token (parser); 9137 if (!c_parser_get_builtin_args (parser, 9138 "__builtin_shuffle", 9139 &cexpr_list, false, 9140 &close_paren_loc)) 9141 { 9142 expr.set_error (); 9143 break; 9144 } 9145 9146 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p) 9147 *p = convert_lvalue_to_rvalue (loc, *p, true, true); 9148 9149 if (vec_safe_length (cexpr_list) == 2) 9150 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value, 9151 NULL_TREE, 9152 (*cexpr_list)[1].value); 9153 9154 else if (vec_safe_length (cexpr_list) == 3) 9155 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value, 9156 (*cexpr_list)[1].value, 9157 (*cexpr_list)[2].value); 9158 else 9159 { 9160 error_at (loc, "wrong number of arguments to " 9161 "%<__builtin_shuffle%>"); 9162 expr.set_error (); 9163 } 9164 set_c_expr_source_range (&expr, loc, close_paren_loc); 9165 break; 9166 } 9167 case RID_BUILTIN_CONVERTVECTOR: 9168 { 9169 location_t start_loc = loc; 9170 c_parser_consume_token (parser); 9171 matching_parens parens; 9172 if (!parens.require_open (parser)) 9173 { 9174 expr.set_error (); 9175 break; 9176 } 9177 e1 = c_parser_expr_no_commas (parser, NULL); 9178 mark_exp_read (e1.value); 9179 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) 9180 { 9181 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 9182 expr.set_error (); 9183 break; 9184 } 9185 loc = c_parser_peek_token (parser)->location; 9186 t1 = c_parser_type_name (parser); 9187 location_t end_loc = c_parser_peek_token (parser)->get_finish (); 9188 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 9189 "expected %<)%>"); 9190 if (t1 == NULL) 9191 expr.set_error (); 9192 else 9193 { 9194 tree type_expr = NULL_TREE; 9195 expr.value = c_build_vec_convert (start_loc, e1.value, loc, 9196 groktypename (t1, &type_expr, 9197 NULL)); 9198 set_c_expr_source_range (&expr, start_loc, end_loc); 9199 } 9200 } 9201 break; 9202 case RID_AT_SELECTOR: 9203 { 9204 gcc_assert (c_dialect_objc ()); 9205 c_parser_consume_token (parser); 9206 matching_parens parens; 9207 if (!parens.require_open (parser)) 9208 { 9209 expr.set_error (); 9210 break; 9211 } 9212 tree sel = c_parser_objc_selector_arg (parser); 9213 location_t close_loc = c_parser_peek_token (parser)->location; 9214 parens.skip_until_found_close (parser); 9215 expr.value = objc_build_selector_expr (loc, sel); 9216 set_c_expr_source_range (&expr, loc, close_loc); 9217 } 9218 break; 9219 case RID_AT_PROTOCOL: 9220 { 9221 gcc_assert (c_dialect_objc ()); 9222 c_parser_consume_token (parser); 9223 matching_parens parens; 9224 if (!parens.require_open (parser)) 9225 { 9226 expr.set_error (); 9227 break; 9228 } 9229 if (c_parser_next_token_is_not (parser, CPP_NAME)) 9230 { 9231 c_parser_error (parser, "expected identifier"); 9232 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 9233 expr.set_error (); 9234 break; 9235 } 9236 tree id = c_parser_peek_token (parser)->value; 9237 c_parser_consume_token (parser); 9238 location_t close_loc = c_parser_peek_token (parser)->location; 9239 parens.skip_until_found_close (parser); 9240 expr.value = objc_build_protocol_expr (id); 9241 set_c_expr_source_range (&expr, loc, close_loc); 9242 } 9243 break; 9244 case RID_AT_ENCODE: 9245 { 9246 /* Extension to support C-structures in the archiver. */ 9247 gcc_assert (c_dialect_objc ()); 9248 c_parser_consume_token (parser); 9249 matching_parens parens; 9250 if (!parens.require_open (parser)) 9251 { 9252 expr.set_error (); 9253 break; 9254 } 9255 t1 = c_parser_type_name (parser); 9256 if (t1 == NULL) 9257 { 9258 expr.set_error (); 9259 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 9260 break; 9261 } 9262 location_t close_loc = c_parser_peek_token (parser)->location; 9263 parens.skip_until_found_close (parser); 9264 tree type = groktypename (t1, NULL, NULL); 9265 expr.value = objc_build_encode_expr (type); 9266 set_c_expr_source_range (&expr, loc, close_loc); 9267 } 9268 break; 9269 case RID_GENERIC: 9270 expr = c_parser_generic_selection (parser); 9271 break; 9272 default: 9273 c_parser_error (parser, "expected expression"); 9274 expr.set_error (); 9275 break; 9276 } 9277 break; 9278 case CPP_OPEN_SQUARE: 9279 if (c_dialect_objc ()) 9280 { 9281 tree receiver, args; 9282 c_parser_consume_token (parser); 9283 receiver = c_parser_objc_receiver (parser); 9284 args = c_parser_objc_message_args (parser); 9285 location_t close_loc = c_parser_peek_token (parser)->location; 9286 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, 9287 "expected %<]%>"); 9288 expr.value = objc_build_message_expr (receiver, args); 9289 set_c_expr_source_range (&expr, loc, close_loc); 9290 break; 9291 } 9292 /* Else fall through to report error. */ 9293 /* FALLTHRU */ 9294 default: 9295 c_parser_error (parser, "expected expression"); 9296 expr.set_error (); 9297 break; 9298 } 9299 out: 9300 return c_parser_postfix_expression_after_primary 9301 (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr); 9302 } 9303 9304 /* Parse a postfix expression after a parenthesized type name: the 9305 brace-enclosed initializer of a compound literal, possibly followed 9306 by some postfix operators. This is separate because it is not 9307 possible to tell until after the type name whether a cast 9308 expression has a cast or a compound literal, or whether the operand 9309 of sizeof is a parenthesized type name or starts with a compound 9310 literal. TYPE_LOC is the location where TYPE_NAME starts--the 9311 location of the first token after the parentheses around the type 9312 name. */ 9313 9314 static struct c_expr 9315 c_parser_postfix_expression_after_paren_type (c_parser *parser, 9316 struct c_type_name *type_name, 9317 location_t type_loc) 9318 { 9319 tree type; 9320 struct c_expr init; 9321 bool non_const; 9322 struct c_expr expr; 9323 location_t start_loc; 9324 tree type_expr = NULL_TREE; 9325 bool type_expr_const = true; 9326 check_compound_literal_type (type_loc, type_name); 9327 rich_location richloc (line_table, type_loc); 9328 start_init (NULL_TREE, NULL, 0, &richloc); 9329 type = groktypename (type_name, &type_expr, &type_expr_const); 9330 start_loc = c_parser_peek_token (parser)->location; 9331 if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type)) 9332 { 9333 error_at (type_loc, "compound literal has variable size"); 9334 type = error_mark_node; 9335 } 9336 init = c_parser_braced_init (parser, type, false, NULL); 9337 finish_init (); 9338 maybe_warn_string_init (type_loc, type, init); 9339 9340 if (type != error_mark_node 9341 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type)) 9342 && current_function_decl) 9343 { 9344 error ("compound literal qualified by address-space qualifier"); 9345 type = error_mark_node; 9346 } 9347 9348 pedwarn_c90 (start_loc, OPT_Wpedantic, "ISO C90 forbids compound literals"); 9349 non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR) 9350 ? CONSTRUCTOR_NON_CONST (init.value) 9351 : init.original_code == C_MAYBE_CONST_EXPR); 9352 non_const |= !type_expr_const; 9353 unsigned int alignas_align = 0; 9354 if (type != error_mark_node 9355 && type_name->specs->align_log != -1) 9356 { 9357 alignas_align = 1U << type_name->specs->align_log; 9358 if (alignas_align < min_align_of_type (type)) 9359 { 9360 error_at (type_name->specs->locations[cdw_alignas], 9361 "%<_Alignas%> specifiers cannot reduce " 9362 "alignment of compound literal"); 9363 alignas_align = 0; 9364 } 9365 } 9366 expr.value = build_compound_literal (start_loc, type, init.value, non_const, 9367 alignas_align); 9368 set_c_expr_source_range (&expr, init.src_range); 9369 expr.original_code = ERROR_MARK; 9370 expr.original_type = NULL; 9371 if (type != error_mark_node 9372 && expr.value != error_mark_node 9373 && type_expr) 9374 { 9375 if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR) 9376 { 9377 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE); 9378 C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr; 9379 } 9380 else 9381 { 9382 gcc_assert (!non_const); 9383 expr.value = build2 (C_MAYBE_CONST_EXPR, type, 9384 type_expr, expr.value); 9385 } 9386 } 9387 return c_parser_postfix_expression_after_primary (parser, start_loc, expr); 9388 } 9389 9390 /* Callback function for sizeof_pointer_memaccess_warning to compare 9391 types. */ 9392 9393 static bool 9394 sizeof_ptr_memacc_comptypes (tree type1, tree type2) 9395 { 9396 return comptypes (type1, type2) == 1; 9397 } 9398 9399 /* Warn for patterns where abs-like function appears to be used incorrectly, 9400 gracefully ignore any non-abs-like function. The warning location should 9401 be LOC. FNDECL is the declaration of called function, it must be a 9402 BUILT_IN_NORMAL function. ARG is the first and only argument of the 9403 call. */ 9404 9405 static void 9406 warn_for_abs (location_t loc, tree fndecl, tree arg) 9407 { 9408 /* Avoid warning in unreachable subexpressions. */ 9409 if (c_inhibit_evaluation_warnings) 9410 return; 9411 9412 tree atype = TREE_TYPE (arg); 9413 9414 /* Casts from pointers (and thus arrays and fndecls) will generate 9415 -Wint-conversion warnings. Most other wrong types hopefully lead to type 9416 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P 9417 types and possibly other exotic types. */ 9418 if (!INTEGRAL_TYPE_P (atype) 9419 && !SCALAR_FLOAT_TYPE_P (atype) 9420 && TREE_CODE (atype) != COMPLEX_TYPE) 9421 return; 9422 9423 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 9424 9425 switch (fcode) 9426 { 9427 case BUILT_IN_ABS: 9428 case BUILT_IN_LABS: 9429 case BUILT_IN_LLABS: 9430 case BUILT_IN_IMAXABS: 9431 if (!INTEGRAL_TYPE_P (atype)) 9432 { 9433 if (SCALAR_FLOAT_TYPE_P (atype)) 9434 warning_at (loc, OPT_Wabsolute_value, 9435 "using integer absolute value function %qD when " 9436 "argument is of floating point type %qT", 9437 fndecl, atype); 9438 else if (TREE_CODE (atype) == COMPLEX_TYPE) 9439 warning_at (loc, OPT_Wabsolute_value, 9440 "using integer absolute value function %qD when " 9441 "argument is of complex type %qT", fndecl, atype); 9442 else 9443 gcc_unreachable (); 9444 return; 9445 } 9446 if (TYPE_UNSIGNED (atype)) 9447 warning_at (loc, OPT_Wabsolute_value, 9448 "taking the absolute value of unsigned type %qT " 9449 "has no effect", atype); 9450 break; 9451 9452 CASE_FLT_FN (BUILT_IN_FABS): 9453 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS): 9454 if (!SCALAR_FLOAT_TYPE_P (atype) 9455 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype))) 9456 { 9457 if (INTEGRAL_TYPE_P (atype)) 9458 warning_at (loc, OPT_Wabsolute_value, 9459 "using floating point absolute value function %qD " 9460 "when argument is of integer type %qT", fndecl, atype); 9461 else if (DECIMAL_FLOAT_TYPE_P (atype)) 9462 warning_at (loc, OPT_Wabsolute_value, 9463 "using floating point absolute value function %qD " 9464 "when argument is of decimal floating point type %qT", 9465 fndecl, atype); 9466 else if (TREE_CODE (atype) == COMPLEX_TYPE) 9467 warning_at (loc, OPT_Wabsolute_value, 9468 "using floating point absolute value function %qD when " 9469 "argument is of complex type %qT", fndecl, atype); 9470 else 9471 gcc_unreachable (); 9472 return; 9473 } 9474 break; 9475 9476 CASE_FLT_FN (BUILT_IN_CABS): 9477 if (TREE_CODE (atype) != COMPLEX_TYPE) 9478 { 9479 if (INTEGRAL_TYPE_P (atype)) 9480 warning_at (loc, OPT_Wabsolute_value, 9481 "using complex absolute value function %qD when " 9482 "argument is of integer type %qT", fndecl, atype); 9483 else if (SCALAR_FLOAT_TYPE_P (atype)) 9484 warning_at (loc, OPT_Wabsolute_value, 9485 "using complex absolute value function %qD when " 9486 "argument is of floating point type %qT", 9487 fndecl, atype); 9488 else 9489 gcc_unreachable (); 9490 9491 return; 9492 } 9493 break; 9494 9495 case BUILT_IN_FABSD32: 9496 case BUILT_IN_FABSD64: 9497 case BUILT_IN_FABSD128: 9498 if (!DECIMAL_FLOAT_TYPE_P (atype)) 9499 { 9500 if (INTEGRAL_TYPE_P (atype)) 9501 warning_at (loc, OPT_Wabsolute_value, 9502 "using decimal floating point absolute value " 9503 "function %qD when argument is of integer type %qT", 9504 fndecl, atype); 9505 else if (SCALAR_FLOAT_TYPE_P (atype)) 9506 warning_at (loc, OPT_Wabsolute_value, 9507 "using decimal floating point absolute value " 9508 "function %qD when argument is of floating point " 9509 "type %qT", fndecl, atype); 9510 else if (TREE_CODE (atype) == COMPLEX_TYPE) 9511 warning_at (loc, OPT_Wabsolute_value, 9512 "using decimal floating point absolute value " 9513 "function %qD when argument is of complex type %qT", 9514 fndecl, atype); 9515 else 9516 gcc_unreachable (); 9517 return; 9518 } 9519 break; 9520 9521 default: 9522 return; 9523 } 9524 9525 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl))) 9526 return; 9527 9528 tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl))); 9529 if (TREE_CODE (atype) == COMPLEX_TYPE) 9530 { 9531 gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE); 9532 atype = TREE_TYPE (atype); 9533 ftype = TREE_TYPE (ftype); 9534 } 9535 9536 if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype)) 9537 warning_at (loc, OPT_Wabsolute_value, 9538 "absolute value function %qD given an argument of type %qT " 9539 "but has parameter of type %qT which may cause truncation " 9540 "of value", fndecl, atype, ftype); 9541 } 9542 9543 9544 /* Parse a postfix expression after the initial primary or compound 9545 literal; that is, parse a series of postfix operators. 9546 9547 EXPR_LOC is the location of the primary expression. */ 9548 9549 static struct c_expr 9550 c_parser_postfix_expression_after_primary (c_parser *parser, 9551 location_t expr_loc, 9552 struct c_expr expr) 9553 { 9554 struct c_expr orig_expr; 9555 tree ident, idx; 9556 location_t sizeof_arg_loc[3], comp_loc; 9557 tree sizeof_arg[3]; 9558 unsigned int literal_zero_mask; 9559 unsigned int i; 9560 vec<tree, va_gc> *exprlist; 9561 vec<tree, va_gc> *origtypes = NULL; 9562 vec<location_t> arg_loc = vNULL; 9563 location_t start; 9564 location_t finish; 9565 9566 while (true) 9567 { 9568 location_t op_loc = c_parser_peek_token (parser)->location; 9569 switch (c_parser_peek_token (parser)->type) 9570 { 9571 case CPP_OPEN_SQUARE: 9572 /* Array reference. */ 9573 c_parser_consume_token (parser); 9574 idx = c_parser_expression (parser).value; 9575 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, 9576 "expected %<]%>"); 9577 start = expr.get_start (); 9578 finish = parser->tokens_buf[0].location; 9579 expr.value = build_array_ref (op_loc, expr.value, idx); 9580 set_c_expr_source_range (&expr, start, finish); 9581 expr.original_code = ERROR_MARK; 9582 expr.original_type = NULL; 9583 break; 9584 case CPP_OPEN_PAREN: 9585 /* Function call. */ 9586 c_parser_consume_token (parser); 9587 for (i = 0; i < 3; i++) 9588 { 9589 sizeof_arg[i] = NULL_TREE; 9590 sizeof_arg_loc[i] = UNKNOWN_LOCATION; 9591 } 9592 literal_zero_mask = 0; 9593 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 9594 exprlist = NULL; 9595 else 9596 exprlist = c_parser_expr_list (parser, true, false, &origtypes, 9597 sizeof_arg_loc, sizeof_arg, 9598 &arg_loc, &literal_zero_mask); 9599 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 9600 "expected %<)%>"); 9601 orig_expr = expr; 9602 mark_exp_read (expr.value); 9603 if (warn_sizeof_pointer_memaccess) 9604 sizeof_pointer_memaccess_warning (sizeof_arg_loc, 9605 expr.value, exprlist, 9606 sizeof_arg, 9607 sizeof_ptr_memacc_comptypes); 9608 if (TREE_CODE (expr.value) == FUNCTION_DECL) 9609 { 9610 if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET) 9611 && vec_safe_length (exprlist) == 3) 9612 { 9613 tree arg0 = (*exprlist)[0]; 9614 tree arg2 = (*exprlist)[2]; 9615 warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask); 9616 } 9617 if (warn_absolute_value 9618 && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL) 9619 && vec_safe_length (exprlist) == 1) 9620 warn_for_abs (expr_loc, expr.value, (*exprlist)[0]); 9621 } 9622 9623 start = expr.get_start (); 9624 finish = parser->tokens_buf[0].get_finish (); 9625 expr.value 9626 = c_build_function_call_vec (expr_loc, arg_loc, expr.value, 9627 exprlist, origtypes); 9628 set_c_expr_source_range (&expr, start, finish); 9629 9630 expr.original_code = ERROR_MARK; 9631 if (TREE_CODE (expr.value) == INTEGER_CST 9632 && TREE_CODE (orig_expr.value) == FUNCTION_DECL 9633 && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P)) 9634 expr.original_code = C_MAYBE_CONST_EXPR; 9635 expr.original_type = NULL; 9636 if (exprlist) 9637 { 9638 release_tree_vector (exprlist); 9639 release_tree_vector (origtypes); 9640 } 9641 arg_loc.release (); 9642 break; 9643 case CPP_DOT: 9644 /* Structure element reference. */ 9645 c_parser_consume_token (parser); 9646 expr = default_function_array_conversion (expr_loc, expr); 9647 if (c_parser_next_token_is (parser, CPP_NAME)) 9648 { 9649 c_token *comp_tok = c_parser_peek_token (parser); 9650 ident = comp_tok->value; 9651 comp_loc = comp_tok->location; 9652 } 9653 else 9654 { 9655 c_parser_error (parser, "expected identifier"); 9656 expr.set_error (); 9657 expr.original_code = ERROR_MARK; 9658 expr.original_type = NULL; 9659 return expr; 9660 } 9661 start = expr.get_start (); 9662 finish = c_parser_peek_token (parser)->get_finish (); 9663 c_parser_consume_token (parser); 9664 expr.value = build_component_ref (op_loc, expr.value, ident, 9665 comp_loc); 9666 set_c_expr_source_range (&expr, start, finish); 9667 expr.original_code = ERROR_MARK; 9668 if (TREE_CODE (expr.value) != COMPONENT_REF) 9669 expr.original_type = NULL; 9670 else 9671 { 9672 /* Remember the original type of a bitfield. */ 9673 tree field = TREE_OPERAND (expr.value, 1); 9674 if (TREE_CODE (field) != FIELD_DECL) 9675 expr.original_type = NULL; 9676 else 9677 expr.original_type = DECL_BIT_FIELD_TYPE (field); 9678 } 9679 break; 9680 case CPP_DEREF: 9681 /* Structure element reference. */ 9682 c_parser_consume_token (parser); 9683 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false); 9684 if (c_parser_next_token_is (parser, CPP_NAME)) 9685 { 9686 c_token *comp_tok = c_parser_peek_token (parser); 9687 ident = comp_tok->value; 9688 comp_loc = comp_tok->location; 9689 } 9690 else 9691 { 9692 c_parser_error (parser, "expected identifier"); 9693 expr.set_error (); 9694 expr.original_code = ERROR_MARK; 9695 expr.original_type = NULL; 9696 return expr; 9697 } 9698 start = expr.get_start (); 9699 finish = c_parser_peek_token (parser)->get_finish (); 9700 c_parser_consume_token (parser); 9701 expr.value = build_component_ref (op_loc, 9702 build_indirect_ref (op_loc, 9703 expr.value, 9704 RO_ARROW), 9705 ident, comp_loc); 9706 set_c_expr_source_range (&expr, start, finish); 9707 expr.original_code = ERROR_MARK; 9708 if (TREE_CODE (expr.value) != COMPONENT_REF) 9709 expr.original_type = NULL; 9710 else 9711 { 9712 /* Remember the original type of a bitfield. */ 9713 tree field = TREE_OPERAND (expr.value, 1); 9714 if (TREE_CODE (field) != FIELD_DECL) 9715 expr.original_type = NULL; 9716 else 9717 expr.original_type = DECL_BIT_FIELD_TYPE (field); 9718 } 9719 break; 9720 case CPP_PLUS_PLUS: 9721 /* Postincrement. */ 9722 start = expr.get_start (); 9723 finish = c_parser_peek_token (parser)->get_finish (); 9724 c_parser_consume_token (parser); 9725 expr = default_function_array_read_conversion (expr_loc, expr); 9726 expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR, 9727 expr.value, false); 9728 set_c_expr_source_range (&expr, start, finish); 9729 expr.original_code = ERROR_MARK; 9730 expr.original_type = NULL; 9731 break; 9732 case CPP_MINUS_MINUS: 9733 /* Postdecrement. */ 9734 start = expr.get_start (); 9735 finish = c_parser_peek_token (parser)->get_finish (); 9736 c_parser_consume_token (parser); 9737 expr = default_function_array_read_conversion (expr_loc, expr); 9738 expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR, 9739 expr.value, false); 9740 set_c_expr_source_range (&expr, start, finish); 9741 expr.original_code = ERROR_MARK; 9742 expr.original_type = NULL; 9743 break; 9744 default: 9745 return expr; 9746 } 9747 } 9748 } 9749 9750 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17). 9751 9752 expression: 9753 assignment-expression 9754 expression , assignment-expression 9755 */ 9756 9757 static struct c_expr 9758 c_parser_expression (c_parser *parser) 9759 { 9760 location_t tloc = c_parser_peek_token (parser)->location; 9761 struct c_expr expr; 9762 expr = c_parser_expr_no_commas (parser, NULL); 9763 if (c_parser_next_token_is (parser, CPP_COMMA)) 9764 expr = convert_lvalue_to_rvalue (tloc, expr, true, false); 9765 while (c_parser_next_token_is (parser, CPP_COMMA)) 9766 { 9767 struct c_expr next; 9768 tree lhsval; 9769 location_t loc = c_parser_peek_token (parser)->location; 9770 location_t expr_loc; 9771 c_parser_consume_token (parser); 9772 expr_loc = c_parser_peek_token (parser)->location; 9773 lhsval = expr.value; 9774 while (TREE_CODE (lhsval) == COMPOUND_EXPR) 9775 lhsval = TREE_OPERAND (lhsval, 1); 9776 if (DECL_P (lhsval) || handled_component_p (lhsval)) 9777 mark_exp_read (lhsval); 9778 next = c_parser_expr_no_commas (parser, NULL); 9779 next = convert_lvalue_to_rvalue (expr_loc, next, true, false); 9780 expr.value = build_compound_expr (loc, expr.value, next.value); 9781 expr.original_code = COMPOUND_EXPR; 9782 expr.original_type = next.original_type; 9783 } 9784 return expr; 9785 } 9786 9787 /* Parse an expression and convert functions or arrays to pointers and 9788 lvalues to rvalues. */ 9789 9790 static struct c_expr 9791 c_parser_expression_conv (c_parser *parser) 9792 { 9793 struct c_expr expr; 9794 location_t loc = c_parser_peek_token (parser)->location; 9795 expr = c_parser_expression (parser); 9796 expr = convert_lvalue_to_rvalue (loc, expr, true, false); 9797 return expr; 9798 } 9799 9800 /* Helper function of c_parser_expr_list. Check if IDXth (0 based) 9801 argument is a literal zero alone and if so, set it in literal_zero_mask. */ 9802 9803 static inline void 9804 c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask, 9805 unsigned int idx) 9806 { 9807 if (idx >= HOST_BITS_PER_INT) 9808 return; 9809 9810 c_token *tok = c_parser_peek_token (parser); 9811 switch (tok->type) 9812 { 9813 case CPP_NUMBER: 9814 case CPP_CHAR: 9815 case CPP_WCHAR: 9816 case CPP_CHAR16: 9817 case CPP_CHAR32: 9818 /* If a parameter is literal zero alone, remember it 9819 for -Wmemset-transposed-args warning. */ 9820 if (integer_zerop (tok->value) 9821 && !TREE_OVERFLOW (tok->value) 9822 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA 9823 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN)) 9824 *literal_zero_mask |= 1U << idx; 9825 default: 9826 break; 9827 } 9828 } 9829 9830 /* Parse a non-empty list of expressions. If CONVERT_P, convert 9831 functions and arrays to pointers and lvalues to rvalues. If 9832 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the 9833 locations of function arguments into this vector. 9834 9835 nonempty-expr-list: 9836 assignment-expression 9837 nonempty-expr-list , assignment-expression 9838 */ 9839 9840 static vec<tree, va_gc> * 9841 c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p, 9842 vec<tree, va_gc> **p_orig_types, 9843 location_t *sizeof_arg_loc, tree *sizeof_arg, 9844 vec<location_t> *locations, 9845 unsigned int *literal_zero_mask) 9846 { 9847 vec<tree, va_gc> *ret; 9848 vec<tree, va_gc> *orig_types; 9849 struct c_expr expr; 9850 unsigned int idx = 0; 9851 9852 ret = make_tree_vector (); 9853 if (p_orig_types == NULL) 9854 orig_types = NULL; 9855 else 9856 orig_types = make_tree_vector (); 9857 9858 if (literal_zero_mask) 9859 c_parser_check_literal_zero (parser, literal_zero_mask, 0); 9860 expr = c_parser_expr_no_commas (parser, NULL); 9861 if (convert_p) 9862 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true); 9863 if (fold_p) 9864 expr.value = c_fully_fold (expr.value, false, NULL); 9865 ret->quick_push (expr.value); 9866 if (orig_types) 9867 orig_types->quick_push (expr.original_type); 9868 if (locations) 9869 locations->safe_push (expr.get_location ()); 9870 if (sizeof_arg != NULL 9871 && expr.original_code == SIZEOF_EXPR) 9872 { 9873 sizeof_arg[0] = c_last_sizeof_arg; 9874 sizeof_arg_loc[0] = c_last_sizeof_loc; 9875 } 9876 while (c_parser_next_token_is (parser, CPP_COMMA)) 9877 { 9878 c_parser_consume_token (parser); 9879 if (literal_zero_mask) 9880 c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1); 9881 expr = c_parser_expr_no_commas (parser, NULL); 9882 if (convert_p) 9883 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, 9884 true); 9885 if (fold_p) 9886 expr.value = c_fully_fold (expr.value, false, NULL); 9887 vec_safe_push (ret, expr.value); 9888 if (orig_types) 9889 vec_safe_push (orig_types, expr.original_type); 9890 if (locations) 9891 locations->safe_push (expr.get_location ()); 9892 if (++idx < 3 9893 && sizeof_arg != NULL 9894 && expr.original_code == SIZEOF_EXPR) 9895 { 9896 sizeof_arg[idx] = c_last_sizeof_arg; 9897 sizeof_arg_loc[idx] = c_last_sizeof_loc; 9898 } 9899 } 9900 if (orig_types) 9901 *p_orig_types = orig_types; 9902 return ret; 9903 } 9904 9905 /* Parse Objective-C-specific constructs. */ 9906 9907 /* Parse an objc-class-definition. 9908 9909 objc-class-definition: 9910 @interface identifier objc-superclass[opt] objc-protocol-refs[opt] 9911 objc-class-instance-variables[opt] objc-methodprotolist @end 9912 @implementation identifier objc-superclass[opt] 9913 objc-class-instance-variables[opt] 9914 @interface identifier ( identifier ) objc-protocol-refs[opt] 9915 objc-methodprotolist @end 9916 @interface identifier ( ) objc-protocol-refs[opt] 9917 objc-methodprotolist @end 9918 @implementation identifier ( identifier ) 9919 9920 objc-superclass: 9921 : identifier 9922 9923 "@interface identifier (" must start "@interface identifier ( 9924 identifier ) ...": objc-methodprotolist in the first production may 9925 not start with a parenthesized identifier as a declarator of a data 9926 definition with no declaration specifiers if the objc-superclass, 9927 objc-protocol-refs and objc-class-instance-variables are omitted. */ 9928 9929 static void 9930 c_parser_objc_class_definition (c_parser *parser, tree attributes) 9931 { 9932 bool iface_p; 9933 tree id1; 9934 tree superclass; 9935 if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE)) 9936 iface_p = true; 9937 else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION)) 9938 iface_p = false; 9939 else 9940 gcc_unreachable (); 9941 9942 c_parser_consume_token (parser); 9943 if (c_parser_next_token_is_not (parser, CPP_NAME)) 9944 { 9945 c_parser_error (parser, "expected identifier"); 9946 return; 9947 } 9948 id1 = c_parser_peek_token (parser)->value; 9949 c_parser_consume_token (parser); 9950 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 9951 { 9952 /* We have a category or class extension. */ 9953 tree id2; 9954 tree proto = NULL_TREE; 9955 matching_parens parens; 9956 parens.consume_open (parser); 9957 if (c_parser_next_token_is_not (parser, CPP_NAME)) 9958 { 9959 if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 9960 { 9961 /* We have a class extension. */ 9962 id2 = NULL_TREE; 9963 } 9964 else 9965 { 9966 c_parser_error (parser, "expected identifier or %<)%>"); 9967 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 9968 return; 9969 } 9970 } 9971 else 9972 { 9973 id2 = c_parser_peek_token (parser)->value; 9974 c_parser_consume_token (parser); 9975 } 9976 parens.skip_until_found_close (parser); 9977 if (!iface_p) 9978 { 9979 objc_start_category_implementation (id1, id2); 9980 return; 9981 } 9982 if (c_parser_next_token_is (parser, CPP_LESS)) 9983 proto = c_parser_objc_protocol_refs (parser); 9984 objc_start_category_interface (id1, id2, proto, attributes); 9985 c_parser_objc_methodprotolist (parser); 9986 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>"); 9987 objc_finish_interface (); 9988 return; 9989 } 9990 if (c_parser_next_token_is (parser, CPP_COLON)) 9991 { 9992 c_parser_consume_token (parser); 9993 if (c_parser_next_token_is_not (parser, CPP_NAME)) 9994 { 9995 c_parser_error (parser, "expected identifier"); 9996 return; 9997 } 9998 superclass = c_parser_peek_token (parser)->value; 9999 c_parser_consume_token (parser); 10000 } 10001 else 10002 superclass = NULL_TREE; 10003 if (iface_p) 10004 { 10005 tree proto = NULL_TREE; 10006 if (c_parser_next_token_is (parser, CPP_LESS)) 10007 proto = c_parser_objc_protocol_refs (parser); 10008 objc_start_class_interface (id1, superclass, proto, attributes); 10009 } 10010 else 10011 objc_start_class_implementation (id1, superclass); 10012 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 10013 c_parser_objc_class_instance_variables (parser); 10014 if (iface_p) 10015 { 10016 objc_continue_interface (); 10017 c_parser_objc_methodprotolist (parser); 10018 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>"); 10019 objc_finish_interface (); 10020 } 10021 else 10022 { 10023 objc_continue_implementation (); 10024 return; 10025 } 10026 } 10027 10028 /* Parse objc-class-instance-variables. 10029 10030 objc-class-instance-variables: 10031 { objc-instance-variable-decl-list[opt] } 10032 10033 objc-instance-variable-decl-list: 10034 objc-visibility-spec 10035 objc-instance-variable-decl ; 10036 ; 10037 objc-instance-variable-decl-list objc-visibility-spec 10038 objc-instance-variable-decl-list objc-instance-variable-decl ; 10039 objc-instance-variable-decl-list ; 10040 10041 objc-visibility-spec: 10042 @private 10043 @protected 10044 @public 10045 10046 objc-instance-variable-decl: 10047 struct-declaration 10048 */ 10049 10050 static void 10051 c_parser_objc_class_instance_variables (c_parser *parser) 10052 { 10053 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE)); 10054 c_parser_consume_token (parser); 10055 while (c_parser_next_token_is_not (parser, CPP_EOF)) 10056 { 10057 tree decls; 10058 /* Parse any stray semicolon. */ 10059 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 10060 { 10061 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic, 10062 "extra semicolon"); 10063 c_parser_consume_token (parser); 10064 continue; 10065 } 10066 /* Stop if at the end of the instance variables. */ 10067 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 10068 { 10069 c_parser_consume_token (parser); 10070 break; 10071 } 10072 /* Parse any objc-visibility-spec. */ 10073 if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE)) 10074 { 10075 c_parser_consume_token (parser); 10076 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE); 10077 continue; 10078 } 10079 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED)) 10080 { 10081 c_parser_consume_token (parser); 10082 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED); 10083 continue; 10084 } 10085 else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC)) 10086 { 10087 c_parser_consume_token (parser); 10088 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC); 10089 continue; 10090 } 10091 else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE)) 10092 { 10093 c_parser_consume_token (parser); 10094 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE); 10095 continue; 10096 } 10097 else if (c_parser_next_token_is (parser, CPP_PRAGMA)) 10098 { 10099 c_parser_pragma (parser, pragma_external, NULL); 10100 continue; 10101 } 10102 10103 /* Parse some comma-separated declarations. */ 10104 decls = c_parser_struct_declaration (parser); 10105 if (decls == NULL) 10106 { 10107 /* There is a syntax error. We want to skip the offending 10108 tokens up to the next ';' (included) or '}' 10109 (excluded). */ 10110 10111 /* First, skip manually a ')' or ']'. This is because they 10112 reduce the nesting level, so c_parser_skip_until_found() 10113 wouldn't be able to skip past them. */ 10114 c_token *token = c_parser_peek_token (parser); 10115 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE) 10116 c_parser_consume_token (parser); 10117 10118 /* Then, do the standard skipping. */ 10119 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); 10120 10121 /* We hopefully recovered. Start normal parsing again. */ 10122 parser->error = false; 10123 continue; 10124 } 10125 else 10126 { 10127 /* Comma-separated instance variables are chained together 10128 in reverse order; add them one by one. */ 10129 tree ivar = nreverse (decls); 10130 for (; ivar; ivar = DECL_CHAIN (ivar)) 10131 objc_add_instance_variable (copy_node (ivar)); 10132 } 10133 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 10134 } 10135 } 10136 10137 /* Parse an objc-class-declaration. 10138 10139 objc-class-declaration: 10140 @class identifier-list ; 10141 */ 10142 10143 static void 10144 c_parser_objc_class_declaration (c_parser *parser) 10145 { 10146 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS)); 10147 c_parser_consume_token (parser); 10148 /* Any identifiers, including those declared as type names, are OK 10149 here. */ 10150 while (true) 10151 { 10152 tree id; 10153 if (c_parser_next_token_is_not (parser, CPP_NAME)) 10154 { 10155 c_parser_error (parser, "expected identifier"); 10156 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); 10157 parser->error = false; 10158 return; 10159 } 10160 id = c_parser_peek_token (parser)->value; 10161 objc_declare_class (id); 10162 c_parser_consume_token (parser); 10163 if (c_parser_next_token_is (parser, CPP_COMMA)) 10164 c_parser_consume_token (parser); 10165 else 10166 break; 10167 } 10168 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 10169 } 10170 10171 /* Parse an objc-alias-declaration. 10172 10173 objc-alias-declaration: 10174 @compatibility_alias identifier identifier ; 10175 */ 10176 10177 static void 10178 c_parser_objc_alias_declaration (c_parser *parser) 10179 { 10180 tree id1, id2; 10181 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS)); 10182 c_parser_consume_token (parser); 10183 if (c_parser_next_token_is_not (parser, CPP_NAME)) 10184 { 10185 c_parser_error (parser, "expected identifier"); 10186 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); 10187 return; 10188 } 10189 id1 = c_parser_peek_token (parser)->value; 10190 c_parser_consume_token (parser); 10191 if (c_parser_next_token_is_not (parser, CPP_NAME)) 10192 { 10193 c_parser_error (parser, "expected identifier"); 10194 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); 10195 return; 10196 } 10197 id2 = c_parser_peek_token (parser)->value; 10198 c_parser_consume_token (parser); 10199 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 10200 objc_declare_alias (id1, id2); 10201 } 10202 10203 /* Parse an objc-protocol-definition. 10204 10205 objc-protocol-definition: 10206 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end 10207 @protocol identifier-list ; 10208 10209 "@protocol identifier ;" should be resolved as "@protocol 10210 identifier-list ;": objc-methodprotolist may not start with a 10211 semicolon in the first alternative if objc-protocol-refs are 10212 omitted. */ 10213 10214 static void 10215 c_parser_objc_protocol_definition (c_parser *parser, tree attributes) 10216 { 10217 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL)); 10218 10219 c_parser_consume_token (parser); 10220 if (c_parser_next_token_is_not (parser, CPP_NAME)) 10221 { 10222 c_parser_error (parser, "expected identifier"); 10223 return; 10224 } 10225 if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA 10226 || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON) 10227 { 10228 /* Any identifiers, including those declared as type names, are 10229 OK here. */ 10230 while (true) 10231 { 10232 tree id; 10233 if (c_parser_next_token_is_not (parser, CPP_NAME)) 10234 { 10235 c_parser_error (parser, "expected identifier"); 10236 break; 10237 } 10238 id = c_parser_peek_token (parser)->value; 10239 objc_declare_protocol (id, attributes); 10240 c_parser_consume_token (parser); 10241 if (c_parser_next_token_is (parser, CPP_COMMA)) 10242 c_parser_consume_token (parser); 10243 else 10244 break; 10245 } 10246 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 10247 } 10248 else 10249 { 10250 tree id = c_parser_peek_token (parser)->value; 10251 tree proto = NULL_TREE; 10252 c_parser_consume_token (parser); 10253 if (c_parser_next_token_is (parser, CPP_LESS)) 10254 proto = c_parser_objc_protocol_refs (parser); 10255 parser->objc_pq_context = true; 10256 objc_start_protocol (id, proto, attributes); 10257 c_parser_objc_methodprotolist (parser); 10258 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>"); 10259 parser->objc_pq_context = false; 10260 objc_finish_interface (); 10261 } 10262 } 10263 10264 /* Parse an objc-method-type. 10265 10266 objc-method-type: 10267 + 10268 - 10269 10270 Return true if it is a class method (+) and false if it is 10271 an instance method (-). 10272 */ 10273 static inline bool 10274 c_parser_objc_method_type (c_parser *parser) 10275 { 10276 switch (c_parser_peek_token (parser)->type) 10277 { 10278 case CPP_PLUS: 10279 c_parser_consume_token (parser); 10280 return true; 10281 case CPP_MINUS: 10282 c_parser_consume_token (parser); 10283 return false; 10284 default: 10285 gcc_unreachable (); 10286 } 10287 } 10288 10289 /* Parse an objc-method-definition. 10290 10291 objc-method-definition: 10292 objc-method-type objc-method-decl ;[opt] compound-statement 10293 */ 10294 10295 static void 10296 c_parser_objc_method_definition (c_parser *parser) 10297 { 10298 bool is_class_method = c_parser_objc_method_type (parser); 10299 tree decl, attributes = NULL_TREE, expr = NULL_TREE; 10300 parser->objc_pq_context = true; 10301 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes, 10302 &expr); 10303 if (decl == error_mark_node) 10304 return; /* Bail here. */ 10305 10306 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 10307 { 10308 c_parser_consume_token (parser); 10309 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic, 10310 "extra semicolon in method definition specified"); 10311 } 10312 10313 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 10314 { 10315 c_parser_error (parser, "expected %<{%>"); 10316 return; 10317 } 10318 10319 parser->objc_pq_context = false; 10320 if (objc_start_method_definition (is_class_method, decl, attributes, expr)) 10321 { 10322 add_stmt (c_parser_compound_statement (parser)); 10323 objc_finish_method_definition (current_function_decl); 10324 } 10325 else 10326 { 10327 /* This code is executed when we find a method definition 10328 outside of an @implementation context (or invalid for other 10329 reasons). Parse the method (to keep going) but do not emit 10330 any code. 10331 */ 10332 c_parser_compound_statement (parser); 10333 } 10334 } 10335 10336 /* Parse an objc-methodprotolist. 10337 10338 objc-methodprotolist: 10339 empty 10340 objc-methodprotolist objc-methodproto 10341 objc-methodprotolist declaration 10342 objc-methodprotolist ; 10343 @optional 10344 @required 10345 10346 The declaration is a data definition, which may be missing 10347 declaration specifiers under the same rules and diagnostics as 10348 other data definitions outside functions, and the stray semicolon 10349 is diagnosed the same way as a stray semicolon outside a 10350 function. */ 10351 10352 static void 10353 c_parser_objc_methodprotolist (c_parser *parser) 10354 { 10355 while (true) 10356 { 10357 /* The list is terminated by @end. */ 10358 switch (c_parser_peek_token (parser)->type) 10359 { 10360 case CPP_SEMICOLON: 10361 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic, 10362 "ISO C does not allow extra %<;%> outside of a function"); 10363 c_parser_consume_token (parser); 10364 break; 10365 case CPP_PLUS: 10366 case CPP_MINUS: 10367 c_parser_objc_methodproto (parser); 10368 break; 10369 case CPP_PRAGMA: 10370 c_parser_pragma (parser, pragma_external, NULL); 10371 break; 10372 case CPP_EOF: 10373 return; 10374 default: 10375 if (c_parser_next_token_is_keyword (parser, RID_AT_END)) 10376 return; 10377 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY)) 10378 c_parser_objc_at_property_declaration (parser); 10379 else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL)) 10380 { 10381 objc_set_method_opt (true); 10382 c_parser_consume_token (parser); 10383 } 10384 else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED)) 10385 { 10386 objc_set_method_opt (false); 10387 c_parser_consume_token (parser); 10388 } 10389 else 10390 c_parser_declaration_or_fndef (parser, false, false, true, 10391 false, true, NULL, vNULL); 10392 break; 10393 } 10394 } 10395 } 10396 10397 /* Parse an objc-methodproto. 10398 10399 objc-methodproto: 10400 objc-method-type objc-method-decl ; 10401 */ 10402 10403 static void 10404 c_parser_objc_methodproto (c_parser *parser) 10405 { 10406 bool is_class_method = c_parser_objc_method_type (parser); 10407 tree decl, attributes = NULL_TREE; 10408 10409 /* Remember protocol qualifiers in prototypes. */ 10410 parser->objc_pq_context = true; 10411 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes, 10412 NULL); 10413 /* Forget protocol qualifiers now. */ 10414 parser->objc_pq_context = false; 10415 10416 /* Do not allow the presence of attributes to hide an erroneous 10417 method implementation in the interface section. */ 10418 if (!c_parser_next_token_is (parser, CPP_SEMICOLON)) 10419 { 10420 c_parser_error (parser, "expected %<;%>"); 10421 return; 10422 } 10423 10424 if (decl != error_mark_node) 10425 objc_add_method_declaration (is_class_method, decl, attributes); 10426 10427 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 10428 } 10429 10430 /* If we are at a position that method attributes may be present, check that 10431 there are not any parsed already (a syntax error) and then collect any 10432 specified at the current location. Finally, if new attributes were present, 10433 check that the next token is legal ( ';' for decls and '{' for defs). */ 10434 10435 static bool 10436 c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes) 10437 { 10438 bool bad = false; 10439 if (*attributes) 10440 { 10441 c_parser_error (parser, 10442 "method attributes must be specified at the end only"); 10443 *attributes = NULL_TREE; 10444 bad = true; 10445 } 10446 10447 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 10448 *attributes = c_parser_attributes (parser); 10449 10450 /* If there were no attributes here, just report any earlier error. */ 10451 if (*attributes == NULL_TREE || bad) 10452 return bad; 10453 10454 /* If the attributes are followed by a ; or {, then just report any earlier 10455 error. */ 10456 if (c_parser_next_token_is (parser, CPP_SEMICOLON) 10457 || c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 10458 return bad; 10459 10460 /* We've got attributes, but not at the end. */ 10461 c_parser_error (parser, 10462 "expected %<;%> or %<{%> after method attribute definition"); 10463 return true; 10464 } 10465 10466 /* Parse an objc-method-decl. 10467 10468 objc-method-decl: 10469 ( objc-type-name ) objc-selector 10470 objc-selector 10471 ( objc-type-name ) objc-keyword-selector objc-optparmlist 10472 objc-keyword-selector objc-optparmlist 10473 attributes 10474 10475 objc-keyword-selector: 10476 objc-keyword-decl 10477 objc-keyword-selector objc-keyword-decl 10478 10479 objc-keyword-decl: 10480 objc-selector : ( objc-type-name ) identifier 10481 objc-selector : identifier 10482 : ( objc-type-name ) identifier 10483 : identifier 10484 10485 objc-optparmlist: 10486 objc-optparms objc-optellipsis 10487 10488 objc-optparms: 10489 empty 10490 objc-opt-parms , parameter-declaration 10491 10492 objc-optellipsis: 10493 empty 10494 , ... 10495 */ 10496 10497 static tree 10498 c_parser_objc_method_decl (c_parser *parser, bool is_class_method, 10499 tree *attributes, tree *expr) 10500 { 10501 tree type = NULL_TREE; 10502 tree sel; 10503 tree parms = NULL_TREE; 10504 bool ellipsis = false; 10505 bool attr_err = false; 10506 10507 *attributes = NULL_TREE; 10508 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 10509 { 10510 matching_parens parens; 10511 parens.consume_open (parser); 10512 type = c_parser_objc_type_name (parser); 10513 parens.skip_until_found_close (parser); 10514 } 10515 sel = c_parser_objc_selector (parser); 10516 /* If there is no selector, or a colon follows, we have an 10517 objc-keyword-selector. If there is a selector, and a colon does 10518 not follow, that selector ends the objc-method-decl. */ 10519 if (!sel || c_parser_next_token_is (parser, CPP_COLON)) 10520 { 10521 tree tsel = sel; 10522 tree list = NULL_TREE; 10523 while (true) 10524 { 10525 tree atype = NULL_TREE, id, keyworddecl; 10526 tree param_attr = NULL_TREE; 10527 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 10528 break; 10529 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 10530 { 10531 c_parser_consume_token (parser); 10532 atype = c_parser_objc_type_name (parser); 10533 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 10534 "expected %<)%>"); 10535 } 10536 /* New ObjC allows attributes on method parameters. */ 10537 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 10538 param_attr = c_parser_attributes (parser); 10539 if (c_parser_next_token_is_not (parser, CPP_NAME)) 10540 { 10541 c_parser_error (parser, "expected identifier"); 10542 return error_mark_node; 10543 } 10544 id = c_parser_peek_token (parser)->value; 10545 c_parser_consume_token (parser); 10546 keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr); 10547 list = chainon (list, keyworddecl); 10548 tsel = c_parser_objc_selector (parser); 10549 if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON)) 10550 break; 10551 } 10552 10553 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ; 10554 10555 /* Parse the optional parameter list. Optional Objective-C 10556 method parameters follow the C syntax, and may include '...' 10557 to denote a variable number of arguments. */ 10558 parms = make_node (TREE_LIST); 10559 while (c_parser_next_token_is (parser, CPP_COMMA)) 10560 { 10561 struct c_parm *parm; 10562 c_parser_consume_token (parser); 10563 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) 10564 { 10565 ellipsis = true; 10566 c_parser_consume_token (parser); 10567 attr_err |= c_parser_objc_maybe_method_attributes 10568 (parser, attributes) ; 10569 break; 10570 } 10571 parm = c_parser_parameter_declaration (parser, NULL_TREE); 10572 if (parm == NULL) 10573 break; 10574 parms = chainon (parms, 10575 build_tree_list (NULL_TREE, grokparm (parm, expr))); 10576 } 10577 sel = list; 10578 } 10579 else 10580 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ; 10581 10582 if (sel == NULL) 10583 { 10584 c_parser_error (parser, "objective-c method declaration is expected"); 10585 return error_mark_node; 10586 } 10587 10588 if (attr_err) 10589 return error_mark_node; 10590 10591 return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis); 10592 } 10593 10594 /* Parse an objc-type-name. 10595 10596 objc-type-name: 10597 objc-type-qualifiers[opt] type-name 10598 objc-type-qualifiers[opt] 10599 10600 objc-type-qualifiers: 10601 objc-type-qualifier 10602 objc-type-qualifiers objc-type-qualifier 10603 10604 objc-type-qualifier: one of 10605 in out inout bycopy byref oneway 10606 */ 10607 10608 static tree 10609 c_parser_objc_type_name (c_parser *parser) 10610 { 10611 tree quals = NULL_TREE; 10612 struct c_type_name *type_name = NULL; 10613 tree type = NULL_TREE; 10614 while (true) 10615 { 10616 c_token *token = c_parser_peek_token (parser); 10617 if (token->type == CPP_KEYWORD 10618 && (token->keyword == RID_IN 10619 || token->keyword == RID_OUT 10620 || token->keyword == RID_INOUT 10621 || token->keyword == RID_BYCOPY 10622 || token->keyword == RID_BYREF 10623 || token->keyword == RID_ONEWAY)) 10624 { 10625 quals = chainon (build_tree_list (NULL_TREE, token->value), quals); 10626 c_parser_consume_token (parser); 10627 } 10628 else 10629 break; 10630 } 10631 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type)) 10632 type_name = c_parser_type_name (parser); 10633 if (type_name) 10634 type = groktypename (type_name, NULL, NULL); 10635 10636 /* If the type is unknown, and error has already been produced and 10637 we need to recover from the error. In that case, use NULL_TREE 10638 for the type, as if no type had been specified; this will use the 10639 default type ('id') which is good for error recovery. */ 10640 if (type == error_mark_node) 10641 type = NULL_TREE; 10642 10643 return build_tree_list (quals, type); 10644 } 10645 10646 /* Parse objc-protocol-refs. 10647 10648 objc-protocol-refs: 10649 < identifier-list > 10650 */ 10651 10652 static tree 10653 c_parser_objc_protocol_refs (c_parser *parser) 10654 { 10655 tree list = NULL_TREE; 10656 gcc_assert (c_parser_next_token_is (parser, CPP_LESS)); 10657 c_parser_consume_token (parser); 10658 /* Any identifiers, including those declared as type names, are OK 10659 here. */ 10660 while (true) 10661 { 10662 tree id; 10663 if (c_parser_next_token_is_not (parser, CPP_NAME)) 10664 { 10665 c_parser_error (parser, "expected identifier"); 10666 break; 10667 } 10668 id = c_parser_peek_token (parser)->value; 10669 list = chainon (list, build_tree_list (NULL_TREE, id)); 10670 c_parser_consume_token (parser); 10671 if (c_parser_next_token_is (parser, CPP_COMMA)) 10672 c_parser_consume_token (parser); 10673 else 10674 break; 10675 } 10676 c_parser_require (parser, CPP_GREATER, "expected %<>%>"); 10677 return list; 10678 } 10679 10680 /* Parse an objc-try-catch-finally-statement. 10681 10682 objc-try-catch-finally-statement: 10683 @try compound-statement objc-catch-list[opt] 10684 @try compound-statement objc-catch-list[opt] @finally compound-statement 10685 10686 objc-catch-list: 10687 @catch ( objc-catch-parameter-declaration ) compound-statement 10688 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement 10689 10690 objc-catch-parameter-declaration: 10691 parameter-declaration 10692 '...' 10693 10694 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS. 10695 10696 PS: This function is identical to cp_parser_objc_try_catch_finally_statement 10697 for C++. Keep them in sync. */ 10698 10699 static void 10700 c_parser_objc_try_catch_finally_statement (c_parser *parser) 10701 { 10702 location_t location; 10703 tree stmt; 10704 10705 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY)); 10706 c_parser_consume_token (parser); 10707 location = c_parser_peek_token (parser)->location; 10708 objc_maybe_warn_exceptions (location); 10709 stmt = c_parser_compound_statement (parser); 10710 objc_begin_try_stmt (location, stmt); 10711 10712 while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH)) 10713 { 10714 struct c_parm *parm; 10715 tree parameter_declaration = error_mark_node; 10716 bool seen_open_paren = false; 10717 10718 c_parser_consume_token (parser); 10719 matching_parens parens; 10720 if (!parens.require_open (parser)) 10721 seen_open_paren = true; 10722 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) 10723 { 10724 /* We have "@catch (...)" (where the '...' are literally 10725 what is in the code). Skip the '...'. 10726 parameter_declaration is set to NULL_TREE, and 10727 objc_being_catch_clauses() knows that that means 10728 '...'. */ 10729 c_parser_consume_token (parser); 10730 parameter_declaration = NULL_TREE; 10731 } 10732 else 10733 { 10734 /* We have "@catch (NSException *exception)" or something 10735 like that. Parse the parameter declaration. */ 10736 parm = c_parser_parameter_declaration (parser, NULL_TREE); 10737 if (parm == NULL) 10738 parameter_declaration = error_mark_node; 10739 else 10740 parameter_declaration = grokparm (parm, NULL); 10741 } 10742 if (seen_open_paren) 10743 parens.require_close (parser); 10744 else 10745 { 10746 /* If there was no open parenthesis, we are recovering from 10747 an error, and we are trying to figure out what mistake 10748 the user has made. */ 10749 10750 /* If there is an immediate closing parenthesis, the user 10751 probably forgot the opening one (ie, they typed "@catch 10752 NSException *e)". Parse the closing parenthesis and keep 10753 going. */ 10754 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 10755 c_parser_consume_token (parser); 10756 10757 /* If these is no immediate closing parenthesis, the user 10758 probably doesn't know that parenthesis are required at 10759 all (ie, they typed "@catch NSException *e"). So, just 10760 forget about the closing parenthesis and keep going. */ 10761 } 10762 objc_begin_catch_clause (parameter_declaration); 10763 if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) 10764 c_parser_compound_statement_nostart (parser); 10765 objc_finish_catch_clause (); 10766 } 10767 if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY)) 10768 { 10769 c_parser_consume_token (parser); 10770 location = c_parser_peek_token (parser)->location; 10771 stmt = c_parser_compound_statement (parser); 10772 objc_build_finally_clause (location, stmt); 10773 } 10774 objc_finish_try_stmt (); 10775 } 10776 10777 /* Parse an objc-synchronized-statement. 10778 10779 objc-synchronized-statement: 10780 @synchronized ( expression ) compound-statement 10781 */ 10782 10783 static void 10784 c_parser_objc_synchronized_statement (c_parser *parser) 10785 { 10786 location_t loc; 10787 tree expr, stmt; 10788 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED)); 10789 c_parser_consume_token (parser); 10790 loc = c_parser_peek_token (parser)->location; 10791 objc_maybe_warn_exceptions (loc); 10792 matching_parens parens; 10793 if (parens.require_open (parser)) 10794 { 10795 struct c_expr ce = c_parser_expression (parser); 10796 ce = convert_lvalue_to_rvalue (loc, ce, false, false); 10797 expr = ce.value; 10798 expr = c_fully_fold (expr, false, NULL); 10799 parens.skip_until_found_close (parser); 10800 } 10801 else 10802 expr = error_mark_node; 10803 stmt = c_parser_compound_statement (parser); 10804 objc_build_synchronized (loc, expr, stmt); 10805 } 10806 10807 /* Parse an objc-selector; return NULL_TREE without an error if the 10808 next token is not an objc-selector. 10809 10810 objc-selector: 10811 identifier 10812 one of 10813 enum struct union if else while do for switch case default 10814 break continue return goto asm sizeof typeof __alignof 10815 unsigned long const short volatile signed restrict _Complex 10816 in out inout bycopy byref oneway int char float double void _Bool 10817 _Atomic 10818 10819 ??? Why this selection of keywords but not, for example, storage 10820 class specifiers? */ 10821 10822 static tree 10823 c_parser_objc_selector (c_parser *parser) 10824 { 10825 c_token *token = c_parser_peek_token (parser); 10826 tree value = token->value; 10827 if (token->type == CPP_NAME) 10828 { 10829 c_parser_consume_token (parser); 10830 return value; 10831 } 10832 if (token->type != CPP_KEYWORD) 10833 return NULL_TREE; 10834 switch (token->keyword) 10835 { 10836 case RID_ENUM: 10837 case RID_STRUCT: 10838 case RID_UNION: 10839 case RID_IF: 10840 case RID_ELSE: 10841 case RID_WHILE: 10842 case RID_DO: 10843 case RID_FOR: 10844 case RID_SWITCH: 10845 case RID_CASE: 10846 case RID_DEFAULT: 10847 case RID_BREAK: 10848 case RID_CONTINUE: 10849 case RID_RETURN: 10850 case RID_GOTO: 10851 case RID_ASM: 10852 case RID_SIZEOF: 10853 case RID_TYPEOF: 10854 case RID_ALIGNOF: 10855 case RID_UNSIGNED: 10856 case RID_LONG: 10857 case RID_CONST: 10858 case RID_SHORT: 10859 case RID_VOLATILE: 10860 case RID_SIGNED: 10861 case RID_RESTRICT: 10862 case RID_COMPLEX: 10863 case RID_IN: 10864 case RID_OUT: 10865 case RID_INOUT: 10866 case RID_BYCOPY: 10867 case RID_BYREF: 10868 case RID_ONEWAY: 10869 case RID_INT: 10870 case RID_CHAR: 10871 case RID_FLOAT: 10872 case RID_DOUBLE: 10873 CASE_RID_FLOATN_NX: 10874 case RID_VOID: 10875 case RID_BOOL: 10876 case RID_ATOMIC: 10877 case RID_AUTO_TYPE: 10878 case RID_INT_N_0: 10879 case RID_INT_N_1: 10880 case RID_INT_N_2: 10881 case RID_INT_N_3: 10882 c_parser_consume_token (parser); 10883 return value; 10884 default: 10885 return NULL_TREE; 10886 } 10887 } 10888 10889 /* Parse an objc-selector-arg. 10890 10891 objc-selector-arg: 10892 objc-selector 10893 objc-keywordname-list 10894 10895 objc-keywordname-list: 10896 objc-keywordname 10897 objc-keywordname-list objc-keywordname 10898 10899 objc-keywordname: 10900 objc-selector : 10901 : 10902 */ 10903 10904 static tree 10905 c_parser_objc_selector_arg (c_parser *parser) 10906 { 10907 tree sel = c_parser_objc_selector (parser); 10908 tree list = NULL_TREE; 10909 if (sel && c_parser_next_token_is_not (parser, CPP_COLON)) 10910 return sel; 10911 while (true) 10912 { 10913 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 10914 return list; 10915 list = chainon (list, build_tree_list (sel, NULL_TREE)); 10916 sel = c_parser_objc_selector (parser); 10917 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON)) 10918 break; 10919 } 10920 return list; 10921 } 10922 10923 /* Parse an objc-receiver. 10924 10925 objc-receiver: 10926 expression 10927 class-name 10928 type-name 10929 */ 10930 10931 static tree 10932 c_parser_objc_receiver (c_parser *parser) 10933 { 10934 location_t loc = c_parser_peek_token (parser)->location; 10935 10936 if (c_parser_peek_token (parser)->type == CPP_NAME 10937 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME 10938 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)) 10939 { 10940 tree id = c_parser_peek_token (parser)->value; 10941 c_parser_consume_token (parser); 10942 return objc_get_class_reference (id); 10943 } 10944 struct c_expr ce = c_parser_expression (parser); 10945 ce = convert_lvalue_to_rvalue (loc, ce, false, false); 10946 return c_fully_fold (ce.value, false, NULL); 10947 } 10948 10949 /* Parse objc-message-args. 10950 10951 objc-message-args: 10952 objc-selector 10953 objc-keywordarg-list 10954 10955 objc-keywordarg-list: 10956 objc-keywordarg 10957 objc-keywordarg-list objc-keywordarg 10958 10959 objc-keywordarg: 10960 objc-selector : objc-keywordexpr 10961 : objc-keywordexpr 10962 */ 10963 10964 static tree 10965 c_parser_objc_message_args (c_parser *parser) 10966 { 10967 tree sel = c_parser_objc_selector (parser); 10968 tree list = NULL_TREE; 10969 if (sel && c_parser_next_token_is_not (parser, CPP_COLON)) 10970 return sel; 10971 while (true) 10972 { 10973 tree keywordexpr; 10974 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 10975 return error_mark_node; 10976 keywordexpr = c_parser_objc_keywordexpr (parser); 10977 list = chainon (list, build_tree_list (sel, keywordexpr)); 10978 sel = c_parser_objc_selector (parser); 10979 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON)) 10980 break; 10981 } 10982 return list; 10983 } 10984 10985 /* Parse an objc-keywordexpr. 10986 10987 objc-keywordexpr: 10988 nonempty-expr-list 10989 */ 10990 10991 static tree 10992 c_parser_objc_keywordexpr (c_parser *parser) 10993 { 10994 tree ret; 10995 vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true, 10996 NULL, NULL, NULL, NULL); 10997 if (vec_safe_length (expr_list) == 1) 10998 { 10999 /* Just return the expression, remove a level of 11000 indirection. */ 11001 ret = (*expr_list)[0]; 11002 } 11003 else 11004 { 11005 /* We have a comma expression, we will collapse later. */ 11006 ret = build_tree_list_vec (expr_list); 11007 } 11008 release_tree_vector (expr_list); 11009 return ret; 11010 } 11011 11012 /* A check, needed in several places, that ObjC interface, implementation or 11013 method definitions are not prefixed by incorrect items. */ 11014 static bool 11015 c_parser_objc_diagnose_bad_element_prefix (c_parser *parser, 11016 struct c_declspecs *specs) 11017 { 11018 if (!specs->declspecs_seen_p || specs->non_sc_seen_p 11019 || specs->typespec_kind != ctsk_none) 11020 { 11021 c_parser_error (parser, 11022 "no type or storage class may be specified here,"); 11023 c_parser_skip_to_end_of_block_or_statement (parser); 11024 return true; 11025 } 11026 return false; 11027 } 11028 11029 /* Parse an Objective-C @property declaration. The syntax is: 11030 11031 objc-property-declaration: 11032 '@property' objc-property-attributes[opt] struct-declaration ; 11033 11034 objc-property-attributes: 11035 '(' objc-property-attribute-list ')' 11036 11037 objc-property-attribute-list: 11038 objc-property-attribute 11039 objc-property-attribute-list, objc-property-attribute 11040 11041 objc-property-attribute 11042 'getter' = identifier 11043 'setter' = identifier 11044 'readonly' 11045 'readwrite' 11046 'assign' 11047 'retain' 11048 'copy' 11049 'nonatomic' 11050 11051 For example: 11052 @property NSString *name; 11053 @property (readonly) id object; 11054 @property (retain, nonatomic, getter=getTheName) id name; 11055 @property int a, b, c; 11056 11057 PS: This function is identical to cp_parser_objc_at_propery_declaration 11058 for C++. Keep them in sync. */ 11059 static void 11060 c_parser_objc_at_property_declaration (c_parser *parser) 11061 { 11062 /* The following variables hold the attributes of the properties as 11063 parsed. They are 'false' or 'NULL_TREE' if the attribute was not 11064 seen. When we see an attribute, we set them to 'true' (if they 11065 are boolean properties) or to the identifier (if they have an 11066 argument, ie, for getter and setter). Note that here we only 11067 parse the list of attributes, check the syntax and accumulate the 11068 attributes that we find. objc_add_property_declaration() will 11069 then process the information. */ 11070 bool property_assign = false; 11071 bool property_copy = false; 11072 tree property_getter_ident = NULL_TREE; 11073 bool property_nonatomic = false; 11074 bool property_readonly = false; 11075 bool property_readwrite = false; 11076 bool property_retain = false; 11077 tree property_setter_ident = NULL_TREE; 11078 11079 /* 'properties' is the list of properties that we read. Usually a 11080 single one, but maybe more (eg, in "@property int a, b, c;" there 11081 are three). */ 11082 tree properties; 11083 location_t loc; 11084 11085 loc = c_parser_peek_token (parser)->location; 11086 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY)); 11087 11088 c_parser_consume_token (parser); /* Eat '@property'. */ 11089 11090 /* Parse the optional attribute list... */ 11091 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 11092 { 11093 matching_parens parens; 11094 11095 /* Eat the '(' */ 11096 parens.consume_open (parser); 11097 11098 /* Property attribute keywords are valid now. */ 11099 parser->objc_property_attr_context = true; 11100 11101 while (true) 11102 { 11103 bool syntax_error = false; 11104 c_token *token = c_parser_peek_token (parser); 11105 enum rid keyword; 11106 11107 if (token->type != CPP_KEYWORD) 11108 { 11109 if (token->type == CPP_CLOSE_PAREN) 11110 c_parser_error (parser, "expected identifier"); 11111 else 11112 { 11113 c_parser_consume_token (parser); 11114 c_parser_error (parser, "unknown property attribute"); 11115 } 11116 break; 11117 } 11118 keyword = token->keyword; 11119 c_parser_consume_token (parser); 11120 switch (keyword) 11121 { 11122 case RID_ASSIGN: property_assign = true; break; 11123 case RID_COPY: property_copy = true; break; 11124 case RID_NONATOMIC: property_nonatomic = true; break; 11125 case RID_READONLY: property_readonly = true; break; 11126 case RID_READWRITE: property_readwrite = true; break; 11127 case RID_RETAIN: property_retain = true; break; 11128 11129 case RID_GETTER: 11130 case RID_SETTER: 11131 if (c_parser_next_token_is_not (parser, CPP_EQ)) 11132 { 11133 if (keyword == RID_GETTER) 11134 c_parser_error (parser, 11135 "missing %<=%> (after %<getter%> attribute)"); 11136 else 11137 c_parser_error (parser, 11138 "missing %<=%> (after %<setter%> attribute)"); 11139 syntax_error = true; 11140 break; 11141 } 11142 c_parser_consume_token (parser); /* eat the = */ 11143 if (c_parser_next_token_is_not (parser, CPP_NAME)) 11144 { 11145 c_parser_error (parser, "expected identifier"); 11146 syntax_error = true; 11147 break; 11148 } 11149 if (keyword == RID_SETTER) 11150 { 11151 if (property_setter_ident != NULL_TREE) 11152 c_parser_error (parser, "the %<setter%> attribute may only be specified once"); 11153 else 11154 property_setter_ident = c_parser_peek_token (parser)->value; 11155 c_parser_consume_token (parser); 11156 if (c_parser_next_token_is_not (parser, CPP_COLON)) 11157 c_parser_error (parser, "setter name must terminate with %<:%>"); 11158 else 11159 c_parser_consume_token (parser); 11160 } 11161 else 11162 { 11163 if (property_getter_ident != NULL_TREE) 11164 c_parser_error (parser, "the %<getter%> attribute may only be specified once"); 11165 else 11166 property_getter_ident = c_parser_peek_token (parser)->value; 11167 c_parser_consume_token (parser); 11168 } 11169 break; 11170 default: 11171 c_parser_error (parser, "unknown property attribute"); 11172 syntax_error = true; 11173 break; 11174 } 11175 11176 if (syntax_error) 11177 break; 11178 11179 if (c_parser_next_token_is (parser, CPP_COMMA)) 11180 c_parser_consume_token (parser); 11181 else 11182 break; 11183 } 11184 parser->objc_property_attr_context = false; 11185 parens.skip_until_found_close (parser); 11186 } 11187 /* ... and the property declaration(s). */ 11188 properties = c_parser_struct_declaration (parser); 11189 11190 if (properties == error_mark_node) 11191 { 11192 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); 11193 parser->error = false; 11194 return; 11195 } 11196 11197 if (properties == NULL_TREE) 11198 c_parser_error (parser, "expected identifier"); 11199 else 11200 { 11201 /* Comma-separated properties are chained together in 11202 reverse order; add them one by one. */ 11203 properties = nreverse (properties); 11204 11205 for (; properties; properties = TREE_CHAIN (properties)) 11206 objc_add_property_declaration (loc, copy_node (properties), 11207 property_readonly, property_readwrite, 11208 property_assign, property_retain, 11209 property_copy, property_nonatomic, 11210 property_getter_ident, property_setter_ident); 11211 } 11212 11213 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 11214 parser->error = false; 11215 } 11216 11217 /* Parse an Objective-C @synthesize declaration. The syntax is: 11218 11219 objc-synthesize-declaration: 11220 @synthesize objc-synthesize-identifier-list ; 11221 11222 objc-synthesize-identifier-list: 11223 objc-synthesize-identifier 11224 objc-synthesize-identifier-list, objc-synthesize-identifier 11225 11226 objc-synthesize-identifier 11227 identifier 11228 identifier = identifier 11229 11230 For example: 11231 @synthesize MyProperty; 11232 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty; 11233 11234 PS: This function is identical to cp_parser_objc_at_synthesize_declaration 11235 for C++. Keep them in sync. 11236 */ 11237 static void 11238 c_parser_objc_at_synthesize_declaration (c_parser *parser) 11239 { 11240 tree list = NULL_TREE; 11241 location_t loc; 11242 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE)); 11243 loc = c_parser_peek_token (parser)->location; 11244 11245 c_parser_consume_token (parser); 11246 while (true) 11247 { 11248 tree property, ivar; 11249 if (c_parser_next_token_is_not (parser, CPP_NAME)) 11250 { 11251 c_parser_error (parser, "expected identifier"); 11252 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); 11253 /* Once we find the semicolon, we can resume normal parsing. 11254 We have to reset parser->error manually because 11255 c_parser_skip_until_found() won't reset it for us if the 11256 next token is precisely a semicolon. */ 11257 parser->error = false; 11258 return; 11259 } 11260 property = c_parser_peek_token (parser)->value; 11261 c_parser_consume_token (parser); 11262 if (c_parser_next_token_is (parser, CPP_EQ)) 11263 { 11264 c_parser_consume_token (parser); 11265 if (c_parser_next_token_is_not (parser, CPP_NAME)) 11266 { 11267 c_parser_error (parser, "expected identifier"); 11268 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); 11269 parser->error = false; 11270 return; 11271 } 11272 ivar = c_parser_peek_token (parser)->value; 11273 c_parser_consume_token (parser); 11274 } 11275 else 11276 ivar = NULL_TREE; 11277 list = chainon (list, build_tree_list (ivar, property)); 11278 if (c_parser_next_token_is (parser, CPP_COMMA)) 11279 c_parser_consume_token (parser); 11280 else 11281 break; 11282 } 11283 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 11284 objc_add_synthesize_declaration (loc, list); 11285 } 11286 11287 /* Parse an Objective-C @dynamic declaration. The syntax is: 11288 11289 objc-dynamic-declaration: 11290 @dynamic identifier-list ; 11291 11292 For example: 11293 @dynamic MyProperty; 11294 @dynamic MyProperty, AnotherProperty; 11295 11296 PS: This function is identical to cp_parser_objc_at_dynamic_declaration 11297 for C++. Keep them in sync. 11298 */ 11299 static void 11300 c_parser_objc_at_dynamic_declaration (c_parser *parser) 11301 { 11302 tree list = NULL_TREE; 11303 location_t loc; 11304 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC)); 11305 loc = c_parser_peek_token (parser)->location; 11306 11307 c_parser_consume_token (parser); 11308 while (true) 11309 { 11310 tree property; 11311 if (c_parser_next_token_is_not (parser, CPP_NAME)) 11312 { 11313 c_parser_error (parser, "expected identifier"); 11314 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); 11315 parser->error = false; 11316 return; 11317 } 11318 property = c_parser_peek_token (parser)->value; 11319 list = chainon (list, build_tree_list (NULL_TREE, property)); 11320 c_parser_consume_token (parser); 11321 if (c_parser_next_token_is (parser, CPP_COMMA)) 11322 c_parser_consume_token (parser); 11323 else 11324 break; 11325 } 11326 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 11327 objc_add_dynamic_declaration (loc, list); 11328 } 11329 11330 11331 /* Parse a pragma GCC ivdep. */ 11332 11333 static bool 11334 c_parse_pragma_ivdep (c_parser *parser) 11335 { 11336 c_parser_consume_pragma (parser); 11337 c_parser_skip_to_pragma_eol (parser); 11338 return true; 11339 } 11340 11341 /* Parse a pragma GCC unroll. */ 11342 11343 static unsigned short 11344 c_parser_pragma_unroll (c_parser *parser) 11345 { 11346 unsigned short unroll; 11347 c_parser_consume_pragma (parser); 11348 location_t location = c_parser_peek_token (parser)->location; 11349 tree expr = c_parser_expr_no_commas (parser, NULL).value; 11350 mark_exp_read (expr); 11351 expr = c_fully_fold (expr, false, NULL); 11352 HOST_WIDE_INT lunroll = 0; 11353 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)) 11354 || TREE_CODE (expr) != INTEGER_CST 11355 || (lunroll = tree_to_shwi (expr)) < 0 11356 || lunroll >= USHRT_MAX) 11357 { 11358 error_at (location, "%<#pragma GCC unroll%> requires an" 11359 " assignment-expression that evaluates to a non-negative" 11360 " integral constant less than %u", USHRT_MAX); 11361 unroll = 0; 11362 } 11363 else 11364 { 11365 unroll = (unsigned short)lunroll; 11366 if (unroll == 0) 11367 unroll = 1; 11368 } 11369 11370 c_parser_skip_to_pragma_eol (parser); 11371 return unroll; 11372 } 11373 11374 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore 11375 should be considered, statements. ALLOW_STMT is true if we're within 11376 the context of a function and such pragmas are to be allowed. Returns 11377 true if we actually parsed such a pragma. */ 11378 11379 static bool 11380 c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p) 11381 { 11382 unsigned int id; 11383 const char *construct = NULL; 11384 11385 id = c_parser_peek_token (parser)->pragma_kind; 11386 gcc_assert (id != PRAGMA_NONE); 11387 11388 switch (id) 11389 { 11390 case PRAGMA_OACC_DECLARE: 11391 c_parser_oacc_declare (parser); 11392 return false; 11393 11394 case PRAGMA_OACC_ENTER_DATA: 11395 if (context != pragma_compound) 11396 { 11397 construct = "acc enter data"; 11398 in_compound: 11399 if (context == pragma_stmt) 11400 { 11401 error_at (c_parser_peek_token (parser)->location, 11402 "%<#pragma %s%> may only be used in compound " 11403 "statements", construct); 11404 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); 11405 return false; 11406 } 11407 goto bad_stmt; 11408 } 11409 c_parser_oacc_enter_exit_data (parser, true); 11410 return false; 11411 11412 case PRAGMA_OACC_EXIT_DATA: 11413 if (context != pragma_compound) 11414 { 11415 construct = "acc exit data"; 11416 goto in_compound; 11417 } 11418 c_parser_oacc_enter_exit_data (parser, false); 11419 return false; 11420 11421 case PRAGMA_OACC_ROUTINE: 11422 if (context != pragma_external) 11423 { 11424 error_at (c_parser_peek_token (parser)->location, 11425 "%<#pragma acc routine%> must be at file scope"); 11426 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); 11427 return false; 11428 } 11429 c_parser_oacc_routine (parser, context); 11430 return false; 11431 11432 case PRAGMA_OACC_UPDATE: 11433 if (context != pragma_compound) 11434 { 11435 construct = "acc update"; 11436 goto in_compound; 11437 } 11438 c_parser_oacc_update (parser); 11439 return false; 11440 11441 case PRAGMA_OMP_BARRIER: 11442 if (context != pragma_compound) 11443 { 11444 construct = "omp barrier"; 11445 goto in_compound; 11446 } 11447 c_parser_omp_barrier (parser); 11448 return false; 11449 11450 case PRAGMA_OMP_DEPOBJ: 11451 if (context != pragma_compound) 11452 { 11453 construct = "omp depobj"; 11454 goto in_compound; 11455 } 11456 c_parser_omp_depobj (parser); 11457 return false; 11458 11459 case PRAGMA_OMP_FLUSH: 11460 if (context != pragma_compound) 11461 { 11462 construct = "omp flush"; 11463 goto in_compound; 11464 } 11465 c_parser_omp_flush (parser); 11466 return false; 11467 11468 case PRAGMA_OMP_TASKWAIT: 11469 if (context != pragma_compound) 11470 { 11471 construct = "omp taskwait"; 11472 goto in_compound; 11473 } 11474 c_parser_omp_taskwait (parser); 11475 return false; 11476 11477 case PRAGMA_OMP_TASKYIELD: 11478 if (context != pragma_compound) 11479 { 11480 construct = "omp taskyield"; 11481 goto in_compound; 11482 } 11483 c_parser_omp_taskyield (parser); 11484 return false; 11485 11486 case PRAGMA_OMP_CANCEL: 11487 if (context != pragma_compound) 11488 { 11489 construct = "omp cancel"; 11490 goto in_compound; 11491 } 11492 c_parser_omp_cancel (parser); 11493 return false; 11494 11495 case PRAGMA_OMP_CANCELLATION_POINT: 11496 c_parser_omp_cancellation_point (parser, context); 11497 return false; 11498 11499 case PRAGMA_OMP_THREADPRIVATE: 11500 c_parser_omp_threadprivate (parser); 11501 return false; 11502 11503 case PRAGMA_OMP_TARGET: 11504 return c_parser_omp_target (parser, context, if_p); 11505 11506 case PRAGMA_OMP_END_DECLARE_TARGET: 11507 c_parser_omp_end_declare_target (parser); 11508 return false; 11509 11510 case PRAGMA_OMP_SECTION: 11511 error_at (c_parser_peek_token (parser)->location, 11512 "%<#pragma omp section%> may only be used in " 11513 "%<#pragma omp sections%> construct"); 11514 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); 11515 return false; 11516 11517 case PRAGMA_OMP_DECLARE: 11518 c_parser_omp_declare (parser, context); 11519 return false; 11520 11521 case PRAGMA_OMP_REQUIRES: 11522 c_parser_omp_requires (parser); 11523 return false; 11524 11525 case PRAGMA_OMP_ORDERED: 11526 return c_parser_omp_ordered (parser, context, if_p); 11527 11528 case PRAGMA_IVDEP: 11529 { 11530 const bool ivdep = c_parse_pragma_ivdep (parser); 11531 unsigned short unroll; 11532 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_UNROLL) 11533 unroll = c_parser_pragma_unroll (parser); 11534 else 11535 unroll = 0; 11536 if (!c_parser_next_token_is_keyword (parser, RID_FOR) 11537 && !c_parser_next_token_is_keyword (parser, RID_WHILE) 11538 && !c_parser_next_token_is_keyword (parser, RID_DO)) 11539 { 11540 c_parser_error (parser, "for, while or do statement expected"); 11541 return false; 11542 } 11543 if (c_parser_next_token_is_keyword (parser, RID_FOR)) 11544 c_parser_for_statement (parser, ivdep, unroll, if_p); 11545 else if (c_parser_next_token_is_keyword (parser, RID_WHILE)) 11546 c_parser_while_statement (parser, ivdep, unroll, if_p); 11547 else 11548 c_parser_do_statement (parser, ivdep, unroll); 11549 } 11550 return false; 11551 11552 case PRAGMA_UNROLL: 11553 { 11554 unsigned short unroll = c_parser_pragma_unroll (parser); 11555 bool ivdep; 11556 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_IVDEP) 11557 ivdep = c_parse_pragma_ivdep (parser); 11558 else 11559 ivdep = false; 11560 if (!c_parser_next_token_is_keyword (parser, RID_FOR) 11561 && !c_parser_next_token_is_keyword (parser, RID_WHILE) 11562 && !c_parser_next_token_is_keyword (parser, RID_DO)) 11563 { 11564 c_parser_error (parser, "for, while or do statement expected"); 11565 return false; 11566 } 11567 if (c_parser_next_token_is_keyword (parser, RID_FOR)) 11568 c_parser_for_statement (parser, ivdep, unroll, if_p); 11569 else if (c_parser_next_token_is_keyword (parser, RID_WHILE)) 11570 c_parser_while_statement (parser, ivdep, unroll, if_p); 11571 else 11572 c_parser_do_statement (parser, ivdep, unroll); 11573 } 11574 return false; 11575 11576 case PRAGMA_GCC_PCH_PREPROCESS: 11577 c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first"); 11578 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); 11579 return false; 11580 11581 case PRAGMA_OACC_WAIT: 11582 if (context != pragma_compound) 11583 { 11584 construct = "acc wait"; 11585 goto in_compound; 11586 } 11587 /* FALL THROUGH. */ 11588 11589 default: 11590 if (id < PRAGMA_FIRST_EXTERNAL) 11591 { 11592 if (context != pragma_stmt && context != pragma_compound) 11593 { 11594 bad_stmt: 11595 c_parser_error (parser, "expected declaration specifiers"); 11596 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); 11597 return false; 11598 } 11599 c_parser_omp_construct (parser, if_p); 11600 return true; 11601 } 11602 break; 11603 } 11604 11605 c_parser_consume_pragma (parser); 11606 c_invoke_pragma_handler (id); 11607 11608 /* Skip to EOL, but suppress any error message. Those will have been 11609 generated by the handler routine through calling error, as opposed 11610 to calling c_parser_error. */ 11611 parser->error = true; 11612 c_parser_skip_to_pragma_eol (parser); 11613 11614 return false; 11615 } 11616 11617 /* The interface the pragma parsers have to the lexer. */ 11618 11619 enum cpp_ttype 11620 pragma_lex (tree *value, location_t *loc) 11621 { 11622 c_token *tok = c_parser_peek_token (the_parser); 11623 enum cpp_ttype ret = tok->type; 11624 11625 *value = tok->value; 11626 if (loc) 11627 *loc = tok->location; 11628 11629 if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF) 11630 ret = CPP_EOF; 11631 else 11632 { 11633 if (ret == CPP_KEYWORD) 11634 ret = CPP_NAME; 11635 c_parser_consume_token (the_parser); 11636 } 11637 11638 return ret; 11639 } 11640 11641 static void 11642 c_parser_pragma_pch_preprocess (c_parser *parser) 11643 { 11644 tree name = NULL; 11645 11646 c_parser_consume_pragma (parser); 11647 if (c_parser_next_token_is (parser, CPP_STRING)) 11648 { 11649 name = c_parser_peek_token (parser)->value; 11650 c_parser_consume_token (parser); 11651 } 11652 else 11653 c_parser_error (parser, "expected string literal"); 11654 c_parser_skip_to_pragma_eol (parser); 11655 11656 if (name) 11657 c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name)); 11658 } 11659 11660 /* OpenACC and OpenMP parsing routines. */ 11661 11662 /* Returns name of the next clause. 11663 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and 11664 the token is not consumed. Otherwise appropriate pragma_omp_clause is 11665 returned and the token is consumed. */ 11666 11667 static pragma_omp_clause 11668 c_parser_omp_clause_name (c_parser *parser) 11669 { 11670 pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE; 11671 11672 if (c_parser_next_token_is_keyword (parser, RID_AUTO)) 11673 result = PRAGMA_OACC_CLAUSE_AUTO; 11674 else if (c_parser_next_token_is_keyword (parser, RID_IF)) 11675 result = PRAGMA_OMP_CLAUSE_IF; 11676 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)) 11677 result = PRAGMA_OMP_CLAUSE_DEFAULT; 11678 else if (c_parser_next_token_is_keyword (parser, RID_FOR)) 11679 result = PRAGMA_OMP_CLAUSE_FOR; 11680 else if (c_parser_next_token_is (parser, CPP_NAME)) 11681 { 11682 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 11683 11684 switch (p[0]) 11685 { 11686 case 'a': 11687 if (!strcmp ("aligned", p)) 11688 result = PRAGMA_OMP_CLAUSE_ALIGNED; 11689 else if (!strcmp ("async", p)) 11690 result = PRAGMA_OACC_CLAUSE_ASYNC; 11691 break; 11692 case 'c': 11693 if (!strcmp ("collapse", p)) 11694 result = PRAGMA_OMP_CLAUSE_COLLAPSE; 11695 else if (!strcmp ("copy", p)) 11696 result = PRAGMA_OACC_CLAUSE_COPY; 11697 else if (!strcmp ("copyin", p)) 11698 result = PRAGMA_OMP_CLAUSE_COPYIN; 11699 else if (!strcmp ("copyout", p)) 11700 result = PRAGMA_OACC_CLAUSE_COPYOUT; 11701 else if (!strcmp ("copyprivate", p)) 11702 result = PRAGMA_OMP_CLAUSE_COPYPRIVATE; 11703 else if (!strcmp ("create", p)) 11704 result = PRAGMA_OACC_CLAUSE_CREATE; 11705 break; 11706 case 'd': 11707 if (!strcmp ("defaultmap", p)) 11708 result = PRAGMA_OMP_CLAUSE_DEFAULTMAP; 11709 else if (!strcmp ("delete", p)) 11710 result = PRAGMA_OACC_CLAUSE_DELETE; 11711 else if (!strcmp ("depend", p)) 11712 result = PRAGMA_OMP_CLAUSE_DEPEND; 11713 else if (!strcmp ("device", p)) 11714 result = PRAGMA_OMP_CLAUSE_DEVICE; 11715 else if (!strcmp ("deviceptr", p)) 11716 result = PRAGMA_OACC_CLAUSE_DEVICEPTR; 11717 else if (!strcmp ("device_resident", p)) 11718 result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT; 11719 else if (!strcmp ("dist_schedule", p)) 11720 result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE; 11721 break; 11722 case 'f': 11723 if (!strcmp ("final", p)) 11724 result = PRAGMA_OMP_CLAUSE_FINAL; 11725 else if (!strcmp ("finalize", p)) 11726 result = PRAGMA_OACC_CLAUSE_FINALIZE; 11727 else if (!strcmp ("firstprivate", p)) 11728 result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE; 11729 else if (!strcmp ("from", p)) 11730 result = PRAGMA_OMP_CLAUSE_FROM; 11731 break; 11732 case 'g': 11733 if (!strcmp ("gang", p)) 11734 result = PRAGMA_OACC_CLAUSE_GANG; 11735 else if (!strcmp ("grainsize", p)) 11736 result = PRAGMA_OMP_CLAUSE_GRAINSIZE; 11737 break; 11738 case 'h': 11739 if (!strcmp ("hint", p)) 11740 result = PRAGMA_OMP_CLAUSE_HINT; 11741 else if (!strcmp ("host", p)) 11742 result = PRAGMA_OACC_CLAUSE_HOST; 11743 break; 11744 case 'i': 11745 if (!strcmp ("if_present", p)) 11746 result = PRAGMA_OACC_CLAUSE_IF_PRESENT; 11747 else if (!strcmp ("in_reduction", p)) 11748 result = PRAGMA_OMP_CLAUSE_IN_REDUCTION; 11749 else if (!strcmp ("inbranch", p)) 11750 result = PRAGMA_OMP_CLAUSE_INBRANCH; 11751 else if (!strcmp ("independent", p)) 11752 result = PRAGMA_OACC_CLAUSE_INDEPENDENT; 11753 else if (!strcmp ("is_device_ptr", p)) 11754 result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR; 11755 break; 11756 case 'l': 11757 if (!strcmp ("lastprivate", p)) 11758 result = PRAGMA_OMP_CLAUSE_LASTPRIVATE; 11759 else if (!strcmp ("linear", p)) 11760 result = PRAGMA_OMP_CLAUSE_LINEAR; 11761 else if (!strcmp ("link", p)) 11762 result = PRAGMA_OMP_CLAUSE_LINK; 11763 break; 11764 case 'm': 11765 if (!strcmp ("map", p)) 11766 result = PRAGMA_OMP_CLAUSE_MAP; 11767 else if (!strcmp ("mergeable", p)) 11768 result = PRAGMA_OMP_CLAUSE_MERGEABLE; 11769 break; 11770 case 'n': 11771 if (!strcmp ("nogroup", p)) 11772 result = PRAGMA_OMP_CLAUSE_NOGROUP; 11773 else if (!strcmp ("nontemporal", p)) 11774 result = PRAGMA_OMP_CLAUSE_NONTEMPORAL; 11775 else if (!strcmp ("notinbranch", p)) 11776 result = PRAGMA_OMP_CLAUSE_NOTINBRANCH; 11777 else if (!strcmp ("nowait", p)) 11778 result = PRAGMA_OMP_CLAUSE_NOWAIT; 11779 else if (!strcmp ("num_gangs", p)) 11780 result = PRAGMA_OACC_CLAUSE_NUM_GANGS; 11781 else if (!strcmp ("num_tasks", p)) 11782 result = PRAGMA_OMP_CLAUSE_NUM_TASKS; 11783 else if (!strcmp ("num_teams", p)) 11784 result = PRAGMA_OMP_CLAUSE_NUM_TEAMS; 11785 else if (!strcmp ("num_threads", p)) 11786 result = PRAGMA_OMP_CLAUSE_NUM_THREADS; 11787 else if (!strcmp ("num_workers", p)) 11788 result = PRAGMA_OACC_CLAUSE_NUM_WORKERS; 11789 break; 11790 case 'o': 11791 if (!strcmp ("ordered", p)) 11792 result = PRAGMA_OMP_CLAUSE_ORDERED; 11793 break; 11794 case 'p': 11795 if (!strcmp ("parallel", p)) 11796 result = PRAGMA_OMP_CLAUSE_PARALLEL; 11797 else if (!strcmp ("present", p)) 11798 result = PRAGMA_OACC_CLAUSE_PRESENT; 11799 /* As of OpenACC 2.5, these are now aliases of the non-present_or 11800 clauses. */ 11801 else if (!strcmp ("present_or_copy", p) 11802 || !strcmp ("pcopy", p)) 11803 result = PRAGMA_OACC_CLAUSE_COPY; 11804 else if (!strcmp ("present_or_copyin", p) 11805 || !strcmp ("pcopyin", p)) 11806 result = PRAGMA_OACC_CLAUSE_COPYIN; 11807 else if (!strcmp ("present_or_copyout", p) 11808 || !strcmp ("pcopyout", p)) 11809 result = PRAGMA_OACC_CLAUSE_COPYOUT; 11810 else if (!strcmp ("present_or_create", p) 11811 || !strcmp ("pcreate", p)) 11812 result = PRAGMA_OACC_CLAUSE_CREATE; 11813 else if (!strcmp ("priority", p)) 11814 result = PRAGMA_OMP_CLAUSE_PRIORITY; 11815 else if (!strcmp ("private", p)) 11816 result = PRAGMA_OMP_CLAUSE_PRIVATE; 11817 else if (!strcmp ("proc_bind", p)) 11818 result = PRAGMA_OMP_CLAUSE_PROC_BIND; 11819 break; 11820 case 'r': 11821 if (!strcmp ("reduction", p)) 11822 result = PRAGMA_OMP_CLAUSE_REDUCTION; 11823 break; 11824 case 's': 11825 if (!strcmp ("safelen", p)) 11826 result = PRAGMA_OMP_CLAUSE_SAFELEN; 11827 else if (!strcmp ("schedule", p)) 11828 result = PRAGMA_OMP_CLAUSE_SCHEDULE; 11829 else if (!strcmp ("sections", p)) 11830 result = PRAGMA_OMP_CLAUSE_SECTIONS; 11831 else if (!strcmp ("self", p)) /* "self" is a synonym for "host". */ 11832 result = PRAGMA_OACC_CLAUSE_HOST; 11833 else if (!strcmp ("seq", p)) 11834 result = PRAGMA_OACC_CLAUSE_SEQ; 11835 else if (!strcmp ("shared", p)) 11836 result = PRAGMA_OMP_CLAUSE_SHARED; 11837 else if (!strcmp ("simd", p)) 11838 result = PRAGMA_OMP_CLAUSE_SIMD; 11839 else if (!strcmp ("simdlen", p)) 11840 result = PRAGMA_OMP_CLAUSE_SIMDLEN; 11841 break; 11842 case 't': 11843 if (!strcmp ("task_reduction", p)) 11844 result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION; 11845 else if (!strcmp ("taskgroup", p)) 11846 result = PRAGMA_OMP_CLAUSE_TASKGROUP; 11847 else if (!strcmp ("thread_limit", p)) 11848 result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT; 11849 else if (!strcmp ("threads", p)) 11850 result = PRAGMA_OMP_CLAUSE_THREADS; 11851 else if (!strcmp ("tile", p)) 11852 result = PRAGMA_OACC_CLAUSE_TILE; 11853 else if (!strcmp ("to", p)) 11854 result = PRAGMA_OMP_CLAUSE_TO; 11855 break; 11856 case 'u': 11857 if (!strcmp ("uniform", p)) 11858 result = PRAGMA_OMP_CLAUSE_UNIFORM; 11859 else if (!strcmp ("untied", p)) 11860 result = PRAGMA_OMP_CLAUSE_UNTIED; 11861 else if (!strcmp ("use_device", p)) 11862 result = PRAGMA_OACC_CLAUSE_USE_DEVICE; 11863 else if (!strcmp ("use_device_ptr", p)) 11864 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR; 11865 break; 11866 case 'v': 11867 if (!strcmp ("vector", p)) 11868 result = PRAGMA_OACC_CLAUSE_VECTOR; 11869 else if (!strcmp ("vector_length", p)) 11870 result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH; 11871 break; 11872 case 'w': 11873 if (!strcmp ("wait", p)) 11874 result = PRAGMA_OACC_CLAUSE_WAIT; 11875 else if (!strcmp ("worker", p)) 11876 result = PRAGMA_OACC_CLAUSE_WORKER; 11877 break; 11878 } 11879 } 11880 11881 if (result != PRAGMA_OMP_CLAUSE_NONE) 11882 c_parser_consume_token (parser); 11883 11884 return result; 11885 } 11886 11887 /* Validate that a clause of the given type does not already exist. */ 11888 11889 static void 11890 check_no_duplicate_clause (tree clauses, enum omp_clause_code code, 11891 const char *name) 11892 { 11893 tree c; 11894 11895 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c)) 11896 if (OMP_CLAUSE_CODE (c) == code) 11897 { 11898 location_t loc = OMP_CLAUSE_LOCATION (c); 11899 error_at (loc, "too many %qs clauses", name); 11900 break; 11901 } 11902 } 11903 11904 /* OpenACC 2.0 11905 Parse wait clause or wait directive parameters. */ 11906 11907 static tree 11908 c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list) 11909 { 11910 vec<tree, va_gc> *args; 11911 tree t, args_tree; 11912 11913 matching_parens parens; 11914 if (!parens.require_open (parser)) 11915 return list; 11916 11917 args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL); 11918 args_tree = build_tree_list_vec (args); 11919 11920 for (t = args_tree; t; t = TREE_CHAIN (t)) 11921 { 11922 tree targ = TREE_VALUE (t); 11923 11924 if (targ != error_mark_node) 11925 { 11926 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ))) 11927 { 11928 c_parser_error (parser, "expression must be integral"); 11929 targ = error_mark_node; 11930 } 11931 else 11932 { 11933 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT); 11934 11935 OMP_CLAUSE_DECL (c) = targ; 11936 OMP_CLAUSE_CHAIN (c) = list; 11937 list = c; 11938 } 11939 } 11940 } 11941 11942 release_tree_vector (args); 11943 parens.require_close (parser); 11944 return list; 11945 } 11946 11947 /* OpenACC 2.0, OpenMP 2.5: 11948 variable-list: 11949 identifier 11950 variable-list , identifier 11951 11952 If KIND is nonzero, create the appropriate node and install the 11953 decl in OMP_CLAUSE_DECL and add the node to the head of the list. 11954 If KIND is nonzero, CLAUSE_LOC is the location of the clause. 11955 11956 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE; 11957 return the list created. */ 11958 11959 static tree 11960 c_parser_omp_variable_list (c_parser *parser, 11961 location_t clause_loc, 11962 enum omp_clause_code kind, tree list) 11963 { 11964 auto_vec<c_token> tokens; 11965 unsigned int tokens_avail = 0; 11966 bool first = true; 11967 11968 while (1) 11969 { 11970 bool array_section_p = false; 11971 if (kind == OMP_CLAUSE_DEPEND) 11972 { 11973 if (c_parser_next_token_is_not (parser, CPP_NAME) 11974 || c_parser_peek_token (parser)->id_kind != C_ID_ID) 11975 { 11976 struct c_expr expr = c_parser_expr_no_commas (parser, NULL); 11977 if (expr.value != error_mark_node) 11978 { 11979 tree u = build_omp_clause (clause_loc, kind); 11980 OMP_CLAUSE_DECL (u) = expr.value; 11981 OMP_CLAUSE_CHAIN (u) = list; 11982 list = u; 11983 } 11984 11985 if (c_parser_next_token_is_not (parser, CPP_COMMA)) 11986 break; 11987 11988 c_parser_consume_token (parser); 11989 first = false; 11990 continue; 11991 } 11992 11993 tokens.truncate (0); 11994 unsigned int nesting_depth = 0; 11995 while (1) 11996 { 11997 c_token *token = c_parser_peek_token (parser); 11998 switch (token->type) 11999 { 12000 case CPP_EOF: 12001 case CPP_PRAGMA_EOL: 12002 break; 12003 case CPP_OPEN_BRACE: 12004 case CPP_OPEN_PAREN: 12005 case CPP_OPEN_SQUARE: 12006 ++nesting_depth; 12007 goto add; 12008 case CPP_CLOSE_BRACE: 12009 case CPP_CLOSE_PAREN: 12010 case CPP_CLOSE_SQUARE: 12011 if (nesting_depth-- == 0) 12012 break; 12013 goto add; 12014 case CPP_COMMA: 12015 if (nesting_depth == 0) 12016 break; 12017 goto add; 12018 default: 12019 add: 12020 tokens.safe_push (*token); 12021 c_parser_consume_token (parser); 12022 continue; 12023 } 12024 break; 12025 } 12026 12027 /* Make sure nothing tries to read past the end of the tokens. */ 12028 c_token eof_token; 12029 memset (&eof_token, 0, sizeof (eof_token)); 12030 eof_token.type = CPP_EOF; 12031 tokens.safe_push (eof_token); 12032 tokens.safe_push (eof_token); 12033 12034 tokens_avail = parser->tokens_avail; 12035 gcc_assert (parser->tokens == &parser->tokens_buf[0]); 12036 parser->tokens = tokens.address (); 12037 parser->tokens_avail = tokens.length (); 12038 } 12039 12040 tree t = NULL_TREE; 12041 12042 if (c_parser_next_token_is (parser, CPP_NAME) 12043 && c_parser_peek_token (parser)->id_kind == C_ID_ID) 12044 { 12045 t = lookup_name (c_parser_peek_token (parser)->value); 12046 12047 if (t == NULL_TREE) 12048 { 12049 undeclared_variable (c_parser_peek_token (parser)->location, 12050 c_parser_peek_token (parser)->value); 12051 t = error_mark_node; 12052 } 12053 12054 c_parser_consume_token (parser); 12055 } 12056 else if (c_parser_next_token_is (parser, CPP_KEYWORD) 12057 && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME 12058 || (c_parser_peek_token (parser)->keyword 12059 == RID_PRETTY_FUNCTION_NAME) 12060 || (c_parser_peek_token (parser)->keyword 12061 == RID_C99_FUNCTION_NAME))) 12062 t = c_parser_predefined_identifier (parser).value; 12063 else 12064 { 12065 if (first) 12066 c_parser_error (parser, "expected identifier"); 12067 break; 12068 } 12069 12070 if (t == error_mark_node) 12071 ; 12072 else if (kind != 0) 12073 { 12074 switch (kind) 12075 { 12076 case OMP_CLAUSE__CACHE_: 12077 /* The OpenACC cache directive explicitly only allows "array 12078 elements or subarrays". */ 12079 if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE) 12080 { 12081 c_parser_error (parser, "expected %<[%>"); 12082 t = error_mark_node; 12083 break; 12084 } 12085 /* FALLTHROUGH */ 12086 case OMP_CLAUSE_MAP: 12087 case OMP_CLAUSE_FROM: 12088 case OMP_CLAUSE_TO: 12089 while (c_parser_next_token_is (parser, CPP_DOT)) 12090 { 12091 location_t op_loc = c_parser_peek_token (parser)->location; 12092 c_parser_consume_token (parser); 12093 if (!c_parser_next_token_is (parser, CPP_NAME)) 12094 { 12095 c_parser_error (parser, "expected identifier"); 12096 t = error_mark_node; 12097 break; 12098 } 12099 12100 c_token *comp_tok = c_parser_peek_token (parser); 12101 tree ident = comp_tok->value; 12102 location_t comp_loc = comp_tok->location; 12103 c_parser_consume_token (parser); 12104 t = build_component_ref (op_loc, t, ident, comp_loc); 12105 } 12106 /* FALLTHROUGH */ 12107 case OMP_CLAUSE_DEPEND: 12108 case OMP_CLAUSE_REDUCTION: 12109 case OMP_CLAUSE_IN_REDUCTION: 12110 case OMP_CLAUSE_TASK_REDUCTION: 12111 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)) 12112 { 12113 tree low_bound = NULL_TREE, length = NULL_TREE; 12114 12115 c_parser_consume_token (parser); 12116 if (!c_parser_next_token_is (parser, CPP_COLON)) 12117 { 12118 location_t expr_loc 12119 = c_parser_peek_token (parser)->location; 12120 c_expr expr = c_parser_expression (parser); 12121 expr = convert_lvalue_to_rvalue (expr_loc, expr, 12122 false, true); 12123 low_bound = expr.value; 12124 } 12125 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) 12126 length = integer_one_node; 12127 else 12128 { 12129 /* Look for `:'. */ 12130 if (!c_parser_require (parser, CPP_COLON, 12131 "expected %<:%>")) 12132 { 12133 t = error_mark_node; 12134 break; 12135 } 12136 array_section_p = true; 12137 if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) 12138 { 12139 location_t expr_loc 12140 = c_parser_peek_token (parser)->location; 12141 c_expr expr = c_parser_expression (parser); 12142 expr = convert_lvalue_to_rvalue (expr_loc, expr, 12143 false, true); 12144 length = expr.value; 12145 } 12146 } 12147 /* Look for the closing `]'. */ 12148 if (!c_parser_require (parser, CPP_CLOSE_SQUARE, 12149 "expected %<]%>")) 12150 { 12151 t = error_mark_node; 12152 break; 12153 } 12154 12155 t = tree_cons (low_bound, length, t); 12156 } 12157 if (kind == OMP_CLAUSE_DEPEND 12158 && t != error_mark_node 12159 && parser->tokens_avail != 2) 12160 { 12161 if (array_section_p) 12162 { 12163 error_at (c_parser_peek_token (parser)->location, 12164 "expected %<)%> or %<,%>"); 12165 t = error_mark_node; 12166 } 12167 else 12168 { 12169 parser->tokens = tokens.address (); 12170 parser->tokens_avail = tokens.length (); 12171 12172 t = c_parser_expr_no_commas (parser, NULL).value; 12173 if (t != error_mark_node && parser->tokens_avail != 2) 12174 { 12175 error_at (c_parser_peek_token (parser)->location, 12176 "expected %<)%> or %<,%>"); 12177 t = error_mark_node; 12178 } 12179 } 12180 } 12181 break; 12182 default: 12183 break; 12184 } 12185 12186 if (t != error_mark_node) 12187 { 12188 tree u = build_omp_clause (clause_loc, kind); 12189 OMP_CLAUSE_DECL (u) = t; 12190 OMP_CLAUSE_CHAIN (u) = list; 12191 list = u; 12192 } 12193 } 12194 else 12195 list = tree_cons (t, NULL_TREE, list); 12196 12197 if (kind == OMP_CLAUSE_DEPEND) 12198 { 12199 parser->tokens = &parser->tokens_buf[0]; 12200 parser->tokens_avail = tokens_avail; 12201 } 12202 if (c_parser_next_token_is_not (parser, CPP_COMMA)) 12203 break; 12204 12205 c_parser_consume_token (parser); 12206 first = false; 12207 } 12208 12209 return list; 12210 } 12211 12212 /* Similarly, but expect leading and trailing parenthesis. This is a very 12213 common case for OpenACC and OpenMP clauses. */ 12214 12215 static tree 12216 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind, 12217 tree list) 12218 { 12219 /* The clauses location. */ 12220 location_t loc = c_parser_peek_token (parser)->location; 12221 12222 matching_parens parens; 12223 if (parens.require_open (parser)) 12224 { 12225 list = c_parser_omp_variable_list (parser, loc, kind, list); 12226 parens.skip_until_found_close (parser); 12227 } 12228 return list; 12229 } 12230 12231 /* OpenACC 2.0: 12232 copy ( variable-list ) 12233 copyin ( variable-list ) 12234 copyout ( variable-list ) 12235 create ( variable-list ) 12236 delete ( variable-list ) 12237 present ( variable-list ) */ 12238 12239 static tree 12240 c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind, 12241 tree list) 12242 { 12243 enum gomp_map_kind kind; 12244 switch (c_kind) 12245 { 12246 case PRAGMA_OACC_CLAUSE_COPY: 12247 kind = GOMP_MAP_TOFROM; 12248 break; 12249 case PRAGMA_OACC_CLAUSE_COPYIN: 12250 kind = GOMP_MAP_TO; 12251 break; 12252 case PRAGMA_OACC_CLAUSE_COPYOUT: 12253 kind = GOMP_MAP_FROM; 12254 break; 12255 case PRAGMA_OACC_CLAUSE_CREATE: 12256 kind = GOMP_MAP_ALLOC; 12257 break; 12258 case PRAGMA_OACC_CLAUSE_DELETE: 12259 kind = GOMP_MAP_RELEASE; 12260 break; 12261 case PRAGMA_OACC_CLAUSE_DEVICE: 12262 kind = GOMP_MAP_FORCE_TO; 12263 break; 12264 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT: 12265 kind = GOMP_MAP_DEVICE_RESIDENT; 12266 break; 12267 case PRAGMA_OACC_CLAUSE_HOST: 12268 kind = GOMP_MAP_FORCE_FROM; 12269 break; 12270 case PRAGMA_OACC_CLAUSE_LINK: 12271 kind = GOMP_MAP_LINK; 12272 break; 12273 case PRAGMA_OACC_CLAUSE_PRESENT: 12274 kind = GOMP_MAP_FORCE_PRESENT; 12275 break; 12276 default: 12277 gcc_unreachable (); 12278 } 12279 tree nl, c; 12280 nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list); 12281 12282 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) 12283 OMP_CLAUSE_SET_MAP_KIND (c, kind); 12284 12285 return nl; 12286 } 12287 12288 /* OpenACC 2.0: 12289 deviceptr ( variable-list ) */ 12290 12291 static tree 12292 c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list) 12293 { 12294 location_t loc = c_parser_peek_token (parser)->location; 12295 tree vars, t; 12296 12297 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic 12298 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR, 12299 variable-list must only allow for pointer variables. */ 12300 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL); 12301 for (t = vars; t && t; t = TREE_CHAIN (t)) 12302 { 12303 tree v = TREE_PURPOSE (t); 12304 12305 /* FIXME diagnostics: Ideally we should keep individual 12306 locations for all the variables in the var list to make the 12307 following errors more precise. Perhaps 12308 c_parser_omp_var_list_parens() should construct a list of 12309 locations to go along with the var list. */ 12310 12311 if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL) 12312 error_at (loc, "%qD is not a variable", v); 12313 else if (TREE_TYPE (v) == error_mark_node) 12314 ; 12315 else if (!POINTER_TYPE_P (TREE_TYPE (v))) 12316 error_at (loc, "%qD is not a pointer variable", v); 12317 12318 tree u = build_omp_clause (loc, OMP_CLAUSE_MAP); 12319 OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR); 12320 OMP_CLAUSE_DECL (u) = v; 12321 OMP_CLAUSE_CHAIN (u) = list; 12322 list = u; 12323 } 12324 12325 return list; 12326 } 12327 12328 /* OpenACC 2.0, OpenMP 3.0: 12329 collapse ( constant-expression ) */ 12330 12331 static tree 12332 c_parser_omp_clause_collapse (c_parser *parser, tree list) 12333 { 12334 tree c, num = error_mark_node; 12335 HOST_WIDE_INT n; 12336 location_t loc; 12337 12338 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse"); 12339 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile"); 12340 12341 loc = c_parser_peek_token (parser)->location; 12342 matching_parens parens; 12343 if (parens.require_open (parser)) 12344 { 12345 num = c_parser_expr_no_commas (parser, NULL).value; 12346 parens.skip_until_found_close (parser); 12347 } 12348 if (num == error_mark_node) 12349 return list; 12350 mark_exp_read (num); 12351 num = c_fully_fold (num, false, NULL); 12352 if (!INTEGRAL_TYPE_P (TREE_TYPE (num)) 12353 || !tree_fits_shwi_p (num) 12354 || (n = tree_to_shwi (num)) <= 0 12355 || (int) n != n) 12356 { 12357 error_at (loc, 12358 "collapse argument needs positive constant integer expression"); 12359 return list; 12360 } 12361 c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE); 12362 OMP_CLAUSE_COLLAPSE_EXPR (c) = num; 12363 OMP_CLAUSE_CHAIN (c) = list; 12364 return c; 12365 } 12366 12367 /* OpenMP 2.5: 12368 copyin ( variable-list ) */ 12369 12370 static tree 12371 c_parser_omp_clause_copyin (c_parser *parser, tree list) 12372 { 12373 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list); 12374 } 12375 12376 /* OpenMP 2.5: 12377 copyprivate ( variable-list ) */ 12378 12379 static tree 12380 c_parser_omp_clause_copyprivate (c_parser *parser, tree list) 12381 { 12382 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list); 12383 } 12384 12385 /* OpenMP 2.5: 12386 default ( none | shared ) 12387 12388 OpenACC: 12389 default ( none | present ) */ 12390 12391 static tree 12392 c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc) 12393 { 12394 enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED; 12395 location_t loc = c_parser_peek_token (parser)->location; 12396 tree c; 12397 12398 matching_parens parens; 12399 if (!parens.require_open (parser)) 12400 return list; 12401 if (c_parser_next_token_is (parser, CPP_NAME)) 12402 { 12403 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 12404 12405 switch (p[0]) 12406 { 12407 case 'n': 12408 if (strcmp ("none", p) != 0) 12409 goto invalid_kind; 12410 kind = OMP_CLAUSE_DEFAULT_NONE; 12411 break; 12412 12413 case 'p': 12414 if (strcmp ("present", p) != 0 || !is_oacc) 12415 goto invalid_kind; 12416 kind = OMP_CLAUSE_DEFAULT_PRESENT; 12417 break; 12418 12419 case 's': 12420 if (strcmp ("shared", p) != 0 || is_oacc) 12421 goto invalid_kind; 12422 kind = OMP_CLAUSE_DEFAULT_SHARED; 12423 break; 12424 12425 default: 12426 goto invalid_kind; 12427 } 12428 12429 c_parser_consume_token (parser); 12430 } 12431 else 12432 { 12433 invalid_kind: 12434 if (is_oacc) 12435 c_parser_error (parser, "expected %<none%> or %<present%>"); 12436 else 12437 c_parser_error (parser, "expected %<none%> or %<shared%>"); 12438 } 12439 parens.skip_until_found_close (parser); 12440 12441 if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED) 12442 return list; 12443 12444 check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default"); 12445 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT); 12446 OMP_CLAUSE_CHAIN (c) = list; 12447 OMP_CLAUSE_DEFAULT_KIND (c) = kind; 12448 12449 return c; 12450 } 12451 12452 /* OpenMP 2.5: 12453 firstprivate ( variable-list ) */ 12454 12455 static tree 12456 c_parser_omp_clause_firstprivate (c_parser *parser, tree list) 12457 { 12458 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list); 12459 } 12460 12461 /* OpenMP 3.1: 12462 final ( expression ) */ 12463 12464 static tree 12465 c_parser_omp_clause_final (c_parser *parser, tree list) 12466 { 12467 location_t loc = c_parser_peek_token (parser)->location; 12468 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 12469 { 12470 matching_parens parens; 12471 tree t, c; 12472 if (!parens.require_open (parser)) 12473 t = error_mark_node; 12474 else 12475 { 12476 location_t eloc = c_parser_peek_token (parser)->location; 12477 c_expr expr = c_parser_expr_no_commas (parser, NULL); 12478 t = convert_lvalue_to_rvalue (eloc, expr, true, true).value; 12479 t = c_objc_common_truthvalue_conversion (eloc, t); 12480 t = c_fully_fold (t, false, NULL); 12481 parens.skip_until_found_close (parser); 12482 } 12483 12484 check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final"); 12485 12486 c = build_omp_clause (loc, OMP_CLAUSE_FINAL); 12487 OMP_CLAUSE_FINAL_EXPR (c) = t; 12488 OMP_CLAUSE_CHAIN (c) = list; 12489 list = c; 12490 } 12491 else 12492 c_parser_error (parser, "expected %<(%>"); 12493 12494 return list; 12495 } 12496 12497 /* OpenACC, OpenMP 2.5: 12498 if ( expression ) 12499 12500 OpenMP 4.5: 12501 if ( directive-name-modifier : expression ) 12502 12503 directive-name-modifier: 12504 parallel | task | taskloop | target data | target | target update 12505 | target enter data | target exit data 12506 12507 OpenMP 5.0: 12508 directive-name-modifier: 12509 ... | simd | cancel */ 12510 12511 static tree 12512 c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp) 12513 { 12514 location_t location = c_parser_peek_token (parser)->location; 12515 enum tree_code if_modifier = ERROR_MARK; 12516 12517 matching_parens parens; 12518 if (!parens.require_open (parser)) 12519 return list; 12520 12521 if (is_omp && c_parser_next_token_is (parser, CPP_NAME)) 12522 { 12523 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 12524 int n = 2; 12525 if (strcmp (p, "cancel") == 0) 12526 if_modifier = VOID_CST; 12527 else if (strcmp (p, "parallel") == 0) 12528 if_modifier = OMP_PARALLEL; 12529 else if (strcmp (p, "simd") == 0) 12530 if_modifier = OMP_SIMD; 12531 else if (strcmp (p, "task") == 0) 12532 if_modifier = OMP_TASK; 12533 else if (strcmp (p, "taskloop") == 0) 12534 if_modifier = OMP_TASKLOOP; 12535 else if (strcmp (p, "target") == 0) 12536 { 12537 if_modifier = OMP_TARGET; 12538 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME) 12539 { 12540 p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value); 12541 if (strcmp ("data", p) == 0) 12542 if_modifier = OMP_TARGET_DATA; 12543 else if (strcmp ("update", p) == 0) 12544 if_modifier = OMP_TARGET_UPDATE; 12545 else if (strcmp ("enter", p) == 0) 12546 if_modifier = OMP_TARGET_ENTER_DATA; 12547 else if (strcmp ("exit", p) == 0) 12548 if_modifier = OMP_TARGET_EXIT_DATA; 12549 if (if_modifier != OMP_TARGET) 12550 { 12551 n = 3; 12552 c_parser_consume_token (parser); 12553 } 12554 else 12555 { 12556 location_t loc = c_parser_peek_2nd_token (parser)->location; 12557 error_at (loc, "expected %<data%>, %<update%>, %<enter%> " 12558 "or %<exit%>"); 12559 if_modifier = ERROR_MARK; 12560 } 12561 if (if_modifier == OMP_TARGET_ENTER_DATA 12562 || if_modifier == OMP_TARGET_EXIT_DATA) 12563 { 12564 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME) 12565 { 12566 p = IDENTIFIER_POINTER 12567 (c_parser_peek_2nd_token (parser)->value); 12568 if (strcmp ("data", p) == 0) 12569 n = 4; 12570 } 12571 if (n == 4) 12572 c_parser_consume_token (parser); 12573 else 12574 { 12575 location_t loc 12576 = c_parser_peek_2nd_token (parser)->location; 12577 error_at (loc, "expected %<data%>"); 12578 if_modifier = ERROR_MARK; 12579 } 12580 } 12581 } 12582 } 12583 if (if_modifier != ERROR_MARK) 12584 { 12585 if (c_parser_peek_2nd_token (parser)->type == CPP_COLON) 12586 { 12587 c_parser_consume_token (parser); 12588 c_parser_consume_token (parser); 12589 } 12590 else 12591 { 12592 if (n > 2) 12593 { 12594 location_t loc = c_parser_peek_2nd_token (parser)->location; 12595 error_at (loc, "expected %<:%>"); 12596 } 12597 if_modifier = ERROR_MARK; 12598 } 12599 } 12600 } 12601 12602 location_t loc = c_parser_peek_token (parser)->location; 12603 c_expr expr = c_parser_expr_no_commas (parser, NULL); 12604 expr = convert_lvalue_to_rvalue (loc, expr, true, true); 12605 tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c; 12606 t = c_fully_fold (t, false, NULL); 12607 parens.skip_until_found_close (parser); 12608 12609 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c)) 12610 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF) 12611 { 12612 if (if_modifier != ERROR_MARK 12613 && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier) 12614 { 12615 const char *p = NULL; 12616 switch (if_modifier) 12617 { 12618 case VOID_CST: p = "cancel"; break; 12619 case OMP_PARALLEL: p = "parallel"; break; 12620 case OMP_SIMD: p = "simd"; break; 12621 case OMP_TASK: p = "task"; break; 12622 case OMP_TASKLOOP: p = "taskloop"; break; 12623 case OMP_TARGET_DATA: p = "target data"; break; 12624 case OMP_TARGET: p = "target"; break; 12625 case OMP_TARGET_UPDATE: p = "target update"; break; 12626 case OMP_TARGET_ENTER_DATA: p = "enter data"; break; 12627 case OMP_TARGET_EXIT_DATA: p = "exit data"; break; 12628 default: gcc_unreachable (); 12629 } 12630 error_at (location, "too many %<if%> clauses with %qs modifier", 12631 p); 12632 return list; 12633 } 12634 else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier) 12635 { 12636 if (!is_omp) 12637 error_at (location, "too many %<if%> clauses"); 12638 else 12639 error_at (location, "too many %<if%> clauses without modifier"); 12640 return list; 12641 } 12642 else if (if_modifier == ERROR_MARK 12643 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK) 12644 { 12645 error_at (location, "if any %<if%> clause has modifier, then all " 12646 "%<if%> clauses have to use modifier"); 12647 return list; 12648 } 12649 } 12650 12651 c = build_omp_clause (location, OMP_CLAUSE_IF); 12652 OMP_CLAUSE_IF_MODIFIER (c) = if_modifier; 12653 OMP_CLAUSE_IF_EXPR (c) = t; 12654 OMP_CLAUSE_CHAIN (c) = list; 12655 return c; 12656 } 12657 12658 /* OpenMP 2.5: 12659 lastprivate ( variable-list ) 12660 12661 OpenMP 5.0: 12662 lastprivate ( [ lastprivate-modifier : ] variable-list ) */ 12663 12664 static tree 12665 c_parser_omp_clause_lastprivate (c_parser *parser, tree list) 12666 { 12667 /* The clauses location. */ 12668 location_t loc = c_parser_peek_token (parser)->location; 12669 12670 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 12671 { 12672 bool conditional = false; 12673 if (c_parser_next_token_is (parser, CPP_NAME) 12674 && c_parser_peek_2nd_token (parser)->type == CPP_COLON) 12675 { 12676 const char *p 12677 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 12678 if (strcmp (p, "conditional") == 0) 12679 { 12680 conditional = true; 12681 c_parser_consume_token (parser); 12682 c_parser_consume_token (parser); 12683 } 12684 } 12685 tree nlist = c_parser_omp_variable_list (parser, loc, 12686 OMP_CLAUSE_LASTPRIVATE, list); 12687 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 12688 if (conditional) 12689 for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c)) 12690 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1; 12691 return nlist; 12692 } 12693 return list; 12694 } 12695 12696 /* OpenMP 3.1: 12697 mergeable */ 12698 12699 static tree 12700 c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list) 12701 { 12702 tree c; 12703 12704 /* FIXME: Should we allow duplicates? */ 12705 check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable"); 12706 12707 c = build_omp_clause (c_parser_peek_token (parser)->location, 12708 OMP_CLAUSE_MERGEABLE); 12709 OMP_CLAUSE_CHAIN (c) = list; 12710 12711 return c; 12712 } 12713 12714 /* OpenMP 2.5: 12715 nowait */ 12716 12717 static tree 12718 c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list) 12719 { 12720 tree c; 12721 location_t loc = c_parser_peek_token (parser)->location; 12722 12723 check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait"); 12724 12725 c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT); 12726 OMP_CLAUSE_CHAIN (c) = list; 12727 return c; 12728 } 12729 12730 /* OpenMP 2.5: 12731 num_threads ( expression ) */ 12732 12733 static tree 12734 c_parser_omp_clause_num_threads (c_parser *parser, tree list) 12735 { 12736 location_t num_threads_loc = c_parser_peek_token (parser)->location; 12737 matching_parens parens; 12738 if (parens.require_open (parser)) 12739 { 12740 location_t expr_loc = c_parser_peek_token (parser)->location; 12741 c_expr expr = c_parser_expr_no_commas (parser, NULL); 12742 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 12743 tree c, t = expr.value; 12744 t = c_fully_fold (t, false, NULL); 12745 12746 parens.skip_until_found_close (parser); 12747 12748 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 12749 { 12750 c_parser_error (parser, "expected integer expression"); 12751 return list; 12752 } 12753 12754 /* Attempt to statically determine when the number isn't positive. */ 12755 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t, 12756 build_int_cst (TREE_TYPE (t), 0)); 12757 protected_set_expr_location (c, expr_loc); 12758 if (c == boolean_true_node) 12759 { 12760 warning_at (expr_loc, 0, 12761 "%<num_threads%> value must be positive"); 12762 t = integer_one_node; 12763 } 12764 12765 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads"); 12766 12767 c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS); 12768 OMP_CLAUSE_NUM_THREADS_EXPR (c) = t; 12769 OMP_CLAUSE_CHAIN (c) = list; 12770 list = c; 12771 } 12772 12773 return list; 12774 } 12775 12776 /* OpenMP 4.5: 12777 num_tasks ( expression ) */ 12778 12779 static tree 12780 c_parser_omp_clause_num_tasks (c_parser *parser, tree list) 12781 { 12782 location_t num_tasks_loc = c_parser_peek_token (parser)->location; 12783 matching_parens parens; 12784 if (parens.require_open (parser)) 12785 { 12786 location_t expr_loc = c_parser_peek_token (parser)->location; 12787 c_expr expr = c_parser_expr_no_commas (parser, NULL); 12788 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 12789 tree c, t = expr.value; 12790 t = c_fully_fold (t, false, NULL); 12791 12792 parens.skip_until_found_close (parser); 12793 12794 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 12795 { 12796 c_parser_error (parser, "expected integer expression"); 12797 return list; 12798 } 12799 12800 /* Attempt to statically determine when the number isn't positive. */ 12801 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t, 12802 build_int_cst (TREE_TYPE (t), 0)); 12803 if (CAN_HAVE_LOCATION_P (c)) 12804 SET_EXPR_LOCATION (c, expr_loc); 12805 if (c == boolean_true_node) 12806 { 12807 warning_at (expr_loc, 0, "%<num_tasks%> value must be positive"); 12808 t = integer_one_node; 12809 } 12810 12811 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks"); 12812 12813 c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS); 12814 OMP_CLAUSE_NUM_TASKS_EXPR (c) = t; 12815 OMP_CLAUSE_CHAIN (c) = list; 12816 list = c; 12817 } 12818 12819 return list; 12820 } 12821 12822 /* OpenMP 4.5: 12823 grainsize ( expression ) */ 12824 12825 static tree 12826 c_parser_omp_clause_grainsize (c_parser *parser, tree list) 12827 { 12828 location_t grainsize_loc = c_parser_peek_token (parser)->location; 12829 matching_parens parens; 12830 if (parens.require_open (parser)) 12831 { 12832 location_t expr_loc = c_parser_peek_token (parser)->location; 12833 c_expr expr = c_parser_expr_no_commas (parser, NULL); 12834 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 12835 tree c, t = expr.value; 12836 t = c_fully_fold (t, false, NULL); 12837 12838 parens.skip_until_found_close (parser); 12839 12840 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 12841 { 12842 c_parser_error (parser, "expected integer expression"); 12843 return list; 12844 } 12845 12846 /* Attempt to statically determine when the number isn't positive. */ 12847 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t, 12848 build_int_cst (TREE_TYPE (t), 0)); 12849 if (CAN_HAVE_LOCATION_P (c)) 12850 SET_EXPR_LOCATION (c, expr_loc); 12851 if (c == boolean_true_node) 12852 { 12853 warning_at (expr_loc, 0, "%<grainsize%> value must be positive"); 12854 t = integer_one_node; 12855 } 12856 12857 check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize"); 12858 12859 c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE); 12860 OMP_CLAUSE_GRAINSIZE_EXPR (c) = t; 12861 OMP_CLAUSE_CHAIN (c) = list; 12862 list = c; 12863 } 12864 12865 return list; 12866 } 12867 12868 /* OpenMP 4.5: 12869 priority ( expression ) */ 12870 12871 static tree 12872 c_parser_omp_clause_priority (c_parser *parser, tree list) 12873 { 12874 location_t priority_loc = c_parser_peek_token (parser)->location; 12875 matching_parens parens; 12876 if (parens.require_open (parser)) 12877 { 12878 location_t expr_loc = c_parser_peek_token (parser)->location; 12879 c_expr expr = c_parser_expr_no_commas (parser, NULL); 12880 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 12881 tree c, t = expr.value; 12882 t = c_fully_fold (t, false, NULL); 12883 12884 parens.skip_until_found_close (parser); 12885 12886 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 12887 { 12888 c_parser_error (parser, "expected integer expression"); 12889 return list; 12890 } 12891 12892 /* Attempt to statically determine when the number isn't 12893 non-negative. */ 12894 c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t, 12895 build_int_cst (TREE_TYPE (t), 0)); 12896 if (CAN_HAVE_LOCATION_P (c)) 12897 SET_EXPR_LOCATION (c, expr_loc); 12898 if (c == boolean_true_node) 12899 { 12900 warning_at (expr_loc, 0, "%<priority%> value must be non-negative"); 12901 t = integer_one_node; 12902 } 12903 12904 check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority"); 12905 12906 c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY); 12907 OMP_CLAUSE_PRIORITY_EXPR (c) = t; 12908 OMP_CLAUSE_CHAIN (c) = list; 12909 list = c; 12910 } 12911 12912 return list; 12913 } 12914 12915 /* OpenMP 4.5: 12916 hint ( expression ) */ 12917 12918 static tree 12919 c_parser_omp_clause_hint (c_parser *parser, tree list) 12920 { 12921 location_t hint_loc = c_parser_peek_token (parser)->location; 12922 matching_parens parens; 12923 if (parens.require_open (parser)) 12924 { 12925 location_t expr_loc = c_parser_peek_token (parser)->location; 12926 c_expr expr = c_parser_expr_no_commas (parser, NULL); 12927 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 12928 tree c, t = expr.value; 12929 t = c_fully_fold (t, false, NULL); 12930 12931 parens.skip_until_found_close (parser); 12932 12933 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)) 12934 || TREE_CODE (t) != INTEGER_CST) 12935 { 12936 c_parser_error (parser, "expected constant integer expression"); 12937 return list; 12938 } 12939 12940 check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint"); 12941 12942 c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT); 12943 OMP_CLAUSE_HINT_EXPR (c) = t; 12944 OMP_CLAUSE_CHAIN (c) = list; 12945 list = c; 12946 } 12947 12948 return list; 12949 } 12950 12951 /* OpenMP 4.5: 12952 defaultmap ( tofrom : scalar ) 12953 12954 OpenMP 5.0: 12955 defaultmap ( implicit-behavior [ : variable-category ] ) */ 12956 12957 static tree 12958 c_parser_omp_clause_defaultmap (c_parser *parser, tree list) 12959 { 12960 location_t loc = c_parser_peek_token (parser)->location; 12961 tree c; 12962 const char *p; 12963 enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT; 12964 enum omp_clause_defaultmap_kind category 12965 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED; 12966 12967 matching_parens parens; 12968 if (!parens.require_open (parser)) 12969 return list; 12970 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)) 12971 p = "default"; 12972 else if (!c_parser_next_token_is (parser, CPP_NAME)) 12973 { 12974 invalid_behavior: 12975 c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, " 12976 "%<tofrom%>, %<firstprivate%>, %<none%> " 12977 "or %<default%>"); 12978 goto out_err; 12979 } 12980 else 12981 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 12982 12983 switch (p[0]) 12984 { 12985 case 'a': 12986 if (strcmp ("alloc", p) == 0) 12987 behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC; 12988 else 12989 goto invalid_behavior; 12990 break; 12991 12992 case 'd': 12993 if (strcmp ("default", p) == 0) 12994 behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT; 12995 else 12996 goto invalid_behavior; 12997 break; 12998 12999 case 'f': 13000 if (strcmp ("firstprivate", p) == 0) 13001 behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE; 13002 else if (strcmp ("from", p) == 0) 13003 behavior = OMP_CLAUSE_DEFAULTMAP_FROM; 13004 else 13005 goto invalid_behavior; 13006 break; 13007 13008 case 'n': 13009 if (strcmp ("none", p) == 0) 13010 behavior = OMP_CLAUSE_DEFAULTMAP_NONE; 13011 else 13012 goto invalid_behavior; 13013 break; 13014 13015 case 't': 13016 if (strcmp ("tofrom", p) == 0) 13017 behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM; 13018 else if (strcmp ("to", p) == 0) 13019 behavior = OMP_CLAUSE_DEFAULTMAP_TO; 13020 else 13021 goto invalid_behavior; 13022 break; 13023 13024 default: 13025 goto invalid_behavior; 13026 } 13027 c_parser_consume_token (parser); 13028 13029 if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 13030 { 13031 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 13032 goto out_err; 13033 if (!c_parser_next_token_is (parser, CPP_NAME)) 13034 { 13035 invalid_category: 13036 c_parser_error (parser, "expected %<scalar%>, %<aggregate%> or " 13037 "%<pointer%>"); 13038 goto out_err; 13039 } 13040 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 13041 switch (p[0]) 13042 { 13043 case 'a': 13044 if (strcmp ("aggregate", p) == 0) 13045 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE; 13046 else 13047 goto invalid_category; 13048 break; 13049 13050 case 'p': 13051 if (strcmp ("pointer", p) == 0) 13052 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER; 13053 else 13054 goto invalid_category; 13055 break; 13056 13057 case 's': 13058 if (strcmp ("scalar", p) == 0) 13059 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR; 13060 else 13061 goto invalid_category; 13062 break; 13063 13064 default: 13065 goto invalid_category; 13066 } 13067 13068 c_parser_consume_token (parser); 13069 } 13070 parens.skip_until_found_close (parser); 13071 13072 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c)) 13073 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP 13074 && (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED 13075 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category 13076 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) 13077 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED))) 13078 { 13079 enum omp_clause_defaultmap_kind cat = category; 13080 location_t loc = OMP_CLAUSE_LOCATION (c); 13081 if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED) 13082 cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c); 13083 p = NULL; 13084 switch (cat) 13085 { 13086 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED: 13087 p = NULL; 13088 break; 13089 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE: 13090 p = "aggregate"; 13091 break; 13092 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER: 13093 p = "pointer"; 13094 break; 13095 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR: 13096 p = "scalar"; 13097 break; 13098 default: 13099 gcc_unreachable (); 13100 } 13101 if (p) 13102 error_at (loc, "too many %<defaultmap%> clauses with %qs category", 13103 p); 13104 else 13105 error_at (loc, "too many %<defaultmap%> clauses with unspecified " 13106 "category"); 13107 break; 13108 } 13109 13110 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP); 13111 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category); 13112 OMP_CLAUSE_CHAIN (c) = list; 13113 return c; 13114 13115 out_err: 13116 parens.skip_until_found_close (parser); 13117 return list; 13118 } 13119 13120 /* OpenACC 2.0: 13121 use_device ( variable-list ) 13122 13123 OpenMP 4.5: 13124 use_device_ptr ( variable-list ) */ 13125 13126 static tree 13127 c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list) 13128 { 13129 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR, 13130 list); 13131 } 13132 13133 /* OpenMP 4.5: 13134 is_device_ptr ( variable-list ) */ 13135 13136 static tree 13137 c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list) 13138 { 13139 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list); 13140 } 13141 13142 /* OpenACC: 13143 num_gangs ( expression ) 13144 num_workers ( expression ) 13145 vector_length ( expression ) */ 13146 13147 static tree 13148 c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code, 13149 tree list) 13150 { 13151 location_t loc = c_parser_peek_token (parser)->location; 13152 13153 matching_parens parens; 13154 if (!parens.require_open (parser)) 13155 return list; 13156 13157 location_t expr_loc = c_parser_peek_token (parser)->location; 13158 c_expr expr = c_parser_expression (parser); 13159 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 13160 tree c, t = expr.value; 13161 t = c_fully_fold (t, false, NULL); 13162 13163 parens.skip_until_found_close (parser); 13164 13165 if (t == error_mark_node) 13166 return list; 13167 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 13168 { 13169 error_at (expr_loc, "%qs expression must be integral", 13170 omp_clause_code_name[code]); 13171 return list; 13172 } 13173 13174 /* Attempt to statically determine when the number isn't positive. */ 13175 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t, 13176 build_int_cst (TREE_TYPE (t), 0)); 13177 protected_set_expr_location (c, expr_loc); 13178 if (c == boolean_true_node) 13179 { 13180 warning_at (expr_loc, 0, 13181 "%qs value must be positive", 13182 omp_clause_code_name[code]); 13183 t = integer_one_node; 13184 } 13185 13186 check_no_duplicate_clause (list, code, omp_clause_code_name[code]); 13187 13188 c = build_omp_clause (loc, code); 13189 OMP_CLAUSE_OPERAND (c, 0) = t; 13190 OMP_CLAUSE_CHAIN (c) = list; 13191 return c; 13192 } 13193 13194 /* OpenACC: 13195 13196 gang [( gang-arg-list )] 13197 worker [( [num:] int-expr )] 13198 vector [( [length:] int-expr )] 13199 13200 where gang-arg is one of: 13201 13202 [num:] int-expr 13203 static: size-expr 13204 13205 and size-expr may be: 13206 13207 * 13208 int-expr 13209 */ 13210 13211 static tree 13212 c_parser_oacc_shape_clause (c_parser *parser, location_t loc, 13213 omp_clause_code kind, 13214 const char *str, tree list) 13215 { 13216 const char *id = "num"; 13217 tree ops[2] = { NULL_TREE, NULL_TREE }, c; 13218 13219 if (kind == OMP_CLAUSE_VECTOR) 13220 id = "length"; 13221 13222 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 13223 { 13224 c_parser_consume_token (parser); 13225 13226 do 13227 { 13228 c_token *next = c_parser_peek_token (parser); 13229 int idx = 0; 13230 13231 /* Gang static argument. */ 13232 if (kind == OMP_CLAUSE_GANG 13233 && c_parser_next_token_is_keyword (parser, RID_STATIC)) 13234 { 13235 c_parser_consume_token (parser); 13236 13237 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 13238 goto cleanup_error; 13239 13240 idx = 1; 13241 if (ops[idx] != NULL_TREE) 13242 { 13243 c_parser_error (parser, "too many %<static%> arguments"); 13244 goto cleanup_error; 13245 } 13246 13247 /* Check for the '*' argument. */ 13248 if (c_parser_next_token_is (parser, CPP_MULT) 13249 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA 13250 || c_parser_peek_2nd_token (parser)->type 13251 == CPP_CLOSE_PAREN)) 13252 { 13253 c_parser_consume_token (parser); 13254 ops[idx] = integer_minus_one_node; 13255 13256 if (c_parser_next_token_is (parser, CPP_COMMA)) 13257 { 13258 c_parser_consume_token (parser); 13259 continue; 13260 } 13261 else 13262 break; 13263 } 13264 } 13265 /* Worker num: argument and vector length: arguments. */ 13266 else if (c_parser_next_token_is (parser, CPP_NAME) 13267 && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0 13268 && c_parser_peek_2nd_token (parser)->type == CPP_COLON) 13269 { 13270 c_parser_consume_token (parser); /* id */ 13271 c_parser_consume_token (parser); /* ':' */ 13272 } 13273 13274 /* Now collect the actual argument. */ 13275 if (ops[idx] != NULL_TREE) 13276 { 13277 c_parser_error (parser, "unexpected argument"); 13278 goto cleanup_error; 13279 } 13280 13281 location_t expr_loc = c_parser_peek_token (parser)->location; 13282 c_expr cexpr = c_parser_expr_no_commas (parser, NULL); 13283 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true); 13284 tree expr = cexpr.value; 13285 if (expr == error_mark_node) 13286 goto cleanup_error; 13287 13288 expr = c_fully_fold (expr, false, NULL); 13289 13290 /* Attempt to statically determine when the number isn't a 13291 positive integer. */ 13292 13293 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))) 13294 { 13295 c_parser_error (parser, "expected integer expression"); 13296 return list; 13297 } 13298 13299 tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr, 13300 build_int_cst (TREE_TYPE (expr), 0)); 13301 if (c == boolean_true_node) 13302 { 13303 warning_at (loc, 0, 13304 "%qs value must be positive", str); 13305 expr = integer_one_node; 13306 } 13307 13308 ops[idx] = expr; 13309 13310 if (kind == OMP_CLAUSE_GANG 13311 && c_parser_next_token_is (parser, CPP_COMMA)) 13312 { 13313 c_parser_consume_token (parser); 13314 continue; 13315 } 13316 break; 13317 } 13318 while (1); 13319 13320 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) 13321 goto cleanup_error; 13322 } 13323 13324 check_no_duplicate_clause (list, kind, str); 13325 13326 c = build_omp_clause (loc, kind); 13327 13328 if (ops[1]) 13329 OMP_CLAUSE_OPERAND (c, 1) = ops[1]; 13330 13331 OMP_CLAUSE_OPERAND (c, 0) = ops[0]; 13332 OMP_CLAUSE_CHAIN (c) = list; 13333 13334 return c; 13335 13336 cleanup_error: 13337 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0); 13338 return list; 13339 } 13340 13341 /* OpenACC 2.5: 13342 auto 13343 finalize 13344 independent 13345 nohost 13346 seq */ 13347 13348 static tree 13349 c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code, 13350 tree list) 13351 { 13352 check_no_duplicate_clause (list, code, omp_clause_code_name[code]); 13353 13354 tree c = build_omp_clause (loc, code); 13355 OMP_CLAUSE_CHAIN (c) = list; 13356 13357 return c; 13358 } 13359 13360 /* OpenACC: 13361 async [( int-expr )] */ 13362 13363 static tree 13364 c_parser_oacc_clause_async (c_parser *parser, tree list) 13365 { 13366 tree c, t; 13367 location_t loc = c_parser_peek_token (parser)->location; 13368 13369 t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL); 13370 13371 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN) 13372 { 13373 c_parser_consume_token (parser); 13374 13375 t = c_parser_expression (parser).value; 13376 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 13377 c_parser_error (parser, "expected integer expression"); 13378 else if (t == error_mark_node 13379 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) 13380 return list; 13381 } 13382 else 13383 t = c_fully_fold (t, false, NULL); 13384 13385 check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async"); 13386 13387 c = build_omp_clause (loc, OMP_CLAUSE_ASYNC); 13388 OMP_CLAUSE_ASYNC_EXPR (c) = t; 13389 OMP_CLAUSE_CHAIN (c) = list; 13390 list = c; 13391 13392 return list; 13393 } 13394 13395 /* OpenACC 2.0: 13396 tile ( size-expr-list ) */ 13397 13398 static tree 13399 c_parser_oacc_clause_tile (c_parser *parser, tree list) 13400 { 13401 tree c, expr = error_mark_node; 13402 location_t loc; 13403 tree tile = NULL_TREE; 13404 13405 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile"); 13406 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse"); 13407 13408 loc = c_parser_peek_token (parser)->location; 13409 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 13410 return list; 13411 13412 do 13413 { 13414 if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>")) 13415 return list; 13416 13417 if (c_parser_next_token_is (parser, CPP_MULT) 13418 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA 13419 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN)) 13420 { 13421 c_parser_consume_token (parser); 13422 expr = integer_zero_node; 13423 } 13424 else 13425 { 13426 location_t expr_loc = c_parser_peek_token (parser)->location; 13427 c_expr cexpr = c_parser_expr_no_commas (parser, NULL); 13428 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true); 13429 expr = cexpr.value; 13430 13431 if (expr == error_mark_node) 13432 { 13433 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 13434 "expected %<)%>"); 13435 return list; 13436 } 13437 13438 expr = c_fully_fold (expr, false, NULL); 13439 13440 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)) 13441 || !tree_fits_shwi_p (expr) 13442 || tree_to_shwi (expr) <= 0) 13443 { 13444 error_at (expr_loc, "%<tile%> argument needs positive" 13445 " integral constant"); 13446 expr = integer_zero_node; 13447 } 13448 } 13449 13450 tile = tree_cons (NULL_TREE, expr, tile); 13451 } 13452 while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN)); 13453 13454 /* Consume the trailing ')'. */ 13455 c_parser_consume_token (parser); 13456 13457 c = build_omp_clause (loc, OMP_CLAUSE_TILE); 13458 tile = nreverse (tile); 13459 OMP_CLAUSE_TILE_LIST (c) = tile; 13460 OMP_CLAUSE_CHAIN (c) = list; 13461 return c; 13462 } 13463 13464 /* OpenACC: 13465 wait [( int-expr-list )] */ 13466 13467 static tree 13468 c_parser_oacc_clause_wait (c_parser *parser, tree list) 13469 { 13470 location_t clause_loc = c_parser_peek_token (parser)->location; 13471 13472 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN) 13473 list = c_parser_oacc_wait_list (parser, clause_loc, list); 13474 else 13475 { 13476 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT); 13477 13478 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL); 13479 OMP_CLAUSE_CHAIN (c) = list; 13480 list = c; 13481 } 13482 13483 return list; 13484 } 13485 13486 /* OpenMP 2.5: 13487 ordered 13488 13489 OpenMP 4.5: 13490 ordered ( constant-expression ) */ 13491 13492 static tree 13493 c_parser_omp_clause_ordered (c_parser *parser, tree list) 13494 { 13495 check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered"); 13496 13497 tree c, num = NULL_TREE; 13498 HOST_WIDE_INT n; 13499 location_t loc = c_parser_peek_token (parser)->location; 13500 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 13501 { 13502 matching_parens parens; 13503 parens.consume_open (parser); 13504 num = c_parser_expr_no_commas (parser, NULL).value; 13505 parens.skip_until_found_close (parser); 13506 } 13507 if (num == error_mark_node) 13508 return list; 13509 if (num) 13510 { 13511 mark_exp_read (num); 13512 num = c_fully_fold (num, false, NULL); 13513 if (!INTEGRAL_TYPE_P (TREE_TYPE (num)) 13514 || !tree_fits_shwi_p (num) 13515 || (n = tree_to_shwi (num)) <= 0 13516 || (int) n != n) 13517 { 13518 error_at (loc, "ordered argument needs positive " 13519 "constant integer expression"); 13520 return list; 13521 } 13522 } 13523 c = build_omp_clause (loc, OMP_CLAUSE_ORDERED); 13524 OMP_CLAUSE_ORDERED_EXPR (c) = num; 13525 OMP_CLAUSE_CHAIN (c) = list; 13526 return c; 13527 } 13528 13529 /* OpenMP 2.5: 13530 private ( variable-list ) */ 13531 13532 static tree 13533 c_parser_omp_clause_private (c_parser *parser, tree list) 13534 { 13535 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list); 13536 } 13537 13538 /* OpenMP 2.5: 13539 reduction ( reduction-operator : variable-list ) 13540 13541 reduction-operator: 13542 One of: + * - & ^ | && || 13543 13544 OpenMP 3.1: 13545 13546 reduction-operator: 13547 One of: + * - & ^ | && || max min 13548 13549 OpenMP 4.0: 13550 13551 reduction-operator: 13552 One of: + * - & ^ | && || 13553 identifier 13554 13555 OpenMP 5.0: 13556 reduction ( reduction-modifier, reduction-operator : variable-list ) 13557 in_reduction ( reduction-operator : variable-list ) 13558 task_reduction ( reduction-operator : variable-list ) */ 13559 13560 static tree 13561 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind, 13562 bool is_omp, tree list) 13563 { 13564 location_t clause_loc = c_parser_peek_token (parser)->location; 13565 matching_parens parens; 13566 if (parens.require_open (parser)) 13567 { 13568 bool task = false; 13569 bool inscan = false; 13570 enum tree_code code = ERROR_MARK; 13571 tree reduc_id = NULL_TREE; 13572 13573 if (kind == OMP_CLAUSE_REDUCTION && is_omp) 13574 { 13575 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT) 13576 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA) 13577 { 13578 c_parser_consume_token (parser); 13579 c_parser_consume_token (parser); 13580 } 13581 else if (c_parser_next_token_is (parser, CPP_NAME) 13582 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA) 13583 { 13584 const char *p 13585 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 13586 if (strcmp (p, "task") == 0) 13587 task = true; 13588 else if (strcmp (p, "inscan") == 0) 13589 { 13590 inscan = true; 13591 sorry ("%<inscan%> modifier on %<reduction%> clause " 13592 "not supported yet"); 13593 } 13594 if (task || inscan) 13595 { 13596 c_parser_consume_token (parser); 13597 c_parser_consume_token (parser); 13598 } 13599 } 13600 } 13601 13602 switch (c_parser_peek_token (parser)->type) 13603 { 13604 case CPP_PLUS: 13605 code = PLUS_EXPR; 13606 break; 13607 case CPP_MULT: 13608 code = MULT_EXPR; 13609 break; 13610 case CPP_MINUS: 13611 code = MINUS_EXPR; 13612 break; 13613 case CPP_AND: 13614 code = BIT_AND_EXPR; 13615 break; 13616 case CPP_XOR: 13617 code = BIT_XOR_EXPR; 13618 break; 13619 case CPP_OR: 13620 code = BIT_IOR_EXPR; 13621 break; 13622 case CPP_AND_AND: 13623 code = TRUTH_ANDIF_EXPR; 13624 break; 13625 case CPP_OR_OR: 13626 code = TRUTH_ORIF_EXPR; 13627 break; 13628 case CPP_NAME: 13629 { 13630 const char *p 13631 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 13632 if (strcmp (p, "min") == 0) 13633 { 13634 code = MIN_EXPR; 13635 break; 13636 } 13637 if (strcmp (p, "max") == 0) 13638 { 13639 code = MAX_EXPR; 13640 break; 13641 } 13642 reduc_id = c_parser_peek_token (parser)->value; 13643 break; 13644 } 13645 default: 13646 c_parser_error (parser, 13647 "expected %<+%>, %<*%>, %<-%>, %<&%>, " 13648 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier"); 13649 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0); 13650 return list; 13651 } 13652 c_parser_consume_token (parser); 13653 reduc_id = c_omp_reduction_id (code, reduc_id); 13654 if (c_parser_require (parser, CPP_COLON, "expected %<:%>")) 13655 { 13656 tree nl, c; 13657 13658 nl = c_parser_omp_variable_list (parser, clause_loc, kind, list); 13659 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) 13660 { 13661 tree d = OMP_CLAUSE_DECL (c), type; 13662 if (TREE_CODE (d) != TREE_LIST) 13663 type = TREE_TYPE (d); 13664 else 13665 { 13666 int cnt = 0; 13667 tree t; 13668 for (t = d; TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t)) 13669 cnt++; 13670 type = TREE_TYPE (t); 13671 while (cnt > 0) 13672 { 13673 if (TREE_CODE (type) != POINTER_TYPE 13674 && TREE_CODE (type) != ARRAY_TYPE) 13675 break; 13676 type = TREE_TYPE (type); 13677 cnt--; 13678 } 13679 } 13680 while (TREE_CODE (type) == ARRAY_TYPE) 13681 type = TREE_TYPE (type); 13682 OMP_CLAUSE_REDUCTION_CODE (c) = code; 13683 if (task) 13684 OMP_CLAUSE_REDUCTION_TASK (c) = 1; 13685 else if (inscan) 13686 OMP_CLAUSE_REDUCTION_INSCAN (c) = 1; 13687 if (code == ERROR_MARK 13688 || !(INTEGRAL_TYPE_P (type) 13689 || TREE_CODE (type) == REAL_TYPE 13690 || TREE_CODE (type) == COMPLEX_TYPE)) 13691 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) 13692 = c_omp_reduction_lookup (reduc_id, 13693 TYPE_MAIN_VARIANT (type)); 13694 } 13695 13696 list = nl; 13697 } 13698 parens.skip_until_found_close (parser); 13699 } 13700 return list; 13701 } 13702 13703 /* OpenMP 2.5: 13704 schedule ( schedule-kind ) 13705 schedule ( schedule-kind , expression ) 13706 13707 schedule-kind: 13708 static | dynamic | guided | runtime | auto 13709 13710 OpenMP 4.5: 13711 schedule ( schedule-modifier : schedule-kind ) 13712 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression ) 13713 13714 schedule-modifier: 13715 simd 13716 monotonic 13717 nonmonotonic */ 13718 13719 static tree 13720 c_parser_omp_clause_schedule (c_parser *parser, tree list) 13721 { 13722 tree c, t; 13723 location_t loc = c_parser_peek_token (parser)->location; 13724 int modifiers = 0, nmodifiers = 0; 13725 13726 matching_parens parens; 13727 if (!parens.require_open (parser)) 13728 return list; 13729 13730 c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE); 13731 13732 while (c_parser_next_token_is (parser, CPP_NAME)) 13733 { 13734 tree kind = c_parser_peek_token (parser)->value; 13735 const char *p = IDENTIFIER_POINTER (kind); 13736 if (strcmp ("simd", p) == 0) 13737 OMP_CLAUSE_SCHEDULE_SIMD (c) = 1; 13738 else if (strcmp ("monotonic", p) == 0) 13739 modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC; 13740 else if (strcmp ("nonmonotonic", p) == 0) 13741 modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC; 13742 else 13743 break; 13744 c_parser_consume_token (parser); 13745 if (nmodifiers++ == 0 13746 && c_parser_next_token_is (parser, CPP_COMMA)) 13747 c_parser_consume_token (parser); 13748 else 13749 { 13750 c_parser_require (parser, CPP_COLON, "expected %<:%>"); 13751 break; 13752 } 13753 } 13754 13755 if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC 13756 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC)) 13757 == (OMP_CLAUSE_SCHEDULE_MONOTONIC 13758 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC)) 13759 { 13760 error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers " 13761 "specified"); 13762 modifiers = 0; 13763 } 13764 13765 if (c_parser_next_token_is (parser, CPP_NAME)) 13766 { 13767 tree kind = c_parser_peek_token (parser)->value; 13768 const char *p = IDENTIFIER_POINTER (kind); 13769 13770 switch (p[0]) 13771 { 13772 case 'd': 13773 if (strcmp ("dynamic", p) != 0) 13774 goto invalid_kind; 13775 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC; 13776 break; 13777 13778 case 'g': 13779 if (strcmp ("guided", p) != 0) 13780 goto invalid_kind; 13781 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED; 13782 break; 13783 13784 case 'r': 13785 if (strcmp ("runtime", p) != 0) 13786 goto invalid_kind; 13787 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME; 13788 break; 13789 13790 default: 13791 goto invalid_kind; 13792 } 13793 } 13794 else if (c_parser_next_token_is_keyword (parser, RID_STATIC)) 13795 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC; 13796 else if (c_parser_next_token_is_keyword (parser, RID_AUTO)) 13797 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO; 13798 else 13799 goto invalid_kind; 13800 13801 c_parser_consume_token (parser); 13802 if (c_parser_next_token_is (parser, CPP_COMMA)) 13803 { 13804 location_t here; 13805 c_parser_consume_token (parser); 13806 13807 here = c_parser_peek_token (parser)->location; 13808 c_expr expr = c_parser_expr_no_commas (parser, NULL); 13809 expr = convert_lvalue_to_rvalue (here, expr, false, true); 13810 t = expr.value; 13811 t = c_fully_fold (t, false, NULL); 13812 13813 if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME) 13814 error_at (here, "schedule %<runtime%> does not take " 13815 "a %<chunk_size%> parameter"); 13816 else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO) 13817 error_at (here, 13818 "schedule %<auto%> does not take " 13819 "a %<chunk_size%> parameter"); 13820 else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE) 13821 { 13822 /* Attempt to statically determine when the number isn't 13823 positive. */ 13824 tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t, 13825 build_int_cst (TREE_TYPE (t), 0)); 13826 protected_set_expr_location (s, loc); 13827 if (s == boolean_true_node) 13828 { 13829 warning_at (loc, 0, 13830 "chunk size value must be positive"); 13831 t = integer_one_node; 13832 } 13833 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t; 13834 } 13835 else 13836 c_parser_error (parser, "expected integer expression"); 13837 13838 parens.skip_until_found_close (parser); 13839 } 13840 else 13841 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 13842 "expected %<,%> or %<)%>"); 13843 13844 OMP_CLAUSE_SCHEDULE_KIND (c) 13845 = (enum omp_clause_schedule_kind) 13846 (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers); 13847 13848 check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule"); 13849 OMP_CLAUSE_CHAIN (c) = list; 13850 return c; 13851 13852 invalid_kind: 13853 c_parser_error (parser, "invalid schedule kind"); 13854 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0); 13855 return list; 13856 } 13857 13858 /* OpenMP 2.5: 13859 shared ( variable-list ) */ 13860 13861 static tree 13862 c_parser_omp_clause_shared (c_parser *parser, tree list) 13863 { 13864 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list); 13865 } 13866 13867 /* OpenMP 3.0: 13868 untied */ 13869 13870 static tree 13871 c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list) 13872 { 13873 tree c; 13874 13875 /* FIXME: Should we allow duplicates? */ 13876 check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied"); 13877 13878 c = build_omp_clause (c_parser_peek_token (parser)->location, 13879 OMP_CLAUSE_UNTIED); 13880 OMP_CLAUSE_CHAIN (c) = list; 13881 13882 return c; 13883 } 13884 13885 /* OpenMP 4.0: 13886 inbranch 13887 notinbranch */ 13888 13889 static tree 13890 c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED, 13891 enum omp_clause_code code, tree list) 13892 { 13893 check_no_duplicate_clause (list, code, omp_clause_code_name[code]); 13894 13895 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code); 13896 OMP_CLAUSE_CHAIN (c) = list; 13897 13898 return c; 13899 } 13900 13901 /* OpenMP 4.0: 13902 parallel 13903 for 13904 sections 13905 taskgroup */ 13906 13907 static tree 13908 c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED, 13909 enum omp_clause_code code, tree list) 13910 { 13911 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code); 13912 OMP_CLAUSE_CHAIN (c) = list; 13913 13914 return c; 13915 } 13916 13917 /* OpenMP 4.5: 13918 nogroup */ 13919 13920 static tree 13921 c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list) 13922 { 13923 check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup"); 13924 tree c = build_omp_clause (c_parser_peek_token (parser)->location, 13925 OMP_CLAUSE_NOGROUP); 13926 OMP_CLAUSE_CHAIN (c) = list; 13927 return c; 13928 } 13929 13930 /* OpenMP 4.5: 13931 simd 13932 threads */ 13933 13934 static tree 13935 c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED, 13936 enum omp_clause_code code, tree list) 13937 { 13938 check_no_duplicate_clause (list, code, omp_clause_code_name[code]); 13939 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code); 13940 OMP_CLAUSE_CHAIN (c) = list; 13941 return c; 13942 } 13943 13944 /* OpenMP 4.0: 13945 num_teams ( expression ) */ 13946 13947 static tree 13948 c_parser_omp_clause_num_teams (c_parser *parser, tree list) 13949 { 13950 location_t num_teams_loc = c_parser_peek_token (parser)->location; 13951 matching_parens parens; 13952 if (parens.require_open (parser)) 13953 { 13954 location_t expr_loc = c_parser_peek_token (parser)->location; 13955 c_expr expr = c_parser_expr_no_commas (parser, NULL); 13956 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 13957 tree c, t = expr.value; 13958 t = c_fully_fold (t, false, NULL); 13959 13960 parens.skip_until_found_close (parser); 13961 13962 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 13963 { 13964 c_parser_error (parser, "expected integer expression"); 13965 return list; 13966 } 13967 13968 /* Attempt to statically determine when the number isn't positive. */ 13969 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t, 13970 build_int_cst (TREE_TYPE (t), 0)); 13971 protected_set_expr_location (c, expr_loc); 13972 if (c == boolean_true_node) 13973 { 13974 warning_at (expr_loc, 0, "%<num_teams%> value must be positive"); 13975 t = integer_one_node; 13976 } 13977 13978 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams"); 13979 13980 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS); 13981 OMP_CLAUSE_NUM_TEAMS_EXPR (c) = t; 13982 OMP_CLAUSE_CHAIN (c) = list; 13983 list = c; 13984 } 13985 13986 return list; 13987 } 13988 13989 /* OpenMP 4.0: 13990 thread_limit ( expression ) */ 13991 13992 static tree 13993 c_parser_omp_clause_thread_limit (c_parser *parser, tree list) 13994 { 13995 location_t num_thread_limit_loc = c_parser_peek_token (parser)->location; 13996 matching_parens parens; 13997 if (parens.require_open (parser)) 13998 { 13999 location_t expr_loc = c_parser_peek_token (parser)->location; 14000 c_expr expr = c_parser_expr_no_commas (parser, NULL); 14001 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 14002 tree c, t = expr.value; 14003 t = c_fully_fold (t, false, NULL); 14004 14005 parens.skip_until_found_close (parser); 14006 14007 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 14008 { 14009 c_parser_error (parser, "expected integer expression"); 14010 return list; 14011 } 14012 14013 /* Attempt to statically determine when the number isn't positive. */ 14014 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t, 14015 build_int_cst (TREE_TYPE (t), 0)); 14016 protected_set_expr_location (c, expr_loc); 14017 if (c == boolean_true_node) 14018 { 14019 warning_at (expr_loc, 0, "%<thread_limit%> value must be positive"); 14020 t = integer_one_node; 14021 } 14022 14023 check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT, 14024 "thread_limit"); 14025 14026 c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT); 14027 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t; 14028 OMP_CLAUSE_CHAIN (c) = list; 14029 list = c; 14030 } 14031 14032 return list; 14033 } 14034 14035 /* OpenMP 4.0: 14036 aligned ( variable-list ) 14037 aligned ( variable-list : constant-expression ) */ 14038 14039 static tree 14040 c_parser_omp_clause_aligned (c_parser *parser, tree list) 14041 { 14042 location_t clause_loc = c_parser_peek_token (parser)->location; 14043 tree nl, c; 14044 14045 matching_parens parens; 14046 if (!parens.require_open (parser)) 14047 return list; 14048 14049 nl = c_parser_omp_variable_list (parser, clause_loc, 14050 OMP_CLAUSE_ALIGNED, list); 14051 14052 if (c_parser_next_token_is (parser, CPP_COLON)) 14053 { 14054 c_parser_consume_token (parser); 14055 location_t expr_loc = c_parser_peek_token (parser)->location; 14056 c_expr expr = c_parser_expr_no_commas (parser, NULL); 14057 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 14058 tree alignment = expr.value; 14059 alignment = c_fully_fold (alignment, false, NULL); 14060 if (TREE_CODE (alignment) != INTEGER_CST 14061 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment)) 14062 || tree_int_cst_sgn (alignment) != 1) 14063 { 14064 error_at (clause_loc, "%<aligned%> clause alignment expression must " 14065 "be positive constant integer expression"); 14066 alignment = NULL_TREE; 14067 } 14068 14069 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) 14070 OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment; 14071 } 14072 14073 parens.skip_until_found_close (parser); 14074 return nl; 14075 } 14076 14077 /* OpenMP 4.0: 14078 linear ( variable-list ) 14079 linear ( variable-list : expression ) 14080 14081 OpenMP 4.5: 14082 linear ( modifier ( variable-list ) ) 14083 linear ( modifier ( variable-list ) : expression ) */ 14084 14085 static tree 14086 c_parser_omp_clause_linear (c_parser *parser, tree list) 14087 { 14088 location_t clause_loc = c_parser_peek_token (parser)->location; 14089 tree nl, c, step; 14090 enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT; 14091 14092 matching_parens parens; 14093 if (!parens.require_open (parser)) 14094 return list; 14095 14096 if (c_parser_next_token_is (parser, CPP_NAME)) 14097 { 14098 c_token *tok = c_parser_peek_token (parser); 14099 const char *p = IDENTIFIER_POINTER (tok->value); 14100 if (strcmp ("val", p) == 0) 14101 kind = OMP_CLAUSE_LINEAR_VAL; 14102 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN) 14103 kind = OMP_CLAUSE_LINEAR_DEFAULT; 14104 if (kind != OMP_CLAUSE_LINEAR_DEFAULT) 14105 { 14106 c_parser_consume_token (parser); 14107 c_parser_consume_token (parser); 14108 } 14109 } 14110 14111 nl = c_parser_omp_variable_list (parser, clause_loc, 14112 OMP_CLAUSE_LINEAR, list); 14113 14114 if (kind != OMP_CLAUSE_LINEAR_DEFAULT) 14115 parens.skip_until_found_close (parser); 14116 14117 if (c_parser_next_token_is (parser, CPP_COLON)) 14118 { 14119 c_parser_consume_token (parser); 14120 location_t expr_loc = c_parser_peek_token (parser)->location; 14121 c_expr expr = c_parser_expr_no_commas (parser, NULL); 14122 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 14123 step = expr.value; 14124 step = c_fully_fold (step, false, NULL); 14125 if (!INTEGRAL_TYPE_P (TREE_TYPE (step))) 14126 { 14127 error_at (clause_loc, "%<linear%> clause step expression must " 14128 "be integral"); 14129 step = integer_one_node; 14130 } 14131 14132 } 14133 else 14134 step = integer_one_node; 14135 14136 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) 14137 { 14138 OMP_CLAUSE_LINEAR_STEP (c) = step; 14139 OMP_CLAUSE_LINEAR_KIND (c) = kind; 14140 } 14141 14142 parens.skip_until_found_close (parser); 14143 return nl; 14144 } 14145 14146 /* OpenMP 5.0: 14147 nontemporal ( variable-list ) */ 14148 14149 static tree 14150 c_parser_omp_clause_nontemporal (c_parser *parser, tree list) 14151 { 14152 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list); 14153 } 14154 14155 /* OpenMP 4.0: 14156 safelen ( constant-expression ) */ 14157 14158 static tree 14159 c_parser_omp_clause_safelen (c_parser *parser, tree list) 14160 { 14161 location_t clause_loc = c_parser_peek_token (parser)->location; 14162 tree c, t; 14163 14164 matching_parens parens; 14165 if (!parens.require_open (parser)) 14166 return list; 14167 14168 location_t expr_loc = c_parser_peek_token (parser)->location; 14169 c_expr expr = c_parser_expr_no_commas (parser, NULL); 14170 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 14171 t = expr.value; 14172 t = c_fully_fold (t, false, NULL); 14173 if (TREE_CODE (t) != INTEGER_CST 14174 || !INTEGRAL_TYPE_P (TREE_TYPE (t)) 14175 || tree_int_cst_sgn (t) != 1) 14176 { 14177 error_at (clause_loc, "%<safelen%> clause expression must " 14178 "be positive constant integer expression"); 14179 t = NULL_TREE; 14180 } 14181 14182 parens.skip_until_found_close (parser); 14183 if (t == NULL_TREE || t == error_mark_node) 14184 return list; 14185 14186 check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen"); 14187 14188 c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN); 14189 OMP_CLAUSE_SAFELEN_EXPR (c) = t; 14190 OMP_CLAUSE_CHAIN (c) = list; 14191 return c; 14192 } 14193 14194 /* OpenMP 4.0: 14195 simdlen ( constant-expression ) */ 14196 14197 static tree 14198 c_parser_omp_clause_simdlen (c_parser *parser, tree list) 14199 { 14200 location_t clause_loc = c_parser_peek_token (parser)->location; 14201 tree c, t; 14202 14203 matching_parens parens; 14204 if (!parens.require_open (parser)) 14205 return list; 14206 14207 location_t expr_loc = c_parser_peek_token (parser)->location; 14208 c_expr expr = c_parser_expr_no_commas (parser, NULL); 14209 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 14210 t = expr.value; 14211 t = c_fully_fold (t, false, NULL); 14212 if (TREE_CODE (t) != INTEGER_CST 14213 || !INTEGRAL_TYPE_P (TREE_TYPE (t)) 14214 || tree_int_cst_sgn (t) != 1) 14215 { 14216 error_at (clause_loc, "%<simdlen%> clause expression must " 14217 "be positive constant integer expression"); 14218 t = NULL_TREE; 14219 } 14220 14221 parens.skip_until_found_close (parser); 14222 if (t == NULL_TREE || t == error_mark_node) 14223 return list; 14224 14225 check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen"); 14226 14227 c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN); 14228 OMP_CLAUSE_SIMDLEN_EXPR (c) = t; 14229 OMP_CLAUSE_CHAIN (c) = list; 14230 return c; 14231 } 14232 14233 /* OpenMP 4.5: 14234 vec: 14235 identifier [+/- integer] 14236 vec , identifier [+/- integer] 14237 */ 14238 14239 static tree 14240 c_parser_omp_clause_depend_sink (c_parser *parser, location_t clause_loc, 14241 tree list) 14242 { 14243 tree vec = NULL; 14244 if (c_parser_next_token_is_not (parser, CPP_NAME) 14245 || c_parser_peek_token (parser)->id_kind != C_ID_ID) 14246 { 14247 c_parser_error (parser, "expected identifier"); 14248 return list; 14249 } 14250 14251 while (c_parser_next_token_is (parser, CPP_NAME) 14252 && c_parser_peek_token (parser)->id_kind == C_ID_ID) 14253 { 14254 tree t = lookup_name (c_parser_peek_token (parser)->value); 14255 tree addend = NULL; 14256 14257 if (t == NULL_TREE) 14258 { 14259 undeclared_variable (c_parser_peek_token (parser)->location, 14260 c_parser_peek_token (parser)->value); 14261 t = error_mark_node; 14262 } 14263 14264 c_parser_consume_token (parser); 14265 14266 bool neg = false; 14267 if (c_parser_next_token_is (parser, CPP_MINUS)) 14268 neg = true; 14269 else if (!c_parser_next_token_is (parser, CPP_PLUS)) 14270 { 14271 addend = integer_zero_node; 14272 neg = false; 14273 goto add_to_vector; 14274 } 14275 c_parser_consume_token (parser); 14276 14277 if (c_parser_next_token_is_not (parser, CPP_NUMBER)) 14278 { 14279 c_parser_error (parser, "expected integer"); 14280 return list; 14281 } 14282 14283 addend = c_parser_peek_token (parser)->value; 14284 if (TREE_CODE (addend) != INTEGER_CST) 14285 { 14286 c_parser_error (parser, "expected integer"); 14287 return list; 14288 } 14289 c_parser_consume_token (parser); 14290 14291 add_to_vector: 14292 if (t != error_mark_node) 14293 { 14294 vec = tree_cons (addend, t, vec); 14295 if (neg) 14296 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1; 14297 } 14298 14299 if (c_parser_next_token_is_not (parser, CPP_COMMA)) 14300 break; 14301 14302 c_parser_consume_token (parser); 14303 } 14304 14305 if (vec == NULL_TREE) 14306 return list; 14307 14308 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND); 14309 OMP_CLAUSE_DEPEND_KIND (u) = OMP_CLAUSE_DEPEND_SINK; 14310 OMP_CLAUSE_DECL (u) = nreverse (vec); 14311 OMP_CLAUSE_CHAIN (u) = list; 14312 return u; 14313 } 14314 14315 /* OpenMP 5.0: 14316 iterators ( iterators-definition ) 14317 14318 iterators-definition: 14319 iterator-specifier 14320 iterator-specifier , iterators-definition 14321 14322 iterator-specifier: 14323 identifier = range-specification 14324 iterator-type identifier = range-specification 14325 14326 range-specification: 14327 begin : end 14328 begin : end : step */ 14329 14330 static tree 14331 c_parser_omp_iterators (c_parser *parser) 14332 { 14333 tree ret = NULL_TREE, *last = &ret; 14334 c_parser_consume_token (parser); 14335 14336 push_scope (); 14337 14338 matching_parens parens; 14339 if (!parens.require_open (parser)) 14340 return error_mark_node; 14341 14342 do 14343 { 14344 tree iter_type = NULL_TREE, type_expr = NULL_TREE; 14345 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id)) 14346 { 14347 struct c_type_name *type = c_parser_type_name (parser); 14348 if (type != NULL) 14349 iter_type = groktypename (type, &type_expr, NULL); 14350 } 14351 if (iter_type == NULL_TREE) 14352 iter_type = integer_type_node; 14353 14354 location_t loc = c_parser_peek_token (parser)->location; 14355 if (!c_parser_next_token_is (parser, CPP_NAME)) 14356 { 14357 c_parser_error (parser, "expected identifier"); 14358 break; 14359 } 14360 14361 tree id = c_parser_peek_token (parser)->value; 14362 c_parser_consume_token (parser); 14363 14364 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) 14365 break; 14366 14367 location_t eloc = c_parser_peek_token (parser)->location; 14368 c_expr expr = c_parser_expr_no_commas (parser, NULL); 14369 expr = convert_lvalue_to_rvalue (eloc, expr, true, false); 14370 tree begin = expr.value; 14371 14372 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 14373 break; 14374 14375 eloc = c_parser_peek_token (parser)->location; 14376 expr = c_parser_expr_no_commas (parser, NULL); 14377 expr = convert_lvalue_to_rvalue (eloc, expr, true, false); 14378 tree end = expr.value; 14379 14380 tree step = integer_one_node; 14381 if (c_parser_next_token_is (parser, CPP_COLON)) 14382 { 14383 c_parser_consume_token (parser); 14384 eloc = c_parser_peek_token (parser)->location; 14385 expr = c_parser_expr_no_commas (parser, NULL); 14386 expr = convert_lvalue_to_rvalue (eloc, expr, true, false); 14387 step = expr.value; 14388 } 14389 14390 tree iter_var = build_decl (loc, VAR_DECL, id, iter_type); 14391 DECL_ARTIFICIAL (iter_var) = 1; 14392 DECL_CONTEXT (iter_var) = current_function_decl; 14393 pushdecl (iter_var); 14394 14395 *last = make_tree_vec (6); 14396 TREE_VEC_ELT (*last, 0) = iter_var; 14397 TREE_VEC_ELT (*last, 1) = begin; 14398 TREE_VEC_ELT (*last, 2) = end; 14399 TREE_VEC_ELT (*last, 3) = step; 14400 last = &TREE_CHAIN (*last); 14401 14402 if (c_parser_next_token_is (parser, CPP_COMMA)) 14403 { 14404 c_parser_consume_token (parser); 14405 continue; 14406 } 14407 break; 14408 } 14409 while (1); 14410 14411 parens.skip_until_found_close (parser); 14412 return ret ? ret : error_mark_node; 14413 } 14414 14415 /* OpenMP 4.0: 14416 depend ( depend-kind: variable-list ) 14417 14418 depend-kind: 14419 in | out | inout 14420 14421 OpenMP 4.5: 14422 depend ( source ) 14423 14424 depend ( sink : vec ) 14425 14426 OpenMP 5.0: 14427 depend ( depend-modifier , depend-kind: variable-list ) 14428 14429 depend-kind: 14430 in | out | inout | mutexinoutset | depobj 14431 14432 depend-modifier: 14433 iterator ( iterators-definition ) */ 14434 14435 static tree 14436 c_parser_omp_clause_depend (c_parser *parser, tree list) 14437 { 14438 location_t clause_loc = c_parser_peek_token (parser)->location; 14439 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST; 14440 tree nl, c, iterators = NULL_TREE; 14441 14442 matching_parens parens; 14443 if (!parens.require_open (parser)) 14444 return list; 14445 14446 do 14447 { 14448 if (c_parser_next_token_is_not (parser, CPP_NAME)) 14449 goto invalid_kind; 14450 14451 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 14452 if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE) 14453 { 14454 iterators = c_parser_omp_iterators (parser); 14455 c_parser_require (parser, CPP_COMMA, "expected %<,%>"); 14456 continue; 14457 } 14458 if (strcmp ("in", p) == 0) 14459 kind = OMP_CLAUSE_DEPEND_IN; 14460 else if (strcmp ("inout", p) == 0) 14461 kind = OMP_CLAUSE_DEPEND_INOUT; 14462 else if (strcmp ("mutexinoutset", p) == 0) 14463 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET; 14464 else if (strcmp ("out", p) == 0) 14465 kind = OMP_CLAUSE_DEPEND_OUT; 14466 else if (strcmp ("depobj", p) == 0) 14467 kind = OMP_CLAUSE_DEPEND_DEPOBJ; 14468 else if (strcmp ("sink", p) == 0) 14469 kind = OMP_CLAUSE_DEPEND_SINK; 14470 else if (strcmp ("source", p) == 0) 14471 kind = OMP_CLAUSE_DEPEND_SOURCE; 14472 else 14473 goto invalid_kind; 14474 break; 14475 } 14476 while (1); 14477 14478 c_parser_consume_token (parser); 14479 14480 if (iterators 14481 && (kind == OMP_CLAUSE_DEPEND_SOURCE || kind == OMP_CLAUSE_DEPEND_SINK)) 14482 { 14483 pop_scope (); 14484 error_at (clause_loc, "%<iterator%> modifier incompatible with %qs", 14485 kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink"); 14486 iterators = NULL_TREE; 14487 } 14488 14489 if (kind == OMP_CLAUSE_DEPEND_SOURCE) 14490 { 14491 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND); 14492 OMP_CLAUSE_DEPEND_KIND (c) = kind; 14493 OMP_CLAUSE_DECL (c) = NULL_TREE; 14494 OMP_CLAUSE_CHAIN (c) = list; 14495 parens.skip_until_found_close (parser); 14496 return c; 14497 } 14498 14499 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 14500 goto resync_fail; 14501 14502 if (kind == OMP_CLAUSE_DEPEND_SINK) 14503 nl = c_parser_omp_clause_depend_sink (parser, clause_loc, list); 14504 else 14505 { 14506 nl = c_parser_omp_variable_list (parser, clause_loc, 14507 OMP_CLAUSE_DEPEND, list); 14508 14509 if (iterators) 14510 { 14511 tree block = pop_scope (); 14512 if (iterators == error_mark_node) 14513 iterators = NULL_TREE; 14514 else 14515 TREE_VEC_ELT (iterators, 5) = block; 14516 } 14517 14518 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) 14519 { 14520 OMP_CLAUSE_DEPEND_KIND (c) = kind; 14521 if (iterators) 14522 OMP_CLAUSE_DECL (c) 14523 = build_tree_list (iterators, OMP_CLAUSE_DECL (c)); 14524 } 14525 } 14526 14527 parens.skip_until_found_close (parser); 14528 return nl; 14529 14530 invalid_kind: 14531 c_parser_error (parser, "invalid depend kind"); 14532 resync_fail: 14533 parens.skip_until_found_close (parser); 14534 if (iterators) 14535 pop_scope (); 14536 return list; 14537 } 14538 14539 /* OpenMP 4.0: 14540 map ( map-kind: variable-list ) 14541 map ( variable-list ) 14542 14543 map-kind: 14544 alloc | to | from | tofrom 14545 14546 OpenMP 4.5: 14547 map-kind: 14548 alloc | to | from | tofrom | release | delete 14549 14550 map ( always [,] map-kind: variable-list ) */ 14551 14552 static tree 14553 c_parser_omp_clause_map (c_parser *parser, tree list) 14554 { 14555 location_t clause_loc = c_parser_peek_token (parser)->location; 14556 enum gomp_map_kind kind = GOMP_MAP_TOFROM; 14557 int always = 0; 14558 enum c_id_kind always_id_kind = C_ID_NONE; 14559 location_t always_loc = UNKNOWN_LOCATION; 14560 tree always_id = NULL_TREE; 14561 tree nl, c; 14562 14563 matching_parens parens; 14564 if (!parens.require_open (parser)) 14565 return list; 14566 14567 if (c_parser_next_token_is (parser, CPP_NAME)) 14568 { 14569 c_token *tok = c_parser_peek_token (parser); 14570 const char *p = IDENTIFIER_POINTER (tok->value); 14571 always_id_kind = tok->id_kind; 14572 always_loc = tok->location; 14573 always_id = tok->value; 14574 if (strcmp ("always", p) == 0) 14575 { 14576 c_token *sectok = c_parser_peek_2nd_token (parser); 14577 if (sectok->type == CPP_COMMA) 14578 { 14579 c_parser_consume_token (parser); 14580 c_parser_consume_token (parser); 14581 always = 2; 14582 } 14583 else if (sectok->type == CPP_NAME) 14584 { 14585 p = IDENTIFIER_POINTER (sectok->value); 14586 if (strcmp ("alloc", p) == 0 14587 || strcmp ("to", p) == 0 14588 || strcmp ("from", p) == 0 14589 || strcmp ("tofrom", p) == 0 14590 || strcmp ("release", p) == 0 14591 || strcmp ("delete", p) == 0) 14592 { 14593 c_parser_consume_token (parser); 14594 always = 1; 14595 } 14596 } 14597 } 14598 } 14599 14600 if (c_parser_next_token_is (parser, CPP_NAME) 14601 && c_parser_peek_2nd_token (parser)->type == CPP_COLON) 14602 { 14603 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 14604 if (strcmp ("alloc", p) == 0) 14605 kind = GOMP_MAP_ALLOC; 14606 else if (strcmp ("to", p) == 0) 14607 kind = always ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO; 14608 else if (strcmp ("from", p) == 0) 14609 kind = always ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM; 14610 else if (strcmp ("tofrom", p) == 0) 14611 kind = always ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM; 14612 else if (strcmp ("release", p) == 0) 14613 kind = GOMP_MAP_RELEASE; 14614 else if (strcmp ("delete", p) == 0) 14615 kind = GOMP_MAP_DELETE; 14616 else 14617 { 14618 c_parser_error (parser, "invalid map kind"); 14619 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 14620 "expected %<)%>"); 14621 return list; 14622 } 14623 c_parser_consume_token (parser); 14624 c_parser_consume_token (parser); 14625 } 14626 else if (always) 14627 { 14628 if (always_id_kind != C_ID_ID) 14629 { 14630 c_parser_error (parser, "expected identifier"); 14631 parens.skip_until_found_close (parser); 14632 return list; 14633 } 14634 14635 tree t = lookup_name (always_id); 14636 if (t == NULL_TREE) 14637 { 14638 undeclared_variable (always_loc, always_id); 14639 t = error_mark_node; 14640 } 14641 if (t != error_mark_node) 14642 { 14643 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_MAP); 14644 OMP_CLAUSE_DECL (u) = t; 14645 OMP_CLAUSE_CHAIN (u) = list; 14646 OMP_CLAUSE_SET_MAP_KIND (u, kind); 14647 list = u; 14648 } 14649 if (always == 1) 14650 { 14651 parens.skip_until_found_close (parser); 14652 return list; 14653 } 14654 } 14655 14656 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list); 14657 14658 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) 14659 OMP_CLAUSE_SET_MAP_KIND (c, kind); 14660 14661 parens.skip_until_found_close (parser); 14662 return nl; 14663 } 14664 14665 /* OpenMP 4.0: 14666 device ( expression ) */ 14667 14668 static tree 14669 c_parser_omp_clause_device (c_parser *parser, tree list) 14670 { 14671 location_t clause_loc = c_parser_peek_token (parser)->location; 14672 matching_parens parens; 14673 if (parens.require_open (parser)) 14674 { 14675 location_t expr_loc = c_parser_peek_token (parser)->location; 14676 c_expr expr = c_parser_expr_no_commas (parser, NULL); 14677 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 14678 tree c, t = expr.value; 14679 t = c_fully_fold (t, false, NULL); 14680 14681 parens.skip_until_found_close (parser); 14682 14683 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 14684 { 14685 c_parser_error (parser, "expected integer expression"); 14686 return list; 14687 } 14688 14689 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device"); 14690 14691 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE); 14692 OMP_CLAUSE_DEVICE_ID (c) = t; 14693 OMP_CLAUSE_CHAIN (c) = list; 14694 list = c; 14695 } 14696 14697 return list; 14698 } 14699 14700 /* OpenMP 4.0: 14701 dist_schedule ( static ) 14702 dist_schedule ( static , expression ) */ 14703 14704 static tree 14705 c_parser_omp_clause_dist_schedule (c_parser *parser, tree list) 14706 { 14707 tree c, t = NULL_TREE; 14708 location_t loc = c_parser_peek_token (parser)->location; 14709 14710 matching_parens parens; 14711 if (!parens.require_open (parser)) 14712 return list; 14713 14714 if (!c_parser_next_token_is_keyword (parser, RID_STATIC)) 14715 { 14716 c_parser_error (parser, "invalid dist_schedule kind"); 14717 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 14718 "expected %<)%>"); 14719 return list; 14720 } 14721 14722 c_parser_consume_token (parser); 14723 if (c_parser_next_token_is (parser, CPP_COMMA)) 14724 { 14725 c_parser_consume_token (parser); 14726 14727 location_t expr_loc = c_parser_peek_token (parser)->location; 14728 c_expr expr = c_parser_expr_no_commas (parser, NULL); 14729 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 14730 t = expr.value; 14731 t = c_fully_fold (t, false, NULL); 14732 parens.skip_until_found_close (parser); 14733 } 14734 else 14735 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 14736 "expected %<,%> or %<)%>"); 14737 14738 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE, 14739 "dist_schedule"); */ 14740 if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE)) 14741 warning_at (loc, 0, "too many %qs clauses", "dist_schedule"); 14742 if (t == error_mark_node) 14743 return list; 14744 14745 c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE); 14746 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t; 14747 OMP_CLAUSE_CHAIN (c) = list; 14748 return c; 14749 } 14750 14751 /* OpenMP 4.0: 14752 proc_bind ( proc-bind-kind ) 14753 14754 proc-bind-kind: 14755 master | close | spread */ 14756 14757 static tree 14758 c_parser_omp_clause_proc_bind (c_parser *parser, tree list) 14759 { 14760 location_t clause_loc = c_parser_peek_token (parser)->location; 14761 enum omp_clause_proc_bind_kind kind; 14762 tree c; 14763 14764 matching_parens parens; 14765 if (!parens.require_open (parser)) 14766 return list; 14767 14768 if (c_parser_next_token_is (parser, CPP_NAME)) 14769 { 14770 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 14771 if (strcmp ("master", p) == 0) 14772 kind = OMP_CLAUSE_PROC_BIND_MASTER; 14773 else if (strcmp ("close", p) == 0) 14774 kind = OMP_CLAUSE_PROC_BIND_CLOSE; 14775 else if (strcmp ("spread", p) == 0) 14776 kind = OMP_CLAUSE_PROC_BIND_SPREAD; 14777 else 14778 goto invalid_kind; 14779 } 14780 else 14781 goto invalid_kind; 14782 14783 c_parser_consume_token (parser); 14784 parens.skip_until_found_close (parser); 14785 c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND); 14786 OMP_CLAUSE_PROC_BIND_KIND (c) = kind; 14787 OMP_CLAUSE_CHAIN (c) = list; 14788 return c; 14789 14790 invalid_kind: 14791 c_parser_error (parser, "invalid proc_bind kind"); 14792 parens.skip_until_found_close (parser); 14793 return list; 14794 } 14795 14796 /* OpenMP 4.0: 14797 to ( variable-list ) */ 14798 14799 static tree 14800 c_parser_omp_clause_to (c_parser *parser, tree list) 14801 { 14802 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO, list); 14803 } 14804 14805 /* OpenMP 4.0: 14806 from ( variable-list ) */ 14807 14808 static tree 14809 c_parser_omp_clause_from (c_parser *parser, tree list) 14810 { 14811 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FROM, list); 14812 } 14813 14814 /* OpenMP 4.0: 14815 uniform ( variable-list ) */ 14816 14817 static tree 14818 c_parser_omp_clause_uniform (c_parser *parser, tree list) 14819 { 14820 /* The clauses location. */ 14821 location_t loc = c_parser_peek_token (parser)->location; 14822 14823 matching_parens parens; 14824 if (parens.require_open (parser)) 14825 { 14826 list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM, 14827 list); 14828 parens.skip_until_found_close (parser); 14829 } 14830 return list; 14831 } 14832 14833 /* Parse all OpenACC clauses. The set clauses allowed by the directive 14834 is a bitmask in MASK. Return the list of clauses found. */ 14835 14836 static tree 14837 c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask, 14838 const char *where, bool finish_p = true) 14839 { 14840 tree clauses = NULL; 14841 bool first = true; 14842 14843 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 14844 { 14845 location_t here; 14846 pragma_omp_clause c_kind; 14847 const char *c_name; 14848 tree prev = clauses; 14849 14850 if (!first && c_parser_next_token_is (parser, CPP_COMMA)) 14851 c_parser_consume_token (parser); 14852 14853 here = c_parser_peek_token (parser)->location; 14854 c_kind = c_parser_omp_clause_name (parser); 14855 14856 switch (c_kind) 14857 { 14858 case PRAGMA_OACC_CLAUSE_ASYNC: 14859 clauses = c_parser_oacc_clause_async (parser, clauses); 14860 c_name = "async"; 14861 break; 14862 case PRAGMA_OACC_CLAUSE_AUTO: 14863 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO, 14864 clauses); 14865 c_name = "auto"; 14866 break; 14867 case PRAGMA_OACC_CLAUSE_COLLAPSE: 14868 clauses = c_parser_omp_clause_collapse (parser, clauses); 14869 c_name = "collapse"; 14870 break; 14871 case PRAGMA_OACC_CLAUSE_COPY: 14872 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 14873 c_name = "copy"; 14874 break; 14875 case PRAGMA_OACC_CLAUSE_COPYIN: 14876 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 14877 c_name = "copyin"; 14878 break; 14879 case PRAGMA_OACC_CLAUSE_COPYOUT: 14880 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 14881 c_name = "copyout"; 14882 break; 14883 case PRAGMA_OACC_CLAUSE_CREATE: 14884 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 14885 c_name = "create"; 14886 break; 14887 case PRAGMA_OACC_CLAUSE_DELETE: 14888 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 14889 c_name = "delete"; 14890 break; 14891 case PRAGMA_OMP_CLAUSE_DEFAULT: 14892 clauses = c_parser_omp_clause_default (parser, clauses, true); 14893 c_name = "default"; 14894 break; 14895 case PRAGMA_OACC_CLAUSE_DEVICE: 14896 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 14897 c_name = "device"; 14898 break; 14899 case PRAGMA_OACC_CLAUSE_DEVICEPTR: 14900 clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses); 14901 c_name = "deviceptr"; 14902 break; 14903 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT: 14904 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 14905 c_name = "device_resident"; 14906 break; 14907 case PRAGMA_OACC_CLAUSE_FINALIZE: 14908 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE, 14909 clauses); 14910 c_name = "finalize"; 14911 break; 14912 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE: 14913 clauses = c_parser_omp_clause_firstprivate (parser, clauses); 14914 c_name = "firstprivate"; 14915 break; 14916 case PRAGMA_OACC_CLAUSE_GANG: 14917 c_name = "gang"; 14918 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG, 14919 c_name, clauses); 14920 break; 14921 case PRAGMA_OACC_CLAUSE_HOST: 14922 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 14923 c_name = "host"; 14924 break; 14925 case PRAGMA_OACC_CLAUSE_IF: 14926 clauses = c_parser_omp_clause_if (parser, clauses, false); 14927 c_name = "if"; 14928 break; 14929 case PRAGMA_OACC_CLAUSE_IF_PRESENT: 14930 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT, 14931 clauses); 14932 c_name = "if_present"; 14933 break; 14934 case PRAGMA_OACC_CLAUSE_INDEPENDENT: 14935 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT, 14936 clauses); 14937 c_name = "independent"; 14938 break; 14939 case PRAGMA_OACC_CLAUSE_LINK: 14940 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 14941 c_name = "link"; 14942 break; 14943 case PRAGMA_OACC_CLAUSE_NUM_GANGS: 14944 clauses = c_parser_oacc_single_int_clause (parser, 14945 OMP_CLAUSE_NUM_GANGS, 14946 clauses); 14947 c_name = "num_gangs"; 14948 break; 14949 case PRAGMA_OACC_CLAUSE_NUM_WORKERS: 14950 clauses = c_parser_oacc_single_int_clause (parser, 14951 OMP_CLAUSE_NUM_WORKERS, 14952 clauses); 14953 c_name = "num_workers"; 14954 break; 14955 case PRAGMA_OACC_CLAUSE_PRESENT: 14956 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 14957 c_name = "present"; 14958 break; 14959 case PRAGMA_OACC_CLAUSE_PRIVATE: 14960 clauses = c_parser_omp_clause_private (parser, clauses); 14961 c_name = "private"; 14962 break; 14963 case PRAGMA_OACC_CLAUSE_REDUCTION: 14964 clauses 14965 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION, 14966 false, clauses); 14967 c_name = "reduction"; 14968 break; 14969 case PRAGMA_OACC_CLAUSE_SEQ: 14970 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ, 14971 clauses); 14972 c_name = "seq"; 14973 break; 14974 case PRAGMA_OACC_CLAUSE_TILE: 14975 clauses = c_parser_oacc_clause_tile (parser, clauses); 14976 c_name = "tile"; 14977 break; 14978 case PRAGMA_OACC_CLAUSE_USE_DEVICE: 14979 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses); 14980 c_name = "use_device"; 14981 break; 14982 case PRAGMA_OACC_CLAUSE_VECTOR: 14983 c_name = "vector"; 14984 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR, 14985 c_name, clauses); 14986 break; 14987 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH: 14988 clauses = c_parser_oacc_single_int_clause (parser, 14989 OMP_CLAUSE_VECTOR_LENGTH, 14990 clauses); 14991 c_name = "vector_length"; 14992 break; 14993 case PRAGMA_OACC_CLAUSE_WAIT: 14994 clauses = c_parser_oacc_clause_wait (parser, clauses); 14995 c_name = "wait"; 14996 break; 14997 case PRAGMA_OACC_CLAUSE_WORKER: 14998 c_name = "worker"; 14999 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER, 15000 c_name, clauses); 15001 break; 15002 default: 15003 c_parser_error (parser, "expected %<#pragma acc%> clause"); 15004 goto saw_error; 15005 } 15006 15007 first = false; 15008 15009 if (((mask >> c_kind) & 1) == 0) 15010 { 15011 /* Remove the invalid clause(s) from the list to avoid 15012 confusing the rest of the compiler. */ 15013 clauses = prev; 15014 error_at (here, "%qs is not valid for %qs", c_name, where); 15015 } 15016 } 15017 15018 saw_error: 15019 c_parser_skip_to_pragma_eol (parser); 15020 15021 if (finish_p) 15022 return c_finish_omp_clauses (clauses, C_ORT_ACC); 15023 15024 return clauses; 15025 } 15026 15027 /* Parse all OpenMP clauses. The set clauses allowed by the directive 15028 is a bitmask in MASK. Return the list of clauses found. */ 15029 15030 static tree 15031 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask, 15032 const char *where, bool finish_p = true) 15033 { 15034 tree clauses = NULL; 15035 bool first = true; 15036 15037 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 15038 { 15039 location_t here; 15040 pragma_omp_clause c_kind; 15041 const char *c_name; 15042 tree prev = clauses; 15043 15044 if (!first && c_parser_next_token_is (parser, CPP_COMMA)) 15045 c_parser_consume_token (parser); 15046 15047 here = c_parser_peek_token (parser)->location; 15048 c_kind = c_parser_omp_clause_name (parser); 15049 15050 switch (c_kind) 15051 { 15052 case PRAGMA_OMP_CLAUSE_COLLAPSE: 15053 clauses = c_parser_omp_clause_collapse (parser, clauses); 15054 c_name = "collapse"; 15055 break; 15056 case PRAGMA_OMP_CLAUSE_COPYIN: 15057 clauses = c_parser_omp_clause_copyin (parser, clauses); 15058 c_name = "copyin"; 15059 break; 15060 case PRAGMA_OMP_CLAUSE_COPYPRIVATE: 15061 clauses = c_parser_omp_clause_copyprivate (parser, clauses); 15062 c_name = "copyprivate"; 15063 break; 15064 case PRAGMA_OMP_CLAUSE_DEFAULT: 15065 clauses = c_parser_omp_clause_default (parser, clauses, false); 15066 c_name = "default"; 15067 break; 15068 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE: 15069 clauses = c_parser_omp_clause_firstprivate (parser, clauses); 15070 c_name = "firstprivate"; 15071 break; 15072 case PRAGMA_OMP_CLAUSE_FINAL: 15073 clauses = c_parser_omp_clause_final (parser, clauses); 15074 c_name = "final"; 15075 break; 15076 case PRAGMA_OMP_CLAUSE_GRAINSIZE: 15077 clauses = c_parser_omp_clause_grainsize (parser, clauses); 15078 c_name = "grainsize"; 15079 break; 15080 case PRAGMA_OMP_CLAUSE_HINT: 15081 clauses = c_parser_omp_clause_hint (parser, clauses); 15082 c_name = "hint"; 15083 break; 15084 case PRAGMA_OMP_CLAUSE_DEFAULTMAP: 15085 clauses = c_parser_omp_clause_defaultmap (parser, clauses); 15086 c_name = "defaultmap"; 15087 break; 15088 case PRAGMA_OMP_CLAUSE_IF: 15089 clauses = c_parser_omp_clause_if (parser, clauses, true); 15090 c_name = "if"; 15091 break; 15092 case PRAGMA_OMP_CLAUSE_IN_REDUCTION: 15093 clauses 15094 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION, 15095 true, clauses); 15096 c_name = "in_reduction"; 15097 break; 15098 case PRAGMA_OMP_CLAUSE_LASTPRIVATE: 15099 clauses = c_parser_omp_clause_lastprivate (parser, clauses); 15100 c_name = "lastprivate"; 15101 break; 15102 case PRAGMA_OMP_CLAUSE_MERGEABLE: 15103 clauses = c_parser_omp_clause_mergeable (parser, clauses); 15104 c_name = "mergeable"; 15105 break; 15106 case PRAGMA_OMP_CLAUSE_NOWAIT: 15107 clauses = c_parser_omp_clause_nowait (parser, clauses); 15108 c_name = "nowait"; 15109 break; 15110 case PRAGMA_OMP_CLAUSE_NUM_TASKS: 15111 clauses = c_parser_omp_clause_num_tasks (parser, clauses); 15112 c_name = "num_tasks"; 15113 break; 15114 case PRAGMA_OMP_CLAUSE_NUM_THREADS: 15115 clauses = c_parser_omp_clause_num_threads (parser, clauses); 15116 c_name = "num_threads"; 15117 break; 15118 case PRAGMA_OMP_CLAUSE_ORDERED: 15119 clauses = c_parser_omp_clause_ordered (parser, clauses); 15120 c_name = "ordered"; 15121 break; 15122 case PRAGMA_OMP_CLAUSE_PRIORITY: 15123 clauses = c_parser_omp_clause_priority (parser, clauses); 15124 c_name = "priority"; 15125 break; 15126 case PRAGMA_OMP_CLAUSE_PRIVATE: 15127 clauses = c_parser_omp_clause_private (parser, clauses); 15128 c_name = "private"; 15129 break; 15130 case PRAGMA_OMP_CLAUSE_REDUCTION: 15131 clauses 15132 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION, 15133 true, clauses); 15134 c_name = "reduction"; 15135 break; 15136 case PRAGMA_OMP_CLAUSE_SCHEDULE: 15137 clauses = c_parser_omp_clause_schedule (parser, clauses); 15138 c_name = "schedule"; 15139 break; 15140 case PRAGMA_OMP_CLAUSE_SHARED: 15141 clauses = c_parser_omp_clause_shared (parser, clauses); 15142 c_name = "shared"; 15143 break; 15144 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION: 15145 clauses 15146 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION, 15147 true, clauses); 15148 c_name = "task_reduction"; 15149 break; 15150 case PRAGMA_OMP_CLAUSE_UNTIED: 15151 clauses = c_parser_omp_clause_untied (parser, clauses); 15152 c_name = "untied"; 15153 break; 15154 case PRAGMA_OMP_CLAUSE_INBRANCH: 15155 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH, 15156 clauses); 15157 c_name = "inbranch"; 15158 break; 15159 case PRAGMA_OMP_CLAUSE_NONTEMPORAL: 15160 clauses = c_parser_omp_clause_nontemporal (parser, clauses); 15161 c_name = "nontemporal"; 15162 break; 15163 case PRAGMA_OMP_CLAUSE_NOTINBRANCH: 15164 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH, 15165 clauses); 15166 c_name = "notinbranch"; 15167 break; 15168 case PRAGMA_OMP_CLAUSE_PARALLEL: 15169 clauses 15170 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL, 15171 clauses); 15172 c_name = "parallel"; 15173 if (!first) 15174 { 15175 clause_not_first: 15176 error_at (here, "%qs must be the first clause of %qs", 15177 c_name, where); 15178 clauses = prev; 15179 } 15180 break; 15181 case PRAGMA_OMP_CLAUSE_FOR: 15182 clauses 15183 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR, 15184 clauses); 15185 c_name = "for"; 15186 if (!first) 15187 goto clause_not_first; 15188 break; 15189 case PRAGMA_OMP_CLAUSE_SECTIONS: 15190 clauses 15191 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS, 15192 clauses); 15193 c_name = "sections"; 15194 if (!first) 15195 goto clause_not_first; 15196 break; 15197 case PRAGMA_OMP_CLAUSE_TASKGROUP: 15198 clauses 15199 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP, 15200 clauses); 15201 c_name = "taskgroup"; 15202 if (!first) 15203 goto clause_not_first; 15204 break; 15205 case PRAGMA_OMP_CLAUSE_LINK: 15206 clauses 15207 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses); 15208 c_name = "link"; 15209 break; 15210 case PRAGMA_OMP_CLAUSE_TO: 15211 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0) 15212 clauses 15213 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE, 15214 clauses); 15215 else 15216 clauses = c_parser_omp_clause_to (parser, clauses); 15217 c_name = "to"; 15218 break; 15219 case PRAGMA_OMP_CLAUSE_FROM: 15220 clauses = c_parser_omp_clause_from (parser, clauses); 15221 c_name = "from"; 15222 break; 15223 case PRAGMA_OMP_CLAUSE_UNIFORM: 15224 clauses = c_parser_omp_clause_uniform (parser, clauses); 15225 c_name = "uniform"; 15226 break; 15227 case PRAGMA_OMP_CLAUSE_NUM_TEAMS: 15228 clauses = c_parser_omp_clause_num_teams (parser, clauses); 15229 c_name = "num_teams"; 15230 break; 15231 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT: 15232 clauses = c_parser_omp_clause_thread_limit (parser, clauses); 15233 c_name = "thread_limit"; 15234 break; 15235 case PRAGMA_OMP_CLAUSE_ALIGNED: 15236 clauses = c_parser_omp_clause_aligned (parser, clauses); 15237 c_name = "aligned"; 15238 break; 15239 case PRAGMA_OMP_CLAUSE_LINEAR: 15240 clauses = c_parser_omp_clause_linear (parser, clauses); 15241 c_name = "linear"; 15242 break; 15243 case PRAGMA_OMP_CLAUSE_DEPEND: 15244 clauses = c_parser_omp_clause_depend (parser, clauses); 15245 c_name = "depend"; 15246 break; 15247 case PRAGMA_OMP_CLAUSE_MAP: 15248 clauses = c_parser_omp_clause_map (parser, clauses); 15249 c_name = "map"; 15250 break; 15251 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR: 15252 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses); 15253 c_name = "use_device_ptr"; 15254 break; 15255 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR: 15256 clauses = c_parser_omp_clause_is_device_ptr (parser, clauses); 15257 c_name = "is_device_ptr"; 15258 break; 15259 case PRAGMA_OMP_CLAUSE_DEVICE: 15260 clauses = c_parser_omp_clause_device (parser, clauses); 15261 c_name = "device"; 15262 break; 15263 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE: 15264 clauses = c_parser_omp_clause_dist_schedule (parser, clauses); 15265 c_name = "dist_schedule"; 15266 break; 15267 case PRAGMA_OMP_CLAUSE_PROC_BIND: 15268 clauses = c_parser_omp_clause_proc_bind (parser, clauses); 15269 c_name = "proc_bind"; 15270 break; 15271 case PRAGMA_OMP_CLAUSE_SAFELEN: 15272 clauses = c_parser_omp_clause_safelen (parser, clauses); 15273 c_name = "safelen"; 15274 break; 15275 case PRAGMA_OMP_CLAUSE_SIMDLEN: 15276 clauses = c_parser_omp_clause_simdlen (parser, clauses); 15277 c_name = "simdlen"; 15278 break; 15279 case PRAGMA_OMP_CLAUSE_NOGROUP: 15280 clauses = c_parser_omp_clause_nogroup (parser, clauses); 15281 c_name = "nogroup"; 15282 break; 15283 case PRAGMA_OMP_CLAUSE_THREADS: 15284 clauses 15285 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS, 15286 clauses); 15287 c_name = "threads"; 15288 break; 15289 case PRAGMA_OMP_CLAUSE_SIMD: 15290 clauses 15291 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD, 15292 clauses); 15293 c_name = "simd"; 15294 break; 15295 default: 15296 c_parser_error (parser, "expected %<#pragma omp%> clause"); 15297 goto saw_error; 15298 } 15299 15300 first = false; 15301 15302 if (((mask >> c_kind) & 1) == 0) 15303 { 15304 /* Remove the invalid clause(s) from the list to avoid 15305 confusing the rest of the compiler. */ 15306 clauses = prev; 15307 error_at (here, "%qs is not valid for %qs", c_name, where); 15308 } 15309 } 15310 15311 saw_error: 15312 c_parser_skip_to_pragma_eol (parser); 15313 15314 if (finish_p) 15315 { 15316 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0) 15317 return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD); 15318 return c_finish_omp_clauses (clauses, C_ORT_OMP); 15319 } 15320 15321 return clauses; 15322 } 15323 15324 /* OpenACC 2.0, OpenMP 2.5: 15325 structured-block: 15326 statement 15327 15328 In practice, we're also interested in adding the statement to an 15329 outer node. So it is convenient if we work around the fact that 15330 c_parser_statement calls add_stmt. */ 15331 15332 static tree 15333 c_parser_omp_structured_block (c_parser *parser, bool *if_p) 15334 { 15335 tree stmt = push_stmt_list (); 15336 c_parser_statement (parser, if_p); 15337 return pop_stmt_list (stmt); 15338 } 15339 15340 /* OpenACC 2.0: 15341 # pragma acc cache (variable-list) new-line 15342 15343 LOC is the location of the #pragma token. 15344 */ 15345 15346 static tree 15347 c_parser_oacc_cache (location_t loc, c_parser *parser) 15348 { 15349 tree stmt, clauses; 15350 15351 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL); 15352 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC); 15353 15354 c_parser_skip_to_pragma_eol (parser); 15355 15356 stmt = make_node (OACC_CACHE); 15357 TREE_TYPE (stmt) = void_type_node; 15358 OACC_CACHE_CLAUSES (stmt) = clauses; 15359 SET_EXPR_LOCATION (stmt, loc); 15360 add_stmt (stmt); 15361 15362 return stmt; 15363 } 15364 15365 /* OpenACC 2.0: 15366 # pragma acc data oacc-data-clause[optseq] new-line 15367 structured-block 15368 15369 LOC is the location of the #pragma token. 15370 */ 15371 15372 #define OACC_DATA_CLAUSE_MASK \ 15373 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \ 15374 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \ 15375 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \ 15376 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \ 15377 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \ 15378 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \ 15379 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)) 15380 15381 static tree 15382 c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p) 15383 { 15384 tree stmt, clauses, block; 15385 15386 clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK, 15387 "#pragma acc data"); 15388 15389 block = c_begin_omp_parallel (); 15390 add_stmt (c_parser_omp_structured_block (parser, if_p)); 15391 15392 stmt = c_finish_oacc_data (loc, clauses, block); 15393 15394 return stmt; 15395 } 15396 15397 /* OpenACC 2.0: 15398 # pragma acc declare oacc-data-clause[optseq] new-line 15399 */ 15400 15401 #define OACC_DECLARE_CLAUSE_MASK \ 15402 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \ 15403 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \ 15404 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \ 15405 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \ 15406 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \ 15407 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \ 15408 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \ 15409 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)) 15410 15411 static void 15412 c_parser_oacc_declare (c_parser *parser) 15413 { 15414 location_t pragma_loc = c_parser_peek_token (parser)->location; 15415 tree clauses, stmt, t, decl; 15416 15417 bool error = false; 15418 15419 c_parser_consume_pragma (parser); 15420 15421 clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK, 15422 "#pragma acc declare"); 15423 if (!clauses) 15424 { 15425 error_at (pragma_loc, 15426 "no valid clauses specified in %<#pragma acc declare%>"); 15427 return; 15428 } 15429 15430 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t)) 15431 { 15432 location_t loc = OMP_CLAUSE_LOCATION (t); 15433 decl = OMP_CLAUSE_DECL (t); 15434 if (!DECL_P (decl)) 15435 { 15436 error_at (loc, "array section in %<#pragma acc declare%>"); 15437 error = true; 15438 continue; 15439 } 15440 15441 switch (OMP_CLAUSE_MAP_KIND (t)) 15442 { 15443 case GOMP_MAP_FIRSTPRIVATE_POINTER: 15444 case GOMP_MAP_ALLOC: 15445 case GOMP_MAP_TO: 15446 case GOMP_MAP_FORCE_DEVICEPTR: 15447 case GOMP_MAP_DEVICE_RESIDENT: 15448 break; 15449 15450 case GOMP_MAP_LINK: 15451 if (!global_bindings_p () 15452 && (TREE_STATIC (decl) 15453 || !DECL_EXTERNAL (decl))) 15454 { 15455 error_at (loc, 15456 "%qD must be a global variable in " 15457 "%<#pragma acc declare link%>", 15458 decl); 15459 error = true; 15460 continue; 15461 } 15462 break; 15463 15464 default: 15465 if (global_bindings_p ()) 15466 { 15467 error_at (loc, "invalid OpenACC clause at file scope"); 15468 error = true; 15469 continue; 15470 } 15471 if (DECL_EXTERNAL (decl)) 15472 { 15473 error_at (loc, 15474 "invalid use of %<extern%> variable %qD " 15475 "in %<#pragma acc declare%>", decl); 15476 error = true; 15477 continue; 15478 } 15479 else if (TREE_PUBLIC (decl)) 15480 { 15481 error_at (loc, 15482 "invalid use of %<global%> variable %qD " 15483 "in %<#pragma acc declare%>", decl); 15484 error = true; 15485 continue; 15486 } 15487 break; 15488 } 15489 15490 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)) 15491 || lookup_attribute ("omp declare target link", 15492 DECL_ATTRIBUTES (decl))) 15493 { 15494 error_at (loc, "variable %qD used more than once with " 15495 "%<#pragma acc declare%>", decl); 15496 error = true; 15497 continue; 15498 } 15499 15500 if (!error) 15501 { 15502 tree id; 15503 15504 if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK) 15505 id = get_identifier ("omp declare target link"); 15506 else 15507 id = get_identifier ("omp declare target"); 15508 15509 DECL_ATTRIBUTES (decl) 15510 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl)); 15511 15512 if (global_bindings_p ()) 15513 { 15514 symtab_node *node = symtab_node::get (decl); 15515 if (node != NULL) 15516 { 15517 node->offloadable = 1; 15518 if (ENABLE_OFFLOADING) 15519 { 15520 g->have_offload = true; 15521 if (is_a <varpool_node *> (node)) 15522 vec_safe_push (offload_vars, decl); 15523 } 15524 } 15525 } 15526 } 15527 } 15528 15529 if (error || global_bindings_p ()) 15530 return; 15531 15532 stmt = make_node (OACC_DECLARE); 15533 TREE_TYPE (stmt) = void_type_node; 15534 OACC_DECLARE_CLAUSES (stmt) = clauses; 15535 SET_EXPR_LOCATION (stmt, pragma_loc); 15536 15537 add_stmt (stmt); 15538 15539 return; 15540 } 15541 15542 /* OpenACC 2.0: 15543 # pragma acc enter data oacc-enter-data-clause[optseq] new-line 15544 15545 or 15546 15547 # pragma acc exit data oacc-exit-data-clause[optseq] new-line 15548 15549 15550 LOC is the location of the #pragma token. 15551 */ 15552 15553 #define OACC_ENTER_DATA_CLAUSE_MASK \ 15554 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \ 15555 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \ 15556 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \ 15557 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \ 15558 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) ) 15559 15560 #define OACC_EXIT_DATA_CLAUSE_MASK \ 15561 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \ 15562 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \ 15563 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \ 15564 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \ 15565 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \ 15566 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) ) 15567 15568 static void 15569 c_parser_oacc_enter_exit_data (c_parser *parser, bool enter) 15570 { 15571 location_t loc = c_parser_peek_token (parser)->location; 15572 tree clauses, stmt; 15573 const char *p = ""; 15574 15575 c_parser_consume_pragma (parser); 15576 15577 if (c_parser_next_token_is (parser, CPP_NAME)) 15578 { 15579 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 15580 c_parser_consume_token (parser); 15581 } 15582 15583 if (strcmp (p, "data") != 0) 15584 { 15585 error_at (loc, "expected %<data%> after %<#pragma acc %s%>", 15586 enter ? "enter" : "exit"); 15587 parser->error = true; 15588 c_parser_skip_to_pragma_eol (parser); 15589 return; 15590 } 15591 15592 if (enter) 15593 clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK, 15594 "#pragma acc enter data"); 15595 else 15596 clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK, 15597 "#pragma acc exit data"); 15598 15599 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE) 15600 { 15601 error_at (loc, "%<#pragma acc %s data%> has no data movement clause", 15602 enter ? "enter" : "exit"); 15603 return; 15604 } 15605 15606 stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA); 15607 TREE_TYPE (stmt) = void_type_node; 15608 OMP_STANDALONE_CLAUSES (stmt) = clauses; 15609 SET_EXPR_LOCATION (stmt, loc); 15610 add_stmt (stmt); 15611 } 15612 15613 15614 /* OpenACC 2.0: 15615 # pragma acc host_data oacc-data-clause[optseq] new-line 15616 structured-block 15617 */ 15618 15619 #define OACC_HOST_DATA_CLAUSE_MASK \ 15620 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) ) 15621 15622 static tree 15623 c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p) 15624 { 15625 tree stmt, clauses, block; 15626 15627 clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK, 15628 "#pragma acc host_data"); 15629 15630 block = c_begin_omp_parallel (); 15631 add_stmt (c_parser_omp_structured_block (parser, if_p)); 15632 stmt = c_finish_oacc_host_data (loc, clauses, block); 15633 return stmt; 15634 } 15635 15636 15637 /* OpenACC 2.0: 15638 15639 # pragma acc loop oacc-loop-clause[optseq] new-line 15640 structured-block 15641 15642 LOC is the location of the #pragma token. 15643 */ 15644 15645 #define OACC_LOOP_CLAUSE_MASK \ 15646 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \ 15647 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \ 15648 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \ 15649 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \ 15650 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \ 15651 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \ 15652 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \ 15653 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \ 15654 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \ 15655 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) ) 15656 static tree 15657 c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name, 15658 omp_clause_mask mask, tree *cclauses, bool *if_p) 15659 { 15660 bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1; 15661 15662 strcat (p_name, " loop"); 15663 mask |= OACC_LOOP_CLAUSE_MASK; 15664 15665 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name, 15666 cclauses == NULL); 15667 if (cclauses) 15668 { 15669 clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel); 15670 if (*cclauses) 15671 *cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC); 15672 if (clauses) 15673 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC); 15674 } 15675 15676 tree block = c_begin_compound_stmt (true); 15677 tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL, 15678 if_p); 15679 block = c_end_compound_stmt (loc, block, true); 15680 add_stmt (block); 15681 15682 return stmt; 15683 } 15684 15685 /* OpenACC 2.0: 15686 # pragma acc kernels oacc-kernels-clause[optseq] new-line 15687 structured-block 15688 15689 or 15690 15691 # pragma acc parallel oacc-parallel-clause[optseq] new-line 15692 structured-block 15693 15694 LOC is the location of the #pragma token. 15695 */ 15696 15697 #define OACC_KERNELS_CLAUSE_MASK \ 15698 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \ 15699 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \ 15700 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \ 15701 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \ 15702 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \ 15703 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \ 15704 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \ 15705 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \ 15706 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \ 15707 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \ 15708 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \ 15709 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \ 15710 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) ) 15711 15712 #define OACC_PARALLEL_CLAUSE_MASK \ 15713 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \ 15714 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \ 15715 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \ 15716 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \ 15717 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \ 15718 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \ 15719 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \ 15720 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \ 15721 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \ 15722 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \ 15723 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \ 15724 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \ 15725 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \ 15726 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \ 15727 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \ 15728 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) ) 15729 15730 static tree 15731 c_parser_oacc_kernels_parallel (location_t loc, c_parser *parser, 15732 enum pragma_kind p_kind, char *p_name, 15733 bool *if_p) 15734 { 15735 omp_clause_mask mask; 15736 enum tree_code code; 15737 switch (p_kind) 15738 { 15739 case PRAGMA_OACC_KERNELS: 15740 strcat (p_name, " kernels"); 15741 mask = OACC_KERNELS_CLAUSE_MASK; 15742 code = OACC_KERNELS; 15743 break; 15744 case PRAGMA_OACC_PARALLEL: 15745 strcat (p_name, " parallel"); 15746 mask = OACC_PARALLEL_CLAUSE_MASK; 15747 code = OACC_PARALLEL; 15748 break; 15749 default: 15750 gcc_unreachable (); 15751 } 15752 15753 if (c_parser_next_token_is (parser, CPP_NAME)) 15754 { 15755 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 15756 if (strcmp (p, "loop") == 0) 15757 { 15758 c_parser_consume_token (parser); 15759 tree block = c_begin_omp_parallel (); 15760 tree clauses; 15761 c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p); 15762 return c_finish_omp_construct (loc, code, block, clauses); 15763 } 15764 } 15765 15766 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name); 15767 15768 tree block = c_begin_omp_parallel (); 15769 add_stmt (c_parser_omp_structured_block (parser, if_p)); 15770 15771 return c_finish_omp_construct (loc, code, block, clauses); 15772 } 15773 15774 /* OpenACC 2.0: 15775 # pragma acc routine oacc-routine-clause[optseq] new-line 15776 function-definition 15777 15778 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line 15779 */ 15780 15781 #define OACC_ROUTINE_CLAUSE_MASK \ 15782 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \ 15783 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \ 15784 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \ 15785 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) ) 15786 15787 /* Parse an OpenACC routine directive. For named directives, we apply 15788 immediately to the named function. For unnamed ones we then parse 15789 a declaration or definition, which must be for a function. */ 15790 15791 static void 15792 c_parser_oacc_routine (c_parser *parser, enum pragma_context context) 15793 { 15794 gcc_checking_assert (context == pragma_external); 15795 15796 oacc_routine_data data; 15797 data.error_seen = false; 15798 data.fndecl_seen = false; 15799 data.clauses = NULL_TREE; 15800 data.loc = c_parser_peek_token (parser)->location; 15801 15802 c_parser_consume_pragma (parser); 15803 15804 /* Look for optional '( name )'. */ 15805 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 15806 { 15807 c_parser_consume_token (parser); /* '(' */ 15808 15809 tree decl = NULL_TREE; 15810 c_token *name_token = c_parser_peek_token (parser); 15811 location_t name_loc = name_token->location; 15812 if (name_token->type == CPP_NAME 15813 && (name_token->id_kind == C_ID_ID 15814 || name_token->id_kind == C_ID_TYPENAME)) 15815 { 15816 decl = lookup_name (name_token->value); 15817 if (!decl) 15818 error_at (name_loc, 15819 "%qE has not been declared", name_token->value); 15820 c_parser_consume_token (parser); 15821 } 15822 else 15823 c_parser_error (parser, "expected function name"); 15824 15825 if (!decl 15826 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) 15827 { 15828 c_parser_skip_to_pragma_eol (parser, false); 15829 return; 15830 } 15831 15832 data.clauses 15833 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK, 15834 "#pragma acc routine"); 15835 15836 if (TREE_CODE (decl) != FUNCTION_DECL) 15837 { 15838 error_at (name_loc, "%qD does not refer to a function", decl); 15839 return; 15840 } 15841 15842 c_finish_oacc_routine (&data, decl, false); 15843 } 15844 else /* No optional '( name )'. */ 15845 { 15846 data.clauses 15847 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK, 15848 "#pragma acc routine"); 15849 15850 /* Emit a helpful diagnostic if there's another pragma following this 15851 one. Also don't allow a static assertion declaration, as in the 15852 following we'll just parse a *single* "declaration or function 15853 definition", and the static assertion counts an one. */ 15854 if (c_parser_next_token_is (parser, CPP_PRAGMA) 15855 || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT)) 15856 { 15857 error_at (data.loc, 15858 "%<#pragma acc routine%> not immediately followed by" 15859 " function declaration or definition"); 15860 /* ..., and then just keep going. */ 15861 return; 15862 } 15863 15864 /* We only have to consider the pragma_external case here. */ 15865 if (c_parser_next_token_is (parser, CPP_KEYWORD) 15866 && c_parser_peek_token (parser)->keyword == RID_EXTENSION) 15867 { 15868 int ext = disable_extension_diagnostics (); 15869 do 15870 c_parser_consume_token (parser); 15871 while (c_parser_next_token_is (parser, CPP_KEYWORD) 15872 && c_parser_peek_token (parser)->keyword == RID_EXTENSION); 15873 c_parser_declaration_or_fndef (parser, true, true, true, false, true, 15874 NULL, vNULL, &data); 15875 restore_extension_diagnostics (ext); 15876 } 15877 else 15878 c_parser_declaration_or_fndef (parser, true, true, true, false, true, 15879 NULL, vNULL, &data); 15880 } 15881 } 15882 15883 /* Finalize an OpenACC routine pragma, applying it to FNDECL. 15884 IS_DEFN is true if we're applying it to the definition. */ 15885 15886 static void 15887 c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl, 15888 bool is_defn) 15889 { 15890 /* Keep going if we're in error reporting mode. */ 15891 if (data->error_seen 15892 || fndecl == error_mark_node) 15893 return; 15894 15895 if (data->fndecl_seen) 15896 { 15897 error_at (data->loc, 15898 "%<#pragma acc routine%> not immediately followed by" 15899 " a single function declaration or definition"); 15900 data->error_seen = true; 15901 return; 15902 } 15903 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL) 15904 { 15905 error_at (data->loc, 15906 "%<#pragma acc routine%> not immediately followed by" 15907 " function declaration or definition"); 15908 data->error_seen = true; 15909 return; 15910 } 15911 15912 if (oacc_get_fn_attrib (fndecl)) 15913 { 15914 error_at (data->loc, 15915 "%<#pragma acc routine%> already applied to %qD", fndecl); 15916 data->error_seen = true; 15917 return; 15918 } 15919 15920 if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl))) 15921 { 15922 error_at (data->loc, 15923 TREE_USED (fndecl) 15924 ? G_("%<#pragma acc routine%> must be applied before use") 15925 : G_("%<#pragma acc routine%> must be applied before " 15926 "definition")); 15927 data->error_seen = true; 15928 return; 15929 } 15930 15931 /* Process the routine's dimension clauses. */ 15932 tree dims = oacc_build_routine_dims (data->clauses); 15933 oacc_replace_fn_attrib (fndecl, dims); 15934 15935 /* Add an "omp declare target" attribute. */ 15936 DECL_ATTRIBUTES (fndecl) 15937 = tree_cons (get_identifier ("omp declare target"), 15938 NULL_TREE, DECL_ATTRIBUTES (fndecl)); 15939 15940 /* Remember that we've used this "#pragma acc routine". */ 15941 data->fndecl_seen = true; 15942 } 15943 15944 /* OpenACC 2.0: 15945 # pragma acc update oacc-update-clause[optseq] new-line 15946 */ 15947 15948 #define OACC_UPDATE_CLAUSE_MASK \ 15949 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \ 15950 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \ 15951 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \ 15952 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \ 15953 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \ 15954 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) ) 15955 15956 static void 15957 c_parser_oacc_update (c_parser *parser) 15958 { 15959 location_t loc = c_parser_peek_token (parser)->location; 15960 15961 c_parser_consume_pragma (parser); 15962 15963 tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK, 15964 "#pragma acc update"); 15965 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE) 15966 { 15967 error_at (loc, 15968 "%<#pragma acc update%> must contain at least one " 15969 "%<device%> or %<host%> or %<self%> clause"); 15970 return; 15971 } 15972 15973 if (parser->error) 15974 return; 15975 15976 tree stmt = make_node (OACC_UPDATE); 15977 TREE_TYPE (stmt) = void_type_node; 15978 OACC_UPDATE_CLAUSES (stmt) = clauses; 15979 SET_EXPR_LOCATION (stmt, loc); 15980 add_stmt (stmt); 15981 } 15982 15983 /* OpenACC 2.0: 15984 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line 15985 15986 LOC is the location of the #pragma token. 15987 */ 15988 15989 #define OACC_WAIT_CLAUSE_MASK \ 15990 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) ) 15991 15992 static tree 15993 c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name) 15994 { 15995 tree clauses, list = NULL_TREE, stmt = NULL_TREE; 15996 15997 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN) 15998 list = c_parser_oacc_wait_list (parser, loc, list); 15999 16000 strcpy (p_name, " wait"); 16001 clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name); 16002 stmt = c_finish_oacc_wait (loc, list, clauses); 16003 add_stmt (stmt); 16004 16005 return stmt; 16006 } 16007 16008 /* OpenMP 2.5: 16009 # pragma omp atomic new-line 16010 expression-stmt 16011 16012 expression-stmt: 16013 x binop= expr | x++ | ++x | x-- | --x 16014 binop: 16015 +, *, -, /, &, ^, |, <<, >> 16016 16017 where x is an lvalue expression with scalar type. 16018 16019 OpenMP 3.1: 16020 # pragma omp atomic new-line 16021 update-stmt 16022 16023 # pragma omp atomic read new-line 16024 read-stmt 16025 16026 # pragma omp atomic write new-line 16027 write-stmt 16028 16029 # pragma omp atomic update new-line 16030 update-stmt 16031 16032 # pragma omp atomic capture new-line 16033 capture-stmt 16034 16035 # pragma omp atomic capture new-line 16036 capture-block 16037 16038 read-stmt: 16039 v = x 16040 write-stmt: 16041 x = expr 16042 update-stmt: 16043 expression-stmt | x = x binop expr 16044 capture-stmt: 16045 v = expression-stmt 16046 capture-block: 16047 { v = x; update-stmt; } | { update-stmt; v = x; } 16048 16049 OpenMP 4.0: 16050 update-stmt: 16051 expression-stmt | x = x binop expr | x = expr binop x 16052 capture-stmt: 16053 v = update-stmt 16054 capture-block: 16055 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; } 16056 16057 where x and v are lvalue expressions with scalar type. 16058 16059 LOC is the location of the #pragma token. */ 16060 16061 static void 16062 c_parser_omp_atomic (location_t loc, c_parser *parser) 16063 { 16064 tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE; 16065 tree lhs1 = NULL_TREE, rhs1 = NULL_TREE; 16066 tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE; 16067 enum tree_code code = ERROR_MARK, opcode = NOP_EXPR; 16068 enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED; 16069 struct c_expr expr; 16070 location_t eloc; 16071 bool structured_block = false; 16072 bool swapped = false; 16073 bool non_lvalue_p; 16074 bool first = true; 16075 tree clauses = NULL_TREE; 16076 16077 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 16078 { 16079 if (!first && c_parser_next_token_is (parser, CPP_COMMA)) 16080 c_parser_consume_token (parser); 16081 16082 first = false; 16083 16084 if (c_parser_next_token_is (parser, CPP_NAME)) 16085 { 16086 const char *p 16087 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 16088 location_t cloc = c_parser_peek_token (parser)->location; 16089 enum tree_code new_code = ERROR_MARK; 16090 enum omp_memory_order new_memory_order 16091 = OMP_MEMORY_ORDER_UNSPECIFIED; 16092 16093 if (!strcmp (p, "read")) 16094 new_code = OMP_ATOMIC_READ; 16095 else if (!strcmp (p, "write")) 16096 new_code = NOP_EXPR; 16097 else if (!strcmp (p, "update")) 16098 new_code = OMP_ATOMIC; 16099 else if (!strcmp (p, "capture")) 16100 new_code = OMP_ATOMIC_CAPTURE_NEW; 16101 else if (!strcmp (p, "seq_cst")) 16102 new_memory_order = OMP_MEMORY_ORDER_SEQ_CST; 16103 else if (!strcmp (p, "acq_rel")) 16104 new_memory_order = OMP_MEMORY_ORDER_ACQ_REL; 16105 else if (!strcmp (p, "release")) 16106 new_memory_order = OMP_MEMORY_ORDER_RELEASE; 16107 else if (!strcmp (p, "acquire")) 16108 new_memory_order = OMP_MEMORY_ORDER_ACQUIRE; 16109 else if (!strcmp (p, "relaxed")) 16110 new_memory_order = OMP_MEMORY_ORDER_RELAXED; 16111 else if (!strcmp (p, "hint")) 16112 { 16113 c_parser_consume_token (parser); 16114 clauses = c_parser_omp_clause_hint (parser, clauses); 16115 continue; 16116 } 16117 else 16118 { 16119 p = NULL; 16120 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, " 16121 "%<capture%>, %<seq_cst%>, %<acq_rel%>, " 16122 "%<release%>, %<relaxed%> or %<hint%> clause"); 16123 } 16124 if (p) 16125 { 16126 if (new_code != ERROR_MARK) 16127 { 16128 if (code != ERROR_MARK) 16129 error_at (cloc, "too many atomic clauses"); 16130 else 16131 code = new_code; 16132 } 16133 else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED) 16134 { 16135 if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED) 16136 error_at (cloc, "too many memory order clauses"); 16137 else 16138 memory_order = new_memory_order; 16139 } 16140 c_parser_consume_token (parser); 16141 continue; 16142 } 16143 } 16144 break; 16145 } 16146 c_parser_skip_to_pragma_eol (parser); 16147 16148 if (code == ERROR_MARK) 16149 code = OMP_ATOMIC; 16150 if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED) 16151 { 16152 omp_requires_mask 16153 = (enum omp_requires) (omp_requires_mask 16154 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED); 16155 switch ((enum omp_memory_order) 16156 (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER)) 16157 { 16158 case OMP_MEMORY_ORDER_UNSPECIFIED: 16159 case OMP_MEMORY_ORDER_RELAXED: 16160 memory_order = OMP_MEMORY_ORDER_RELAXED; 16161 break; 16162 case OMP_MEMORY_ORDER_SEQ_CST: 16163 memory_order = OMP_MEMORY_ORDER_SEQ_CST; 16164 break; 16165 case OMP_MEMORY_ORDER_ACQ_REL: 16166 switch (code) 16167 { 16168 case OMP_ATOMIC_READ: 16169 memory_order = OMP_MEMORY_ORDER_ACQUIRE; 16170 break; 16171 case NOP_EXPR: /* atomic write */ 16172 case OMP_ATOMIC: 16173 memory_order = OMP_MEMORY_ORDER_RELEASE; 16174 break; 16175 default: 16176 memory_order = OMP_MEMORY_ORDER_ACQ_REL; 16177 break; 16178 } 16179 break; 16180 default: 16181 gcc_unreachable (); 16182 } 16183 } 16184 else 16185 switch (code) 16186 { 16187 case OMP_ATOMIC_READ: 16188 if (memory_order == OMP_MEMORY_ORDER_ACQ_REL 16189 || memory_order == OMP_MEMORY_ORDER_RELEASE) 16190 { 16191 error_at (loc, "%<#pragma omp atomic read%> incompatible with " 16192 "%<acq_rel%> or %<release%> clauses"); 16193 memory_order = OMP_MEMORY_ORDER_SEQ_CST; 16194 } 16195 break; 16196 case NOP_EXPR: /* atomic write */ 16197 if (memory_order == OMP_MEMORY_ORDER_ACQ_REL 16198 || memory_order == OMP_MEMORY_ORDER_ACQUIRE) 16199 { 16200 error_at (loc, "%<#pragma omp atomic write%> incompatible with " 16201 "%<acq_rel%> or %<acquire%> clauses"); 16202 memory_order = OMP_MEMORY_ORDER_SEQ_CST; 16203 } 16204 break; 16205 case OMP_ATOMIC: 16206 if (memory_order == OMP_MEMORY_ORDER_ACQ_REL 16207 || memory_order == OMP_MEMORY_ORDER_ACQUIRE) 16208 { 16209 error_at (loc, "%<#pragma omp atomic update%> incompatible with " 16210 "%<acq_rel%> or %<acquire%> clauses"); 16211 memory_order = OMP_MEMORY_ORDER_SEQ_CST; 16212 } 16213 break; 16214 default: 16215 break; 16216 } 16217 16218 switch (code) 16219 { 16220 case OMP_ATOMIC_READ: 16221 case NOP_EXPR: /* atomic write */ 16222 v = c_parser_cast_expression (parser, NULL).value; 16223 non_lvalue_p = !lvalue_p (v); 16224 v = c_fully_fold (v, false, NULL, true); 16225 if (v == error_mark_node) 16226 goto saw_error; 16227 if (non_lvalue_p) 16228 v = non_lvalue (v); 16229 loc = c_parser_peek_token (parser)->location; 16230 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) 16231 goto saw_error; 16232 if (code == NOP_EXPR) 16233 { 16234 lhs = c_parser_expression (parser).value; 16235 lhs = c_fully_fold (lhs, false, NULL); 16236 if (lhs == error_mark_node) 16237 goto saw_error; 16238 } 16239 else 16240 { 16241 lhs = c_parser_cast_expression (parser, NULL).value; 16242 non_lvalue_p = !lvalue_p (lhs); 16243 lhs = c_fully_fold (lhs, false, NULL, true); 16244 if (lhs == error_mark_node) 16245 goto saw_error; 16246 if (non_lvalue_p) 16247 lhs = non_lvalue (lhs); 16248 } 16249 if (code == NOP_EXPR) 16250 { 16251 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR 16252 opcode. */ 16253 code = OMP_ATOMIC; 16254 rhs = lhs; 16255 lhs = v; 16256 v = NULL_TREE; 16257 } 16258 goto done; 16259 case OMP_ATOMIC_CAPTURE_NEW: 16260 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 16261 { 16262 c_parser_consume_token (parser); 16263 structured_block = true; 16264 } 16265 else 16266 { 16267 v = c_parser_cast_expression (parser, NULL).value; 16268 non_lvalue_p = !lvalue_p (v); 16269 v = c_fully_fold (v, false, NULL, true); 16270 if (v == error_mark_node) 16271 goto saw_error; 16272 if (non_lvalue_p) 16273 v = non_lvalue (v); 16274 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) 16275 goto saw_error; 16276 } 16277 break; 16278 default: 16279 break; 16280 } 16281 16282 /* For structured_block case we don't know yet whether 16283 old or new x should be captured. */ 16284 restart: 16285 eloc = c_parser_peek_token (parser)->location; 16286 expr = c_parser_cast_expression (parser, NULL); 16287 lhs = expr.value; 16288 expr = default_function_array_conversion (eloc, expr); 16289 unfolded_lhs = expr.value; 16290 lhs = c_fully_fold (lhs, false, NULL, true); 16291 orig_lhs = lhs; 16292 switch (TREE_CODE (lhs)) 16293 { 16294 case ERROR_MARK: 16295 saw_error: 16296 c_parser_skip_to_end_of_block_or_statement (parser); 16297 if (structured_block) 16298 { 16299 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 16300 c_parser_consume_token (parser); 16301 else if (code == OMP_ATOMIC_CAPTURE_NEW) 16302 { 16303 c_parser_skip_to_end_of_block_or_statement (parser); 16304 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 16305 c_parser_consume_token (parser); 16306 } 16307 } 16308 return; 16309 16310 case POSTINCREMENT_EXPR: 16311 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block) 16312 code = OMP_ATOMIC_CAPTURE_OLD; 16313 /* FALLTHROUGH */ 16314 case PREINCREMENT_EXPR: 16315 lhs = TREE_OPERAND (lhs, 0); 16316 unfolded_lhs = NULL_TREE; 16317 opcode = PLUS_EXPR; 16318 rhs = integer_one_node; 16319 break; 16320 16321 case POSTDECREMENT_EXPR: 16322 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block) 16323 code = OMP_ATOMIC_CAPTURE_OLD; 16324 /* FALLTHROUGH */ 16325 case PREDECREMENT_EXPR: 16326 lhs = TREE_OPERAND (lhs, 0); 16327 unfolded_lhs = NULL_TREE; 16328 opcode = MINUS_EXPR; 16329 rhs = integer_one_node; 16330 break; 16331 16332 case COMPOUND_EXPR: 16333 if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR 16334 && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR 16335 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR 16336 && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0) 16337 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND 16338 (TREE_OPERAND (lhs, 1), 0), 0))) 16339 == BOOLEAN_TYPE) 16340 /* Undo effects of boolean_increment for post {in,de}crement. */ 16341 lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0); 16342 /* FALLTHRU */ 16343 case MODIFY_EXPR: 16344 if (TREE_CODE (lhs) == MODIFY_EXPR 16345 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE) 16346 { 16347 /* Undo effects of boolean_increment. */ 16348 if (integer_onep (TREE_OPERAND (lhs, 1))) 16349 { 16350 /* This is pre or post increment. */ 16351 rhs = TREE_OPERAND (lhs, 1); 16352 lhs = TREE_OPERAND (lhs, 0); 16353 unfolded_lhs = NULL_TREE; 16354 opcode = NOP_EXPR; 16355 if (code == OMP_ATOMIC_CAPTURE_NEW 16356 && !structured_block 16357 && TREE_CODE (orig_lhs) == COMPOUND_EXPR) 16358 code = OMP_ATOMIC_CAPTURE_OLD; 16359 break; 16360 } 16361 if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR 16362 && TREE_OPERAND (lhs, 0) 16363 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) 16364 { 16365 /* This is pre or post decrement. */ 16366 rhs = TREE_OPERAND (lhs, 1); 16367 lhs = TREE_OPERAND (lhs, 0); 16368 unfolded_lhs = NULL_TREE; 16369 opcode = NOP_EXPR; 16370 if (code == OMP_ATOMIC_CAPTURE_NEW 16371 && !structured_block 16372 && TREE_CODE (orig_lhs) == COMPOUND_EXPR) 16373 code = OMP_ATOMIC_CAPTURE_OLD; 16374 break; 16375 } 16376 } 16377 /* FALLTHRU */ 16378 default: 16379 if (!lvalue_p (unfolded_lhs)) 16380 lhs = non_lvalue (lhs); 16381 switch (c_parser_peek_token (parser)->type) 16382 { 16383 case CPP_MULT_EQ: 16384 opcode = MULT_EXPR; 16385 break; 16386 case CPP_DIV_EQ: 16387 opcode = TRUNC_DIV_EXPR; 16388 break; 16389 case CPP_PLUS_EQ: 16390 opcode = PLUS_EXPR; 16391 break; 16392 case CPP_MINUS_EQ: 16393 opcode = MINUS_EXPR; 16394 break; 16395 case CPP_LSHIFT_EQ: 16396 opcode = LSHIFT_EXPR; 16397 break; 16398 case CPP_RSHIFT_EQ: 16399 opcode = RSHIFT_EXPR; 16400 break; 16401 case CPP_AND_EQ: 16402 opcode = BIT_AND_EXPR; 16403 break; 16404 case CPP_OR_EQ: 16405 opcode = BIT_IOR_EXPR; 16406 break; 16407 case CPP_XOR_EQ: 16408 opcode = BIT_XOR_EXPR; 16409 break; 16410 case CPP_EQ: 16411 c_parser_consume_token (parser); 16412 eloc = c_parser_peek_token (parser)->location; 16413 expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs); 16414 rhs1 = expr.value; 16415 switch (TREE_CODE (rhs1)) 16416 { 16417 case MULT_EXPR: 16418 case TRUNC_DIV_EXPR: 16419 case RDIV_EXPR: 16420 case PLUS_EXPR: 16421 case MINUS_EXPR: 16422 case LSHIFT_EXPR: 16423 case RSHIFT_EXPR: 16424 case BIT_AND_EXPR: 16425 case BIT_IOR_EXPR: 16426 case BIT_XOR_EXPR: 16427 if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs)) 16428 { 16429 opcode = TREE_CODE (rhs1); 16430 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL, 16431 true); 16432 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL, 16433 true); 16434 goto stmt_done; 16435 } 16436 if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs)) 16437 { 16438 opcode = TREE_CODE (rhs1); 16439 rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL, 16440 true); 16441 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL, 16442 true); 16443 swapped = !commutative_tree_code (opcode); 16444 goto stmt_done; 16445 } 16446 break; 16447 case ERROR_MARK: 16448 goto saw_error; 16449 default: 16450 break; 16451 } 16452 if (c_parser_peek_token (parser)->type == CPP_SEMICOLON) 16453 { 16454 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW) 16455 { 16456 code = OMP_ATOMIC_CAPTURE_OLD; 16457 v = lhs; 16458 lhs = NULL_TREE; 16459 expr = default_function_array_read_conversion (eloc, expr); 16460 unfolded_lhs1 = expr.value; 16461 lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true); 16462 rhs1 = NULL_TREE; 16463 c_parser_consume_token (parser); 16464 goto restart; 16465 } 16466 if (structured_block) 16467 { 16468 opcode = NOP_EXPR; 16469 expr = default_function_array_read_conversion (eloc, expr); 16470 rhs = c_fully_fold (expr.value, false, NULL, true); 16471 rhs1 = NULL_TREE; 16472 goto stmt_done; 16473 } 16474 } 16475 c_parser_error (parser, "invalid form of %<#pragma omp atomic%>"); 16476 goto saw_error; 16477 default: 16478 c_parser_error (parser, 16479 "invalid operator for %<#pragma omp atomic%>"); 16480 goto saw_error; 16481 } 16482 16483 /* Arrange to pass the location of the assignment operator to 16484 c_finish_omp_atomic. */ 16485 loc = c_parser_peek_token (parser)->location; 16486 c_parser_consume_token (parser); 16487 eloc = c_parser_peek_token (parser)->location; 16488 expr = c_parser_expression (parser); 16489 expr = default_function_array_read_conversion (eloc, expr); 16490 rhs = expr.value; 16491 rhs = c_fully_fold (rhs, false, NULL, true); 16492 break; 16493 } 16494 stmt_done: 16495 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW) 16496 { 16497 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>")) 16498 goto saw_error; 16499 v = c_parser_cast_expression (parser, NULL).value; 16500 non_lvalue_p = !lvalue_p (v); 16501 v = c_fully_fold (v, false, NULL, true); 16502 if (v == error_mark_node) 16503 goto saw_error; 16504 if (non_lvalue_p) 16505 v = non_lvalue (v); 16506 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) 16507 goto saw_error; 16508 eloc = c_parser_peek_token (parser)->location; 16509 expr = c_parser_cast_expression (parser, NULL); 16510 lhs1 = expr.value; 16511 expr = default_function_array_read_conversion (eloc, expr); 16512 unfolded_lhs1 = expr.value; 16513 lhs1 = c_fully_fold (lhs1, false, NULL, true); 16514 if (lhs1 == error_mark_node) 16515 goto saw_error; 16516 if (!lvalue_p (unfolded_lhs1)) 16517 lhs1 = non_lvalue (lhs1); 16518 } 16519 if (structured_block) 16520 { 16521 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 16522 c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"); 16523 } 16524 done: 16525 if (unfolded_lhs && unfolded_lhs1 16526 && !c_tree_equal (unfolded_lhs, unfolded_lhs1)) 16527 { 16528 error ("%<#pragma omp atomic capture%> uses two different " 16529 "expressions for memory"); 16530 stmt = error_mark_node; 16531 } 16532 else 16533 stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1, 16534 swapped, memory_order); 16535 if (stmt != error_mark_node) 16536 add_stmt (stmt); 16537 16538 if (!structured_block) 16539 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 16540 } 16541 16542 16543 /* OpenMP 2.5: 16544 # pragma omp barrier new-line 16545 */ 16546 16547 static void 16548 c_parser_omp_barrier (c_parser *parser) 16549 { 16550 location_t loc = c_parser_peek_token (parser)->location; 16551 c_parser_consume_pragma (parser); 16552 c_parser_skip_to_pragma_eol (parser); 16553 16554 c_finish_omp_barrier (loc); 16555 } 16556 16557 /* OpenMP 2.5: 16558 # pragma omp critical [(name)] new-line 16559 structured-block 16560 16561 OpenMP 4.5: 16562 # pragma omp critical [(name) [hint(expression)]] new-line 16563 16564 LOC is the location of the #pragma itself. */ 16565 16566 #define OMP_CRITICAL_CLAUSE_MASK \ 16567 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) ) 16568 16569 static tree 16570 c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p) 16571 { 16572 tree stmt, name = NULL_TREE, clauses = NULL_TREE; 16573 16574 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 16575 { 16576 c_parser_consume_token (parser); 16577 if (c_parser_next_token_is (parser, CPP_NAME)) 16578 { 16579 name = c_parser_peek_token (parser)->value; 16580 c_parser_consume_token (parser); 16581 c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 16582 } 16583 else 16584 c_parser_error (parser, "expected identifier"); 16585 16586 if (c_parser_next_token_is (parser, CPP_COMMA) 16587 && c_parser_peek_2nd_token (parser)->type == CPP_NAME) 16588 c_parser_consume_token (parser); 16589 16590 clauses = c_parser_omp_all_clauses (parser, 16591 OMP_CRITICAL_CLAUSE_MASK, 16592 "#pragma omp critical"); 16593 } 16594 else 16595 { 16596 if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 16597 c_parser_error (parser, "expected %<(%> or end of line"); 16598 c_parser_skip_to_pragma_eol (parser); 16599 } 16600 16601 stmt = c_parser_omp_structured_block (parser, if_p); 16602 return c_finish_omp_critical (loc, stmt, name, clauses); 16603 } 16604 16605 /* OpenMP 5.0: 16606 # pragma omp depobj ( depobj ) depobj-clause new-line 16607 16608 depobj-clause: 16609 depend (dependence-type : locator) 16610 destroy 16611 update (dependence-type) 16612 16613 dependence-type: 16614 in 16615 out 16616 inout 16617 mutexinout */ 16618 16619 static void 16620 c_parser_omp_depobj (c_parser *parser) 16621 { 16622 location_t loc = c_parser_peek_token (parser)->location; 16623 c_parser_consume_pragma (parser); 16624 matching_parens parens; 16625 if (!parens.require_open (parser)) 16626 { 16627 c_parser_skip_to_pragma_eol (parser); 16628 return; 16629 } 16630 16631 tree depobj = c_parser_expr_no_commas (parser, NULL).value; 16632 if (depobj != error_mark_node) 16633 { 16634 if (!lvalue_p (depobj)) 16635 { 16636 error_at (EXPR_LOC_OR_LOC (depobj, loc), 16637 "%<depobj%> expression is not lvalue expression"); 16638 depobj = error_mark_node; 16639 } 16640 else 16641 { 16642 tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR, 16643 depobj, false); 16644 if (addr == error_mark_node) 16645 depobj = error_mark_node; 16646 else 16647 depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc), 16648 addr, RO_UNARY_STAR); 16649 } 16650 } 16651 16652 parens.skip_until_found_close (parser); 16653 tree clause = NULL_TREE; 16654 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_SOURCE; 16655 location_t c_loc = c_parser_peek_token (parser)->location; 16656 if (c_parser_next_token_is (parser, CPP_NAME)) 16657 { 16658 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 16659 16660 c_parser_consume_token (parser); 16661 if (!strcmp ("depend", p)) 16662 { 16663 clause = c_parser_omp_clause_depend (parser, NULL_TREE); 16664 clause = c_finish_omp_clauses (clause, C_ORT_OMP); 16665 if (!clause) 16666 clause = error_mark_node; 16667 } 16668 else if (!strcmp ("destroy", p)) 16669 kind = OMP_CLAUSE_DEPEND_LAST; 16670 else if (!strcmp ("update", p)) 16671 { 16672 matching_parens c_parens; 16673 if (c_parens.require_open (parser)) 16674 { 16675 location_t c2_loc = c_parser_peek_token (parser)->location; 16676 if (c_parser_next_token_is (parser, CPP_NAME)) 16677 { 16678 const char *p2 16679 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 16680 16681 c_parser_consume_token (parser); 16682 if (!strcmp ("in", p2)) 16683 kind = OMP_CLAUSE_DEPEND_IN; 16684 else if (!strcmp ("out", p2)) 16685 kind = OMP_CLAUSE_DEPEND_OUT; 16686 else if (!strcmp ("inout", p2)) 16687 kind = OMP_CLAUSE_DEPEND_INOUT; 16688 else if (!strcmp ("mutexinoutset", p2)) 16689 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET; 16690 } 16691 if (kind == OMP_CLAUSE_DEPEND_SOURCE) 16692 { 16693 clause = error_mark_node; 16694 error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%> or " 16695 "%<mutexinoutset%>"); 16696 } 16697 c_parens.skip_until_found_close (parser); 16698 } 16699 else 16700 clause = error_mark_node; 16701 } 16702 } 16703 if (!clause && kind == OMP_CLAUSE_DEPEND_SOURCE) 16704 { 16705 clause = error_mark_node; 16706 error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause"); 16707 } 16708 c_parser_skip_to_pragma_eol (parser); 16709 16710 c_finish_omp_depobj (loc, depobj, kind, clause); 16711 } 16712 16713 16714 /* OpenMP 2.5: 16715 # pragma omp flush flush-vars[opt] new-line 16716 16717 flush-vars: 16718 ( variable-list ) 16719 16720 OpenMP 5.0: 16721 # pragma omp flush memory-order-clause new-line */ 16722 16723 static void 16724 c_parser_omp_flush (c_parser *parser) 16725 { 16726 location_t loc = c_parser_peek_token (parser)->location; 16727 c_parser_consume_pragma (parser); 16728 enum memmodel mo = MEMMODEL_LAST; 16729 if (c_parser_next_token_is (parser, CPP_NAME)) 16730 { 16731 const char *p 16732 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 16733 16734 if (!strcmp (p, "acq_rel")) 16735 mo = MEMMODEL_ACQ_REL; 16736 else if (!strcmp (p, "release")) 16737 mo = MEMMODEL_RELEASE; 16738 else if (!strcmp (p, "acquire")) 16739 mo = MEMMODEL_ACQUIRE; 16740 else 16741 error_at (c_parser_peek_token (parser)->location, 16742 "expected %<acq_rel%>, %<release%> or %<acquire%>"); 16743 c_parser_consume_token (parser); 16744 } 16745 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 16746 { 16747 if (mo != MEMMODEL_LAST) 16748 error_at (c_parser_peek_token (parser)->location, 16749 "%<flush%> list specified together with memory order " 16750 "clause"); 16751 c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL); 16752 } 16753 else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 16754 c_parser_error (parser, "expected %<(%> or end of line"); 16755 c_parser_skip_to_pragma_eol (parser); 16756 16757 c_finish_omp_flush (loc, mo); 16758 } 16759 16760 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP. 16761 The real trick here is to determine the loop control variable early 16762 so that we can push a new decl if necessary to make it private. 16763 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp", 16764 respectively. */ 16765 16766 static tree 16767 c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code, 16768 tree clauses, tree *cclauses, bool *if_p) 16769 { 16770 tree decl, cond, incr, save_break, save_cont, body, init, stmt, cl; 16771 tree declv, condv, incrv, initv, ret = NULL_TREE; 16772 tree pre_body = NULL_TREE, this_pre_body; 16773 tree ordered_cl = NULL_TREE; 16774 bool fail = false, open_brace_parsed = false; 16775 int i, collapse = 1, ordered = 0, count, nbraces = 0; 16776 location_t for_loc; 16777 bool tiling = false; 16778 vec<tree, va_gc> *for_block = make_tree_vector (); 16779 16780 for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl)) 16781 if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE) 16782 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl)); 16783 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE) 16784 { 16785 tiling = true; 16786 collapse = list_length (OMP_CLAUSE_TILE_LIST (cl)); 16787 } 16788 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED 16789 && OMP_CLAUSE_ORDERED_EXPR (cl)) 16790 { 16791 ordered_cl = cl; 16792 ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl)); 16793 } 16794 16795 if (ordered && ordered < collapse) 16796 { 16797 error_at (OMP_CLAUSE_LOCATION (ordered_cl), 16798 "%<ordered%> clause parameter is less than %<collapse%>"); 16799 OMP_CLAUSE_ORDERED_EXPR (ordered_cl) 16800 = build_int_cst (NULL_TREE, collapse); 16801 ordered = collapse; 16802 } 16803 if (ordered) 16804 { 16805 for (tree *pc = &clauses; *pc; ) 16806 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR) 16807 { 16808 error_at (OMP_CLAUSE_LOCATION (*pc), 16809 "%<linear%> clause may not be specified together " 16810 "with %<ordered%> clause with a parameter"); 16811 *pc = OMP_CLAUSE_CHAIN (*pc); 16812 } 16813 else 16814 pc = &OMP_CLAUSE_CHAIN (*pc); 16815 } 16816 16817 gcc_assert (tiling || (collapse >= 1 && ordered >= 0)); 16818 count = ordered ? ordered : collapse; 16819 16820 declv = make_tree_vec (count); 16821 initv = make_tree_vec (count); 16822 condv = make_tree_vec (count); 16823 incrv = make_tree_vec (count); 16824 16825 if (!c_parser_next_token_is_keyword (parser, RID_FOR)) 16826 { 16827 c_parser_error (parser, "for statement expected"); 16828 return NULL; 16829 } 16830 for_loc = c_parser_peek_token (parser)->location; 16831 c_parser_consume_token (parser); 16832 16833 for (i = 0; i < count; i++) 16834 { 16835 int bracecount = 0; 16836 16837 matching_parens parens; 16838 if (!parens.require_open (parser)) 16839 goto pop_scopes; 16840 16841 /* Parse the initialization declaration or expression. */ 16842 if (c_parser_next_tokens_start_declaration (parser)) 16843 { 16844 if (i > 0) 16845 vec_safe_push (for_block, c_begin_compound_stmt (true)); 16846 this_pre_body = push_stmt_list (); 16847 c_parser_declaration_or_fndef (parser, true, true, true, true, true, 16848 NULL, vNULL); 16849 if (this_pre_body) 16850 { 16851 this_pre_body = pop_stmt_list (this_pre_body); 16852 if (pre_body) 16853 { 16854 tree t = pre_body; 16855 pre_body = push_stmt_list (); 16856 add_stmt (t); 16857 add_stmt (this_pre_body); 16858 pre_body = pop_stmt_list (pre_body); 16859 } 16860 else 16861 pre_body = this_pre_body; 16862 } 16863 decl = check_for_loop_decls (for_loc, flag_isoc99); 16864 if (decl == NULL) 16865 goto error_init; 16866 if (DECL_INITIAL (decl) == error_mark_node) 16867 decl = error_mark_node; 16868 init = decl; 16869 } 16870 else if (c_parser_next_token_is (parser, CPP_NAME) 16871 && c_parser_peek_2nd_token (parser)->type == CPP_EQ) 16872 { 16873 struct c_expr decl_exp; 16874 struct c_expr init_exp; 16875 location_t init_loc; 16876 16877 decl_exp = c_parser_postfix_expression (parser); 16878 decl = decl_exp.value; 16879 16880 c_parser_require (parser, CPP_EQ, "expected %<=%>"); 16881 16882 init_loc = c_parser_peek_token (parser)->location; 16883 init_exp = c_parser_expr_no_commas (parser, NULL); 16884 init_exp = default_function_array_read_conversion (init_loc, 16885 init_exp); 16886 init = build_modify_expr (init_loc, decl, decl_exp.original_type, 16887 NOP_EXPR, init_loc, init_exp.value, 16888 init_exp.original_type); 16889 init = c_process_expr_stmt (init_loc, init); 16890 16891 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 16892 } 16893 else 16894 { 16895 error_init: 16896 c_parser_error (parser, 16897 "expected iteration declaration or initialization"); 16898 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 16899 "expected %<)%>"); 16900 fail = true; 16901 goto parse_next; 16902 } 16903 16904 /* Parse the loop condition. */ 16905 cond = NULL_TREE; 16906 if (c_parser_next_token_is_not (parser, CPP_SEMICOLON)) 16907 { 16908 location_t cond_loc = c_parser_peek_token (parser)->location; 16909 struct c_expr cond_expr 16910 = c_parser_binary_expression (parser, NULL, NULL_TREE); 16911 16912 cond = cond_expr.value; 16913 cond = c_objc_common_truthvalue_conversion (cond_loc, cond); 16914 if (COMPARISON_CLASS_P (cond)) 16915 { 16916 tree op0 = TREE_OPERAND (cond, 0), op1 = TREE_OPERAND (cond, 1); 16917 op0 = c_fully_fold (op0, false, NULL); 16918 op1 = c_fully_fold (op1, false, NULL); 16919 TREE_OPERAND (cond, 0) = op0; 16920 TREE_OPERAND (cond, 1) = op1; 16921 } 16922 switch (cond_expr.original_code) 16923 { 16924 case GT_EXPR: 16925 case GE_EXPR: 16926 case LT_EXPR: 16927 case LE_EXPR: 16928 break; 16929 case NE_EXPR: 16930 if (code != OACC_LOOP) 16931 break; 16932 /* FALLTHRU. */ 16933 default: 16934 /* Can't be cond = error_mark_node, because we want to preserve 16935 the location until c_finish_omp_for. */ 16936 cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node); 16937 break; 16938 } 16939 protected_set_expr_location (cond, cond_loc); 16940 } 16941 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 16942 16943 /* Parse the increment expression. */ 16944 incr = NULL_TREE; 16945 if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN)) 16946 { 16947 location_t incr_loc = c_parser_peek_token (parser)->location; 16948 16949 incr = c_process_expr_stmt (incr_loc, 16950 c_parser_expression (parser).value); 16951 } 16952 parens.skip_until_found_close (parser); 16953 16954 if (decl == NULL || decl == error_mark_node || init == error_mark_node) 16955 fail = true; 16956 else 16957 { 16958 TREE_VEC_ELT (declv, i) = decl; 16959 TREE_VEC_ELT (initv, i) = init; 16960 TREE_VEC_ELT (condv, i) = cond; 16961 TREE_VEC_ELT (incrv, i) = incr; 16962 } 16963 16964 parse_next: 16965 if (i == count - 1) 16966 break; 16967 16968 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed 16969 in between the collapsed for loops to be still considered perfectly 16970 nested. Hopefully the final version clarifies this. 16971 For now handle (multiple) {'s and empty statements. */ 16972 do 16973 { 16974 if (c_parser_next_token_is_keyword (parser, RID_FOR)) 16975 { 16976 c_parser_consume_token (parser); 16977 break; 16978 } 16979 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 16980 { 16981 c_parser_consume_token (parser); 16982 bracecount++; 16983 } 16984 else if (bracecount 16985 && c_parser_next_token_is (parser, CPP_SEMICOLON)) 16986 c_parser_consume_token (parser); 16987 else 16988 { 16989 c_parser_error (parser, "not enough perfectly nested loops"); 16990 if (bracecount) 16991 { 16992 open_brace_parsed = true; 16993 bracecount--; 16994 } 16995 fail = true; 16996 count = 0; 16997 break; 16998 } 16999 } 17000 while (1); 17001 17002 nbraces += bracecount; 17003 } 17004 17005 if (nbraces) 17006 if_p = NULL; 17007 17008 save_break = c_break_label; 17009 c_break_label = size_one_node; 17010 save_cont = c_cont_label; 17011 c_cont_label = NULL_TREE; 17012 body = push_stmt_list (); 17013 17014 if (open_brace_parsed) 17015 { 17016 location_t here = c_parser_peek_token (parser)->location; 17017 stmt = c_begin_compound_stmt (true); 17018 c_parser_compound_statement_nostart (parser); 17019 add_stmt (c_end_compound_stmt (here, stmt, true)); 17020 } 17021 else 17022 add_stmt (c_parser_c99_block_statement (parser, if_p)); 17023 if (c_cont_label) 17024 { 17025 tree t = build1 (LABEL_EXPR, void_type_node, c_cont_label); 17026 SET_EXPR_LOCATION (t, loc); 17027 add_stmt (t); 17028 } 17029 17030 body = pop_stmt_list (body); 17031 c_break_label = save_break; 17032 c_cont_label = save_cont; 17033 17034 while (nbraces) 17035 { 17036 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 17037 { 17038 c_parser_consume_token (parser); 17039 nbraces--; 17040 } 17041 else if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 17042 c_parser_consume_token (parser); 17043 else 17044 { 17045 c_parser_error (parser, "collapsed loops not perfectly nested"); 17046 while (nbraces) 17047 { 17048 location_t here = c_parser_peek_token (parser)->location; 17049 stmt = c_begin_compound_stmt (true); 17050 add_stmt (body); 17051 c_parser_compound_statement_nostart (parser); 17052 body = c_end_compound_stmt (here, stmt, true); 17053 nbraces--; 17054 } 17055 goto pop_scopes; 17056 } 17057 } 17058 17059 /* Only bother calling c_finish_omp_for if we haven't already generated 17060 an error from the initialization parsing. */ 17061 if (!fail) 17062 { 17063 stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv, 17064 incrv, body, pre_body, true); 17065 17066 /* Check for iterators appearing in lb, b or incr expressions. */ 17067 if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL)) 17068 stmt = NULL_TREE; 17069 17070 if (stmt) 17071 { 17072 add_stmt (stmt); 17073 17074 if (cclauses != NULL 17075 && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL) 17076 { 17077 tree *c; 17078 for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; ) 17079 if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE 17080 && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE) 17081 c = &OMP_CLAUSE_CHAIN (*c); 17082 else 17083 { 17084 for (i = 0; i < count; i++) 17085 if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c)) 17086 break; 17087 if (i == count) 17088 c = &OMP_CLAUSE_CHAIN (*c); 17089 else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE) 17090 { 17091 error_at (loc, 17092 "iteration variable %qD should not be firstprivate", 17093 OMP_CLAUSE_DECL (*c)); 17094 *c = OMP_CLAUSE_CHAIN (*c); 17095 } 17096 else 17097 { 17098 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */ 17099 tree l = *c; 17100 *c = OMP_CLAUSE_CHAIN (*c); 17101 if (code == OMP_SIMD) 17102 { 17103 OMP_CLAUSE_CHAIN (l) 17104 = cclauses[C_OMP_CLAUSE_SPLIT_FOR]; 17105 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l; 17106 } 17107 else 17108 { 17109 OMP_CLAUSE_CHAIN (l) = clauses; 17110 clauses = l; 17111 } 17112 } 17113 } 17114 } 17115 OMP_FOR_CLAUSES (stmt) = clauses; 17116 } 17117 ret = stmt; 17118 } 17119 pop_scopes: 17120 while (!for_block->is_empty ()) 17121 { 17122 /* FIXME diagnostics: LOC below should be the actual location of 17123 this particular for block. We need to build a list of 17124 locations to go along with FOR_BLOCK. */ 17125 stmt = c_end_compound_stmt (loc, for_block->pop (), true); 17126 add_stmt (stmt); 17127 } 17128 release_tree_vector (for_block); 17129 return ret; 17130 } 17131 17132 /* Helper function for OpenMP parsing, split clauses and call 17133 finish_omp_clauses on each of the set of clauses afterwards. */ 17134 17135 static void 17136 omp_split_clauses (location_t loc, enum tree_code code, 17137 omp_clause_mask mask, tree clauses, tree *cclauses) 17138 { 17139 int i; 17140 c_omp_split_clauses (loc, code, mask, clauses, cclauses); 17141 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++) 17142 if (cclauses[i]) 17143 cclauses[i] = c_finish_omp_clauses (cclauses[i], C_ORT_OMP); 17144 } 17145 17146 /* OpenMP 4.0: 17147 #pragma omp simd simd-clause[optseq] new-line 17148 for-loop 17149 17150 LOC is the location of the #pragma token. 17151 */ 17152 17153 #define OMP_SIMD_CLAUSE_MASK \ 17154 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \ 17155 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \ 17156 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \ 17157 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \ 17158 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 17159 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ 17160 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ 17161 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \ 17162 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 17163 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL)) 17164 17165 static tree 17166 c_parser_omp_simd (location_t loc, c_parser *parser, 17167 char *p_name, omp_clause_mask mask, tree *cclauses, 17168 bool *if_p) 17169 { 17170 tree block, clauses, ret; 17171 17172 strcat (p_name, " simd"); 17173 mask |= OMP_SIMD_CLAUSE_MASK; 17174 17175 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); 17176 if (cclauses) 17177 { 17178 omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses); 17179 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD]; 17180 tree c = omp_find_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR], 17181 OMP_CLAUSE_ORDERED); 17182 if (c && OMP_CLAUSE_ORDERED_EXPR (c)) 17183 { 17184 error_at (OMP_CLAUSE_LOCATION (c), 17185 "%<ordered%> clause with parameter may not be specified " 17186 "on %qs construct", p_name); 17187 OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE; 17188 } 17189 } 17190 17191 block = c_begin_compound_stmt (true); 17192 ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p); 17193 block = c_end_compound_stmt (loc, block, true); 17194 add_stmt (block); 17195 17196 return ret; 17197 } 17198 17199 /* OpenMP 2.5: 17200 #pragma omp for for-clause[optseq] new-line 17201 for-loop 17202 17203 OpenMP 4.0: 17204 #pragma omp for simd for-simd-clause[optseq] new-line 17205 for-loop 17206 17207 LOC is the location of the #pragma token. 17208 */ 17209 17210 #define OMP_FOR_CLAUSE_MASK \ 17211 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 17212 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 17213 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ 17214 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \ 17215 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ 17216 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \ 17217 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \ 17218 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \ 17219 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)) 17220 17221 static tree 17222 c_parser_omp_for (location_t loc, c_parser *parser, 17223 char *p_name, omp_clause_mask mask, tree *cclauses, 17224 bool *if_p) 17225 { 17226 tree block, clauses, ret; 17227 17228 strcat (p_name, " for"); 17229 mask |= OMP_FOR_CLAUSE_MASK; 17230 /* parallel for{, simd} disallows nowait clause, but for 17231 target {teams distribute ,}parallel for{, simd} it should be accepted. */ 17232 if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0) 17233 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT); 17234 /* Composite distribute parallel for{, simd} disallows ordered clause. */ 17235 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0) 17236 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED); 17237 17238 if (c_parser_next_token_is (parser, CPP_NAME)) 17239 { 17240 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 17241 17242 if (strcmp (p, "simd") == 0) 17243 { 17244 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 17245 if (cclauses == NULL) 17246 cclauses = cclauses_buf; 17247 17248 c_parser_consume_token (parser); 17249 if (!flag_openmp) /* flag_openmp_simd */ 17250 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses, 17251 if_p); 17252 block = c_begin_compound_stmt (true); 17253 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p); 17254 block = c_end_compound_stmt (loc, block, true); 17255 if (ret == NULL_TREE) 17256 return ret; 17257 ret = make_node (OMP_FOR); 17258 TREE_TYPE (ret) = void_type_node; 17259 OMP_FOR_BODY (ret) = block; 17260 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR]; 17261 SET_EXPR_LOCATION (ret, loc); 17262 add_stmt (ret); 17263 return ret; 17264 } 17265 } 17266 if (!flag_openmp) /* flag_openmp_simd */ 17267 { 17268 c_parser_skip_to_pragma_eol (parser, false); 17269 return NULL_TREE; 17270 } 17271 17272 /* Composite distribute parallel for disallows linear clause. */ 17273 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0) 17274 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR); 17275 17276 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); 17277 if (cclauses) 17278 { 17279 omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses); 17280 clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR]; 17281 } 17282 17283 block = c_begin_compound_stmt (true); 17284 ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p); 17285 block = c_end_compound_stmt (loc, block, true); 17286 add_stmt (block); 17287 17288 return ret; 17289 } 17290 17291 static tree c_parser_omp_taskloop (location_t, c_parser *, char *, 17292 omp_clause_mask, tree *, bool *); 17293 17294 /* OpenMP 2.5: 17295 # pragma omp master new-line 17296 structured-block 17297 17298 LOC is the location of the #pragma token. 17299 */ 17300 17301 static tree 17302 c_parser_omp_master (location_t loc, c_parser *parser, 17303 char *p_name, omp_clause_mask mask, tree *cclauses, 17304 bool *if_p) 17305 { 17306 tree block, clauses, ret; 17307 17308 strcat (p_name, " master"); 17309 17310 if (c_parser_next_token_is (parser, CPP_NAME)) 17311 { 17312 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 17313 17314 if (strcmp (p, "taskloop") == 0) 17315 { 17316 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 17317 if (cclauses == NULL) 17318 cclauses = cclauses_buf; 17319 17320 c_parser_consume_token (parser); 17321 if (!flag_openmp) /* flag_openmp_simd */ 17322 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses, 17323 if_p); 17324 block = c_begin_compound_stmt (true); 17325 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses, 17326 if_p); 17327 block = c_end_compound_stmt (loc, block, true); 17328 if (ret == NULL_TREE) 17329 return ret; 17330 ret = c_finish_omp_master (loc, block); 17331 return ret; 17332 } 17333 } 17334 if (!flag_openmp) /* flag_openmp_simd */ 17335 { 17336 c_parser_skip_to_pragma_eol (parser, false); 17337 return NULL_TREE; 17338 } 17339 17340 if (cclauses) 17341 { 17342 clauses = c_parser_omp_all_clauses (parser, mask, p_name, false); 17343 omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses); 17344 } 17345 else 17346 c_parser_skip_to_pragma_eol (parser); 17347 17348 return c_finish_omp_master (loc, c_parser_omp_structured_block (parser, 17349 if_p)); 17350 } 17351 17352 /* OpenMP 2.5: 17353 # pragma omp ordered new-line 17354 structured-block 17355 17356 OpenMP 4.5: 17357 # pragma omp ordered ordered-clauses new-line 17358 structured-block 17359 17360 # pragma omp ordered depend-clauses new-line */ 17361 17362 #define OMP_ORDERED_CLAUSE_MASK \ 17363 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \ 17364 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD)) 17365 17366 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \ 17367 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) 17368 17369 static bool 17370 c_parser_omp_ordered (c_parser *parser, enum pragma_context context, 17371 bool *if_p) 17372 { 17373 location_t loc = c_parser_peek_token (parser)->location; 17374 c_parser_consume_pragma (parser); 17375 17376 if (context != pragma_stmt && context != pragma_compound) 17377 { 17378 c_parser_error (parser, "expected declaration specifiers"); 17379 c_parser_skip_to_pragma_eol (parser, false); 17380 return false; 17381 } 17382 17383 if (c_parser_next_token_is (parser, CPP_NAME)) 17384 { 17385 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 17386 17387 if (!strcmp ("depend", p)) 17388 { 17389 if (!flag_openmp) /* flag_openmp_simd */ 17390 { 17391 c_parser_skip_to_pragma_eol (parser, false); 17392 return false; 17393 } 17394 if (context == pragma_stmt) 17395 { 17396 error_at (loc, 17397 "%<#pragma omp ordered%> with %<depend%> clause may " 17398 "only be used in compound statements"); 17399 c_parser_skip_to_pragma_eol (parser, false); 17400 return false; 17401 } 17402 17403 tree clauses 17404 = c_parser_omp_all_clauses (parser, 17405 OMP_ORDERED_DEPEND_CLAUSE_MASK, 17406 "#pragma omp ordered"); 17407 c_finish_omp_ordered (loc, clauses, NULL_TREE); 17408 return false; 17409 } 17410 } 17411 17412 tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK, 17413 "#pragma omp ordered"); 17414 17415 if (!flag_openmp /* flag_openmp_simd */ 17416 && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE) 17417 return false; 17418 17419 c_finish_omp_ordered (loc, clauses, 17420 c_parser_omp_structured_block (parser, if_p)); 17421 return true; 17422 } 17423 17424 /* OpenMP 2.5: 17425 17426 section-scope: 17427 { section-sequence } 17428 17429 section-sequence: 17430 section-directive[opt] structured-block 17431 section-sequence section-directive structured-block 17432 17433 SECTIONS_LOC is the location of the #pragma omp sections. */ 17434 17435 static tree 17436 c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser) 17437 { 17438 tree stmt, substmt; 17439 bool error_suppress = false; 17440 location_t loc; 17441 17442 loc = c_parser_peek_token (parser)->location; 17443 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) 17444 { 17445 /* Avoid skipping until the end of the block. */ 17446 parser->error = false; 17447 return NULL_TREE; 17448 } 17449 17450 stmt = push_stmt_list (); 17451 17452 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION) 17453 { 17454 substmt = c_parser_omp_structured_block (parser, NULL); 17455 substmt = build1 (OMP_SECTION, void_type_node, substmt); 17456 SET_EXPR_LOCATION (substmt, loc); 17457 add_stmt (substmt); 17458 } 17459 17460 while (1) 17461 { 17462 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 17463 break; 17464 if (c_parser_next_token_is (parser, CPP_EOF)) 17465 break; 17466 17467 loc = c_parser_peek_token (parser)->location; 17468 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION) 17469 { 17470 c_parser_consume_pragma (parser); 17471 c_parser_skip_to_pragma_eol (parser); 17472 error_suppress = false; 17473 } 17474 else if (!error_suppress) 17475 { 17476 error_at (loc, "expected %<#pragma omp section%> or %<}%>"); 17477 error_suppress = true; 17478 } 17479 17480 substmt = c_parser_omp_structured_block (parser, NULL); 17481 substmt = build1 (OMP_SECTION, void_type_node, substmt); 17482 SET_EXPR_LOCATION (substmt, loc); 17483 add_stmt (substmt); 17484 } 17485 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, 17486 "expected %<#pragma omp section%> or %<}%>"); 17487 17488 substmt = pop_stmt_list (stmt); 17489 17490 stmt = make_node (OMP_SECTIONS); 17491 SET_EXPR_LOCATION (stmt, sections_loc); 17492 TREE_TYPE (stmt) = void_type_node; 17493 OMP_SECTIONS_BODY (stmt) = substmt; 17494 17495 return add_stmt (stmt); 17496 } 17497 17498 /* OpenMP 2.5: 17499 # pragma omp sections sections-clause[optseq] newline 17500 sections-scope 17501 17502 LOC is the location of the #pragma token. 17503 */ 17504 17505 #define OMP_SECTIONS_CLAUSE_MASK \ 17506 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 17507 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 17508 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ 17509 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ 17510 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)) 17511 17512 static tree 17513 c_parser_omp_sections (location_t loc, c_parser *parser, 17514 char *p_name, omp_clause_mask mask, tree *cclauses) 17515 { 17516 tree block, clauses, ret; 17517 17518 strcat (p_name, " sections"); 17519 mask |= OMP_SECTIONS_CLAUSE_MASK; 17520 if (cclauses) 17521 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT); 17522 17523 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); 17524 if (cclauses) 17525 { 17526 omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses); 17527 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS]; 17528 } 17529 17530 block = c_begin_compound_stmt (true); 17531 ret = c_parser_omp_sections_scope (loc, parser); 17532 if (ret) 17533 OMP_SECTIONS_CLAUSES (ret) = clauses; 17534 block = c_end_compound_stmt (loc, block, true); 17535 add_stmt (block); 17536 17537 return ret; 17538 } 17539 17540 /* OpenMP 2.5: 17541 # pragma omp parallel parallel-clause[optseq] new-line 17542 structured-block 17543 # pragma omp parallel for parallel-for-clause[optseq] new-line 17544 structured-block 17545 # pragma omp parallel sections parallel-sections-clause[optseq] new-line 17546 structured-block 17547 17548 OpenMP 4.0: 17549 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line 17550 structured-block 17551 17552 LOC is the location of the #pragma token. 17553 */ 17554 17555 #define OMP_PARALLEL_CLAUSE_MASK \ 17556 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 17557 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 17558 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 17559 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \ 17560 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \ 17561 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \ 17562 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ 17563 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \ 17564 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND)) 17565 17566 static tree 17567 c_parser_omp_parallel (location_t loc, c_parser *parser, 17568 char *p_name, omp_clause_mask mask, tree *cclauses, 17569 bool *if_p) 17570 { 17571 tree stmt, clauses, block; 17572 17573 strcat (p_name, " parallel"); 17574 mask |= OMP_PARALLEL_CLAUSE_MASK; 17575 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */ 17576 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0 17577 && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0) 17578 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN); 17579 17580 if (c_parser_next_token_is_keyword (parser, RID_FOR)) 17581 { 17582 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 17583 if (cclauses == NULL) 17584 cclauses = cclauses_buf; 17585 17586 c_parser_consume_token (parser); 17587 if (!flag_openmp) /* flag_openmp_simd */ 17588 return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p); 17589 block = c_begin_omp_parallel (); 17590 tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p); 17591 stmt 17592 = c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL], 17593 block); 17594 if (ret == NULL_TREE) 17595 return ret; 17596 OMP_PARALLEL_COMBINED (stmt) = 1; 17597 return stmt; 17598 } 17599 /* When combined with distribute, parallel has to be followed by for. 17600 #pragma omp target parallel is allowed though. */ 17601 else if (cclauses 17602 && (mask & (OMP_CLAUSE_MASK_1 17603 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0) 17604 { 17605 error_at (loc, "expected %<for%> after %qs", p_name); 17606 c_parser_skip_to_pragma_eol (parser); 17607 return NULL_TREE; 17608 } 17609 else if (cclauses == NULL && c_parser_next_token_is (parser, CPP_NAME)) 17610 { 17611 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 17612 if (strcmp (p, "master") == 0) 17613 { 17614 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 17615 cclauses = cclauses_buf; 17616 17617 c_parser_consume_token (parser); 17618 if (!flag_openmp) /* flag_openmp_simd */ 17619 return c_parser_omp_master (loc, parser, p_name, mask, cclauses, 17620 if_p); 17621 block = c_begin_omp_parallel (); 17622 tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses, 17623 if_p); 17624 stmt = c_finish_omp_parallel (loc, 17625 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL], 17626 block); 17627 OMP_PARALLEL_COMBINED (stmt) = 1; 17628 if (ret == NULL) 17629 return ret; 17630 return stmt; 17631 } 17632 else if (!flag_openmp) /* flag_openmp_simd */ 17633 { 17634 c_parser_skip_to_pragma_eol (parser, false); 17635 return NULL_TREE; 17636 } 17637 else if (strcmp (p, "sections") == 0) 17638 { 17639 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 17640 cclauses = cclauses_buf; 17641 17642 c_parser_consume_token (parser); 17643 block = c_begin_omp_parallel (); 17644 c_parser_omp_sections (loc, parser, p_name, mask, cclauses); 17645 stmt = c_finish_omp_parallel (loc, 17646 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL], 17647 block); 17648 OMP_PARALLEL_COMBINED (stmt) = 1; 17649 return stmt; 17650 } 17651 } 17652 else if (!flag_openmp) /* flag_openmp_simd */ 17653 { 17654 c_parser_skip_to_pragma_eol (parser, false); 17655 return NULL_TREE; 17656 } 17657 17658 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); 17659 if (cclauses) 17660 { 17661 omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses); 17662 clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; 17663 } 17664 17665 block = c_begin_omp_parallel (); 17666 c_parser_statement (parser, if_p); 17667 stmt = c_finish_omp_parallel (loc, clauses, block); 17668 17669 return stmt; 17670 } 17671 17672 /* OpenMP 2.5: 17673 # pragma omp single single-clause[optseq] new-line 17674 structured-block 17675 17676 LOC is the location of the #pragma. 17677 */ 17678 17679 #define OMP_SINGLE_CLAUSE_MASK \ 17680 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 17681 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 17682 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \ 17683 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)) 17684 17685 static tree 17686 c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p) 17687 { 17688 tree stmt = make_node (OMP_SINGLE); 17689 SET_EXPR_LOCATION (stmt, loc); 17690 TREE_TYPE (stmt) = void_type_node; 17691 17692 OMP_SINGLE_CLAUSES (stmt) 17693 = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK, 17694 "#pragma omp single"); 17695 OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p); 17696 17697 return add_stmt (stmt); 17698 } 17699 17700 /* OpenMP 3.0: 17701 # pragma omp task task-clause[optseq] new-line 17702 17703 LOC is the location of the #pragma. 17704 */ 17705 17706 #define OMP_TASK_CLAUSE_MASK \ 17707 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 17708 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \ 17709 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \ 17710 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 17711 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 17712 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \ 17713 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \ 17714 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \ 17715 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \ 17716 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \ 17717 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION)) 17718 17719 static tree 17720 c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p) 17721 { 17722 tree clauses, block; 17723 17724 clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK, 17725 "#pragma omp task"); 17726 17727 block = c_begin_omp_task (); 17728 c_parser_statement (parser, if_p); 17729 return c_finish_omp_task (loc, clauses, block); 17730 } 17731 17732 /* OpenMP 3.0: 17733 # pragma omp taskwait new-line 17734 17735 OpenMP 5.0: 17736 # pragma omp taskwait taskwait-clause[optseq] new-line 17737 */ 17738 17739 #define OMP_TASKWAIT_CLAUSE_MASK \ 17740 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) 17741 17742 static void 17743 c_parser_omp_taskwait (c_parser *parser) 17744 { 17745 location_t loc = c_parser_peek_token (parser)->location; 17746 c_parser_consume_pragma (parser); 17747 17748 tree clauses 17749 = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK, 17750 "#pragma omp taskwait"); 17751 17752 if (clauses) 17753 { 17754 tree stmt = make_node (OMP_TASK); 17755 TREE_TYPE (stmt) = void_node; 17756 OMP_TASK_CLAUSES (stmt) = clauses; 17757 OMP_TASK_BODY (stmt) = NULL_TREE; 17758 SET_EXPR_LOCATION (stmt, loc); 17759 add_stmt (stmt); 17760 } 17761 else 17762 c_finish_omp_taskwait (loc); 17763 } 17764 17765 /* OpenMP 3.1: 17766 # pragma omp taskyield new-line 17767 */ 17768 17769 static void 17770 c_parser_omp_taskyield (c_parser *parser) 17771 { 17772 location_t loc = c_parser_peek_token (parser)->location; 17773 c_parser_consume_pragma (parser); 17774 c_parser_skip_to_pragma_eol (parser); 17775 17776 c_finish_omp_taskyield (loc); 17777 } 17778 17779 /* OpenMP 4.0: 17780 # pragma omp taskgroup new-line 17781 17782 OpenMP 5.0: 17783 # pragma omp taskgroup taskgroup-clause[optseq] new-line 17784 */ 17785 17786 #define OMP_TASKGROUP_CLAUSE_MASK \ 17787 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION)) 17788 17789 static tree 17790 c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p) 17791 { 17792 tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK, 17793 "#pragma omp taskgroup"); 17794 17795 tree body = c_parser_omp_structured_block (parser, if_p); 17796 return c_finish_omp_taskgroup (loc, body, clauses); 17797 } 17798 17799 /* OpenMP 4.0: 17800 # pragma omp cancel cancel-clause[optseq] new-line 17801 17802 LOC is the location of the #pragma. 17803 */ 17804 17805 #define OMP_CANCEL_CLAUSE_MASK \ 17806 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \ 17807 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \ 17808 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \ 17809 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \ 17810 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)) 17811 17812 static void 17813 c_parser_omp_cancel (c_parser *parser) 17814 { 17815 location_t loc = c_parser_peek_token (parser)->location; 17816 17817 c_parser_consume_pragma (parser); 17818 tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK, 17819 "#pragma omp cancel"); 17820 17821 c_finish_omp_cancel (loc, clauses); 17822 } 17823 17824 /* OpenMP 4.0: 17825 # pragma omp cancellation point cancelpt-clause[optseq] new-line 17826 17827 LOC is the location of the #pragma. 17828 */ 17829 17830 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \ 17831 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \ 17832 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \ 17833 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \ 17834 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP)) 17835 17836 static void 17837 c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context) 17838 { 17839 location_t loc = c_parser_peek_token (parser)->location; 17840 tree clauses; 17841 bool point_seen = false; 17842 17843 c_parser_consume_pragma (parser); 17844 if (c_parser_next_token_is (parser, CPP_NAME)) 17845 { 17846 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 17847 if (strcmp (p, "point") == 0) 17848 { 17849 c_parser_consume_token (parser); 17850 point_seen = true; 17851 } 17852 } 17853 if (!point_seen) 17854 { 17855 c_parser_error (parser, "expected %<point%>"); 17856 c_parser_skip_to_pragma_eol (parser); 17857 return; 17858 } 17859 17860 if (context != pragma_compound) 17861 { 17862 if (context == pragma_stmt) 17863 error_at (loc, 17864 "%<#pragma %s%> may only be used in compound statements", 17865 "omp cancellation point"); 17866 else 17867 c_parser_error (parser, "expected declaration specifiers"); 17868 c_parser_skip_to_pragma_eol (parser, false); 17869 return; 17870 } 17871 17872 clauses 17873 = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK, 17874 "#pragma omp cancellation point"); 17875 17876 c_finish_omp_cancellation_point (loc, clauses); 17877 } 17878 17879 /* OpenMP 4.0: 17880 #pragma omp distribute distribute-clause[optseq] new-line 17881 for-loop */ 17882 17883 #define OMP_DISTRIBUTE_CLAUSE_MASK \ 17884 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 17885 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 17886 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ 17887 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\ 17888 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)) 17889 17890 static tree 17891 c_parser_omp_distribute (location_t loc, c_parser *parser, 17892 char *p_name, omp_clause_mask mask, tree *cclauses, 17893 bool *if_p) 17894 { 17895 tree clauses, block, ret; 17896 17897 strcat (p_name, " distribute"); 17898 mask |= OMP_DISTRIBUTE_CLAUSE_MASK; 17899 17900 if (c_parser_next_token_is (parser, CPP_NAME)) 17901 { 17902 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 17903 bool simd = false; 17904 bool parallel = false; 17905 17906 if (strcmp (p, "simd") == 0) 17907 simd = true; 17908 else 17909 parallel = strcmp (p, "parallel") == 0; 17910 if (parallel || simd) 17911 { 17912 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 17913 if (cclauses == NULL) 17914 cclauses = cclauses_buf; 17915 c_parser_consume_token (parser); 17916 if (!flag_openmp) /* flag_openmp_simd */ 17917 { 17918 if (simd) 17919 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses, 17920 if_p); 17921 else 17922 return c_parser_omp_parallel (loc, parser, p_name, mask, 17923 cclauses, if_p); 17924 } 17925 block = c_begin_compound_stmt (true); 17926 if (simd) 17927 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, 17928 if_p); 17929 else 17930 ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses, 17931 if_p); 17932 block = c_end_compound_stmt (loc, block, true); 17933 if (ret == NULL) 17934 return ret; 17935 ret = make_node (OMP_DISTRIBUTE); 17936 TREE_TYPE (ret) = void_type_node; 17937 OMP_FOR_BODY (ret) = block; 17938 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE]; 17939 SET_EXPR_LOCATION (ret, loc); 17940 add_stmt (ret); 17941 return ret; 17942 } 17943 } 17944 if (!flag_openmp) /* flag_openmp_simd */ 17945 { 17946 c_parser_skip_to_pragma_eol (parser, false); 17947 return NULL_TREE; 17948 } 17949 17950 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); 17951 if (cclauses) 17952 { 17953 omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses); 17954 clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE]; 17955 } 17956 17957 block = c_begin_compound_stmt (true); 17958 ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL, 17959 if_p); 17960 block = c_end_compound_stmt (loc, block, true); 17961 add_stmt (block); 17962 17963 return ret; 17964 } 17965 17966 /* OpenMP 4.0: 17967 # pragma omp teams teams-clause[optseq] new-line 17968 structured-block */ 17969 17970 #define OMP_TEAMS_CLAUSE_MASK \ 17971 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 17972 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 17973 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \ 17974 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ 17975 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \ 17976 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \ 17977 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT)) 17978 17979 static tree 17980 c_parser_omp_teams (location_t loc, c_parser *parser, 17981 char *p_name, omp_clause_mask mask, tree *cclauses, 17982 bool *if_p) 17983 { 17984 tree clauses, block, ret; 17985 17986 strcat (p_name, " teams"); 17987 mask |= OMP_TEAMS_CLAUSE_MASK; 17988 17989 if (c_parser_next_token_is (parser, CPP_NAME)) 17990 { 17991 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 17992 if (strcmp (p, "distribute") == 0) 17993 { 17994 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 17995 if (cclauses == NULL) 17996 cclauses = cclauses_buf; 17997 17998 c_parser_consume_token (parser); 17999 if (!flag_openmp) /* flag_openmp_simd */ 18000 return c_parser_omp_distribute (loc, parser, p_name, mask, 18001 cclauses, if_p); 18002 block = c_begin_omp_parallel (); 18003 ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses, 18004 if_p); 18005 block = c_end_compound_stmt (loc, block, true); 18006 if (ret == NULL) 18007 return ret; 18008 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS]; 18009 ret = make_node (OMP_TEAMS); 18010 TREE_TYPE (ret) = void_type_node; 18011 OMP_TEAMS_CLAUSES (ret) = clauses; 18012 OMP_TEAMS_BODY (ret) = block; 18013 OMP_TEAMS_COMBINED (ret) = 1; 18014 SET_EXPR_LOCATION (ret, loc); 18015 return add_stmt (ret); 18016 } 18017 } 18018 if (!flag_openmp) /* flag_openmp_simd */ 18019 { 18020 c_parser_skip_to_pragma_eol (parser, false); 18021 return NULL_TREE; 18022 } 18023 18024 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); 18025 if (cclauses) 18026 { 18027 omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses); 18028 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS]; 18029 } 18030 18031 tree stmt = make_node (OMP_TEAMS); 18032 TREE_TYPE (stmt) = void_type_node; 18033 OMP_TEAMS_CLAUSES (stmt) = clauses; 18034 block = c_begin_omp_parallel (); 18035 add_stmt (c_parser_omp_structured_block (parser, if_p)); 18036 OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true); 18037 SET_EXPR_LOCATION (stmt, loc); 18038 18039 return add_stmt (stmt); 18040 } 18041 18042 /* OpenMP 4.0: 18043 # pragma omp target data target-data-clause[optseq] new-line 18044 structured-block */ 18045 18046 #define OMP_TARGET_DATA_CLAUSE_MASK \ 18047 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \ 18048 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \ 18049 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 18050 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR)) 18051 18052 static tree 18053 c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p) 18054 { 18055 tree clauses 18056 = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK, 18057 "#pragma omp target data"); 18058 int map_seen = 0; 18059 for (tree *pc = &clauses; *pc;) 18060 { 18061 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP) 18062 switch (OMP_CLAUSE_MAP_KIND (*pc)) 18063 { 18064 case GOMP_MAP_TO: 18065 case GOMP_MAP_ALWAYS_TO: 18066 case GOMP_MAP_FROM: 18067 case GOMP_MAP_ALWAYS_FROM: 18068 case GOMP_MAP_TOFROM: 18069 case GOMP_MAP_ALWAYS_TOFROM: 18070 case GOMP_MAP_ALLOC: 18071 map_seen = 3; 18072 break; 18073 case GOMP_MAP_FIRSTPRIVATE_POINTER: 18074 case GOMP_MAP_ALWAYS_POINTER: 18075 break; 18076 default: 18077 map_seen |= 1; 18078 error_at (OMP_CLAUSE_LOCATION (*pc), 18079 "%<#pragma omp target data%> with map-type other " 18080 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> " 18081 "on %<map%> clause"); 18082 *pc = OMP_CLAUSE_CHAIN (*pc); 18083 continue; 18084 } 18085 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR) 18086 map_seen = 3; 18087 pc = &OMP_CLAUSE_CHAIN (*pc); 18088 } 18089 18090 if (map_seen != 3) 18091 { 18092 if (map_seen == 0) 18093 error_at (loc, 18094 "%<#pragma omp target data%> must contain at least " 18095 "one %<map%> or %<use_device_ptr%> clause"); 18096 return NULL_TREE; 18097 } 18098 18099 tree stmt = make_node (OMP_TARGET_DATA); 18100 TREE_TYPE (stmt) = void_type_node; 18101 OMP_TARGET_DATA_CLAUSES (stmt) = clauses; 18102 keep_next_level (); 18103 tree block = c_begin_compound_stmt (true); 18104 add_stmt (c_parser_omp_structured_block (parser, if_p)); 18105 OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true); 18106 18107 SET_EXPR_LOCATION (stmt, loc); 18108 return add_stmt (stmt); 18109 } 18110 18111 /* OpenMP 4.0: 18112 # pragma omp target update target-update-clause[optseq] new-line */ 18113 18114 #define OMP_TARGET_UPDATE_CLAUSE_MASK \ 18115 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \ 18116 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \ 18117 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \ 18118 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 18119 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \ 18120 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)) 18121 18122 static bool 18123 c_parser_omp_target_update (location_t loc, c_parser *parser, 18124 enum pragma_context context) 18125 { 18126 if (context == pragma_stmt) 18127 { 18128 error_at (loc, "%<#pragma %s%> may only be used in compound statements", 18129 "omp target update"); 18130 c_parser_skip_to_pragma_eol (parser, false); 18131 return false; 18132 } 18133 18134 tree clauses 18135 = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK, 18136 "#pragma omp target update"); 18137 if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE 18138 && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE) 18139 { 18140 error_at (loc, 18141 "%<#pragma omp target update%> must contain at least one " 18142 "%<from%> or %<to%> clauses"); 18143 return false; 18144 } 18145 18146 tree stmt = make_node (OMP_TARGET_UPDATE); 18147 TREE_TYPE (stmt) = void_type_node; 18148 OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses; 18149 SET_EXPR_LOCATION (stmt, loc); 18150 add_stmt (stmt); 18151 return false; 18152 } 18153 18154 /* OpenMP 4.5: 18155 # pragma omp target enter data target-data-clause[optseq] new-line */ 18156 18157 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \ 18158 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \ 18159 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \ 18160 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 18161 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \ 18162 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)) 18163 18164 static tree 18165 c_parser_omp_target_enter_data (location_t loc, c_parser *parser, 18166 enum pragma_context context) 18167 { 18168 bool data_seen = false; 18169 if (c_parser_next_token_is (parser, CPP_NAME)) 18170 { 18171 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 18172 if (strcmp (p, "data") == 0) 18173 { 18174 c_parser_consume_token (parser); 18175 data_seen = true; 18176 } 18177 } 18178 if (!data_seen) 18179 { 18180 c_parser_error (parser, "expected %<data%>"); 18181 c_parser_skip_to_pragma_eol (parser); 18182 return NULL_TREE; 18183 } 18184 18185 if (context == pragma_stmt) 18186 { 18187 error_at (loc, "%<#pragma %s%> may only be used in compound statements", 18188 "omp target enter data"); 18189 c_parser_skip_to_pragma_eol (parser, false); 18190 return NULL_TREE; 18191 } 18192 18193 tree clauses 18194 = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK, 18195 "#pragma omp target enter data"); 18196 int map_seen = 0; 18197 for (tree *pc = &clauses; *pc;) 18198 { 18199 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP) 18200 switch (OMP_CLAUSE_MAP_KIND (*pc)) 18201 { 18202 case GOMP_MAP_TO: 18203 case GOMP_MAP_ALWAYS_TO: 18204 case GOMP_MAP_ALLOC: 18205 map_seen = 3; 18206 break; 18207 case GOMP_MAP_FIRSTPRIVATE_POINTER: 18208 case GOMP_MAP_ALWAYS_POINTER: 18209 break; 18210 default: 18211 map_seen |= 1; 18212 error_at (OMP_CLAUSE_LOCATION (*pc), 18213 "%<#pragma omp target enter data%> with map-type other " 18214 "than %<to%> or %<alloc%> on %<map%> clause"); 18215 *pc = OMP_CLAUSE_CHAIN (*pc); 18216 continue; 18217 } 18218 pc = &OMP_CLAUSE_CHAIN (*pc); 18219 } 18220 18221 if (map_seen != 3) 18222 { 18223 if (map_seen == 0) 18224 error_at (loc, 18225 "%<#pragma omp target enter data%> must contain at least " 18226 "one %<map%> clause"); 18227 return NULL_TREE; 18228 } 18229 18230 tree stmt = make_node (OMP_TARGET_ENTER_DATA); 18231 TREE_TYPE (stmt) = void_type_node; 18232 OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses; 18233 SET_EXPR_LOCATION (stmt, loc); 18234 add_stmt (stmt); 18235 return stmt; 18236 } 18237 18238 /* OpenMP 4.5: 18239 # pragma omp target exit data target-data-clause[optseq] new-line */ 18240 18241 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \ 18242 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \ 18243 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \ 18244 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 18245 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \ 18246 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)) 18247 18248 static tree 18249 c_parser_omp_target_exit_data (location_t loc, c_parser *parser, 18250 enum pragma_context context) 18251 { 18252 bool data_seen = false; 18253 if (c_parser_next_token_is (parser, CPP_NAME)) 18254 { 18255 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 18256 if (strcmp (p, "data") == 0) 18257 { 18258 c_parser_consume_token (parser); 18259 data_seen = true; 18260 } 18261 } 18262 if (!data_seen) 18263 { 18264 c_parser_error (parser, "expected %<data%>"); 18265 c_parser_skip_to_pragma_eol (parser); 18266 return NULL_TREE; 18267 } 18268 18269 if (context == pragma_stmt) 18270 { 18271 error_at (loc, "%<#pragma %s%> may only be used in compound statements", 18272 "omp target exit data"); 18273 c_parser_skip_to_pragma_eol (parser, false); 18274 return NULL_TREE; 18275 } 18276 18277 tree clauses 18278 = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK, 18279 "#pragma omp target exit data"); 18280 18281 int map_seen = 0; 18282 for (tree *pc = &clauses; *pc;) 18283 { 18284 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP) 18285 switch (OMP_CLAUSE_MAP_KIND (*pc)) 18286 { 18287 case GOMP_MAP_FROM: 18288 case GOMP_MAP_ALWAYS_FROM: 18289 case GOMP_MAP_RELEASE: 18290 case GOMP_MAP_DELETE: 18291 map_seen = 3; 18292 break; 18293 case GOMP_MAP_FIRSTPRIVATE_POINTER: 18294 case GOMP_MAP_ALWAYS_POINTER: 18295 break; 18296 default: 18297 map_seen |= 1; 18298 error_at (OMP_CLAUSE_LOCATION (*pc), 18299 "%<#pragma omp target exit data%> with map-type other " 18300 "than %<from%>, %<release%> or %<delete%> on %<map%>" 18301 " clause"); 18302 *pc = OMP_CLAUSE_CHAIN (*pc); 18303 continue; 18304 } 18305 pc = &OMP_CLAUSE_CHAIN (*pc); 18306 } 18307 18308 if (map_seen != 3) 18309 { 18310 if (map_seen == 0) 18311 error_at (loc, 18312 "%<#pragma omp target exit data%> must contain at least one " 18313 "%<map%> clause"); 18314 return NULL_TREE; 18315 } 18316 18317 tree stmt = make_node (OMP_TARGET_EXIT_DATA); 18318 TREE_TYPE (stmt) = void_type_node; 18319 OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses; 18320 SET_EXPR_LOCATION (stmt, loc); 18321 add_stmt (stmt); 18322 return stmt; 18323 } 18324 18325 /* OpenMP 4.0: 18326 # pragma omp target target-clause[optseq] new-line 18327 structured-block */ 18328 18329 #define OMP_TARGET_CLAUSE_MASK \ 18330 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \ 18331 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \ 18332 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 18333 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \ 18334 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \ 18335 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 18336 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 18337 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \ 18338 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)) 18339 18340 static bool 18341 c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p) 18342 { 18343 location_t loc = c_parser_peek_token (parser)->location; 18344 c_parser_consume_pragma (parser); 18345 tree *pc = NULL, stmt, block; 18346 18347 if (context != pragma_stmt && context != pragma_compound) 18348 { 18349 c_parser_error (parser, "expected declaration specifiers"); 18350 c_parser_skip_to_pragma_eol (parser); 18351 return false; 18352 } 18353 18354 if (flag_openmp) 18355 omp_requires_mask 18356 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED); 18357 18358 if (c_parser_next_token_is (parser, CPP_NAME)) 18359 { 18360 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 18361 enum tree_code ccode = ERROR_MARK; 18362 18363 if (strcmp (p, "teams") == 0) 18364 ccode = OMP_TEAMS; 18365 else if (strcmp (p, "parallel") == 0) 18366 ccode = OMP_PARALLEL; 18367 else if (strcmp (p, "simd") == 0) 18368 ccode = OMP_SIMD; 18369 if (ccode != ERROR_MARK) 18370 { 18371 tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT]; 18372 char p_name[sizeof ("#pragma omp target teams distribute " 18373 "parallel for simd")]; 18374 18375 c_parser_consume_token (parser); 18376 strcpy (p_name, "#pragma omp target"); 18377 if (!flag_openmp) /* flag_openmp_simd */ 18378 { 18379 tree stmt; 18380 switch (ccode) 18381 { 18382 case OMP_TEAMS: 18383 stmt = c_parser_omp_teams (loc, parser, p_name, 18384 OMP_TARGET_CLAUSE_MASK, 18385 cclauses, if_p); 18386 break; 18387 case OMP_PARALLEL: 18388 stmt = c_parser_omp_parallel (loc, parser, p_name, 18389 OMP_TARGET_CLAUSE_MASK, 18390 cclauses, if_p); 18391 break; 18392 case OMP_SIMD: 18393 stmt = c_parser_omp_simd (loc, parser, p_name, 18394 OMP_TARGET_CLAUSE_MASK, 18395 cclauses, if_p); 18396 break; 18397 default: 18398 gcc_unreachable (); 18399 } 18400 return stmt != NULL_TREE; 18401 } 18402 keep_next_level (); 18403 tree block = c_begin_compound_stmt (true), ret; 18404 switch (ccode) 18405 { 18406 case OMP_TEAMS: 18407 ret = c_parser_omp_teams (loc, parser, p_name, 18408 OMP_TARGET_CLAUSE_MASK, cclauses, 18409 if_p); 18410 break; 18411 case OMP_PARALLEL: 18412 ret = c_parser_omp_parallel (loc, parser, p_name, 18413 OMP_TARGET_CLAUSE_MASK, cclauses, 18414 if_p); 18415 break; 18416 case OMP_SIMD: 18417 ret = c_parser_omp_simd (loc, parser, p_name, 18418 OMP_TARGET_CLAUSE_MASK, cclauses, 18419 if_p); 18420 break; 18421 default: 18422 gcc_unreachable (); 18423 } 18424 block = c_end_compound_stmt (loc, block, true); 18425 if (ret == NULL_TREE) 18426 return false; 18427 if (ccode == OMP_TEAMS) 18428 { 18429 /* For combined target teams, ensure the num_teams and 18430 thread_limit clause expressions are evaluated on the host, 18431 before entering the target construct. */ 18432 tree c; 18433 for (c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS]; 18434 c; c = OMP_CLAUSE_CHAIN (c)) 18435 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS 18436 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT) 18437 && TREE_CODE (OMP_CLAUSE_OPERAND (c, 0)) != INTEGER_CST) 18438 { 18439 tree expr = OMP_CLAUSE_OPERAND (c, 0); 18440 tree tmp = create_tmp_var_raw (TREE_TYPE (expr)); 18441 expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp, 18442 expr, NULL_TREE, NULL_TREE); 18443 add_stmt (expr); 18444 OMP_CLAUSE_OPERAND (c, 0) = expr; 18445 tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c), 18446 OMP_CLAUSE_FIRSTPRIVATE); 18447 OMP_CLAUSE_DECL (tc) = tmp; 18448 OMP_CLAUSE_CHAIN (tc) 18449 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET]; 18450 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc; 18451 } 18452 } 18453 tree stmt = make_node (OMP_TARGET); 18454 TREE_TYPE (stmt) = void_type_node; 18455 OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET]; 18456 OMP_TARGET_BODY (stmt) = block; 18457 OMP_TARGET_COMBINED (stmt) = 1; 18458 SET_EXPR_LOCATION (stmt, loc); 18459 add_stmt (stmt); 18460 pc = &OMP_TARGET_CLAUSES (stmt); 18461 goto check_clauses; 18462 } 18463 else if (!flag_openmp) /* flag_openmp_simd */ 18464 { 18465 c_parser_skip_to_pragma_eol (parser, false); 18466 return false; 18467 } 18468 else if (strcmp (p, "data") == 0) 18469 { 18470 c_parser_consume_token (parser); 18471 c_parser_omp_target_data (loc, parser, if_p); 18472 return true; 18473 } 18474 else if (strcmp (p, "enter") == 0) 18475 { 18476 c_parser_consume_token (parser); 18477 c_parser_omp_target_enter_data (loc, parser, context); 18478 return false; 18479 } 18480 else if (strcmp (p, "exit") == 0) 18481 { 18482 c_parser_consume_token (parser); 18483 c_parser_omp_target_exit_data (loc, parser, context); 18484 return false; 18485 } 18486 else if (strcmp (p, "update") == 0) 18487 { 18488 c_parser_consume_token (parser); 18489 return c_parser_omp_target_update (loc, parser, context); 18490 } 18491 } 18492 if (!flag_openmp) /* flag_openmp_simd */ 18493 { 18494 c_parser_skip_to_pragma_eol (parser, false); 18495 return false; 18496 } 18497 18498 stmt = make_node (OMP_TARGET); 18499 TREE_TYPE (stmt) = void_type_node; 18500 18501 OMP_TARGET_CLAUSES (stmt) 18502 = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK, 18503 "#pragma omp target"); 18504 pc = &OMP_TARGET_CLAUSES (stmt); 18505 keep_next_level (); 18506 block = c_begin_compound_stmt (true); 18507 add_stmt (c_parser_omp_structured_block (parser, if_p)); 18508 OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true); 18509 18510 SET_EXPR_LOCATION (stmt, loc); 18511 add_stmt (stmt); 18512 18513 check_clauses: 18514 while (*pc) 18515 { 18516 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP) 18517 switch (OMP_CLAUSE_MAP_KIND (*pc)) 18518 { 18519 case GOMP_MAP_TO: 18520 case GOMP_MAP_ALWAYS_TO: 18521 case GOMP_MAP_FROM: 18522 case GOMP_MAP_ALWAYS_FROM: 18523 case GOMP_MAP_TOFROM: 18524 case GOMP_MAP_ALWAYS_TOFROM: 18525 case GOMP_MAP_ALLOC: 18526 case GOMP_MAP_FIRSTPRIVATE_POINTER: 18527 case GOMP_MAP_ALWAYS_POINTER: 18528 break; 18529 default: 18530 error_at (OMP_CLAUSE_LOCATION (*pc), 18531 "%<#pragma omp target%> with map-type other " 18532 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> " 18533 "on %<map%> clause"); 18534 *pc = OMP_CLAUSE_CHAIN (*pc); 18535 continue; 18536 } 18537 pc = &OMP_CLAUSE_CHAIN (*pc); 18538 } 18539 return true; 18540 } 18541 18542 /* OpenMP 4.0: 18543 # pragma omp declare simd declare-simd-clauses[optseq] new-line */ 18544 18545 #define OMP_DECLARE_SIMD_CLAUSE_MASK \ 18546 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \ 18547 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \ 18548 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \ 18549 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \ 18550 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \ 18551 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH)) 18552 18553 static void 18554 c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context) 18555 { 18556 auto_vec<c_token> clauses; 18557 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 18558 { 18559 c_token *token = c_parser_peek_token (parser); 18560 if (token->type == CPP_EOF) 18561 { 18562 c_parser_skip_to_pragma_eol (parser); 18563 return; 18564 } 18565 clauses.safe_push (*token); 18566 c_parser_consume_token (parser); 18567 } 18568 clauses.safe_push (*c_parser_peek_token (parser)); 18569 c_parser_skip_to_pragma_eol (parser); 18570 18571 while (c_parser_next_token_is (parser, CPP_PRAGMA)) 18572 { 18573 if (c_parser_peek_token (parser)->pragma_kind 18574 != PRAGMA_OMP_DECLARE 18575 || c_parser_peek_2nd_token (parser)->type != CPP_NAME 18576 || strcmp (IDENTIFIER_POINTER 18577 (c_parser_peek_2nd_token (parser)->value), 18578 "simd") != 0) 18579 { 18580 c_parser_error (parser, 18581 "%<#pragma omp declare simd%> must be followed by " 18582 "function declaration or definition or another " 18583 "%<#pragma omp declare simd%>"); 18584 return; 18585 } 18586 c_parser_consume_pragma (parser); 18587 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 18588 { 18589 c_token *token = c_parser_peek_token (parser); 18590 if (token->type == CPP_EOF) 18591 { 18592 c_parser_skip_to_pragma_eol (parser); 18593 return; 18594 } 18595 clauses.safe_push (*token); 18596 c_parser_consume_token (parser); 18597 } 18598 clauses.safe_push (*c_parser_peek_token (parser)); 18599 c_parser_skip_to_pragma_eol (parser); 18600 } 18601 18602 /* Make sure nothing tries to read past the end of the tokens. */ 18603 c_token eof_token; 18604 memset (&eof_token, 0, sizeof (eof_token)); 18605 eof_token.type = CPP_EOF; 18606 clauses.safe_push (eof_token); 18607 clauses.safe_push (eof_token); 18608 18609 switch (context) 18610 { 18611 case pragma_external: 18612 if (c_parser_next_token_is (parser, CPP_KEYWORD) 18613 && c_parser_peek_token (parser)->keyword == RID_EXTENSION) 18614 { 18615 int ext = disable_extension_diagnostics (); 18616 do 18617 c_parser_consume_token (parser); 18618 while (c_parser_next_token_is (parser, CPP_KEYWORD) 18619 && c_parser_peek_token (parser)->keyword == RID_EXTENSION); 18620 c_parser_declaration_or_fndef (parser, true, true, true, false, true, 18621 NULL, clauses); 18622 restore_extension_diagnostics (ext); 18623 } 18624 else 18625 c_parser_declaration_or_fndef (parser, true, true, true, false, true, 18626 NULL, clauses); 18627 break; 18628 case pragma_struct: 18629 case pragma_param: 18630 case pragma_stmt: 18631 c_parser_error (parser, "%<#pragma omp declare simd%> must be followed by " 18632 "function declaration or definition"); 18633 break; 18634 case pragma_compound: 18635 if (c_parser_next_token_is (parser, CPP_KEYWORD) 18636 && c_parser_peek_token (parser)->keyword == RID_EXTENSION) 18637 { 18638 int ext = disable_extension_diagnostics (); 18639 do 18640 c_parser_consume_token (parser); 18641 while (c_parser_next_token_is (parser, CPP_KEYWORD) 18642 && c_parser_peek_token (parser)->keyword == RID_EXTENSION); 18643 if (c_parser_next_tokens_start_declaration (parser)) 18644 { 18645 c_parser_declaration_or_fndef (parser, true, true, true, true, 18646 true, NULL, clauses); 18647 restore_extension_diagnostics (ext); 18648 break; 18649 } 18650 restore_extension_diagnostics (ext); 18651 } 18652 else if (c_parser_next_tokens_start_declaration (parser)) 18653 { 18654 c_parser_declaration_or_fndef (parser, true, true, true, true, true, 18655 NULL, clauses); 18656 break; 18657 } 18658 c_parser_error (parser, "%<#pragma omp declare simd%> must be followed by " 18659 "function declaration or definition"); 18660 break; 18661 default: 18662 gcc_unreachable (); 18663 } 18664 } 18665 18666 /* Finalize #pragma omp declare simd clauses after FNDECL has been parsed, 18667 and put that into "omp declare simd" attribute. */ 18668 18669 static void 18670 c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms, 18671 vec<c_token> clauses) 18672 { 18673 /* Normally first token is CPP_NAME "simd". CPP_EOF there indicates 18674 error has been reported and CPP_PRAGMA that c_finish_omp_declare_simd 18675 has already processed the tokens. */ 18676 if (clauses.exists () && clauses[0].type == CPP_EOF) 18677 return; 18678 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL) 18679 { 18680 error ("%<#pragma omp declare simd%> not immediately followed by " 18681 "a function declaration or definition"); 18682 clauses[0].type = CPP_EOF; 18683 return; 18684 } 18685 if (clauses.exists () && clauses[0].type != CPP_NAME) 18686 { 18687 error_at (DECL_SOURCE_LOCATION (fndecl), 18688 "%<#pragma omp declare simd%> not immediately followed by " 18689 "a single function declaration or definition"); 18690 clauses[0].type = CPP_EOF; 18691 return; 18692 } 18693 18694 if (parms == NULL_TREE) 18695 parms = DECL_ARGUMENTS (fndecl); 18696 18697 unsigned int tokens_avail = parser->tokens_avail; 18698 gcc_assert (parser->tokens == &parser->tokens_buf[0]); 18699 18700 18701 parser->tokens = clauses.address (); 18702 parser->tokens_avail = clauses.length (); 18703 18704 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */ 18705 while (parser->tokens_avail > 3) 18706 { 18707 c_token *token = c_parser_peek_token (parser); 18708 gcc_assert (token->type == CPP_NAME 18709 && strcmp (IDENTIFIER_POINTER (token->value), "simd") == 0); 18710 c_parser_consume_token (parser); 18711 parser->in_pragma = true; 18712 18713 tree c = NULL_TREE; 18714 c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK, 18715 "#pragma omp declare simd"); 18716 c = c_omp_declare_simd_clauses_to_numbers (parms, c); 18717 if (c != NULL_TREE) 18718 c = tree_cons (NULL_TREE, c, NULL_TREE); 18719 c = build_tree_list (get_identifier ("omp declare simd"), c); 18720 TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl); 18721 DECL_ATTRIBUTES (fndecl) = c; 18722 } 18723 18724 parser->tokens = &parser->tokens_buf[0]; 18725 parser->tokens_avail = tokens_avail; 18726 if (clauses.exists ()) 18727 clauses[0].type = CPP_PRAGMA; 18728 } 18729 18730 18731 /* OpenMP 4.0: 18732 # pragma omp declare target new-line 18733 declarations and definitions 18734 # pragma omp end declare target new-line 18735 18736 OpenMP 4.5: 18737 # pragma omp declare target ( extended-list ) new-line 18738 18739 # pragma omp declare target declare-target-clauses[seq] new-line */ 18740 18741 #define OMP_DECLARE_TARGET_CLAUSE_MASK \ 18742 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \ 18743 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) 18744 18745 static void 18746 c_parser_omp_declare_target (c_parser *parser) 18747 { 18748 location_t loc = c_parser_peek_token (parser)->location; 18749 tree clauses = NULL_TREE; 18750 if (c_parser_next_token_is (parser, CPP_NAME)) 18751 clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK, 18752 "#pragma omp declare target"); 18753 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 18754 { 18755 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE, 18756 clauses); 18757 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP); 18758 c_parser_skip_to_pragma_eol (parser); 18759 } 18760 else 18761 { 18762 c_parser_skip_to_pragma_eol (parser); 18763 current_omp_declare_target_attribute++; 18764 return; 18765 } 18766 if (current_omp_declare_target_attribute) 18767 error_at (loc, "%<#pragma omp declare target%> with clauses in between " 18768 "%<#pragma omp declare target%> without clauses and " 18769 "%<#pragma omp end declare target%>"); 18770 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c)) 18771 { 18772 tree t = OMP_CLAUSE_DECL (c), id; 18773 tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t)); 18774 tree at2 = lookup_attribute ("omp declare target link", 18775 DECL_ATTRIBUTES (t)); 18776 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK) 18777 { 18778 id = get_identifier ("omp declare target link"); 18779 std::swap (at1, at2); 18780 } 18781 else 18782 id = get_identifier ("omp declare target"); 18783 if (at2) 18784 { 18785 error_at (OMP_CLAUSE_LOCATION (c), 18786 "%qD specified both in declare target %<link%> and %<to%>" 18787 " clauses", t); 18788 continue; 18789 } 18790 if (!at1) 18791 { 18792 DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t)); 18793 if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t)) 18794 continue; 18795 18796 symtab_node *node = symtab_node::get (t); 18797 if (node != NULL) 18798 { 18799 node->offloadable = 1; 18800 if (ENABLE_OFFLOADING) 18801 { 18802 g->have_offload = true; 18803 if (is_a <varpool_node *> (node)) 18804 vec_safe_push (offload_vars, t); 18805 } 18806 } 18807 } 18808 } 18809 } 18810 18811 static void 18812 c_parser_omp_end_declare_target (c_parser *parser) 18813 { 18814 location_t loc = c_parser_peek_token (parser)->location; 18815 c_parser_consume_pragma (parser); 18816 if (c_parser_next_token_is (parser, CPP_NAME) 18817 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value), 18818 "declare") == 0) 18819 { 18820 c_parser_consume_token (parser); 18821 if (c_parser_next_token_is (parser, CPP_NAME) 18822 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value), 18823 "target") == 0) 18824 c_parser_consume_token (parser); 18825 else 18826 { 18827 c_parser_error (parser, "expected %<target%>"); 18828 c_parser_skip_to_pragma_eol (parser); 18829 return; 18830 } 18831 } 18832 else 18833 { 18834 c_parser_error (parser, "expected %<declare%>"); 18835 c_parser_skip_to_pragma_eol (parser); 18836 return; 18837 } 18838 c_parser_skip_to_pragma_eol (parser); 18839 if (!current_omp_declare_target_attribute) 18840 error_at (loc, "%<#pragma omp end declare target%> without corresponding " 18841 "%<#pragma omp declare target%>"); 18842 else 18843 current_omp_declare_target_attribute--; 18844 } 18845 18846 18847 /* OpenMP 4.0 18848 #pragma omp declare reduction (reduction-id : typename-list : expression) \ 18849 initializer-clause[opt] new-line 18850 18851 initializer-clause: 18852 initializer (omp_priv = initializer) 18853 initializer (function-name (argument-list)) */ 18854 18855 static void 18856 c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context) 18857 { 18858 unsigned int tokens_avail = 0, i; 18859 vec<tree> types = vNULL; 18860 vec<c_token> clauses = vNULL; 18861 enum tree_code reduc_code = ERROR_MARK; 18862 tree reduc_id = NULL_TREE; 18863 tree type; 18864 location_t rloc = c_parser_peek_token (parser)->location; 18865 18866 if (context == pragma_struct || context == pragma_param) 18867 { 18868 error ("%<#pragma omp declare reduction%> not at file or block scope"); 18869 goto fail; 18870 } 18871 18872 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 18873 goto fail; 18874 18875 switch (c_parser_peek_token (parser)->type) 18876 { 18877 case CPP_PLUS: 18878 reduc_code = PLUS_EXPR; 18879 break; 18880 case CPP_MULT: 18881 reduc_code = MULT_EXPR; 18882 break; 18883 case CPP_MINUS: 18884 reduc_code = MINUS_EXPR; 18885 break; 18886 case CPP_AND: 18887 reduc_code = BIT_AND_EXPR; 18888 break; 18889 case CPP_XOR: 18890 reduc_code = BIT_XOR_EXPR; 18891 break; 18892 case CPP_OR: 18893 reduc_code = BIT_IOR_EXPR; 18894 break; 18895 case CPP_AND_AND: 18896 reduc_code = TRUTH_ANDIF_EXPR; 18897 break; 18898 case CPP_OR_OR: 18899 reduc_code = TRUTH_ORIF_EXPR; 18900 break; 18901 case CPP_NAME: 18902 const char *p; 18903 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 18904 if (strcmp (p, "min") == 0) 18905 { 18906 reduc_code = MIN_EXPR; 18907 break; 18908 } 18909 if (strcmp (p, "max") == 0) 18910 { 18911 reduc_code = MAX_EXPR; 18912 break; 18913 } 18914 reduc_id = c_parser_peek_token (parser)->value; 18915 break; 18916 default: 18917 c_parser_error (parser, 18918 "expected %<+%>, %<*%>, %<-%>, %<&%>, " 18919 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier"); 18920 goto fail; 18921 } 18922 18923 tree orig_reduc_id, reduc_decl; 18924 orig_reduc_id = reduc_id; 18925 reduc_id = c_omp_reduction_id (reduc_code, reduc_id); 18926 reduc_decl = c_omp_reduction_decl (reduc_id); 18927 c_parser_consume_token (parser); 18928 18929 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 18930 goto fail; 18931 18932 while (true) 18933 { 18934 location_t loc = c_parser_peek_token (parser)->location; 18935 struct c_type_name *ctype = c_parser_type_name (parser); 18936 if (ctype != NULL) 18937 { 18938 type = groktypename (ctype, NULL, NULL); 18939 if (type == error_mark_node) 18940 ; 18941 else if ((INTEGRAL_TYPE_P (type) 18942 || TREE_CODE (type) == REAL_TYPE 18943 || TREE_CODE (type) == COMPLEX_TYPE) 18944 && orig_reduc_id == NULL_TREE) 18945 error_at (loc, "predeclared arithmetic type in " 18946 "%<#pragma omp declare reduction%>"); 18947 else if (TREE_CODE (type) == FUNCTION_TYPE 18948 || TREE_CODE (type) == ARRAY_TYPE) 18949 error_at (loc, "function or array type in " 18950 "%<#pragma omp declare reduction%>"); 18951 else if (TYPE_ATOMIC (type)) 18952 error_at (loc, "%<_Atomic%> qualified type in " 18953 "%<#pragma omp declare reduction%>"); 18954 else if (TYPE_QUALS_NO_ADDR_SPACE (type)) 18955 error_at (loc, "const, volatile or restrict qualified type in " 18956 "%<#pragma omp declare reduction%>"); 18957 else 18958 { 18959 tree t; 18960 for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t)) 18961 if (comptypes (TREE_PURPOSE (t), type)) 18962 { 18963 error_at (loc, "redeclaration of %qs " 18964 "%<#pragma omp declare reduction%> for " 18965 "type %qT", 18966 IDENTIFIER_POINTER (reduc_id) 18967 + sizeof ("omp declare reduction ") - 1, 18968 type); 18969 location_t ploc 18970 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t), 18971 0)); 18972 error_at (ploc, "previous %<#pragma omp declare " 18973 "reduction%>"); 18974 break; 18975 } 18976 if (t == NULL_TREE) 18977 types.safe_push (type); 18978 } 18979 if (c_parser_next_token_is (parser, CPP_COMMA)) 18980 c_parser_consume_token (parser); 18981 else 18982 break; 18983 } 18984 else 18985 break; 18986 } 18987 18988 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>") 18989 || types.is_empty ()) 18990 { 18991 fail: 18992 clauses.release (); 18993 types.release (); 18994 while (true) 18995 { 18996 c_token *token = c_parser_peek_token (parser); 18997 if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL) 18998 break; 18999 c_parser_consume_token (parser); 19000 } 19001 c_parser_skip_to_pragma_eol (parser); 19002 return; 19003 } 19004 19005 if (types.length () > 1) 19006 { 19007 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 19008 { 19009 c_token *token = c_parser_peek_token (parser); 19010 if (token->type == CPP_EOF) 19011 goto fail; 19012 clauses.safe_push (*token); 19013 c_parser_consume_token (parser); 19014 } 19015 clauses.safe_push (*c_parser_peek_token (parser)); 19016 c_parser_skip_to_pragma_eol (parser); 19017 19018 /* Make sure nothing tries to read past the end of the tokens. */ 19019 c_token eof_token; 19020 memset (&eof_token, 0, sizeof (eof_token)); 19021 eof_token.type = CPP_EOF; 19022 clauses.safe_push (eof_token); 19023 clauses.safe_push (eof_token); 19024 } 19025 19026 int errs = errorcount; 19027 FOR_EACH_VEC_ELT (types, i, type) 19028 { 19029 tokens_avail = parser->tokens_avail; 19030 gcc_assert (parser->tokens == &parser->tokens_buf[0]); 19031 if (!clauses.is_empty ()) 19032 { 19033 parser->tokens = clauses.address (); 19034 parser->tokens_avail = clauses.length (); 19035 parser->in_pragma = true; 19036 } 19037 19038 bool nested = current_function_decl != NULL_TREE; 19039 if (nested) 19040 c_push_function_context (); 19041 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, 19042 reduc_id, default_function_type); 19043 current_function_decl = fndecl; 19044 allocate_struct_function (fndecl, true); 19045 push_scope (); 19046 tree stmt = push_stmt_list (); 19047 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't 19048 warn about these. */ 19049 tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL, 19050 get_identifier ("omp_out"), type); 19051 DECL_ARTIFICIAL (omp_out) = 1; 19052 DECL_CONTEXT (omp_out) = fndecl; 19053 pushdecl (omp_out); 19054 tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL, 19055 get_identifier ("omp_in"), type); 19056 DECL_ARTIFICIAL (omp_in) = 1; 19057 DECL_CONTEXT (omp_in) = fndecl; 19058 pushdecl (omp_in); 19059 struct c_expr combiner = c_parser_expression (parser); 19060 struct c_expr initializer; 19061 tree omp_priv = NULL_TREE, omp_orig = NULL_TREE; 19062 bool bad = false; 19063 initializer.set_error (); 19064 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) 19065 bad = true; 19066 else if (c_parser_next_token_is (parser, CPP_NAME) 19067 && strcmp (IDENTIFIER_POINTER 19068 (c_parser_peek_token (parser)->value), 19069 "initializer") == 0) 19070 { 19071 c_parser_consume_token (parser); 19072 pop_scope (); 19073 push_scope (); 19074 omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL, 19075 get_identifier ("omp_priv"), type); 19076 DECL_ARTIFICIAL (omp_priv) = 1; 19077 DECL_INITIAL (omp_priv) = error_mark_node; 19078 DECL_CONTEXT (omp_priv) = fndecl; 19079 pushdecl (omp_priv); 19080 omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL, 19081 get_identifier ("omp_orig"), type); 19082 DECL_ARTIFICIAL (omp_orig) = 1; 19083 DECL_CONTEXT (omp_orig) = fndecl; 19084 pushdecl (omp_orig); 19085 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 19086 bad = true; 19087 else if (!c_parser_next_token_is (parser, CPP_NAME)) 19088 { 19089 c_parser_error (parser, "expected %<omp_priv%> or " 19090 "function-name"); 19091 bad = true; 19092 } 19093 else if (strcmp (IDENTIFIER_POINTER 19094 (c_parser_peek_token (parser)->value), 19095 "omp_priv") != 0) 19096 { 19097 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN 19098 || c_parser_peek_token (parser)->id_kind != C_ID_ID) 19099 { 19100 c_parser_error (parser, "expected function-name %<(%>"); 19101 bad = true; 19102 } 19103 else 19104 initializer = c_parser_postfix_expression (parser); 19105 if (initializer.value 19106 && TREE_CODE (initializer.value) == CALL_EXPR) 19107 { 19108 int j; 19109 tree c = initializer.value; 19110 for (j = 0; j < call_expr_nargs (c); j++) 19111 { 19112 tree a = CALL_EXPR_ARG (c, j); 19113 STRIP_NOPS (a); 19114 if (TREE_CODE (a) == ADDR_EXPR 19115 && TREE_OPERAND (a, 0) == omp_priv) 19116 break; 19117 } 19118 if (j == call_expr_nargs (c)) 19119 error ("one of the initializer call arguments should be " 19120 "%<&omp_priv%>"); 19121 } 19122 } 19123 else 19124 { 19125 c_parser_consume_token (parser); 19126 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) 19127 bad = true; 19128 else 19129 { 19130 tree st = push_stmt_list (); 19131 location_t loc = c_parser_peek_token (parser)->location; 19132 rich_location richloc (line_table, loc); 19133 start_init (omp_priv, NULL_TREE, 0, &richloc); 19134 struct c_expr init = c_parser_initializer (parser); 19135 finish_init (); 19136 finish_decl (omp_priv, loc, init.value, 19137 init.original_type, NULL_TREE); 19138 pop_stmt_list (st); 19139 } 19140 } 19141 if (!bad 19142 && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) 19143 bad = true; 19144 } 19145 19146 if (!bad) 19147 { 19148 c_parser_skip_to_pragma_eol (parser); 19149 19150 tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3), 19151 DECL_INITIAL (reduc_decl)); 19152 DECL_INITIAL (reduc_decl) = t; 19153 DECL_SOURCE_LOCATION (omp_out) = rloc; 19154 TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out; 19155 TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in; 19156 TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value; 19157 walk_tree (&combiner.value, c_check_omp_declare_reduction_r, 19158 &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL); 19159 if (omp_priv) 19160 { 19161 DECL_SOURCE_LOCATION (omp_priv) = rloc; 19162 TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv; 19163 TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig; 19164 TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value; 19165 walk_tree (&initializer.value, c_check_omp_declare_reduction_r, 19166 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL); 19167 walk_tree (&DECL_INITIAL (omp_priv), 19168 c_check_omp_declare_reduction_r, 19169 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL); 19170 } 19171 } 19172 19173 pop_stmt_list (stmt); 19174 pop_scope (); 19175 if (cfun->language != NULL) 19176 { 19177 ggc_free (cfun->language); 19178 cfun->language = NULL; 19179 } 19180 set_cfun (NULL); 19181 current_function_decl = NULL_TREE; 19182 if (nested) 19183 c_pop_function_context (); 19184 19185 if (!clauses.is_empty ()) 19186 { 19187 parser->tokens = &parser->tokens_buf[0]; 19188 parser->tokens_avail = tokens_avail; 19189 } 19190 if (bad) 19191 goto fail; 19192 if (errs != errorcount) 19193 break; 19194 } 19195 19196 clauses.release (); 19197 types.release (); 19198 } 19199 19200 19201 /* OpenMP 4.0 19202 #pragma omp declare simd declare-simd-clauses[optseq] new-line 19203 #pragma omp declare reduction (reduction-id : typename-list : expression) \ 19204 initializer-clause[opt] new-line 19205 #pragma omp declare target new-line */ 19206 19207 static void 19208 c_parser_omp_declare (c_parser *parser, enum pragma_context context) 19209 { 19210 c_parser_consume_pragma (parser); 19211 if (c_parser_next_token_is (parser, CPP_NAME)) 19212 { 19213 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 19214 if (strcmp (p, "simd") == 0) 19215 { 19216 /* c_parser_consume_token (parser); done in 19217 c_parser_omp_declare_simd. */ 19218 c_parser_omp_declare_simd (parser, context); 19219 return; 19220 } 19221 if (strcmp (p, "reduction") == 0) 19222 { 19223 c_parser_consume_token (parser); 19224 c_parser_omp_declare_reduction (parser, context); 19225 return; 19226 } 19227 if (!flag_openmp) /* flag_openmp_simd */ 19228 { 19229 c_parser_skip_to_pragma_eol (parser, false); 19230 return; 19231 } 19232 if (strcmp (p, "target") == 0) 19233 { 19234 c_parser_consume_token (parser); 19235 c_parser_omp_declare_target (parser); 19236 return; 19237 } 19238 } 19239 19240 c_parser_error (parser, "expected %<simd%> or %<reduction%> " 19241 "or %<target%>"); 19242 c_parser_skip_to_pragma_eol (parser); 19243 } 19244 19245 /* OpenMP 5.0 19246 #pragma omp requires clauses[optseq] new-line */ 19247 19248 static void 19249 c_parser_omp_requires (c_parser *parser) 19250 { 19251 bool first = true; 19252 enum omp_requires new_req = (enum omp_requires) 0; 19253 19254 c_parser_consume_pragma (parser); 19255 19256 location_t loc = c_parser_peek_token (parser)->location; 19257 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 19258 { 19259 if (!first && c_parser_next_token_is (parser, CPP_COMMA)) 19260 c_parser_consume_token (parser); 19261 19262 first = false; 19263 19264 if (c_parser_next_token_is (parser, CPP_NAME)) 19265 { 19266 const char *p 19267 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 19268 location_t cloc = c_parser_peek_token (parser)->location; 19269 enum omp_requires this_req = (enum omp_requires) 0; 19270 19271 if (!strcmp (p, "unified_address")) 19272 this_req = OMP_REQUIRES_UNIFIED_ADDRESS; 19273 else if (!strcmp (p, "unified_shared_memory")) 19274 this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY; 19275 else if (!strcmp (p, "dynamic_allocators")) 19276 this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS; 19277 else if (!strcmp (p, "reverse_offload")) 19278 this_req = OMP_REQUIRES_REVERSE_OFFLOAD; 19279 else if (!strcmp (p, "atomic_default_mem_order")) 19280 { 19281 c_parser_consume_token (parser); 19282 19283 matching_parens parens; 19284 if (parens.require_open (parser)) 19285 { 19286 if (c_parser_next_token_is (parser, CPP_NAME)) 19287 { 19288 tree v = c_parser_peek_token (parser)->value; 19289 p = IDENTIFIER_POINTER (v); 19290 19291 if (!strcmp (p, "seq_cst")) 19292 this_req 19293 = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST; 19294 else if (!strcmp (p, "relaxed")) 19295 this_req 19296 = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED; 19297 else if (!strcmp (p, "acq_rel")) 19298 this_req 19299 = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL; 19300 } 19301 if (this_req == 0) 19302 { 19303 error_at (c_parser_peek_token (parser)->location, 19304 "expected %<seq_cst%>, %<relaxed%> or " 19305 "%<acq_rel%>"); 19306 if (c_parser_peek_2nd_token (parser)->type 19307 == CPP_CLOSE_PAREN) 19308 c_parser_consume_token (parser); 19309 } 19310 else 19311 c_parser_consume_token (parser); 19312 19313 parens.skip_until_found_close (parser); 19314 if (this_req == 0) 19315 { 19316 c_parser_skip_to_pragma_eol (parser, false); 19317 return; 19318 } 19319 } 19320 p = NULL; 19321 } 19322 else 19323 { 19324 error_at (cloc, "expected %<unified_address%>, " 19325 "%<unified_shared_memory%>, " 19326 "%<dynamic_allocators%>, " 19327 "%<reverse_offload%> " 19328 "or %<atomic_default_mem_order%> clause"); 19329 c_parser_skip_to_pragma_eol (parser, false); 19330 return; 19331 } 19332 if (p) 19333 sorry_at (cloc, "%qs clause on %<requires%> directive not " 19334 "supported yet", p); 19335 if (p) 19336 c_parser_consume_token (parser); 19337 if (this_req) 19338 { 19339 if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0) 19340 { 19341 if ((this_req & new_req) != 0) 19342 error_at (cloc, "too many %qs clauses", p); 19343 if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS 19344 && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0) 19345 error_at (cloc, "%qs clause used lexically after first " 19346 "target construct or offloading API", p); 19347 } 19348 else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0) 19349 { 19350 error_at (cloc, "too many %qs clauses", 19351 "atomic_default_mem_order"); 19352 this_req = (enum omp_requires) 0; 19353 } 19354 else if ((omp_requires_mask 19355 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0) 19356 { 19357 error_at (cloc, "more than one %<atomic_default_mem_order%>" 19358 " clause in a single compilation unit"); 19359 this_req 19360 = (enum omp_requires) 19361 (omp_requires_mask 19362 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER); 19363 } 19364 else if ((omp_requires_mask 19365 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0) 19366 error_at (cloc, "%<atomic_default_mem_order%> clause used " 19367 "lexically after first %<atomic%> construct " 19368 "without memory order clause"); 19369 new_req = (enum omp_requires) (new_req | this_req); 19370 omp_requires_mask 19371 = (enum omp_requires) (omp_requires_mask | this_req); 19372 continue; 19373 } 19374 } 19375 break; 19376 } 19377 c_parser_skip_to_pragma_eol (parser); 19378 19379 if (new_req == 0) 19380 error_at (loc, "%<pragma omp requires%> requires at least one clause"); 19381 } 19382 19383 /* Helper function for c_parser_omp_taskloop. 19384 Disallow zero sized or potentially zero sized task reductions. */ 19385 19386 static tree 19387 c_finish_taskloop_clauses (tree clauses) 19388 { 19389 tree *pc = &clauses; 19390 for (tree c = clauses; c; c = *pc) 19391 { 19392 bool remove = false; 19393 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION) 19394 { 19395 tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c))); 19396 if (integer_zerop (TYPE_SIZE_UNIT (type))) 19397 { 19398 error_at (OMP_CLAUSE_LOCATION (c), 19399 "zero sized type %qT in %<reduction%> clause", type); 19400 remove = true; 19401 } 19402 else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST) 19403 { 19404 error_at (OMP_CLAUSE_LOCATION (c), 19405 "variable sized type %qT in %<reduction%> clause", 19406 type); 19407 remove = true; 19408 } 19409 } 19410 if (remove) 19411 *pc = OMP_CLAUSE_CHAIN (c); 19412 else 19413 pc = &OMP_CLAUSE_CHAIN (c); 19414 } 19415 return clauses; 19416 } 19417 19418 /* OpenMP 4.5: 19419 #pragma omp taskloop taskloop-clause[optseq] new-line 19420 for-loop 19421 19422 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line 19423 for-loop */ 19424 19425 #define OMP_TASKLOOP_CLAUSE_MASK \ 19426 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \ 19427 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 19428 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 19429 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ 19430 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \ 19431 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \ 19432 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \ 19433 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \ 19434 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \ 19435 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 19436 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \ 19437 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \ 19438 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \ 19439 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \ 19440 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ 19441 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION)) 19442 19443 static tree 19444 c_parser_omp_taskloop (location_t loc, c_parser *parser, 19445 char *p_name, omp_clause_mask mask, tree *cclauses, 19446 bool *if_p) 19447 { 19448 tree clauses, block, ret; 19449 19450 strcat (p_name, " taskloop"); 19451 mask |= OMP_TASKLOOP_CLAUSE_MASK; 19452 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction 19453 clause. */ 19454 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0) 19455 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION); 19456 19457 if (c_parser_next_token_is (parser, CPP_NAME)) 19458 { 19459 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 19460 19461 if (strcmp (p, "simd") == 0) 19462 { 19463 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 19464 if (cclauses == NULL) 19465 cclauses = cclauses_buf; 19466 c_parser_consume_token (parser); 19467 if (!flag_openmp) /* flag_openmp_simd */ 19468 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses, 19469 if_p); 19470 block = c_begin_compound_stmt (true); 19471 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p); 19472 block = c_end_compound_stmt (loc, block, true); 19473 if (ret == NULL) 19474 return ret; 19475 ret = make_node (OMP_TASKLOOP); 19476 TREE_TYPE (ret) = void_type_node; 19477 OMP_FOR_BODY (ret) = block; 19478 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP]; 19479 OMP_FOR_CLAUSES (ret) 19480 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret)); 19481 SET_EXPR_LOCATION (ret, loc); 19482 add_stmt (ret); 19483 return ret; 19484 } 19485 } 19486 if (!flag_openmp) /* flag_openmp_simd */ 19487 { 19488 c_parser_skip_to_pragma_eol (parser, false); 19489 return NULL_TREE; 19490 } 19491 19492 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); 19493 if (cclauses) 19494 { 19495 omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses); 19496 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP]; 19497 } 19498 19499 clauses = c_finish_taskloop_clauses (clauses); 19500 block = c_begin_compound_stmt (true); 19501 ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p); 19502 block = c_end_compound_stmt (loc, block, true); 19503 add_stmt (block); 19504 19505 return ret; 19506 } 19507 19508 /* Main entry point to parsing most OpenMP pragmas. */ 19509 19510 static void 19511 c_parser_omp_construct (c_parser *parser, bool *if_p) 19512 { 19513 enum pragma_kind p_kind; 19514 location_t loc; 19515 tree stmt; 19516 char p_name[sizeof "#pragma omp teams distribute parallel for simd"]; 19517 omp_clause_mask mask (0); 19518 19519 loc = c_parser_peek_token (parser)->location; 19520 p_kind = c_parser_peek_token (parser)->pragma_kind; 19521 c_parser_consume_pragma (parser); 19522 19523 switch (p_kind) 19524 { 19525 case PRAGMA_OACC_ATOMIC: 19526 c_parser_omp_atomic (loc, parser); 19527 return; 19528 case PRAGMA_OACC_CACHE: 19529 strcpy (p_name, "#pragma acc"); 19530 stmt = c_parser_oacc_cache (loc, parser); 19531 break; 19532 case PRAGMA_OACC_DATA: 19533 stmt = c_parser_oacc_data (loc, parser, if_p); 19534 break; 19535 case PRAGMA_OACC_HOST_DATA: 19536 stmt = c_parser_oacc_host_data (loc, parser, if_p); 19537 break; 19538 case PRAGMA_OACC_KERNELS: 19539 case PRAGMA_OACC_PARALLEL: 19540 strcpy (p_name, "#pragma acc"); 19541 stmt = c_parser_oacc_kernels_parallel (loc, parser, p_kind, p_name, 19542 if_p); 19543 break; 19544 case PRAGMA_OACC_LOOP: 19545 strcpy (p_name, "#pragma acc"); 19546 stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p); 19547 break; 19548 case PRAGMA_OACC_WAIT: 19549 strcpy (p_name, "#pragma wait"); 19550 stmt = c_parser_oacc_wait (loc, parser, p_name); 19551 break; 19552 case PRAGMA_OMP_ATOMIC: 19553 c_parser_omp_atomic (loc, parser); 19554 return; 19555 case PRAGMA_OMP_CRITICAL: 19556 stmt = c_parser_omp_critical (loc, parser, if_p); 19557 break; 19558 case PRAGMA_OMP_DISTRIBUTE: 19559 strcpy (p_name, "#pragma omp"); 19560 stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p); 19561 break; 19562 case PRAGMA_OMP_FOR: 19563 strcpy (p_name, "#pragma omp"); 19564 stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p); 19565 break; 19566 case PRAGMA_OMP_MASTER: 19567 strcpy (p_name, "#pragma omp"); 19568 stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p); 19569 break; 19570 case PRAGMA_OMP_PARALLEL: 19571 strcpy (p_name, "#pragma omp"); 19572 stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p); 19573 break; 19574 case PRAGMA_OMP_SECTIONS: 19575 strcpy (p_name, "#pragma omp"); 19576 stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL); 19577 break; 19578 case PRAGMA_OMP_SIMD: 19579 strcpy (p_name, "#pragma omp"); 19580 stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p); 19581 break; 19582 case PRAGMA_OMP_SINGLE: 19583 stmt = c_parser_omp_single (loc, parser, if_p); 19584 break; 19585 case PRAGMA_OMP_TASK: 19586 stmt = c_parser_omp_task (loc, parser, if_p); 19587 break; 19588 case PRAGMA_OMP_TASKGROUP: 19589 stmt = c_parser_omp_taskgroup (loc, parser, if_p); 19590 break; 19591 case PRAGMA_OMP_TASKLOOP: 19592 strcpy (p_name, "#pragma omp"); 19593 stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p); 19594 break; 19595 case PRAGMA_OMP_TEAMS: 19596 strcpy (p_name, "#pragma omp"); 19597 stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p); 19598 break; 19599 default: 19600 gcc_unreachable (); 19601 } 19602 19603 if (stmt) 19604 gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION); 19605 } 19606 19607 19608 /* OpenMP 2.5: 19609 # pragma omp threadprivate (variable-list) */ 19610 19611 static void 19612 c_parser_omp_threadprivate (c_parser *parser) 19613 { 19614 tree vars, t; 19615 location_t loc; 19616 19617 c_parser_consume_pragma (parser); 19618 loc = c_parser_peek_token (parser)->location; 19619 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL); 19620 19621 /* Mark every variable in VARS to be assigned thread local storage. */ 19622 for (t = vars; t; t = TREE_CHAIN (t)) 19623 { 19624 tree v = TREE_PURPOSE (t); 19625 19626 /* FIXME diagnostics: Ideally we should keep individual 19627 locations for all the variables in the var list to make the 19628 following errors more precise. Perhaps 19629 c_parser_omp_var_list_parens() should construct a list of 19630 locations to go along with the var list. */ 19631 19632 /* If V had already been marked threadprivate, it doesn't matter 19633 whether it had been used prior to this point. */ 19634 if (!VAR_P (v)) 19635 error_at (loc, "%qD is not a variable", v); 19636 else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v)) 19637 error_at (loc, "%qE declared %<threadprivate%> after first use", v); 19638 else if (! is_global_var (v)) 19639 error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v); 19640 else if (TREE_TYPE (v) == error_mark_node) 19641 ; 19642 else if (! COMPLETE_TYPE_P (TREE_TYPE (v))) 19643 error_at (loc, "%<threadprivate%> %qE has incomplete type", v); 19644 else 19645 { 19646 if (! DECL_THREAD_LOCAL_P (v)) 19647 { 19648 set_decl_tls_model (v, decl_default_tls_model (v)); 19649 /* If rtl has been already set for this var, call 19650 make_decl_rtl once again, so that encode_section_info 19651 has a chance to look at the new decl flags. */ 19652 if (DECL_RTL_SET_P (v)) 19653 make_decl_rtl (v); 19654 } 19655 C_DECL_THREADPRIVATE_P (v) = 1; 19656 } 19657 } 19658 19659 c_parser_skip_to_pragma_eol (parser); 19660 } 19661 19662 /* Parse a transaction attribute (GCC Extension). 19663 19664 transaction-attribute: 19665 attributes 19666 [ [ any-word ] ] 19667 19668 The transactional memory language description is written for C++, 19669 and uses the C++0x attribute syntax. For compatibility, allow the 19670 bracket style for transactions in C as well. */ 19671 19672 static tree 19673 c_parser_transaction_attributes (c_parser *parser) 19674 { 19675 tree attr_name, attr = NULL; 19676 19677 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 19678 return c_parser_attributes (parser); 19679 19680 if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE)) 19681 return NULL_TREE; 19682 c_parser_consume_token (parser); 19683 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>")) 19684 goto error1; 19685 19686 attr_name = c_parser_attribute_any_word (parser); 19687 if (attr_name) 19688 { 19689 c_parser_consume_token (parser); 19690 attr = build_tree_list (attr_name, NULL_TREE); 19691 } 19692 else 19693 c_parser_error (parser, "expected identifier"); 19694 19695 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>"); 19696 error1: 19697 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>"); 19698 return attr; 19699 } 19700 19701 /* Parse a __transaction_atomic or __transaction_relaxed statement 19702 (GCC Extension). 19703 19704 transaction-statement: 19705 __transaction_atomic transaction-attribute[opt] compound-statement 19706 __transaction_relaxed compound-statement 19707 19708 Note that the only valid attribute is: "outer". 19709 */ 19710 19711 static tree 19712 c_parser_transaction (c_parser *parser, enum rid keyword) 19713 { 19714 unsigned int old_in = parser->in_transaction; 19715 unsigned int this_in = 1, new_in; 19716 location_t loc = c_parser_peek_token (parser)->location; 19717 tree stmt, attrs; 19718 19719 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC 19720 || keyword == RID_TRANSACTION_RELAXED) 19721 && c_parser_next_token_is_keyword (parser, keyword)); 19722 c_parser_consume_token (parser); 19723 19724 if (keyword == RID_TRANSACTION_RELAXED) 19725 this_in |= TM_STMT_ATTR_RELAXED; 19726 else 19727 { 19728 attrs = c_parser_transaction_attributes (parser); 19729 if (attrs) 19730 this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER); 19731 } 19732 19733 /* Keep track if we're in the lexical scope of an outer transaction. */ 19734 new_in = this_in | (old_in & TM_STMT_ATTR_OUTER); 19735 19736 parser->in_transaction = new_in; 19737 stmt = c_parser_compound_statement (parser); 19738 parser->in_transaction = old_in; 19739 19740 if (flag_tm) 19741 stmt = c_finish_transaction (loc, stmt, this_in); 19742 else 19743 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ? 19744 "%<__transaction_atomic%> without transactional memory support enabled" 19745 : "%<__transaction_relaxed %> " 19746 "without transactional memory support enabled")); 19747 19748 return stmt; 19749 } 19750 19751 /* Parse a __transaction_atomic or __transaction_relaxed expression 19752 (GCC Extension). 19753 19754 transaction-expression: 19755 __transaction_atomic ( expression ) 19756 __transaction_relaxed ( expression ) 19757 */ 19758 19759 static struct c_expr 19760 c_parser_transaction_expression (c_parser *parser, enum rid keyword) 19761 { 19762 struct c_expr ret; 19763 unsigned int old_in = parser->in_transaction; 19764 unsigned int this_in = 1; 19765 location_t loc = c_parser_peek_token (parser)->location; 19766 tree attrs; 19767 19768 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC 19769 || keyword == RID_TRANSACTION_RELAXED) 19770 && c_parser_next_token_is_keyword (parser, keyword)); 19771 c_parser_consume_token (parser); 19772 19773 if (keyword == RID_TRANSACTION_RELAXED) 19774 this_in |= TM_STMT_ATTR_RELAXED; 19775 else 19776 { 19777 attrs = c_parser_transaction_attributes (parser); 19778 if (attrs) 19779 this_in |= parse_tm_stmt_attr (attrs, 0); 19780 } 19781 19782 parser->in_transaction = this_in; 19783 matching_parens parens; 19784 if (parens.require_open (parser)) 19785 { 19786 tree expr = c_parser_expression (parser).value; 19787 ret.original_type = TREE_TYPE (expr); 19788 ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr); 19789 if (this_in & TM_STMT_ATTR_RELAXED) 19790 TRANSACTION_EXPR_RELAXED (ret.value) = 1; 19791 SET_EXPR_LOCATION (ret.value, loc); 19792 ret.original_code = TRANSACTION_EXPR; 19793 if (!parens.require_close (parser)) 19794 { 19795 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 19796 goto error; 19797 } 19798 } 19799 else 19800 { 19801 error: 19802 ret.set_error (); 19803 ret.original_code = ERROR_MARK; 19804 ret.original_type = NULL; 19805 } 19806 parser->in_transaction = old_in; 19807 19808 if (!flag_tm) 19809 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ? 19810 "%<__transaction_atomic%> without transactional memory support enabled" 19811 : "%<__transaction_relaxed %> " 19812 "without transactional memory support enabled")); 19813 19814 set_c_expr_source_range (&ret, loc, loc); 19815 19816 return ret; 19817 } 19818 19819 /* Parse a __transaction_cancel statement (GCC Extension). 19820 19821 transaction-cancel-statement: 19822 __transaction_cancel transaction-attribute[opt] ; 19823 19824 Note that the only valid attribute is "outer". 19825 */ 19826 19827 static tree 19828 c_parser_transaction_cancel (c_parser *parser) 19829 { 19830 location_t loc = c_parser_peek_token (parser)->location; 19831 tree attrs; 19832 bool is_outer = false; 19833 19834 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL)); 19835 c_parser_consume_token (parser); 19836 19837 attrs = c_parser_transaction_attributes (parser); 19838 if (attrs) 19839 is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0); 19840 19841 if (!flag_tm) 19842 { 19843 error_at (loc, "%<__transaction_cancel%> without " 19844 "transactional memory support enabled"); 19845 goto ret_error; 19846 } 19847 else if (parser->in_transaction & TM_STMT_ATTR_RELAXED) 19848 { 19849 error_at (loc, "%<__transaction_cancel%> within a " 19850 "%<__transaction_relaxed%>"); 19851 goto ret_error; 19852 } 19853 else if (is_outer) 19854 { 19855 if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0 19856 && !is_tm_may_cancel_outer (current_function_decl)) 19857 { 19858 error_at (loc, "outer %<__transaction_cancel%> not " 19859 "within outer %<__transaction_atomic%>"); 19860 error_at (loc, " or a %<transaction_may_cancel_outer%> function"); 19861 goto ret_error; 19862 } 19863 } 19864 else if (parser->in_transaction == 0) 19865 { 19866 error_at (loc, "%<__transaction_cancel%> not within " 19867 "%<__transaction_atomic%>"); 19868 goto ret_error; 19869 } 19870 19871 return add_stmt (build_tm_abort_call (loc, is_outer)); 19872 19873 ret_error: 19874 return build1 (NOP_EXPR, void_type_node, error_mark_node); 19875 } 19876 19877 /* Parse a single source file. */ 19878 19879 void 19880 c_parse_file (void) 19881 { 19882 /* Use local storage to begin. If the first token is a pragma, parse it. 19883 If it is #pragma GCC pch_preprocess, then this will load a PCH file 19884 which will cause garbage collection. */ 19885 c_parser tparser; 19886 19887 memset (&tparser, 0, sizeof tparser); 19888 tparser.tokens = &tparser.tokens_buf[0]; 19889 the_parser = &tparser; 19890 19891 if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS) 19892 c_parser_pragma_pch_preprocess (&tparser); 19893 else 19894 c_common_no_more_pch (); 19895 19896 the_parser = ggc_alloc<c_parser> (); 19897 *the_parser = tparser; 19898 if (tparser.tokens == &tparser.tokens_buf[0]) 19899 the_parser->tokens = &the_parser->tokens_buf[0]; 19900 19901 /* Initialize EH, if we've been told to do so. */ 19902 if (flag_exceptions) 19903 using_eh_for_cleanups (); 19904 19905 c_parser_translation_unit (the_parser); 19906 the_parser = NULL; 19907 } 19908 19909 /* Parse the body of a function declaration marked with "__RTL". 19910 19911 The RTL parser works on the level of characters read from a 19912 FILE *, whereas c_parser works at the level of tokens. 19913 Square this circle by consuming all of the tokens up to and 19914 including the closing brace, recording the start/end of the RTL 19915 fragment, and reopening the file and re-reading the relevant 19916 lines within the RTL parser. 19917 19918 This requires the opening and closing braces of the C function 19919 to be on separate lines from the RTL they wrap. 19920 19921 Take ownership of START_WITH_PASS, if non-NULL. */ 19922 19923 void 19924 c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass) 19925 { 19926 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) 19927 { 19928 free (start_with_pass); 19929 return; 19930 } 19931 19932 location_t start_loc = c_parser_peek_token (parser)->location; 19933 19934 /* Consume all tokens, up to the closing brace, handling 19935 matching pairs of braces in the rtl dump. */ 19936 int num_open_braces = 1; 19937 while (1) 19938 { 19939 switch (c_parser_peek_token (parser)->type) 19940 { 19941 case CPP_OPEN_BRACE: 19942 num_open_braces++; 19943 break; 19944 case CPP_CLOSE_BRACE: 19945 if (--num_open_braces == 0) 19946 goto found_closing_brace; 19947 break; 19948 case CPP_EOF: 19949 error_at (start_loc, "no closing brace"); 19950 free (start_with_pass); 19951 return; 19952 default: 19953 break; 19954 } 19955 c_parser_consume_token (parser); 19956 } 19957 19958 found_closing_brace: 19959 /* At the closing brace; record its location. */ 19960 location_t end_loc = c_parser_peek_token (parser)->location; 19961 19962 /* Consume the closing brace. */ 19963 c_parser_consume_token (parser); 19964 19965 /* Invoke the RTL parser. */ 19966 if (!read_rtl_function_body_from_file_range (start_loc, end_loc)) 19967 { 19968 free (start_with_pass); 19969 return; 19970 } 19971 19972 /* If a pass name was provided for START_WITH_PASS, run the backend 19973 accordingly now, on the cfun created above, transferring 19974 ownership of START_WITH_PASS. */ 19975 if (start_with_pass) 19976 run_rtl_passes (start_with_pass); 19977 } 19978 19979 #include "gt-c-c-parser.h" 19980