1 /* Parser for C and Objective-C. 2 Copyright (C) 1987-2020 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 sprintf (name, "__int%d__", int_n_data[i].bitsize); 162 id = get_identifier (name); 163 C_SET_RID_CODE (id, RID_FIRST_INT_N + i); 164 C_IS_RESERVED_WORD (id) = 1; 165 } 166 } 167 168 /* A parser structure recording information about the state and 169 context of parsing. Includes lexer information with up to two 170 tokens of look-ahead; more are not needed for C. */ 171 struct GTY(()) c_parser { 172 /* The look-ahead tokens. */ 173 c_token * GTY((skip)) tokens; 174 /* Buffer for look-ahead tokens. */ 175 c_token tokens_buf[4]; 176 /* How many look-ahead tokens are available (0 - 4, or 177 more if parsing from pre-lexed tokens). */ 178 unsigned int tokens_avail; 179 /* Raw look-ahead tokens, used only for checking in Objective-C 180 whether '[[' starts attributes. */ 181 vec<c_token, va_gc> *raw_tokens; 182 /* The number of raw look-ahead tokens that have since been fully 183 lexed. */ 184 unsigned int raw_tokens_used; 185 /* True if a syntax error is being recovered from; false otherwise. 186 c_parser_error sets this flag. It should clear this flag when 187 enough tokens have been consumed to recover from the error. */ 188 BOOL_BITFIELD error : 1; 189 /* True if we're processing a pragma, and shouldn't automatically 190 consume CPP_PRAGMA_EOL. */ 191 BOOL_BITFIELD in_pragma : 1; 192 /* True if we're parsing the outermost block of an if statement. */ 193 BOOL_BITFIELD in_if_block : 1; 194 /* True if we want to lex a translated, joined string (for an 195 initial #pragma pch_preprocess). Otherwise the parser is 196 responsible for concatenating strings and translating to the 197 execution character set as needed. */ 198 BOOL_BITFIELD lex_joined_string : 1; 199 /* True if, when the parser is concatenating string literals, it 200 should translate them to the execution character set (false 201 inside attributes). */ 202 BOOL_BITFIELD translate_strings_p : 1; 203 204 /* Objective-C specific parser/lexer information. */ 205 206 /* True if we are in a context where the Objective-C "PQ" keywords 207 are considered keywords. */ 208 BOOL_BITFIELD objc_pq_context : 1; 209 /* True if we are parsing a (potential) Objective-C foreach 210 statement. This is set to true after we parsed 'for (' and while 211 we wait for 'in' or ';' to decide if it's a standard C for loop or an 212 Objective-C foreach loop. */ 213 BOOL_BITFIELD objc_could_be_foreach_context : 1; 214 /* The following flag is needed to contextualize Objective-C lexical 215 analysis. In some cases (e.g., 'int NSObject;'), it is 216 undesirable to bind an identifier to an Objective-C class, even 217 if a class with that name exists. */ 218 BOOL_BITFIELD objc_need_raw_identifier : 1; 219 /* Nonzero if we're processing a __transaction statement. The value 220 is 1 | TM_STMT_ATTR_*. */ 221 unsigned int in_transaction : 4; 222 /* True if we are in a context where the Objective-C "Property attribute" 223 keywords are valid. */ 224 BOOL_BITFIELD objc_property_attr_context : 1; 225 226 /* Location of the last consumed token. */ 227 location_t last_token_location; 228 }; 229 230 /* Return a pointer to the Nth token in PARSERs tokens_buf. */ 231 232 c_token * 233 c_parser_tokens_buf (c_parser *parser, unsigned n) 234 { 235 return &parser->tokens_buf[n]; 236 } 237 238 /* Return the error state of PARSER. */ 239 240 bool 241 c_parser_error (c_parser *parser) 242 { 243 return parser->error; 244 } 245 246 /* Set the error state of PARSER to ERR. */ 247 248 void 249 c_parser_set_error (c_parser *parser, bool err) 250 { 251 parser->error = err; 252 } 253 254 255 /* The actual parser and external interface. ??? Does this need to be 256 garbage-collected? */ 257 258 static GTY (()) c_parser *the_parser; 259 260 /* Read in and lex a single token, storing it in *TOKEN. If RAW, 261 context-sensitive postprocessing of the token is not done. */ 262 263 static void 264 c_lex_one_token (c_parser *parser, c_token *token, bool raw = false) 265 { 266 timevar_push (TV_LEX); 267 268 if (raw || vec_safe_length (parser->raw_tokens) == 0) 269 { 270 token->type = c_lex_with_flags (&token->value, &token->location, 271 &token->flags, 272 (parser->lex_joined_string 273 ? 0 : C_LEX_STRING_NO_JOIN)); 274 token->id_kind = C_ID_NONE; 275 token->keyword = RID_MAX; 276 token->pragma_kind = PRAGMA_NONE; 277 } 278 else 279 { 280 /* Use a token previously lexed as a raw look-ahead token, and 281 complete the processing on it. */ 282 *token = (*parser->raw_tokens)[parser->raw_tokens_used]; 283 ++parser->raw_tokens_used; 284 if (parser->raw_tokens_used == vec_safe_length (parser->raw_tokens)) 285 { 286 vec_free (parser->raw_tokens); 287 parser->raw_tokens_used = 0; 288 } 289 } 290 291 if (raw) 292 goto out; 293 294 switch (token->type) 295 { 296 case CPP_NAME: 297 { 298 tree decl; 299 300 bool objc_force_identifier = parser->objc_need_raw_identifier; 301 if (c_dialect_objc ()) 302 parser->objc_need_raw_identifier = false; 303 304 if (C_IS_RESERVED_WORD (token->value)) 305 { 306 enum rid rid_code = C_RID_CODE (token->value); 307 308 if (rid_code == RID_CXX_COMPAT_WARN) 309 { 310 warning_at (token->location, 311 OPT_Wc___compat, 312 "identifier %qE conflicts with C++ keyword", 313 token->value); 314 } 315 else if (rid_code >= RID_FIRST_ADDR_SPACE 316 && rid_code <= RID_LAST_ADDR_SPACE) 317 { 318 addr_space_t as; 319 as = (addr_space_t) (rid_code - RID_FIRST_ADDR_SPACE); 320 targetm.addr_space.diagnose_usage (as, token->location); 321 token->id_kind = C_ID_ADDRSPACE; 322 token->keyword = rid_code; 323 break; 324 } 325 else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code)) 326 { 327 /* We found an Objective-C "pq" keyword (in, out, 328 inout, bycopy, byref, oneway). They need special 329 care because the interpretation depends on the 330 context. */ 331 if (parser->objc_pq_context) 332 { 333 token->type = CPP_KEYWORD; 334 token->keyword = rid_code; 335 break; 336 } 337 else if (parser->objc_could_be_foreach_context 338 && rid_code == RID_IN) 339 { 340 /* We are in Objective-C, inside a (potential) 341 foreach context (which means after having 342 parsed 'for (', but before having parsed ';'), 343 and we found 'in'. We consider it the keyword 344 which terminates the declaration at the 345 beginning of a foreach-statement. Note that 346 this means you can't use 'in' for anything else 347 in that context; in particular, in Objective-C 348 you can't use 'in' as the name of the running 349 variable in a C for loop. We could potentially 350 try to add code here to disambiguate, but it 351 seems a reasonable limitation. */ 352 token->type = CPP_KEYWORD; 353 token->keyword = rid_code; 354 break; 355 } 356 /* Else, "pq" keywords outside of the "pq" context are 357 not keywords, and we fall through to the code for 358 normal tokens. */ 359 } 360 else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code)) 361 { 362 /* We found an Objective-C "property attribute" 363 keyword (getter, setter, readonly, etc). These are 364 only valid in the property context. */ 365 if (parser->objc_property_attr_context) 366 { 367 token->type = CPP_KEYWORD; 368 token->keyword = rid_code; 369 break; 370 } 371 /* Else they are not special keywords. 372 */ 373 } 374 else if (c_dialect_objc () 375 && (OBJC_IS_AT_KEYWORD (rid_code) 376 || OBJC_IS_CXX_KEYWORD (rid_code))) 377 { 378 /* We found one of the Objective-C "@" keywords (defs, 379 selector, synchronized, etc) or one of the 380 Objective-C "cxx" keywords (class, private, 381 protected, public, try, catch, throw) without a 382 preceding '@' sign. Do nothing and fall through to 383 the code for normal tokens (in C++ we would still 384 consider the CXX ones keywords, but not in C). */ 385 ; 386 } 387 else 388 { 389 token->type = CPP_KEYWORD; 390 token->keyword = rid_code; 391 break; 392 } 393 } 394 395 decl = lookup_name (token->value); 396 if (decl) 397 { 398 if (TREE_CODE (decl) == TYPE_DECL) 399 { 400 token->id_kind = C_ID_TYPENAME; 401 break; 402 } 403 } 404 else if (c_dialect_objc ()) 405 { 406 tree objc_interface_decl = objc_is_class_name (token->value); 407 /* Objective-C class names are in the same namespace as 408 variables and typedefs, and hence are shadowed by local 409 declarations. */ 410 if (objc_interface_decl 411 && (!objc_force_identifier || global_bindings_p ())) 412 { 413 token->value = objc_interface_decl; 414 token->id_kind = C_ID_CLASSNAME; 415 break; 416 } 417 } 418 token->id_kind = C_ID_ID; 419 } 420 break; 421 case CPP_AT_NAME: 422 /* This only happens in Objective-C; it must be a keyword. */ 423 token->type = CPP_KEYWORD; 424 switch (C_RID_CODE (token->value)) 425 { 426 /* Replace 'class' with '@class', 'private' with '@private', 427 etc. This prevents confusion with the C++ keyword 428 'class', and makes the tokens consistent with other 429 Objective-C 'AT' keywords. For example '@class' is 430 reported as RID_AT_CLASS which is consistent with 431 '@synchronized', which is reported as 432 RID_AT_SYNCHRONIZED. 433 */ 434 case RID_CLASS: token->keyword = RID_AT_CLASS; break; 435 case RID_PRIVATE: token->keyword = RID_AT_PRIVATE; break; 436 case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break; 437 case RID_PUBLIC: token->keyword = RID_AT_PUBLIC; break; 438 case RID_THROW: token->keyword = RID_AT_THROW; break; 439 case RID_TRY: token->keyword = RID_AT_TRY; break; 440 case RID_CATCH: token->keyword = RID_AT_CATCH; break; 441 case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break; 442 default: token->keyword = C_RID_CODE (token->value); 443 } 444 break; 445 case CPP_COLON: 446 case CPP_COMMA: 447 case CPP_CLOSE_PAREN: 448 case CPP_SEMICOLON: 449 /* These tokens may affect the interpretation of any identifiers 450 following, if doing Objective-C. */ 451 if (c_dialect_objc ()) 452 parser->objc_need_raw_identifier = false; 453 break; 454 case CPP_PRAGMA: 455 /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST. */ 456 token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value); 457 token->value = NULL; 458 break; 459 default: 460 break; 461 } 462 out: 463 timevar_pop (TV_LEX); 464 } 465 466 /* Return a pointer to the next token from PARSER, reading it in if 467 necessary. */ 468 469 c_token * 470 c_parser_peek_token (c_parser *parser) 471 { 472 if (parser->tokens_avail == 0) 473 { 474 c_lex_one_token (parser, &parser->tokens[0]); 475 parser->tokens_avail = 1; 476 } 477 return &parser->tokens[0]; 478 } 479 480 /* Return a pointer to the next-but-one token from PARSER, reading it 481 in if necessary. The next token is already read in. */ 482 483 c_token * 484 c_parser_peek_2nd_token (c_parser *parser) 485 { 486 if (parser->tokens_avail >= 2) 487 return &parser->tokens[1]; 488 gcc_assert (parser->tokens_avail == 1); 489 gcc_assert (parser->tokens[0].type != CPP_EOF); 490 gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL); 491 c_lex_one_token (parser, &parser->tokens[1]); 492 parser->tokens_avail = 2; 493 return &parser->tokens[1]; 494 } 495 496 /* Return a pointer to the Nth token from PARSER, reading it 497 in if necessary. The N-1th token is already read in. */ 498 499 c_token * 500 c_parser_peek_nth_token (c_parser *parser, unsigned int n) 501 { 502 /* N is 1-based, not zero-based. */ 503 gcc_assert (n > 0); 504 505 if (parser->tokens_avail >= n) 506 return &parser->tokens[n - 1]; 507 gcc_assert (parser->tokens_avail == n - 1); 508 c_lex_one_token (parser, &parser->tokens[n - 1]); 509 parser->tokens_avail = n; 510 return &parser->tokens[n - 1]; 511 } 512 513 /* Return a pointer to the Nth token from PARSER, reading it in as a 514 raw look-ahead token if necessary. The N-1th token is already read 515 in. Raw look-ahead tokens remain available for when the non-raw 516 functions above are called. */ 517 518 c_token * 519 c_parser_peek_nth_token_raw (c_parser *parser, unsigned int n) 520 { 521 /* N is 1-based, not zero-based. */ 522 gcc_assert (n > 0); 523 524 if (parser->tokens_avail >= n) 525 return &parser->tokens[n - 1]; 526 unsigned int raw_len = vec_safe_length (parser->raw_tokens); 527 unsigned int raw_avail 528 = parser->tokens_avail + raw_len - parser->raw_tokens_used; 529 gcc_assert (raw_avail >= n - 1); 530 if (raw_avail >= n) 531 return &(*parser->raw_tokens)[parser->raw_tokens_used 532 + n - 1 - parser->tokens_avail]; 533 vec_safe_reserve (parser->raw_tokens, 1); 534 parser->raw_tokens->quick_grow (raw_len + 1); 535 c_lex_one_token (parser, &(*parser->raw_tokens)[raw_len], true); 536 return &(*parser->raw_tokens)[raw_len]; 537 } 538 539 bool 540 c_keyword_starts_typename (enum rid keyword) 541 { 542 switch (keyword) 543 { 544 case RID_UNSIGNED: 545 case RID_LONG: 546 case RID_SHORT: 547 case RID_SIGNED: 548 case RID_COMPLEX: 549 case RID_INT: 550 case RID_CHAR: 551 case RID_FLOAT: 552 case RID_DOUBLE: 553 case RID_VOID: 554 case RID_DFLOAT32: 555 case RID_DFLOAT64: 556 case RID_DFLOAT128: 557 CASE_RID_FLOATN_NX: 558 case RID_BOOL: 559 case RID_ENUM: 560 case RID_STRUCT: 561 case RID_UNION: 562 case RID_TYPEOF: 563 case RID_CONST: 564 case RID_ATOMIC: 565 case RID_VOLATILE: 566 case RID_RESTRICT: 567 case RID_ATTRIBUTE: 568 case RID_FRACT: 569 case RID_ACCUM: 570 case RID_SAT: 571 case RID_AUTO_TYPE: 572 case RID_ALIGNAS: 573 return true; 574 default: 575 if (keyword >= RID_FIRST_INT_N 576 && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS 577 && int_n_enabled_p[keyword - RID_FIRST_INT_N]) 578 return true; 579 return false; 580 } 581 } 582 583 /* Return true if TOKEN can start a type name, 584 false otherwise. */ 585 bool 586 c_token_starts_typename (c_token *token) 587 { 588 switch (token->type) 589 { 590 case CPP_NAME: 591 switch (token->id_kind) 592 { 593 case C_ID_ID: 594 return false; 595 case C_ID_ADDRSPACE: 596 return true; 597 case C_ID_TYPENAME: 598 return true; 599 case C_ID_CLASSNAME: 600 gcc_assert (c_dialect_objc ()); 601 return true; 602 default: 603 gcc_unreachable (); 604 } 605 case CPP_KEYWORD: 606 return c_keyword_starts_typename (token->keyword); 607 case CPP_LESS: 608 if (c_dialect_objc ()) 609 return true; 610 return false; 611 default: 612 return false; 613 } 614 } 615 616 /* Return true if the next token from PARSER can start a type name, 617 false otherwise. LA specifies how to do lookahead in order to 618 detect unknown type names. If unsure, pick CLA_PREFER_ID. */ 619 620 static inline bool 621 c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la) 622 { 623 c_token *token = c_parser_peek_token (parser); 624 if (c_token_starts_typename (token)) 625 return true; 626 627 /* Try a bit harder to detect an unknown typename. */ 628 if (la != cla_prefer_id 629 && token->type == CPP_NAME 630 && token->id_kind == C_ID_ID 631 632 /* Do not try too hard when we could have "object in array". */ 633 && !parser->objc_could_be_foreach_context 634 635 && (la == cla_prefer_type 636 || c_parser_peek_2nd_token (parser)->type == CPP_NAME 637 || c_parser_peek_2nd_token (parser)->type == CPP_MULT) 638 639 /* Only unknown identifiers. */ 640 && !lookup_name (token->value)) 641 return true; 642 643 return false; 644 } 645 646 /* Return true if TOKEN is a type qualifier, false otherwise. */ 647 static bool 648 c_token_is_qualifier (c_token *token) 649 { 650 switch (token->type) 651 { 652 case CPP_NAME: 653 switch (token->id_kind) 654 { 655 case C_ID_ADDRSPACE: 656 return true; 657 default: 658 return false; 659 } 660 case CPP_KEYWORD: 661 switch (token->keyword) 662 { 663 case RID_CONST: 664 case RID_VOLATILE: 665 case RID_RESTRICT: 666 case RID_ATTRIBUTE: 667 case RID_ATOMIC: 668 return true; 669 default: 670 return false; 671 } 672 case CPP_LESS: 673 return false; 674 default: 675 gcc_unreachable (); 676 } 677 } 678 679 /* Return true if the next token from PARSER is a type qualifier, 680 false otherwise. */ 681 static inline bool 682 c_parser_next_token_is_qualifier (c_parser *parser) 683 { 684 c_token *token = c_parser_peek_token (parser); 685 return c_token_is_qualifier (token); 686 } 687 688 /* Return true if TOKEN can start declaration specifiers (not 689 including standard attributes), false otherwise. */ 690 static bool 691 c_token_starts_declspecs (c_token *token) 692 { 693 switch (token->type) 694 { 695 case CPP_NAME: 696 switch (token->id_kind) 697 { 698 case C_ID_ID: 699 return false; 700 case C_ID_ADDRSPACE: 701 return true; 702 case C_ID_TYPENAME: 703 return true; 704 case C_ID_CLASSNAME: 705 gcc_assert (c_dialect_objc ()); 706 return true; 707 default: 708 gcc_unreachable (); 709 } 710 case CPP_KEYWORD: 711 switch (token->keyword) 712 { 713 case RID_STATIC: 714 case RID_EXTERN: 715 case RID_REGISTER: 716 case RID_TYPEDEF: 717 case RID_INLINE: 718 case RID_NORETURN: 719 case RID_AUTO: 720 case RID_THREAD: 721 case RID_UNSIGNED: 722 case RID_LONG: 723 case RID_SHORT: 724 case RID_SIGNED: 725 case RID_COMPLEX: 726 case RID_INT: 727 case RID_CHAR: 728 case RID_FLOAT: 729 case RID_DOUBLE: 730 case RID_VOID: 731 case RID_DFLOAT32: 732 case RID_DFLOAT64: 733 case RID_DFLOAT128: 734 CASE_RID_FLOATN_NX: 735 case RID_BOOL: 736 case RID_ENUM: 737 case RID_STRUCT: 738 case RID_UNION: 739 case RID_TYPEOF: 740 case RID_CONST: 741 case RID_VOLATILE: 742 case RID_RESTRICT: 743 case RID_ATTRIBUTE: 744 case RID_FRACT: 745 case RID_ACCUM: 746 case RID_SAT: 747 case RID_ALIGNAS: 748 case RID_ATOMIC: 749 case RID_AUTO_TYPE: 750 return true; 751 default: 752 if (token->keyword >= RID_FIRST_INT_N 753 && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS 754 && int_n_enabled_p[token->keyword - RID_FIRST_INT_N]) 755 return true; 756 return false; 757 } 758 case CPP_LESS: 759 if (c_dialect_objc ()) 760 return true; 761 return false; 762 default: 763 return false; 764 } 765 } 766 767 768 /* Return true if TOKEN can start declaration specifiers (not 769 including standard attributes) or a static assertion, false 770 otherwise. */ 771 static bool 772 c_token_starts_declaration (c_token *token) 773 { 774 if (c_token_starts_declspecs (token) 775 || token->keyword == RID_STATIC_ASSERT) 776 return true; 777 else 778 return false; 779 } 780 781 /* Return true if the next token from PARSER can start declaration 782 specifiers (not including standard attributes), false 783 otherwise. */ 784 bool 785 c_parser_next_token_starts_declspecs (c_parser *parser) 786 { 787 c_token *token = c_parser_peek_token (parser); 788 789 /* In Objective-C, a classname normally starts a declspecs unless it 790 is immediately followed by a dot. In that case, it is the 791 Objective-C 2.0 "dot-syntax" for class objects, ie, calls the 792 setter/getter on the class. c_token_starts_declspecs() can't 793 differentiate between the two cases because it only checks the 794 current token, so we have a special check here. */ 795 if (c_dialect_objc () 796 && token->type == CPP_NAME 797 && token->id_kind == C_ID_CLASSNAME 798 && c_parser_peek_2nd_token (parser)->type == CPP_DOT) 799 return false; 800 801 return c_token_starts_declspecs (token); 802 } 803 804 /* Return true if the next tokens from PARSER can start declaration 805 specifiers (not including standard attributes) or a static 806 assertion, false otherwise. */ 807 bool 808 c_parser_next_tokens_start_declaration (c_parser *parser) 809 { 810 c_token *token = c_parser_peek_token (parser); 811 812 /* Same as above. */ 813 if (c_dialect_objc () 814 && token->type == CPP_NAME 815 && token->id_kind == C_ID_CLASSNAME 816 && c_parser_peek_2nd_token (parser)->type == CPP_DOT) 817 return false; 818 819 /* Labels do not start declarations. */ 820 if (token->type == CPP_NAME 821 && c_parser_peek_2nd_token (parser)->type == CPP_COLON) 822 return false; 823 824 if (c_token_starts_declaration (token)) 825 return true; 826 827 if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl)) 828 return true; 829 830 return false; 831 } 832 833 /* Consume the next token from PARSER. */ 834 835 void 836 c_parser_consume_token (c_parser *parser) 837 { 838 gcc_assert (parser->tokens_avail >= 1); 839 gcc_assert (parser->tokens[0].type != CPP_EOF); 840 gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL); 841 gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA); 842 parser->last_token_location = parser->tokens[0].location; 843 if (parser->tokens != &parser->tokens_buf[0]) 844 parser->tokens++; 845 else if (parser->tokens_avail >= 2) 846 { 847 parser->tokens[0] = parser->tokens[1]; 848 if (parser->tokens_avail >= 3) 849 { 850 parser->tokens[1] = parser->tokens[2]; 851 if (parser->tokens_avail >= 4) 852 parser->tokens[2] = parser->tokens[3]; 853 } 854 } 855 parser->tokens_avail--; 856 } 857 858 /* Expect the current token to be a #pragma. Consume it and remember 859 that we've begun parsing a pragma. */ 860 861 static void 862 c_parser_consume_pragma (c_parser *parser) 863 { 864 gcc_assert (!parser->in_pragma); 865 gcc_assert (parser->tokens_avail >= 1); 866 gcc_assert (parser->tokens[0].type == CPP_PRAGMA); 867 if (parser->tokens != &parser->tokens_buf[0]) 868 parser->tokens++; 869 else if (parser->tokens_avail >= 2) 870 { 871 parser->tokens[0] = parser->tokens[1]; 872 if (parser->tokens_avail >= 3) 873 parser->tokens[1] = parser->tokens[2]; 874 } 875 parser->tokens_avail--; 876 parser->in_pragma = true; 877 } 878 879 /* Update the global input_location from TOKEN. */ 880 static inline void 881 c_parser_set_source_position_from_token (c_token *token) 882 { 883 if (token->type != CPP_EOF) 884 { 885 input_location = token->location; 886 } 887 } 888 889 /* Helper function for c_parser_error. 890 Having peeked a token of kind TOK1_KIND that might signify 891 a conflict marker, peek successor tokens to determine 892 if we actually do have a conflict marker. 893 Specifically, we consider a run of 7 '<', '=' or '>' characters 894 at the start of a line as a conflict marker. 895 These come through the lexer as three pairs and a single, 896 e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<'). 897 If it returns true, *OUT_LOC is written to with the location/range 898 of the marker. */ 899 900 static bool 901 c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind, 902 location_t *out_loc) 903 { 904 c_token *token2 = c_parser_peek_2nd_token (parser); 905 if (token2->type != tok1_kind) 906 return false; 907 c_token *token3 = c_parser_peek_nth_token (parser, 3); 908 if (token3->type != tok1_kind) 909 return false; 910 c_token *token4 = c_parser_peek_nth_token (parser, 4); 911 if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind)) 912 return false; 913 914 /* It must be at the start of the line. */ 915 location_t start_loc = c_parser_peek_token (parser)->location; 916 if (LOCATION_COLUMN (start_loc) != 1) 917 return false; 918 919 /* We have a conflict marker. Construct a location of the form: 920 <<<<<<< 921 ^~~~~~~ 922 with start == caret, finishing at the end of the marker. */ 923 location_t finish_loc = get_finish (token4->location); 924 *out_loc = make_location (start_loc, start_loc, finish_loc); 925 926 return true; 927 } 928 929 /* Issue a diagnostic of the form 930 FILE:LINE: MESSAGE before TOKEN 931 where TOKEN is the next token in the input stream of PARSER. 932 MESSAGE (specified by the caller) is usually of the form "expected 933 OTHER-TOKEN". 934 935 Use RICHLOC as the location of the diagnostic. 936 937 Do not issue a diagnostic if still recovering from an error. 938 939 Return true iff an error was actually emitted. 940 941 ??? This is taken from the C++ parser, but building up messages in 942 this way is not i18n-friendly and some other approach should be 943 used. */ 944 945 static bool 946 c_parser_error_richloc (c_parser *parser, const char *gmsgid, 947 rich_location *richloc) 948 { 949 c_token *token = c_parser_peek_token (parser); 950 if (parser->error) 951 return false; 952 parser->error = true; 953 if (!gmsgid) 954 return false; 955 956 /* If this is actually a conflict marker, report it as such. */ 957 if (token->type == CPP_LSHIFT 958 || token->type == CPP_RSHIFT 959 || token->type == CPP_EQ_EQ) 960 { 961 location_t loc; 962 if (c_parser_peek_conflict_marker (parser, token->type, &loc)) 963 { 964 error_at (loc, "version control conflict marker in file"); 965 return true; 966 } 967 } 968 969 c_parse_error (gmsgid, 970 /* Because c_parse_error does not understand 971 CPP_KEYWORD, keywords are treated like 972 identifiers. */ 973 (token->type == CPP_KEYWORD ? CPP_NAME : token->type), 974 /* ??? The C parser does not save the cpp flags of a 975 token, we need to pass 0 here and we will not get 976 the source spelling of some tokens but rather the 977 canonical spelling. */ 978 token->value, /*flags=*/0, richloc); 979 return true; 980 } 981 982 /* As c_parser_error_richloc, but issue the message at the 983 location of PARSER's next token, or at input_location 984 if the next token is EOF. */ 985 986 bool 987 c_parser_error (c_parser *parser, const char *gmsgid) 988 { 989 c_token *token = c_parser_peek_token (parser); 990 c_parser_set_source_position_from_token (token); 991 rich_location richloc (line_table, input_location); 992 return c_parser_error_richloc (parser, gmsgid, &richloc); 993 } 994 995 /* Some tokens naturally come in pairs e.g.'(' and ')'. 996 This class is for tracking such a matching pair of symbols. 997 In particular, it tracks the location of the first token, 998 so that if the second token is missing, we can highlight the 999 location of the first token when notifying the user about the 1000 problem. */ 1001 1002 template <typename traits_t> 1003 class token_pair 1004 { 1005 public: 1006 /* token_pair's ctor. */ 1007 token_pair () : m_open_loc (UNKNOWN_LOCATION) {} 1008 1009 /* If the next token is the opening symbol for this pair, consume it and 1010 return true. 1011 Otherwise, issue an error and return false. 1012 In either case, record the location of the opening token. */ 1013 1014 bool require_open (c_parser *parser) 1015 { 1016 c_token *token = c_parser_peek_token (parser); 1017 if (token) 1018 m_open_loc = token->location; 1019 1020 return c_parser_require (parser, traits_t::open_token_type, 1021 traits_t::open_gmsgid); 1022 } 1023 1024 /* Consume the next token from PARSER, recording its location as 1025 that of the opening token within the pair. */ 1026 1027 void consume_open (c_parser *parser) 1028 { 1029 c_token *token = c_parser_peek_token (parser); 1030 gcc_assert (token->type == traits_t::open_token_type); 1031 m_open_loc = token->location; 1032 c_parser_consume_token (parser); 1033 } 1034 1035 /* If the next token is the closing symbol for this pair, consume it 1036 and return true. 1037 Otherwise, issue an error, highlighting the location of the 1038 corresponding opening token, and return false. */ 1039 1040 bool require_close (c_parser *parser) const 1041 { 1042 return c_parser_require (parser, traits_t::close_token_type, 1043 traits_t::close_gmsgid, m_open_loc); 1044 } 1045 1046 /* Like token_pair::require_close, except that tokens will be skipped 1047 until the desired token is found. An error message is still produced 1048 if the next token is not as expected. */ 1049 1050 void skip_until_found_close (c_parser *parser) const 1051 { 1052 c_parser_skip_until_found (parser, traits_t::close_token_type, 1053 traits_t::close_gmsgid, m_open_loc); 1054 } 1055 1056 private: 1057 location_t m_open_loc; 1058 }; 1059 1060 /* Traits for token_pair<T> for tracking matching pairs of parentheses. */ 1061 1062 struct matching_paren_traits 1063 { 1064 static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN; 1065 static const char * const open_gmsgid; 1066 static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN; 1067 static const char * const close_gmsgid; 1068 }; 1069 1070 const char * const matching_paren_traits::open_gmsgid = "expected %<(%>"; 1071 const char * const matching_paren_traits::close_gmsgid = "expected %<)%>"; 1072 1073 /* "matching_parens" is a token_pair<T> class for tracking matching 1074 pairs of parentheses. */ 1075 1076 typedef token_pair<matching_paren_traits> matching_parens; 1077 1078 /* Traits for token_pair<T> for tracking matching pairs of braces. */ 1079 1080 struct matching_brace_traits 1081 { 1082 static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE; 1083 static const char * const open_gmsgid; 1084 static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE; 1085 static const char * const close_gmsgid; 1086 }; 1087 1088 const char * const matching_brace_traits::open_gmsgid = "expected %<{%>"; 1089 const char * const matching_brace_traits::close_gmsgid = "expected %<}%>"; 1090 1091 /* "matching_braces" is a token_pair<T> class for tracking matching 1092 pairs of braces. */ 1093 1094 typedef token_pair<matching_brace_traits> matching_braces; 1095 1096 /* Get a description of the matching symbol to TYPE e.g. "(" for 1097 CPP_CLOSE_PAREN. */ 1098 1099 static const char * 1100 get_matching_symbol (enum cpp_ttype type) 1101 { 1102 switch (type) 1103 { 1104 default: 1105 gcc_unreachable (); 1106 return ""; 1107 case CPP_CLOSE_PAREN: 1108 return "("; 1109 case CPP_CLOSE_BRACE: 1110 return "{"; 1111 } 1112 } 1113 1114 /* If the next token is of the indicated TYPE, consume it. Otherwise, 1115 issue the error MSGID. If MSGID is NULL then a message has already 1116 been produced and no message will be produced this time. Returns 1117 true if found, false otherwise. 1118 1119 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it 1120 within any error as the location of an "opening" token matching 1121 the close token TYPE (e.g. the location of the '(' when TYPE is 1122 CPP_CLOSE_PAREN). 1123 1124 If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly 1125 one type (e.g. "expected %<)%>") and thus it may be reasonable to 1126 attempt to generate a fix-it hint for the problem. 1127 Otherwise msgid describes multiple token types (e.g. 1128 "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to 1129 generate a fix-it hint. */ 1130 1131 bool 1132 c_parser_require (c_parser *parser, 1133 enum cpp_ttype type, 1134 const char *msgid, 1135 location_t matching_location, 1136 bool type_is_unique) 1137 { 1138 if (c_parser_next_token_is (parser, type)) 1139 { 1140 c_parser_consume_token (parser); 1141 return true; 1142 } 1143 else 1144 { 1145 location_t next_token_loc = c_parser_peek_token (parser)->location; 1146 gcc_rich_location richloc (next_token_loc); 1147 1148 /* Potentially supply a fix-it hint, suggesting to add the 1149 missing token immediately after the *previous* token. 1150 This may move the primary location within richloc. */ 1151 if (!parser->error && type_is_unique) 1152 maybe_suggest_missing_token_insertion (&richloc, type, 1153 parser->last_token_location); 1154 1155 /* If matching_location != UNKNOWN_LOCATION, highlight it. 1156 Attempt to consolidate diagnostics by printing it as a 1157 secondary range within the main diagnostic. */ 1158 bool added_matching_location = false; 1159 if (matching_location != UNKNOWN_LOCATION) 1160 added_matching_location 1161 = richloc.add_location_if_nearby (matching_location); 1162 1163 if (c_parser_error_richloc (parser, msgid, &richloc)) 1164 /* If we weren't able to consolidate matching_location, then 1165 print it as a secondary diagnostic. */ 1166 if (matching_location != UNKNOWN_LOCATION && !added_matching_location) 1167 inform (matching_location, "to match this %qs", 1168 get_matching_symbol (type)); 1169 1170 return false; 1171 } 1172 } 1173 1174 /* If the next token is the indicated keyword, consume it. Otherwise, 1175 issue the error MSGID. Returns true if found, false otherwise. */ 1176 1177 static bool 1178 c_parser_require_keyword (c_parser *parser, 1179 enum rid keyword, 1180 const char *msgid) 1181 { 1182 if (c_parser_next_token_is_keyword (parser, keyword)) 1183 { 1184 c_parser_consume_token (parser); 1185 return true; 1186 } 1187 else 1188 { 1189 c_parser_error (parser, msgid); 1190 return false; 1191 } 1192 } 1193 1194 /* Like c_parser_require, except that tokens will be skipped until the 1195 desired token is found. An error message is still produced if the 1196 next token is not as expected. If MSGID is NULL then a message has 1197 already been produced and no message will be produced this 1198 time. 1199 1200 If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it 1201 within any error as the location of an "opening" token matching 1202 the close token TYPE (e.g. the location of the '(' when TYPE is 1203 CPP_CLOSE_PAREN). */ 1204 1205 void 1206 c_parser_skip_until_found (c_parser *parser, 1207 enum cpp_ttype type, 1208 const char *msgid, 1209 location_t matching_location) 1210 { 1211 unsigned nesting_depth = 0; 1212 1213 if (c_parser_require (parser, type, msgid, matching_location)) 1214 return; 1215 1216 /* Skip tokens until the desired token is found. */ 1217 while (true) 1218 { 1219 /* Peek at the next token. */ 1220 c_token *token = c_parser_peek_token (parser); 1221 /* If we've reached the token we want, consume it and stop. */ 1222 if (token->type == type && !nesting_depth) 1223 { 1224 c_parser_consume_token (parser); 1225 break; 1226 } 1227 1228 /* If we've run out of tokens, stop. */ 1229 if (token->type == CPP_EOF) 1230 return; 1231 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma) 1232 return; 1233 if (token->type == CPP_OPEN_BRACE 1234 || token->type == CPP_OPEN_PAREN 1235 || token->type == CPP_OPEN_SQUARE) 1236 ++nesting_depth; 1237 else if (token->type == CPP_CLOSE_BRACE 1238 || token->type == CPP_CLOSE_PAREN 1239 || token->type == CPP_CLOSE_SQUARE) 1240 { 1241 if (nesting_depth-- == 0) 1242 break; 1243 } 1244 /* Consume this token. */ 1245 c_parser_consume_token (parser); 1246 } 1247 parser->error = false; 1248 } 1249 1250 /* Skip tokens until the end of a parameter is found, but do not 1251 consume the comma, semicolon or closing delimiter. */ 1252 1253 static void 1254 c_parser_skip_to_end_of_parameter (c_parser *parser) 1255 { 1256 unsigned nesting_depth = 0; 1257 1258 while (true) 1259 { 1260 c_token *token = c_parser_peek_token (parser); 1261 if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON) 1262 && !nesting_depth) 1263 break; 1264 /* If we've run out of tokens, stop. */ 1265 if (token->type == CPP_EOF) 1266 return; 1267 if (token->type == CPP_PRAGMA_EOL && parser->in_pragma) 1268 return; 1269 if (token->type == CPP_OPEN_BRACE 1270 || token->type == CPP_OPEN_PAREN 1271 || token->type == CPP_OPEN_SQUARE) 1272 ++nesting_depth; 1273 else if (token->type == CPP_CLOSE_BRACE 1274 || token->type == CPP_CLOSE_PAREN 1275 || token->type == CPP_CLOSE_SQUARE) 1276 { 1277 if (nesting_depth-- == 0) 1278 break; 1279 } 1280 /* Consume this token. */ 1281 c_parser_consume_token (parser); 1282 } 1283 parser->error = false; 1284 } 1285 1286 /* Expect to be at the end of the pragma directive and consume an 1287 end of line marker. */ 1288 1289 static void 1290 c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true) 1291 { 1292 gcc_assert (parser->in_pragma); 1293 parser->in_pragma = false; 1294 1295 if (error_if_not_eol && c_parser_peek_token (parser)->type != CPP_PRAGMA_EOL) 1296 c_parser_error (parser, "expected end of line"); 1297 1298 cpp_ttype token_type; 1299 do 1300 { 1301 c_token *token = c_parser_peek_token (parser); 1302 token_type = token->type; 1303 if (token_type == CPP_EOF) 1304 break; 1305 c_parser_consume_token (parser); 1306 } 1307 while (token_type != CPP_PRAGMA_EOL); 1308 1309 parser->error = false; 1310 } 1311 1312 /* Skip tokens until we have consumed an entire block, or until we 1313 have consumed a non-nested ';'. */ 1314 1315 static void 1316 c_parser_skip_to_end_of_block_or_statement (c_parser *parser) 1317 { 1318 unsigned nesting_depth = 0; 1319 bool save_error = parser->error; 1320 1321 while (true) 1322 { 1323 c_token *token; 1324 1325 /* Peek at the next token. */ 1326 token = c_parser_peek_token (parser); 1327 1328 switch (token->type) 1329 { 1330 case CPP_EOF: 1331 return; 1332 1333 case CPP_PRAGMA_EOL: 1334 if (parser->in_pragma) 1335 return; 1336 break; 1337 1338 case CPP_SEMICOLON: 1339 /* If the next token is a ';', we have reached the 1340 end of the statement. */ 1341 if (!nesting_depth) 1342 { 1343 /* Consume the ';'. */ 1344 c_parser_consume_token (parser); 1345 goto finished; 1346 } 1347 break; 1348 1349 case CPP_CLOSE_BRACE: 1350 /* If the next token is a non-nested '}', then we have 1351 reached the end of the current block. */ 1352 if (nesting_depth == 0 || --nesting_depth == 0) 1353 { 1354 c_parser_consume_token (parser); 1355 goto finished; 1356 } 1357 break; 1358 1359 case CPP_OPEN_BRACE: 1360 /* If it the next token is a '{', then we are entering a new 1361 block. Consume the entire block. */ 1362 ++nesting_depth; 1363 break; 1364 1365 case CPP_PRAGMA: 1366 /* If we see a pragma, consume the whole thing at once. We 1367 have some safeguards against consuming pragmas willy-nilly. 1368 Normally, we'd expect to be here with parser->error set, 1369 which disables these safeguards. But it's possible to get 1370 here for secondary error recovery, after parser->error has 1371 been cleared. */ 1372 c_parser_consume_pragma (parser); 1373 c_parser_skip_to_pragma_eol (parser); 1374 parser->error = save_error; 1375 continue; 1376 1377 default: 1378 break; 1379 } 1380 1381 c_parser_consume_token (parser); 1382 } 1383 1384 finished: 1385 parser->error = false; 1386 } 1387 1388 /* CPP's options (initialized by c-opts.c). */ 1389 extern cpp_options *cpp_opts; 1390 1391 /* Save the warning flags which are controlled by __extension__. */ 1392 1393 static inline int 1394 disable_extension_diagnostics (void) 1395 { 1396 int ret = (pedantic 1397 | (warn_pointer_arith << 1) 1398 | (warn_traditional << 2) 1399 | (flag_iso << 3) 1400 | (warn_long_long << 4) 1401 | (warn_cxx_compat << 5) 1402 | (warn_overlength_strings << 6) 1403 /* warn_c90_c99_compat has three states: -1/0/1, so we must 1404 play tricks to properly restore it. */ 1405 | ((warn_c90_c99_compat == 1) << 7) 1406 | ((warn_c90_c99_compat == -1) << 8) 1407 /* Similarly for warn_c99_c11_compat. */ 1408 | ((warn_c99_c11_compat == 1) << 9) 1409 | ((warn_c99_c11_compat == -1) << 10) 1410 /* Similarly for warn_c11_c2x_compat. */ 1411 | ((warn_c11_c2x_compat == 1) << 11) 1412 | ((warn_c11_c2x_compat == -1) << 12) 1413 ); 1414 cpp_opts->cpp_pedantic = pedantic = 0; 1415 warn_pointer_arith = 0; 1416 cpp_opts->cpp_warn_traditional = warn_traditional = 0; 1417 flag_iso = 0; 1418 cpp_opts->cpp_warn_long_long = warn_long_long = 0; 1419 warn_cxx_compat = 0; 1420 warn_overlength_strings = 0; 1421 warn_c90_c99_compat = 0; 1422 warn_c99_c11_compat = 0; 1423 warn_c11_c2x_compat = 0; 1424 return ret; 1425 } 1426 1427 /* Restore the warning flags which are controlled by __extension__. 1428 FLAGS is the return value from disable_extension_diagnostics. */ 1429 1430 static inline void 1431 restore_extension_diagnostics (int flags) 1432 { 1433 cpp_opts->cpp_pedantic = pedantic = flags & 1; 1434 warn_pointer_arith = (flags >> 1) & 1; 1435 cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1; 1436 flag_iso = (flags >> 3) & 1; 1437 cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1; 1438 warn_cxx_compat = (flags >> 5) & 1; 1439 warn_overlength_strings = (flags >> 6) & 1; 1440 /* See above for why is this needed. */ 1441 warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0); 1442 warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0); 1443 warn_c11_c2x_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0); 1444 } 1445 1446 /* Helper data structure for parsing #pragma acc routine. */ 1447 struct oacc_routine_data { 1448 bool error_seen; /* Set if error has been reported. */ 1449 bool fndecl_seen; /* Set if one fn decl/definition has been seen already. */ 1450 tree clauses; 1451 location_t loc; 1452 }; 1453 1454 static bool c_parser_nth_token_starts_std_attributes (c_parser *, 1455 unsigned int); 1456 static tree c_parser_std_attribute_specifier_sequence (c_parser *); 1457 static void c_parser_external_declaration (c_parser *); 1458 static void c_parser_asm_definition (c_parser *); 1459 static void c_parser_declaration_or_fndef (c_parser *, bool, bool, bool, 1460 bool, bool, tree *, vec<c_token>, 1461 bool have_attrs = false, 1462 tree attrs = NULL, 1463 struct oacc_routine_data * = NULL, 1464 bool * = NULL); 1465 static void c_parser_static_assert_declaration_no_semi (c_parser *); 1466 static void c_parser_static_assert_declaration (c_parser *); 1467 static struct c_typespec c_parser_enum_specifier (c_parser *); 1468 static struct c_typespec c_parser_struct_or_union_specifier (c_parser *); 1469 static tree c_parser_struct_declaration (c_parser *); 1470 static struct c_typespec c_parser_typeof_specifier (c_parser *); 1471 static tree c_parser_alignas_specifier (c_parser *); 1472 static struct c_declarator *c_parser_direct_declarator (c_parser *, bool, 1473 c_dtr_syn, bool *); 1474 static struct c_declarator *c_parser_direct_declarator_inner (c_parser *, 1475 bool, 1476 struct c_declarator *); 1477 static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree, 1478 bool); 1479 static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree, 1480 tree, bool); 1481 static struct c_parm *c_parser_parameter_declaration (c_parser *, tree, bool); 1482 static tree c_parser_simple_asm_expr (c_parser *); 1483 static tree c_parser_gnu_attributes (c_parser *); 1484 static struct c_expr c_parser_initializer (c_parser *); 1485 static struct c_expr c_parser_braced_init (c_parser *, tree, bool, 1486 struct obstack *); 1487 static void c_parser_initelt (c_parser *, struct obstack *); 1488 static void c_parser_initval (c_parser *, struct c_expr *, 1489 struct obstack *); 1490 static tree c_parser_compound_statement (c_parser *, location_t * = NULL); 1491 static location_t c_parser_compound_statement_nostart (c_parser *); 1492 static void c_parser_label (c_parser *); 1493 static void c_parser_statement (c_parser *, bool *, location_t * = NULL); 1494 static void c_parser_statement_after_labels (c_parser *, bool *, 1495 vec<tree> * = NULL); 1496 static tree c_parser_c99_block_statement (c_parser *, bool *, 1497 location_t * = NULL); 1498 static void c_parser_if_statement (c_parser *, bool *, vec<tree> *); 1499 static void c_parser_switch_statement (c_parser *, bool *); 1500 static void c_parser_while_statement (c_parser *, bool, unsigned short, bool *); 1501 static void c_parser_do_statement (c_parser *, bool, unsigned short); 1502 static void c_parser_for_statement (c_parser *, bool, unsigned short, bool *); 1503 static tree c_parser_asm_statement (c_parser *); 1504 static tree c_parser_asm_operands (c_parser *); 1505 static tree c_parser_asm_goto_operands (c_parser *); 1506 static tree c_parser_asm_clobbers (c_parser *); 1507 static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *, 1508 tree = NULL_TREE); 1509 static struct c_expr c_parser_conditional_expression (c_parser *, 1510 struct c_expr *, tree); 1511 static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *, 1512 tree); 1513 static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *); 1514 static struct c_expr c_parser_unary_expression (c_parser *); 1515 static struct c_expr c_parser_sizeof_expression (c_parser *); 1516 static struct c_expr c_parser_alignof_expression (c_parser *); 1517 static struct c_expr c_parser_postfix_expression (c_parser *); 1518 static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *, 1519 struct c_type_name *, 1520 location_t); 1521 static struct c_expr c_parser_postfix_expression_after_primary (c_parser *, 1522 location_t loc, 1523 struct c_expr); 1524 static tree c_parser_transaction (c_parser *, enum rid); 1525 static struct c_expr c_parser_transaction_expression (c_parser *, enum rid); 1526 static tree c_parser_transaction_cancel (c_parser *); 1527 static struct c_expr c_parser_expression (c_parser *); 1528 static struct c_expr c_parser_expression_conv (c_parser *); 1529 static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool, 1530 vec<tree, va_gc> **, location_t *, 1531 tree *, vec<location_t> *, 1532 unsigned int * = NULL); 1533 static struct c_expr c_parser_has_attribute_expression (c_parser *); 1534 1535 static void c_parser_oacc_declare (c_parser *); 1536 static void c_parser_oacc_enter_exit_data (c_parser *, bool); 1537 static void c_parser_oacc_update (c_parser *); 1538 static void c_parser_omp_construct (c_parser *, bool *); 1539 static void c_parser_omp_threadprivate (c_parser *); 1540 static void c_parser_omp_barrier (c_parser *); 1541 static void c_parser_omp_depobj (c_parser *); 1542 static void c_parser_omp_flush (c_parser *); 1543 static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code, 1544 tree, tree *, bool *); 1545 static void c_parser_omp_taskwait (c_parser *); 1546 static void c_parser_omp_taskyield (c_parser *); 1547 static void c_parser_omp_cancel (c_parser *); 1548 1549 enum pragma_context { pragma_external, pragma_struct, pragma_param, 1550 pragma_stmt, pragma_compound }; 1551 static bool c_parser_pragma (c_parser *, enum pragma_context, bool *); 1552 static void c_parser_omp_cancellation_point (c_parser *, enum pragma_context); 1553 static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *); 1554 static void c_parser_omp_end_declare_target (c_parser *); 1555 static void c_parser_omp_declare (c_parser *, enum pragma_context); 1556 static void c_parser_omp_requires (c_parser *); 1557 static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *); 1558 static void c_parser_oacc_routine (c_parser *, enum pragma_context); 1559 1560 /* These Objective-C parser functions are only ever called when 1561 compiling Objective-C. */ 1562 static void c_parser_objc_class_definition (c_parser *, tree); 1563 static void c_parser_objc_class_instance_variables (c_parser *); 1564 static void c_parser_objc_class_declaration (c_parser *); 1565 static void c_parser_objc_alias_declaration (c_parser *); 1566 static void c_parser_objc_protocol_definition (c_parser *, tree); 1567 static bool c_parser_objc_method_type (c_parser *); 1568 static void c_parser_objc_method_definition (c_parser *); 1569 static void c_parser_objc_methodprotolist (c_parser *); 1570 static void c_parser_objc_methodproto (c_parser *); 1571 static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *); 1572 static tree c_parser_objc_type_name (c_parser *); 1573 static tree c_parser_objc_protocol_refs (c_parser *); 1574 static void c_parser_objc_try_catch_finally_statement (c_parser *); 1575 static void c_parser_objc_synchronized_statement (c_parser *); 1576 static tree c_parser_objc_selector (c_parser *); 1577 static tree c_parser_objc_selector_arg (c_parser *); 1578 static tree c_parser_objc_receiver (c_parser *); 1579 static tree c_parser_objc_message_args (c_parser *); 1580 static tree c_parser_objc_keywordexpr (c_parser *); 1581 static void c_parser_objc_at_property_declaration (c_parser *); 1582 static void c_parser_objc_at_synthesize_declaration (c_parser *); 1583 static void c_parser_objc_at_dynamic_declaration (c_parser *); 1584 static bool c_parser_objc_diagnose_bad_element_prefix 1585 (c_parser *, struct c_declspecs *); 1586 static location_t c_parser_parse_rtl_body (c_parser *, char *); 1587 1588 /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9). 1589 1590 translation-unit: 1591 external-declarations 1592 1593 external-declarations: 1594 external-declaration 1595 external-declarations external-declaration 1596 1597 GNU extensions: 1598 1599 translation-unit: 1600 empty 1601 */ 1602 1603 static void 1604 c_parser_translation_unit (c_parser *parser) 1605 { 1606 if (c_parser_next_token_is (parser, CPP_EOF)) 1607 { 1608 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic, 1609 "ISO C forbids an empty translation unit"); 1610 } 1611 else 1612 { 1613 void *obstack_position = obstack_alloc (&parser_obstack, 0); 1614 mark_valid_location_for_stdc_pragma (false); 1615 do 1616 { 1617 ggc_collect (); 1618 c_parser_external_declaration (parser); 1619 obstack_free (&parser_obstack, obstack_position); 1620 } 1621 while (c_parser_next_token_is_not (parser, CPP_EOF)); 1622 } 1623 1624 unsigned int i; 1625 tree decl; 1626 FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl) 1627 if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node) 1628 error ("storage size of %q+D isn%'t known", decl); 1629 1630 if (current_omp_declare_target_attribute) 1631 { 1632 if (!errorcount) 1633 error ("%<#pragma omp declare target%> without corresponding " 1634 "%<#pragma omp end declare target%>"); 1635 current_omp_declare_target_attribute = 0; 1636 } 1637 } 1638 1639 /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9). 1640 1641 external-declaration: 1642 function-definition 1643 declaration 1644 1645 GNU extensions: 1646 1647 external-declaration: 1648 asm-definition 1649 ; 1650 __extension__ external-declaration 1651 1652 Objective-C: 1653 1654 external-declaration: 1655 objc-class-definition 1656 objc-class-declaration 1657 objc-alias-declaration 1658 objc-protocol-definition 1659 objc-method-definition 1660 @end 1661 */ 1662 1663 static void 1664 c_parser_external_declaration (c_parser *parser) 1665 { 1666 int ext; 1667 switch (c_parser_peek_token (parser)->type) 1668 { 1669 case CPP_KEYWORD: 1670 switch (c_parser_peek_token (parser)->keyword) 1671 { 1672 case RID_EXTENSION: 1673 ext = disable_extension_diagnostics (); 1674 c_parser_consume_token (parser); 1675 c_parser_external_declaration (parser); 1676 restore_extension_diagnostics (ext); 1677 break; 1678 case RID_ASM: 1679 c_parser_asm_definition (parser); 1680 break; 1681 case RID_AT_INTERFACE: 1682 case RID_AT_IMPLEMENTATION: 1683 gcc_assert (c_dialect_objc ()); 1684 c_parser_objc_class_definition (parser, NULL_TREE); 1685 break; 1686 case RID_AT_CLASS: 1687 gcc_assert (c_dialect_objc ()); 1688 c_parser_objc_class_declaration (parser); 1689 break; 1690 case RID_AT_ALIAS: 1691 gcc_assert (c_dialect_objc ()); 1692 c_parser_objc_alias_declaration (parser); 1693 break; 1694 case RID_AT_PROTOCOL: 1695 gcc_assert (c_dialect_objc ()); 1696 c_parser_objc_protocol_definition (parser, NULL_TREE); 1697 break; 1698 case RID_AT_PROPERTY: 1699 gcc_assert (c_dialect_objc ()); 1700 c_parser_objc_at_property_declaration (parser); 1701 break; 1702 case RID_AT_SYNTHESIZE: 1703 gcc_assert (c_dialect_objc ()); 1704 c_parser_objc_at_synthesize_declaration (parser); 1705 break; 1706 case RID_AT_DYNAMIC: 1707 gcc_assert (c_dialect_objc ()); 1708 c_parser_objc_at_dynamic_declaration (parser); 1709 break; 1710 case RID_AT_END: 1711 gcc_assert (c_dialect_objc ()); 1712 c_parser_consume_token (parser); 1713 objc_finish_implementation (); 1714 break; 1715 default: 1716 goto decl_or_fndef; 1717 } 1718 break; 1719 case CPP_SEMICOLON: 1720 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic, 1721 "ISO C does not allow extra %<;%> outside of a function"); 1722 c_parser_consume_token (parser); 1723 break; 1724 case CPP_PRAGMA: 1725 mark_valid_location_for_stdc_pragma (true); 1726 c_parser_pragma (parser, pragma_external, NULL); 1727 mark_valid_location_for_stdc_pragma (false); 1728 break; 1729 case CPP_PLUS: 1730 case CPP_MINUS: 1731 if (c_dialect_objc ()) 1732 { 1733 c_parser_objc_method_definition (parser); 1734 break; 1735 } 1736 /* Else fall through, and yield a syntax error trying to parse 1737 as a declaration or function definition. */ 1738 /* FALLTHRU */ 1739 default: 1740 decl_or_fndef: 1741 /* A declaration or a function definition (or, in Objective-C, 1742 an @interface or @protocol with prefix attributes). We can 1743 only tell which after parsing the declaration specifiers, if 1744 any, and the first declarator. */ 1745 c_parser_declaration_or_fndef (parser, true, true, true, false, true, 1746 NULL, vNULL); 1747 break; 1748 } 1749 } 1750 1751 static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token>); 1752 static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool); 1753 1754 /* Build and add a DEBUG_BEGIN_STMT statement with location LOC. */ 1755 1756 static void 1757 add_debug_begin_stmt (location_t loc) 1758 { 1759 /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721. */ 1760 if (!MAY_HAVE_DEBUG_MARKER_STMTS || !building_stmt_list_p ()) 1761 return; 1762 1763 tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node); 1764 SET_EXPR_LOCATION (stmt, loc); 1765 add_stmt (stmt); 1766 } 1767 1768 /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99 1769 6.7, 6.9.1, C11 6.7, 6.9.1). If FNDEF_OK is true, a function definition 1770 is accepted; otherwise (old-style parameter declarations) only other 1771 declarations are accepted. If STATIC_ASSERT_OK is true, a static 1772 assertion is accepted; otherwise (old-style parameter declarations) 1773 it is not. If NESTED is true, we are inside a function or parsing 1774 old-style parameter declarations; any functions encountered are 1775 nested functions and declaration specifiers are required; otherwise 1776 we are at top level and functions are normal functions and 1777 declaration specifiers may be optional. If EMPTY_OK is true, empty 1778 declarations are OK (subject to all other constraints); otherwise 1779 (old-style parameter declarations) they are diagnosed. If 1780 START_ATTR_OK is true, the declaration specifiers may start with 1781 attributes (GNU or standard); otherwise they may not. 1782 OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed 1783 declaration when parsing an Objective-C foreach statement. 1784 FALLTHRU_ATTR_P is used to signal whether this function parsed 1785 "__attribute__((fallthrough));". ATTRS are any standard attributes 1786 parsed in the caller (in contexts where such attributes had to be 1787 parsed to determine whether what follows is a declaration or a 1788 statement); HAVE_ATTRS says whether there were any such attributes 1789 (even empty). 1790 1791 declaration: 1792 declaration-specifiers init-declarator-list[opt] ; 1793 static_assert-declaration 1794 1795 function-definition: 1796 declaration-specifiers[opt] declarator declaration-list[opt] 1797 compound-statement 1798 1799 declaration-list: 1800 declaration 1801 declaration-list declaration 1802 1803 init-declarator-list: 1804 init-declarator 1805 init-declarator-list , init-declarator 1806 1807 init-declarator: 1808 declarator simple-asm-expr[opt] gnu-attributes[opt] 1809 declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer 1810 1811 GNU extensions: 1812 1813 nested-function-definition: 1814 declaration-specifiers declarator declaration-list[opt] 1815 compound-statement 1816 1817 attribute ; 1818 1819 Objective-C: 1820 gnu-attributes objc-class-definition 1821 gnu-attributes objc-category-definition 1822 gnu-attributes objc-protocol-definition 1823 1824 The simple-asm-expr and gnu-attributes are GNU extensions. 1825 1826 This function does not handle __extension__; that is handled in its 1827 callers. ??? Following the old parser, __extension__ may start 1828 external declarations, declarations in functions and declarations 1829 at the start of "for" loops, but not old-style parameter 1830 declarations. 1831 1832 C99 requires declaration specifiers in a function definition; the 1833 absence is diagnosed through the diagnosis of implicit int. In GNU 1834 C we also allow but diagnose declarations without declaration 1835 specifiers, but only at top level (elsewhere they conflict with 1836 other syntax). 1837 1838 In Objective-C, declarations of the looping variable in a foreach 1839 statement are exceptionally terminated by 'in' (for example, 'for 1840 (NSObject *object in array) { ... }'). 1841 1842 OpenMP: 1843 1844 declaration: 1845 threadprivate-directive 1846 1847 GIMPLE: 1848 1849 gimple-function-definition: 1850 declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator 1851 declaration-list[opt] compound-statement 1852 1853 rtl-function-definition: 1854 declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator 1855 declaration-list[opt] compound-statement */ 1856 1857 static void 1858 c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, 1859 bool static_assert_ok, bool empty_ok, 1860 bool nested, bool start_attr_ok, 1861 tree *objc_foreach_object_declaration, 1862 vec<c_token> omp_declare_simd_clauses, 1863 bool have_attrs, tree attrs, 1864 struct oacc_routine_data *oacc_routine_data, 1865 bool *fallthru_attr_p) 1866 { 1867 struct c_declspecs *specs; 1868 tree prefix_attrs; 1869 tree all_prefix_attrs; 1870 bool diagnosed_no_specs = false; 1871 location_t here = c_parser_peek_token (parser)->location; 1872 1873 add_debug_begin_stmt (c_parser_peek_token (parser)->location); 1874 1875 if (static_assert_ok 1876 && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT)) 1877 { 1878 c_parser_static_assert_declaration (parser); 1879 return; 1880 } 1881 specs = build_null_declspecs (); 1882 1883 /* Handle any standard attributes parsed in the caller. */ 1884 if (have_attrs) 1885 { 1886 declspecs_add_attrs (here, specs, attrs); 1887 specs->non_std_attrs_seen_p = false; 1888 } 1889 1890 /* Try to detect an unknown type name when we have "A B" or "A *B". */ 1891 if (c_parser_peek_token (parser)->type == CPP_NAME 1892 && c_parser_peek_token (parser)->id_kind == C_ID_ID 1893 && (c_parser_peek_2nd_token (parser)->type == CPP_NAME 1894 || c_parser_peek_2nd_token (parser)->type == CPP_MULT) 1895 && (!nested || !lookup_name (c_parser_peek_token (parser)->value))) 1896 { 1897 tree name = c_parser_peek_token (parser)->value; 1898 1899 /* Issue a warning about NAME being an unknown type name, perhaps 1900 with some kind of hint. 1901 If the user forgot a "struct" etc, suggest inserting 1902 it. Otherwise, attempt to look for misspellings. */ 1903 gcc_rich_location richloc (here); 1904 if (tag_exists_p (RECORD_TYPE, name)) 1905 { 1906 /* This is not C++ with its implicit typedef. */ 1907 richloc.add_fixit_insert_before ("struct "); 1908 error_at (&richloc, 1909 "unknown type name %qE;" 1910 " use %<struct%> keyword to refer to the type", 1911 name); 1912 } 1913 else if (tag_exists_p (UNION_TYPE, name)) 1914 { 1915 richloc.add_fixit_insert_before ("union "); 1916 error_at (&richloc, 1917 "unknown type name %qE;" 1918 " use %<union%> keyword to refer to the type", 1919 name); 1920 } 1921 else if (tag_exists_p (ENUMERAL_TYPE, name)) 1922 { 1923 richloc.add_fixit_insert_before ("enum "); 1924 error_at (&richloc, 1925 "unknown type name %qE;" 1926 " use %<enum%> keyword to refer to the type", 1927 name); 1928 } 1929 else 1930 { 1931 auto_diagnostic_group d; 1932 name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME, 1933 here); 1934 if (const char *suggestion = hint.suggestion ()) 1935 { 1936 richloc.add_fixit_replace (suggestion); 1937 error_at (&richloc, 1938 "unknown type name %qE; did you mean %qs?", 1939 name, suggestion); 1940 } 1941 else 1942 error_at (here, "unknown type name %qE", name); 1943 } 1944 1945 /* Parse declspecs normally to get a correct pointer type, but avoid 1946 a further "fails to be a type name" error. Refuse nested functions 1947 since it is not how the user likely wants us to recover. */ 1948 c_parser_peek_token (parser)->type = CPP_KEYWORD; 1949 c_parser_peek_token (parser)->keyword = RID_VOID; 1950 c_parser_peek_token (parser)->value = error_mark_node; 1951 fndef_ok = !nested; 1952 } 1953 1954 /* When there are standard attributes at the start of the 1955 declaration (to apply to the entity being declared), an 1956 init-declarator-list or function definition must be present. */ 1957 if (c_parser_nth_token_starts_std_attributes (parser, 1)) 1958 have_attrs = true; 1959 1960 c_parser_declspecs (parser, specs, true, true, start_attr_ok, 1961 true, true, start_attr_ok, true, cla_nonabstract_decl); 1962 if (parser->error) 1963 { 1964 c_parser_skip_to_end_of_block_or_statement (parser); 1965 return; 1966 } 1967 if (nested && !specs->declspecs_seen_p) 1968 { 1969 c_parser_error (parser, "expected declaration specifiers"); 1970 c_parser_skip_to_end_of_block_or_statement (parser); 1971 return; 1972 } 1973 1974 finish_declspecs (specs); 1975 bool auto_type_p = specs->typespec_word == cts_auto_type; 1976 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 1977 { 1978 if (auto_type_p) 1979 error_at (here, "%<__auto_type%> in empty declaration"); 1980 else if (specs->typespec_kind == ctsk_none 1981 && attribute_fallthrough_p (specs->attrs)) 1982 { 1983 if (fallthru_attr_p != NULL) 1984 *fallthru_attr_p = true; 1985 if (nested) 1986 { 1987 tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH, 1988 void_type_node, 0); 1989 add_stmt (fn); 1990 } 1991 else 1992 pedwarn (here, OPT_Wattributes, 1993 "%<fallthrough%> attribute at top level"); 1994 } 1995 else if (empty_ok && !(have_attrs 1996 && specs->non_std_attrs_seen_p)) 1997 shadow_tag (specs); 1998 else 1999 { 2000 shadow_tag_warned (specs, 1); 2001 pedwarn (here, 0, "empty declaration"); 2002 } 2003 c_parser_consume_token (parser); 2004 if (oacc_routine_data) 2005 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false); 2006 return; 2007 } 2008 2009 /* Provide better error recovery. Note that a type name here is usually 2010 better diagnosed as a redeclaration. */ 2011 if (empty_ok 2012 && specs->typespec_kind == ctsk_tagdef 2013 && c_parser_next_token_starts_declspecs (parser) 2014 && !c_parser_next_token_is (parser, CPP_NAME)) 2015 { 2016 c_parser_error (parser, "expected %<;%>, identifier or %<(%>"); 2017 parser->error = false; 2018 shadow_tag_warned (specs, 1); 2019 return; 2020 } 2021 else if (c_dialect_objc () && !auto_type_p) 2022 { 2023 /* Prefix attributes are an error on method decls. */ 2024 switch (c_parser_peek_token (parser)->type) 2025 { 2026 case CPP_PLUS: 2027 case CPP_MINUS: 2028 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs)) 2029 return; 2030 if (specs->attrs) 2031 { 2032 warning_at (c_parser_peek_token (parser)->location, 2033 OPT_Wattributes, 2034 "prefix attributes are ignored for methods"); 2035 specs->attrs = NULL_TREE; 2036 } 2037 if (fndef_ok) 2038 c_parser_objc_method_definition (parser); 2039 else 2040 c_parser_objc_methodproto (parser); 2041 return; 2042 break; 2043 default: 2044 break; 2045 } 2046 /* This is where we parse 'attributes @interface ...', 2047 'attributes @implementation ...', 'attributes @protocol ...' 2048 (where attributes could be, for example, __attribute__ 2049 ((deprecated)). 2050 */ 2051 switch (c_parser_peek_token (parser)->keyword) 2052 { 2053 case RID_AT_INTERFACE: 2054 { 2055 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs)) 2056 return; 2057 c_parser_objc_class_definition (parser, specs->attrs); 2058 return; 2059 } 2060 break; 2061 case RID_AT_IMPLEMENTATION: 2062 { 2063 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs)) 2064 return; 2065 if (specs->attrs) 2066 { 2067 warning_at (c_parser_peek_token (parser)->location, 2068 OPT_Wattributes, 2069 "prefix attributes are ignored for implementations"); 2070 specs->attrs = NULL_TREE; 2071 } 2072 c_parser_objc_class_definition (parser, NULL_TREE); 2073 return; 2074 } 2075 break; 2076 case RID_AT_PROTOCOL: 2077 { 2078 if (c_parser_objc_diagnose_bad_element_prefix (parser, specs)) 2079 return; 2080 c_parser_objc_protocol_definition (parser, specs->attrs); 2081 return; 2082 } 2083 break; 2084 case RID_AT_ALIAS: 2085 case RID_AT_CLASS: 2086 case RID_AT_END: 2087 case RID_AT_PROPERTY: 2088 if (specs->attrs) 2089 { 2090 c_parser_error (parser, "unexpected attribute"); 2091 specs->attrs = NULL; 2092 } 2093 break; 2094 default: 2095 break; 2096 } 2097 } 2098 else if (attribute_fallthrough_p (specs->attrs)) 2099 warning_at (here, OPT_Wattributes, 2100 "%<fallthrough%> attribute not followed by %<;%>"); 2101 2102 pending_xref_error (); 2103 prefix_attrs = specs->attrs; 2104 all_prefix_attrs = prefix_attrs; 2105 specs->attrs = NULL_TREE; 2106 while (true) 2107 { 2108 struct c_declarator *declarator; 2109 bool dummy = false; 2110 timevar_id_t tv; 2111 tree fnbody = NULL_TREE; 2112 /* Declaring either one or more declarators (in which case we 2113 should diagnose if there were no declaration specifiers) or a 2114 function definition (in which case the diagnostic for 2115 implicit int suffices). */ 2116 declarator = c_parser_declarator (parser, 2117 specs->typespec_kind != ctsk_none, 2118 C_DTR_NORMAL, &dummy); 2119 if (declarator == NULL) 2120 { 2121 if (omp_declare_simd_clauses.exists ()) 2122 c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE, 2123 omp_declare_simd_clauses); 2124 if (oacc_routine_data) 2125 c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false); 2126 c_parser_skip_to_end_of_block_or_statement (parser); 2127 return; 2128 } 2129 if (auto_type_p && declarator->kind != cdk_id) 2130 { 2131 error_at (here, 2132 "%<__auto_type%> requires a plain identifier" 2133 " as declarator"); 2134 c_parser_skip_to_end_of_block_or_statement (parser); 2135 return; 2136 } 2137 if (c_parser_next_token_is (parser, CPP_EQ) 2138 || c_parser_next_token_is (parser, CPP_COMMA) 2139 || c_parser_next_token_is (parser, CPP_SEMICOLON) 2140 || c_parser_next_token_is_keyword (parser, RID_ASM) 2141 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE) 2142 || c_parser_next_token_is_keyword (parser, RID_IN)) 2143 { 2144 tree asm_name = NULL_TREE; 2145 tree postfix_attrs = NULL_TREE; 2146 if (!diagnosed_no_specs && !specs->declspecs_seen_p) 2147 { 2148 diagnosed_no_specs = true; 2149 pedwarn (here, 0, "data definition has no type or storage class"); 2150 } 2151 /* Having seen a data definition, there cannot now be a 2152 function definition. */ 2153 fndef_ok = false; 2154 if (c_parser_next_token_is_keyword (parser, RID_ASM)) 2155 asm_name = c_parser_simple_asm_expr (parser); 2156 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 2157 { 2158 postfix_attrs = c_parser_gnu_attributes (parser); 2159 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 2160 { 2161 /* This means there is an attribute specifier after 2162 the declarator in a function definition. Provide 2163 some more information for the user. */ 2164 error_at (here, "attributes should be specified before the " 2165 "declarator in a function definition"); 2166 c_parser_skip_to_end_of_block_or_statement (parser); 2167 return; 2168 } 2169 } 2170 if (c_parser_next_token_is (parser, CPP_EQ)) 2171 { 2172 tree d; 2173 struct c_expr init; 2174 location_t init_loc; 2175 c_parser_consume_token (parser); 2176 if (auto_type_p) 2177 { 2178 init_loc = c_parser_peek_token (parser)->location; 2179 rich_location richloc (line_table, init_loc); 2180 start_init (NULL_TREE, asm_name, global_bindings_p (), &richloc); 2181 /* A parameter is initialized, which is invalid. Don't 2182 attempt to instrument the initializer. */ 2183 int flag_sanitize_save = flag_sanitize; 2184 if (nested && !empty_ok) 2185 flag_sanitize = 0; 2186 init = c_parser_expr_no_commas (parser, NULL); 2187 flag_sanitize = flag_sanitize_save; 2188 if (TREE_CODE (init.value) == COMPONENT_REF 2189 && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1))) 2190 error_at (here, 2191 "%<__auto_type%> used with a bit-field" 2192 " initializer"); 2193 init = convert_lvalue_to_rvalue (init_loc, init, true, true); 2194 tree init_type = TREE_TYPE (init.value); 2195 /* As with typeof, remove all qualifiers from atomic types. */ 2196 if (init_type != error_mark_node && TYPE_ATOMIC (init_type)) 2197 init_type 2198 = c_build_qualified_type (init_type, TYPE_UNQUALIFIED); 2199 bool vm_type = variably_modified_type_p (init_type, 2200 NULL_TREE); 2201 if (vm_type) 2202 init.value = save_expr (init.value); 2203 finish_init (); 2204 specs->typespec_kind = ctsk_typeof; 2205 specs->locations[cdw_typedef] = init_loc; 2206 specs->typedef_p = true; 2207 specs->type = init_type; 2208 if (vm_type) 2209 { 2210 bool maybe_const = true; 2211 tree type_expr = c_fully_fold (init.value, false, 2212 &maybe_const); 2213 specs->expr_const_operands &= maybe_const; 2214 if (specs->expr) 2215 specs->expr = build2 (COMPOUND_EXPR, 2216 TREE_TYPE (type_expr), 2217 specs->expr, type_expr); 2218 else 2219 specs->expr = type_expr; 2220 } 2221 d = start_decl (declarator, specs, true, 2222 chainon (postfix_attrs, all_prefix_attrs)); 2223 if (!d) 2224 d = error_mark_node; 2225 if (omp_declare_simd_clauses.exists ()) 2226 c_finish_omp_declare_simd (parser, d, NULL_TREE, 2227 omp_declare_simd_clauses); 2228 } 2229 else 2230 { 2231 /* The declaration of the variable is in effect while 2232 its initializer is parsed. */ 2233 d = start_decl (declarator, specs, true, 2234 chainon (postfix_attrs, all_prefix_attrs)); 2235 if (!d) 2236 d = error_mark_node; 2237 if (omp_declare_simd_clauses.exists ()) 2238 c_finish_omp_declare_simd (parser, d, NULL_TREE, 2239 omp_declare_simd_clauses); 2240 init_loc = c_parser_peek_token (parser)->location; 2241 rich_location richloc (line_table, init_loc); 2242 start_init (d, asm_name, global_bindings_p (), &richloc); 2243 /* A parameter is initialized, which is invalid. Don't 2244 attempt to instrument the initializer. */ 2245 int flag_sanitize_save = flag_sanitize; 2246 if (TREE_CODE (d) == PARM_DECL) 2247 flag_sanitize = 0; 2248 init = c_parser_initializer (parser); 2249 flag_sanitize = flag_sanitize_save; 2250 finish_init (); 2251 } 2252 if (oacc_routine_data) 2253 c_finish_oacc_routine (oacc_routine_data, d, false); 2254 if (d != error_mark_node) 2255 { 2256 maybe_warn_string_init (init_loc, TREE_TYPE (d), init); 2257 finish_decl (d, init_loc, init.value, 2258 init.original_type, asm_name); 2259 } 2260 } 2261 else 2262 { 2263 if (auto_type_p) 2264 { 2265 error_at (here, 2266 "%<__auto_type%> requires an initialized " 2267 "data declaration"); 2268 c_parser_skip_to_end_of_block_or_statement (parser); 2269 return; 2270 } 2271 tree d = start_decl (declarator, specs, false, 2272 chainon (postfix_attrs, 2273 all_prefix_attrs)); 2274 if (d 2275 && TREE_CODE (d) == FUNCTION_DECL 2276 && DECL_ARGUMENTS (d) == NULL_TREE 2277 && DECL_INITIAL (d) == NULL_TREE) 2278 { 2279 /* Find the innermost declarator that is neither cdk_id 2280 nor cdk_attrs. */ 2281 const struct c_declarator *decl = declarator; 2282 const struct c_declarator *last_non_id_attrs = NULL; 2283 2284 while (decl) 2285 switch (decl->kind) 2286 { 2287 case cdk_array: 2288 case cdk_function: 2289 case cdk_pointer: 2290 last_non_id_attrs = decl; 2291 decl = decl->declarator; 2292 break; 2293 2294 case cdk_attrs: 2295 decl = decl->declarator; 2296 break; 2297 2298 case cdk_id: 2299 decl = 0; 2300 break; 2301 2302 default: 2303 gcc_unreachable (); 2304 } 2305 2306 /* If it exists and is cdk_function, use its parameters. */ 2307 if (last_non_id_attrs 2308 && last_non_id_attrs->kind == cdk_function) 2309 DECL_ARGUMENTS (d) = last_non_id_attrs->u.arg_info->parms; 2310 } 2311 if (omp_declare_simd_clauses.exists ()) 2312 { 2313 tree parms = NULL_TREE; 2314 if (d && TREE_CODE (d) == FUNCTION_DECL) 2315 { 2316 struct c_declarator *ce = declarator; 2317 while (ce != NULL) 2318 if (ce->kind == cdk_function) 2319 { 2320 parms = ce->u.arg_info->parms; 2321 break; 2322 } 2323 else 2324 ce = ce->declarator; 2325 } 2326 if (parms) 2327 temp_store_parm_decls (d, parms); 2328 c_finish_omp_declare_simd (parser, d, parms, 2329 omp_declare_simd_clauses); 2330 if (parms) 2331 temp_pop_parm_decls (); 2332 } 2333 if (oacc_routine_data) 2334 c_finish_oacc_routine (oacc_routine_data, d, false); 2335 if (d) 2336 finish_decl (d, UNKNOWN_LOCATION, NULL_TREE, 2337 NULL_TREE, asm_name); 2338 2339 if (c_parser_next_token_is_keyword (parser, RID_IN)) 2340 { 2341 if (d) 2342 *objc_foreach_object_declaration = d; 2343 else 2344 *objc_foreach_object_declaration = error_mark_node; 2345 } 2346 } 2347 if (c_parser_next_token_is (parser, CPP_COMMA)) 2348 { 2349 if (auto_type_p) 2350 { 2351 error_at (here, 2352 "%<__auto_type%> may only be used with" 2353 " a single declarator"); 2354 c_parser_skip_to_end_of_block_or_statement (parser); 2355 return; 2356 } 2357 c_parser_consume_token (parser); 2358 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 2359 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser), 2360 prefix_attrs); 2361 else 2362 all_prefix_attrs = prefix_attrs; 2363 continue; 2364 } 2365 else if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 2366 { 2367 c_parser_consume_token (parser); 2368 return; 2369 } 2370 else if (c_parser_next_token_is_keyword (parser, RID_IN)) 2371 { 2372 /* This can only happen in Objective-C: we found the 2373 'in' that terminates the declaration inside an 2374 Objective-C foreach statement. Do not consume the 2375 token, so that the caller can use it to determine 2376 that this indeed is a foreach context. */ 2377 return; 2378 } 2379 else 2380 { 2381 c_parser_error (parser, "expected %<,%> or %<;%>"); 2382 c_parser_skip_to_end_of_block_or_statement (parser); 2383 return; 2384 } 2385 } 2386 else if (auto_type_p) 2387 { 2388 error_at (here, 2389 "%<__auto_type%> requires an initialized data declaration"); 2390 c_parser_skip_to_end_of_block_or_statement (parser); 2391 return; 2392 } 2393 else if (!fndef_ok) 2394 { 2395 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, " 2396 "%<asm%> or %<__attribute__%>"); 2397 c_parser_skip_to_end_of_block_or_statement (parser); 2398 return; 2399 } 2400 /* Function definition (nested or otherwise). */ 2401 if (nested) 2402 { 2403 pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions"); 2404 c_push_function_context (); 2405 } 2406 if (!start_function (specs, declarator, all_prefix_attrs)) 2407 { 2408 /* At this point we've consumed: 2409 declaration-specifiers declarator 2410 and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON, 2411 RID_ASM, RID_ATTRIBUTE, or RID_IN, 2412 but the 2413 declaration-specifiers declarator 2414 aren't grokkable as a function definition, so we have 2415 an error. */ 2416 gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON)); 2417 if (c_parser_next_token_starts_declspecs (parser)) 2418 { 2419 /* If we have 2420 declaration-specifiers declarator decl-specs 2421 then assume we have a missing semicolon, which would 2422 give us: 2423 declaration-specifiers declarator decl-specs 2424 ^ 2425 ; 2426 <~~~~~~~~~ declaration ~~~~~~~~~~> 2427 Use c_parser_require to get an error with a fix-it hint. */ 2428 c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"); 2429 parser->error = false; 2430 } 2431 else 2432 { 2433 /* This can appear in many cases looking nothing like a 2434 function definition, so we don't give a more specific 2435 error suggesting there was one. */ 2436 c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> " 2437 "or %<__attribute__%>"); 2438 } 2439 if (nested) 2440 c_pop_function_context (); 2441 break; 2442 } 2443 2444 if (DECL_DECLARED_INLINE_P (current_function_decl)) 2445 tv = TV_PARSE_INLINE; 2446 else 2447 tv = TV_PARSE_FUNC; 2448 auto_timevar at (g_timer, tv); 2449 2450 /* Parse old-style parameter declarations. ??? Attributes are 2451 not allowed to start declaration specifiers here because of a 2452 syntax conflict between a function declaration with attribute 2453 suffix and a function definition with an attribute prefix on 2454 first old-style parameter declaration. Following the old 2455 parser, they are not accepted on subsequent old-style 2456 parameter declarations either. However, there is no 2457 ambiguity after the first declaration, nor indeed on the 2458 first as long as we don't allow postfix attributes after a 2459 declarator with a nonempty identifier list in a definition; 2460 and postfix attributes have never been accepted here in 2461 function definitions either. */ 2462 while (c_parser_next_token_is_not (parser, CPP_EOF) 2463 && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE)) 2464 c_parser_declaration_or_fndef (parser, false, false, false, 2465 true, false, NULL, vNULL); 2466 store_parm_decls (); 2467 if (omp_declare_simd_clauses.exists ()) 2468 c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE, 2469 omp_declare_simd_clauses); 2470 if (oacc_routine_data) 2471 c_finish_oacc_routine (oacc_routine_data, current_function_decl, true); 2472 location_t startloc = c_parser_peek_token (parser)->location; 2473 DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus 2474 = startloc; 2475 location_t endloc = startloc; 2476 2477 /* If the definition was marked with __RTL, use the RTL parser now, 2478 consuming the function body. */ 2479 if (specs->declspec_il == cdil_rtl) 2480 { 2481 endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass); 2482 2483 /* Normally, store_parm_decls sets next_is_function_body, 2484 anticipating a function body. We need a push_scope/pop_scope 2485 pair to flush out this state, or subsequent function parsing 2486 will go wrong. */ 2487 push_scope (); 2488 pop_scope (); 2489 2490 finish_function (endloc); 2491 return; 2492 } 2493 /* If the definition was marked with __GIMPLE then parse the 2494 function body as GIMPLE. */ 2495 else if (specs->declspec_il != cdil_none) 2496 { 2497 bool saved = in_late_binary_op; 2498 in_late_binary_op = true; 2499 c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass, 2500 specs->declspec_il, 2501 specs->entry_bb_count); 2502 in_late_binary_op = saved; 2503 } 2504 else 2505 fnbody = c_parser_compound_statement (parser, &endloc); 2506 tree fndecl = current_function_decl; 2507 if (nested) 2508 { 2509 tree decl = current_function_decl; 2510 /* Mark nested functions as needing static-chain initially. 2511 lower_nested_functions will recompute it but the 2512 DECL_STATIC_CHAIN flag is also used before that happens, 2513 by initializer_constant_valid_p. See gcc.dg/nested-fn-2.c. */ 2514 DECL_STATIC_CHAIN (decl) = 1; 2515 add_stmt (fnbody); 2516 finish_function (endloc); 2517 c_pop_function_context (); 2518 add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl)); 2519 } 2520 else 2521 { 2522 if (fnbody) 2523 add_stmt (fnbody); 2524 finish_function (endloc); 2525 } 2526 /* Get rid of the empty stmt list for GIMPLE/RTL. */ 2527 if (specs->declspec_il != cdil_none) 2528 DECL_SAVED_TREE (fndecl) = NULL_TREE; 2529 2530 break; 2531 } 2532 } 2533 2534 /* Parse an asm-definition (asm() outside a function body). This is a 2535 GNU extension. 2536 2537 asm-definition: 2538 simple-asm-expr ; 2539 */ 2540 2541 static void 2542 c_parser_asm_definition (c_parser *parser) 2543 { 2544 tree asm_str = c_parser_simple_asm_expr (parser); 2545 if (asm_str) 2546 symtab->finalize_toplevel_asm (asm_str); 2547 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 2548 } 2549 2550 /* Parse a static assertion (C11 6.7.10). 2551 2552 static_assert-declaration: 2553 static_assert-declaration-no-semi ; 2554 */ 2555 2556 static void 2557 c_parser_static_assert_declaration (c_parser *parser) 2558 { 2559 c_parser_static_assert_declaration_no_semi (parser); 2560 if (parser->error 2561 || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>")) 2562 c_parser_skip_to_end_of_block_or_statement (parser); 2563 } 2564 2565 /* Parse a static assertion (C11 6.7.10), without the trailing 2566 semicolon. 2567 2568 static_assert-declaration-no-semi: 2569 _Static_assert ( constant-expression , string-literal ) 2570 2571 C2X: 2572 static_assert-declaration-no-semi: 2573 _Static_assert ( constant-expression ) 2574 */ 2575 2576 static void 2577 c_parser_static_assert_declaration_no_semi (c_parser *parser) 2578 { 2579 location_t assert_loc, value_loc; 2580 tree value; 2581 tree string = NULL_TREE; 2582 2583 gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT)); 2584 assert_loc = c_parser_peek_token (parser)->location; 2585 if (flag_isoc99) 2586 pedwarn_c99 (assert_loc, OPT_Wpedantic, 2587 "ISO C99 does not support %<_Static_assert%>"); 2588 else 2589 pedwarn_c99 (assert_loc, OPT_Wpedantic, 2590 "ISO C90 does not support %<_Static_assert%>"); 2591 c_parser_consume_token (parser); 2592 matching_parens parens; 2593 if (!parens.require_open (parser)) 2594 return; 2595 location_t value_tok_loc = c_parser_peek_token (parser)->location; 2596 value = c_parser_expr_no_commas (parser, NULL).value; 2597 value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc); 2598 if (c_parser_next_token_is (parser, CPP_COMMA)) 2599 { 2600 c_parser_consume_token (parser); 2601 switch (c_parser_peek_token (parser)->type) 2602 { 2603 case CPP_STRING: 2604 case CPP_STRING16: 2605 case CPP_STRING32: 2606 case CPP_WSTRING: 2607 case CPP_UTF8STRING: 2608 string = c_parser_string_literal (parser, false, true).value; 2609 break; 2610 default: 2611 c_parser_error (parser, "expected string literal"); 2612 return; 2613 } 2614 } 2615 else if (flag_isoc11) 2616 /* If pedantic for pre-C11, the use of _Static_assert itself will 2617 have been diagnosed, so do not also diagnose the use of this 2618 new C2X feature of _Static_assert. */ 2619 pedwarn_c11 (assert_loc, OPT_Wpedantic, 2620 "ISO C11 does not support omitting the string in " 2621 "%<_Static_assert%>"); 2622 parens.require_close (parser); 2623 2624 if (!INTEGRAL_TYPE_P (TREE_TYPE (value))) 2625 { 2626 error_at (value_loc, "expression in static assertion is not an integer"); 2627 return; 2628 } 2629 if (TREE_CODE (value) != INTEGER_CST) 2630 { 2631 value = c_fully_fold (value, false, NULL); 2632 /* Strip no-op conversions. */ 2633 STRIP_TYPE_NOPS (value); 2634 if (TREE_CODE (value) == INTEGER_CST) 2635 pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion " 2636 "is not an integer constant expression"); 2637 } 2638 if (TREE_CODE (value) != INTEGER_CST) 2639 { 2640 error_at (value_loc, "expression in static assertion is not constant"); 2641 return; 2642 } 2643 constant_expression_warning (value); 2644 if (integer_zerop (value)) 2645 { 2646 if (string) 2647 error_at (assert_loc, "static assertion failed: %E", string); 2648 else 2649 error_at (assert_loc, "static assertion failed"); 2650 } 2651 } 2652 2653 /* Parse some declaration specifiers (possibly none) (C90 6.5, C99 2654 6.7, C11 6.7), adding them to SPECS (which may already include some). 2655 Storage class specifiers are accepted iff SCSPEC_OK; type 2656 specifiers are accepted iff TYPESPEC_OK; alignment specifiers are 2657 accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start 2658 iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK. In 2659 addition to the syntax shown, standard attributes are accepted at 2660 the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK; 2661 unlike gnu-attributes, they are not accepted in the middle of the 2662 list. (This combines various different syntax productions in the C 2663 standard, and in some cases gnu-attributes and standard attributes 2664 at the start may already have been parsed before this function is 2665 called.) 2666 2667 declaration-specifiers: 2668 storage-class-specifier declaration-specifiers[opt] 2669 type-specifier declaration-specifiers[opt] 2670 type-qualifier declaration-specifiers[opt] 2671 function-specifier declaration-specifiers[opt] 2672 alignment-specifier declaration-specifiers[opt] 2673 2674 Function specifiers (inline) are from C99, and are currently 2675 handled as storage class specifiers, as is __thread. Alignment 2676 specifiers are from C11. 2677 2678 C90 6.5.1, C99 6.7.1, C11 6.7.1: 2679 storage-class-specifier: 2680 typedef 2681 extern 2682 static 2683 auto 2684 register 2685 _Thread_local 2686 2687 (_Thread_local is new in C11.) 2688 2689 C99 6.7.4, C11 6.7.4: 2690 function-specifier: 2691 inline 2692 _Noreturn 2693 2694 (_Noreturn is new in C11.) 2695 2696 C90 6.5.2, C99 6.7.2, C11 6.7.2: 2697 type-specifier: 2698 void 2699 char 2700 short 2701 int 2702 long 2703 float 2704 double 2705 signed 2706 unsigned 2707 _Bool 2708 _Complex 2709 [_Imaginary removed in C99 TC2] 2710 struct-or-union-specifier 2711 enum-specifier 2712 typedef-name 2713 atomic-type-specifier 2714 2715 (_Bool and _Complex are new in C99.) 2716 (atomic-type-specifier is new in C11.) 2717 2718 C90 6.5.3, C99 6.7.3, C11 6.7.3: 2719 2720 type-qualifier: 2721 const 2722 restrict 2723 volatile 2724 address-space-qualifier 2725 _Atomic 2726 2727 (restrict is new in C99.) 2728 (_Atomic is new in C11.) 2729 2730 GNU extensions: 2731 2732 declaration-specifiers: 2733 gnu-attributes declaration-specifiers[opt] 2734 2735 type-qualifier: 2736 address-space 2737 2738 address-space: 2739 identifier recognized by the target 2740 2741 storage-class-specifier: 2742 __thread 2743 2744 type-specifier: 2745 typeof-specifier 2746 __auto_type 2747 __intN 2748 _Decimal32 2749 _Decimal64 2750 _Decimal128 2751 _Fract 2752 _Accum 2753 _Sat 2754 2755 (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037: 2756 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf) 2757 2758 atomic-type-specifier 2759 _Atomic ( type-name ) 2760 2761 Objective-C: 2762 2763 type-specifier: 2764 class-name objc-protocol-refs[opt] 2765 typedef-name objc-protocol-refs 2766 objc-protocol-refs 2767 */ 2768 2769 void 2770 c_parser_declspecs (c_parser *parser, struct c_declspecs *specs, 2771 bool scspec_ok, bool typespec_ok, bool start_attr_ok, 2772 bool alignspec_ok, bool auto_type_ok, 2773 bool start_std_attr_ok, bool end_std_attr_ok, 2774 enum c_lookahead_kind la) 2775 { 2776 bool attrs_ok = start_attr_ok; 2777 bool seen_type = specs->typespec_kind != ctsk_none; 2778 2779 if (!typespec_ok) 2780 gcc_assert (la == cla_prefer_id); 2781 2782 if (start_std_attr_ok 2783 && c_parser_nth_token_starts_std_attributes (parser, 1)) 2784 { 2785 gcc_assert (!specs->non_std_attrs_seen_p); 2786 location_t loc = c_parser_peek_token (parser)->location; 2787 tree attrs = c_parser_std_attribute_specifier_sequence (parser); 2788 declspecs_add_attrs (loc, specs, attrs); 2789 specs->non_std_attrs_seen_p = false; 2790 } 2791 2792 while (c_parser_next_token_is (parser, CPP_NAME) 2793 || c_parser_next_token_is (parser, CPP_KEYWORD) 2794 || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS))) 2795 { 2796 struct c_typespec t; 2797 tree attrs; 2798 tree align; 2799 location_t loc = c_parser_peek_token (parser)->location; 2800 2801 /* If we cannot accept a type, exit if the next token must start 2802 one. Also, if we already have seen a tagged definition, 2803 a typename would be an error anyway and likely the user 2804 has simply forgotten a semicolon, so we exit. */ 2805 if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef) 2806 && c_parser_next_tokens_start_typename (parser, la) 2807 && !c_parser_next_token_is_qualifier (parser) 2808 && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS)) 2809 break; 2810 2811 if (c_parser_next_token_is (parser, CPP_NAME)) 2812 { 2813 c_token *name_token = c_parser_peek_token (parser); 2814 tree value = name_token->value; 2815 c_id_kind kind = name_token->id_kind; 2816 2817 if (kind == C_ID_ADDRSPACE) 2818 { 2819 addr_space_t as 2820 = name_token->keyword - RID_FIRST_ADDR_SPACE; 2821 declspecs_add_addrspace (name_token->location, specs, as); 2822 c_parser_consume_token (parser); 2823 attrs_ok = true; 2824 continue; 2825 } 2826 2827 gcc_assert (!c_parser_next_token_is_qualifier (parser)); 2828 2829 /* If we cannot accept a type, and the next token must start one, 2830 exit. Do the same if we already have seen a tagged definition, 2831 since it would be an error anyway and likely the user has simply 2832 forgotten a semicolon. */ 2833 if (seen_type || !c_parser_next_tokens_start_typename (parser, la)) 2834 break; 2835 2836 /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or 2837 a C_ID_CLASSNAME. */ 2838 c_parser_consume_token (parser); 2839 seen_type = true; 2840 attrs_ok = true; 2841 if (kind == C_ID_ID) 2842 { 2843 error_at (loc, "unknown type name %qE", value); 2844 t.kind = ctsk_typedef; 2845 t.spec = error_mark_node; 2846 } 2847 else if (kind == C_ID_TYPENAME 2848 && (!c_dialect_objc () 2849 || c_parser_next_token_is_not (parser, CPP_LESS))) 2850 { 2851 t.kind = ctsk_typedef; 2852 /* For a typedef name, record the meaning, not the name. 2853 In case of 'foo foo, bar;'. */ 2854 t.spec = lookup_name (value); 2855 } 2856 else 2857 { 2858 tree proto = NULL_TREE; 2859 gcc_assert (c_dialect_objc ()); 2860 t.kind = ctsk_objc; 2861 if (c_parser_next_token_is (parser, CPP_LESS)) 2862 proto = c_parser_objc_protocol_refs (parser); 2863 t.spec = objc_get_protocol_qualified_type (value, proto); 2864 } 2865 t.expr = NULL_TREE; 2866 t.expr_const_operands = true; 2867 declspecs_add_type (name_token->location, specs, t); 2868 continue; 2869 } 2870 if (c_parser_next_token_is (parser, CPP_LESS)) 2871 { 2872 /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" - 2873 nisse@lysator.liu.se. */ 2874 tree proto; 2875 gcc_assert (c_dialect_objc ()); 2876 if (!typespec_ok || seen_type) 2877 break; 2878 proto = c_parser_objc_protocol_refs (parser); 2879 t.kind = ctsk_objc; 2880 t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto); 2881 t.expr = NULL_TREE; 2882 t.expr_const_operands = true; 2883 declspecs_add_type (loc, specs, t); 2884 continue; 2885 } 2886 gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD)); 2887 switch (c_parser_peek_token (parser)->keyword) 2888 { 2889 case RID_STATIC: 2890 case RID_EXTERN: 2891 case RID_REGISTER: 2892 case RID_TYPEDEF: 2893 case RID_INLINE: 2894 case RID_NORETURN: 2895 case RID_AUTO: 2896 case RID_THREAD: 2897 if (!scspec_ok) 2898 goto out; 2899 attrs_ok = true; 2900 /* TODO: Distinguish between function specifiers (inline, noreturn) 2901 and storage class specifiers, either here or in 2902 declspecs_add_scspec. */ 2903 declspecs_add_scspec (loc, specs, 2904 c_parser_peek_token (parser)->value); 2905 c_parser_consume_token (parser); 2906 break; 2907 case RID_AUTO_TYPE: 2908 if (!auto_type_ok) 2909 goto out; 2910 /* Fall through. */ 2911 case RID_UNSIGNED: 2912 case RID_LONG: 2913 case RID_SHORT: 2914 case RID_SIGNED: 2915 case RID_COMPLEX: 2916 case RID_INT: 2917 case RID_CHAR: 2918 case RID_FLOAT: 2919 case RID_DOUBLE: 2920 case RID_VOID: 2921 case RID_DFLOAT32: 2922 case RID_DFLOAT64: 2923 case RID_DFLOAT128: 2924 CASE_RID_FLOATN_NX: 2925 case RID_BOOL: 2926 case RID_FRACT: 2927 case RID_ACCUM: 2928 case RID_SAT: 2929 case RID_INT_N_0: 2930 case RID_INT_N_1: 2931 case RID_INT_N_2: 2932 case RID_INT_N_3: 2933 if (!typespec_ok) 2934 goto out; 2935 attrs_ok = true; 2936 seen_type = true; 2937 if (c_dialect_objc ()) 2938 parser->objc_need_raw_identifier = true; 2939 t.kind = ctsk_resword; 2940 t.spec = c_parser_peek_token (parser)->value; 2941 t.expr = NULL_TREE; 2942 t.expr_const_operands = true; 2943 declspecs_add_type (loc, specs, t); 2944 c_parser_consume_token (parser); 2945 break; 2946 case RID_ENUM: 2947 if (!typespec_ok) 2948 goto out; 2949 attrs_ok = true; 2950 seen_type = true; 2951 t = c_parser_enum_specifier (parser); 2952 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec); 2953 declspecs_add_type (loc, specs, t); 2954 break; 2955 case RID_STRUCT: 2956 case RID_UNION: 2957 if (!typespec_ok) 2958 goto out; 2959 attrs_ok = true; 2960 seen_type = true; 2961 t = c_parser_struct_or_union_specifier (parser); 2962 invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec); 2963 declspecs_add_type (loc, specs, t); 2964 break; 2965 case RID_TYPEOF: 2966 /* ??? The old parser rejected typeof after other type 2967 specifiers, but is a syntax error the best way of 2968 handling this? */ 2969 if (!typespec_ok || seen_type) 2970 goto out; 2971 attrs_ok = true; 2972 seen_type = true; 2973 t = c_parser_typeof_specifier (parser); 2974 declspecs_add_type (loc, specs, t); 2975 break; 2976 case RID_ATOMIC: 2977 /* C parser handling of Objective-C constructs needs 2978 checking for correct lvalue-to-rvalue conversions, and 2979 the code in build_modify_expr handling various 2980 Objective-C cases, and that in build_unary_op handling 2981 Objective-C cases for increment / decrement, also needs 2982 updating; uses of TYPE_MAIN_VARIANT in objc_compare_types 2983 and objc_types_are_equivalent may also need updates. */ 2984 if (c_dialect_objc ()) 2985 sorry ("%<_Atomic%> in Objective-C"); 2986 if (flag_isoc99) 2987 pedwarn_c99 (loc, OPT_Wpedantic, 2988 "ISO C99 does not support the %<_Atomic%> qualifier"); 2989 else 2990 pedwarn_c99 (loc, OPT_Wpedantic, 2991 "ISO C90 does not support the %<_Atomic%> qualifier"); 2992 attrs_ok = true; 2993 tree value; 2994 value = c_parser_peek_token (parser)->value; 2995 c_parser_consume_token (parser); 2996 if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 2997 { 2998 /* _Atomic ( type-name ). */ 2999 seen_type = true; 3000 c_parser_consume_token (parser); 3001 struct c_type_name *type = c_parser_type_name (parser); 3002 t.kind = ctsk_typeof; 3003 t.spec = error_mark_node; 3004 t.expr = NULL_TREE; 3005 t.expr_const_operands = true; 3006 if (type != NULL) 3007 t.spec = groktypename (type, &t.expr, 3008 &t.expr_const_operands); 3009 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 3010 "expected %<)%>"); 3011 if (t.spec != error_mark_node) 3012 { 3013 if (TREE_CODE (t.spec) == ARRAY_TYPE) 3014 error_at (loc, "%<_Atomic%>-qualified array type"); 3015 else if (TREE_CODE (t.spec) == FUNCTION_TYPE) 3016 error_at (loc, "%<_Atomic%>-qualified function type"); 3017 else if (TYPE_QUALS (t.spec) != TYPE_UNQUALIFIED) 3018 error_at (loc, "%<_Atomic%> applied to a qualified type"); 3019 else 3020 t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC); 3021 } 3022 declspecs_add_type (loc, specs, t); 3023 } 3024 else 3025 declspecs_add_qual (loc, specs, value); 3026 break; 3027 case RID_CONST: 3028 case RID_VOLATILE: 3029 case RID_RESTRICT: 3030 attrs_ok = true; 3031 declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value); 3032 c_parser_consume_token (parser); 3033 break; 3034 case RID_ATTRIBUTE: 3035 if (!attrs_ok) 3036 goto out; 3037 attrs = c_parser_gnu_attributes (parser); 3038 declspecs_add_attrs (loc, specs, attrs); 3039 break; 3040 case RID_ALIGNAS: 3041 if (!alignspec_ok) 3042 goto out; 3043 align = c_parser_alignas_specifier (parser); 3044 declspecs_add_alignas (loc, specs, align); 3045 break; 3046 case RID_GIMPLE: 3047 if (! flag_gimple) 3048 error_at (loc, "%<__GIMPLE%> only valid with %<-fgimple%>"); 3049 c_parser_consume_token (parser); 3050 specs->declspec_il = cdil_gimple; 3051 specs->locations[cdw_gimple] = loc; 3052 c_parser_gimple_or_rtl_pass_list (parser, specs); 3053 break; 3054 case RID_RTL: 3055 c_parser_consume_token (parser); 3056 specs->declspec_il = cdil_rtl; 3057 specs->locations[cdw_rtl] = loc; 3058 c_parser_gimple_or_rtl_pass_list (parser, specs); 3059 break; 3060 default: 3061 goto out; 3062 } 3063 } 3064 out: 3065 if (end_std_attr_ok 3066 && c_parser_nth_token_starts_std_attributes (parser, 1)) 3067 specs->postfix_attrs = c_parser_std_attribute_specifier_sequence (parser); 3068 } 3069 3070 /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2). 3071 3072 enum-specifier: 3073 enum gnu-attributes[opt] identifier[opt] { enumerator-list } 3074 gnu-attributes[opt] 3075 enum gnu-attributes[opt] identifier[opt] { enumerator-list , } 3076 gnu-attributes[opt] 3077 enum gnu-attributes[opt] identifier 3078 3079 The form with trailing comma is new in C99. The forms with 3080 gnu-attributes are GNU extensions. In GNU C, we accept any expression 3081 without commas in the syntax (assignment expressions, not just 3082 conditional expressions); assignment expressions will be diagnosed 3083 as non-constant. 3084 3085 enumerator-list: 3086 enumerator 3087 enumerator-list , enumerator 3088 3089 enumerator: 3090 enumeration-constant attribute-specifier-sequence[opt] 3091 enumeration-constant attribute-specifier-sequence[opt] 3092 = constant-expression 3093 3094 GNU Extensions: 3095 3096 enumerator: 3097 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt] 3098 enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt] 3099 = constant-expression 3100 3101 */ 3102 3103 static struct c_typespec 3104 c_parser_enum_specifier (c_parser *parser) 3105 { 3106 struct c_typespec ret; 3107 bool have_std_attrs; 3108 tree std_attrs = NULL_TREE; 3109 tree attrs; 3110 tree ident = NULL_TREE; 3111 location_t enum_loc; 3112 location_t ident_loc = UNKNOWN_LOCATION; /* Quiet warning. */ 3113 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM)); 3114 c_parser_consume_token (parser); 3115 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1); 3116 if (have_std_attrs) 3117 std_attrs = c_parser_std_attribute_specifier_sequence (parser); 3118 attrs = c_parser_gnu_attributes (parser); 3119 enum_loc = c_parser_peek_token (parser)->location; 3120 /* Set the location in case we create a decl now. */ 3121 c_parser_set_source_position_from_token (c_parser_peek_token (parser)); 3122 if (c_parser_next_token_is (parser, CPP_NAME)) 3123 { 3124 ident = c_parser_peek_token (parser)->value; 3125 ident_loc = c_parser_peek_token (parser)->location; 3126 enum_loc = ident_loc; 3127 c_parser_consume_token (parser); 3128 } 3129 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 3130 { 3131 /* Parse an enum definition. */ 3132 struct c_enum_contents the_enum; 3133 tree type; 3134 tree postfix_attrs; 3135 /* We chain the enumerators in reverse order, then put them in 3136 forward order at the end. */ 3137 tree values; 3138 timevar_push (TV_PARSE_ENUM); 3139 type = start_enum (enum_loc, &the_enum, ident); 3140 values = NULL_TREE; 3141 c_parser_consume_token (parser); 3142 while (true) 3143 { 3144 tree enum_id; 3145 tree enum_value; 3146 tree enum_decl; 3147 bool seen_comma; 3148 c_token *token; 3149 location_t comma_loc = UNKNOWN_LOCATION; /* Quiet warning. */ 3150 location_t decl_loc, value_loc; 3151 if (c_parser_next_token_is_not (parser, CPP_NAME)) 3152 { 3153 /* Give a nicer error for "enum {}". */ 3154 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE) 3155 && !parser->error) 3156 { 3157 error_at (c_parser_peek_token (parser)->location, 3158 "empty enum is invalid"); 3159 parser->error = true; 3160 } 3161 else 3162 c_parser_error (parser, "expected identifier"); 3163 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL); 3164 values = error_mark_node; 3165 break; 3166 } 3167 token = c_parser_peek_token (parser); 3168 enum_id = token->value; 3169 /* Set the location in case we create a decl now. */ 3170 c_parser_set_source_position_from_token (token); 3171 decl_loc = value_loc = token->location; 3172 c_parser_consume_token (parser); 3173 /* Parse any specified attributes. */ 3174 tree std_attrs = NULL_TREE; 3175 if (c_parser_nth_token_starts_std_attributes (parser, 1)) 3176 std_attrs = c_parser_std_attribute_specifier_sequence (parser); 3177 tree enum_attrs = chainon (std_attrs, 3178 c_parser_gnu_attributes (parser)); 3179 if (c_parser_next_token_is (parser, CPP_EQ)) 3180 { 3181 c_parser_consume_token (parser); 3182 value_loc = c_parser_peek_token (parser)->location; 3183 enum_value = c_parser_expr_no_commas (parser, NULL).value; 3184 } 3185 else 3186 enum_value = NULL_TREE; 3187 enum_decl = build_enumerator (decl_loc, value_loc, 3188 &the_enum, enum_id, enum_value); 3189 if (enum_attrs) 3190 decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0); 3191 TREE_CHAIN (enum_decl) = values; 3192 values = enum_decl; 3193 seen_comma = false; 3194 if (c_parser_next_token_is (parser, CPP_COMMA)) 3195 { 3196 comma_loc = c_parser_peek_token (parser)->location; 3197 seen_comma = true; 3198 c_parser_consume_token (parser); 3199 } 3200 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 3201 { 3202 if (seen_comma) 3203 pedwarn_c90 (comma_loc, OPT_Wpedantic, 3204 "comma at end of enumerator list"); 3205 c_parser_consume_token (parser); 3206 break; 3207 } 3208 if (!seen_comma) 3209 { 3210 c_parser_error (parser, "expected %<,%> or %<}%>"); 3211 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL); 3212 values = error_mark_node; 3213 break; 3214 } 3215 } 3216 postfix_attrs = c_parser_gnu_attributes (parser); 3217 ret.spec = finish_enum (type, nreverse (values), 3218 chainon (std_attrs, 3219 chainon (attrs, postfix_attrs))); 3220 ret.kind = ctsk_tagdef; 3221 ret.expr = NULL_TREE; 3222 ret.expr_const_operands = true; 3223 timevar_pop (TV_PARSE_ENUM); 3224 return ret; 3225 } 3226 else if (!ident) 3227 { 3228 c_parser_error (parser, "expected %<{%>"); 3229 ret.spec = error_mark_node; 3230 ret.kind = ctsk_tagref; 3231 ret.expr = NULL_TREE; 3232 ret.expr_const_operands = true; 3233 return ret; 3234 } 3235 /* Attributes may only appear when the members are defined or in 3236 certain forward declarations (treat enum forward declarations in 3237 GNU C analogously to struct and union forward declarations in 3238 standard C). */ 3239 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON)) 3240 c_parser_error (parser, "expected %<;%>"); 3241 ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident, have_std_attrs, 3242 std_attrs); 3243 /* In ISO C, enumerated types can be referred to only if already 3244 defined. */ 3245 if (pedantic && !COMPLETE_TYPE_P (ret.spec)) 3246 { 3247 gcc_assert (ident); 3248 pedwarn (enum_loc, OPT_Wpedantic, 3249 "ISO C forbids forward references to %<enum%> types"); 3250 } 3251 return ret; 3252 } 3253 3254 /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1). 3255 3256 struct-or-union-specifier: 3257 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt] 3258 identifier[opt] { struct-contents } gnu-attributes[opt] 3259 struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt] 3260 identifier 3261 3262 struct-contents: 3263 struct-declaration-list 3264 3265 struct-declaration-list: 3266 struct-declaration ; 3267 struct-declaration-list struct-declaration ; 3268 3269 GNU extensions: 3270 3271 struct-contents: 3272 empty 3273 struct-declaration 3274 struct-declaration-list struct-declaration 3275 3276 struct-declaration-list: 3277 struct-declaration-list ; 3278 ; 3279 3280 (Note that in the syntax here, unlike that in ISO C, the semicolons 3281 are included here rather than in struct-declaration, in order to 3282 describe the syntax with extra semicolons and missing semicolon at 3283 end.) 3284 3285 Objective-C: 3286 3287 struct-declaration-list: 3288 @defs ( class-name ) 3289 3290 (Note this does not include a trailing semicolon, but can be 3291 followed by further declarations, and gets a pedwarn-if-pedantic 3292 when followed by a semicolon.) */ 3293 3294 static struct c_typespec 3295 c_parser_struct_or_union_specifier (c_parser *parser) 3296 { 3297 struct c_typespec ret; 3298 bool have_std_attrs; 3299 tree std_attrs = NULL_TREE; 3300 tree attrs; 3301 tree ident = NULL_TREE; 3302 location_t struct_loc; 3303 location_t ident_loc = UNKNOWN_LOCATION; 3304 enum tree_code code; 3305 switch (c_parser_peek_token (parser)->keyword) 3306 { 3307 case RID_STRUCT: 3308 code = RECORD_TYPE; 3309 break; 3310 case RID_UNION: 3311 code = UNION_TYPE; 3312 break; 3313 default: 3314 gcc_unreachable (); 3315 } 3316 struct_loc = c_parser_peek_token (parser)->location; 3317 c_parser_consume_token (parser); 3318 have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1); 3319 if (have_std_attrs) 3320 std_attrs = c_parser_std_attribute_specifier_sequence (parser); 3321 attrs = c_parser_gnu_attributes (parser); 3322 3323 /* Set the location in case we create a decl now. */ 3324 c_parser_set_source_position_from_token (c_parser_peek_token (parser)); 3325 3326 if (c_parser_next_token_is (parser, CPP_NAME)) 3327 { 3328 ident = c_parser_peek_token (parser)->value; 3329 ident_loc = c_parser_peek_token (parser)->location; 3330 struct_loc = ident_loc; 3331 c_parser_consume_token (parser); 3332 } 3333 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 3334 { 3335 /* Parse a struct or union definition. Start the scope of the 3336 tag before parsing components. */ 3337 class c_struct_parse_info *struct_info; 3338 tree type = start_struct (struct_loc, code, ident, &struct_info); 3339 tree postfix_attrs; 3340 /* We chain the components in reverse order, then put them in 3341 forward order at the end. Each struct-declaration may 3342 declare multiple components (comma-separated), so we must use 3343 chainon to join them, although when parsing each 3344 struct-declaration we can use TREE_CHAIN directly. 3345 3346 The theory behind all this is that there will be more 3347 semicolon separated fields than comma separated fields, and 3348 so we'll be minimizing the number of node traversals required 3349 by chainon. */ 3350 tree contents; 3351 timevar_push (TV_PARSE_STRUCT); 3352 contents = NULL_TREE; 3353 c_parser_consume_token (parser); 3354 /* Handle the Objective-C @defs construct, 3355 e.g. foo(sizeof(struct{ @defs(ClassName) }));. */ 3356 if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS)) 3357 { 3358 tree name; 3359 gcc_assert (c_dialect_objc ()); 3360 c_parser_consume_token (parser); 3361 matching_parens parens; 3362 if (!parens.require_open (parser)) 3363 goto end_at_defs; 3364 if (c_parser_next_token_is (parser, CPP_NAME) 3365 && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME) 3366 { 3367 name = c_parser_peek_token (parser)->value; 3368 c_parser_consume_token (parser); 3369 } 3370 else 3371 { 3372 c_parser_error (parser, "expected class name"); 3373 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 3374 goto end_at_defs; 3375 } 3376 parens.skip_until_found_close (parser); 3377 contents = nreverse (objc_get_class_ivars (name)); 3378 } 3379 end_at_defs: 3380 /* Parse the struct-declarations and semicolons. Problems with 3381 semicolons are diagnosed here; empty structures are diagnosed 3382 elsewhere. */ 3383 while (true) 3384 { 3385 tree decls; 3386 /* Parse any stray semicolon. */ 3387 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 3388 { 3389 location_t semicolon_loc 3390 = c_parser_peek_token (parser)->location; 3391 gcc_rich_location richloc (semicolon_loc); 3392 richloc.add_fixit_remove (); 3393 pedwarn (&richloc, OPT_Wpedantic, 3394 "extra semicolon in struct or union specified"); 3395 c_parser_consume_token (parser); 3396 continue; 3397 } 3398 /* Stop if at the end of the struct or union contents. */ 3399 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 3400 { 3401 c_parser_consume_token (parser); 3402 break; 3403 } 3404 /* Accept #pragmas at struct scope. */ 3405 if (c_parser_next_token_is (parser, CPP_PRAGMA)) 3406 { 3407 c_parser_pragma (parser, pragma_struct, NULL); 3408 continue; 3409 } 3410 /* Parse some comma-separated declarations, but not the 3411 trailing semicolon if any. */ 3412 decls = c_parser_struct_declaration (parser); 3413 contents = chainon (decls, contents); 3414 /* If no semicolon follows, either we have a parse error or 3415 are at the end of the struct or union and should 3416 pedwarn. */ 3417 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 3418 c_parser_consume_token (parser); 3419 else 3420 { 3421 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 3422 pedwarn (c_parser_peek_token (parser)->location, 0, 3423 "no semicolon at end of struct or union"); 3424 else if (parser->error 3425 || !c_parser_next_token_starts_declspecs (parser)) 3426 { 3427 c_parser_error (parser, "expected %<;%>"); 3428 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL); 3429 break; 3430 } 3431 3432 /* If we come here, we have already emitted an error 3433 for an expected `;', identifier or `(', and we also 3434 recovered already. Go on with the next field. */ 3435 } 3436 } 3437 postfix_attrs = c_parser_gnu_attributes (parser); 3438 ret.spec = finish_struct (struct_loc, type, nreverse (contents), 3439 chainon (std_attrs, 3440 chainon (attrs, postfix_attrs)), 3441 struct_info); 3442 ret.kind = ctsk_tagdef; 3443 ret.expr = NULL_TREE; 3444 ret.expr_const_operands = true; 3445 timevar_pop (TV_PARSE_STRUCT); 3446 return ret; 3447 } 3448 else if (!ident) 3449 { 3450 c_parser_error (parser, "expected %<{%>"); 3451 ret.spec = error_mark_node; 3452 ret.kind = ctsk_tagref; 3453 ret.expr = NULL_TREE; 3454 ret.expr_const_operands = true; 3455 return ret; 3456 } 3457 /* Attributes may only appear when the members are defined or in 3458 certain forward declarations. */ 3459 if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON)) 3460 c_parser_error (parser, "expected %<;%>"); 3461 /* ??? Existing practice is that GNU attributes are ignored after 3462 the struct or union keyword when not defining the members. */ 3463 ret = parser_xref_tag (ident_loc, code, ident, have_std_attrs, std_attrs); 3464 return ret; 3465 } 3466 3467 /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1), 3468 *without* the trailing semicolon. 3469 3470 struct-declaration: 3471 attribute-specifier-sequence[opt] specifier-qualifier-list 3472 attribute-specifier-sequence[opt] struct-declarator-list 3473 static_assert-declaration-no-semi 3474 3475 specifier-qualifier-list: 3476 type-specifier specifier-qualifier-list[opt] 3477 type-qualifier specifier-qualifier-list[opt] 3478 alignment-specifier specifier-qualifier-list[opt] 3479 gnu-attributes specifier-qualifier-list[opt] 3480 3481 struct-declarator-list: 3482 struct-declarator 3483 struct-declarator-list , gnu-attributes[opt] struct-declarator 3484 3485 struct-declarator: 3486 declarator gnu-attributes[opt] 3487 declarator[opt] : constant-expression gnu-attributes[opt] 3488 3489 GNU extensions: 3490 3491 struct-declaration: 3492 __extension__ struct-declaration 3493 specifier-qualifier-list 3494 3495 Unlike the ISO C syntax, semicolons are handled elsewhere. The use 3496 of gnu-attributes where shown is a GNU extension. In GNU C, we accept 3497 any expression without commas in the syntax (assignment 3498 expressions, not just conditional expressions); assignment 3499 expressions will be diagnosed as non-constant. */ 3500 3501 static tree 3502 c_parser_struct_declaration (c_parser *parser) 3503 { 3504 struct c_declspecs *specs; 3505 tree prefix_attrs; 3506 tree all_prefix_attrs; 3507 tree decls; 3508 location_t decl_loc; 3509 if (c_parser_next_token_is_keyword (parser, RID_EXTENSION)) 3510 { 3511 int ext; 3512 tree decl; 3513 ext = disable_extension_diagnostics (); 3514 c_parser_consume_token (parser); 3515 decl = c_parser_struct_declaration (parser); 3516 restore_extension_diagnostics (ext); 3517 return decl; 3518 } 3519 if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT)) 3520 { 3521 c_parser_static_assert_declaration_no_semi (parser); 3522 return NULL_TREE; 3523 } 3524 specs = build_null_declspecs (); 3525 decl_loc = c_parser_peek_token (parser)->location; 3526 /* Strictly by the standard, we shouldn't allow _Alignas here, 3527 but it appears to have been intended to allow it there, so 3528 we're keeping it as it is until WG14 reaches a conclusion 3529 of N1731. 3530 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf> */ 3531 c_parser_declspecs (parser, specs, false, true, true, 3532 true, false, true, true, cla_nonabstract_decl); 3533 if (parser->error) 3534 return NULL_TREE; 3535 if (!specs->declspecs_seen_p) 3536 { 3537 c_parser_error (parser, "expected specifier-qualifier-list"); 3538 return NULL_TREE; 3539 } 3540 finish_declspecs (specs); 3541 if (c_parser_next_token_is (parser, CPP_SEMICOLON) 3542 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 3543 { 3544 tree ret; 3545 if (specs->typespec_kind == ctsk_none) 3546 { 3547 pedwarn (decl_loc, OPT_Wpedantic, 3548 "ISO C forbids member declarations with no members"); 3549 shadow_tag_warned (specs, pedantic); 3550 ret = NULL_TREE; 3551 } 3552 else 3553 { 3554 /* Support for unnamed structs or unions as members of 3555 structs or unions (which is [a] useful and [b] supports 3556 MS P-SDK). */ 3557 tree attrs = NULL; 3558 3559 ret = grokfield (c_parser_peek_token (parser)->location, 3560 build_id_declarator (NULL_TREE), specs, 3561 NULL_TREE, &attrs); 3562 if (ret) 3563 decl_attributes (&ret, attrs, 0); 3564 } 3565 return ret; 3566 } 3567 3568 /* Provide better error recovery. Note that a type name here is valid, 3569 and will be treated as a field name. */ 3570 if (specs->typespec_kind == ctsk_tagdef 3571 && TREE_CODE (specs->type) != ENUMERAL_TYPE 3572 && c_parser_next_token_starts_declspecs (parser) 3573 && !c_parser_next_token_is (parser, CPP_NAME)) 3574 { 3575 c_parser_error (parser, "expected %<;%>, identifier or %<(%>"); 3576 parser->error = false; 3577 return NULL_TREE; 3578 } 3579 3580 pending_xref_error (); 3581 prefix_attrs = specs->attrs; 3582 all_prefix_attrs = prefix_attrs; 3583 specs->attrs = NULL_TREE; 3584 decls = NULL_TREE; 3585 while (true) 3586 { 3587 /* Declaring one or more declarators or un-named bit-fields. */ 3588 struct c_declarator *declarator; 3589 bool dummy = false; 3590 if (c_parser_next_token_is (parser, CPP_COLON)) 3591 declarator = build_id_declarator (NULL_TREE); 3592 else 3593 declarator = c_parser_declarator (parser, 3594 specs->typespec_kind != ctsk_none, 3595 C_DTR_NORMAL, &dummy); 3596 if (declarator == NULL) 3597 { 3598 c_parser_skip_to_end_of_block_or_statement (parser); 3599 break; 3600 } 3601 if (c_parser_next_token_is (parser, CPP_COLON) 3602 || c_parser_next_token_is (parser, CPP_COMMA) 3603 || c_parser_next_token_is (parser, CPP_SEMICOLON) 3604 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE) 3605 || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 3606 { 3607 tree postfix_attrs = NULL_TREE; 3608 tree width = NULL_TREE; 3609 tree d; 3610 if (c_parser_next_token_is (parser, CPP_COLON)) 3611 { 3612 c_parser_consume_token (parser); 3613 width = c_parser_expr_no_commas (parser, NULL).value; 3614 } 3615 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 3616 postfix_attrs = c_parser_gnu_attributes (parser); 3617 d = grokfield (c_parser_peek_token (parser)->location, 3618 declarator, specs, width, &all_prefix_attrs); 3619 decl_attributes (&d, chainon (postfix_attrs, 3620 all_prefix_attrs), 0); 3621 DECL_CHAIN (d) = decls; 3622 decls = d; 3623 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 3624 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser), 3625 prefix_attrs); 3626 else 3627 all_prefix_attrs = prefix_attrs; 3628 if (c_parser_next_token_is (parser, CPP_COMMA)) 3629 c_parser_consume_token (parser); 3630 else if (c_parser_next_token_is (parser, CPP_SEMICOLON) 3631 || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 3632 { 3633 /* Semicolon consumed in caller. */ 3634 break; 3635 } 3636 else 3637 { 3638 c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>"); 3639 break; 3640 } 3641 } 3642 else 3643 { 3644 c_parser_error (parser, 3645 "expected %<:%>, %<,%>, %<;%>, %<}%> or " 3646 "%<__attribute__%>"); 3647 break; 3648 } 3649 } 3650 return decls; 3651 } 3652 3653 /* Parse a typeof specifier (a GNU extension). 3654 3655 typeof-specifier: 3656 typeof ( expression ) 3657 typeof ( type-name ) 3658 */ 3659 3660 static struct c_typespec 3661 c_parser_typeof_specifier (c_parser *parser) 3662 { 3663 struct c_typespec ret; 3664 ret.kind = ctsk_typeof; 3665 ret.spec = error_mark_node; 3666 ret.expr = NULL_TREE; 3667 ret.expr_const_operands = true; 3668 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF)); 3669 c_parser_consume_token (parser); 3670 c_inhibit_evaluation_warnings++; 3671 in_typeof++; 3672 matching_parens parens; 3673 if (!parens.require_open (parser)) 3674 { 3675 c_inhibit_evaluation_warnings--; 3676 in_typeof--; 3677 return ret; 3678 } 3679 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id)) 3680 { 3681 struct c_type_name *type = c_parser_type_name (parser); 3682 c_inhibit_evaluation_warnings--; 3683 in_typeof--; 3684 if (type != NULL) 3685 { 3686 ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands); 3687 pop_maybe_used (variably_modified_type_p (ret.spec, NULL_TREE)); 3688 } 3689 } 3690 else 3691 { 3692 bool was_vm; 3693 location_t here = c_parser_peek_token (parser)->location; 3694 struct c_expr expr = c_parser_expression (parser); 3695 c_inhibit_evaluation_warnings--; 3696 in_typeof--; 3697 if (TREE_CODE (expr.value) == COMPONENT_REF 3698 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1))) 3699 error_at (here, "%<typeof%> applied to a bit-field"); 3700 mark_exp_read (expr.value); 3701 ret.spec = TREE_TYPE (expr.value); 3702 was_vm = variably_modified_type_p (ret.spec, NULL_TREE); 3703 /* This is returned with the type so that when the type is 3704 evaluated, this can be evaluated. */ 3705 if (was_vm) 3706 ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands); 3707 pop_maybe_used (was_vm); 3708 /* For use in macros such as those in <stdatomic.h>, remove all 3709 qualifiers from atomic types. (const can be an issue for more macros 3710 using typeof than just the <stdatomic.h> ones.) */ 3711 if (ret.spec != error_mark_node && TYPE_ATOMIC (ret.spec)) 3712 ret.spec = c_build_qualified_type (ret.spec, TYPE_UNQUALIFIED); 3713 } 3714 parens.skip_until_found_close (parser); 3715 return ret; 3716 } 3717 3718 /* Parse an alignment-specifier. 3719 3720 C11 6.7.5: 3721 3722 alignment-specifier: 3723 _Alignas ( type-name ) 3724 _Alignas ( constant-expression ) 3725 */ 3726 3727 static tree 3728 c_parser_alignas_specifier (c_parser * parser) 3729 { 3730 tree ret = error_mark_node; 3731 location_t loc = c_parser_peek_token (parser)->location; 3732 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS)); 3733 c_parser_consume_token (parser); 3734 if (flag_isoc99) 3735 pedwarn_c99 (loc, OPT_Wpedantic, 3736 "ISO C99 does not support %<_Alignas%>"); 3737 else 3738 pedwarn_c99 (loc, OPT_Wpedantic, 3739 "ISO C90 does not support %<_Alignas%>"); 3740 matching_parens parens; 3741 if (!parens.require_open (parser)) 3742 return ret; 3743 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id)) 3744 { 3745 struct c_type_name *type = c_parser_type_name (parser); 3746 if (type != NULL) 3747 ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL), 3748 false, true, 1); 3749 } 3750 else 3751 ret = c_parser_expr_no_commas (parser, NULL).value; 3752 parens.skip_until_found_close (parser); 3753 return ret; 3754 } 3755 3756 /* Parse a declarator, possibly an abstract declarator (C90 6.5.4, 3757 6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7). If TYPE_SEEN_P then 3758 a typedef name may be redeclared; otherwise it may not. KIND 3759 indicates which kind of declarator is wanted. Returns a valid 3760 declarator except in the case of a syntax error in which case NULL is 3761 returned. *SEEN_ID is set to true if an identifier being declared is 3762 seen; this is used to diagnose bad forms of abstract array declarators 3763 and to determine whether an identifier list is syntactically permitted. 3764 3765 declarator: 3766 pointer[opt] direct-declarator 3767 3768 direct-declarator: 3769 identifier 3770 ( gnu-attributes[opt] declarator ) 3771 direct-declarator array-declarator 3772 direct-declarator ( parameter-type-list ) 3773 direct-declarator ( identifier-list[opt] ) 3774 3775 pointer: 3776 * type-qualifier-list[opt] 3777 * type-qualifier-list[opt] pointer 3778 3779 type-qualifier-list: 3780 type-qualifier 3781 gnu-attributes 3782 type-qualifier-list type-qualifier 3783 type-qualifier-list gnu-attributes 3784 3785 array-declarator: 3786 [ type-qualifier-list[opt] assignment-expression[opt] ] 3787 [ static type-qualifier-list[opt] assignment-expression ] 3788 [ type-qualifier-list static assignment-expression ] 3789 [ type-qualifier-list[opt] * ] 3790 3791 parameter-type-list: 3792 parameter-list 3793 parameter-list , ... 3794 3795 parameter-list: 3796 parameter-declaration 3797 parameter-list , parameter-declaration 3798 3799 parameter-declaration: 3800 declaration-specifiers declarator gnu-attributes[opt] 3801 declaration-specifiers abstract-declarator[opt] gnu-attributes[opt] 3802 3803 identifier-list: 3804 identifier 3805 identifier-list , identifier 3806 3807 abstract-declarator: 3808 pointer 3809 pointer[opt] direct-abstract-declarator 3810 3811 direct-abstract-declarator: 3812 ( gnu-attributes[opt] abstract-declarator ) 3813 direct-abstract-declarator[opt] array-declarator 3814 direct-abstract-declarator[opt] ( parameter-type-list[opt] ) 3815 3816 GNU extensions: 3817 3818 direct-declarator: 3819 direct-declarator ( parameter-forward-declarations 3820 parameter-type-list[opt] ) 3821 3822 direct-abstract-declarator: 3823 direct-abstract-declarator[opt] ( parameter-forward-declarations 3824 parameter-type-list[opt] ) 3825 3826 parameter-forward-declarations: 3827 parameter-list ; 3828 parameter-forward-declarations parameter-list ; 3829 3830 The uses of gnu-attributes shown above are GNU extensions. 3831 3832 Some forms of array declarator are not included in C99 in the 3833 syntax for abstract declarators; these are disallowed elsewhere. 3834 This may be a defect (DR#289). 3835 3836 This function also accepts an omitted abstract declarator as being 3837 an abstract declarator, although not part of the formal syntax. */ 3838 3839 struct c_declarator * 3840 c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind, 3841 bool *seen_id) 3842 { 3843 /* Parse any initial pointer part. */ 3844 if (c_parser_next_token_is (parser, CPP_MULT)) 3845 { 3846 struct c_declspecs *quals_attrs = build_null_declspecs (); 3847 struct c_declarator *inner; 3848 c_parser_consume_token (parser); 3849 c_parser_declspecs (parser, quals_attrs, false, false, true, 3850 false, false, true, false, cla_prefer_id); 3851 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id); 3852 if (inner == NULL) 3853 return NULL; 3854 else 3855 return make_pointer_declarator (quals_attrs, inner); 3856 } 3857 /* Now we have a direct declarator, direct abstract declarator or 3858 nothing (which counts as a direct abstract declarator here). */ 3859 return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id); 3860 } 3861 3862 /* Parse a direct declarator or direct abstract declarator; arguments 3863 as c_parser_declarator. */ 3864 3865 static struct c_declarator * 3866 c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind, 3867 bool *seen_id) 3868 { 3869 /* The direct declarator must start with an identifier (possibly 3870 omitted) or a parenthesized declarator (possibly abstract). In 3871 an ordinary declarator, initial parentheses must start a 3872 parenthesized declarator. In an abstract declarator or parameter 3873 declarator, they could start a parenthesized declarator or a 3874 parameter list. To tell which, the open parenthesis and any 3875 following gnu-attributes must be read. If a declaration 3876 specifier or standard attributes follow, then it is a parameter 3877 list; if the specifier is a typedef name, there might be an 3878 ambiguity about redeclaring it, which is resolved in the 3879 direction of treating it as a typedef name. If a close 3880 parenthesis follows, it is also an empty parameter list, as the 3881 syntax does not permit empty abstract declarators. Otherwise, it 3882 is a parenthesized declarator (in which case the analysis may be 3883 repeated inside it, recursively). 3884 3885 ??? There is an ambiguity in a parameter declaration "int 3886 (__attribute__((foo)) x)", where x is not a typedef name: it 3887 could be an abstract declarator for a function, or declare x with 3888 parentheses. The proper resolution of this ambiguity needs 3889 documenting. At present we follow an accident of the old 3890 parser's implementation, whereby the first parameter must have 3891 some declaration specifiers other than just gnu-attributes. Thus as 3892 a parameter declaration it is treated as a parenthesized 3893 parameter named x, and as an abstract declarator it is 3894 rejected. 3895 3896 ??? Also following the old parser, gnu-attributes inside an empty 3897 parameter list are ignored, making it a list not yielding a 3898 prototype, rather than giving an error or making it have one 3899 parameter with implicit type int. 3900 3901 ??? Also following the old parser, typedef names may be 3902 redeclared in declarators, but not Objective-C class names. */ 3903 3904 if (kind != C_DTR_ABSTRACT 3905 && c_parser_next_token_is (parser, CPP_NAME) 3906 && ((type_seen_p 3907 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME 3908 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)) 3909 || c_parser_peek_token (parser)->id_kind == C_ID_ID)) 3910 { 3911 struct c_declarator *inner 3912 = build_id_declarator (c_parser_peek_token (parser)->value); 3913 *seen_id = true; 3914 inner->id_loc = c_parser_peek_token (parser)->location; 3915 c_parser_consume_token (parser); 3916 if (c_parser_nth_token_starts_std_attributes (parser, 1)) 3917 inner->u.id.attrs = c_parser_std_attribute_specifier_sequence (parser); 3918 return c_parser_direct_declarator_inner (parser, *seen_id, inner); 3919 } 3920 3921 if (kind != C_DTR_NORMAL 3922 && c_parser_next_token_is (parser, CPP_OPEN_SQUARE) 3923 && !c_parser_nth_token_starts_std_attributes (parser, 1)) 3924 { 3925 struct c_declarator *inner = build_id_declarator (NULL_TREE); 3926 inner->id_loc = c_parser_peek_token (parser)->location; 3927 return c_parser_direct_declarator_inner (parser, *seen_id, inner); 3928 } 3929 3930 /* Either we are at the end of an abstract declarator, or we have 3931 parentheses. */ 3932 3933 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 3934 { 3935 tree attrs; 3936 struct c_declarator *inner; 3937 c_parser_consume_token (parser); 3938 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser, 3939 RID_ATTRIBUTE); 3940 attrs = c_parser_gnu_attributes (parser); 3941 if (kind != C_DTR_NORMAL 3942 && (c_parser_next_token_starts_declspecs (parser) 3943 || (!have_gnu_attrs 3944 && c_parser_nth_token_starts_std_attributes (parser, 1)) 3945 || c_parser_next_token_is (parser, CPP_CLOSE_PAREN))) 3946 { 3947 struct c_arg_info *args 3948 = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL, 3949 attrs, have_gnu_attrs); 3950 if (args == NULL) 3951 return NULL; 3952 else 3953 { 3954 inner = build_id_declarator (NULL_TREE); 3955 if (!(args->types 3956 && args->types != error_mark_node 3957 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE) 3958 && c_parser_nth_token_starts_std_attributes (parser, 1)) 3959 { 3960 tree std_attrs 3961 = c_parser_std_attribute_specifier_sequence (parser); 3962 if (std_attrs) 3963 inner = build_attrs_declarator (std_attrs, inner); 3964 } 3965 inner = build_function_declarator (args, inner); 3966 return c_parser_direct_declarator_inner (parser, *seen_id, 3967 inner); 3968 } 3969 } 3970 /* A parenthesized declarator. */ 3971 inner = c_parser_declarator (parser, type_seen_p, kind, seen_id); 3972 if (inner != NULL && attrs != NULL) 3973 inner = build_attrs_declarator (attrs, inner); 3974 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 3975 { 3976 c_parser_consume_token (parser); 3977 if (inner == NULL) 3978 return NULL; 3979 else 3980 return c_parser_direct_declarator_inner (parser, *seen_id, inner); 3981 } 3982 else 3983 { 3984 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 3985 "expected %<)%>"); 3986 return NULL; 3987 } 3988 } 3989 else 3990 { 3991 if (kind == C_DTR_NORMAL) 3992 { 3993 c_parser_error (parser, "expected identifier or %<(%>"); 3994 return NULL; 3995 } 3996 else 3997 return build_id_declarator (NULL_TREE); 3998 } 3999 } 4000 4001 /* Parse part of a direct declarator or direct abstract declarator, 4002 given that some (in INNER) has already been parsed; ID_PRESENT is 4003 true if an identifier is present, false for an abstract 4004 declarator. */ 4005 4006 static struct c_declarator * 4007 c_parser_direct_declarator_inner (c_parser *parser, bool id_present, 4008 struct c_declarator *inner) 4009 { 4010 /* Parse a sequence of array declarators and parameter lists. */ 4011 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE) 4012 && !c_parser_nth_token_starts_std_attributes (parser, 1)) 4013 { 4014 location_t brace_loc = c_parser_peek_token (parser)->location; 4015 struct c_declarator *declarator; 4016 struct c_declspecs *quals_attrs = build_null_declspecs (); 4017 bool static_seen; 4018 bool star_seen; 4019 struct c_expr dimen; 4020 dimen.value = NULL_TREE; 4021 dimen.original_code = ERROR_MARK; 4022 dimen.original_type = NULL_TREE; 4023 c_parser_consume_token (parser); 4024 c_parser_declspecs (parser, quals_attrs, false, false, true, 4025 false, false, false, false, cla_prefer_id); 4026 static_seen = c_parser_next_token_is_keyword (parser, RID_STATIC); 4027 if (static_seen) 4028 c_parser_consume_token (parser); 4029 if (static_seen && !quals_attrs->declspecs_seen_p) 4030 c_parser_declspecs (parser, quals_attrs, false, false, true, 4031 false, false, false, false, cla_prefer_id); 4032 if (!quals_attrs->declspecs_seen_p) 4033 quals_attrs = NULL; 4034 /* If "static" is present, there must be an array dimension. 4035 Otherwise, there may be a dimension, "*", or no 4036 dimension. */ 4037 if (static_seen) 4038 { 4039 star_seen = false; 4040 dimen = c_parser_expr_no_commas (parser, NULL); 4041 } 4042 else 4043 { 4044 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) 4045 { 4046 dimen.value = NULL_TREE; 4047 star_seen = false; 4048 } 4049 else if (c_parser_next_token_is (parser, CPP_MULT)) 4050 { 4051 if (c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE) 4052 { 4053 dimen.value = NULL_TREE; 4054 star_seen = true; 4055 c_parser_consume_token (parser); 4056 } 4057 else 4058 { 4059 star_seen = false; 4060 dimen = c_parser_expr_no_commas (parser, NULL); 4061 } 4062 } 4063 else 4064 { 4065 star_seen = false; 4066 dimen = c_parser_expr_no_commas (parser, NULL); 4067 } 4068 } 4069 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) 4070 c_parser_consume_token (parser); 4071 else 4072 { 4073 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, 4074 "expected %<]%>"); 4075 return NULL; 4076 } 4077 if (dimen.value) 4078 dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true); 4079 declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs, 4080 static_seen, star_seen); 4081 if (declarator == NULL) 4082 return NULL; 4083 if (c_parser_nth_token_starts_std_attributes (parser, 1)) 4084 { 4085 tree std_attrs 4086 = c_parser_std_attribute_specifier_sequence (parser); 4087 if (std_attrs) 4088 inner = build_attrs_declarator (std_attrs, inner); 4089 } 4090 inner = set_array_declarator_inner (declarator, inner); 4091 return c_parser_direct_declarator_inner (parser, id_present, inner); 4092 } 4093 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 4094 { 4095 tree attrs; 4096 struct c_arg_info *args; 4097 c_parser_consume_token (parser); 4098 bool have_gnu_attrs = c_parser_next_token_is_keyword (parser, 4099 RID_ATTRIBUTE); 4100 attrs = c_parser_gnu_attributes (parser); 4101 args = c_parser_parms_declarator (parser, id_present, attrs, 4102 have_gnu_attrs); 4103 if (args == NULL) 4104 return NULL; 4105 else 4106 { 4107 if (!(args->types 4108 && args->types != error_mark_node 4109 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE) 4110 && c_parser_nth_token_starts_std_attributes (parser, 1)) 4111 { 4112 tree std_attrs 4113 = c_parser_std_attribute_specifier_sequence (parser); 4114 if (std_attrs) 4115 inner = build_attrs_declarator (std_attrs, inner); 4116 } 4117 inner = build_function_declarator (args, inner); 4118 return c_parser_direct_declarator_inner (parser, id_present, inner); 4119 } 4120 } 4121 return inner; 4122 } 4123 4124 /* Parse a parameter list or identifier list, including the closing 4125 parenthesis but not the opening one. ATTRS are the gnu-attributes 4126 at the start of the list. ID_LIST_OK is true if an identifier list 4127 is acceptable; such a list must not have attributes at the start. 4128 HAVE_GNU_ATTRS says whether any gnu-attributes (including empty 4129 attributes) were present (in which case standard attributes cannot 4130 occur). */ 4131 4132 static struct c_arg_info * 4133 c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs, 4134 bool have_gnu_attrs) 4135 { 4136 push_scope (); 4137 declare_parm_level (); 4138 /* If the list starts with an identifier, it is an identifier list. 4139 Otherwise, it is either a prototype list or an empty list. */ 4140 if (id_list_ok 4141 && !attrs 4142 && c_parser_next_token_is (parser, CPP_NAME) 4143 && c_parser_peek_token (parser)->id_kind == C_ID_ID 4144 4145 /* Look ahead to detect typos in type names. */ 4146 && c_parser_peek_2nd_token (parser)->type != CPP_NAME 4147 && c_parser_peek_2nd_token (parser)->type != CPP_MULT 4148 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN 4149 && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE 4150 && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD) 4151 { 4152 tree list = NULL_TREE, *nextp = &list; 4153 while (c_parser_next_token_is (parser, CPP_NAME) 4154 && c_parser_peek_token (parser)->id_kind == C_ID_ID) 4155 { 4156 *nextp = build_tree_list (NULL_TREE, 4157 c_parser_peek_token (parser)->value); 4158 nextp = & TREE_CHAIN (*nextp); 4159 c_parser_consume_token (parser); 4160 if (c_parser_next_token_is_not (parser, CPP_COMMA)) 4161 break; 4162 c_parser_consume_token (parser); 4163 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 4164 { 4165 c_parser_error (parser, "expected identifier"); 4166 break; 4167 } 4168 } 4169 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 4170 { 4171 struct c_arg_info *ret = build_arg_info (); 4172 ret->types = list; 4173 c_parser_consume_token (parser); 4174 pop_scope (); 4175 return ret; 4176 } 4177 else 4178 { 4179 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 4180 "expected %<)%>"); 4181 pop_scope (); 4182 return NULL; 4183 } 4184 } 4185 else 4186 { 4187 struct c_arg_info *ret 4188 = c_parser_parms_list_declarator (parser, attrs, NULL, have_gnu_attrs); 4189 pop_scope (); 4190 return ret; 4191 } 4192 } 4193 4194 /* Parse a parameter list (possibly empty), including the closing 4195 parenthesis but not the opening one. ATTRS are the gnu-attributes 4196 at the start of the list; if HAVE_GNU_ATTRS, there were some such 4197 attributes (possibly empty, in which case ATTRS is NULL_TREE), 4198 which means standard attributes cannot start the list. EXPR is 4199 NULL or an expression that needs to be evaluated for the side 4200 effects of array size expressions in the parameters. */ 4201 4202 static struct c_arg_info * 4203 c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr, 4204 bool have_gnu_attrs) 4205 { 4206 bool bad_parm = false; 4207 4208 /* ??? Following the old parser, forward parameter declarations may 4209 use abstract declarators, and if no real parameter declarations 4210 follow the forward declarations then this is not diagnosed. Also 4211 note as above that gnu-attributes are ignored as the only contents of 4212 the parentheses, or as the only contents after forward 4213 declarations. */ 4214 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 4215 { 4216 struct c_arg_info *ret = build_arg_info (); 4217 c_parser_consume_token (parser); 4218 return ret; 4219 } 4220 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) 4221 { 4222 struct c_arg_info *ret = build_arg_info (); 4223 4224 if (flag_allow_parameterless_variadic_functions) 4225 { 4226 /* F (...) is allowed. */ 4227 ret->types = NULL_TREE; 4228 } 4229 else 4230 { 4231 /* Suppress -Wold-style-definition for this case. */ 4232 ret->types = error_mark_node; 4233 error_at (c_parser_peek_token (parser)->location, 4234 "ISO C requires a named argument before %<...%>"); 4235 } 4236 c_parser_consume_token (parser); 4237 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 4238 { 4239 c_parser_consume_token (parser); 4240 return ret; 4241 } 4242 else 4243 { 4244 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 4245 "expected %<)%>"); 4246 return NULL; 4247 } 4248 } 4249 /* Nonempty list of parameters, either terminated with semicolon 4250 (forward declarations; recurse) or with close parenthesis (normal 4251 function) or with ", ... )" (variadic function). */ 4252 while (true) 4253 { 4254 /* Parse a parameter. */ 4255 struct c_parm *parm = c_parser_parameter_declaration (parser, attrs, 4256 have_gnu_attrs); 4257 attrs = NULL_TREE; 4258 have_gnu_attrs = false; 4259 if (parm == NULL) 4260 bad_parm = true; 4261 else 4262 push_parm_decl (parm, &expr); 4263 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 4264 { 4265 tree new_attrs; 4266 c_parser_consume_token (parser); 4267 mark_forward_parm_decls (); 4268 bool new_have_gnu_attrs 4269 = c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE); 4270 new_attrs = c_parser_gnu_attributes (parser); 4271 return c_parser_parms_list_declarator (parser, new_attrs, expr, 4272 new_have_gnu_attrs); 4273 } 4274 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 4275 { 4276 c_parser_consume_token (parser); 4277 if (bad_parm) 4278 return NULL; 4279 else 4280 return get_parm_info (false, expr); 4281 } 4282 if (!c_parser_require (parser, CPP_COMMA, 4283 "expected %<;%>, %<,%> or %<)%>", 4284 UNKNOWN_LOCATION, false)) 4285 { 4286 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 4287 return NULL; 4288 } 4289 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) 4290 { 4291 c_parser_consume_token (parser); 4292 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 4293 { 4294 c_parser_consume_token (parser); 4295 if (bad_parm) 4296 return NULL; 4297 else 4298 return get_parm_info (true, expr); 4299 } 4300 else 4301 { 4302 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 4303 "expected %<)%>"); 4304 return NULL; 4305 } 4306 } 4307 } 4308 } 4309 4310 /* Parse a parameter declaration. ATTRS are the gnu-attributes at the 4311 start of the declaration if it is the first parameter; 4312 HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even 4313 empty) there. */ 4314 4315 static struct c_parm * 4316 c_parser_parameter_declaration (c_parser *parser, tree attrs, 4317 bool have_gnu_attrs) 4318 { 4319 struct c_declspecs *specs; 4320 struct c_declarator *declarator; 4321 tree prefix_attrs; 4322 tree postfix_attrs = NULL_TREE; 4323 bool dummy = false; 4324 4325 /* Accept #pragmas between parameter declarations. */ 4326 while (c_parser_next_token_is (parser, CPP_PRAGMA)) 4327 c_parser_pragma (parser, pragma_param, NULL); 4328 4329 if (!c_parser_next_token_starts_declspecs (parser) 4330 && !c_parser_nth_token_starts_std_attributes (parser, 1)) 4331 { 4332 c_token *token = c_parser_peek_token (parser); 4333 if (parser->error) 4334 return NULL; 4335 c_parser_set_source_position_from_token (token); 4336 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type)) 4337 { 4338 auto_diagnostic_group d; 4339 name_hint hint = lookup_name_fuzzy (token->value, 4340 FUZZY_LOOKUP_TYPENAME, 4341 token->location); 4342 if (const char *suggestion = hint.suggestion ()) 4343 { 4344 gcc_rich_location richloc (token->location); 4345 richloc.add_fixit_replace (suggestion); 4346 error_at (&richloc, 4347 "unknown type name %qE; did you mean %qs?", 4348 token->value, suggestion); 4349 } 4350 else 4351 error_at (token->location, "unknown type name %qE", token->value); 4352 parser->error = true; 4353 } 4354 /* ??? In some Objective-C cases '...' isn't applicable so there 4355 should be a different message. */ 4356 else 4357 c_parser_error (parser, 4358 "expected declaration specifiers or %<...%>"); 4359 c_parser_skip_to_end_of_parameter (parser); 4360 return NULL; 4361 } 4362 4363 location_t start_loc = c_parser_peek_token (parser)->location; 4364 4365 specs = build_null_declspecs (); 4366 if (attrs) 4367 { 4368 declspecs_add_attrs (input_location, specs, attrs); 4369 attrs = NULL_TREE; 4370 } 4371 c_parser_declspecs (parser, specs, true, true, true, true, false, 4372 !have_gnu_attrs, true, cla_nonabstract_decl); 4373 finish_declspecs (specs); 4374 pending_xref_error (); 4375 prefix_attrs = specs->attrs; 4376 specs->attrs = NULL_TREE; 4377 declarator = c_parser_declarator (parser, 4378 specs->typespec_kind != ctsk_none, 4379 C_DTR_PARM, &dummy); 4380 if (declarator == NULL) 4381 { 4382 c_parser_skip_until_found (parser, CPP_COMMA, NULL); 4383 return NULL; 4384 } 4385 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 4386 postfix_attrs = c_parser_gnu_attributes (parser); 4387 4388 /* Generate a location for the parameter, ranging from the start of the 4389 initial token to the end of the final token. 4390 4391 If we have a identifier, then use it for the caret location, e.g. 4392 4393 extern int callee (int one, int (*two)(int, int), float three); 4394 ~~~~~~^~~~~~~~~~~~~~ 4395 4396 otherwise, reuse the start location for the caret location e.g.: 4397 4398 extern int callee (int one, int (*)(int, int), float three); 4399 ^~~~~~~~~~~~~~~~~ 4400 */ 4401 location_t end_loc = parser->last_token_location; 4402 4403 /* Find any cdk_id declarator; determine if we have an identifier. */ 4404 c_declarator *id_declarator = declarator; 4405 while (id_declarator && id_declarator->kind != cdk_id) 4406 id_declarator = id_declarator->declarator; 4407 location_t caret_loc = (id_declarator->u.id.id 4408 ? id_declarator->id_loc 4409 : start_loc); 4410 location_t param_loc = make_location (caret_loc, start_loc, end_loc); 4411 4412 return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs), 4413 declarator, param_loc); 4414 } 4415 4416 /* Parse a string literal in an asm expression. It should not be 4417 translated, and wide string literals are an error although 4418 permitted by the syntax. This is a GNU extension. 4419 4420 asm-string-literal: 4421 string-literal 4422 */ 4423 4424 static tree 4425 c_parser_asm_string_literal (c_parser *parser) 4426 { 4427 tree str; 4428 int save_flag = warn_overlength_strings; 4429 warn_overlength_strings = 0; 4430 str = c_parser_string_literal (parser, false, false).value; 4431 warn_overlength_strings = save_flag; 4432 return str; 4433 } 4434 4435 /* Parse a simple asm expression. This is used in restricted 4436 contexts, where a full expression with inputs and outputs does not 4437 make sense. This is a GNU extension. 4438 4439 simple-asm-expr: 4440 asm ( asm-string-literal ) 4441 */ 4442 4443 static tree 4444 c_parser_simple_asm_expr (c_parser *parser) 4445 { 4446 tree str; 4447 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM)); 4448 c_parser_consume_token (parser); 4449 matching_parens parens; 4450 if (!parens.require_open (parser)) 4451 return NULL_TREE; 4452 str = c_parser_asm_string_literal (parser); 4453 if (!parens.require_close (parser)) 4454 { 4455 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 4456 return NULL_TREE; 4457 } 4458 return str; 4459 } 4460 4461 static tree 4462 c_parser_gnu_attribute_any_word (c_parser *parser) 4463 { 4464 tree attr_name = NULL_TREE; 4465 4466 if (c_parser_next_token_is (parser, CPP_KEYWORD)) 4467 { 4468 /* ??? See comment above about what keywords are accepted here. */ 4469 bool ok; 4470 switch (c_parser_peek_token (parser)->keyword) 4471 { 4472 case RID_STATIC: 4473 case RID_UNSIGNED: 4474 case RID_LONG: 4475 case RID_CONST: 4476 case RID_EXTERN: 4477 case RID_REGISTER: 4478 case RID_TYPEDEF: 4479 case RID_SHORT: 4480 case RID_INLINE: 4481 case RID_NORETURN: 4482 case RID_VOLATILE: 4483 case RID_SIGNED: 4484 case RID_AUTO: 4485 case RID_RESTRICT: 4486 case RID_COMPLEX: 4487 case RID_THREAD: 4488 case RID_INT: 4489 case RID_CHAR: 4490 case RID_FLOAT: 4491 case RID_DOUBLE: 4492 case RID_VOID: 4493 case RID_DFLOAT32: 4494 case RID_DFLOAT64: 4495 case RID_DFLOAT128: 4496 CASE_RID_FLOATN_NX: 4497 case RID_BOOL: 4498 case RID_FRACT: 4499 case RID_ACCUM: 4500 case RID_SAT: 4501 case RID_TRANSACTION_ATOMIC: 4502 case RID_TRANSACTION_CANCEL: 4503 case RID_ATOMIC: 4504 case RID_AUTO_TYPE: 4505 case RID_INT_N_0: 4506 case RID_INT_N_1: 4507 case RID_INT_N_2: 4508 case RID_INT_N_3: 4509 ok = true; 4510 break; 4511 default: 4512 ok = false; 4513 break; 4514 } 4515 if (!ok) 4516 return NULL_TREE; 4517 4518 /* Accept __attribute__((__const)) as __attribute__((const)) etc. */ 4519 attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword]; 4520 } 4521 else if (c_parser_next_token_is (parser, CPP_NAME)) 4522 attr_name = c_parser_peek_token (parser)->value; 4523 4524 return attr_name; 4525 } 4526 4527 /* Parse attribute arguments. This is a common form of syntax 4528 covering all currently valid GNU and standard attributes. 4529 4530 gnu-attribute-arguments: 4531 identifier 4532 identifier , nonempty-expr-list 4533 expr-list 4534 4535 where the "identifier" must not be declared as a type. ??? Why not 4536 allow identifiers declared as types to start the arguments? */ 4537 4538 static tree 4539 c_parser_attribute_arguments (c_parser *parser, bool takes_identifier, 4540 bool require_string, bool allow_empty_args) 4541 { 4542 vec<tree, va_gc> *expr_list; 4543 tree attr_args; 4544 /* Parse the attribute contents. If they start with an 4545 identifier which is followed by a comma or close 4546 parenthesis, then the arguments start with that 4547 identifier; otherwise they are an expression list. 4548 In objective-c the identifier may be a classname. */ 4549 if (c_parser_next_token_is (parser, CPP_NAME) 4550 && (c_parser_peek_token (parser)->id_kind == C_ID_ID 4551 || (c_dialect_objc () 4552 && c_parser_peek_token (parser)->id_kind 4553 == C_ID_CLASSNAME)) 4554 && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA) 4555 || (c_parser_peek_2nd_token (parser)->type 4556 == CPP_CLOSE_PAREN)) 4557 && (takes_identifier 4558 || (c_dialect_objc () 4559 && c_parser_peek_token (parser)->id_kind 4560 == C_ID_CLASSNAME))) 4561 { 4562 tree arg1 = c_parser_peek_token (parser)->value; 4563 c_parser_consume_token (parser); 4564 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 4565 attr_args = build_tree_list (NULL_TREE, arg1); 4566 else 4567 { 4568 tree tree_list; 4569 c_parser_consume_token (parser); 4570 expr_list = c_parser_expr_list (parser, false, true, 4571 NULL, NULL, NULL, NULL); 4572 tree_list = build_tree_list_vec (expr_list); 4573 attr_args = tree_cons (NULL_TREE, arg1, tree_list); 4574 release_tree_vector (expr_list); 4575 } 4576 } 4577 else 4578 { 4579 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 4580 { 4581 if (!allow_empty_args) 4582 error_at (c_parser_peek_token (parser)->location, 4583 "parentheses must be omitted if " 4584 "attribute argument list is empty"); 4585 attr_args = NULL_TREE; 4586 } 4587 else if (require_string) 4588 { 4589 /* The only valid argument for this attribute is a string 4590 literal. Handle this specially here to avoid accepting 4591 string literals with excess parentheses. */ 4592 tree string = c_parser_string_literal (parser, false, true).value; 4593 attr_args = build_tree_list (NULL_TREE, string); 4594 } 4595 else 4596 { 4597 expr_list = c_parser_expr_list (parser, false, true, 4598 NULL, NULL, NULL, NULL); 4599 attr_args = build_tree_list_vec (expr_list); 4600 release_tree_vector (expr_list); 4601 } 4602 } 4603 return attr_args; 4604 } 4605 4606 /* Parse (possibly empty) gnu-attributes. This is a GNU extension. 4607 4608 gnu-attributes: 4609 empty 4610 gnu-attributes gnu-attribute 4611 4612 gnu-attribute: 4613 __attribute__ ( ( gnu-attribute-list ) ) 4614 4615 gnu-attribute-list: 4616 gnu-attrib 4617 gnu-attribute_list , gnu-attrib 4618 4619 gnu-attrib: 4620 empty 4621 any-word 4622 any-word ( gnu-attribute-arguments ) 4623 4624 where "any-word" may be any identifier (including one declared as a 4625 type), a reserved word storage class specifier, type specifier or 4626 type qualifier. ??? This still leaves out most reserved keywords 4627 (following the old parser), shouldn't we include them? 4628 When EXPECT_COMMA is true, expect the attribute to be preceded 4629 by a comma and fail if it isn't. 4630 When EMPTY_OK is true, allow and consume any number of consecutive 4631 commas with no attributes in between. */ 4632 4633 static tree 4634 c_parser_gnu_attribute (c_parser *parser, tree attrs, 4635 bool expect_comma = false, bool empty_ok = true) 4636 { 4637 bool comma_first = c_parser_next_token_is (parser, CPP_COMMA); 4638 if (!comma_first 4639 && !c_parser_next_token_is (parser, CPP_NAME) 4640 && !c_parser_next_token_is (parser, CPP_KEYWORD)) 4641 return NULL_TREE; 4642 4643 while (c_parser_next_token_is (parser, CPP_COMMA)) 4644 { 4645 c_parser_consume_token (parser); 4646 if (!empty_ok) 4647 return attrs; 4648 } 4649 4650 tree attr_name = c_parser_gnu_attribute_any_word (parser); 4651 if (attr_name == NULL_TREE) 4652 return NULL_TREE; 4653 4654 attr_name = canonicalize_attr_name (attr_name); 4655 c_parser_consume_token (parser); 4656 4657 tree attr; 4658 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN)) 4659 { 4660 if (expect_comma && !comma_first) 4661 { 4662 /* A comma is missing between the last attribute on the chain 4663 and this one. */ 4664 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 4665 "expected %<)%>"); 4666 return error_mark_node; 4667 } 4668 attr = build_tree_list (attr_name, NULL_TREE); 4669 /* Add this attribute to the list. */ 4670 attrs = chainon (attrs, attr); 4671 return attrs; 4672 } 4673 c_parser_consume_token (parser); 4674 4675 tree attr_args 4676 = c_parser_attribute_arguments (parser, 4677 attribute_takes_identifier_p (attr_name), 4678 false, true); 4679 4680 attr = build_tree_list (attr_name, attr_args); 4681 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 4682 c_parser_consume_token (parser); 4683 else 4684 { 4685 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 4686 "expected %<)%>"); 4687 return error_mark_node; 4688 } 4689 4690 if (expect_comma && !comma_first) 4691 { 4692 /* A comma is missing between the last attribute on the chain 4693 and this one. */ 4694 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 4695 "expected %<)%>"); 4696 return error_mark_node; 4697 } 4698 4699 /* Add this attribute to the list. */ 4700 attrs = chainon (attrs, attr); 4701 return attrs; 4702 } 4703 4704 static tree 4705 c_parser_gnu_attributes (c_parser *parser) 4706 { 4707 tree attrs = NULL_TREE; 4708 while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 4709 { 4710 bool save_translate_strings_p = parser->translate_strings_p; 4711 parser->translate_strings_p = false; 4712 /* Consume the `__attribute__' keyword. */ 4713 c_parser_consume_token (parser); 4714 /* Look for the two `(' tokens. */ 4715 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 4716 { 4717 parser->translate_strings_p = save_translate_strings_p; 4718 return attrs; 4719 } 4720 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 4721 { 4722 parser->translate_strings_p = save_translate_strings_p; 4723 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 4724 return attrs; 4725 } 4726 /* Parse the attribute list. Require a comma between successive 4727 (possibly empty) attributes. */ 4728 for (bool expect_comma = false; ; expect_comma = true) 4729 { 4730 /* Parse a single attribute. */ 4731 tree attr = c_parser_gnu_attribute (parser, attrs, expect_comma); 4732 if (attr == error_mark_node) 4733 return attrs; 4734 if (!attr) 4735 break; 4736 attrs = attr; 4737 } 4738 4739 /* Look for the two `)' tokens. */ 4740 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 4741 c_parser_consume_token (parser); 4742 else 4743 { 4744 parser->translate_strings_p = save_translate_strings_p; 4745 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 4746 "expected %<)%>"); 4747 return attrs; 4748 } 4749 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 4750 c_parser_consume_token (parser); 4751 else 4752 { 4753 parser->translate_strings_p = save_translate_strings_p; 4754 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 4755 "expected %<)%>"); 4756 return attrs; 4757 } 4758 parser->translate_strings_p = save_translate_strings_p; 4759 } 4760 4761 return attrs; 4762 } 4763 4764 /* Parse an optional balanced token sequence. 4765 4766 balanced-token-sequence: 4767 balanced-token 4768 balanced-token-sequence balanced-token 4769 4770 balanced-token: 4771 ( balanced-token-sequence[opt] ) 4772 [ balanced-token-sequence[opt] ] 4773 { balanced-token-sequence[opt] } 4774 any token other than ()[]{} 4775 */ 4776 4777 static void 4778 c_parser_balanced_token_sequence (c_parser *parser) 4779 { 4780 while (true) 4781 { 4782 c_token *token = c_parser_peek_token (parser); 4783 switch (token->type) 4784 { 4785 case CPP_OPEN_BRACE: 4786 { 4787 matching_braces braces; 4788 braces.consume_open (parser); 4789 c_parser_balanced_token_sequence (parser); 4790 braces.require_close (parser); 4791 break; 4792 } 4793 4794 case CPP_OPEN_PAREN: 4795 { 4796 matching_parens parens; 4797 parens.consume_open (parser); 4798 c_parser_balanced_token_sequence (parser); 4799 parens.require_close (parser); 4800 break; 4801 } 4802 4803 case CPP_OPEN_SQUARE: 4804 c_parser_consume_token (parser); 4805 c_parser_balanced_token_sequence (parser); 4806 c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>"); 4807 break; 4808 4809 case CPP_CLOSE_BRACE: 4810 case CPP_CLOSE_PAREN: 4811 case CPP_CLOSE_SQUARE: 4812 case CPP_EOF: 4813 return; 4814 4815 case CPP_PRAGMA: 4816 c_parser_consume_pragma (parser); 4817 c_parser_skip_to_pragma_eol (parser, false); 4818 break; 4819 4820 default: 4821 c_parser_consume_token (parser); 4822 break; 4823 } 4824 } 4825 } 4826 4827 /* Parse standard (C2X) attributes (including GNU attributes in the 4828 gnu:: namespace). 4829 4830 attribute-specifier-sequence: 4831 attribute-specifier-sequence[opt] attribute-specifier 4832 4833 attribute-specifier: 4834 [ [ attribute-list ] ] 4835 4836 attribute-list: 4837 attribute[opt] 4838 attribute-list, attribute[opt] 4839 4840 attribute: 4841 attribute-token attribute-argument-clause[opt] 4842 4843 attribute-token: 4844 standard-attribute 4845 attribute-prefixed-token 4846 4847 standard-attribute: 4848 identifier 4849 4850 attribute-prefixed-token: 4851 attribute-prefix :: identifier 4852 4853 attribute-prefix: 4854 identifier 4855 4856 attribute-argument-clause: 4857 ( balanced-token-sequence[opt] ) 4858 4859 Keywords are accepted as identifiers for this purpose. 4860 */ 4861 4862 static tree 4863 c_parser_std_attribute (c_parser *parser, bool for_tm) 4864 { 4865 c_token *token = c_parser_peek_token (parser); 4866 tree ns, name, attribute; 4867 4868 /* Parse the attribute-token. */ 4869 if (token->type != CPP_NAME && token->type != CPP_KEYWORD) 4870 { 4871 c_parser_error (parser, "expected identifier"); 4872 return error_mark_node; 4873 } 4874 name = canonicalize_attr_name (token->value); 4875 c_parser_consume_token (parser); 4876 if (c_parser_next_token_is (parser, CPP_SCOPE)) 4877 { 4878 ns = name; 4879 c_parser_consume_token (parser); 4880 token = c_parser_peek_token (parser); 4881 if (token->type != CPP_NAME && token->type != CPP_KEYWORD) 4882 { 4883 c_parser_error (parser, "expected identifier"); 4884 return error_mark_node; 4885 } 4886 name = canonicalize_attr_name (token->value); 4887 c_parser_consume_token (parser); 4888 } 4889 else 4890 ns = NULL_TREE; 4891 attribute = build_tree_list (build_tree_list (ns, name), NULL_TREE); 4892 4893 /* Parse the arguments, if any. */ 4894 const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute)); 4895 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN)) 4896 goto out; 4897 { 4898 location_t open_loc = c_parser_peek_token (parser)->location; 4899 matching_parens parens; 4900 parens.consume_open (parser); 4901 if ((as && as->max_length == 0) 4902 /* Special-case the transactional-memory attribute "outer", 4903 which is specially handled but not registered as an 4904 attribute, to avoid allowing arbitrary balanced token 4905 sequences as arguments. */ 4906 || is_attribute_p ("outer", name)) 4907 { 4908 error_at (open_loc, "%qE attribute does not take any arguments", name); 4909 parens.skip_until_found_close (parser); 4910 return error_mark_node; 4911 } 4912 if (as) 4913 { 4914 bool takes_identifier 4915 = (ns != NULL_TREE 4916 && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0 4917 && attribute_takes_identifier_p (name)); 4918 bool require_string 4919 = (ns == NULL_TREE 4920 && strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0); 4921 TREE_VALUE (attribute) 4922 = c_parser_attribute_arguments (parser, takes_identifier, 4923 require_string, false); 4924 } 4925 else 4926 c_parser_balanced_token_sequence (parser); 4927 parens.require_close (parser); 4928 } 4929 out: 4930 if (ns == NULL_TREE && !for_tm && !as && !is_attribute_p ("nodiscard", name)) 4931 { 4932 /* An attribute with standard syntax and no namespace specified 4933 is a constraint violation if it is not one of the known 4934 standard attributes (of which nodiscard is the only one 4935 without a handler in GCC). Diagnose it here with a pedwarn 4936 and then discard it to prevent a duplicate warning later. */ 4937 pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored", 4938 name); 4939 return error_mark_node; 4940 } 4941 return attribute; 4942 } 4943 4944 static tree 4945 c_parser_std_attribute_specifier (c_parser *parser, bool for_tm) 4946 { 4947 bool seen_deprecated = false; 4948 bool seen_fallthrough = false; 4949 bool seen_maybe_unused = false; 4950 location_t loc = c_parser_peek_token (parser)->location; 4951 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>")) 4952 return NULL_TREE; 4953 if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>")) 4954 { 4955 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>"); 4956 return NULL_TREE; 4957 } 4958 if (!for_tm) 4959 pedwarn_c11 (loc, OPT_Wpedantic, 4960 "ISO C does not support %<[[]]%> attributes before C2X"); 4961 tree attributes = NULL_TREE; 4962 while (true) 4963 { 4964 c_token *token = c_parser_peek_token (parser); 4965 if (token->type == CPP_CLOSE_SQUARE) 4966 break; 4967 if (token->type == CPP_COMMA) 4968 { 4969 c_parser_consume_token (parser); 4970 continue; 4971 } 4972 tree attribute = c_parser_std_attribute (parser, for_tm); 4973 if (attribute != error_mark_node) 4974 { 4975 bool duplicate = false; 4976 tree name = get_attribute_name (attribute); 4977 tree ns = get_attribute_namespace (attribute); 4978 if (ns == NULL_TREE) 4979 { 4980 /* Some standard attributes may appear at most once in 4981 each attribute list. Diagnose duplicates and remove 4982 them from the list to avoid subsequent diagnostics 4983 such as the more general one for multiple 4984 "fallthrough" attributes in the same place (including 4985 in separate attribute lists in the same attribute 4986 specifier sequence, which is not a constraint 4987 violation). */ 4988 if (is_attribute_p ("deprecated", name)) 4989 { 4990 if (seen_deprecated) 4991 { 4992 error ("attribute %<deprecated%> can appear at most " 4993 "once in an attribute-list"); 4994 duplicate = true; 4995 } 4996 seen_deprecated = true; 4997 } 4998 else if (is_attribute_p ("fallthrough", name)) 4999 { 5000 if (seen_fallthrough) 5001 { 5002 error ("attribute %<fallthrough%> can appear at most " 5003 "once in an attribute-list"); 5004 duplicate = true; 5005 } 5006 seen_fallthrough = true; 5007 } 5008 else if (is_attribute_p ("maybe_unused", name)) 5009 { 5010 if (seen_maybe_unused) 5011 { 5012 error ("attribute %<maybe_unused%> can appear at most " 5013 "once in an attribute-list"); 5014 duplicate = true; 5015 } 5016 seen_maybe_unused = true; 5017 } 5018 } 5019 if (!duplicate) 5020 { 5021 TREE_CHAIN (attribute) = attributes; 5022 attributes = attribute; 5023 } 5024 } 5025 if (c_parser_next_token_is_not (parser, CPP_COMMA)) 5026 break; 5027 } 5028 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>"); 5029 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>"); 5030 return nreverse (attributes); 5031 } 5032 5033 /* Look past an optional balanced token sequence of raw look-ahead 5034 tokens starting with the *Nth token. *N is updated to point to the 5035 following token. Return true if such a sequence was found, false 5036 if the tokens parsed were not balanced. */ 5037 5038 static bool 5039 c_parser_check_balanced_raw_token_sequence (c_parser *parser, unsigned int *n) 5040 { 5041 while (true) 5042 { 5043 c_token *token = c_parser_peek_nth_token_raw (parser, *n); 5044 switch (token->type) 5045 { 5046 case CPP_OPEN_BRACE: 5047 { 5048 ++*n; 5049 if (c_parser_check_balanced_raw_token_sequence (parser, n)) 5050 { 5051 token = c_parser_peek_nth_token_raw (parser, *n); 5052 if (token->type == CPP_CLOSE_BRACE) 5053 ++*n; 5054 else 5055 return false; 5056 } 5057 else 5058 return false; 5059 break; 5060 } 5061 5062 case CPP_OPEN_PAREN: 5063 { 5064 ++*n; 5065 if (c_parser_check_balanced_raw_token_sequence (parser, n)) 5066 { 5067 token = c_parser_peek_nth_token_raw (parser, *n); 5068 if (token->type == CPP_CLOSE_PAREN) 5069 ++*n; 5070 else 5071 return false; 5072 } 5073 else 5074 return false; 5075 break; 5076 } 5077 5078 case CPP_OPEN_SQUARE: 5079 { 5080 ++*n; 5081 if (c_parser_check_balanced_raw_token_sequence (parser, n)) 5082 { 5083 token = c_parser_peek_nth_token_raw (parser, *n); 5084 if (token->type == CPP_CLOSE_SQUARE) 5085 ++*n; 5086 else 5087 return false; 5088 } 5089 else 5090 return false; 5091 break; 5092 } 5093 5094 case CPP_CLOSE_BRACE: 5095 case CPP_CLOSE_PAREN: 5096 case CPP_CLOSE_SQUARE: 5097 case CPP_EOF: 5098 return true; 5099 5100 default: 5101 ++*n; 5102 break; 5103 } 5104 } 5105 } 5106 5107 /* Return whether standard attributes start with the Nth token. */ 5108 5109 static bool 5110 c_parser_nth_token_starts_std_attributes (c_parser *parser, unsigned int n) 5111 { 5112 if (!(c_parser_peek_nth_token (parser, n)->type == CPP_OPEN_SQUARE 5113 && c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_SQUARE)) 5114 return false; 5115 /* In C, '[[' must start attributes. In Objective-C, we need to 5116 check whether '[[' is matched by ']]'. */ 5117 if (!c_dialect_objc ()) 5118 return true; 5119 n += 2; 5120 if (!c_parser_check_balanced_raw_token_sequence (parser, &n)) 5121 return false; 5122 c_token *token = c_parser_peek_nth_token_raw (parser, n); 5123 if (token->type != CPP_CLOSE_SQUARE) 5124 return false; 5125 token = c_parser_peek_nth_token_raw (parser, n + 1); 5126 return token->type == CPP_CLOSE_SQUARE; 5127 } 5128 5129 static tree 5130 c_parser_std_attribute_specifier_sequence (c_parser *parser) 5131 { 5132 tree attributes = NULL_TREE; 5133 do 5134 { 5135 tree attrs = c_parser_std_attribute_specifier (parser, false); 5136 attributes = chainon (attributes, attrs); 5137 } 5138 while (c_parser_nth_token_starts_std_attributes (parser, 1)); 5139 return attributes; 5140 } 5141 5142 /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7). ALIGNAS_OK 5143 says whether alignment specifiers are OK (only in cases that might 5144 be the type name of a compound literal). 5145 5146 type-name: 5147 specifier-qualifier-list abstract-declarator[opt] 5148 */ 5149 5150 struct c_type_name * 5151 c_parser_type_name (c_parser *parser, bool alignas_ok) 5152 { 5153 struct c_declspecs *specs = build_null_declspecs (); 5154 struct c_declarator *declarator; 5155 struct c_type_name *ret; 5156 bool dummy = false; 5157 c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false, 5158 false, true, cla_prefer_type); 5159 if (!specs->declspecs_seen_p) 5160 { 5161 c_parser_error (parser, "expected specifier-qualifier-list"); 5162 return NULL; 5163 } 5164 if (specs->type != error_mark_node) 5165 { 5166 pending_xref_error (); 5167 finish_declspecs (specs); 5168 } 5169 declarator = c_parser_declarator (parser, 5170 specs->typespec_kind != ctsk_none, 5171 C_DTR_ABSTRACT, &dummy); 5172 if (declarator == NULL) 5173 return NULL; 5174 ret = XOBNEW (&parser_obstack, struct c_type_name); 5175 ret->specs = specs; 5176 ret->declarator = declarator; 5177 return ret; 5178 } 5179 5180 /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9). 5181 5182 initializer: 5183 assignment-expression 5184 { initializer-list } 5185 { initializer-list , } 5186 5187 initializer-list: 5188 designation[opt] initializer 5189 initializer-list , designation[opt] initializer 5190 5191 designation: 5192 designator-list = 5193 5194 designator-list: 5195 designator 5196 designator-list designator 5197 5198 designator: 5199 array-designator 5200 . identifier 5201 5202 array-designator: 5203 [ constant-expression ] 5204 5205 GNU extensions: 5206 5207 initializer: 5208 { } 5209 5210 designation: 5211 array-designator 5212 identifier : 5213 5214 array-designator: 5215 [ constant-expression ... constant-expression ] 5216 5217 Any expression without commas is accepted in the syntax for the 5218 constant-expressions, with non-constant expressions rejected later. 5219 5220 This function is only used for top-level initializers; for nested 5221 ones, see c_parser_initval. */ 5222 5223 static struct c_expr 5224 c_parser_initializer (c_parser *parser) 5225 { 5226 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 5227 return c_parser_braced_init (parser, NULL_TREE, false, NULL); 5228 else 5229 { 5230 struct c_expr ret; 5231 location_t loc = c_parser_peek_token (parser)->location; 5232 ret = c_parser_expr_no_commas (parser, NULL); 5233 if (TREE_CODE (ret.value) != STRING_CST 5234 && TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR) 5235 ret = convert_lvalue_to_rvalue (loc, ret, true, true); 5236 return ret; 5237 } 5238 } 5239 5240 /* The location of the last comma within the current initializer list, 5241 or UNKNOWN_LOCATION if not within one. */ 5242 5243 location_t last_init_list_comma; 5244 5245 /* Parse a braced initializer list. TYPE is the type specified for a 5246 compound literal, and NULL_TREE for other initializers and for 5247 nested braced lists. NESTED_P is true for nested braced lists, 5248 false for the list of a compound literal or the list that is the 5249 top-level initializer in a declaration. */ 5250 5251 static struct c_expr 5252 c_parser_braced_init (c_parser *parser, tree type, bool nested_p, 5253 struct obstack *outer_obstack) 5254 { 5255 struct c_expr ret; 5256 struct obstack braced_init_obstack; 5257 location_t brace_loc = c_parser_peek_token (parser)->location; 5258 gcc_obstack_init (&braced_init_obstack); 5259 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE)); 5260 matching_braces braces; 5261 braces.consume_open (parser); 5262 if (nested_p) 5263 { 5264 finish_implicit_inits (brace_loc, outer_obstack); 5265 push_init_level (brace_loc, 0, &braced_init_obstack); 5266 } 5267 else 5268 really_start_incremental_init (type); 5269 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 5270 { 5271 pedwarn (brace_loc, OPT_Wpedantic, "ISO C forbids empty initializer braces"); 5272 } 5273 else 5274 { 5275 /* Parse a non-empty initializer list, possibly with a trailing 5276 comma. */ 5277 while (true) 5278 { 5279 c_parser_initelt (parser, &braced_init_obstack); 5280 if (parser->error) 5281 break; 5282 if (c_parser_next_token_is (parser, CPP_COMMA)) 5283 { 5284 last_init_list_comma = c_parser_peek_token (parser)->location; 5285 c_parser_consume_token (parser); 5286 } 5287 else 5288 break; 5289 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 5290 break; 5291 } 5292 } 5293 c_token *next_tok = c_parser_peek_token (parser); 5294 if (next_tok->type != CPP_CLOSE_BRACE) 5295 { 5296 ret.set_error (); 5297 ret.original_code = ERROR_MARK; 5298 ret.original_type = NULL; 5299 braces.skip_until_found_close (parser); 5300 pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma); 5301 obstack_free (&braced_init_obstack, NULL); 5302 return ret; 5303 } 5304 location_t close_loc = next_tok->location; 5305 c_parser_consume_token (parser); 5306 ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc); 5307 obstack_free (&braced_init_obstack, NULL); 5308 set_c_expr_source_range (&ret, brace_loc, close_loc); 5309 return ret; 5310 } 5311 5312 /* Parse a nested initializer, including designators. */ 5313 5314 static void 5315 c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack) 5316 { 5317 /* Parse any designator or designator list. A single array 5318 designator may have the subsequent "=" omitted in GNU C, but a 5319 longer list or a structure member designator may not. */ 5320 if (c_parser_next_token_is (parser, CPP_NAME) 5321 && c_parser_peek_2nd_token (parser)->type == CPP_COLON) 5322 { 5323 /* Old-style structure member designator. */ 5324 set_init_label (c_parser_peek_token (parser)->location, 5325 c_parser_peek_token (parser)->value, 5326 c_parser_peek_token (parser)->location, 5327 braced_init_obstack); 5328 /* Use the colon as the error location. */ 5329 pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic, 5330 "obsolete use of designated initializer with %<:%>"); 5331 c_parser_consume_token (parser); 5332 c_parser_consume_token (parser); 5333 } 5334 else 5335 { 5336 /* des_seen is 0 if there have been no designators, 1 if there 5337 has been a single array designator and 2 otherwise. */ 5338 int des_seen = 0; 5339 /* Location of a designator. */ 5340 location_t des_loc = UNKNOWN_LOCATION; /* Quiet warning. */ 5341 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE) 5342 || c_parser_next_token_is (parser, CPP_DOT)) 5343 { 5344 int des_prev = des_seen; 5345 if (!des_seen) 5346 des_loc = c_parser_peek_token (parser)->location; 5347 if (des_seen < 2) 5348 des_seen++; 5349 if (c_parser_next_token_is (parser, CPP_DOT)) 5350 { 5351 des_seen = 2; 5352 c_parser_consume_token (parser); 5353 if (c_parser_next_token_is (parser, CPP_NAME)) 5354 { 5355 set_init_label (des_loc, c_parser_peek_token (parser)->value, 5356 c_parser_peek_token (parser)->location, 5357 braced_init_obstack); 5358 c_parser_consume_token (parser); 5359 } 5360 else 5361 { 5362 struct c_expr init; 5363 init.set_error (); 5364 init.original_code = ERROR_MARK; 5365 init.original_type = NULL; 5366 c_parser_error (parser, "expected identifier"); 5367 c_parser_skip_until_found (parser, CPP_COMMA, NULL); 5368 process_init_element (input_location, init, false, 5369 braced_init_obstack); 5370 return; 5371 } 5372 } 5373 else 5374 { 5375 tree first, second; 5376 location_t ellipsis_loc = UNKNOWN_LOCATION; /* Quiet warning. */ 5377 location_t array_index_loc = UNKNOWN_LOCATION; 5378 /* ??? Following the old parser, [ objc-receiver 5379 objc-message-args ] is accepted as an initializer, 5380 being distinguished from a designator by what follows 5381 the first assignment expression inside the square 5382 brackets, but after a first array designator a 5383 subsequent square bracket is for Objective-C taken to 5384 start an expression, using the obsolete form of 5385 designated initializer without '=', rather than 5386 possibly being a second level of designation: in LALR 5387 terms, the '[' is shifted rather than reducing 5388 designator to designator-list. */ 5389 if (des_prev == 1 && c_dialect_objc ()) 5390 { 5391 des_seen = des_prev; 5392 break; 5393 } 5394 if (des_prev == 0 && c_dialect_objc ()) 5395 { 5396 /* This might be an array designator or an 5397 Objective-C message expression. If the former, 5398 continue parsing here; if the latter, parse the 5399 remainder of the initializer given the starting 5400 primary-expression. ??? It might make sense to 5401 distinguish when des_prev == 1 as well; see 5402 previous comment. */ 5403 tree rec, args; 5404 struct c_expr mexpr; 5405 c_parser_consume_token (parser); 5406 if (c_parser_peek_token (parser)->type == CPP_NAME 5407 && ((c_parser_peek_token (parser)->id_kind 5408 == C_ID_TYPENAME) 5409 || (c_parser_peek_token (parser)->id_kind 5410 == C_ID_CLASSNAME))) 5411 { 5412 /* Type name receiver. */ 5413 tree id = c_parser_peek_token (parser)->value; 5414 c_parser_consume_token (parser); 5415 rec = objc_get_class_reference (id); 5416 goto parse_message_args; 5417 } 5418 first = c_parser_expr_no_commas (parser, NULL).value; 5419 mark_exp_read (first); 5420 if (c_parser_next_token_is (parser, CPP_ELLIPSIS) 5421 || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) 5422 goto array_desig_after_first; 5423 /* Expression receiver. So far only one part 5424 without commas has been parsed; there might be 5425 more of the expression. */ 5426 rec = first; 5427 while (c_parser_next_token_is (parser, CPP_COMMA)) 5428 { 5429 struct c_expr next; 5430 location_t comma_loc, exp_loc; 5431 comma_loc = c_parser_peek_token (parser)->location; 5432 c_parser_consume_token (parser); 5433 exp_loc = c_parser_peek_token (parser)->location; 5434 next = c_parser_expr_no_commas (parser, NULL); 5435 next = convert_lvalue_to_rvalue (exp_loc, next, 5436 true, true); 5437 rec = build_compound_expr (comma_loc, rec, next.value); 5438 } 5439 parse_message_args: 5440 /* Now parse the objc-message-args. */ 5441 args = c_parser_objc_message_args (parser); 5442 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, 5443 "expected %<]%>"); 5444 mexpr.value 5445 = objc_build_message_expr (rec, args); 5446 mexpr.original_code = ERROR_MARK; 5447 mexpr.original_type = NULL; 5448 /* Now parse and process the remainder of the 5449 initializer, starting with this message 5450 expression as a primary-expression. */ 5451 c_parser_initval (parser, &mexpr, braced_init_obstack); 5452 return; 5453 } 5454 c_parser_consume_token (parser); 5455 array_index_loc = c_parser_peek_token (parser)->location; 5456 first = c_parser_expr_no_commas (parser, NULL).value; 5457 mark_exp_read (first); 5458 array_desig_after_first: 5459 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) 5460 { 5461 ellipsis_loc = c_parser_peek_token (parser)->location; 5462 c_parser_consume_token (parser); 5463 second = c_parser_expr_no_commas (parser, NULL).value; 5464 mark_exp_read (second); 5465 } 5466 else 5467 second = NULL_TREE; 5468 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) 5469 { 5470 c_parser_consume_token (parser); 5471 set_init_index (array_index_loc, first, second, 5472 braced_init_obstack); 5473 if (second) 5474 pedwarn (ellipsis_loc, OPT_Wpedantic, 5475 "ISO C forbids specifying range of elements to initialize"); 5476 } 5477 else 5478 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, 5479 "expected %<]%>"); 5480 } 5481 } 5482 if (des_seen >= 1) 5483 { 5484 if (c_parser_next_token_is (parser, CPP_EQ)) 5485 { 5486 pedwarn_c90 (des_loc, OPT_Wpedantic, 5487 "ISO C90 forbids specifying subobject " 5488 "to initialize"); 5489 c_parser_consume_token (parser); 5490 } 5491 else 5492 { 5493 if (des_seen == 1) 5494 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic, 5495 "obsolete use of designated initializer without %<=%>"); 5496 else 5497 { 5498 struct c_expr init; 5499 init.set_error (); 5500 init.original_code = ERROR_MARK; 5501 init.original_type = NULL; 5502 c_parser_error (parser, "expected %<=%>"); 5503 c_parser_skip_until_found (parser, CPP_COMMA, NULL); 5504 process_init_element (input_location, init, false, 5505 braced_init_obstack); 5506 return; 5507 } 5508 } 5509 } 5510 } 5511 c_parser_initval (parser, NULL, braced_init_obstack); 5512 } 5513 5514 /* Parse a nested initializer; as c_parser_initializer but parses 5515 initializers within braced lists, after any designators have been 5516 applied. If AFTER is not NULL then it is an Objective-C message 5517 expression which is the primary-expression starting the 5518 initializer. */ 5519 5520 static void 5521 c_parser_initval (c_parser *parser, struct c_expr *after, 5522 struct obstack * braced_init_obstack) 5523 { 5524 struct c_expr init; 5525 gcc_assert (!after || c_dialect_objc ()); 5526 location_t loc = c_parser_peek_token (parser)->location; 5527 5528 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after) 5529 init = c_parser_braced_init (parser, NULL_TREE, true, 5530 braced_init_obstack); 5531 else 5532 { 5533 init = c_parser_expr_no_commas (parser, after); 5534 if (init.value != NULL_TREE 5535 && TREE_CODE (init.value) != STRING_CST 5536 && TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR) 5537 init = convert_lvalue_to_rvalue (loc, init, true, true); 5538 } 5539 process_init_element (loc, init, false, braced_init_obstack); 5540 } 5541 5542 /* Parse a compound statement (possibly a function body) (C90 6.6.2, 5543 C99 6.8.2, C11 6.8.2). 5544 5545 compound-statement: 5546 { block-item-list[opt] } 5547 { label-declarations block-item-list } 5548 5549 block-item-list: 5550 block-item 5551 block-item-list block-item 5552 5553 block-item: 5554 nested-declaration 5555 statement 5556 5557 nested-declaration: 5558 declaration 5559 5560 GNU extensions: 5561 5562 compound-statement: 5563 { label-declarations block-item-list } 5564 5565 nested-declaration: 5566 __extension__ nested-declaration 5567 nested-function-definition 5568 5569 label-declarations: 5570 label-declaration 5571 label-declarations label-declaration 5572 5573 label-declaration: 5574 __label__ identifier-list ; 5575 5576 Allowing the mixing of declarations and code is new in C99. The 5577 GNU syntax also permits (not shown above) labels at the end of 5578 compound statements, which yield an error. We don't allow labels 5579 on declarations; this might seem like a natural extension, but 5580 there would be a conflict between gnu-attributes on the label and 5581 prefix gnu-attributes on the declaration. ??? The syntax follows the 5582 old parser in requiring something after label declarations. 5583 Although they are erroneous if the labels declared aren't defined, 5584 is it useful for the syntax to be this way? 5585 5586 OpenACC: 5587 5588 block-item: 5589 openacc-directive 5590 5591 openacc-directive: 5592 update-directive 5593 5594 OpenMP: 5595 5596 block-item: 5597 openmp-directive 5598 5599 openmp-directive: 5600 barrier-directive 5601 flush-directive 5602 taskwait-directive 5603 taskyield-directive 5604 cancel-directive 5605 cancellation-point-directive */ 5606 5607 static tree 5608 c_parser_compound_statement (c_parser *parser, location_t *endlocp) 5609 { 5610 tree stmt; 5611 location_t brace_loc; 5612 brace_loc = c_parser_peek_token (parser)->location; 5613 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) 5614 { 5615 /* Ensure a scope is entered and left anyway to avoid confusion 5616 if we have just prepared to enter a function body. */ 5617 stmt = c_begin_compound_stmt (true); 5618 c_end_compound_stmt (brace_loc, stmt, true); 5619 return error_mark_node; 5620 } 5621 stmt = c_begin_compound_stmt (true); 5622 location_t end_loc = c_parser_compound_statement_nostart (parser); 5623 if (endlocp) 5624 *endlocp = end_loc; 5625 5626 return c_end_compound_stmt (brace_loc, stmt, true); 5627 } 5628 5629 /* Parse a compound statement except for the opening brace. This is 5630 used for parsing both compound statements and statement expressions 5631 (which follow different paths to handling the opening). */ 5632 5633 static location_t 5634 c_parser_compound_statement_nostart (c_parser *parser) 5635 { 5636 bool last_stmt = false; 5637 bool last_label = false; 5638 bool save_valid_for_pragma = valid_location_for_stdc_pragma_p (); 5639 location_t label_loc = UNKNOWN_LOCATION; /* Quiet warning. */ 5640 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 5641 { 5642 location_t endloc = c_parser_peek_token (parser)->location; 5643 add_debug_begin_stmt (endloc); 5644 c_parser_consume_token (parser); 5645 return endloc; 5646 } 5647 mark_valid_location_for_stdc_pragma (true); 5648 if (c_parser_next_token_is_keyword (parser, RID_LABEL)) 5649 { 5650 /* Read zero or more forward-declarations for labels that nested 5651 functions can jump to. */ 5652 mark_valid_location_for_stdc_pragma (false); 5653 while (c_parser_next_token_is_keyword (parser, RID_LABEL)) 5654 { 5655 label_loc = c_parser_peek_token (parser)->location; 5656 c_parser_consume_token (parser); 5657 /* Any identifiers, including those declared as type names, 5658 are OK here. */ 5659 while (true) 5660 { 5661 tree label; 5662 if (c_parser_next_token_is_not (parser, CPP_NAME)) 5663 { 5664 c_parser_error (parser, "expected identifier"); 5665 break; 5666 } 5667 label 5668 = declare_label (c_parser_peek_token (parser)->value); 5669 C_DECLARED_LABEL_FLAG (label) = 1; 5670 add_stmt (build_stmt (label_loc, DECL_EXPR, label)); 5671 c_parser_consume_token (parser); 5672 if (c_parser_next_token_is (parser, CPP_COMMA)) 5673 c_parser_consume_token (parser); 5674 else 5675 break; 5676 } 5677 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 5678 } 5679 pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations"); 5680 } 5681 /* We must now have at least one statement, label or declaration. */ 5682 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 5683 { 5684 mark_valid_location_for_stdc_pragma (save_valid_for_pragma); 5685 c_parser_error (parser, "expected declaration or statement"); 5686 location_t endloc = c_parser_peek_token (parser)->location; 5687 c_parser_consume_token (parser); 5688 return endloc; 5689 } 5690 while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE)) 5691 { 5692 location_t loc = c_parser_peek_token (parser)->location; 5693 loc = expansion_point_location_if_in_system_header (loc); 5694 /* Standard attributes may start a statement or a declaration. */ 5695 bool have_std_attrs 5696 = c_parser_nth_token_starts_std_attributes (parser, 1); 5697 tree std_attrs = NULL_TREE; 5698 if (have_std_attrs) 5699 std_attrs = c_parser_std_attribute_specifier_sequence (parser); 5700 if (c_parser_next_token_is_keyword (parser, RID_CASE) 5701 || c_parser_next_token_is_keyword (parser, RID_DEFAULT) 5702 || (c_parser_next_token_is (parser, CPP_NAME) 5703 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) 5704 { 5705 c_warn_unused_attributes (std_attrs); 5706 if (c_parser_next_token_is_keyword (parser, RID_CASE)) 5707 label_loc = c_parser_peek_2nd_token (parser)->location; 5708 else 5709 label_loc = c_parser_peek_token (parser)->location; 5710 last_label = true; 5711 last_stmt = false; 5712 mark_valid_location_for_stdc_pragma (false); 5713 c_parser_label (parser); 5714 } 5715 else if (!last_label 5716 && (c_parser_next_tokens_start_declaration (parser) 5717 || (have_std_attrs 5718 && c_parser_next_token_is (parser, CPP_SEMICOLON)))) 5719 { 5720 last_label = false; 5721 mark_valid_location_for_stdc_pragma (false); 5722 bool fallthru_attr_p = false; 5723 c_parser_declaration_or_fndef (parser, true, !have_std_attrs, 5724 true, true, true, NULL, 5725 vNULL, have_std_attrs, std_attrs, 5726 NULL, &fallthru_attr_p); 5727 if (last_stmt && !fallthru_attr_p) 5728 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement, 5729 "ISO C90 forbids mixed declarations and code"); 5730 last_stmt = fallthru_attr_p; 5731 } 5732 else if (!last_label 5733 && c_parser_next_token_is_keyword (parser, RID_EXTENSION)) 5734 { 5735 /* __extension__ can start a declaration, but is also an 5736 unary operator that can start an expression. Consume all 5737 but the last of a possible series of __extension__ to 5738 determine which. If standard attributes have already 5739 been seen, it must start a statement, not a declaration, 5740 but standard attributes starting a declaration may appear 5741 after __extension__. */ 5742 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD 5743 && (c_parser_peek_2nd_token (parser)->keyword 5744 == RID_EXTENSION)) 5745 c_parser_consume_token (parser); 5746 if (!have_std_attrs 5747 && (c_token_starts_declaration (c_parser_peek_2nd_token (parser)) 5748 || c_parser_nth_token_starts_std_attributes (parser, 2))) 5749 { 5750 int ext; 5751 ext = disable_extension_diagnostics (); 5752 c_parser_consume_token (parser); 5753 last_label = false; 5754 mark_valid_location_for_stdc_pragma (false); 5755 c_parser_declaration_or_fndef (parser, true, true, true, true, 5756 true, NULL, vNULL); 5757 /* Following the old parser, __extension__ does not 5758 disable this diagnostic. */ 5759 restore_extension_diagnostics (ext); 5760 if (last_stmt) 5761 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement, 5762 "ISO C90 forbids mixed declarations and code"); 5763 last_stmt = false; 5764 } 5765 else 5766 goto statement; 5767 } 5768 else if (c_parser_next_token_is (parser, CPP_PRAGMA)) 5769 { 5770 if (have_std_attrs) 5771 c_parser_error (parser, "expected declaration or statement"); 5772 /* External pragmas, and some omp pragmas, are not associated 5773 with regular c code, and so are not to be considered statements 5774 syntactically. This ensures that the user doesn't put them 5775 places that would turn into syntax errors if the directive 5776 were ignored. */ 5777 if (c_parser_pragma (parser, 5778 last_label ? pragma_stmt : pragma_compound, 5779 NULL)) 5780 last_label = false, last_stmt = true; 5781 } 5782 else if (c_parser_next_token_is (parser, CPP_EOF)) 5783 { 5784 mark_valid_location_for_stdc_pragma (save_valid_for_pragma); 5785 c_parser_error (parser, "expected declaration or statement"); 5786 return c_parser_peek_token (parser)->location; 5787 } 5788 else if (c_parser_next_token_is_keyword (parser, RID_ELSE)) 5789 { 5790 if (parser->in_if_block) 5791 { 5792 mark_valid_location_for_stdc_pragma (save_valid_for_pragma); 5793 error_at (loc, "expected %<}%> before %<else%>"); 5794 return c_parser_peek_token (parser)->location; 5795 } 5796 else 5797 { 5798 error_at (loc, "%<else%> without a previous %<if%>"); 5799 c_parser_consume_token (parser); 5800 continue; 5801 } 5802 } 5803 else 5804 { 5805 statement: 5806 c_warn_unused_attributes (std_attrs); 5807 last_label = false; 5808 last_stmt = true; 5809 mark_valid_location_for_stdc_pragma (false); 5810 c_parser_statement_after_labels (parser, NULL); 5811 } 5812 5813 parser->error = false; 5814 } 5815 if (last_label) 5816 error_at (label_loc, "label at end of compound statement"); 5817 location_t endloc = c_parser_peek_token (parser)->location; 5818 c_parser_consume_token (parser); 5819 /* Restore the value we started with. */ 5820 mark_valid_location_for_stdc_pragma (save_valid_for_pragma); 5821 return endloc; 5822 } 5823 5824 /* Parse all consecutive labels, possibly preceded by standard 5825 attributes. In this context, a statement is required, not a 5826 declaration, so attributes must be followed by a statement that is 5827 not just a semicolon. */ 5828 5829 static void 5830 c_parser_all_labels (c_parser *parser) 5831 { 5832 if (c_parser_nth_token_starts_std_attributes (parser, 1)) 5833 { 5834 tree std_attrs = c_parser_std_attribute_specifier_sequence (parser); 5835 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 5836 c_parser_error (parser, "expected statement"); 5837 else 5838 c_warn_unused_attributes (std_attrs); 5839 } 5840 while (c_parser_next_token_is_keyword (parser, RID_CASE) 5841 || c_parser_next_token_is_keyword (parser, RID_DEFAULT) 5842 || (c_parser_next_token_is (parser, CPP_NAME) 5843 && c_parser_peek_2nd_token (parser)->type == CPP_COLON)) 5844 c_parser_label (parser); 5845 } 5846 5847 /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1). 5848 5849 label: 5850 identifier : gnu-attributes[opt] 5851 case constant-expression : 5852 default : 5853 5854 GNU extensions: 5855 5856 label: 5857 case constant-expression ... constant-expression : 5858 5859 The use of gnu-attributes on labels is a GNU extension. The syntax in 5860 GNU C accepts any expressions without commas, non-constant 5861 expressions being rejected later. Any standard 5862 attribute-specifier-sequence before the first label has been parsed 5863 in the caller, to distinguish statements from declarations. Any 5864 attribute-specifier-sequence after the label is parsed in this 5865 function. */ 5866 5867 static void 5868 c_parser_label (c_parser *parser) 5869 { 5870 location_t loc1 = c_parser_peek_token (parser)->location; 5871 tree label = NULL_TREE; 5872 5873 /* Remember whether this case or a user-defined label is allowed to fall 5874 through to. */ 5875 bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH; 5876 5877 if (c_parser_next_token_is_keyword (parser, RID_CASE)) 5878 { 5879 tree exp1, exp2; 5880 c_parser_consume_token (parser); 5881 exp1 = c_parser_expr_no_commas (parser, NULL).value; 5882 if (c_parser_next_token_is (parser, CPP_COLON)) 5883 { 5884 c_parser_consume_token (parser); 5885 label = do_case (loc1, exp1, NULL_TREE); 5886 } 5887 else if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) 5888 { 5889 c_parser_consume_token (parser); 5890 exp2 = c_parser_expr_no_commas (parser, NULL).value; 5891 if (c_parser_require (parser, CPP_COLON, "expected %<:%>")) 5892 label = do_case (loc1, exp1, exp2); 5893 } 5894 else 5895 c_parser_error (parser, "expected %<:%> or %<...%>"); 5896 } 5897 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)) 5898 { 5899 c_parser_consume_token (parser); 5900 if (c_parser_require (parser, CPP_COLON, "expected %<:%>")) 5901 label = do_case (loc1, NULL_TREE, NULL_TREE); 5902 } 5903 else 5904 { 5905 tree name = c_parser_peek_token (parser)->value; 5906 tree tlab; 5907 tree attrs; 5908 location_t loc2 = c_parser_peek_token (parser)->location; 5909 gcc_assert (c_parser_next_token_is (parser, CPP_NAME)); 5910 c_parser_consume_token (parser); 5911 gcc_assert (c_parser_next_token_is (parser, CPP_COLON)); 5912 c_parser_consume_token (parser); 5913 attrs = c_parser_gnu_attributes (parser); 5914 tlab = define_label (loc2, name); 5915 if (tlab) 5916 { 5917 decl_attributes (&tlab, attrs, 0); 5918 label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab)); 5919 } 5920 } 5921 if (label) 5922 { 5923 if (TREE_CODE (label) == LABEL_EXPR) 5924 FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p; 5925 else 5926 FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p; 5927 5928 /* Standard attributes are only allowed here if they start a 5929 statement, not a declaration (including the case of an 5930 attribute-declaration with only attributes). */ 5931 bool have_std_attrs 5932 = c_parser_nth_token_starts_std_attributes (parser, 1); 5933 tree std_attrs = NULL_TREE; 5934 if (have_std_attrs) 5935 std_attrs = c_parser_std_attribute_specifier_sequence (parser); 5936 5937 /* Allow '__attribute__((fallthrough));'. */ 5938 if (!have_std_attrs 5939 && c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 5940 { 5941 location_t loc = c_parser_peek_token (parser)->location; 5942 tree attrs = c_parser_gnu_attributes (parser); 5943 if (attribute_fallthrough_p (attrs)) 5944 { 5945 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 5946 { 5947 tree fn = build_call_expr_internal_loc (loc, 5948 IFN_FALLTHROUGH, 5949 void_type_node, 0); 5950 add_stmt (fn); 5951 } 5952 else 5953 warning_at (loc, OPT_Wattributes, "%<fallthrough%> attribute " 5954 "not followed by %<;%>"); 5955 } 5956 else if (attrs != NULL_TREE) 5957 warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>" 5958 " can be applied to a null statement"); 5959 } 5960 if (c_parser_next_tokens_start_declaration (parser) 5961 || (have_std_attrs 5962 && c_parser_next_token_is (parser, CPP_SEMICOLON))) 5963 { 5964 error_at (c_parser_peek_token (parser)->location, 5965 "a label can only be part of a statement and " 5966 "a declaration is not a statement"); 5967 c_parser_declaration_or_fndef (parser, /*fndef_ok*/ false, 5968 /*static_assert_ok*/ true, 5969 /*empty_ok*/ true, /*nested*/ true, 5970 /*start_attr_ok*/ true, NULL, 5971 vNULL, have_std_attrs, std_attrs); 5972 } 5973 else if (std_attrs) 5974 /* Nonempty attributes on the following statement are ignored. */ 5975 c_warn_unused_attributes (std_attrs); 5976 } 5977 } 5978 5979 /* Parse a statement (C90 6.6, C99 6.8, C11 6.8). 5980 5981 statement: 5982 labeled-statement 5983 attribute-specifier-sequence[opt] compound-statement 5984 expression-statement 5985 attribute-specifier-sequence[opt] selection-statement 5986 attribute-specifier-sequence[opt] iteration-statement 5987 attribute-specifier-sequence[opt] jump-statement 5988 5989 labeled-statement: 5990 attribute-specifier-sequence[opt] label statement 5991 5992 expression-statement: 5993 expression[opt] ; 5994 attribute-specifier-sequence expression ; 5995 5996 selection-statement: 5997 if-statement 5998 switch-statement 5999 6000 iteration-statement: 6001 while-statement 6002 do-statement 6003 for-statement 6004 6005 jump-statement: 6006 goto identifier ; 6007 continue ; 6008 break ; 6009 return expression[opt] ; 6010 6011 GNU extensions: 6012 6013 statement: 6014 attribute-specifier-sequence[opt] asm-statement 6015 6016 jump-statement: 6017 goto * expression ; 6018 6019 expression-statement: 6020 gnu-attributes ; 6021 6022 Objective-C: 6023 6024 statement: 6025 attribute-specifier-sequence[opt] objc-throw-statement 6026 attribute-specifier-sequence[opt] objc-try-catch-statement 6027 attribute-specifier-sequence[opt] objc-synchronized-statement 6028 6029 objc-throw-statement: 6030 @throw expression ; 6031 @throw ; 6032 6033 OpenACC: 6034 6035 statement: 6036 attribute-specifier-sequence[opt] openacc-construct 6037 6038 openacc-construct: 6039 parallel-construct 6040 kernels-construct 6041 data-construct 6042 loop-construct 6043 6044 parallel-construct: 6045 parallel-directive structured-block 6046 6047 kernels-construct: 6048 kernels-directive structured-block 6049 6050 data-construct: 6051 data-directive structured-block 6052 6053 loop-construct: 6054 loop-directive structured-block 6055 6056 OpenMP: 6057 6058 statement: 6059 attribute-specifier-sequence[opt] openmp-construct 6060 6061 openmp-construct: 6062 parallel-construct 6063 for-construct 6064 simd-construct 6065 for-simd-construct 6066 sections-construct 6067 single-construct 6068 parallel-for-construct 6069 parallel-for-simd-construct 6070 parallel-sections-construct 6071 master-construct 6072 critical-construct 6073 atomic-construct 6074 ordered-construct 6075 6076 parallel-construct: 6077 parallel-directive structured-block 6078 6079 for-construct: 6080 for-directive iteration-statement 6081 6082 simd-construct: 6083 simd-directive iteration-statements 6084 6085 for-simd-construct: 6086 for-simd-directive iteration-statements 6087 6088 sections-construct: 6089 sections-directive section-scope 6090 6091 single-construct: 6092 single-directive structured-block 6093 6094 parallel-for-construct: 6095 parallel-for-directive iteration-statement 6096 6097 parallel-for-simd-construct: 6098 parallel-for-simd-directive iteration-statement 6099 6100 parallel-sections-construct: 6101 parallel-sections-directive section-scope 6102 6103 master-construct: 6104 master-directive structured-block 6105 6106 critical-construct: 6107 critical-directive structured-block 6108 6109 atomic-construct: 6110 atomic-directive expression-statement 6111 6112 ordered-construct: 6113 ordered-directive structured-block 6114 6115 Transactional Memory: 6116 6117 statement: 6118 attribute-specifier-sequence[opt] transaction-statement 6119 attribute-specifier-sequence[opt] transaction-cancel-statement 6120 6121 IF_P is used to track whether there's a (possibly labeled) if statement 6122 which is not enclosed in braces and has an else clause. This is used to 6123 implement -Wparentheses. */ 6124 6125 static void 6126 c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels) 6127 { 6128 c_parser_all_labels (parser); 6129 if (loc_after_labels) 6130 *loc_after_labels = c_parser_peek_token (parser)->location; 6131 c_parser_statement_after_labels (parser, if_p, NULL); 6132 } 6133 6134 /* Parse a statement, other than a labeled statement. CHAIN is a vector 6135 of if-else-if conditions. All labels and standard attributes have 6136 been parsed in the caller. 6137 6138 IF_P is used to track whether there's a (possibly labeled) if statement 6139 which is not enclosed in braces and has an else clause. This is used to 6140 implement -Wparentheses. */ 6141 6142 static void 6143 c_parser_statement_after_labels (c_parser *parser, bool *if_p, 6144 vec<tree> *chain) 6145 { 6146 location_t loc = c_parser_peek_token (parser)->location; 6147 tree stmt = NULL_TREE; 6148 bool in_if_block = parser->in_if_block; 6149 parser->in_if_block = false; 6150 if (if_p != NULL) 6151 *if_p = false; 6152 6153 if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE) 6154 add_debug_begin_stmt (loc); 6155 6156 switch (c_parser_peek_token (parser)->type) 6157 { 6158 case CPP_OPEN_BRACE: 6159 add_stmt (c_parser_compound_statement (parser)); 6160 break; 6161 case CPP_KEYWORD: 6162 switch (c_parser_peek_token (parser)->keyword) 6163 { 6164 case RID_IF: 6165 c_parser_if_statement (parser, if_p, chain); 6166 break; 6167 case RID_SWITCH: 6168 c_parser_switch_statement (parser, if_p); 6169 break; 6170 case RID_WHILE: 6171 c_parser_while_statement (parser, false, 0, if_p); 6172 break; 6173 case RID_DO: 6174 c_parser_do_statement (parser, 0, false); 6175 break; 6176 case RID_FOR: 6177 c_parser_for_statement (parser, false, 0, if_p); 6178 break; 6179 case RID_GOTO: 6180 c_parser_consume_token (parser); 6181 if (c_parser_next_token_is (parser, CPP_NAME)) 6182 { 6183 stmt = c_finish_goto_label (loc, 6184 c_parser_peek_token (parser)->value); 6185 c_parser_consume_token (parser); 6186 } 6187 else if (c_parser_next_token_is (parser, CPP_MULT)) 6188 { 6189 struct c_expr val; 6190 6191 c_parser_consume_token (parser); 6192 val = c_parser_expression (parser); 6193 val = convert_lvalue_to_rvalue (loc, val, false, true); 6194 stmt = c_finish_goto_ptr (loc, val.value); 6195 } 6196 else 6197 c_parser_error (parser, "expected identifier or %<*%>"); 6198 goto expect_semicolon; 6199 case RID_CONTINUE: 6200 c_parser_consume_token (parser); 6201 stmt = c_finish_bc_stmt (loc, &c_cont_label, false); 6202 goto expect_semicolon; 6203 case RID_BREAK: 6204 c_parser_consume_token (parser); 6205 stmt = c_finish_bc_stmt (loc, &c_break_label, true); 6206 goto expect_semicolon; 6207 case RID_RETURN: 6208 c_parser_consume_token (parser); 6209 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 6210 { 6211 stmt = c_finish_return (loc, NULL_TREE, NULL_TREE); 6212 c_parser_consume_token (parser); 6213 } 6214 else 6215 { 6216 location_t xloc = c_parser_peek_token (parser)->location; 6217 struct c_expr expr = c_parser_expression_conv (parser); 6218 mark_exp_read (expr.value); 6219 stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc), 6220 expr.value, expr.original_type); 6221 goto expect_semicolon; 6222 } 6223 break; 6224 case RID_ASM: 6225 stmt = c_parser_asm_statement (parser); 6226 break; 6227 case RID_TRANSACTION_ATOMIC: 6228 case RID_TRANSACTION_RELAXED: 6229 stmt = c_parser_transaction (parser, 6230 c_parser_peek_token (parser)->keyword); 6231 break; 6232 case RID_TRANSACTION_CANCEL: 6233 stmt = c_parser_transaction_cancel (parser); 6234 goto expect_semicolon; 6235 case RID_AT_THROW: 6236 gcc_assert (c_dialect_objc ()); 6237 c_parser_consume_token (parser); 6238 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 6239 { 6240 stmt = objc_build_throw_stmt (loc, NULL_TREE); 6241 c_parser_consume_token (parser); 6242 } 6243 else 6244 { 6245 struct c_expr expr = c_parser_expression (parser); 6246 expr = convert_lvalue_to_rvalue (loc, expr, false, false); 6247 expr.value = c_fully_fold (expr.value, false, NULL); 6248 stmt = objc_build_throw_stmt (loc, expr.value); 6249 goto expect_semicolon; 6250 } 6251 break; 6252 case RID_AT_TRY: 6253 gcc_assert (c_dialect_objc ()); 6254 c_parser_objc_try_catch_finally_statement (parser); 6255 break; 6256 case RID_AT_SYNCHRONIZED: 6257 gcc_assert (c_dialect_objc ()); 6258 c_parser_objc_synchronized_statement (parser); 6259 break; 6260 case RID_ATTRIBUTE: 6261 { 6262 /* Allow '__attribute__((fallthrough));'. */ 6263 tree attrs = c_parser_gnu_attributes (parser); 6264 if (attribute_fallthrough_p (attrs)) 6265 { 6266 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 6267 { 6268 tree fn = build_call_expr_internal_loc (loc, 6269 IFN_FALLTHROUGH, 6270 void_type_node, 0); 6271 add_stmt (fn); 6272 /* Eat the ';'. */ 6273 c_parser_consume_token (parser); 6274 } 6275 else 6276 warning_at (loc, OPT_Wattributes, 6277 "%<fallthrough%> attribute not followed " 6278 "by %<;%>"); 6279 } 6280 else if (attrs != NULL_TREE) 6281 warning_at (loc, OPT_Wattributes, "only attribute %<fallthrough%>" 6282 " can be applied to a null statement"); 6283 break; 6284 } 6285 default: 6286 goto expr_stmt; 6287 } 6288 break; 6289 case CPP_SEMICOLON: 6290 c_parser_consume_token (parser); 6291 break; 6292 case CPP_CLOSE_PAREN: 6293 case CPP_CLOSE_SQUARE: 6294 /* Avoid infinite loop in error recovery: 6295 c_parser_skip_until_found stops at a closing nesting 6296 delimiter without consuming it, but here we need to consume 6297 it to proceed further. */ 6298 c_parser_error (parser, "expected statement"); 6299 c_parser_consume_token (parser); 6300 break; 6301 case CPP_PRAGMA: 6302 c_parser_pragma (parser, pragma_stmt, if_p); 6303 break; 6304 default: 6305 expr_stmt: 6306 stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value); 6307 expect_semicolon: 6308 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 6309 break; 6310 } 6311 /* Two cases cannot and do not have line numbers associated: If stmt 6312 is degenerate, such as "2;", then stmt is an INTEGER_CST, which 6313 cannot hold line numbers. But that's OK because the statement 6314 will either be changed to a MODIFY_EXPR during gimplification of 6315 the statement expr, or discarded. If stmt was compound, but 6316 without new variables, we will have skipped the creation of a 6317 BIND and will have a bare STATEMENT_LIST. But that's OK because 6318 (recursively) all of the component statements should already have 6319 line numbers assigned. ??? Can we discard no-op statements 6320 earlier? */ 6321 if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION) 6322 protected_set_expr_location (stmt, loc); 6323 6324 parser->in_if_block = in_if_block; 6325 } 6326 6327 /* Parse the condition from an if, do, while or for statements. */ 6328 6329 static tree 6330 c_parser_condition (c_parser *parser) 6331 { 6332 location_t loc = c_parser_peek_token (parser)->location; 6333 tree cond; 6334 cond = c_parser_expression_conv (parser).value; 6335 cond = c_objc_common_truthvalue_conversion (loc, cond); 6336 cond = c_fully_fold (cond, false, NULL); 6337 if (warn_sequence_point) 6338 verify_sequence_points (cond); 6339 return cond; 6340 } 6341 6342 /* Parse a parenthesized condition from an if, do or while statement. 6343 6344 condition: 6345 ( expression ) 6346 */ 6347 static tree 6348 c_parser_paren_condition (c_parser *parser) 6349 { 6350 tree cond; 6351 matching_parens parens; 6352 if (!parens.require_open (parser)) 6353 return error_mark_node; 6354 cond = c_parser_condition (parser); 6355 parens.skip_until_found_close (parser); 6356 return cond; 6357 } 6358 6359 /* Parse a statement which is a block in C99. 6360 6361 IF_P is used to track whether there's a (possibly labeled) if statement 6362 which is not enclosed in braces and has an else clause. This is used to 6363 implement -Wparentheses. */ 6364 6365 static tree 6366 c_parser_c99_block_statement (c_parser *parser, bool *if_p, 6367 location_t *loc_after_labels) 6368 { 6369 tree block = c_begin_compound_stmt (flag_isoc99); 6370 location_t loc = c_parser_peek_token (parser)->location; 6371 c_parser_statement (parser, if_p, loc_after_labels); 6372 return c_end_compound_stmt (loc, block, flag_isoc99); 6373 } 6374 6375 /* Parse the body of an if statement. This is just parsing a 6376 statement but (a) it is a block in C99, (b) we track whether the 6377 body is an if statement for the sake of -Wparentheses warnings, (c) 6378 we handle an empty body specially for the sake of -Wempty-body 6379 warnings, and (d) we call parser_compound_statement directly 6380 because c_parser_statement_after_labels resets 6381 parser->in_if_block. 6382 6383 IF_P is used to track whether there's a (possibly labeled) if statement 6384 which is not enclosed in braces and has an else clause. This is used to 6385 implement -Wparentheses. */ 6386 6387 static tree 6388 c_parser_if_body (c_parser *parser, bool *if_p, 6389 const token_indent_info &if_tinfo) 6390 { 6391 tree block = c_begin_compound_stmt (flag_isoc99); 6392 location_t body_loc = c_parser_peek_token (parser)->location; 6393 location_t body_loc_after_labels = UNKNOWN_LOCATION; 6394 token_indent_info body_tinfo 6395 = get_token_indent_info (c_parser_peek_token (parser)); 6396 6397 c_parser_all_labels (parser); 6398 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 6399 { 6400 location_t loc = c_parser_peek_token (parser)->location; 6401 add_stmt (build_empty_stmt (loc)); 6402 c_parser_consume_token (parser); 6403 if (!c_parser_next_token_is_keyword (parser, RID_ELSE)) 6404 warning_at (loc, OPT_Wempty_body, 6405 "suggest braces around empty body in an %<if%> statement"); 6406 } 6407 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 6408 add_stmt (c_parser_compound_statement (parser)); 6409 else 6410 { 6411 body_loc_after_labels = c_parser_peek_token (parser)->location; 6412 c_parser_statement_after_labels (parser, if_p); 6413 } 6414 6415 token_indent_info next_tinfo 6416 = get_token_indent_info (c_parser_peek_token (parser)); 6417 warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo); 6418 if (body_loc_after_labels != UNKNOWN_LOCATION 6419 && next_tinfo.type != CPP_SEMICOLON) 6420 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location, 6421 if_tinfo.location, RID_IF); 6422 6423 return c_end_compound_stmt (body_loc, block, flag_isoc99); 6424 } 6425 6426 /* Parse the else body of an if statement. This is just parsing a 6427 statement but (a) it is a block in C99, (b) we handle an empty body 6428 specially for the sake of -Wempty-body warnings. CHAIN is a vector 6429 of if-else-if conditions. */ 6430 6431 static tree 6432 c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo, 6433 vec<tree> *chain) 6434 { 6435 location_t body_loc = c_parser_peek_token (parser)->location; 6436 tree block = c_begin_compound_stmt (flag_isoc99); 6437 token_indent_info body_tinfo 6438 = get_token_indent_info (c_parser_peek_token (parser)); 6439 location_t body_loc_after_labels = UNKNOWN_LOCATION; 6440 6441 c_parser_all_labels (parser); 6442 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 6443 { 6444 location_t loc = c_parser_peek_token (parser)->location; 6445 warning_at (loc, 6446 OPT_Wempty_body, 6447 "suggest braces around empty body in an %<else%> statement"); 6448 add_stmt (build_empty_stmt (loc)); 6449 c_parser_consume_token (parser); 6450 } 6451 else 6452 { 6453 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 6454 body_loc_after_labels = c_parser_peek_token (parser)->location; 6455 c_parser_statement_after_labels (parser, NULL, chain); 6456 } 6457 6458 token_indent_info next_tinfo 6459 = get_token_indent_info (c_parser_peek_token (parser)); 6460 warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo); 6461 if (body_loc_after_labels != UNKNOWN_LOCATION 6462 && next_tinfo.type != CPP_SEMICOLON) 6463 warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location, 6464 else_tinfo.location, RID_ELSE); 6465 6466 return c_end_compound_stmt (body_loc, block, flag_isoc99); 6467 } 6468 6469 /* We might need to reclassify any previously-lexed identifier, e.g. 6470 when we've left a for loop with an if-statement without else in the 6471 body - we might have used a wrong scope for the token. See PR67784. */ 6472 6473 static void 6474 c_parser_maybe_reclassify_token (c_parser *parser) 6475 { 6476 if (c_parser_next_token_is (parser, CPP_NAME)) 6477 { 6478 c_token *token = c_parser_peek_token (parser); 6479 6480 if (token->id_kind != C_ID_CLASSNAME) 6481 { 6482 tree decl = lookup_name (token->value); 6483 6484 token->id_kind = C_ID_ID; 6485 if (decl) 6486 { 6487 if (TREE_CODE (decl) == TYPE_DECL) 6488 token->id_kind = C_ID_TYPENAME; 6489 } 6490 else if (c_dialect_objc ()) 6491 { 6492 tree objc_interface_decl = objc_is_class_name (token->value); 6493 /* Objective-C class names are in the same namespace as 6494 variables and typedefs, and hence are shadowed by local 6495 declarations. */ 6496 if (objc_interface_decl) 6497 { 6498 token->value = objc_interface_decl; 6499 token->id_kind = C_ID_CLASSNAME; 6500 } 6501 } 6502 } 6503 } 6504 } 6505 6506 /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4). 6507 6508 if-statement: 6509 if ( expression ) statement 6510 if ( expression ) statement else statement 6511 6512 CHAIN is a vector of if-else-if conditions. 6513 IF_P is used to track whether there's a (possibly labeled) if statement 6514 which is not enclosed in braces and has an else clause. This is used to 6515 implement -Wparentheses. */ 6516 6517 static void 6518 c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain) 6519 { 6520 tree block; 6521 location_t loc; 6522 tree cond; 6523 bool nested_if = false; 6524 tree first_body, second_body; 6525 bool in_if_block; 6526 6527 gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF)); 6528 token_indent_info if_tinfo 6529 = get_token_indent_info (c_parser_peek_token (parser)); 6530 c_parser_consume_token (parser); 6531 block = c_begin_compound_stmt (flag_isoc99); 6532 loc = c_parser_peek_token (parser)->location; 6533 cond = c_parser_paren_condition (parser); 6534 in_if_block = parser->in_if_block; 6535 parser->in_if_block = true; 6536 first_body = c_parser_if_body (parser, &nested_if, if_tinfo); 6537 parser->in_if_block = in_if_block; 6538 6539 if (warn_duplicated_cond) 6540 warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain); 6541 6542 if (c_parser_next_token_is_keyword (parser, RID_ELSE)) 6543 { 6544 token_indent_info else_tinfo 6545 = get_token_indent_info (c_parser_peek_token (parser)); 6546 c_parser_consume_token (parser); 6547 if (warn_duplicated_cond) 6548 { 6549 if (c_parser_next_token_is_keyword (parser, RID_IF) 6550 && chain == NULL) 6551 { 6552 /* We've got "if (COND) else if (COND2)". Start the 6553 condition chain and add COND as the first element. */ 6554 chain = new vec<tree> (); 6555 if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond)) 6556 chain->safe_push (cond); 6557 } 6558 else if (!c_parser_next_token_is_keyword (parser, RID_IF)) 6559 { 6560 /* This is if-else without subsequent if. Zap the condition 6561 chain; we would have already warned at this point. */ 6562 delete chain; 6563 chain = NULL; 6564 } 6565 } 6566 second_body = c_parser_else_body (parser, else_tinfo, chain); 6567 /* Set IF_P to true to indicate that this if statement has an 6568 else clause. This may trigger the Wparentheses warning 6569 below when we get back up to the parent if statement. */ 6570 if (if_p != NULL) 6571 *if_p = true; 6572 } 6573 else 6574 { 6575 second_body = NULL_TREE; 6576 6577 /* Diagnose an ambiguous else if if-then-else is nested inside 6578 if-then. */ 6579 if (nested_if) 6580 warning_at (loc, OPT_Wdangling_else, 6581 "suggest explicit braces to avoid ambiguous %<else%>"); 6582 6583 if (warn_duplicated_cond) 6584 { 6585 /* This if statement does not have an else clause. We don't 6586 need the condition chain anymore. */ 6587 delete chain; 6588 chain = NULL; 6589 } 6590 } 6591 c_finish_if_stmt (loc, cond, first_body, second_body); 6592 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99)); 6593 6594 c_parser_maybe_reclassify_token (parser); 6595 } 6596 6597 /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4). 6598 6599 switch-statement: 6600 switch (expression) statement 6601 */ 6602 6603 static void 6604 c_parser_switch_statement (c_parser *parser, bool *if_p) 6605 { 6606 struct c_expr ce; 6607 tree block, expr, body, save_break; 6608 location_t switch_loc = c_parser_peek_token (parser)->location; 6609 location_t switch_cond_loc; 6610 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH)); 6611 c_parser_consume_token (parser); 6612 block = c_begin_compound_stmt (flag_isoc99); 6613 bool explicit_cast_p = false; 6614 matching_parens parens; 6615 if (parens.require_open (parser)) 6616 { 6617 switch_cond_loc = c_parser_peek_token (parser)->location; 6618 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN) 6619 && c_token_starts_typename (c_parser_peek_2nd_token (parser))) 6620 explicit_cast_p = true; 6621 ce = c_parser_expression (parser); 6622 ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, true); 6623 expr = ce.value; 6624 /* ??? expr has no valid location? */ 6625 parens.skip_until_found_close (parser); 6626 } 6627 else 6628 { 6629 switch_cond_loc = UNKNOWN_LOCATION; 6630 expr = error_mark_node; 6631 ce.original_type = error_mark_node; 6632 } 6633 c_start_case (switch_loc, switch_cond_loc, expr, explicit_cast_p); 6634 save_break = c_break_label; 6635 c_break_label = NULL_TREE; 6636 location_t loc_after_labels; 6637 bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE; 6638 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels); 6639 location_t next_loc = c_parser_peek_token (parser)->location; 6640 if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON) 6641 warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc, 6642 RID_SWITCH); 6643 if (c_break_label) 6644 { 6645 location_t here = c_parser_peek_token (parser)->location; 6646 tree t = build1 (LABEL_EXPR, void_type_node, c_break_label); 6647 SET_EXPR_LOCATION (t, here); 6648 SWITCH_BREAK_LABEL_P (c_break_label) = 1; 6649 append_to_statement_list_force (t, &body); 6650 } 6651 c_finish_case (body, ce.original_type); 6652 c_break_label = save_break; 6653 add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99)); 6654 c_parser_maybe_reclassify_token (parser); 6655 } 6656 6657 /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5). 6658 6659 while-statement: 6660 while (expression) statement 6661 6662 IF_P is used to track whether there's a (possibly labeled) if statement 6663 which is not enclosed in braces and has an else clause. This is used to 6664 implement -Wparentheses. */ 6665 6666 static void 6667 c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll, 6668 bool *if_p) 6669 { 6670 tree block, cond, body, save_break, save_cont; 6671 location_t loc; 6672 gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE)); 6673 token_indent_info while_tinfo 6674 = get_token_indent_info (c_parser_peek_token (parser)); 6675 c_parser_consume_token (parser); 6676 block = c_begin_compound_stmt (flag_isoc99); 6677 loc = c_parser_peek_token (parser)->location; 6678 cond = c_parser_paren_condition (parser); 6679 if (ivdep && cond != error_mark_node) 6680 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, 6681 build_int_cst (integer_type_node, 6682 annot_expr_ivdep_kind), 6683 integer_zero_node); 6684 if (unroll && cond != error_mark_node) 6685 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, 6686 build_int_cst (integer_type_node, 6687 annot_expr_unroll_kind), 6688 build_int_cst (integer_type_node, unroll)); 6689 save_break = c_break_label; 6690 c_break_label = NULL_TREE; 6691 save_cont = c_cont_label; 6692 c_cont_label = NULL_TREE; 6693 6694 token_indent_info body_tinfo 6695 = get_token_indent_info (c_parser_peek_token (parser)); 6696 6697 location_t loc_after_labels; 6698 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE); 6699 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels); 6700 c_finish_loop (loc, loc, cond, UNKNOWN_LOCATION, NULL, body, 6701 c_break_label, c_cont_label, true); 6702 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99)); 6703 c_parser_maybe_reclassify_token (parser); 6704 6705 token_indent_info next_tinfo 6706 = get_token_indent_info (c_parser_peek_token (parser)); 6707 warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo); 6708 6709 if (next_tinfo.type != CPP_SEMICOLON && !open_brace) 6710 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location, 6711 while_tinfo.location, RID_WHILE); 6712 6713 c_break_label = save_break; 6714 c_cont_label = save_cont; 6715 } 6716 6717 /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5). 6718 6719 do-statement: 6720 do statement while ( expression ) ; 6721 */ 6722 6723 static void 6724 c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll) 6725 { 6726 tree block, cond, body, save_break, save_cont, new_break, new_cont; 6727 location_t loc; 6728 gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO)); 6729 c_parser_consume_token (parser); 6730 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 6731 warning_at (c_parser_peek_token (parser)->location, 6732 OPT_Wempty_body, 6733 "suggest braces around empty body in %<do%> statement"); 6734 block = c_begin_compound_stmt (flag_isoc99); 6735 loc = c_parser_peek_token (parser)->location; 6736 save_break = c_break_label; 6737 c_break_label = NULL_TREE; 6738 save_cont = c_cont_label; 6739 c_cont_label = NULL_TREE; 6740 body = c_parser_c99_block_statement (parser, NULL); 6741 c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>"); 6742 new_break = c_break_label; 6743 c_break_label = save_break; 6744 new_cont = c_cont_label; 6745 c_cont_label = save_cont; 6746 location_t cond_loc = c_parser_peek_token (parser)->location; 6747 cond = c_parser_paren_condition (parser); 6748 if (ivdep && cond != error_mark_node) 6749 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, 6750 build_int_cst (integer_type_node, 6751 annot_expr_ivdep_kind), 6752 integer_zero_node); 6753 if (unroll && cond != error_mark_node) 6754 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, 6755 build_int_cst (integer_type_node, 6756 annot_expr_unroll_kind), 6757 build_int_cst (integer_type_node, unroll)); 6758 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>")) 6759 c_parser_skip_to_end_of_block_or_statement (parser); 6760 c_finish_loop (loc, cond_loc, cond, UNKNOWN_LOCATION, NULL, body, 6761 new_break, new_cont, false); 6762 add_stmt (c_end_compound_stmt (loc, block, flag_isoc99)); 6763 } 6764 6765 /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5). 6766 6767 for-statement: 6768 for ( expression[opt] ; expression[opt] ; expression[opt] ) statement 6769 for ( nested-declaration expression[opt] ; expression[opt] ) statement 6770 6771 The form with a declaration is new in C99. 6772 6773 ??? In accordance with the old parser, the declaration may be a 6774 nested function, which is then rejected in check_for_loop_decls, 6775 but does it make any sense for this to be included in the grammar? 6776 Note in particular that the nested function does not include a 6777 trailing ';', whereas the "declaration" production includes one. 6778 Also, can we reject bad declarations earlier and cheaper than 6779 check_for_loop_decls? 6780 6781 In Objective-C, there are two additional variants: 6782 6783 foreach-statement: 6784 for ( expression in expresssion ) statement 6785 for ( declaration in expression ) statement 6786 6787 This is inconsistent with C, because the second variant is allowed 6788 even if c99 is not enabled. 6789 6790 The rest of the comment documents these Objective-C foreach-statement. 6791 6792 Here is the canonical example of the first variant: 6793 for (object in array) { do something with object } 6794 we call the first expression ("object") the "object_expression" and 6795 the second expression ("array") the "collection_expression". 6796 object_expression must be an lvalue of type "id" (a generic Objective-C 6797 object) because the loop works by assigning to object_expression the 6798 various objects from the collection_expression. collection_expression 6799 must evaluate to something of type "id" which responds to the method 6800 countByEnumeratingWithState:objects:count:. 6801 6802 The canonical example of the second variant is: 6803 for (id object in array) { do something with object } 6804 which is completely equivalent to 6805 { 6806 id object; 6807 for (object in array) { do something with object } 6808 } 6809 Note that initizializing 'object' in some way (eg, "for ((object = 6810 xxx) in array) { do something with object }") is possibly 6811 technically valid, but completely pointless as 'object' will be 6812 assigned to something else as soon as the loop starts. We should 6813 most likely reject it (TODO). 6814 6815 The beginning of the Objective-C foreach-statement looks exactly 6816 like the beginning of the for-statement, and we can tell it is a 6817 foreach-statement only because the initial declaration or 6818 expression is terminated by 'in' instead of ';'. 6819 6820 IF_P is used to track whether there's a (possibly labeled) if statement 6821 which is not enclosed in braces and has an else clause. This is used to 6822 implement -Wparentheses. */ 6823 6824 static void 6825 c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll, 6826 bool *if_p) 6827 { 6828 tree block, cond, incr, save_break, save_cont, body; 6829 /* The following are only used when parsing an ObjC foreach statement. */ 6830 tree object_expression; 6831 /* Silence the bogus uninitialized warning. */ 6832 tree collection_expression = NULL; 6833 location_t loc = c_parser_peek_token (parser)->location; 6834 location_t for_loc = loc; 6835 location_t cond_loc = UNKNOWN_LOCATION; 6836 location_t incr_loc = UNKNOWN_LOCATION; 6837 bool is_foreach_statement = false; 6838 gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR)); 6839 token_indent_info for_tinfo 6840 = get_token_indent_info (c_parser_peek_token (parser)); 6841 c_parser_consume_token (parser); 6842 /* Open a compound statement in Objective-C as well, just in case this is 6843 as foreach expression. */ 6844 block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ()); 6845 cond = error_mark_node; 6846 incr = error_mark_node; 6847 matching_parens parens; 6848 if (parens.require_open (parser)) 6849 { 6850 /* Parse the initialization declaration or expression. */ 6851 object_expression = error_mark_node; 6852 parser->objc_could_be_foreach_context = c_dialect_objc (); 6853 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 6854 { 6855 parser->objc_could_be_foreach_context = false; 6856 c_parser_consume_token (parser); 6857 c_finish_expr_stmt (loc, NULL_TREE); 6858 } 6859 else if (c_parser_next_tokens_start_declaration (parser) 6860 || c_parser_nth_token_starts_std_attributes (parser, 1)) 6861 { 6862 c_parser_declaration_or_fndef (parser, true, true, true, true, true, 6863 &object_expression, vNULL); 6864 parser->objc_could_be_foreach_context = false; 6865 6866 if (c_parser_next_token_is_keyword (parser, RID_IN)) 6867 { 6868 c_parser_consume_token (parser); 6869 is_foreach_statement = true; 6870 if (check_for_loop_decls (for_loc, true) == NULL_TREE) 6871 c_parser_error (parser, "multiple iterating variables in " 6872 "fast enumeration"); 6873 } 6874 else 6875 check_for_loop_decls (for_loc, flag_isoc99); 6876 } 6877 else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION)) 6878 { 6879 /* __extension__ can start a declaration, but is also an 6880 unary operator that can start an expression. Consume all 6881 but the last of a possible series of __extension__ to 6882 determine which. */ 6883 while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD 6884 && (c_parser_peek_2nd_token (parser)->keyword 6885 == RID_EXTENSION)) 6886 c_parser_consume_token (parser); 6887 if (c_token_starts_declaration (c_parser_peek_2nd_token (parser)) 6888 || c_parser_nth_token_starts_std_attributes (parser, 2)) 6889 { 6890 int ext; 6891 ext = disable_extension_diagnostics (); 6892 c_parser_consume_token (parser); 6893 c_parser_declaration_or_fndef (parser, true, true, true, true, 6894 true, &object_expression, vNULL); 6895 parser->objc_could_be_foreach_context = false; 6896 6897 restore_extension_diagnostics (ext); 6898 if (c_parser_next_token_is_keyword (parser, RID_IN)) 6899 { 6900 c_parser_consume_token (parser); 6901 is_foreach_statement = true; 6902 if (check_for_loop_decls (for_loc, true) == NULL_TREE) 6903 c_parser_error (parser, "multiple iterating variables in " 6904 "fast enumeration"); 6905 } 6906 else 6907 check_for_loop_decls (for_loc, flag_isoc99); 6908 } 6909 else 6910 goto init_expr; 6911 } 6912 else 6913 { 6914 init_expr: 6915 { 6916 struct c_expr ce; 6917 tree init_expression; 6918 ce = c_parser_expression (parser); 6919 init_expression = ce.value; 6920 parser->objc_could_be_foreach_context = false; 6921 if (c_parser_next_token_is_keyword (parser, RID_IN)) 6922 { 6923 c_parser_consume_token (parser); 6924 is_foreach_statement = true; 6925 if (! lvalue_p (init_expression)) 6926 c_parser_error (parser, "invalid iterating variable in " 6927 "fast enumeration"); 6928 object_expression 6929 = c_fully_fold (init_expression, false, NULL); 6930 } 6931 else 6932 { 6933 ce = convert_lvalue_to_rvalue (loc, ce, true, false); 6934 init_expression = ce.value; 6935 c_finish_expr_stmt (loc, init_expression); 6936 c_parser_skip_until_found (parser, CPP_SEMICOLON, 6937 "expected %<;%>"); 6938 } 6939 } 6940 } 6941 /* Parse the loop condition. In the case of a foreach 6942 statement, there is no loop condition. */ 6943 gcc_assert (!parser->objc_could_be_foreach_context); 6944 if (!is_foreach_statement) 6945 { 6946 cond_loc = c_parser_peek_token (parser)->location; 6947 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 6948 { 6949 if (ivdep) 6950 { 6951 c_parser_error (parser, "missing loop condition in loop " 6952 "with %<GCC ivdep%> pragma"); 6953 cond = error_mark_node; 6954 } 6955 else if (unroll) 6956 { 6957 c_parser_error (parser, "missing loop condition in loop " 6958 "with %<GCC unroll%> pragma"); 6959 cond = error_mark_node; 6960 } 6961 else 6962 { 6963 c_parser_consume_token (parser); 6964 cond = NULL_TREE; 6965 } 6966 } 6967 else 6968 { 6969 cond = c_parser_condition (parser); 6970 c_parser_skip_until_found (parser, CPP_SEMICOLON, 6971 "expected %<;%>"); 6972 } 6973 if (ivdep && cond != error_mark_node) 6974 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, 6975 build_int_cst (integer_type_node, 6976 annot_expr_ivdep_kind), 6977 integer_zero_node); 6978 if (unroll && cond != error_mark_node) 6979 cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, 6980 build_int_cst (integer_type_node, 6981 annot_expr_unroll_kind), 6982 build_int_cst (integer_type_node, unroll)); 6983 } 6984 /* Parse the increment expression (the third expression in a 6985 for-statement). In the case of a foreach-statement, this is 6986 the expression that follows the 'in'. */ 6987 loc = incr_loc = c_parser_peek_token (parser)->location; 6988 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 6989 { 6990 if (is_foreach_statement) 6991 { 6992 c_parser_error (parser, 6993 "missing collection in fast enumeration"); 6994 collection_expression = error_mark_node; 6995 } 6996 else 6997 incr = c_process_expr_stmt (loc, NULL_TREE); 6998 } 6999 else 7000 { 7001 if (is_foreach_statement) 7002 collection_expression 7003 = c_fully_fold (c_parser_expression (parser).value, false, NULL); 7004 else 7005 { 7006 struct c_expr ce = c_parser_expression (parser); 7007 ce = convert_lvalue_to_rvalue (loc, ce, true, false); 7008 incr = c_process_expr_stmt (loc, ce.value); 7009 } 7010 } 7011 parens.skip_until_found_close (parser); 7012 } 7013 save_break = c_break_label; 7014 c_break_label = NULL_TREE; 7015 save_cont = c_cont_label; 7016 c_cont_label = NULL_TREE; 7017 7018 token_indent_info body_tinfo 7019 = get_token_indent_info (c_parser_peek_token (parser)); 7020 7021 location_t loc_after_labels; 7022 bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE); 7023 body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels); 7024 7025 if (is_foreach_statement) 7026 objc_finish_foreach_loop (for_loc, object_expression, 7027 collection_expression, body, c_break_label, 7028 c_cont_label); 7029 else 7030 c_finish_loop (for_loc, cond_loc, cond, incr_loc, incr, body, 7031 c_break_label, c_cont_label, true); 7032 add_stmt (c_end_compound_stmt (for_loc, block, 7033 flag_isoc99 || c_dialect_objc ())); 7034 c_parser_maybe_reclassify_token (parser); 7035 7036 token_indent_info next_tinfo 7037 = get_token_indent_info (c_parser_peek_token (parser)); 7038 warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo); 7039 7040 if (next_tinfo.type != CPP_SEMICOLON && !open_brace) 7041 warn_for_multistatement_macros (loc_after_labels, next_tinfo.location, 7042 for_tinfo.location, RID_FOR); 7043 7044 c_break_label = save_break; 7045 c_cont_label = save_cont; 7046 } 7047 7048 /* Parse an asm statement, a GNU extension. This is a full-blown asm 7049 statement with inputs, outputs, clobbers, and volatile, inline, and goto 7050 tags allowed. 7051 7052 asm-qualifier: 7053 volatile 7054 inline 7055 goto 7056 7057 asm-qualifier-list: 7058 asm-qualifier-list asm-qualifier 7059 asm-qualifier 7060 7061 asm-statement: 7062 asm asm-qualifier-list[opt] ( asm-argument ) ; 7063 7064 asm-argument: 7065 asm-string-literal 7066 asm-string-literal : asm-operands[opt] 7067 asm-string-literal : asm-operands[opt] : asm-operands[opt] 7068 asm-string-literal : asm-operands[opt] : asm-operands[opt] \ 7069 : asm-clobbers[opt] 7070 asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \ 7071 : asm-goto-operands 7072 7073 The form with asm-goto-operands is valid if and only if the 7074 asm-qualifier-list contains goto, and is the only allowed form in that case. 7075 Duplicate asm-qualifiers are not allowed. 7076 7077 The :: token is considered equivalent to two consecutive : tokens. */ 7078 7079 static tree 7080 c_parser_asm_statement (c_parser *parser) 7081 { 7082 tree str, outputs, inputs, clobbers, labels, ret; 7083 bool simple; 7084 location_t asm_loc = c_parser_peek_token (parser)->location; 7085 int section, nsections; 7086 7087 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM)); 7088 c_parser_consume_token (parser); 7089 7090 /* Handle the asm-qualifier-list. */ 7091 location_t volatile_loc = UNKNOWN_LOCATION; 7092 location_t inline_loc = UNKNOWN_LOCATION; 7093 location_t goto_loc = UNKNOWN_LOCATION; 7094 for (;;) 7095 { 7096 c_token *token = c_parser_peek_token (parser); 7097 location_t loc = token->location; 7098 switch (token->keyword) 7099 { 7100 case RID_VOLATILE: 7101 if (volatile_loc) 7102 { 7103 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value); 7104 inform (volatile_loc, "first seen here"); 7105 } 7106 else 7107 volatile_loc = loc; 7108 c_parser_consume_token (parser); 7109 continue; 7110 7111 case RID_INLINE: 7112 if (inline_loc) 7113 { 7114 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value); 7115 inform (inline_loc, "first seen here"); 7116 } 7117 else 7118 inline_loc = loc; 7119 c_parser_consume_token (parser); 7120 continue; 7121 7122 case RID_GOTO: 7123 if (goto_loc) 7124 { 7125 error_at (loc, "duplicate %<asm%> qualifier %qE", token->value); 7126 inform (goto_loc, "first seen here"); 7127 } 7128 else 7129 goto_loc = loc; 7130 c_parser_consume_token (parser); 7131 continue; 7132 7133 case RID_CONST: 7134 case RID_RESTRICT: 7135 error_at (loc, "%qE is not a valid %<asm%> qualifier", token->value); 7136 c_parser_consume_token (parser); 7137 continue; 7138 7139 default: 7140 break; 7141 } 7142 break; 7143 } 7144 7145 bool is_volatile = (volatile_loc != UNKNOWN_LOCATION); 7146 bool is_inline = (inline_loc != UNKNOWN_LOCATION); 7147 bool is_goto = (goto_loc != UNKNOWN_LOCATION); 7148 7149 ret = NULL; 7150 7151 matching_parens parens; 7152 if (!parens.require_open (parser)) 7153 goto error; 7154 7155 str = c_parser_asm_string_literal (parser); 7156 if (str == NULL_TREE) 7157 goto error_close_paren; 7158 7159 simple = true; 7160 outputs = NULL_TREE; 7161 inputs = NULL_TREE; 7162 clobbers = NULL_TREE; 7163 labels = NULL_TREE; 7164 7165 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto) 7166 goto done_asm; 7167 7168 /* Parse each colon-delimited section of operands. */ 7169 nsections = 3 + is_goto; 7170 for (section = 0; section < nsections; ++section) 7171 { 7172 if (c_parser_next_token_is (parser, CPP_SCOPE)) 7173 { 7174 ++section; 7175 if (section == nsections) 7176 { 7177 c_parser_error (parser, "expected %<)%>"); 7178 goto error_close_paren; 7179 } 7180 c_parser_consume_token (parser); 7181 } 7182 else if (!c_parser_require (parser, CPP_COLON, 7183 is_goto 7184 ? G_("expected %<:%>") 7185 : G_("expected %<:%> or %<)%>"), 7186 UNKNOWN_LOCATION, is_goto)) 7187 goto error_close_paren; 7188 7189 /* Once past any colon, we're no longer a simple asm. */ 7190 simple = false; 7191 7192 if ((!c_parser_next_token_is (parser, CPP_COLON) 7193 && !c_parser_next_token_is (parser, CPP_SCOPE) 7194 && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 7195 || section == 3) 7196 switch (section) 7197 { 7198 case 0: 7199 /* For asm goto, we don't allow output operands, but reserve 7200 the slot for a future extension that does allow them. */ 7201 if (!is_goto) 7202 outputs = c_parser_asm_operands (parser); 7203 break; 7204 case 1: 7205 inputs = c_parser_asm_operands (parser); 7206 break; 7207 case 2: 7208 clobbers = c_parser_asm_clobbers (parser); 7209 break; 7210 case 3: 7211 labels = c_parser_asm_goto_operands (parser); 7212 break; 7213 default: 7214 gcc_unreachable (); 7215 } 7216 7217 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto) 7218 goto done_asm; 7219 } 7220 7221 done_asm: 7222 if (!parens.require_close (parser)) 7223 { 7224 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 7225 goto error; 7226 } 7227 7228 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>")) 7229 c_parser_skip_to_end_of_block_or_statement (parser); 7230 7231 ret = build_asm_stmt (is_volatile, 7232 build_asm_expr (asm_loc, str, outputs, inputs, 7233 clobbers, labels, simple, is_inline)); 7234 7235 error: 7236 return ret; 7237 7238 error_close_paren: 7239 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 7240 goto error; 7241 } 7242 7243 /* Parse asm operands, a GNU extension. 7244 7245 asm-operands: 7246 asm-operand 7247 asm-operands , asm-operand 7248 7249 asm-operand: 7250 asm-string-literal ( expression ) 7251 [ identifier ] asm-string-literal ( expression ) 7252 */ 7253 7254 static tree 7255 c_parser_asm_operands (c_parser *parser) 7256 { 7257 tree list = NULL_TREE; 7258 while (true) 7259 { 7260 tree name, str; 7261 struct c_expr expr; 7262 if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)) 7263 { 7264 c_parser_consume_token (parser); 7265 if (c_parser_next_token_is (parser, CPP_NAME)) 7266 { 7267 tree id = c_parser_peek_token (parser)->value; 7268 c_parser_consume_token (parser); 7269 name = build_string (IDENTIFIER_LENGTH (id), 7270 IDENTIFIER_POINTER (id)); 7271 } 7272 else 7273 { 7274 c_parser_error (parser, "expected identifier"); 7275 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL); 7276 return NULL_TREE; 7277 } 7278 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, 7279 "expected %<]%>"); 7280 } 7281 else 7282 name = NULL_TREE; 7283 str = c_parser_asm_string_literal (parser); 7284 if (str == NULL_TREE) 7285 return NULL_TREE; 7286 matching_parens parens; 7287 if (!parens.require_open (parser)) 7288 return NULL_TREE; 7289 expr = c_parser_expression (parser); 7290 mark_exp_read (expr.value); 7291 if (!parens.require_close (parser)) 7292 { 7293 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 7294 return NULL_TREE; 7295 } 7296 list = chainon (list, build_tree_list (build_tree_list (name, str), 7297 expr.value)); 7298 if (c_parser_next_token_is (parser, CPP_COMMA)) 7299 c_parser_consume_token (parser); 7300 else 7301 break; 7302 } 7303 return list; 7304 } 7305 7306 /* Parse asm clobbers, a GNU extension. 7307 7308 asm-clobbers: 7309 asm-string-literal 7310 asm-clobbers , asm-string-literal 7311 */ 7312 7313 static tree 7314 c_parser_asm_clobbers (c_parser *parser) 7315 { 7316 tree list = NULL_TREE; 7317 while (true) 7318 { 7319 tree str = c_parser_asm_string_literal (parser); 7320 if (str) 7321 list = tree_cons (NULL_TREE, str, list); 7322 else 7323 return NULL_TREE; 7324 if (c_parser_next_token_is (parser, CPP_COMMA)) 7325 c_parser_consume_token (parser); 7326 else 7327 break; 7328 } 7329 return list; 7330 } 7331 7332 /* Parse asm goto labels, a GNU extension. 7333 7334 asm-goto-operands: 7335 identifier 7336 asm-goto-operands , identifier 7337 */ 7338 7339 static tree 7340 c_parser_asm_goto_operands (c_parser *parser) 7341 { 7342 tree list = NULL_TREE; 7343 while (true) 7344 { 7345 tree name, label; 7346 7347 if (c_parser_next_token_is (parser, CPP_NAME)) 7348 { 7349 c_token *tok = c_parser_peek_token (parser); 7350 name = tok->value; 7351 label = lookup_label_for_goto (tok->location, name); 7352 c_parser_consume_token (parser); 7353 TREE_USED (label) = 1; 7354 } 7355 else 7356 { 7357 c_parser_error (parser, "expected identifier"); 7358 return NULL_TREE; 7359 } 7360 7361 name = build_string (IDENTIFIER_LENGTH (name), 7362 IDENTIFIER_POINTER (name)); 7363 list = tree_cons (name, label, list); 7364 if (c_parser_next_token_is (parser, CPP_COMMA)) 7365 c_parser_consume_token (parser); 7366 else 7367 return nreverse (list); 7368 } 7369 } 7370 7371 /* Parse a possibly concatenated sequence of string literals. 7372 TRANSLATE says whether to translate them to the execution character 7373 set; WIDE_OK says whether any kind of prefixed string literal is 7374 permitted in this context. This code is based on that in 7375 lex_string. */ 7376 7377 struct c_expr 7378 c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok) 7379 { 7380 struct c_expr ret; 7381 size_t count; 7382 struct obstack str_ob; 7383 struct obstack loc_ob; 7384 cpp_string str, istr, *strs; 7385 c_token *tok; 7386 location_t loc, last_tok_loc; 7387 enum cpp_ttype type; 7388 tree value, string_tree; 7389 7390 tok = c_parser_peek_token (parser); 7391 loc = tok->location; 7392 last_tok_loc = linemap_resolve_location (line_table, loc, 7393 LRK_MACRO_DEFINITION_LOCATION, 7394 NULL); 7395 type = tok->type; 7396 switch (type) 7397 { 7398 case CPP_STRING: 7399 case CPP_WSTRING: 7400 case CPP_STRING16: 7401 case CPP_STRING32: 7402 case CPP_UTF8STRING: 7403 string_tree = tok->value; 7404 break; 7405 7406 default: 7407 c_parser_error (parser, "expected string literal"); 7408 ret.set_error (); 7409 ret.value = NULL_TREE; 7410 ret.original_code = ERROR_MARK; 7411 ret.original_type = NULL_TREE; 7412 return ret; 7413 } 7414 7415 /* Try to avoid the overhead of creating and destroying an obstack 7416 for the common case of just one string. */ 7417 switch (c_parser_peek_2nd_token (parser)->type) 7418 { 7419 default: 7420 c_parser_consume_token (parser); 7421 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree); 7422 str.len = TREE_STRING_LENGTH (string_tree); 7423 count = 1; 7424 strs = &str; 7425 break; 7426 7427 case CPP_STRING: 7428 case CPP_WSTRING: 7429 case CPP_STRING16: 7430 case CPP_STRING32: 7431 case CPP_UTF8STRING: 7432 gcc_obstack_init (&str_ob); 7433 gcc_obstack_init (&loc_ob); 7434 count = 0; 7435 do 7436 { 7437 c_parser_consume_token (parser); 7438 count++; 7439 str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree); 7440 str.len = TREE_STRING_LENGTH (string_tree); 7441 if (type != tok->type) 7442 { 7443 if (type == CPP_STRING) 7444 type = tok->type; 7445 else if (tok->type != CPP_STRING) 7446 error ("unsupported non-standard concatenation " 7447 "of string literals"); 7448 } 7449 obstack_grow (&str_ob, &str, sizeof (cpp_string)); 7450 obstack_grow (&loc_ob, &last_tok_loc, sizeof (location_t)); 7451 tok = c_parser_peek_token (parser); 7452 string_tree = tok->value; 7453 last_tok_loc 7454 = linemap_resolve_location (line_table, tok->location, 7455 LRK_MACRO_DEFINITION_LOCATION, NULL); 7456 } 7457 while (tok->type == CPP_STRING 7458 || tok->type == CPP_WSTRING 7459 || tok->type == CPP_STRING16 7460 || tok->type == CPP_STRING32 7461 || tok->type == CPP_UTF8STRING); 7462 strs = (cpp_string *) obstack_finish (&str_ob); 7463 } 7464 7465 if (count > 1 && !in_system_header_at (input_location)) 7466 warning (OPT_Wtraditional, 7467 "traditional C rejects string constant concatenation"); 7468 7469 if ((type == CPP_STRING || wide_ok) 7470 && ((translate 7471 ? cpp_interpret_string : cpp_interpret_string_notranslate) 7472 (parse_in, strs, count, &istr, type))) 7473 { 7474 value = build_string (istr.len, (const char *) istr.text); 7475 free (CONST_CAST (unsigned char *, istr.text)); 7476 if (count > 1) 7477 { 7478 location_t *locs = (location_t *) obstack_finish (&loc_ob); 7479 gcc_assert (g_string_concat_db); 7480 g_string_concat_db->record_string_concatenation (count, locs); 7481 } 7482 } 7483 else 7484 { 7485 if (type != CPP_STRING && !wide_ok) 7486 { 7487 error_at (loc, "a wide string is invalid in this context"); 7488 type = CPP_STRING; 7489 } 7490 /* Callers cannot generally handle error_mark_node in this 7491 context, so return the empty string instead. An error has 7492 been issued, either above or from cpp_interpret_string. */ 7493 switch (type) 7494 { 7495 default: 7496 case CPP_STRING: 7497 case CPP_UTF8STRING: 7498 value = build_string (1, ""); 7499 break; 7500 case CPP_STRING16: 7501 value = build_string (TYPE_PRECISION (char16_type_node) 7502 / TYPE_PRECISION (char_type_node), 7503 "\0"); /* char16_t is 16 bits */ 7504 break; 7505 case CPP_STRING32: 7506 value = build_string (TYPE_PRECISION (char32_type_node) 7507 / TYPE_PRECISION (char_type_node), 7508 "\0\0\0"); /* char32_t is 32 bits */ 7509 break; 7510 case CPP_WSTRING: 7511 value = build_string (TYPE_PRECISION (wchar_type_node) 7512 / TYPE_PRECISION (char_type_node), 7513 "\0\0\0"); /* widest supported wchar_t 7514 is 32 bits */ 7515 break; 7516 } 7517 } 7518 7519 switch (type) 7520 { 7521 default: 7522 case CPP_STRING: 7523 case CPP_UTF8STRING: 7524 TREE_TYPE (value) = char_array_type_node; 7525 break; 7526 case CPP_STRING16: 7527 TREE_TYPE (value) = char16_array_type_node; 7528 break; 7529 case CPP_STRING32: 7530 TREE_TYPE (value) = char32_array_type_node; 7531 break; 7532 case CPP_WSTRING: 7533 TREE_TYPE (value) = wchar_array_type_node; 7534 } 7535 value = fix_string_type (value); 7536 7537 if (count > 1) 7538 { 7539 obstack_free (&str_ob, 0); 7540 obstack_free (&loc_ob, 0); 7541 } 7542 7543 ret.value = value; 7544 ret.original_code = STRING_CST; 7545 ret.original_type = NULL_TREE; 7546 set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc)); 7547 return ret; 7548 } 7549 7550 /* Parse an expression other than a compound expression; that is, an 7551 assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16). If 7552 AFTER is not NULL then it is an Objective-C message expression which 7553 is the primary-expression starting the expression as an initializer. 7554 7555 assignment-expression: 7556 conditional-expression 7557 unary-expression assignment-operator assignment-expression 7558 7559 assignment-operator: one of 7560 = *= /= %= += -= <<= >>= &= ^= |= 7561 7562 In GNU C we accept any conditional expression on the LHS and 7563 diagnose the invalid lvalue rather than producing a syntax 7564 error. */ 7565 7566 static struct c_expr 7567 c_parser_expr_no_commas (c_parser *parser, struct c_expr *after, 7568 tree omp_atomic_lhs) 7569 { 7570 struct c_expr lhs, rhs, ret; 7571 enum tree_code code; 7572 location_t op_location, exp_location; 7573 gcc_assert (!after || c_dialect_objc ()); 7574 lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs); 7575 op_location = c_parser_peek_token (parser)->location; 7576 switch (c_parser_peek_token (parser)->type) 7577 { 7578 case CPP_EQ: 7579 code = NOP_EXPR; 7580 break; 7581 case CPP_MULT_EQ: 7582 code = MULT_EXPR; 7583 break; 7584 case CPP_DIV_EQ: 7585 code = TRUNC_DIV_EXPR; 7586 break; 7587 case CPP_MOD_EQ: 7588 code = TRUNC_MOD_EXPR; 7589 break; 7590 case CPP_PLUS_EQ: 7591 code = PLUS_EXPR; 7592 break; 7593 case CPP_MINUS_EQ: 7594 code = MINUS_EXPR; 7595 break; 7596 case CPP_LSHIFT_EQ: 7597 code = LSHIFT_EXPR; 7598 break; 7599 case CPP_RSHIFT_EQ: 7600 code = RSHIFT_EXPR; 7601 break; 7602 case CPP_AND_EQ: 7603 code = BIT_AND_EXPR; 7604 break; 7605 case CPP_XOR_EQ: 7606 code = BIT_XOR_EXPR; 7607 break; 7608 case CPP_OR_EQ: 7609 code = BIT_IOR_EXPR; 7610 break; 7611 default: 7612 return lhs; 7613 } 7614 c_parser_consume_token (parser); 7615 exp_location = c_parser_peek_token (parser)->location; 7616 rhs = c_parser_expr_no_commas (parser, NULL); 7617 rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true); 7618 7619 ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type, 7620 code, exp_location, rhs.value, 7621 rhs.original_type); 7622 set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ()); 7623 if (code == NOP_EXPR) 7624 ret.original_code = MODIFY_EXPR; 7625 else 7626 { 7627 TREE_NO_WARNING (ret.value) = 1; 7628 ret.original_code = ERROR_MARK; 7629 } 7630 ret.original_type = NULL; 7631 return ret; 7632 } 7633 7634 /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15). If 7635 AFTER is not NULL then it is an Objective-C message expression which is 7636 the primary-expression starting the expression as an initializer. 7637 7638 conditional-expression: 7639 logical-OR-expression 7640 logical-OR-expression ? expression : conditional-expression 7641 7642 GNU extensions: 7643 7644 conditional-expression: 7645 logical-OR-expression ? : conditional-expression 7646 */ 7647 7648 static struct c_expr 7649 c_parser_conditional_expression (c_parser *parser, struct c_expr *after, 7650 tree omp_atomic_lhs) 7651 { 7652 struct c_expr cond, exp1, exp2, ret; 7653 location_t start, cond_loc, colon_loc; 7654 7655 gcc_assert (!after || c_dialect_objc ()); 7656 7657 cond = c_parser_binary_expression (parser, after, omp_atomic_lhs); 7658 7659 if (c_parser_next_token_is_not (parser, CPP_QUERY)) 7660 return cond; 7661 if (cond.value != error_mark_node) 7662 start = cond.get_start (); 7663 else 7664 start = UNKNOWN_LOCATION; 7665 cond_loc = c_parser_peek_token (parser)->location; 7666 cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true); 7667 c_parser_consume_token (parser); 7668 if (c_parser_next_token_is (parser, CPP_COLON)) 7669 { 7670 tree eptype = NULL_TREE; 7671 7672 location_t middle_loc = c_parser_peek_token (parser)->location; 7673 pedwarn (middle_loc, OPT_Wpedantic, 7674 "ISO C forbids omitting the middle term of a %<?:%> expression"); 7675 if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR) 7676 { 7677 eptype = TREE_TYPE (cond.value); 7678 cond.value = TREE_OPERAND (cond.value, 0); 7679 } 7680 tree e = cond.value; 7681 while (TREE_CODE (e) == COMPOUND_EXPR) 7682 e = TREE_OPERAND (e, 1); 7683 warn_for_omitted_condop (middle_loc, e); 7684 /* Make sure first operand is calculated only once. */ 7685 exp1.value = save_expr (default_conversion (cond.value)); 7686 if (eptype) 7687 exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value); 7688 exp1.original_type = NULL; 7689 exp1.src_range = cond.src_range; 7690 cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value); 7691 c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node; 7692 } 7693 else 7694 { 7695 cond.value 7696 = c_objc_common_truthvalue_conversion 7697 (cond_loc, default_conversion (cond.value)); 7698 c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node; 7699 exp1 = c_parser_expression_conv (parser); 7700 mark_exp_read (exp1.value); 7701 c_inhibit_evaluation_warnings += 7702 ((cond.value == truthvalue_true_node) 7703 - (cond.value == truthvalue_false_node)); 7704 } 7705 7706 colon_loc = c_parser_peek_token (parser)->location; 7707 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 7708 { 7709 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node; 7710 ret.set_error (); 7711 ret.original_code = ERROR_MARK; 7712 ret.original_type = NULL; 7713 return ret; 7714 } 7715 { 7716 location_t exp2_loc = c_parser_peek_token (parser)->location; 7717 exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE); 7718 exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true); 7719 } 7720 c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node; 7721 location_t loc1 = make_location (exp1.get_start (), exp1.src_range); 7722 location_t loc2 = make_location (exp2.get_start (), exp2.src_range); 7723 ret.value = build_conditional_expr (colon_loc, cond.value, 7724 cond.original_code == C_MAYBE_CONST_EXPR, 7725 exp1.value, exp1.original_type, loc1, 7726 exp2.value, exp2.original_type, loc2); 7727 ret.original_code = ERROR_MARK; 7728 if (exp1.value == error_mark_node || exp2.value == error_mark_node) 7729 ret.original_type = NULL; 7730 else 7731 { 7732 tree t1, t2; 7733 7734 /* If both sides are enum type, the default conversion will have 7735 made the type of the result be an integer type. We want to 7736 remember the enum types we started with. */ 7737 t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value); 7738 t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value); 7739 ret.original_type = ((t1 != error_mark_node 7740 && t2 != error_mark_node 7741 && (TYPE_MAIN_VARIANT (t1) 7742 == TYPE_MAIN_VARIANT (t2))) 7743 ? t1 7744 : NULL); 7745 } 7746 set_c_expr_source_range (&ret, start, exp2.get_finish ()); 7747 return ret; 7748 } 7749 7750 /* Parse a binary expression; that is, a logical-OR-expression (C90 7751 6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14). If AFTER is not 7752 NULL then it is an Objective-C message expression which is the 7753 primary-expression starting the expression as an initializer. 7754 7755 OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic, 7756 when it should be the unfolded lhs. In a valid OpenMP source, 7757 one of the operands of the toplevel binary expression must be equal 7758 to it. In that case, just return a build2 created binary operation 7759 rather than result of parser_build_binary_op. 7760 7761 multiplicative-expression: 7762 cast-expression 7763 multiplicative-expression * cast-expression 7764 multiplicative-expression / cast-expression 7765 multiplicative-expression % cast-expression 7766 7767 additive-expression: 7768 multiplicative-expression 7769 additive-expression + multiplicative-expression 7770 additive-expression - multiplicative-expression 7771 7772 shift-expression: 7773 additive-expression 7774 shift-expression << additive-expression 7775 shift-expression >> additive-expression 7776 7777 relational-expression: 7778 shift-expression 7779 relational-expression < shift-expression 7780 relational-expression > shift-expression 7781 relational-expression <= shift-expression 7782 relational-expression >= shift-expression 7783 7784 equality-expression: 7785 relational-expression 7786 equality-expression == relational-expression 7787 equality-expression != relational-expression 7788 7789 AND-expression: 7790 equality-expression 7791 AND-expression & equality-expression 7792 7793 exclusive-OR-expression: 7794 AND-expression 7795 exclusive-OR-expression ^ AND-expression 7796 7797 inclusive-OR-expression: 7798 exclusive-OR-expression 7799 inclusive-OR-expression | exclusive-OR-expression 7800 7801 logical-AND-expression: 7802 inclusive-OR-expression 7803 logical-AND-expression && inclusive-OR-expression 7804 7805 logical-OR-expression: 7806 logical-AND-expression 7807 logical-OR-expression || logical-AND-expression 7808 */ 7809 7810 static struct c_expr 7811 c_parser_binary_expression (c_parser *parser, struct c_expr *after, 7812 tree omp_atomic_lhs) 7813 { 7814 /* A binary expression is parsed using operator-precedence parsing, 7815 with the operands being cast expressions. All the binary 7816 operators are left-associative. Thus a binary expression is of 7817 form: 7818 7819 E0 op1 E1 op2 E2 ... 7820 7821 which we represent on a stack. On the stack, the precedence 7822 levels are strictly increasing. When a new operator is 7823 encountered of higher precedence than that at the top of the 7824 stack, it is pushed; its LHS is the top expression, and its RHS 7825 is everything parsed until it is popped. When a new operator is 7826 encountered with precedence less than or equal to that at the top 7827 of the stack, triples E[i-1] op[i] E[i] are popped and replaced 7828 by the result of the operation until the operator at the top of 7829 the stack has lower precedence than the new operator or there is 7830 only one element on the stack; then the top expression is the LHS 7831 of the new operator. In the case of logical AND and OR 7832 expressions, we also need to adjust c_inhibit_evaluation_warnings 7833 as appropriate when the operators are pushed and popped. */ 7834 7835 struct { 7836 /* The expression at this stack level. */ 7837 struct c_expr expr; 7838 /* The precedence of the operator on its left, PREC_NONE at the 7839 bottom of the stack. */ 7840 enum c_parser_prec prec; 7841 /* The operation on its left. */ 7842 enum tree_code op; 7843 /* The source location of this operation. */ 7844 location_t loc; 7845 /* The sizeof argument if expr.original_code == SIZEOF_EXPR. */ 7846 tree sizeof_arg; 7847 } stack[NUM_PRECS]; 7848 int sp; 7849 /* Location of the binary operator. */ 7850 location_t binary_loc = UNKNOWN_LOCATION; /* Quiet warning. */ 7851 #define POP \ 7852 do { \ 7853 switch (stack[sp].op) \ 7854 { \ 7855 case TRUTH_ANDIF_EXPR: \ 7856 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \ 7857 == truthvalue_false_node); \ 7858 break; \ 7859 case TRUTH_ORIF_EXPR: \ 7860 c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value \ 7861 == truthvalue_true_node); \ 7862 break; \ 7863 case TRUNC_DIV_EXPR: \ 7864 if (stack[sp - 1].expr.original_code == SIZEOF_EXPR \ 7865 && stack[sp].expr.original_code == SIZEOF_EXPR) \ 7866 { \ 7867 tree type0 = stack[sp - 1].sizeof_arg; \ 7868 tree type1 = stack[sp].sizeof_arg; \ 7869 tree first_arg = type0; \ 7870 if (!TYPE_P (type0)) \ 7871 type0 = TREE_TYPE (type0); \ 7872 if (!TYPE_P (type1)) \ 7873 type1 = TREE_TYPE (type1); \ 7874 if (POINTER_TYPE_P (type0) \ 7875 && comptypes (TREE_TYPE (type0), type1) \ 7876 && !(TREE_CODE (first_arg) == PARM_DECL \ 7877 && C_ARRAY_PARAMETER (first_arg) \ 7878 && warn_sizeof_array_argument)) \ 7879 { \ 7880 auto_diagnostic_group d; \ 7881 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div, \ 7882 "division %<sizeof (%T) / sizeof (%T)%> " \ 7883 "does not compute the number of array " \ 7884 "elements", \ 7885 type0, type1)) \ 7886 if (DECL_P (first_arg)) \ 7887 inform (DECL_SOURCE_LOCATION (first_arg), \ 7888 "first %<sizeof%> operand was declared here"); \ 7889 } \ 7890 } \ 7891 break; \ 7892 default: \ 7893 break; \ 7894 } \ 7895 stack[sp - 1].expr \ 7896 = convert_lvalue_to_rvalue (stack[sp - 1].loc, \ 7897 stack[sp - 1].expr, true, true); \ 7898 stack[sp].expr \ 7899 = convert_lvalue_to_rvalue (stack[sp].loc, \ 7900 stack[sp].expr, true, true); \ 7901 if (__builtin_expect (omp_atomic_lhs != NULL_TREE, 0) && sp == 1 \ 7902 && c_parser_peek_token (parser)->type == CPP_SEMICOLON \ 7903 && ((1 << stack[sp].prec) \ 7904 & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) | (1 << PREC_BITAND) \ 7905 | (1 << PREC_SHIFT) | (1 << PREC_ADD) | (1 << PREC_MULT))) \ 7906 && stack[sp].op != TRUNC_MOD_EXPR \ 7907 && stack[0].expr.value != error_mark_node \ 7908 && stack[1].expr.value != error_mark_node \ 7909 && (c_tree_equal (stack[0].expr.value, omp_atomic_lhs) \ 7910 || c_tree_equal (stack[1].expr.value, omp_atomic_lhs))) \ 7911 { \ 7912 tree t = make_node (stack[1].op); \ 7913 TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value); \ 7914 TREE_OPERAND (t, 0) = stack[0].expr.value; \ 7915 TREE_OPERAND (t, 1) = stack[1].expr.value; \ 7916 stack[0].expr.value = t; \ 7917 } \ 7918 else \ 7919 stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc, \ 7920 stack[sp].op, \ 7921 stack[sp - 1].expr, \ 7922 stack[sp].expr); \ 7923 sp--; \ 7924 } while (0) 7925 gcc_assert (!after || c_dialect_objc ()); 7926 stack[0].loc = c_parser_peek_token (parser)->location; 7927 stack[0].expr = c_parser_cast_expression (parser, after); 7928 stack[0].prec = PREC_NONE; 7929 stack[0].sizeof_arg = c_last_sizeof_arg; 7930 sp = 0; 7931 while (true) 7932 { 7933 enum c_parser_prec oprec; 7934 enum tree_code ocode; 7935 source_range src_range; 7936 if (parser->error) 7937 goto out; 7938 switch (c_parser_peek_token (parser)->type) 7939 { 7940 case CPP_MULT: 7941 oprec = PREC_MULT; 7942 ocode = MULT_EXPR; 7943 break; 7944 case CPP_DIV: 7945 oprec = PREC_MULT; 7946 ocode = TRUNC_DIV_EXPR; 7947 break; 7948 case CPP_MOD: 7949 oprec = PREC_MULT; 7950 ocode = TRUNC_MOD_EXPR; 7951 break; 7952 case CPP_PLUS: 7953 oprec = PREC_ADD; 7954 ocode = PLUS_EXPR; 7955 break; 7956 case CPP_MINUS: 7957 oprec = PREC_ADD; 7958 ocode = MINUS_EXPR; 7959 break; 7960 case CPP_LSHIFT: 7961 oprec = PREC_SHIFT; 7962 ocode = LSHIFT_EXPR; 7963 break; 7964 case CPP_RSHIFT: 7965 oprec = PREC_SHIFT; 7966 ocode = RSHIFT_EXPR; 7967 break; 7968 case CPP_LESS: 7969 oprec = PREC_REL; 7970 ocode = LT_EXPR; 7971 break; 7972 case CPP_GREATER: 7973 oprec = PREC_REL; 7974 ocode = GT_EXPR; 7975 break; 7976 case CPP_LESS_EQ: 7977 oprec = PREC_REL; 7978 ocode = LE_EXPR; 7979 break; 7980 case CPP_GREATER_EQ: 7981 oprec = PREC_REL; 7982 ocode = GE_EXPR; 7983 break; 7984 case CPP_EQ_EQ: 7985 oprec = PREC_EQ; 7986 ocode = EQ_EXPR; 7987 break; 7988 case CPP_NOT_EQ: 7989 oprec = PREC_EQ; 7990 ocode = NE_EXPR; 7991 break; 7992 case CPP_AND: 7993 oprec = PREC_BITAND; 7994 ocode = BIT_AND_EXPR; 7995 break; 7996 case CPP_XOR: 7997 oprec = PREC_BITXOR; 7998 ocode = BIT_XOR_EXPR; 7999 break; 8000 case CPP_OR: 8001 oprec = PREC_BITOR; 8002 ocode = BIT_IOR_EXPR; 8003 break; 8004 case CPP_AND_AND: 8005 oprec = PREC_LOGAND; 8006 ocode = TRUTH_ANDIF_EXPR; 8007 break; 8008 case CPP_OR_OR: 8009 oprec = PREC_LOGOR; 8010 ocode = TRUTH_ORIF_EXPR; 8011 break; 8012 default: 8013 /* Not a binary operator, so end of the binary 8014 expression. */ 8015 goto out; 8016 } 8017 binary_loc = c_parser_peek_token (parser)->location; 8018 while (oprec <= stack[sp].prec) 8019 POP; 8020 c_parser_consume_token (parser); 8021 switch (ocode) 8022 { 8023 case TRUTH_ANDIF_EXPR: 8024 src_range = stack[sp].expr.src_range; 8025 stack[sp].expr 8026 = convert_lvalue_to_rvalue (stack[sp].loc, 8027 stack[sp].expr, true, true); 8028 stack[sp].expr.value = c_objc_common_truthvalue_conversion 8029 (stack[sp].loc, default_conversion (stack[sp].expr.value)); 8030 c_inhibit_evaluation_warnings += (stack[sp].expr.value 8031 == truthvalue_false_node); 8032 set_c_expr_source_range (&stack[sp].expr, src_range); 8033 break; 8034 case TRUTH_ORIF_EXPR: 8035 src_range = stack[sp].expr.src_range; 8036 stack[sp].expr 8037 = convert_lvalue_to_rvalue (stack[sp].loc, 8038 stack[sp].expr, true, true); 8039 stack[sp].expr.value = c_objc_common_truthvalue_conversion 8040 (stack[sp].loc, default_conversion (stack[sp].expr.value)); 8041 c_inhibit_evaluation_warnings += (stack[sp].expr.value 8042 == truthvalue_true_node); 8043 set_c_expr_source_range (&stack[sp].expr, src_range); 8044 break; 8045 default: 8046 break; 8047 } 8048 sp++; 8049 stack[sp].loc = binary_loc; 8050 stack[sp].expr = c_parser_cast_expression (parser, NULL); 8051 stack[sp].prec = oprec; 8052 stack[sp].op = ocode; 8053 stack[sp].sizeof_arg = c_last_sizeof_arg; 8054 } 8055 out: 8056 while (sp > 0) 8057 POP; 8058 return stack[0].expr; 8059 #undef POP 8060 } 8061 8062 /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4). If AFTER 8063 is not NULL then it is an Objective-C message expression which is the 8064 primary-expression starting the expression as an initializer. 8065 8066 cast-expression: 8067 unary-expression 8068 ( type-name ) unary-expression 8069 */ 8070 8071 static struct c_expr 8072 c_parser_cast_expression (c_parser *parser, struct c_expr *after) 8073 { 8074 location_t cast_loc = c_parser_peek_token (parser)->location; 8075 gcc_assert (!after || c_dialect_objc ()); 8076 if (after) 8077 return c_parser_postfix_expression_after_primary (parser, 8078 cast_loc, *after); 8079 /* If the expression begins with a parenthesized type name, it may 8080 be either a cast or a compound literal; we need to see whether 8081 the next character is '{' to tell the difference. If not, it is 8082 an unary expression. Full detection of unknown typenames here 8083 would require a 3-token lookahead. */ 8084 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN) 8085 && c_token_starts_typename (c_parser_peek_2nd_token (parser))) 8086 { 8087 struct c_type_name *type_name; 8088 struct c_expr ret; 8089 struct c_expr expr; 8090 matching_parens parens; 8091 parens.consume_open (parser); 8092 type_name = c_parser_type_name (parser, true); 8093 parens.skip_until_found_close (parser); 8094 if (type_name == NULL) 8095 { 8096 ret.set_error (); 8097 ret.original_code = ERROR_MARK; 8098 ret.original_type = NULL; 8099 return ret; 8100 } 8101 8102 /* Save casted types in the function's used types hash table. */ 8103 used_types_insert (type_name->specs->type); 8104 8105 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 8106 return c_parser_postfix_expression_after_paren_type (parser, type_name, 8107 cast_loc); 8108 if (type_name->specs->alignas_p) 8109 error_at (type_name->specs->locations[cdw_alignas], 8110 "alignment specified for type name in cast"); 8111 { 8112 location_t expr_loc = c_parser_peek_token (parser)->location; 8113 expr = c_parser_cast_expression (parser, NULL); 8114 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true); 8115 } 8116 ret.value = c_cast_expr (cast_loc, type_name, expr.value); 8117 if (ret.value && expr.value) 8118 set_c_expr_source_range (&ret, cast_loc, expr.get_finish ()); 8119 ret.original_code = ERROR_MARK; 8120 ret.original_type = NULL; 8121 return ret; 8122 } 8123 else 8124 return c_parser_unary_expression (parser); 8125 } 8126 8127 /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3). 8128 8129 unary-expression: 8130 postfix-expression 8131 ++ unary-expression 8132 -- unary-expression 8133 unary-operator cast-expression 8134 sizeof unary-expression 8135 sizeof ( type-name ) 8136 8137 unary-operator: one of 8138 & * + - ~ ! 8139 8140 GNU extensions: 8141 8142 unary-expression: 8143 __alignof__ unary-expression 8144 __alignof__ ( type-name ) 8145 && identifier 8146 8147 (C11 permits _Alignof with type names only.) 8148 8149 unary-operator: one of 8150 __extension__ __real__ __imag__ 8151 8152 Transactional Memory: 8153 8154 unary-expression: 8155 transaction-expression 8156 8157 In addition, the GNU syntax treats ++ and -- as unary operators, so 8158 they may be applied to cast expressions with errors for non-lvalues 8159 given later. */ 8160 8161 static struct c_expr 8162 c_parser_unary_expression (c_parser *parser) 8163 { 8164 int ext; 8165 struct c_expr ret, op; 8166 location_t op_loc = c_parser_peek_token (parser)->location; 8167 location_t exp_loc; 8168 location_t finish; 8169 ret.original_code = ERROR_MARK; 8170 ret.original_type = NULL; 8171 switch (c_parser_peek_token (parser)->type) 8172 { 8173 case CPP_PLUS_PLUS: 8174 c_parser_consume_token (parser); 8175 exp_loc = c_parser_peek_token (parser)->location; 8176 op = c_parser_cast_expression (parser, NULL); 8177 8178 op = default_function_array_read_conversion (exp_loc, op); 8179 return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op); 8180 case CPP_MINUS_MINUS: 8181 c_parser_consume_token (parser); 8182 exp_loc = c_parser_peek_token (parser)->location; 8183 op = c_parser_cast_expression (parser, NULL); 8184 8185 op = default_function_array_read_conversion (exp_loc, op); 8186 return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op); 8187 case CPP_AND: 8188 c_parser_consume_token (parser); 8189 op = c_parser_cast_expression (parser, NULL); 8190 mark_exp_read (op.value); 8191 return parser_build_unary_op (op_loc, ADDR_EXPR, op); 8192 case CPP_MULT: 8193 { 8194 c_parser_consume_token (parser); 8195 exp_loc = c_parser_peek_token (parser)->location; 8196 op = c_parser_cast_expression (parser, NULL); 8197 finish = op.get_finish (); 8198 op = convert_lvalue_to_rvalue (exp_loc, op, true, true); 8199 location_t combined_loc = make_location (op_loc, op_loc, finish); 8200 ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR); 8201 ret.src_range.m_start = op_loc; 8202 ret.src_range.m_finish = finish; 8203 return ret; 8204 } 8205 case CPP_PLUS: 8206 if (!c_dialect_objc () && !in_system_header_at (input_location)) 8207 warning_at (op_loc, 8208 OPT_Wtraditional, 8209 "traditional C rejects the unary plus operator"); 8210 c_parser_consume_token (parser); 8211 exp_loc = c_parser_peek_token (parser)->location; 8212 op = c_parser_cast_expression (parser, NULL); 8213 op = convert_lvalue_to_rvalue (exp_loc, op, true, true); 8214 return parser_build_unary_op (op_loc, CONVERT_EXPR, op); 8215 case CPP_MINUS: 8216 c_parser_consume_token (parser); 8217 exp_loc = c_parser_peek_token (parser)->location; 8218 op = c_parser_cast_expression (parser, NULL); 8219 op = convert_lvalue_to_rvalue (exp_loc, op, true, true); 8220 return parser_build_unary_op (op_loc, NEGATE_EXPR, op); 8221 case CPP_COMPL: 8222 c_parser_consume_token (parser); 8223 exp_loc = c_parser_peek_token (parser)->location; 8224 op = c_parser_cast_expression (parser, NULL); 8225 op = convert_lvalue_to_rvalue (exp_loc, op, true, true); 8226 return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op); 8227 case CPP_NOT: 8228 c_parser_consume_token (parser); 8229 exp_loc = c_parser_peek_token (parser)->location; 8230 op = c_parser_cast_expression (parser, NULL); 8231 op = convert_lvalue_to_rvalue (exp_loc, op, true, true); 8232 return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op); 8233 case CPP_AND_AND: 8234 /* Refer to the address of a label as a pointer. */ 8235 c_parser_consume_token (parser); 8236 if (c_parser_next_token_is (parser, CPP_NAME)) 8237 { 8238 ret.value = finish_label_address_expr 8239 (c_parser_peek_token (parser)->value, op_loc); 8240 set_c_expr_source_range (&ret, op_loc, 8241 c_parser_peek_token (parser)->get_finish ()); 8242 c_parser_consume_token (parser); 8243 } 8244 else 8245 { 8246 c_parser_error (parser, "expected identifier"); 8247 ret.set_error (); 8248 } 8249 return ret; 8250 case CPP_KEYWORD: 8251 switch (c_parser_peek_token (parser)->keyword) 8252 { 8253 case RID_SIZEOF: 8254 return c_parser_sizeof_expression (parser); 8255 case RID_ALIGNOF: 8256 return c_parser_alignof_expression (parser); 8257 case RID_BUILTIN_HAS_ATTRIBUTE: 8258 return c_parser_has_attribute_expression (parser); 8259 case RID_EXTENSION: 8260 c_parser_consume_token (parser); 8261 ext = disable_extension_diagnostics (); 8262 ret = c_parser_cast_expression (parser, NULL); 8263 restore_extension_diagnostics (ext); 8264 return ret; 8265 case RID_REALPART: 8266 c_parser_consume_token (parser); 8267 exp_loc = c_parser_peek_token (parser)->location; 8268 op = c_parser_cast_expression (parser, NULL); 8269 op = default_function_array_conversion (exp_loc, op); 8270 return parser_build_unary_op (op_loc, REALPART_EXPR, op); 8271 case RID_IMAGPART: 8272 c_parser_consume_token (parser); 8273 exp_loc = c_parser_peek_token (parser)->location; 8274 op = c_parser_cast_expression (parser, NULL); 8275 op = default_function_array_conversion (exp_loc, op); 8276 return parser_build_unary_op (op_loc, IMAGPART_EXPR, op); 8277 case RID_TRANSACTION_ATOMIC: 8278 case RID_TRANSACTION_RELAXED: 8279 return c_parser_transaction_expression (parser, 8280 c_parser_peek_token (parser)->keyword); 8281 default: 8282 return c_parser_postfix_expression (parser); 8283 } 8284 default: 8285 return c_parser_postfix_expression (parser); 8286 } 8287 } 8288 8289 /* Parse a sizeof expression. */ 8290 8291 static struct c_expr 8292 c_parser_sizeof_expression (c_parser *parser) 8293 { 8294 struct c_expr expr; 8295 struct c_expr result; 8296 location_t expr_loc; 8297 gcc_assert (c_parser_next_token_is_keyword (parser, RID_SIZEOF)); 8298 8299 location_t start; 8300 location_t finish = UNKNOWN_LOCATION; 8301 8302 start = c_parser_peek_token (parser)->location; 8303 8304 c_parser_consume_token (parser); 8305 c_inhibit_evaluation_warnings++; 8306 in_sizeof++; 8307 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN) 8308 && c_token_starts_typename (c_parser_peek_2nd_token (parser))) 8309 { 8310 /* Either sizeof ( type-name ) or sizeof unary-expression 8311 starting with a compound literal. */ 8312 struct c_type_name *type_name; 8313 matching_parens parens; 8314 parens.consume_open (parser); 8315 expr_loc = c_parser_peek_token (parser)->location; 8316 type_name = c_parser_type_name (parser, true); 8317 parens.skip_until_found_close (parser); 8318 finish = parser->tokens_buf[0].location; 8319 if (type_name == NULL) 8320 { 8321 struct c_expr ret; 8322 c_inhibit_evaluation_warnings--; 8323 in_sizeof--; 8324 ret.set_error (); 8325 ret.original_code = ERROR_MARK; 8326 ret.original_type = NULL; 8327 return ret; 8328 } 8329 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 8330 { 8331 expr = c_parser_postfix_expression_after_paren_type (parser, 8332 type_name, 8333 expr_loc); 8334 finish = expr.get_finish (); 8335 goto sizeof_expr; 8336 } 8337 /* sizeof ( type-name ). */ 8338 if (type_name->specs->alignas_p) 8339 error_at (type_name->specs->locations[cdw_alignas], 8340 "alignment specified for type name in %<sizeof%>"); 8341 c_inhibit_evaluation_warnings--; 8342 in_sizeof--; 8343 result = c_expr_sizeof_type (expr_loc, type_name); 8344 } 8345 else 8346 { 8347 expr_loc = c_parser_peek_token (parser)->location; 8348 expr = c_parser_unary_expression (parser); 8349 finish = expr.get_finish (); 8350 sizeof_expr: 8351 c_inhibit_evaluation_warnings--; 8352 in_sizeof--; 8353 mark_exp_read (expr.value); 8354 if (TREE_CODE (expr.value) == COMPONENT_REF 8355 && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1))) 8356 error_at (expr_loc, "%<sizeof%> applied to a bit-field"); 8357 result = c_expr_sizeof_expr (expr_loc, expr); 8358 } 8359 if (finish == UNKNOWN_LOCATION) 8360 finish = start; 8361 set_c_expr_source_range (&result, start, finish); 8362 return result; 8363 } 8364 8365 /* Parse an alignof expression. */ 8366 8367 static struct c_expr 8368 c_parser_alignof_expression (c_parser *parser) 8369 { 8370 struct c_expr expr; 8371 location_t start_loc = c_parser_peek_token (parser)->location; 8372 location_t end_loc; 8373 tree alignof_spelling = c_parser_peek_token (parser)->value; 8374 gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF)); 8375 bool is_c11_alignof = strcmp (IDENTIFIER_POINTER (alignof_spelling), 8376 "_Alignof") == 0; 8377 /* A diagnostic is not required for the use of this identifier in 8378 the implementation namespace; only diagnose it for the C11 8379 spelling because of existing code using the other spellings. */ 8380 if (is_c11_alignof) 8381 { 8382 if (flag_isoc99) 8383 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE", 8384 alignof_spelling); 8385 else 8386 pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE", 8387 alignof_spelling); 8388 } 8389 c_parser_consume_token (parser); 8390 c_inhibit_evaluation_warnings++; 8391 in_alignof++; 8392 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN) 8393 && c_token_starts_typename (c_parser_peek_2nd_token (parser))) 8394 { 8395 /* Either __alignof__ ( type-name ) or __alignof__ 8396 unary-expression starting with a compound literal. */ 8397 location_t loc; 8398 struct c_type_name *type_name; 8399 struct c_expr ret; 8400 matching_parens parens; 8401 parens.consume_open (parser); 8402 loc = c_parser_peek_token (parser)->location; 8403 type_name = c_parser_type_name (parser, true); 8404 end_loc = c_parser_peek_token (parser)->location; 8405 parens.skip_until_found_close (parser); 8406 if (type_name == NULL) 8407 { 8408 struct c_expr ret; 8409 c_inhibit_evaluation_warnings--; 8410 in_alignof--; 8411 ret.set_error (); 8412 ret.original_code = ERROR_MARK; 8413 ret.original_type = NULL; 8414 return ret; 8415 } 8416 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 8417 { 8418 expr = c_parser_postfix_expression_after_paren_type (parser, 8419 type_name, 8420 loc); 8421 goto alignof_expr; 8422 } 8423 /* alignof ( type-name ). */ 8424 if (type_name->specs->alignas_p) 8425 error_at (type_name->specs->locations[cdw_alignas], 8426 "alignment specified for type name in %qE", 8427 alignof_spelling); 8428 c_inhibit_evaluation_warnings--; 8429 in_alignof--; 8430 ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name, 8431 NULL, NULL), 8432 false, is_c11_alignof, 1); 8433 ret.original_code = ERROR_MARK; 8434 ret.original_type = NULL; 8435 set_c_expr_source_range (&ret, start_loc, end_loc); 8436 return ret; 8437 } 8438 else 8439 { 8440 struct c_expr ret; 8441 expr = c_parser_unary_expression (parser); 8442 end_loc = expr.src_range.m_finish; 8443 alignof_expr: 8444 mark_exp_read (expr.value); 8445 c_inhibit_evaluation_warnings--; 8446 in_alignof--; 8447 if (is_c11_alignof) 8448 pedwarn (start_loc, 8449 OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>", 8450 alignof_spelling); 8451 ret.value = c_alignof_expr (start_loc, expr.value); 8452 ret.original_code = ERROR_MARK; 8453 ret.original_type = NULL; 8454 set_c_expr_source_range (&ret, start_loc, end_loc); 8455 return ret; 8456 } 8457 } 8458 8459 /* Parse the __builtin_has_attribute ([expr|type], attribute-spec) 8460 expression. */ 8461 8462 static struct c_expr 8463 c_parser_has_attribute_expression (c_parser *parser) 8464 { 8465 gcc_assert (c_parser_next_token_is_keyword (parser, 8466 RID_BUILTIN_HAS_ATTRIBUTE)); 8467 location_t start = c_parser_peek_token (parser)->location; 8468 c_parser_consume_token (parser); 8469 8470 c_inhibit_evaluation_warnings++; 8471 8472 matching_parens parens; 8473 if (!parens.require_open (parser)) 8474 { 8475 c_inhibit_evaluation_warnings--; 8476 in_typeof--; 8477 8478 struct c_expr result; 8479 result.set_error (); 8480 result.original_code = ERROR_MARK; 8481 result.original_type = NULL; 8482 return result; 8483 } 8484 8485 /* Treat the type argument the same way as in typeof for the purposes 8486 of warnings. FIXME: Generalize this so the warning refers to 8487 __builtin_has_attribute rather than typeof. */ 8488 in_typeof++; 8489 8490 /* The first operand: one of DECL, EXPR, or TYPE. */ 8491 tree oper = NULL_TREE; 8492 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id)) 8493 { 8494 struct c_type_name *tname = c_parser_type_name (parser); 8495 in_typeof--; 8496 if (tname) 8497 { 8498 oper = groktypename (tname, NULL, NULL); 8499 pop_maybe_used (variably_modified_type_p (oper, NULL_TREE)); 8500 } 8501 } 8502 else 8503 { 8504 struct c_expr cexpr = c_parser_expr_no_commas (parser, NULL); 8505 c_inhibit_evaluation_warnings--; 8506 in_typeof--; 8507 if (cexpr.value != error_mark_node) 8508 { 8509 mark_exp_read (cexpr.value); 8510 oper = cexpr.value; 8511 tree etype = TREE_TYPE (oper); 8512 bool was_vm = variably_modified_type_p (etype, NULL_TREE); 8513 /* This is returned with the type so that when the type is 8514 evaluated, this can be evaluated. */ 8515 if (was_vm) 8516 oper = c_fully_fold (oper, false, NULL); 8517 pop_maybe_used (was_vm); 8518 } 8519 } 8520 8521 struct c_expr result; 8522 result.original_code = ERROR_MARK; 8523 result.original_type = NULL; 8524 8525 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) 8526 { 8527 /* Consume the closing parenthesis if that's the next token 8528 in the likely case the built-in was invoked with fewer 8529 than two arguments. */ 8530 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 8531 c_parser_consume_token (parser); 8532 c_inhibit_evaluation_warnings--; 8533 result.set_error (); 8534 return result; 8535 } 8536 8537 bool save_translate_strings_p = parser->translate_strings_p; 8538 8539 location_t atloc = c_parser_peek_token (parser)->location; 8540 /* Parse a single attribute. Require no leading comma and do not 8541 allow empty attributes. */ 8542 tree attr = c_parser_gnu_attribute (parser, NULL_TREE, false, false); 8543 8544 parser->translate_strings_p = save_translate_strings_p; 8545 8546 location_t finish = c_parser_peek_token (parser)->location; 8547 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 8548 c_parser_consume_token (parser); 8549 else 8550 { 8551 c_parser_error (parser, "expected identifier"); 8552 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 8553 8554 result.set_error (); 8555 return result; 8556 } 8557 8558 if (!attr) 8559 { 8560 error_at (atloc, "expected identifier"); 8561 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 8562 "expected %<)%>"); 8563 result.set_error (); 8564 return result; 8565 } 8566 8567 result.original_code = INTEGER_CST; 8568 result.original_type = boolean_type_node; 8569 8570 if (has_attribute (atloc, oper, attr, default_conversion)) 8571 result.value = boolean_true_node; 8572 else 8573 result.value = boolean_false_node; 8574 8575 set_c_expr_source_range (&result, start, finish); 8576 return result; 8577 } 8578 8579 /* Helper function to read arguments of builtins which are interfaces 8580 for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and 8581 others. The name of the builtin is passed using BNAME parameter. 8582 Function returns true if there were no errors while parsing and 8583 stores the arguments in CEXPR_LIST. If it returns true, 8584 *OUT_CLOSE_PAREN_LOC is written to with the location of the closing 8585 parenthesis. */ 8586 static bool 8587 c_parser_get_builtin_args (c_parser *parser, const char *bname, 8588 vec<c_expr_t, va_gc> **ret_cexpr_list, 8589 bool choose_expr_p, 8590 location_t *out_close_paren_loc) 8591 { 8592 location_t loc = c_parser_peek_token (parser)->location; 8593 vec<c_expr_t, va_gc> *cexpr_list; 8594 c_expr_t expr; 8595 bool saved_force_folding_builtin_constant_p; 8596 8597 *ret_cexpr_list = NULL; 8598 if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN)) 8599 { 8600 error_at (loc, "cannot take address of %qs", bname); 8601 return false; 8602 } 8603 8604 c_parser_consume_token (parser); 8605 8606 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 8607 { 8608 *out_close_paren_loc = c_parser_peek_token (parser)->location; 8609 c_parser_consume_token (parser); 8610 return true; 8611 } 8612 8613 saved_force_folding_builtin_constant_p 8614 = force_folding_builtin_constant_p; 8615 force_folding_builtin_constant_p |= choose_expr_p; 8616 expr = c_parser_expr_no_commas (parser, NULL); 8617 force_folding_builtin_constant_p 8618 = saved_force_folding_builtin_constant_p; 8619 vec_alloc (cexpr_list, 1); 8620 vec_safe_push (cexpr_list, expr); 8621 while (c_parser_next_token_is (parser, CPP_COMMA)) 8622 { 8623 c_parser_consume_token (parser); 8624 expr = c_parser_expr_no_commas (parser, NULL); 8625 vec_safe_push (cexpr_list, expr); 8626 } 8627 8628 *out_close_paren_loc = c_parser_peek_token (parser)->location; 8629 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) 8630 return false; 8631 8632 *ret_cexpr_list = cexpr_list; 8633 return true; 8634 } 8635 8636 /* This represents a single generic-association. */ 8637 8638 struct c_generic_association 8639 { 8640 /* The location of the starting token of the type. */ 8641 location_t type_location; 8642 /* The association's type, or NULL_TREE for 'default'. */ 8643 tree type; 8644 /* The association's expression. */ 8645 struct c_expr expression; 8646 }; 8647 8648 /* Parse a generic-selection. (C11 6.5.1.1). 8649 8650 generic-selection: 8651 _Generic ( assignment-expression , generic-assoc-list ) 8652 8653 generic-assoc-list: 8654 generic-association 8655 generic-assoc-list , generic-association 8656 8657 generic-association: 8658 type-name : assignment-expression 8659 default : assignment-expression 8660 */ 8661 8662 static struct c_expr 8663 c_parser_generic_selection (c_parser *parser) 8664 { 8665 struct c_expr selector, error_expr; 8666 tree selector_type; 8667 struct c_generic_association matched_assoc; 8668 int match_found = -1; 8669 location_t generic_loc, selector_loc; 8670 8671 error_expr.original_code = ERROR_MARK; 8672 error_expr.original_type = NULL; 8673 error_expr.set_error (); 8674 matched_assoc.type_location = UNKNOWN_LOCATION; 8675 matched_assoc.type = NULL_TREE; 8676 matched_assoc.expression = error_expr; 8677 8678 gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC)); 8679 generic_loc = c_parser_peek_token (parser)->location; 8680 c_parser_consume_token (parser); 8681 if (flag_isoc99) 8682 pedwarn_c99 (generic_loc, OPT_Wpedantic, 8683 "ISO C99 does not support %<_Generic%>"); 8684 else 8685 pedwarn_c99 (generic_loc, OPT_Wpedantic, 8686 "ISO C90 does not support %<_Generic%>"); 8687 8688 matching_parens parens; 8689 if (!parens.require_open (parser)) 8690 return error_expr; 8691 8692 c_inhibit_evaluation_warnings++; 8693 selector_loc = c_parser_peek_token (parser)->location; 8694 selector = c_parser_expr_no_commas (parser, NULL); 8695 selector = default_function_array_conversion (selector_loc, selector); 8696 c_inhibit_evaluation_warnings--; 8697 8698 if (selector.value == error_mark_node) 8699 { 8700 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 8701 return selector; 8702 } 8703 mark_exp_read (selector.value); 8704 selector_type = TREE_TYPE (selector.value); 8705 /* In ISO C terms, rvalues (including the controlling expression of 8706 _Generic) do not have qualified types. */ 8707 if (TREE_CODE (selector_type) != ARRAY_TYPE) 8708 selector_type = TYPE_MAIN_VARIANT (selector_type); 8709 /* In ISO C terms, _Noreturn is not part of the type of expressions 8710 such as &abort, but in GCC it is represented internally as a type 8711 qualifier. */ 8712 if (FUNCTION_POINTER_TYPE_P (selector_type) 8713 && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED) 8714 selector_type 8715 = build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type))); 8716 8717 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) 8718 { 8719 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 8720 return error_expr; 8721 } 8722 8723 auto_vec<c_generic_association> associations; 8724 while (1) 8725 { 8726 struct c_generic_association assoc, *iter; 8727 unsigned int ix; 8728 c_token *token = c_parser_peek_token (parser); 8729 8730 assoc.type_location = token->location; 8731 if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT) 8732 { 8733 c_parser_consume_token (parser); 8734 assoc.type = NULL_TREE; 8735 } 8736 else 8737 { 8738 struct c_type_name *type_name; 8739 8740 type_name = c_parser_type_name (parser); 8741 if (type_name == NULL) 8742 { 8743 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 8744 return error_expr; 8745 } 8746 assoc.type = groktypename (type_name, NULL, NULL); 8747 if (assoc.type == error_mark_node) 8748 { 8749 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 8750 return error_expr; 8751 } 8752 8753 if (TREE_CODE (assoc.type) == FUNCTION_TYPE) 8754 error_at (assoc.type_location, 8755 "%<_Generic%> association has function type"); 8756 else if (!COMPLETE_TYPE_P (assoc.type)) 8757 error_at (assoc.type_location, 8758 "%<_Generic%> association has incomplete type"); 8759 8760 if (variably_modified_type_p (assoc.type, NULL_TREE)) 8761 error_at (assoc.type_location, 8762 "%<_Generic%> association has " 8763 "variable length type"); 8764 } 8765 8766 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 8767 { 8768 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 8769 return error_expr; 8770 } 8771 8772 assoc.expression = c_parser_expr_no_commas (parser, NULL); 8773 if (assoc.expression.value == error_mark_node) 8774 { 8775 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 8776 return error_expr; 8777 } 8778 8779 for (ix = 0; associations.iterate (ix, &iter); ++ix) 8780 { 8781 if (assoc.type == NULL_TREE) 8782 { 8783 if (iter->type == NULL_TREE) 8784 { 8785 error_at (assoc.type_location, 8786 "duplicate %<default%> case in %<_Generic%>"); 8787 inform (iter->type_location, "original %<default%> is here"); 8788 } 8789 } 8790 else if (iter->type != NULL_TREE) 8791 { 8792 if (comptypes (assoc.type, iter->type)) 8793 { 8794 error_at (assoc.type_location, 8795 "%<_Generic%> specifies two compatible types"); 8796 inform (iter->type_location, "compatible type is here"); 8797 } 8798 } 8799 } 8800 8801 if (assoc.type == NULL_TREE) 8802 { 8803 if (match_found < 0) 8804 { 8805 matched_assoc = assoc; 8806 match_found = associations.length (); 8807 } 8808 } 8809 else if (comptypes (assoc.type, selector_type)) 8810 { 8811 if (match_found < 0 || matched_assoc.type == NULL_TREE) 8812 { 8813 matched_assoc = assoc; 8814 match_found = associations.length (); 8815 } 8816 else 8817 { 8818 error_at (assoc.type_location, 8819 "%<_Generic%> selector matches multiple associations"); 8820 inform (matched_assoc.type_location, 8821 "other match is here"); 8822 } 8823 } 8824 8825 associations.safe_push (assoc); 8826 8827 if (c_parser_peek_token (parser)->type != CPP_COMMA) 8828 break; 8829 c_parser_consume_token (parser); 8830 } 8831 8832 unsigned int ix; 8833 struct c_generic_association *iter; 8834 FOR_EACH_VEC_ELT (associations, ix, iter) 8835 if (ix != (unsigned) match_found) 8836 mark_exp_read (iter->expression.value); 8837 8838 if (!parens.require_close (parser)) 8839 { 8840 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 8841 return error_expr; 8842 } 8843 8844 if (match_found < 0) 8845 { 8846 error_at (selector_loc, "%<_Generic%> selector of type %qT is not " 8847 "compatible with any association", 8848 selector_type); 8849 return error_expr; 8850 } 8851 8852 return matched_assoc.expression; 8853 } 8854 8855 /* Check the validity of a function pointer argument *EXPR (argument 8856 position POS) to __builtin_tgmath. Return the number of function 8857 arguments if possibly valid; return 0 having reported an error if 8858 not valid. */ 8859 8860 static unsigned int 8861 check_tgmath_function (c_expr *expr, unsigned int pos) 8862 { 8863 tree type = TREE_TYPE (expr->value); 8864 if (!FUNCTION_POINTER_TYPE_P (type)) 8865 { 8866 error_at (expr->get_location (), 8867 "argument %u of %<__builtin_tgmath%> is not a function pointer", 8868 pos); 8869 return 0; 8870 } 8871 type = TREE_TYPE (type); 8872 if (!prototype_p (type)) 8873 { 8874 error_at (expr->get_location (), 8875 "argument %u of %<__builtin_tgmath%> is unprototyped", pos); 8876 return 0; 8877 } 8878 if (stdarg_p (type)) 8879 { 8880 error_at (expr->get_location (), 8881 "argument %u of %<__builtin_tgmath%> has variable arguments", 8882 pos); 8883 return 0; 8884 } 8885 unsigned int nargs = 0; 8886 function_args_iterator iter; 8887 tree t; 8888 FOREACH_FUNCTION_ARGS (type, t, iter) 8889 { 8890 if (t == void_type_node) 8891 break; 8892 nargs++; 8893 } 8894 if (nargs == 0) 8895 { 8896 error_at (expr->get_location (), 8897 "argument %u of %<__builtin_tgmath%> has no arguments", pos); 8898 return 0; 8899 } 8900 return nargs; 8901 } 8902 8903 /* Ways in which a parameter or return value of a type-generic macro 8904 may vary between the different functions the macro may call. */ 8905 enum tgmath_parm_kind 8906 { 8907 tgmath_fixed, tgmath_real, tgmath_complex 8908 }; 8909 8910 /* Helper function for c_parser_postfix_expression. Parse predefined 8911 identifiers. */ 8912 8913 static struct c_expr 8914 c_parser_predefined_identifier (c_parser *parser) 8915 { 8916 location_t loc = c_parser_peek_token (parser)->location; 8917 switch (c_parser_peek_token (parser)->keyword) 8918 { 8919 case RID_FUNCTION_NAME: 8920 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined " 8921 "identifier", "__FUNCTION__"); 8922 break; 8923 case RID_PRETTY_FUNCTION_NAME: 8924 pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined " 8925 "identifier", "__PRETTY_FUNCTION__"); 8926 break; 8927 case RID_C99_FUNCTION_NAME: 8928 pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support " 8929 "%<__func__%> predefined identifier"); 8930 break; 8931 default: 8932 gcc_unreachable (); 8933 } 8934 8935 struct c_expr expr; 8936 expr.original_code = ERROR_MARK; 8937 expr.original_type = NULL; 8938 expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword, 8939 c_parser_peek_token (parser)->value); 8940 set_c_expr_source_range (&expr, loc, loc); 8941 c_parser_consume_token (parser); 8942 return expr; 8943 } 8944 8945 /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2, 8946 C11 6.5.1-6.5.2). Compound literals aren't handled here; callers have to 8947 call c_parser_postfix_expression_after_paren_type on encountering them. 8948 8949 postfix-expression: 8950 primary-expression 8951 postfix-expression [ expression ] 8952 postfix-expression ( argument-expression-list[opt] ) 8953 postfix-expression . identifier 8954 postfix-expression -> identifier 8955 postfix-expression ++ 8956 postfix-expression -- 8957 ( type-name ) { initializer-list } 8958 ( type-name ) { initializer-list , } 8959 8960 argument-expression-list: 8961 argument-expression 8962 argument-expression-list , argument-expression 8963 8964 primary-expression: 8965 identifier 8966 constant 8967 string-literal 8968 ( expression ) 8969 generic-selection 8970 8971 GNU extensions: 8972 8973 primary-expression: 8974 __func__ 8975 (treated as a keyword in GNU C) 8976 __FUNCTION__ 8977 __PRETTY_FUNCTION__ 8978 ( compound-statement ) 8979 __builtin_va_arg ( assignment-expression , type-name ) 8980 __builtin_offsetof ( type-name , offsetof-member-designator ) 8981 __builtin_choose_expr ( assignment-expression , 8982 assignment-expression , 8983 assignment-expression ) 8984 __builtin_types_compatible_p ( type-name , type-name ) 8985 __builtin_tgmath ( expr-list ) 8986 __builtin_complex ( assignment-expression , assignment-expression ) 8987 __builtin_shuffle ( assignment-expression , assignment-expression ) 8988 __builtin_shuffle ( assignment-expression , 8989 assignment-expression , 8990 assignment-expression, ) 8991 __builtin_convertvector ( assignment-expression , type-name ) 8992 8993 offsetof-member-designator: 8994 identifier 8995 offsetof-member-designator . identifier 8996 offsetof-member-designator [ expression ] 8997 8998 Objective-C: 8999 9000 primary-expression: 9001 [ objc-receiver objc-message-args ] 9002 @selector ( objc-selector-arg ) 9003 @protocol ( identifier ) 9004 @encode ( type-name ) 9005 objc-string-literal 9006 Classname . identifier 9007 */ 9008 9009 static struct c_expr 9010 c_parser_postfix_expression (c_parser *parser) 9011 { 9012 struct c_expr expr, e1; 9013 struct c_type_name *t1, *t2; 9014 location_t loc = c_parser_peek_token (parser)->location; 9015 source_range tok_range = c_parser_peek_token (parser)->get_range (); 9016 expr.original_code = ERROR_MARK; 9017 expr.original_type = NULL; 9018 switch (c_parser_peek_token (parser)->type) 9019 { 9020 case CPP_NUMBER: 9021 expr.value = c_parser_peek_token (parser)->value; 9022 set_c_expr_source_range (&expr, tok_range); 9023 loc = c_parser_peek_token (parser)->location; 9024 c_parser_consume_token (parser); 9025 if (TREE_CODE (expr.value) == FIXED_CST 9026 && !targetm.fixed_point_supported_p ()) 9027 { 9028 error_at (loc, "fixed-point types not supported for this target"); 9029 expr.set_error (); 9030 } 9031 break; 9032 case CPP_CHAR: 9033 case CPP_CHAR16: 9034 case CPP_CHAR32: 9035 case CPP_UTF8CHAR: 9036 case CPP_WCHAR: 9037 expr.value = c_parser_peek_token (parser)->value; 9038 /* For the purpose of warning when a pointer is compared with 9039 a zero character constant. */ 9040 expr.original_type = char_type_node; 9041 set_c_expr_source_range (&expr, tok_range); 9042 c_parser_consume_token (parser); 9043 break; 9044 case CPP_STRING: 9045 case CPP_STRING16: 9046 case CPP_STRING32: 9047 case CPP_WSTRING: 9048 case CPP_UTF8STRING: 9049 expr = c_parser_string_literal (parser, parser->translate_strings_p, 9050 true); 9051 break; 9052 case CPP_OBJC_STRING: 9053 gcc_assert (c_dialect_objc ()); 9054 expr.value 9055 = objc_build_string_object (c_parser_peek_token (parser)->value); 9056 set_c_expr_source_range (&expr, tok_range); 9057 c_parser_consume_token (parser); 9058 break; 9059 case CPP_NAME: 9060 switch (c_parser_peek_token (parser)->id_kind) 9061 { 9062 case C_ID_ID: 9063 { 9064 tree id = c_parser_peek_token (parser)->value; 9065 c_parser_consume_token (parser); 9066 expr.value = build_external_ref (loc, id, 9067 (c_parser_peek_token (parser)->type 9068 == CPP_OPEN_PAREN), 9069 &expr.original_type); 9070 set_c_expr_source_range (&expr, tok_range); 9071 break; 9072 } 9073 case C_ID_CLASSNAME: 9074 { 9075 /* Here we parse the Objective-C 2.0 Class.name dot 9076 syntax. */ 9077 tree class_name = c_parser_peek_token (parser)->value; 9078 tree component; 9079 c_parser_consume_token (parser); 9080 gcc_assert (c_dialect_objc ()); 9081 if (!c_parser_require (parser, CPP_DOT, "expected %<.%>")) 9082 { 9083 expr.set_error (); 9084 break; 9085 } 9086 if (c_parser_next_token_is_not (parser, CPP_NAME)) 9087 { 9088 c_parser_error (parser, "expected identifier"); 9089 expr.set_error (); 9090 break; 9091 } 9092 c_token *component_tok = c_parser_peek_token (parser); 9093 component = component_tok->value; 9094 location_t end_loc = component_tok->get_finish (); 9095 c_parser_consume_token (parser); 9096 expr.value = objc_build_class_component_ref (class_name, 9097 component); 9098 set_c_expr_source_range (&expr, loc, end_loc); 9099 break; 9100 } 9101 default: 9102 c_parser_error (parser, "expected expression"); 9103 expr.set_error (); 9104 break; 9105 } 9106 break; 9107 case CPP_OPEN_PAREN: 9108 /* A parenthesized expression, statement expression or compound 9109 literal. */ 9110 if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE) 9111 { 9112 /* A statement expression. */ 9113 tree stmt; 9114 location_t brace_loc; 9115 c_parser_consume_token (parser); 9116 brace_loc = c_parser_peek_token (parser)->location; 9117 c_parser_consume_token (parser); 9118 /* If we've not yet started the current function's statement list, 9119 or we're in the parameter scope of an old-style function 9120 declaration, statement expressions are not allowed. */ 9121 if (!building_stmt_list_p () || old_style_parameter_scope ()) 9122 { 9123 error_at (loc, "braced-group within expression allowed " 9124 "only inside a function"); 9125 parser->error = true; 9126 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL); 9127 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 9128 expr.set_error (); 9129 break; 9130 } 9131 stmt = c_begin_stmt_expr (); 9132 c_parser_compound_statement_nostart (parser); 9133 location_t close_loc = c_parser_peek_token (parser)->location; 9134 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 9135 "expected %<)%>"); 9136 pedwarn (loc, OPT_Wpedantic, 9137 "ISO C forbids braced-groups within expressions"); 9138 expr.value = c_finish_stmt_expr (brace_loc, stmt); 9139 set_c_expr_source_range (&expr, loc, close_loc); 9140 mark_exp_read (expr.value); 9141 } 9142 else 9143 { 9144 /* A parenthesized expression. */ 9145 location_t loc_open_paren = c_parser_peek_token (parser)->location; 9146 c_parser_consume_token (parser); 9147 expr = c_parser_expression (parser); 9148 if (TREE_CODE (expr.value) == MODIFY_EXPR) 9149 TREE_NO_WARNING (expr.value) = 1; 9150 if (expr.original_code != C_MAYBE_CONST_EXPR 9151 && expr.original_code != SIZEOF_EXPR) 9152 expr.original_code = ERROR_MARK; 9153 /* Don't change EXPR.ORIGINAL_TYPE. */ 9154 location_t loc_close_paren = c_parser_peek_token (parser)->location; 9155 set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren); 9156 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 9157 "expected %<)%>", loc_open_paren); 9158 } 9159 break; 9160 case CPP_KEYWORD: 9161 switch (c_parser_peek_token (parser)->keyword) 9162 { 9163 case RID_FUNCTION_NAME: 9164 case RID_PRETTY_FUNCTION_NAME: 9165 case RID_C99_FUNCTION_NAME: 9166 expr = c_parser_predefined_identifier (parser); 9167 break; 9168 case RID_VA_ARG: 9169 { 9170 location_t start_loc = loc; 9171 c_parser_consume_token (parser); 9172 matching_parens parens; 9173 if (!parens.require_open (parser)) 9174 { 9175 expr.set_error (); 9176 break; 9177 } 9178 e1 = c_parser_expr_no_commas (parser, NULL); 9179 mark_exp_read (e1.value); 9180 e1.value = c_fully_fold (e1.value, false, NULL); 9181 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) 9182 { 9183 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 9184 expr.set_error (); 9185 break; 9186 } 9187 loc = c_parser_peek_token (parser)->location; 9188 t1 = c_parser_type_name (parser); 9189 location_t end_loc = c_parser_peek_token (parser)->get_finish (); 9190 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 9191 "expected %<)%>"); 9192 if (t1 == NULL) 9193 { 9194 expr.set_error (); 9195 } 9196 else 9197 { 9198 tree type_expr = NULL_TREE; 9199 expr.value = c_build_va_arg (start_loc, e1.value, loc, 9200 groktypename (t1, &type_expr, NULL)); 9201 if (type_expr) 9202 { 9203 expr.value = build2 (C_MAYBE_CONST_EXPR, 9204 TREE_TYPE (expr.value), type_expr, 9205 expr.value); 9206 C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true; 9207 } 9208 set_c_expr_source_range (&expr, start_loc, end_loc); 9209 } 9210 } 9211 break; 9212 case RID_OFFSETOF: 9213 { 9214 c_parser_consume_token (parser); 9215 matching_parens parens; 9216 if (!parens.require_open (parser)) 9217 { 9218 expr.set_error (); 9219 break; 9220 } 9221 t1 = c_parser_type_name (parser); 9222 if (t1 == NULL) 9223 parser->error = true; 9224 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) 9225 gcc_assert (parser->error); 9226 if (parser->error) 9227 { 9228 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 9229 expr.set_error (); 9230 break; 9231 } 9232 tree type = groktypename (t1, NULL, NULL); 9233 tree offsetof_ref; 9234 if (type == error_mark_node) 9235 offsetof_ref = error_mark_node; 9236 else 9237 { 9238 offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node); 9239 SET_EXPR_LOCATION (offsetof_ref, loc); 9240 } 9241 /* Parse the second argument to __builtin_offsetof. We 9242 must have one identifier, and beyond that we want to 9243 accept sub structure and sub array references. */ 9244 if (c_parser_next_token_is (parser, CPP_NAME)) 9245 { 9246 c_token *comp_tok = c_parser_peek_token (parser); 9247 offsetof_ref = build_component_ref 9248 (loc, offsetof_ref, comp_tok->value, comp_tok->location); 9249 c_parser_consume_token (parser); 9250 while (c_parser_next_token_is (parser, CPP_DOT) 9251 || c_parser_next_token_is (parser, 9252 CPP_OPEN_SQUARE) 9253 || c_parser_next_token_is (parser, 9254 CPP_DEREF)) 9255 { 9256 if (c_parser_next_token_is (parser, CPP_DEREF)) 9257 { 9258 loc = c_parser_peek_token (parser)->location; 9259 offsetof_ref = build_array_ref (loc, 9260 offsetof_ref, 9261 integer_zero_node); 9262 goto do_dot; 9263 } 9264 else if (c_parser_next_token_is (parser, CPP_DOT)) 9265 { 9266 do_dot: 9267 c_parser_consume_token (parser); 9268 if (c_parser_next_token_is_not (parser, 9269 CPP_NAME)) 9270 { 9271 c_parser_error (parser, "expected identifier"); 9272 break; 9273 } 9274 c_token *comp_tok = c_parser_peek_token (parser); 9275 offsetof_ref = build_component_ref 9276 (loc, offsetof_ref, comp_tok->value, 9277 comp_tok->location); 9278 c_parser_consume_token (parser); 9279 } 9280 else 9281 { 9282 struct c_expr ce; 9283 tree idx; 9284 loc = c_parser_peek_token (parser)->location; 9285 c_parser_consume_token (parser); 9286 ce = c_parser_expression (parser); 9287 ce = convert_lvalue_to_rvalue (loc, ce, false, false); 9288 idx = ce.value; 9289 idx = c_fully_fold (idx, false, NULL); 9290 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, 9291 "expected %<]%>"); 9292 offsetof_ref = build_array_ref (loc, offsetof_ref, idx); 9293 } 9294 } 9295 } 9296 else 9297 c_parser_error (parser, "expected identifier"); 9298 location_t end_loc = c_parser_peek_token (parser)->get_finish (); 9299 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 9300 "expected %<)%>"); 9301 expr.value = fold_offsetof (offsetof_ref); 9302 set_c_expr_source_range (&expr, loc, end_loc); 9303 } 9304 break; 9305 case RID_CHOOSE_EXPR: 9306 { 9307 vec<c_expr_t, va_gc> *cexpr_list; 9308 c_expr_t *e1_p, *e2_p, *e3_p; 9309 tree c; 9310 location_t close_paren_loc; 9311 9312 c_parser_consume_token (parser); 9313 if (!c_parser_get_builtin_args (parser, 9314 "__builtin_choose_expr", 9315 &cexpr_list, true, 9316 &close_paren_loc)) 9317 { 9318 expr.set_error (); 9319 break; 9320 } 9321 9322 if (vec_safe_length (cexpr_list) != 3) 9323 { 9324 error_at (loc, "wrong number of arguments to " 9325 "%<__builtin_choose_expr%>"); 9326 expr.set_error (); 9327 break; 9328 } 9329 9330 e1_p = &(*cexpr_list)[0]; 9331 e2_p = &(*cexpr_list)[1]; 9332 e3_p = &(*cexpr_list)[2]; 9333 9334 c = e1_p->value; 9335 mark_exp_read (e2_p->value); 9336 mark_exp_read (e3_p->value); 9337 if (TREE_CODE (c) != INTEGER_CST 9338 || !INTEGRAL_TYPE_P (TREE_TYPE (c))) 9339 error_at (loc, 9340 "first argument to %<__builtin_choose_expr%> not" 9341 " a constant"); 9342 constant_expression_warning (c); 9343 expr = integer_zerop (c) ? *e3_p : *e2_p; 9344 set_c_expr_source_range (&expr, loc, close_paren_loc); 9345 break; 9346 } 9347 case RID_TYPES_COMPATIBLE_P: 9348 { 9349 c_parser_consume_token (parser); 9350 matching_parens parens; 9351 if (!parens.require_open (parser)) 9352 { 9353 expr.set_error (); 9354 break; 9355 } 9356 t1 = c_parser_type_name (parser); 9357 if (t1 == NULL) 9358 { 9359 expr.set_error (); 9360 break; 9361 } 9362 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) 9363 { 9364 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 9365 expr.set_error (); 9366 break; 9367 } 9368 t2 = c_parser_type_name (parser); 9369 if (t2 == NULL) 9370 { 9371 expr.set_error (); 9372 break; 9373 } 9374 location_t close_paren_loc = c_parser_peek_token (parser)->location; 9375 parens.skip_until_found_close (parser); 9376 tree e1, e2; 9377 e1 = groktypename (t1, NULL, NULL); 9378 e2 = groktypename (t2, NULL, NULL); 9379 if (e1 == error_mark_node || e2 == error_mark_node) 9380 { 9381 expr.set_error (); 9382 break; 9383 } 9384 9385 e1 = TYPE_MAIN_VARIANT (e1); 9386 e2 = TYPE_MAIN_VARIANT (e2); 9387 9388 expr.value 9389 = comptypes (e1, e2) ? integer_one_node : integer_zero_node; 9390 set_c_expr_source_range (&expr, loc, close_paren_loc); 9391 } 9392 break; 9393 case RID_BUILTIN_TGMATH: 9394 { 9395 vec<c_expr_t, va_gc> *cexpr_list; 9396 location_t close_paren_loc; 9397 9398 c_parser_consume_token (parser); 9399 if (!c_parser_get_builtin_args (parser, 9400 "__builtin_tgmath", 9401 &cexpr_list, false, 9402 &close_paren_loc)) 9403 { 9404 expr.set_error (); 9405 break; 9406 } 9407 9408 if (vec_safe_length (cexpr_list) < 3) 9409 { 9410 error_at (loc, "too few arguments to %<__builtin_tgmath%>"); 9411 expr.set_error (); 9412 break; 9413 } 9414 9415 unsigned int i; 9416 c_expr_t *p; 9417 FOR_EACH_VEC_ELT (*cexpr_list, i, p) 9418 *p = convert_lvalue_to_rvalue (loc, *p, true, true); 9419 unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1); 9420 if (nargs == 0) 9421 { 9422 expr.set_error (); 9423 break; 9424 } 9425 if (vec_safe_length (cexpr_list) < nargs) 9426 { 9427 error_at (loc, "too few arguments to %<__builtin_tgmath%>"); 9428 expr.set_error (); 9429 break; 9430 } 9431 unsigned int num_functions = vec_safe_length (cexpr_list) - nargs; 9432 if (num_functions < 2) 9433 { 9434 error_at (loc, "too few arguments to %<__builtin_tgmath%>"); 9435 expr.set_error (); 9436 break; 9437 } 9438 9439 /* The first NUM_FUNCTIONS expressions are the function 9440 pointers. The remaining NARGS expressions are the 9441 arguments that are to be passed to one of those 9442 functions, chosen following <tgmath.h> rules. */ 9443 for (unsigned int j = 1; j < num_functions; j++) 9444 { 9445 unsigned int this_nargs 9446 = check_tgmath_function (&(*cexpr_list)[j], j + 1); 9447 if (this_nargs == 0) 9448 { 9449 expr.set_error (); 9450 goto out; 9451 } 9452 if (this_nargs != nargs) 9453 { 9454 error_at ((*cexpr_list)[j].get_location (), 9455 "argument %u of %<__builtin_tgmath%> has " 9456 "wrong number of arguments", j + 1); 9457 expr.set_error (); 9458 goto out; 9459 } 9460 } 9461 9462 /* The functions all have the same number of arguments. 9463 Determine whether arguments and return types vary in 9464 ways permitted for <tgmath.h> functions. */ 9465 /* The first entry in each of these vectors is for the 9466 return type, subsequent entries for parameter 9467 types. */ 9468 auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1); 9469 auto_vec<tree> parm_first (nargs + 1); 9470 auto_vec<bool> parm_complex (nargs + 1); 9471 auto_vec<bool> parm_varies (nargs + 1); 9472 tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value)); 9473 tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type)); 9474 parm_first.quick_push (first_ret); 9475 parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE); 9476 parm_varies.quick_push (false); 9477 function_args_iterator iter; 9478 tree t; 9479 unsigned int argpos; 9480 FOREACH_FUNCTION_ARGS (first_type, t, iter) 9481 { 9482 if (t == void_type_node) 9483 break; 9484 parm_first.quick_push (TYPE_MAIN_VARIANT (t)); 9485 parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE); 9486 parm_varies.quick_push (false); 9487 } 9488 for (unsigned int j = 1; j < num_functions; j++) 9489 { 9490 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value)); 9491 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type)); 9492 if (ret != parm_first[0]) 9493 { 9494 parm_varies[0] = true; 9495 if (!SCALAR_FLOAT_TYPE_P (parm_first[0]) 9496 && !COMPLEX_FLOAT_TYPE_P (parm_first[0])) 9497 { 9498 error_at ((*cexpr_list)[0].get_location (), 9499 "invalid type-generic return type for " 9500 "argument %u of %<__builtin_tgmath%>", 9501 1); 9502 expr.set_error (); 9503 goto out; 9504 } 9505 if (!SCALAR_FLOAT_TYPE_P (ret) 9506 && !COMPLEX_FLOAT_TYPE_P (ret)) 9507 { 9508 error_at ((*cexpr_list)[j].get_location (), 9509 "invalid type-generic return type for " 9510 "argument %u of %<__builtin_tgmath%>", 9511 j + 1); 9512 expr.set_error (); 9513 goto out; 9514 } 9515 } 9516 if (TREE_CODE (ret) == COMPLEX_TYPE) 9517 parm_complex[0] = true; 9518 argpos = 1; 9519 FOREACH_FUNCTION_ARGS (type, t, iter) 9520 { 9521 if (t == void_type_node) 9522 break; 9523 t = TYPE_MAIN_VARIANT (t); 9524 if (t != parm_first[argpos]) 9525 { 9526 parm_varies[argpos] = true; 9527 if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos]) 9528 && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos])) 9529 { 9530 error_at ((*cexpr_list)[0].get_location (), 9531 "invalid type-generic type for " 9532 "argument %u of argument %u of " 9533 "%<__builtin_tgmath%>", argpos, 1); 9534 expr.set_error (); 9535 goto out; 9536 } 9537 if (!SCALAR_FLOAT_TYPE_P (t) 9538 && !COMPLEX_FLOAT_TYPE_P (t)) 9539 { 9540 error_at ((*cexpr_list)[j].get_location (), 9541 "invalid type-generic type for " 9542 "argument %u of argument %u of " 9543 "%<__builtin_tgmath%>", argpos, j + 1); 9544 expr.set_error (); 9545 goto out; 9546 } 9547 } 9548 if (TREE_CODE (t) == COMPLEX_TYPE) 9549 parm_complex[argpos] = true; 9550 argpos++; 9551 } 9552 } 9553 enum tgmath_parm_kind max_variation = tgmath_fixed; 9554 for (unsigned int j = 0; j <= nargs; j++) 9555 { 9556 enum tgmath_parm_kind this_kind; 9557 if (parm_varies[j]) 9558 { 9559 if (parm_complex[j]) 9560 max_variation = this_kind = tgmath_complex; 9561 else 9562 { 9563 this_kind = tgmath_real; 9564 if (max_variation != tgmath_complex) 9565 max_variation = tgmath_real; 9566 } 9567 } 9568 else 9569 this_kind = tgmath_fixed; 9570 parm_kind.quick_push (this_kind); 9571 } 9572 if (max_variation == tgmath_fixed) 9573 { 9574 error_at (loc, "function arguments of %<__builtin_tgmath%> " 9575 "all have the same type"); 9576 expr.set_error (); 9577 break; 9578 } 9579 9580 /* Identify a parameter (not the return type) that varies, 9581 including with complex types if any variation includes 9582 complex types; there must be at least one such 9583 parameter. */ 9584 unsigned int tgarg = 0; 9585 for (unsigned int j = 1; j <= nargs; j++) 9586 if (parm_kind[j] == max_variation) 9587 { 9588 tgarg = j; 9589 break; 9590 } 9591 if (tgarg == 0) 9592 { 9593 error_at (loc, "function arguments of %<__builtin_tgmath%> " 9594 "lack type-generic parameter"); 9595 expr.set_error (); 9596 break; 9597 } 9598 9599 /* Determine the type of the relevant parameter for each 9600 function. */ 9601 auto_vec<tree> tg_type (num_functions); 9602 for (unsigned int j = 0; j < num_functions; j++) 9603 { 9604 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value)); 9605 argpos = 1; 9606 FOREACH_FUNCTION_ARGS (type, t, iter) 9607 { 9608 if (argpos == tgarg) 9609 { 9610 tg_type.quick_push (TYPE_MAIN_VARIANT (t)); 9611 break; 9612 } 9613 argpos++; 9614 } 9615 } 9616 9617 /* Verify that the corresponding types are different for 9618 all the listed functions. Also determine whether all 9619 the types are complex, whether all the types are 9620 standard or binary, and whether all the types are 9621 decimal. */ 9622 bool all_complex = true; 9623 bool all_binary = true; 9624 bool all_decimal = true; 9625 hash_set<tree> tg_types; 9626 FOR_EACH_VEC_ELT (tg_type, i, t) 9627 { 9628 if (TREE_CODE (t) == COMPLEX_TYPE) 9629 all_decimal = false; 9630 else 9631 { 9632 all_complex = false; 9633 if (DECIMAL_FLOAT_TYPE_P (t)) 9634 all_binary = false; 9635 else 9636 all_decimal = false; 9637 } 9638 if (tg_types.add (t)) 9639 { 9640 error_at ((*cexpr_list)[i].get_location (), 9641 "duplicate type-generic parameter type for " 9642 "function argument %u of %<__builtin_tgmath%>", 9643 i + 1); 9644 expr.set_error (); 9645 goto out; 9646 } 9647 } 9648 9649 /* Verify that other parameters and the return type whose 9650 types vary have their types varying in the correct 9651 way. */ 9652 for (unsigned int j = 0; j < num_functions; j++) 9653 { 9654 tree exp_type = tg_type[j]; 9655 tree exp_real_type = exp_type; 9656 if (TREE_CODE (exp_type) == COMPLEX_TYPE) 9657 exp_real_type = TREE_TYPE (exp_type); 9658 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value)); 9659 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type)); 9660 if ((parm_kind[0] == tgmath_complex && ret != exp_type) 9661 || (parm_kind[0] == tgmath_real && ret != exp_real_type)) 9662 { 9663 error_at ((*cexpr_list)[j].get_location (), 9664 "bad return type for function argument %u " 9665 "of %<__builtin_tgmath%>", j + 1); 9666 expr.set_error (); 9667 goto out; 9668 } 9669 argpos = 1; 9670 FOREACH_FUNCTION_ARGS (type, t, iter) 9671 { 9672 if (t == void_type_node) 9673 break; 9674 t = TYPE_MAIN_VARIANT (t); 9675 if ((parm_kind[argpos] == tgmath_complex 9676 && t != exp_type) 9677 || (parm_kind[argpos] == tgmath_real 9678 && t != exp_real_type)) 9679 { 9680 error_at ((*cexpr_list)[j].get_location (), 9681 "bad type for argument %u of " 9682 "function argument %u of " 9683 "%<__builtin_tgmath%>", argpos, j + 1); 9684 expr.set_error (); 9685 goto out; 9686 } 9687 argpos++; 9688 } 9689 } 9690 9691 /* The functions listed are a valid set of functions for a 9692 <tgmath.h> macro to select between. Identify the 9693 matching function, if any. First, the argument types 9694 must be combined following <tgmath.h> rules. Integer 9695 types are treated as _Decimal64 if any type-generic 9696 argument is decimal, or if the only alternatives for 9697 type-generic arguments are of decimal types, and are 9698 otherwise treated as double (or _Complex double for 9699 complex integer types, or _Float64 or _Complex _Float64 9700 if all the return types are the same _FloatN or 9701 _FloatNx type). After that adjustment, types are 9702 combined following the usual arithmetic conversions. 9703 If the function only accepts complex arguments, a 9704 complex type is produced. */ 9705 bool arg_complex = all_complex; 9706 bool arg_binary = all_binary; 9707 bool arg_int_decimal = all_decimal; 9708 for (unsigned int j = 1; j <= nargs; j++) 9709 { 9710 if (parm_kind[j] == tgmath_fixed) 9711 continue; 9712 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1]; 9713 tree type = TREE_TYPE (ce->value); 9714 if (!INTEGRAL_TYPE_P (type) 9715 && !SCALAR_FLOAT_TYPE_P (type) 9716 && TREE_CODE (type) != COMPLEX_TYPE) 9717 { 9718 error_at (ce->get_location (), 9719 "invalid type of argument %u of type-generic " 9720 "function", j); 9721 expr.set_error (); 9722 goto out; 9723 } 9724 if (DECIMAL_FLOAT_TYPE_P (type)) 9725 { 9726 arg_int_decimal = true; 9727 if (all_complex) 9728 { 9729 error_at (ce->get_location (), 9730 "decimal floating-point argument %u to " 9731 "complex-only type-generic function", j); 9732 expr.set_error (); 9733 goto out; 9734 } 9735 else if (all_binary) 9736 { 9737 error_at (ce->get_location (), 9738 "decimal floating-point argument %u to " 9739 "binary-only type-generic function", j); 9740 expr.set_error (); 9741 goto out; 9742 } 9743 else if (arg_complex) 9744 { 9745 error_at (ce->get_location (), 9746 "both complex and decimal floating-point " 9747 "arguments to type-generic function"); 9748 expr.set_error (); 9749 goto out; 9750 } 9751 else if (arg_binary) 9752 { 9753 error_at (ce->get_location (), 9754 "both binary and decimal floating-point " 9755 "arguments to type-generic function"); 9756 expr.set_error (); 9757 goto out; 9758 } 9759 } 9760 else if (TREE_CODE (type) == COMPLEX_TYPE) 9761 { 9762 arg_complex = true; 9763 if (COMPLEX_FLOAT_TYPE_P (type)) 9764 arg_binary = true; 9765 if (all_decimal) 9766 { 9767 error_at (ce->get_location (), 9768 "complex argument %u to " 9769 "decimal-only type-generic function", j); 9770 expr.set_error (); 9771 goto out; 9772 } 9773 else if (arg_int_decimal) 9774 { 9775 error_at (ce->get_location (), 9776 "both complex and decimal floating-point " 9777 "arguments to type-generic function"); 9778 expr.set_error (); 9779 goto out; 9780 } 9781 } 9782 else if (SCALAR_FLOAT_TYPE_P (type)) 9783 { 9784 arg_binary = true; 9785 if (all_decimal) 9786 { 9787 error_at (ce->get_location (), 9788 "binary argument %u to " 9789 "decimal-only type-generic function", j); 9790 expr.set_error (); 9791 goto out; 9792 } 9793 else if (arg_int_decimal) 9794 { 9795 error_at (ce->get_location (), 9796 "both binary and decimal floating-point " 9797 "arguments to type-generic function"); 9798 expr.set_error (); 9799 goto out; 9800 } 9801 } 9802 } 9803 /* For a macro rounding its result to a narrower type, map 9804 integer types to _Float64 not double if the return type 9805 is a _FloatN or _FloatNx type. */ 9806 bool arg_int_float64 = false; 9807 if (parm_kind[0] == tgmath_fixed 9808 && SCALAR_FLOAT_TYPE_P (parm_first[0]) 9809 && float64_type_node != NULL_TREE) 9810 for (unsigned int j = 0; j < NUM_FLOATN_NX_TYPES; j++) 9811 if (parm_first[0] == FLOATN_TYPE_NODE (j)) 9812 { 9813 arg_int_float64 = true; 9814 break; 9815 } 9816 tree arg_real = NULL_TREE; 9817 for (unsigned int j = 1; j <= nargs; j++) 9818 { 9819 if (parm_kind[j] == tgmath_fixed) 9820 continue; 9821 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1]; 9822 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value)); 9823 if (TREE_CODE (type) == COMPLEX_TYPE) 9824 type = TREE_TYPE (type); 9825 if (INTEGRAL_TYPE_P (type)) 9826 type = (arg_int_decimal 9827 ? dfloat64_type_node 9828 : arg_int_float64 9829 ? float64_type_node 9830 : double_type_node); 9831 if (arg_real == NULL_TREE) 9832 arg_real = type; 9833 else 9834 arg_real = common_type (arg_real, type); 9835 if (arg_real == error_mark_node) 9836 { 9837 expr.set_error (); 9838 goto out; 9839 } 9840 } 9841 tree arg_type = (arg_complex 9842 ? build_complex_type (arg_real) 9843 : arg_real); 9844 9845 /* Look for a function to call with type-generic parameter 9846 type ARG_TYPE. */ 9847 c_expr_t *fn = NULL; 9848 for (unsigned int j = 0; j < num_functions; j++) 9849 { 9850 if (tg_type[j] == arg_type) 9851 { 9852 fn = &(*cexpr_list)[j]; 9853 break; 9854 } 9855 } 9856 if (fn == NULL 9857 && parm_kind[0] == tgmath_fixed 9858 && SCALAR_FLOAT_TYPE_P (parm_first[0])) 9859 { 9860 /* Presume this is a macro that rounds its result to a 9861 narrower type, and look for the first function with 9862 at least the range and precision of the argument 9863 type. */ 9864 for (unsigned int j = 0; j < num_functions; j++) 9865 { 9866 if (arg_complex 9867 != (TREE_CODE (tg_type[j]) == COMPLEX_TYPE)) 9868 continue; 9869 tree real_tg_type = (arg_complex 9870 ? TREE_TYPE (tg_type[j]) 9871 : tg_type[j]); 9872 if (DECIMAL_FLOAT_TYPE_P (arg_real) 9873 != DECIMAL_FLOAT_TYPE_P (real_tg_type)) 9874 continue; 9875 scalar_float_mode arg_mode 9876 = SCALAR_FLOAT_TYPE_MODE (arg_real); 9877 scalar_float_mode tg_mode 9878 = SCALAR_FLOAT_TYPE_MODE (real_tg_type); 9879 const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode); 9880 const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode); 9881 if (arg_fmt->b == tg_fmt->b 9882 && arg_fmt->p <= tg_fmt->p 9883 && arg_fmt->emax <= tg_fmt->emax 9884 && (arg_fmt->emin - arg_fmt->p 9885 >= tg_fmt->emin - tg_fmt->p)) 9886 { 9887 fn = &(*cexpr_list)[j]; 9888 break; 9889 } 9890 } 9891 } 9892 if (fn == NULL) 9893 { 9894 error_at (loc, "no matching function for type-generic call"); 9895 expr.set_error (); 9896 break; 9897 } 9898 9899 /* Construct a call to FN. */ 9900 vec<tree, va_gc> *args; 9901 vec_alloc (args, nargs); 9902 vec<tree, va_gc> *origtypes; 9903 vec_alloc (origtypes, nargs); 9904 auto_vec<location_t> arg_loc (nargs); 9905 for (unsigned int j = 0; j < nargs; j++) 9906 { 9907 c_expr_t *ce = &(*cexpr_list)[num_functions + j]; 9908 args->quick_push (ce->value); 9909 arg_loc.quick_push (ce->get_location ()); 9910 origtypes->quick_push (ce->original_type); 9911 } 9912 expr.value = c_build_function_call_vec (loc, arg_loc, fn->value, 9913 args, origtypes); 9914 set_c_expr_source_range (&expr, loc, close_paren_loc); 9915 break; 9916 } 9917 case RID_BUILTIN_CALL_WITH_STATIC_CHAIN: 9918 { 9919 vec<c_expr_t, va_gc> *cexpr_list; 9920 c_expr_t *e2_p; 9921 tree chain_value; 9922 location_t close_paren_loc; 9923 9924 c_parser_consume_token (parser); 9925 if (!c_parser_get_builtin_args (parser, 9926 "__builtin_call_with_static_chain", 9927 &cexpr_list, false, 9928 &close_paren_loc)) 9929 { 9930 expr.set_error (); 9931 break; 9932 } 9933 if (vec_safe_length (cexpr_list) != 2) 9934 { 9935 error_at (loc, "wrong number of arguments to " 9936 "%<__builtin_call_with_static_chain%>"); 9937 expr.set_error (); 9938 break; 9939 } 9940 9941 expr = (*cexpr_list)[0]; 9942 e2_p = &(*cexpr_list)[1]; 9943 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true); 9944 chain_value = e2_p->value; 9945 mark_exp_read (chain_value); 9946 9947 if (TREE_CODE (expr.value) != CALL_EXPR) 9948 error_at (loc, "first argument to " 9949 "%<__builtin_call_with_static_chain%> " 9950 "must be a call expression"); 9951 else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE) 9952 error_at (loc, "second argument to " 9953 "%<__builtin_call_with_static_chain%> " 9954 "must be a pointer type"); 9955 else 9956 CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value; 9957 set_c_expr_source_range (&expr, loc, close_paren_loc); 9958 break; 9959 } 9960 case RID_BUILTIN_COMPLEX: 9961 { 9962 vec<c_expr_t, va_gc> *cexpr_list; 9963 c_expr_t *e1_p, *e2_p; 9964 location_t close_paren_loc; 9965 9966 c_parser_consume_token (parser); 9967 if (!c_parser_get_builtin_args (parser, 9968 "__builtin_complex", 9969 &cexpr_list, false, 9970 &close_paren_loc)) 9971 { 9972 expr.set_error (); 9973 break; 9974 } 9975 9976 if (vec_safe_length (cexpr_list) != 2) 9977 { 9978 error_at (loc, "wrong number of arguments to " 9979 "%<__builtin_complex%>"); 9980 expr.set_error (); 9981 break; 9982 } 9983 9984 e1_p = &(*cexpr_list)[0]; 9985 e2_p = &(*cexpr_list)[1]; 9986 9987 *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true); 9988 if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR) 9989 e1_p->value = convert (TREE_TYPE (e1_p->value), 9990 TREE_OPERAND (e1_p->value, 0)); 9991 *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true); 9992 if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR) 9993 e2_p->value = convert (TREE_TYPE (e2_p->value), 9994 TREE_OPERAND (e2_p->value, 0)); 9995 if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value)) 9996 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value)) 9997 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)) 9998 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))) 9999 { 10000 error_at (loc, "%<__builtin_complex%> operand " 10001 "not of real binary floating-point type"); 10002 expr.set_error (); 10003 break; 10004 } 10005 if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value)) 10006 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value))) 10007 { 10008 error_at (loc, 10009 "%<__builtin_complex%> operands of different types"); 10010 expr.set_error (); 10011 break; 10012 } 10013 pedwarn_c90 (loc, OPT_Wpedantic, 10014 "ISO C90 does not support complex types"); 10015 expr.value = build2_loc (loc, COMPLEX_EXPR, 10016 build_complex_type 10017 (TYPE_MAIN_VARIANT 10018 (TREE_TYPE (e1_p->value))), 10019 e1_p->value, e2_p->value); 10020 set_c_expr_source_range (&expr, loc, close_paren_loc); 10021 break; 10022 } 10023 case RID_BUILTIN_SHUFFLE: 10024 { 10025 vec<c_expr_t, va_gc> *cexpr_list; 10026 unsigned int i; 10027 c_expr_t *p; 10028 location_t close_paren_loc; 10029 10030 c_parser_consume_token (parser); 10031 if (!c_parser_get_builtin_args (parser, 10032 "__builtin_shuffle", 10033 &cexpr_list, false, 10034 &close_paren_loc)) 10035 { 10036 expr.set_error (); 10037 break; 10038 } 10039 10040 FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p) 10041 *p = convert_lvalue_to_rvalue (loc, *p, true, true); 10042 10043 if (vec_safe_length (cexpr_list) == 2) 10044 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value, 10045 NULL_TREE, 10046 (*cexpr_list)[1].value); 10047 10048 else if (vec_safe_length (cexpr_list) == 3) 10049 expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value, 10050 (*cexpr_list)[1].value, 10051 (*cexpr_list)[2].value); 10052 else 10053 { 10054 error_at (loc, "wrong number of arguments to " 10055 "%<__builtin_shuffle%>"); 10056 expr.set_error (); 10057 } 10058 set_c_expr_source_range (&expr, loc, close_paren_loc); 10059 break; 10060 } 10061 case RID_BUILTIN_CONVERTVECTOR: 10062 { 10063 location_t start_loc = loc; 10064 c_parser_consume_token (parser); 10065 matching_parens parens; 10066 if (!parens.require_open (parser)) 10067 { 10068 expr.set_error (); 10069 break; 10070 } 10071 e1 = c_parser_expr_no_commas (parser, NULL); 10072 mark_exp_read (e1.value); 10073 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) 10074 { 10075 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 10076 expr.set_error (); 10077 break; 10078 } 10079 loc = c_parser_peek_token (parser)->location; 10080 t1 = c_parser_type_name (parser); 10081 location_t end_loc = c_parser_peek_token (parser)->get_finish (); 10082 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 10083 "expected %<)%>"); 10084 if (t1 == NULL) 10085 expr.set_error (); 10086 else 10087 { 10088 tree type_expr = NULL_TREE; 10089 expr.value = c_build_vec_convert (start_loc, e1.value, loc, 10090 groktypename (t1, &type_expr, 10091 NULL)); 10092 set_c_expr_source_range (&expr, start_loc, end_loc); 10093 } 10094 } 10095 break; 10096 case RID_AT_SELECTOR: 10097 { 10098 gcc_assert (c_dialect_objc ()); 10099 c_parser_consume_token (parser); 10100 matching_parens parens; 10101 if (!parens.require_open (parser)) 10102 { 10103 expr.set_error (); 10104 break; 10105 } 10106 tree sel = c_parser_objc_selector_arg (parser); 10107 location_t close_loc = c_parser_peek_token (parser)->location; 10108 parens.skip_until_found_close (parser); 10109 expr.value = objc_build_selector_expr (loc, sel); 10110 set_c_expr_source_range (&expr, loc, close_loc); 10111 } 10112 break; 10113 case RID_AT_PROTOCOL: 10114 { 10115 gcc_assert (c_dialect_objc ()); 10116 c_parser_consume_token (parser); 10117 matching_parens parens; 10118 if (!parens.require_open (parser)) 10119 { 10120 expr.set_error (); 10121 break; 10122 } 10123 if (c_parser_next_token_is_not (parser, CPP_NAME)) 10124 { 10125 c_parser_error (parser, "expected identifier"); 10126 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 10127 expr.set_error (); 10128 break; 10129 } 10130 tree id = c_parser_peek_token (parser)->value; 10131 c_parser_consume_token (parser); 10132 location_t close_loc = c_parser_peek_token (parser)->location; 10133 parens.skip_until_found_close (parser); 10134 expr.value = objc_build_protocol_expr (id); 10135 set_c_expr_source_range (&expr, loc, close_loc); 10136 } 10137 break; 10138 case RID_AT_ENCODE: 10139 { 10140 /* Extension to support C-structures in the archiver. */ 10141 gcc_assert (c_dialect_objc ()); 10142 c_parser_consume_token (parser); 10143 matching_parens parens; 10144 if (!parens.require_open (parser)) 10145 { 10146 expr.set_error (); 10147 break; 10148 } 10149 t1 = c_parser_type_name (parser); 10150 if (t1 == NULL) 10151 { 10152 expr.set_error (); 10153 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 10154 break; 10155 } 10156 location_t close_loc = c_parser_peek_token (parser)->location; 10157 parens.skip_until_found_close (parser); 10158 tree type = groktypename (t1, NULL, NULL); 10159 expr.value = objc_build_encode_expr (type); 10160 set_c_expr_source_range (&expr, loc, close_loc); 10161 } 10162 break; 10163 case RID_GENERIC: 10164 expr = c_parser_generic_selection (parser); 10165 break; 10166 default: 10167 c_parser_error (parser, "expected expression"); 10168 expr.set_error (); 10169 break; 10170 } 10171 break; 10172 case CPP_OPEN_SQUARE: 10173 if (c_dialect_objc ()) 10174 { 10175 tree receiver, args; 10176 c_parser_consume_token (parser); 10177 receiver = c_parser_objc_receiver (parser); 10178 args = c_parser_objc_message_args (parser); 10179 location_t close_loc = c_parser_peek_token (parser)->location; 10180 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, 10181 "expected %<]%>"); 10182 expr.value = objc_build_message_expr (receiver, args); 10183 set_c_expr_source_range (&expr, loc, close_loc); 10184 break; 10185 } 10186 /* Else fall through to report error. */ 10187 /* FALLTHRU */ 10188 default: 10189 c_parser_error (parser, "expected expression"); 10190 expr.set_error (); 10191 break; 10192 } 10193 out: 10194 return c_parser_postfix_expression_after_primary 10195 (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr); 10196 } 10197 10198 /* Parse a postfix expression after a parenthesized type name: the 10199 brace-enclosed initializer of a compound literal, possibly followed 10200 by some postfix operators. This is separate because it is not 10201 possible to tell until after the type name whether a cast 10202 expression has a cast or a compound literal, or whether the operand 10203 of sizeof is a parenthesized type name or starts with a compound 10204 literal. TYPE_LOC is the location where TYPE_NAME starts--the 10205 location of the first token after the parentheses around the type 10206 name. */ 10207 10208 static struct c_expr 10209 c_parser_postfix_expression_after_paren_type (c_parser *parser, 10210 struct c_type_name *type_name, 10211 location_t type_loc) 10212 { 10213 tree type; 10214 struct c_expr init; 10215 bool non_const; 10216 struct c_expr expr; 10217 location_t start_loc; 10218 tree type_expr = NULL_TREE; 10219 bool type_expr_const = true; 10220 check_compound_literal_type (type_loc, type_name); 10221 rich_location richloc (line_table, type_loc); 10222 start_init (NULL_TREE, NULL, 0, &richloc); 10223 type = groktypename (type_name, &type_expr, &type_expr_const); 10224 start_loc = c_parser_peek_token (parser)->location; 10225 if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type)) 10226 { 10227 error_at (type_loc, "compound literal has variable size"); 10228 type = error_mark_node; 10229 } 10230 init = c_parser_braced_init (parser, type, false, NULL); 10231 finish_init (); 10232 maybe_warn_string_init (type_loc, type, init); 10233 10234 if (type != error_mark_node 10235 && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type)) 10236 && current_function_decl) 10237 { 10238 error ("compound literal qualified by address-space qualifier"); 10239 type = error_mark_node; 10240 } 10241 10242 pedwarn_c90 (start_loc, OPT_Wpedantic, "ISO C90 forbids compound literals"); 10243 non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR) 10244 ? CONSTRUCTOR_NON_CONST (init.value) 10245 : init.original_code == C_MAYBE_CONST_EXPR); 10246 non_const |= !type_expr_const; 10247 unsigned int alignas_align = 0; 10248 if (type != error_mark_node 10249 && type_name->specs->align_log != -1) 10250 { 10251 alignas_align = 1U << type_name->specs->align_log; 10252 if (alignas_align < min_align_of_type (type)) 10253 { 10254 error_at (type_name->specs->locations[cdw_alignas], 10255 "%<_Alignas%> specifiers cannot reduce " 10256 "alignment of compound literal"); 10257 alignas_align = 0; 10258 } 10259 } 10260 expr.value = build_compound_literal (start_loc, type, init.value, non_const, 10261 alignas_align); 10262 set_c_expr_source_range (&expr, init.src_range); 10263 expr.original_code = ERROR_MARK; 10264 expr.original_type = NULL; 10265 if (type != error_mark_node 10266 && expr.value != error_mark_node 10267 && type_expr) 10268 { 10269 if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR) 10270 { 10271 gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE); 10272 C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr; 10273 } 10274 else 10275 { 10276 gcc_assert (!non_const); 10277 expr.value = build2 (C_MAYBE_CONST_EXPR, type, 10278 type_expr, expr.value); 10279 } 10280 } 10281 return c_parser_postfix_expression_after_primary (parser, start_loc, expr); 10282 } 10283 10284 /* Callback function for sizeof_pointer_memaccess_warning to compare 10285 types. */ 10286 10287 static bool 10288 sizeof_ptr_memacc_comptypes (tree type1, tree type2) 10289 { 10290 return comptypes (type1, type2) == 1; 10291 } 10292 10293 /* Warn for patterns where abs-like function appears to be used incorrectly, 10294 gracefully ignore any non-abs-like function. The warning location should 10295 be LOC. FNDECL is the declaration of called function, it must be a 10296 BUILT_IN_NORMAL function. ARG is the first and only argument of the 10297 call. */ 10298 10299 static void 10300 warn_for_abs (location_t loc, tree fndecl, tree arg) 10301 { 10302 /* Avoid warning in unreachable subexpressions. */ 10303 if (c_inhibit_evaluation_warnings) 10304 return; 10305 10306 tree atype = TREE_TYPE (arg); 10307 10308 /* Casts from pointers (and thus arrays and fndecls) will generate 10309 -Wint-conversion warnings. Most other wrong types hopefully lead to type 10310 mismatch errors. TODO: Think about what to do with FIXED_POINT_TYPE_P 10311 types and possibly other exotic types. */ 10312 if (!INTEGRAL_TYPE_P (atype) 10313 && !SCALAR_FLOAT_TYPE_P (atype) 10314 && TREE_CODE (atype) != COMPLEX_TYPE) 10315 return; 10316 10317 enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl); 10318 10319 switch (fcode) 10320 { 10321 case BUILT_IN_ABS: 10322 case BUILT_IN_LABS: 10323 case BUILT_IN_LLABS: 10324 case BUILT_IN_IMAXABS: 10325 if (!INTEGRAL_TYPE_P (atype)) 10326 { 10327 if (SCALAR_FLOAT_TYPE_P (atype)) 10328 warning_at (loc, OPT_Wabsolute_value, 10329 "using integer absolute value function %qD when " 10330 "argument is of floating-point type %qT", 10331 fndecl, atype); 10332 else if (TREE_CODE (atype) == COMPLEX_TYPE) 10333 warning_at (loc, OPT_Wabsolute_value, 10334 "using integer absolute value function %qD when " 10335 "argument is of complex type %qT", fndecl, atype); 10336 else 10337 gcc_unreachable (); 10338 return; 10339 } 10340 if (TYPE_UNSIGNED (atype)) 10341 warning_at (loc, OPT_Wabsolute_value, 10342 "taking the absolute value of unsigned type %qT " 10343 "has no effect", atype); 10344 break; 10345 10346 CASE_FLT_FN (BUILT_IN_FABS): 10347 CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS): 10348 if (!SCALAR_FLOAT_TYPE_P (atype) 10349 || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype))) 10350 { 10351 if (INTEGRAL_TYPE_P (atype)) 10352 warning_at (loc, OPT_Wabsolute_value, 10353 "using floating-point absolute value function %qD " 10354 "when argument is of integer type %qT", fndecl, atype); 10355 else if (DECIMAL_FLOAT_TYPE_P (atype)) 10356 warning_at (loc, OPT_Wabsolute_value, 10357 "using floating-point absolute value function %qD " 10358 "when argument is of decimal floating-point type %qT", 10359 fndecl, atype); 10360 else if (TREE_CODE (atype) == COMPLEX_TYPE) 10361 warning_at (loc, OPT_Wabsolute_value, 10362 "using floating-point absolute value function %qD when " 10363 "argument is of complex type %qT", fndecl, atype); 10364 else 10365 gcc_unreachable (); 10366 return; 10367 } 10368 break; 10369 10370 CASE_FLT_FN (BUILT_IN_CABS): 10371 if (TREE_CODE (atype) != COMPLEX_TYPE) 10372 { 10373 if (INTEGRAL_TYPE_P (atype)) 10374 warning_at (loc, OPT_Wabsolute_value, 10375 "using complex absolute value function %qD when " 10376 "argument is of integer type %qT", fndecl, atype); 10377 else if (SCALAR_FLOAT_TYPE_P (atype)) 10378 warning_at (loc, OPT_Wabsolute_value, 10379 "using complex absolute value function %qD when " 10380 "argument is of floating-point type %qT", 10381 fndecl, atype); 10382 else 10383 gcc_unreachable (); 10384 10385 return; 10386 } 10387 break; 10388 10389 case BUILT_IN_FABSD32: 10390 case BUILT_IN_FABSD64: 10391 case BUILT_IN_FABSD128: 10392 if (!DECIMAL_FLOAT_TYPE_P (atype)) 10393 { 10394 if (INTEGRAL_TYPE_P (atype)) 10395 warning_at (loc, OPT_Wabsolute_value, 10396 "using decimal floating-point absolute value " 10397 "function %qD when argument is of integer type %qT", 10398 fndecl, atype); 10399 else if (SCALAR_FLOAT_TYPE_P (atype)) 10400 warning_at (loc, OPT_Wabsolute_value, 10401 "using decimal floating-point absolute value " 10402 "function %qD when argument is of floating-point " 10403 "type %qT", fndecl, atype); 10404 else if (TREE_CODE (atype) == COMPLEX_TYPE) 10405 warning_at (loc, OPT_Wabsolute_value, 10406 "using decimal floating-point absolute value " 10407 "function %qD when argument is of complex type %qT", 10408 fndecl, atype); 10409 else 10410 gcc_unreachable (); 10411 return; 10412 } 10413 break; 10414 10415 default: 10416 return; 10417 } 10418 10419 if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl))) 10420 return; 10421 10422 tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl))); 10423 if (TREE_CODE (atype) == COMPLEX_TYPE) 10424 { 10425 gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE); 10426 atype = TREE_TYPE (atype); 10427 ftype = TREE_TYPE (ftype); 10428 } 10429 10430 if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype)) 10431 warning_at (loc, OPT_Wabsolute_value, 10432 "absolute value function %qD given an argument of type %qT " 10433 "but has parameter of type %qT which may cause truncation " 10434 "of value", fndecl, atype, ftype); 10435 } 10436 10437 10438 /* Parse a postfix expression after the initial primary or compound 10439 literal; that is, parse a series of postfix operators. 10440 10441 EXPR_LOC is the location of the primary expression. */ 10442 10443 static struct c_expr 10444 c_parser_postfix_expression_after_primary (c_parser *parser, 10445 location_t expr_loc, 10446 struct c_expr expr) 10447 { 10448 struct c_expr orig_expr; 10449 tree ident, idx; 10450 location_t sizeof_arg_loc[3], comp_loc; 10451 tree sizeof_arg[3]; 10452 unsigned int literal_zero_mask; 10453 unsigned int i; 10454 vec<tree, va_gc> *exprlist; 10455 vec<tree, va_gc> *origtypes = NULL; 10456 vec<location_t> arg_loc = vNULL; 10457 location_t start; 10458 location_t finish; 10459 10460 while (true) 10461 { 10462 location_t op_loc = c_parser_peek_token (parser)->location; 10463 switch (c_parser_peek_token (parser)->type) 10464 { 10465 case CPP_OPEN_SQUARE: 10466 /* Array reference. */ 10467 c_parser_consume_token (parser); 10468 idx = c_parser_expression (parser).value; 10469 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, 10470 "expected %<]%>"); 10471 start = expr.get_start (); 10472 finish = parser->tokens_buf[0].location; 10473 expr.value = build_array_ref (op_loc, expr.value, idx); 10474 set_c_expr_source_range (&expr, start, finish); 10475 expr.original_code = ERROR_MARK; 10476 expr.original_type = NULL; 10477 break; 10478 case CPP_OPEN_PAREN: 10479 /* Function call. */ 10480 c_parser_consume_token (parser); 10481 for (i = 0; i < 3; i++) 10482 { 10483 sizeof_arg[i] = NULL_TREE; 10484 sizeof_arg_loc[i] = UNKNOWN_LOCATION; 10485 } 10486 literal_zero_mask = 0; 10487 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 10488 exprlist = NULL; 10489 else 10490 exprlist = c_parser_expr_list (parser, true, false, &origtypes, 10491 sizeof_arg_loc, sizeof_arg, 10492 &arg_loc, &literal_zero_mask); 10493 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 10494 "expected %<)%>"); 10495 orig_expr = expr; 10496 mark_exp_read (expr.value); 10497 if (warn_sizeof_pointer_memaccess) 10498 sizeof_pointer_memaccess_warning (sizeof_arg_loc, 10499 expr.value, exprlist, 10500 sizeof_arg, 10501 sizeof_ptr_memacc_comptypes); 10502 if (TREE_CODE (expr.value) == FUNCTION_DECL) 10503 { 10504 if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET) 10505 && vec_safe_length (exprlist) == 3) 10506 { 10507 tree arg0 = (*exprlist)[0]; 10508 tree arg2 = (*exprlist)[2]; 10509 warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask); 10510 } 10511 if (warn_absolute_value 10512 && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL) 10513 && vec_safe_length (exprlist) == 1) 10514 warn_for_abs (expr_loc, expr.value, (*exprlist)[0]); 10515 } 10516 10517 start = expr.get_start (); 10518 finish = parser->tokens_buf[0].get_finish (); 10519 expr.value 10520 = c_build_function_call_vec (expr_loc, arg_loc, expr.value, 10521 exprlist, origtypes); 10522 set_c_expr_source_range (&expr, start, finish); 10523 10524 expr.original_code = ERROR_MARK; 10525 if (TREE_CODE (expr.value) == INTEGER_CST 10526 && TREE_CODE (orig_expr.value) == FUNCTION_DECL 10527 && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P)) 10528 expr.original_code = C_MAYBE_CONST_EXPR; 10529 expr.original_type = NULL; 10530 if (exprlist) 10531 { 10532 release_tree_vector (exprlist); 10533 release_tree_vector (origtypes); 10534 } 10535 arg_loc.release (); 10536 break; 10537 case CPP_DOT: 10538 /* Structure element reference. */ 10539 c_parser_consume_token (parser); 10540 expr = default_function_array_conversion (expr_loc, expr); 10541 if (c_parser_next_token_is (parser, CPP_NAME)) 10542 { 10543 c_token *comp_tok = c_parser_peek_token (parser); 10544 ident = comp_tok->value; 10545 comp_loc = comp_tok->location; 10546 } 10547 else 10548 { 10549 c_parser_error (parser, "expected identifier"); 10550 expr.set_error (); 10551 expr.original_code = ERROR_MARK; 10552 expr.original_type = NULL; 10553 return expr; 10554 } 10555 start = expr.get_start (); 10556 finish = c_parser_peek_token (parser)->get_finish (); 10557 c_parser_consume_token (parser); 10558 expr.value = build_component_ref (op_loc, expr.value, ident, 10559 comp_loc); 10560 set_c_expr_source_range (&expr, start, finish); 10561 expr.original_code = ERROR_MARK; 10562 if (TREE_CODE (expr.value) != COMPONENT_REF) 10563 expr.original_type = NULL; 10564 else 10565 { 10566 /* Remember the original type of a bitfield. */ 10567 tree field = TREE_OPERAND (expr.value, 1); 10568 if (TREE_CODE (field) != FIELD_DECL) 10569 expr.original_type = NULL; 10570 else 10571 expr.original_type = DECL_BIT_FIELD_TYPE (field); 10572 } 10573 break; 10574 case CPP_DEREF: 10575 /* Structure element reference. */ 10576 c_parser_consume_token (parser); 10577 expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false); 10578 if (c_parser_next_token_is (parser, CPP_NAME)) 10579 { 10580 c_token *comp_tok = c_parser_peek_token (parser); 10581 ident = comp_tok->value; 10582 comp_loc = comp_tok->location; 10583 } 10584 else 10585 { 10586 c_parser_error (parser, "expected identifier"); 10587 expr.set_error (); 10588 expr.original_code = ERROR_MARK; 10589 expr.original_type = NULL; 10590 return expr; 10591 } 10592 start = expr.get_start (); 10593 finish = c_parser_peek_token (parser)->get_finish (); 10594 c_parser_consume_token (parser); 10595 expr.value = build_component_ref (op_loc, 10596 build_indirect_ref (op_loc, 10597 expr.value, 10598 RO_ARROW), 10599 ident, comp_loc); 10600 set_c_expr_source_range (&expr, start, finish); 10601 expr.original_code = ERROR_MARK; 10602 if (TREE_CODE (expr.value) != COMPONENT_REF) 10603 expr.original_type = NULL; 10604 else 10605 { 10606 /* Remember the original type of a bitfield. */ 10607 tree field = TREE_OPERAND (expr.value, 1); 10608 if (TREE_CODE (field) != FIELD_DECL) 10609 expr.original_type = NULL; 10610 else 10611 expr.original_type = DECL_BIT_FIELD_TYPE (field); 10612 } 10613 break; 10614 case CPP_PLUS_PLUS: 10615 /* Postincrement. */ 10616 start = expr.get_start (); 10617 finish = c_parser_peek_token (parser)->get_finish (); 10618 c_parser_consume_token (parser); 10619 expr = default_function_array_read_conversion (expr_loc, expr); 10620 expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR, 10621 expr.value, false); 10622 set_c_expr_source_range (&expr, start, finish); 10623 expr.original_code = ERROR_MARK; 10624 expr.original_type = NULL; 10625 break; 10626 case CPP_MINUS_MINUS: 10627 /* Postdecrement. */ 10628 start = expr.get_start (); 10629 finish = c_parser_peek_token (parser)->get_finish (); 10630 c_parser_consume_token (parser); 10631 expr = default_function_array_read_conversion (expr_loc, expr); 10632 expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR, 10633 expr.value, false); 10634 set_c_expr_source_range (&expr, start, finish); 10635 expr.original_code = ERROR_MARK; 10636 expr.original_type = NULL; 10637 break; 10638 default: 10639 return expr; 10640 } 10641 } 10642 } 10643 10644 /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17). 10645 10646 expression: 10647 assignment-expression 10648 expression , assignment-expression 10649 */ 10650 10651 static struct c_expr 10652 c_parser_expression (c_parser *parser) 10653 { 10654 location_t tloc = c_parser_peek_token (parser)->location; 10655 struct c_expr expr; 10656 expr = c_parser_expr_no_commas (parser, NULL); 10657 if (c_parser_next_token_is (parser, CPP_COMMA)) 10658 expr = convert_lvalue_to_rvalue (tloc, expr, true, false); 10659 while (c_parser_next_token_is (parser, CPP_COMMA)) 10660 { 10661 struct c_expr next; 10662 tree lhsval; 10663 location_t loc = c_parser_peek_token (parser)->location; 10664 location_t expr_loc; 10665 c_parser_consume_token (parser); 10666 expr_loc = c_parser_peek_token (parser)->location; 10667 lhsval = expr.value; 10668 while (TREE_CODE (lhsval) == COMPOUND_EXPR) 10669 lhsval = TREE_OPERAND (lhsval, 1); 10670 if (DECL_P (lhsval) || handled_component_p (lhsval)) 10671 mark_exp_read (lhsval); 10672 next = c_parser_expr_no_commas (parser, NULL); 10673 next = convert_lvalue_to_rvalue (expr_loc, next, true, false); 10674 expr.value = build_compound_expr (loc, expr.value, next.value); 10675 expr.original_code = COMPOUND_EXPR; 10676 expr.original_type = next.original_type; 10677 } 10678 return expr; 10679 } 10680 10681 /* Parse an expression and convert functions or arrays to pointers and 10682 lvalues to rvalues. */ 10683 10684 static struct c_expr 10685 c_parser_expression_conv (c_parser *parser) 10686 { 10687 struct c_expr expr; 10688 location_t loc = c_parser_peek_token (parser)->location; 10689 expr = c_parser_expression (parser); 10690 expr = convert_lvalue_to_rvalue (loc, expr, true, false); 10691 return expr; 10692 } 10693 10694 /* Helper function of c_parser_expr_list. Check if IDXth (0 based) 10695 argument is a literal zero alone and if so, set it in literal_zero_mask. */ 10696 10697 static inline void 10698 c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask, 10699 unsigned int idx) 10700 { 10701 if (idx >= HOST_BITS_PER_INT) 10702 return; 10703 10704 c_token *tok = c_parser_peek_token (parser); 10705 switch (tok->type) 10706 { 10707 case CPP_NUMBER: 10708 case CPP_CHAR: 10709 case CPP_WCHAR: 10710 case CPP_CHAR16: 10711 case CPP_CHAR32: 10712 case CPP_UTF8CHAR: 10713 /* If a parameter is literal zero alone, remember it 10714 for -Wmemset-transposed-args warning. */ 10715 if (integer_zerop (tok->value) 10716 && !TREE_OVERFLOW (tok->value) 10717 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA 10718 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN)) 10719 *literal_zero_mask |= 1U << idx; 10720 default: 10721 break; 10722 } 10723 } 10724 10725 /* Parse a non-empty list of expressions. If CONVERT_P, convert 10726 functions and arrays to pointers and lvalues to rvalues. If 10727 FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the 10728 locations of function arguments into this vector. 10729 10730 nonempty-expr-list: 10731 assignment-expression 10732 nonempty-expr-list , assignment-expression 10733 */ 10734 10735 static vec<tree, va_gc> * 10736 c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p, 10737 vec<tree, va_gc> **p_orig_types, 10738 location_t *sizeof_arg_loc, tree *sizeof_arg, 10739 vec<location_t> *locations, 10740 unsigned int *literal_zero_mask) 10741 { 10742 vec<tree, va_gc> *ret; 10743 vec<tree, va_gc> *orig_types; 10744 struct c_expr expr; 10745 unsigned int idx = 0; 10746 10747 ret = make_tree_vector (); 10748 if (p_orig_types == NULL) 10749 orig_types = NULL; 10750 else 10751 orig_types = make_tree_vector (); 10752 10753 if (literal_zero_mask) 10754 c_parser_check_literal_zero (parser, literal_zero_mask, 0); 10755 expr = c_parser_expr_no_commas (parser, NULL); 10756 if (convert_p) 10757 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true); 10758 if (fold_p) 10759 expr.value = c_fully_fold (expr.value, false, NULL); 10760 ret->quick_push (expr.value); 10761 if (orig_types) 10762 orig_types->quick_push (expr.original_type); 10763 if (locations) 10764 locations->safe_push (expr.get_location ()); 10765 if (sizeof_arg != NULL 10766 && expr.original_code == SIZEOF_EXPR) 10767 { 10768 sizeof_arg[0] = c_last_sizeof_arg; 10769 sizeof_arg_loc[0] = c_last_sizeof_loc; 10770 } 10771 while (c_parser_next_token_is (parser, CPP_COMMA)) 10772 { 10773 c_parser_consume_token (parser); 10774 if (literal_zero_mask) 10775 c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1); 10776 expr = c_parser_expr_no_commas (parser, NULL); 10777 if (convert_p) 10778 expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, 10779 true); 10780 if (fold_p) 10781 expr.value = c_fully_fold (expr.value, false, NULL); 10782 vec_safe_push (ret, expr.value); 10783 if (orig_types) 10784 vec_safe_push (orig_types, expr.original_type); 10785 if (locations) 10786 locations->safe_push (expr.get_location ()); 10787 if (++idx < 3 10788 && sizeof_arg != NULL 10789 && expr.original_code == SIZEOF_EXPR) 10790 { 10791 sizeof_arg[idx] = c_last_sizeof_arg; 10792 sizeof_arg_loc[idx] = c_last_sizeof_loc; 10793 } 10794 } 10795 if (orig_types) 10796 *p_orig_types = orig_types; 10797 return ret; 10798 } 10799 10800 /* Parse Objective-C-specific constructs. */ 10801 10802 /* Parse an objc-class-definition. 10803 10804 objc-class-definition: 10805 @interface identifier objc-superclass[opt] objc-protocol-refs[opt] 10806 objc-class-instance-variables[opt] objc-methodprotolist @end 10807 @implementation identifier objc-superclass[opt] 10808 objc-class-instance-variables[opt] 10809 @interface identifier ( identifier ) objc-protocol-refs[opt] 10810 objc-methodprotolist @end 10811 @interface identifier ( ) objc-protocol-refs[opt] 10812 objc-methodprotolist @end 10813 @implementation identifier ( identifier ) 10814 10815 objc-superclass: 10816 : identifier 10817 10818 "@interface identifier (" must start "@interface identifier ( 10819 identifier ) ...": objc-methodprotolist in the first production may 10820 not start with a parenthesized identifier as a declarator of a data 10821 definition with no declaration specifiers if the objc-superclass, 10822 objc-protocol-refs and objc-class-instance-variables are omitted. */ 10823 10824 static void 10825 c_parser_objc_class_definition (c_parser *parser, tree attributes) 10826 { 10827 bool iface_p; 10828 tree id1; 10829 tree superclass; 10830 if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE)) 10831 iface_p = true; 10832 else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION)) 10833 iface_p = false; 10834 else 10835 gcc_unreachable (); 10836 10837 c_parser_consume_token (parser); 10838 if (c_parser_next_token_is_not (parser, CPP_NAME)) 10839 { 10840 c_parser_error (parser, "expected identifier"); 10841 return; 10842 } 10843 id1 = c_parser_peek_token (parser)->value; 10844 c_parser_consume_token (parser); 10845 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 10846 { 10847 /* We have a category or class extension. */ 10848 tree id2; 10849 tree proto = NULL_TREE; 10850 matching_parens parens; 10851 parens.consume_open (parser); 10852 if (c_parser_next_token_is_not (parser, CPP_NAME)) 10853 { 10854 if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 10855 { 10856 /* We have a class extension. */ 10857 id2 = NULL_TREE; 10858 } 10859 else 10860 { 10861 c_parser_error (parser, "expected identifier or %<)%>"); 10862 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 10863 return; 10864 } 10865 } 10866 else 10867 { 10868 id2 = c_parser_peek_token (parser)->value; 10869 c_parser_consume_token (parser); 10870 } 10871 parens.skip_until_found_close (parser); 10872 if (!iface_p) 10873 { 10874 objc_start_category_implementation (id1, id2); 10875 return; 10876 } 10877 if (c_parser_next_token_is (parser, CPP_LESS)) 10878 proto = c_parser_objc_protocol_refs (parser); 10879 objc_start_category_interface (id1, id2, proto, attributes); 10880 c_parser_objc_methodprotolist (parser); 10881 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>"); 10882 objc_finish_interface (); 10883 return; 10884 } 10885 if (c_parser_next_token_is (parser, CPP_COLON)) 10886 { 10887 c_parser_consume_token (parser); 10888 if (c_parser_next_token_is_not (parser, CPP_NAME)) 10889 { 10890 c_parser_error (parser, "expected identifier"); 10891 return; 10892 } 10893 superclass = c_parser_peek_token (parser)->value; 10894 c_parser_consume_token (parser); 10895 } 10896 else 10897 superclass = NULL_TREE; 10898 if (iface_p) 10899 { 10900 tree proto = NULL_TREE; 10901 if (c_parser_next_token_is (parser, CPP_LESS)) 10902 proto = c_parser_objc_protocol_refs (parser); 10903 objc_start_class_interface (id1, superclass, proto, attributes); 10904 } 10905 else 10906 objc_start_class_implementation (id1, superclass); 10907 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 10908 c_parser_objc_class_instance_variables (parser); 10909 if (iface_p) 10910 { 10911 objc_continue_interface (); 10912 c_parser_objc_methodprotolist (parser); 10913 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>"); 10914 objc_finish_interface (); 10915 } 10916 else 10917 { 10918 objc_continue_implementation (); 10919 return; 10920 } 10921 } 10922 10923 /* Parse objc-class-instance-variables. 10924 10925 objc-class-instance-variables: 10926 { objc-instance-variable-decl-list[opt] } 10927 10928 objc-instance-variable-decl-list: 10929 objc-visibility-spec 10930 objc-instance-variable-decl ; 10931 ; 10932 objc-instance-variable-decl-list objc-visibility-spec 10933 objc-instance-variable-decl-list objc-instance-variable-decl ; 10934 objc-instance-variable-decl-list ; 10935 10936 objc-visibility-spec: 10937 @private 10938 @protected 10939 @public 10940 10941 objc-instance-variable-decl: 10942 struct-declaration 10943 */ 10944 10945 static void 10946 c_parser_objc_class_instance_variables (c_parser *parser) 10947 { 10948 gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE)); 10949 c_parser_consume_token (parser); 10950 while (c_parser_next_token_is_not (parser, CPP_EOF)) 10951 { 10952 tree decls; 10953 /* Parse any stray semicolon. */ 10954 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 10955 { 10956 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic, 10957 "extra semicolon"); 10958 c_parser_consume_token (parser); 10959 continue; 10960 } 10961 /* Stop if at the end of the instance variables. */ 10962 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 10963 { 10964 c_parser_consume_token (parser); 10965 break; 10966 } 10967 /* Parse any objc-visibility-spec. */ 10968 if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE)) 10969 { 10970 c_parser_consume_token (parser); 10971 objc_set_visibility (OBJC_IVAR_VIS_PRIVATE); 10972 continue; 10973 } 10974 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED)) 10975 { 10976 c_parser_consume_token (parser); 10977 objc_set_visibility (OBJC_IVAR_VIS_PROTECTED); 10978 continue; 10979 } 10980 else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC)) 10981 { 10982 c_parser_consume_token (parser); 10983 objc_set_visibility (OBJC_IVAR_VIS_PUBLIC); 10984 continue; 10985 } 10986 else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE)) 10987 { 10988 c_parser_consume_token (parser); 10989 objc_set_visibility (OBJC_IVAR_VIS_PACKAGE); 10990 continue; 10991 } 10992 else if (c_parser_next_token_is (parser, CPP_PRAGMA)) 10993 { 10994 c_parser_pragma (parser, pragma_external, NULL); 10995 continue; 10996 } 10997 10998 /* Parse some comma-separated declarations. */ 10999 decls = c_parser_struct_declaration (parser); 11000 if (decls == NULL) 11001 { 11002 /* There is a syntax error. We want to skip the offending 11003 tokens up to the next ';' (included) or '}' 11004 (excluded). */ 11005 11006 /* First, skip manually a ')' or ']'. This is because they 11007 reduce the nesting level, so c_parser_skip_until_found() 11008 wouldn't be able to skip past them. */ 11009 c_token *token = c_parser_peek_token (parser); 11010 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE) 11011 c_parser_consume_token (parser); 11012 11013 /* Then, do the standard skipping. */ 11014 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); 11015 11016 /* We hopefully recovered. Start normal parsing again. */ 11017 parser->error = false; 11018 continue; 11019 } 11020 else 11021 { 11022 /* Comma-separated instance variables are chained together 11023 in reverse order; add them one by one. */ 11024 tree ivar = nreverse (decls); 11025 for (; ivar; ivar = DECL_CHAIN (ivar)) 11026 objc_add_instance_variable (copy_node (ivar)); 11027 } 11028 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 11029 } 11030 } 11031 11032 /* Parse an objc-class-declaration. 11033 11034 objc-class-declaration: 11035 @class identifier-list ; 11036 */ 11037 11038 static void 11039 c_parser_objc_class_declaration (c_parser *parser) 11040 { 11041 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS)); 11042 c_parser_consume_token (parser); 11043 /* Any identifiers, including those declared as type names, are OK 11044 here. */ 11045 while (true) 11046 { 11047 tree id; 11048 if (c_parser_next_token_is_not (parser, CPP_NAME)) 11049 { 11050 c_parser_error (parser, "expected identifier"); 11051 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); 11052 parser->error = false; 11053 return; 11054 } 11055 id = c_parser_peek_token (parser)->value; 11056 objc_declare_class (id); 11057 c_parser_consume_token (parser); 11058 if (c_parser_next_token_is (parser, CPP_COMMA)) 11059 c_parser_consume_token (parser); 11060 else 11061 break; 11062 } 11063 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 11064 } 11065 11066 /* Parse an objc-alias-declaration. 11067 11068 objc-alias-declaration: 11069 @compatibility_alias identifier identifier ; 11070 */ 11071 11072 static void 11073 c_parser_objc_alias_declaration (c_parser *parser) 11074 { 11075 tree id1, id2; 11076 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS)); 11077 c_parser_consume_token (parser); 11078 if (c_parser_next_token_is_not (parser, CPP_NAME)) 11079 { 11080 c_parser_error (parser, "expected identifier"); 11081 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); 11082 return; 11083 } 11084 id1 = c_parser_peek_token (parser)->value; 11085 c_parser_consume_token (parser); 11086 if (c_parser_next_token_is_not (parser, CPP_NAME)) 11087 { 11088 c_parser_error (parser, "expected identifier"); 11089 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); 11090 return; 11091 } 11092 id2 = c_parser_peek_token (parser)->value; 11093 c_parser_consume_token (parser); 11094 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 11095 objc_declare_alias (id1, id2); 11096 } 11097 11098 /* Parse an objc-protocol-definition. 11099 11100 objc-protocol-definition: 11101 @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end 11102 @protocol identifier-list ; 11103 11104 "@protocol identifier ;" should be resolved as "@protocol 11105 identifier-list ;": objc-methodprotolist may not start with a 11106 semicolon in the first alternative if objc-protocol-refs are 11107 omitted. */ 11108 11109 static void 11110 c_parser_objc_protocol_definition (c_parser *parser, tree attributes) 11111 { 11112 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL)); 11113 11114 c_parser_consume_token (parser); 11115 if (c_parser_next_token_is_not (parser, CPP_NAME)) 11116 { 11117 c_parser_error (parser, "expected identifier"); 11118 return; 11119 } 11120 if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA 11121 || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON) 11122 { 11123 /* Any identifiers, including those declared as type names, are 11124 OK here. */ 11125 while (true) 11126 { 11127 tree id; 11128 if (c_parser_next_token_is_not (parser, CPP_NAME)) 11129 { 11130 c_parser_error (parser, "expected identifier"); 11131 break; 11132 } 11133 id = c_parser_peek_token (parser)->value; 11134 objc_declare_protocol (id, attributes); 11135 c_parser_consume_token (parser); 11136 if (c_parser_next_token_is (parser, CPP_COMMA)) 11137 c_parser_consume_token (parser); 11138 else 11139 break; 11140 } 11141 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 11142 } 11143 else 11144 { 11145 tree id = c_parser_peek_token (parser)->value; 11146 tree proto = NULL_TREE; 11147 c_parser_consume_token (parser); 11148 if (c_parser_next_token_is (parser, CPP_LESS)) 11149 proto = c_parser_objc_protocol_refs (parser); 11150 parser->objc_pq_context = true; 11151 objc_start_protocol (id, proto, attributes); 11152 c_parser_objc_methodprotolist (parser); 11153 c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>"); 11154 parser->objc_pq_context = false; 11155 objc_finish_interface (); 11156 } 11157 } 11158 11159 /* Parse an objc-method-type. 11160 11161 objc-method-type: 11162 + 11163 - 11164 11165 Return true if it is a class method (+) and false if it is 11166 an instance method (-). 11167 */ 11168 static inline bool 11169 c_parser_objc_method_type (c_parser *parser) 11170 { 11171 switch (c_parser_peek_token (parser)->type) 11172 { 11173 case CPP_PLUS: 11174 c_parser_consume_token (parser); 11175 return true; 11176 case CPP_MINUS: 11177 c_parser_consume_token (parser); 11178 return false; 11179 default: 11180 gcc_unreachable (); 11181 } 11182 } 11183 11184 /* Parse an objc-method-definition. 11185 11186 objc-method-definition: 11187 objc-method-type objc-method-decl ;[opt] compound-statement 11188 */ 11189 11190 static void 11191 c_parser_objc_method_definition (c_parser *parser) 11192 { 11193 bool is_class_method = c_parser_objc_method_type (parser); 11194 tree decl, attributes = NULL_TREE, expr = NULL_TREE; 11195 parser->objc_pq_context = true; 11196 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes, 11197 &expr); 11198 if (decl == error_mark_node) 11199 return; /* Bail here. */ 11200 11201 if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 11202 { 11203 c_parser_consume_token (parser); 11204 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic, 11205 "extra semicolon in method definition specified"); 11206 } 11207 11208 if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 11209 { 11210 c_parser_error (parser, "expected %<{%>"); 11211 return; 11212 } 11213 11214 parser->objc_pq_context = false; 11215 if (objc_start_method_definition (is_class_method, decl, attributes, expr)) 11216 { 11217 add_stmt (c_parser_compound_statement (parser)); 11218 objc_finish_method_definition (current_function_decl); 11219 } 11220 else 11221 { 11222 /* This code is executed when we find a method definition 11223 outside of an @implementation context (or invalid for other 11224 reasons). Parse the method (to keep going) but do not emit 11225 any code. 11226 */ 11227 c_parser_compound_statement (parser); 11228 } 11229 } 11230 11231 /* Parse an objc-methodprotolist. 11232 11233 objc-methodprotolist: 11234 empty 11235 objc-methodprotolist objc-methodproto 11236 objc-methodprotolist declaration 11237 objc-methodprotolist ; 11238 @optional 11239 @required 11240 11241 The declaration is a data definition, which may be missing 11242 declaration specifiers under the same rules and diagnostics as 11243 other data definitions outside functions, and the stray semicolon 11244 is diagnosed the same way as a stray semicolon outside a 11245 function. */ 11246 11247 static void 11248 c_parser_objc_methodprotolist (c_parser *parser) 11249 { 11250 while (true) 11251 { 11252 /* The list is terminated by @end. */ 11253 switch (c_parser_peek_token (parser)->type) 11254 { 11255 case CPP_SEMICOLON: 11256 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic, 11257 "ISO C does not allow extra %<;%> outside of a function"); 11258 c_parser_consume_token (parser); 11259 break; 11260 case CPP_PLUS: 11261 case CPP_MINUS: 11262 c_parser_objc_methodproto (parser); 11263 break; 11264 case CPP_PRAGMA: 11265 c_parser_pragma (parser, pragma_external, NULL); 11266 break; 11267 case CPP_EOF: 11268 return; 11269 default: 11270 if (c_parser_next_token_is_keyword (parser, RID_AT_END)) 11271 return; 11272 else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY)) 11273 c_parser_objc_at_property_declaration (parser); 11274 else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL)) 11275 { 11276 objc_set_method_opt (true); 11277 c_parser_consume_token (parser); 11278 } 11279 else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED)) 11280 { 11281 objc_set_method_opt (false); 11282 c_parser_consume_token (parser); 11283 } 11284 else 11285 c_parser_declaration_or_fndef (parser, false, false, true, 11286 false, true, NULL, vNULL); 11287 break; 11288 } 11289 } 11290 } 11291 11292 /* Parse an objc-methodproto. 11293 11294 objc-methodproto: 11295 objc-method-type objc-method-decl ; 11296 */ 11297 11298 static void 11299 c_parser_objc_methodproto (c_parser *parser) 11300 { 11301 bool is_class_method = c_parser_objc_method_type (parser); 11302 tree decl, attributes = NULL_TREE; 11303 11304 /* Remember protocol qualifiers in prototypes. */ 11305 parser->objc_pq_context = true; 11306 decl = c_parser_objc_method_decl (parser, is_class_method, &attributes, 11307 NULL); 11308 /* Forget protocol qualifiers now. */ 11309 parser->objc_pq_context = false; 11310 11311 /* Do not allow the presence of attributes to hide an erroneous 11312 method implementation in the interface section. */ 11313 if (!c_parser_next_token_is (parser, CPP_SEMICOLON)) 11314 { 11315 c_parser_error (parser, "expected %<;%>"); 11316 return; 11317 } 11318 11319 if (decl != error_mark_node) 11320 objc_add_method_declaration (is_class_method, decl, attributes); 11321 11322 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 11323 } 11324 11325 /* If we are at a position that method attributes may be present, check that 11326 there are not any parsed already (a syntax error) and then collect any 11327 specified at the current location. Finally, if new attributes were present, 11328 check that the next token is legal ( ';' for decls and '{' for defs). */ 11329 11330 static bool 11331 c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes) 11332 { 11333 bool bad = false; 11334 if (*attributes) 11335 { 11336 c_parser_error (parser, 11337 "method attributes must be specified at the end only"); 11338 *attributes = NULL_TREE; 11339 bad = true; 11340 } 11341 11342 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 11343 *attributes = c_parser_gnu_attributes (parser); 11344 11345 /* If there were no attributes here, just report any earlier error. */ 11346 if (*attributes == NULL_TREE || bad) 11347 return bad; 11348 11349 /* If the attributes are followed by a ; or {, then just report any earlier 11350 error. */ 11351 if (c_parser_next_token_is (parser, CPP_SEMICOLON) 11352 || c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 11353 return bad; 11354 11355 /* We've got attributes, but not at the end. */ 11356 c_parser_error (parser, 11357 "expected %<;%> or %<{%> after method attribute definition"); 11358 return true; 11359 } 11360 11361 /* Parse an objc-method-decl. 11362 11363 objc-method-decl: 11364 ( objc-type-name ) objc-selector 11365 objc-selector 11366 ( objc-type-name ) objc-keyword-selector objc-optparmlist 11367 objc-keyword-selector objc-optparmlist 11368 gnu-attributes 11369 11370 objc-keyword-selector: 11371 objc-keyword-decl 11372 objc-keyword-selector objc-keyword-decl 11373 11374 objc-keyword-decl: 11375 objc-selector : ( objc-type-name ) identifier 11376 objc-selector : identifier 11377 : ( objc-type-name ) identifier 11378 : identifier 11379 11380 objc-optparmlist: 11381 objc-optparms objc-optellipsis 11382 11383 objc-optparms: 11384 empty 11385 objc-opt-parms , parameter-declaration 11386 11387 objc-optellipsis: 11388 empty 11389 , ... 11390 */ 11391 11392 static tree 11393 c_parser_objc_method_decl (c_parser *parser, bool is_class_method, 11394 tree *attributes, tree *expr) 11395 { 11396 tree type = NULL_TREE; 11397 tree sel; 11398 tree parms = NULL_TREE; 11399 bool ellipsis = false; 11400 bool attr_err = false; 11401 11402 *attributes = NULL_TREE; 11403 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 11404 { 11405 matching_parens parens; 11406 parens.consume_open (parser); 11407 type = c_parser_objc_type_name (parser); 11408 parens.skip_until_found_close (parser); 11409 } 11410 sel = c_parser_objc_selector (parser); 11411 /* If there is no selector, or a colon follows, we have an 11412 objc-keyword-selector. If there is a selector, and a colon does 11413 not follow, that selector ends the objc-method-decl. */ 11414 if (!sel || c_parser_next_token_is (parser, CPP_COLON)) 11415 { 11416 tree tsel = sel; 11417 tree list = NULL_TREE; 11418 while (true) 11419 { 11420 tree atype = NULL_TREE, id, keyworddecl; 11421 tree param_attr = NULL_TREE; 11422 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 11423 break; 11424 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 11425 { 11426 c_parser_consume_token (parser); 11427 atype = c_parser_objc_type_name (parser); 11428 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 11429 "expected %<)%>"); 11430 } 11431 /* New ObjC allows attributes on method parameters. */ 11432 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 11433 param_attr = c_parser_gnu_attributes (parser); 11434 if (c_parser_next_token_is_not (parser, CPP_NAME)) 11435 { 11436 c_parser_error (parser, "expected identifier"); 11437 return error_mark_node; 11438 } 11439 id = c_parser_peek_token (parser)->value; 11440 c_parser_consume_token (parser); 11441 keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr); 11442 list = chainon (list, keyworddecl); 11443 tsel = c_parser_objc_selector (parser); 11444 if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON)) 11445 break; 11446 } 11447 11448 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ; 11449 11450 /* Parse the optional parameter list. Optional Objective-C 11451 method parameters follow the C syntax, and may include '...' 11452 to denote a variable number of arguments. */ 11453 parms = make_node (TREE_LIST); 11454 while (c_parser_next_token_is (parser, CPP_COMMA)) 11455 { 11456 struct c_parm *parm; 11457 c_parser_consume_token (parser); 11458 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) 11459 { 11460 ellipsis = true; 11461 c_parser_consume_token (parser); 11462 attr_err |= c_parser_objc_maybe_method_attributes 11463 (parser, attributes) ; 11464 break; 11465 } 11466 parm = c_parser_parameter_declaration (parser, NULL_TREE, false); 11467 if (parm == NULL) 11468 break; 11469 parms = chainon (parms, 11470 build_tree_list (NULL_TREE, grokparm (parm, expr))); 11471 } 11472 sel = list; 11473 } 11474 else 11475 attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ; 11476 11477 if (sel == NULL) 11478 { 11479 c_parser_error (parser, "objective-c method declaration is expected"); 11480 return error_mark_node; 11481 } 11482 11483 if (attr_err) 11484 return error_mark_node; 11485 11486 return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis); 11487 } 11488 11489 /* Parse an objc-type-name. 11490 11491 objc-type-name: 11492 objc-type-qualifiers[opt] type-name 11493 objc-type-qualifiers[opt] 11494 11495 objc-type-qualifiers: 11496 objc-type-qualifier 11497 objc-type-qualifiers objc-type-qualifier 11498 11499 objc-type-qualifier: one of 11500 in out inout bycopy byref oneway 11501 */ 11502 11503 static tree 11504 c_parser_objc_type_name (c_parser *parser) 11505 { 11506 tree quals = NULL_TREE; 11507 struct c_type_name *type_name = NULL; 11508 tree type = NULL_TREE; 11509 while (true) 11510 { 11511 c_token *token = c_parser_peek_token (parser); 11512 if (token->type == CPP_KEYWORD 11513 && (token->keyword == RID_IN 11514 || token->keyword == RID_OUT 11515 || token->keyword == RID_INOUT 11516 || token->keyword == RID_BYCOPY 11517 || token->keyword == RID_BYREF 11518 || token->keyword == RID_ONEWAY)) 11519 { 11520 quals = chainon (build_tree_list (NULL_TREE, token->value), quals); 11521 c_parser_consume_token (parser); 11522 } 11523 else 11524 break; 11525 } 11526 if (c_parser_next_tokens_start_typename (parser, cla_prefer_type)) 11527 type_name = c_parser_type_name (parser); 11528 if (type_name) 11529 type = groktypename (type_name, NULL, NULL); 11530 11531 /* If the type is unknown, and error has already been produced and 11532 we need to recover from the error. In that case, use NULL_TREE 11533 for the type, as if no type had been specified; this will use the 11534 default type ('id') which is good for error recovery. */ 11535 if (type == error_mark_node) 11536 type = NULL_TREE; 11537 11538 return build_tree_list (quals, type); 11539 } 11540 11541 /* Parse objc-protocol-refs. 11542 11543 objc-protocol-refs: 11544 < identifier-list > 11545 */ 11546 11547 static tree 11548 c_parser_objc_protocol_refs (c_parser *parser) 11549 { 11550 tree list = NULL_TREE; 11551 gcc_assert (c_parser_next_token_is (parser, CPP_LESS)); 11552 c_parser_consume_token (parser); 11553 /* Any identifiers, including those declared as type names, are OK 11554 here. */ 11555 while (true) 11556 { 11557 tree id; 11558 if (c_parser_next_token_is_not (parser, CPP_NAME)) 11559 { 11560 c_parser_error (parser, "expected identifier"); 11561 break; 11562 } 11563 id = c_parser_peek_token (parser)->value; 11564 list = chainon (list, build_tree_list (NULL_TREE, id)); 11565 c_parser_consume_token (parser); 11566 if (c_parser_next_token_is (parser, CPP_COMMA)) 11567 c_parser_consume_token (parser); 11568 else 11569 break; 11570 } 11571 c_parser_require (parser, CPP_GREATER, "expected %<>%>"); 11572 return list; 11573 } 11574 11575 /* Parse an objc-try-catch-finally-statement. 11576 11577 objc-try-catch-finally-statement: 11578 @try compound-statement objc-catch-list[opt] 11579 @try compound-statement objc-catch-list[opt] @finally compound-statement 11580 11581 objc-catch-list: 11582 @catch ( objc-catch-parameter-declaration ) compound-statement 11583 objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement 11584 11585 objc-catch-parameter-declaration: 11586 parameter-declaration 11587 '...' 11588 11589 where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS. 11590 11591 PS: This function is identical to cp_parser_objc_try_catch_finally_statement 11592 for C++. Keep them in sync. */ 11593 11594 static void 11595 c_parser_objc_try_catch_finally_statement (c_parser *parser) 11596 { 11597 location_t location; 11598 tree stmt; 11599 11600 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY)); 11601 c_parser_consume_token (parser); 11602 location = c_parser_peek_token (parser)->location; 11603 objc_maybe_warn_exceptions (location); 11604 stmt = c_parser_compound_statement (parser); 11605 objc_begin_try_stmt (location, stmt); 11606 11607 while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH)) 11608 { 11609 struct c_parm *parm; 11610 tree parameter_declaration = error_mark_node; 11611 bool seen_open_paren = false; 11612 11613 c_parser_consume_token (parser); 11614 matching_parens parens; 11615 if (!parens.require_open (parser)) 11616 seen_open_paren = true; 11617 if (c_parser_next_token_is (parser, CPP_ELLIPSIS)) 11618 { 11619 /* We have "@catch (...)" (where the '...' are literally 11620 what is in the code). Skip the '...'. 11621 parameter_declaration is set to NULL_TREE, and 11622 objc_being_catch_clauses() knows that that means 11623 '...'. */ 11624 c_parser_consume_token (parser); 11625 parameter_declaration = NULL_TREE; 11626 } 11627 else 11628 { 11629 /* We have "@catch (NSException *exception)" or something 11630 like that. Parse the parameter declaration. */ 11631 parm = c_parser_parameter_declaration (parser, NULL_TREE, false); 11632 if (parm == NULL) 11633 parameter_declaration = error_mark_node; 11634 else 11635 parameter_declaration = grokparm (parm, NULL); 11636 } 11637 if (seen_open_paren) 11638 parens.require_close (parser); 11639 else 11640 { 11641 /* If there was no open parenthesis, we are recovering from 11642 an error, and we are trying to figure out what mistake 11643 the user has made. */ 11644 11645 /* If there is an immediate closing parenthesis, the user 11646 probably forgot the opening one (ie, they typed "@catch 11647 NSException *e)". Parse the closing parenthesis and keep 11648 going. */ 11649 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 11650 c_parser_consume_token (parser); 11651 11652 /* If these is no immediate closing parenthesis, the user 11653 probably doesn't know that parenthesis are required at 11654 all (ie, they typed "@catch NSException *e"). So, just 11655 forget about the closing parenthesis and keep going. */ 11656 } 11657 objc_begin_catch_clause (parameter_declaration); 11658 if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) 11659 c_parser_compound_statement_nostart (parser); 11660 objc_finish_catch_clause (); 11661 } 11662 if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY)) 11663 { 11664 c_parser_consume_token (parser); 11665 location = c_parser_peek_token (parser)->location; 11666 stmt = c_parser_compound_statement (parser); 11667 objc_build_finally_clause (location, stmt); 11668 } 11669 objc_finish_try_stmt (); 11670 } 11671 11672 /* Parse an objc-synchronized-statement. 11673 11674 objc-synchronized-statement: 11675 @synchronized ( expression ) compound-statement 11676 */ 11677 11678 static void 11679 c_parser_objc_synchronized_statement (c_parser *parser) 11680 { 11681 location_t loc; 11682 tree expr, stmt; 11683 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED)); 11684 c_parser_consume_token (parser); 11685 loc = c_parser_peek_token (parser)->location; 11686 objc_maybe_warn_exceptions (loc); 11687 matching_parens parens; 11688 if (parens.require_open (parser)) 11689 { 11690 struct c_expr ce = c_parser_expression (parser); 11691 ce = convert_lvalue_to_rvalue (loc, ce, false, false); 11692 expr = ce.value; 11693 expr = c_fully_fold (expr, false, NULL); 11694 parens.skip_until_found_close (parser); 11695 } 11696 else 11697 expr = error_mark_node; 11698 stmt = c_parser_compound_statement (parser); 11699 objc_build_synchronized (loc, expr, stmt); 11700 } 11701 11702 /* Parse an objc-selector; return NULL_TREE without an error if the 11703 next token is not an objc-selector. 11704 11705 objc-selector: 11706 identifier 11707 one of 11708 enum struct union if else while do for switch case default 11709 break continue return goto asm sizeof typeof __alignof 11710 unsigned long const short volatile signed restrict _Complex 11711 in out inout bycopy byref oneway int char float double void _Bool 11712 _Atomic 11713 11714 ??? Why this selection of keywords but not, for example, storage 11715 class specifiers? */ 11716 11717 static tree 11718 c_parser_objc_selector (c_parser *parser) 11719 { 11720 c_token *token = c_parser_peek_token (parser); 11721 tree value = token->value; 11722 if (token->type == CPP_NAME) 11723 { 11724 c_parser_consume_token (parser); 11725 return value; 11726 } 11727 if (token->type != CPP_KEYWORD) 11728 return NULL_TREE; 11729 switch (token->keyword) 11730 { 11731 case RID_ENUM: 11732 case RID_STRUCT: 11733 case RID_UNION: 11734 case RID_IF: 11735 case RID_ELSE: 11736 case RID_WHILE: 11737 case RID_DO: 11738 case RID_FOR: 11739 case RID_SWITCH: 11740 case RID_CASE: 11741 case RID_DEFAULT: 11742 case RID_BREAK: 11743 case RID_CONTINUE: 11744 case RID_RETURN: 11745 case RID_GOTO: 11746 case RID_ASM: 11747 case RID_SIZEOF: 11748 case RID_TYPEOF: 11749 case RID_ALIGNOF: 11750 case RID_UNSIGNED: 11751 case RID_LONG: 11752 case RID_CONST: 11753 case RID_SHORT: 11754 case RID_VOLATILE: 11755 case RID_SIGNED: 11756 case RID_RESTRICT: 11757 case RID_COMPLEX: 11758 case RID_IN: 11759 case RID_OUT: 11760 case RID_INOUT: 11761 case RID_BYCOPY: 11762 case RID_BYREF: 11763 case RID_ONEWAY: 11764 case RID_INT: 11765 case RID_CHAR: 11766 case RID_FLOAT: 11767 case RID_DOUBLE: 11768 CASE_RID_FLOATN_NX: 11769 case RID_VOID: 11770 case RID_BOOL: 11771 case RID_ATOMIC: 11772 case RID_AUTO_TYPE: 11773 case RID_INT_N_0: 11774 case RID_INT_N_1: 11775 case RID_INT_N_2: 11776 case RID_INT_N_3: 11777 c_parser_consume_token (parser); 11778 return value; 11779 default: 11780 return NULL_TREE; 11781 } 11782 } 11783 11784 /* Parse an objc-selector-arg. 11785 11786 objc-selector-arg: 11787 objc-selector 11788 objc-keywordname-list 11789 11790 objc-keywordname-list: 11791 objc-keywordname 11792 objc-keywordname-list objc-keywordname 11793 11794 objc-keywordname: 11795 objc-selector : 11796 : 11797 */ 11798 11799 static tree 11800 c_parser_objc_selector_arg (c_parser *parser) 11801 { 11802 tree sel = c_parser_objc_selector (parser); 11803 tree list = NULL_TREE; 11804 if (sel 11805 && c_parser_next_token_is_not (parser, CPP_COLON) 11806 && c_parser_next_token_is_not (parser, CPP_SCOPE)) 11807 return sel; 11808 while (true) 11809 { 11810 if (c_parser_next_token_is (parser, CPP_SCOPE)) 11811 { 11812 c_parser_consume_token (parser); 11813 list = chainon (list, build_tree_list (sel, NULL_TREE)); 11814 list = chainon (list, build_tree_list (NULL_TREE, NULL_TREE)); 11815 } 11816 else 11817 { 11818 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 11819 return list; 11820 list = chainon (list, build_tree_list (sel, NULL_TREE)); 11821 } 11822 sel = c_parser_objc_selector (parser); 11823 if (!sel 11824 && c_parser_next_token_is_not (parser, CPP_COLON) 11825 && c_parser_next_token_is_not (parser, CPP_SCOPE)) 11826 break; 11827 } 11828 return list; 11829 } 11830 11831 /* Parse an objc-receiver. 11832 11833 objc-receiver: 11834 expression 11835 class-name 11836 type-name 11837 */ 11838 11839 static tree 11840 c_parser_objc_receiver (c_parser *parser) 11841 { 11842 location_t loc = c_parser_peek_token (parser)->location; 11843 11844 if (c_parser_peek_token (parser)->type == CPP_NAME 11845 && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME 11846 || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)) 11847 { 11848 tree id = c_parser_peek_token (parser)->value; 11849 c_parser_consume_token (parser); 11850 return objc_get_class_reference (id); 11851 } 11852 struct c_expr ce = c_parser_expression (parser); 11853 ce = convert_lvalue_to_rvalue (loc, ce, false, false); 11854 return c_fully_fold (ce.value, false, NULL); 11855 } 11856 11857 /* Parse objc-message-args. 11858 11859 objc-message-args: 11860 objc-selector 11861 objc-keywordarg-list 11862 11863 objc-keywordarg-list: 11864 objc-keywordarg 11865 objc-keywordarg-list objc-keywordarg 11866 11867 objc-keywordarg: 11868 objc-selector : objc-keywordexpr 11869 : objc-keywordexpr 11870 */ 11871 11872 static tree 11873 c_parser_objc_message_args (c_parser *parser) 11874 { 11875 tree sel = c_parser_objc_selector (parser); 11876 tree list = NULL_TREE; 11877 if (sel && c_parser_next_token_is_not (parser, CPP_COLON)) 11878 return sel; 11879 while (true) 11880 { 11881 tree keywordexpr; 11882 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 11883 return error_mark_node; 11884 keywordexpr = c_parser_objc_keywordexpr (parser); 11885 list = chainon (list, build_tree_list (sel, keywordexpr)); 11886 sel = c_parser_objc_selector (parser); 11887 if (!sel && c_parser_next_token_is_not (parser, CPP_COLON)) 11888 break; 11889 } 11890 return list; 11891 } 11892 11893 /* Parse an objc-keywordexpr. 11894 11895 objc-keywordexpr: 11896 nonempty-expr-list 11897 */ 11898 11899 static tree 11900 c_parser_objc_keywordexpr (c_parser *parser) 11901 { 11902 tree ret; 11903 vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true, 11904 NULL, NULL, NULL, NULL); 11905 if (vec_safe_length (expr_list) == 1) 11906 { 11907 /* Just return the expression, remove a level of 11908 indirection. */ 11909 ret = (*expr_list)[0]; 11910 } 11911 else 11912 { 11913 /* We have a comma expression, we will collapse later. */ 11914 ret = build_tree_list_vec (expr_list); 11915 } 11916 release_tree_vector (expr_list); 11917 return ret; 11918 } 11919 11920 /* A check, needed in several places, that ObjC interface, implementation or 11921 method definitions are not prefixed by incorrect items. */ 11922 static bool 11923 c_parser_objc_diagnose_bad_element_prefix (c_parser *parser, 11924 struct c_declspecs *specs) 11925 { 11926 if (!specs->declspecs_seen_p || specs->non_sc_seen_p 11927 || specs->typespec_kind != ctsk_none) 11928 { 11929 c_parser_error (parser, 11930 "no type or storage class may be specified here,"); 11931 c_parser_skip_to_end_of_block_or_statement (parser); 11932 return true; 11933 } 11934 return false; 11935 } 11936 11937 /* Parse an Objective-C @property declaration. The syntax is: 11938 11939 objc-property-declaration: 11940 '@property' objc-property-attributes[opt] struct-declaration ; 11941 11942 objc-property-attributes: 11943 '(' objc-property-attribute-list ')' 11944 11945 objc-property-attribute-list: 11946 objc-property-attribute 11947 objc-property-attribute-list, objc-property-attribute 11948 11949 objc-property-attribute 11950 'getter' = identifier 11951 'setter' = identifier 11952 'readonly' 11953 'readwrite' 11954 'assign' 11955 'retain' 11956 'copy' 11957 'nonatomic' 11958 11959 For example: 11960 @property NSString *name; 11961 @property (readonly) id object; 11962 @property (retain, nonatomic, getter=getTheName) id name; 11963 @property int a, b, c; 11964 11965 PS: This function is identical to cp_parser_objc_at_propery_declaration 11966 for C++. Keep them in sync. */ 11967 static void 11968 c_parser_objc_at_property_declaration (c_parser *parser) 11969 { 11970 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY)); 11971 location_t loc = c_parser_peek_token (parser)->location; 11972 c_parser_consume_token (parser); /* Eat '@property'. */ 11973 11974 /* Parse the optional attribute list. 11975 11976 A list of parsed, but not verified, attributes. */ 11977 vec<property_attribute_info *> prop_attr_list = vNULL; 11978 11979 bool syntax_error = false; 11980 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 11981 { 11982 matching_parens parens; 11983 11984 location_t attr_start = c_parser_peek_token (parser)->location; 11985 /* Eat the '(' */ 11986 parens.consume_open (parser); 11987 11988 /* Property attribute keywords are valid now. */ 11989 parser->objc_property_attr_context = true; 11990 11991 /* Allow @property (), with a warning. */ 11992 location_t attr_end = c_parser_peek_token (parser)->location; 11993 11994 if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 11995 { 11996 location_t attr_comb = make_location (attr_end, attr_start, attr_end); 11997 warning_at (attr_comb, OPT_Wattributes, 11998 "empty property attribute list"); 11999 } 12000 else 12001 while (true) 12002 { 12003 c_token *token = c_parser_peek_token (parser); 12004 attr_start = token->location; 12005 attr_end = get_finish (token->location); 12006 location_t attr_comb = make_location (attr_start, attr_start, 12007 attr_end); 12008 12009 if (token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA) 12010 { 12011 warning_at (attr_comb, OPT_Wattributes, 12012 "missing property attribute"); 12013 if (token->type == CPP_CLOSE_PAREN) 12014 break; 12015 c_parser_consume_token (parser); 12016 continue; 12017 } 12018 12019 tree attr_name = NULL_TREE; 12020 enum rid keyword = RID_MAX; /* Not a valid property attribute. */ 12021 bool add_at = false; 12022 if (token->type == CPP_KEYWORD) 12023 { 12024 keyword = token->keyword; 12025 if (OBJC_IS_AT_KEYWORD (keyword)) 12026 { 12027 /* For '@' keywords the token value has the keyword, 12028 prepend the '@' for diagnostics. */ 12029 attr_name = token->value; 12030 add_at = true; 12031 } 12032 else 12033 attr_name = ridpointers[(int)keyword]; 12034 } 12035 else if (token->type == CPP_NAME) 12036 attr_name = token->value; 12037 c_parser_consume_token (parser); 12038 12039 enum objc_property_attribute_kind prop_kind 12040 = objc_prop_attr_kind_for_rid (keyword); 12041 property_attribute_info *prop 12042 = new property_attribute_info (attr_name, attr_comb, prop_kind); 12043 prop_attr_list.safe_push (prop); 12044 12045 tree meth_name; 12046 switch (prop->prop_kind) 12047 { 12048 default: break; 12049 case OBJC_PROPERTY_ATTR_UNKNOWN: 12050 if (attr_name) 12051 error_at (attr_comb, "unknown property attribute %<%s%s%>", 12052 add_at ? "@" : "", IDENTIFIER_POINTER (attr_name)); 12053 else 12054 error_at (attr_comb, "unknown property attribute"); 12055 prop->parse_error = syntax_error = true; 12056 break; 12057 12058 case OBJC_PROPERTY_ATTR_GETTER: 12059 case OBJC_PROPERTY_ATTR_SETTER: 12060 if (c_parser_next_token_is_not (parser, CPP_EQ)) 12061 { 12062 attr_comb = make_location (attr_end, attr_start, attr_end); 12063 error_at (attr_comb, "expected %<=%> after Objective-C %qE", 12064 attr_name); 12065 prop->parse_error = syntax_error = true; 12066 break; 12067 } 12068 token = c_parser_peek_token (parser); 12069 attr_end = token->location; 12070 c_parser_consume_token (parser); /* eat the = */ 12071 if (c_parser_next_token_is_not (parser, CPP_NAME)) 12072 { 12073 attr_comb = make_location (attr_end, attr_start, attr_end); 12074 error_at (attr_comb, "expected %qE selector name", 12075 attr_name); 12076 prop->parse_error = syntax_error = true; 12077 break; 12078 } 12079 /* Get the end of the method name, and consume the name. */ 12080 token = c_parser_peek_token (parser); 12081 attr_end = get_finish (token->location); 12082 meth_name = token->value; 12083 c_parser_consume_token (parser); 12084 if (prop->prop_kind == OBJC_PROPERTY_ATTR_SETTER) 12085 { 12086 if (c_parser_next_token_is_not (parser, CPP_COLON)) 12087 { 12088 attr_comb = make_location (attr_end, attr_start, 12089 attr_end); 12090 error_at (attr_comb, "setter method names must" 12091 " terminate with %<:%>"); 12092 prop->parse_error = syntax_error = true; 12093 } 12094 else 12095 { 12096 attr_end = get_finish (c_parser_peek_token 12097 (parser)->location); 12098 c_parser_consume_token (parser); 12099 } 12100 attr_comb = make_location (attr_start, attr_start, 12101 attr_end); 12102 } 12103 else 12104 attr_comb = make_location (attr_start, attr_start, 12105 attr_end); 12106 prop->ident = meth_name; 12107 /* Updated location including all that was successfully 12108 parsed. */ 12109 prop->prop_loc = attr_comb; 12110 break; 12111 } 12112 12113 /* If we see a comma here, then keep going - even if we already 12114 saw a syntax error. For simple mistakes e.g. (asign, getter=x) 12115 this makes a more useful output and avoid spurious warnings about 12116 missing attributes that are, in fact, specified after the one with 12117 the syntax error. */ 12118 if (c_parser_next_token_is (parser, CPP_COMMA)) 12119 c_parser_consume_token (parser); 12120 else 12121 break; 12122 } 12123 parser->objc_property_attr_context = false; 12124 12125 if (syntax_error && c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN)) 12126 /* We don't really want to chew the whole of the file looking for a 12127 matching closing parenthesis, so we will try to read the decl and 12128 let the error handling for that close out the statement. */ 12129 ; 12130 else 12131 syntax_error = false, parens.skip_until_found_close (parser); 12132 } 12133 12134 /* 'properties' is the list of properties that we read. Usually a 12135 single one, but maybe more (eg, in "@property int a, b, c;" there 12136 are three). */ 12137 tree properties = c_parser_struct_declaration (parser); 12138 12139 if (properties == error_mark_node) 12140 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); 12141 else 12142 { 12143 if (properties == NULL_TREE) 12144 c_parser_error (parser, "expected identifier"); 12145 else 12146 { 12147 /* Comma-separated properties are chained together in reverse order; 12148 add them one by one. */ 12149 properties = nreverse (properties); 12150 for (; properties; properties = TREE_CHAIN (properties)) 12151 objc_add_property_declaration (loc, copy_node (properties), 12152 prop_attr_list); 12153 } 12154 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 12155 } 12156 12157 while (!prop_attr_list.is_empty()) 12158 delete prop_attr_list.pop (); 12159 prop_attr_list.release (); 12160 parser->error = false; 12161 } 12162 12163 /* Parse an Objective-C @synthesize declaration. The syntax is: 12164 12165 objc-synthesize-declaration: 12166 @synthesize objc-synthesize-identifier-list ; 12167 12168 objc-synthesize-identifier-list: 12169 objc-synthesize-identifier 12170 objc-synthesize-identifier-list, objc-synthesize-identifier 12171 12172 objc-synthesize-identifier 12173 identifier 12174 identifier = identifier 12175 12176 For example: 12177 @synthesize MyProperty; 12178 @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty; 12179 12180 PS: This function is identical to cp_parser_objc_at_synthesize_declaration 12181 for C++. Keep them in sync. 12182 */ 12183 static void 12184 c_parser_objc_at_synthesize_declaration (c_parser *parser) 12185 { 12186 tree list = NULL_TREE; 12187 location_t loc; 12188 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE)); 12189 loc = c_parser_peek_token (parser)->location; 12190 12191 c_parser_consume_token (parser); 12192 while (true) 12193 { 12194 tree property, ivar; 12195 if (c_parser_next_token_is_not (parser, CPP_NAME)) 12196 { 12197 c_parser_error (parser, "expected identifier"); 12198 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); 12199 /* Once we find the semicolon, we can resume normal parsing. 12200 We have to reset parser->error manually because 12201 c_parser_skip_until_found() won't reset it for us if the 12202 next token is precisely a semicolon. */ 12203 parser->error = false; 12204 return; 12205 } 12206 property = c_parser_peek_token (parser)->value; 12207 c_parser_consume_token (parser); 12208 if (c_parser_next_token_is (parser, CPP_EQ)) 12209 { 12210 c_parser_consume_token (parser); 12211 if (c_parser_next_token_is_not (parser, CPP_NAME)) 12212 { 12213 c_parser_error (parser, "expected identifier"); 12214 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); 12215 parser->error = false; 12216 return; 12217 } 12218 ivar = c_parser_peek_token (parser)->value; 12219 c_parser_consume_token (parser); 12220 } 12221 else 12222 ivar = NULL_TREE; 12223 list = chainon (list, build_tree_list (ivar, property)); 12224 if (c_parser_next_token_is (parser, CPP_COMMA)) 12225 c_parser_consume_token (parser); 12226 else 12227 break; 12228 } 12229 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 12230 objc_add_synthesize_declaration (loc, list); 12231 } 12232 12233 /* Parse an Objective-C @dynamic declaration. The syntax is: 12234 12235 objc-dynamic-declaration: 12236 @dynamic identifier-list ; 12237 12238 For example: 12239 @dynamic MyProperty; 12240 @dynamic MyProperty, AnotherProperty; 12241 12242 PS: This function is identical to cp_parser_objc_at_dynamic_declaration 12243 for C++. Keep them in sync. 12244 */ 12245 static void 12246 c_parser_objc_at_dynamic_declaration (c_parser *parser) 12247 { 12248 tree list = NULL_TREE; 12249 location_t loc; 12250 gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC)); 12251 loc = c_parser_peek_token (parser)->location; 12252 12253 c_parser_consume_token (parser); 12254 while (true) 12255 { 12256 tree property; 12257 if (c_parser_next_token_is_not (parser, CPP_NAME)) 12258 { 12259 c_parser_error (parser, "expected identifier"); 12260 c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL); 12261 parser->error = false; 12262 return; 12263 } 12264 property = c_parser_peek_token (parser)->value; 12265 list = chainon (list, build_tree_list (NULL_TREE, property)); 12266 c_parser_consume_token (parser); 12267 if (c_parser_next_token_is (parser, CPP_COMMA)) 12268 c_parser_consume_token (parser); 12269 else 12270 break; 12271 } 12272 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 12273 objc_add_dynamic_declaration (loc, list); 12274 } 12275 12276 12277 /* Parse a pragma GCC ivdep. */ 12278 12279 static bool 12280 c_parse_pragma_ivdep (c_parser *parser) 12281 { 12282 c_parser_consume_pragma (parser); 12283 c_parser_skip_to_pragma_eol (parser); 12284 return true; 12285 } 12286 12287 /* Parse a pragma GCC unroll. */ 12288 12289 static unsigned short 12290 c_parser_pragma_unroll (c_parser *parser) 12291 { 12292 unsigned short unroll; 12293 c_parser_consume_pragma (parser); 12294 location_t location = c_parser_peek_token (parser)->location; 12295 tree expr = c_parser_expr_no_commas (parser, NULL).value; 12296 mark_exp_read (expr); 12297 expr = c_fully_fold (expr, false, NULL); 12298 HOST_WIDE_INT lunroll = 0; 12299 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)) 12300 || TREE_CODE (expr) != INTEGER_CST 12301 || (lunroll = tree_to_shwi (expr)) < 0 12302 || lunroll >= USHRT_MAX) 12303 { 12304 error_at (location, "%<#pragma GCC unroll%> requires an" 12305 " assignment-expression that evaluates to a non-negative" 12306 " integral constant less than %u", USHRT_MAX); 12307 unroll = 0; 12308 } 12309 else 12310 { 12311 unroll = (unsigned short)lunroll; 12312 if (unroll == 0) 12313 unroll = 1; 12314 } 12315 12316 c_parser_skip_to_pragma_eol (parser); 12317 return unroll; 12318 } 12319 12320 /* Handle pragmas. Some OpenMP pragmas are associated with, and therefore 12321 should be considered, statements. ALLOW_STMT is true if we're within 12322 the context of a function and such pragmas are to be allowed. Returns 12323 true if we actually parsed such a pragma. */ 12324 12325 static bool 12326 c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p) 12327 { 12328 unsigned int id; 12329 const char *construct = NULL; 12330 12331 input_location = c_parser_peek_token (parser)->location; 12332 id = c_parser_peek_token (parser)->pragma_kind; 12333 gcc_assert (id != PRAGMA_NONE); 12334 12335 switch (id) 12336 { 12337 case PRAGMA_OACC_DECLARE: 12338 c_parser_oacc_declare (parser); 12339 return false; 12340 12341 case PRAGMA_OACC_ENTER_DATA: 12342 if (context != pragma_compound) 12343 { 12344 construct = "acc enter data"; 12345 in_compound: 12346 if (context == pragma_stmt) 12347 { 12348 error_at (c_parser_peek_token (parser)->location, 12349 "%<#pragma %s%> may only be used in compound " 12350 "statements", construct); 12351 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); 12352 return false; 12353 } 12354 goto bad_stmt; 12355 } 12356 c_parser_oacc_enter_exit_data (parser, true); 12357 return false; 12358 12359 case PRAGMA_OACC_EXIT_DATA: 12360 if (context != pragma_compound) 12361 { 12362 construct = "acc exit data"; 12363 goto in_compound; 12364 } 12365 c_parser_oacc_enter_exit_data (parser, false); 12366 return false; 12367 12368 case PRAGMA_OACC_ROUTINE: 12369 if (context != pragma_external) 12370 { 12371 error_at (c_parser_peek_token (parser)->location, 12372 "%<#pragma acc routine%> must be at file scope"); 12373 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); 12374 return false; 12375 } 12376 c_parser_oacc_routine (parser, context); 12377 return false; 12378 12379 case PRAGMA_OACC_UPDATE: 12380 if (context != pragma_compound) 12381 { 12382 construct = "acc update"; 12383 goto in_compound; 12384 } 12385 c_parser_oacc_update (parser); 12386 return false; 12387 12388 case PRAGMA_OMP_BARRIER: 12389 if (context != pragma_compound) 12390 { 12391 construct = "omp barrier"; 12392 goto in_compound; 12393 } 12394 c_parser_omp_barrier (parser); 12395 return false; 12396 12397 case PRAGMA_OMP_DEPOBJ: 12398 if (context != pragma_compound) 12399 { 12400 construct = "omp depobj"; 12401 goto in_compound; 12402 } 12403 c_parser_omp_depobj (parser); 12404 return false; 12405 12406 case PRAGMA_OMP_FLUSH: 12407 if (context != pragma_compound) 12408 { 12409 construct = "omp flush"; 12410 goto in_compound; 12411 } 12412 c_parser_omp_flush (parser); 12413 return false; 12414 12415 case PRAGMA_OMP_TASKWAIT: 12416 if (context != pragma_compound) 12417 { 12418 construct = "omp taskwait"; 12419 goto in_compound; 12420 } 12421 c_parser_omp_taskwait (parser); 12422 return false; 12423 12424 case PRAGMA_OMP_TASKYIELD: 12425 if (context != pragma_compound) 12426 { 12427 construct = "omp taskyield"; 12428 goto in_compound; 12429 } 12430 c_parser_omp_taskyield (parser); 12431 return false; 12432 12433 case PRAGMA_OMP_CANCEL: 12434 if (context != pragma_compound) 12435 { 12436 construct = "omp cancel"; 12437 goto in_compound; 12438 } 12439 c_parser_omp_cancel (parser); 12440 return false; 12441 12442 case PRAGMA_OMP_CANCELLATION_POINT: 12443 c_parser_omp_cancellation_point (parser, context); 12444 return false; 12445 12446 case PRAGMA_OMP_THREADPRIVATE: 12447 c_parser_omp_threadprivate (parser); 12448 return false; 12449 12450 case PRAGMA_OMP_TARGET: 12451 return c_parser_omp_target (parser, context, if_p); 12452 12453 case PRAGMA_OMP_END_DECLARE_TARGET: 12454 c_parser_omp_end_declare_target (parser); 12455 return false; 12456 12457 case PRAGMA_OMP_SCAN: 12458 error_at (c_parser_peek_token (parser)->location, 12459 "%<#pragma omp scan%> may only be used in " 12460 "a loop construct with %<inscan%> %<reduction%> clause"); 12461 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); 12462 return false; 12463 12464 case PRAGMA_OMP_SECTION: 12465 error_at (c_parser_peek_token (parser)->location, 12466 "%<#pragma omp section%> may only be used in " 12467 "%<#pragma omp sections%> construct"); 12468 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); 12469 return false; 12470 12471 case PRAGMA_OMP_DECLARE: 12472 c_parser_omp_declare (parser, context); 12473 return false; 12474 12475 case PRAGMA_OMP_REQUIRES: 12476 if (context != pragma_external) 12477 { 12478 error_at (c_parser_peek_token (parser)->location, 12479 "%<#pragma omp requires%> may only be used at file scope"); 12480 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); 12481 return false; 12482 } 12483 c_parser_omp_requires (parser); 12484 return false; 12485 12486 case PRAGMA_OMP_ORDERED: 12487 return c_parser_omp_ordered (parser, context, if_p); 12488 12489 case PRAGMA_IVDEP: 12490 { 12491 const bool ivdep = c_parse_pragma_ivdep (parser); 12492 unsigned short unroll; 12493 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_UNROLL) 12494 unroll = c_parser_pragma_unroll (parser); 12495 else 12496 unroll = 0; 12497 if (!c_parser_next_token_is_keyword (parser, RID_FOR) 12498 && !c_parser_next_token_is_keyword (parser, RID_WHILE) 12499 && !c_parser_next_token_is_keyword (parser, RID_DO)) 12500 { 12501 c_parser_error (parser, "for, while or do statement expected"); 12502 return false; 12503 } 12504 if (c_parser_next_token_is_keyword (parser, RID_FOR)) 12505 c_parser_for_statement (parser, ivdep, unroll, if_p); 12506 else if (c_parser_next_token_is_keyword (parser, RID_WHILE)) 12507 c_parser_while_statement (parser, ivdep, unroll, if_p); 12508 else 12509 c_parser_do_statement (parser, ivdep, unroll); 12510 } 12511 return false; 12512 12513 case PRAGMA_UNROLL: 12514 { 12515 unsigned short unroll = c_parser_pragma_unroll (parser); 12516 bool ivdep; 12517 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_IVDEP) 12518 ivdep = c_parse_pragma_ivdep (parser); 12519 else 12520 ivdep = false; 12521 if (!c_parser_next_token_is_keyword (parser, RID_FOR) 12522 && !c_parser_next_token_is_keyword (parser, RID_WHILE) 12523 && !c_parser_next_token_is_keyword (parser, RID_DO)) 12524 { 12525 c_parser_error (parser, "for, while or do statement expected"); 12526 return false; 12527 } 12528 if (c_parser_next_token_is_keyword (parser, RID_FOR)) 12529 c_parser_for_statement (parser, ivdep, unroll, if_p); 12530 else if (c_parser_next_token_is_keyword (parser, RID_WHILE)) 12531 c_parser_while_statement (parser, ivdep, unroll, if_p); 12532 else 12533 c_parser_do_statement (parser, ivdep, unroll); 12534 } 12535 return false; 12536 12537 case PRAGMA_GCC_PCH_PREPROCESS: 12538 c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first"); 12539 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); 12540 return false; 12541 12542 case PRAGMA_OACC_WAIT: 12543 if (context != pragma_compound) 12544 { 12545 construct = "acc wait"; 12546 goto in_compound; 12547 } 12548 /* FALL THROUGH. */ 12549 12550 default: 12551 if (id < PRAGMA_FIRST_EXTERNAL) 12552 { 12553 if (context != pragma_stmt && context != pragma_compound) 12554 { 12555 bad_stmt: 12556 c_parser_error (parser, "expected declaration specifiers"); 12557 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); 12558 return false; 12559 } 12560 c_parser_omp_construct (parser, if_p); 12561 return true; 12562 } 12563 break; 12564 } 12565 12566 c_parser_consume_pragma (parser); 12567 c_invoke_pragma_handler (id); 12568 12569 /* Skip to EOL, but suppress any error message. Those will have been 12570 generated by the handler routine through calling error, as opposed 12571 to calling c_parser_error. */ 12572 parser->error = true; 12573 c_parser_skip_to_pragma_eol (parser); 12574 12575 return false; 12576 } 12577 12578 /* The interface the pragma parsers have to the lexer. */ 12579 12580 enum cpp_ttype 12581 pragma_lex (tree *value, location_t *loc) 12582 { 12583 c_token *tok = c_parser_peek_token (the_parser); 12584 enum cpp_ttype ret = tok->type; 12585 12586 *value = tok->value; 12587 if (loc) 12588 *loc = tok->location; 12589 12590 if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF) 12591 ret = CPP_EOF; 12592 else if (ret == CPP_STRING) 12593 *value = c_parser_string_literal (the_parser, false, false).value; 12594 else 12595 { 12596 if (ret == CPP_KEYWORD) 12597 ret = CPP_NAME; 12598 c_parser_consume_token (the_parser); 12599 } 12600 12601 return ret; 12602 } 12603 12604 static void 12605 c_parser_pragma_pch_preprocess (c_parser *parser) 12606 { 12607 tree name = NULL; 12608 12609 parser->lex_joined_string = true; 12610 c_parser_consume_pragma (parser); 12611 if (c_parser_next_token_is (parser, CPP_STRING)) 12612 { 12613 name = c_parser_peek_token (parser)->value; 12614 c_parser_consume_token (parser); 12615 } 12616 else 12617 c_parser_error (parser, "expected string literal"); 12618 c_parser_skip_to_pragma_eol (parser); 12619 parser->lex_joined_string = false; 12620 12621 if (name) 12622 c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name)); 12623 } 12624 12625 /* OpenACC and OpenMP parsing routines. */ 12626 12627 /* Returns name of the next clause. 12628 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and 12629 the token is not consumed. Otherwise appropriate pragma_omp_clause is 12630 returned and the token is consumed. */ 12631 12632 static pragma_omp_clause 12633 c_parser_omp_clause_name (c_parser *parser) 12634 { 12635 pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE; 12636 12637 if (c_parser_next_token_is_keyword (parser, RID_AUTO)) 12638 result = PRAGMA_OACC_CLAUSE_AUTO; 12639 else if (c_parser_next_token_is_keyword (parser, RID_IF)) 12640 result = PRAGMA_OMP_CLAUSE_IF; 12641 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)) 12642 result = PRAGMA_OMP_CLAUSE_DEFAULT; 12643 else if (c_parser_next_token_is_keyword (parser, RID_FOR)) 12644 result = PRAGMA_OMP_CLAUSE_FOR; 12645 else if (c_parser_next_token_is (parser, CPP_NAME)) 12646 { 12647 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 12648 12649 switch (p[0]) 12650 { 12651 case 'a': 12652 if (!strcmp ("aligned", p)) 12653 result = PRAGMA_OMP_CLAUSE_ALIGNED; 12654 else if (!strcmp ("async", p)) 12655 result = PRAGMA_OACC_CLAUSE_ASYNC; 12656 else if (!strcmp ("attach", p)) 12657 result = PRAGMA_OACC_CLAUSE_ATTACH; 12658 break; 12659 case 'b': 12660 if (!strcmp ("bind", p)) 12661 result = PRAGMA_OMP_CLAUSE_BIND; 12662 break; 12663 case 'c': 12664 if (!strcmp ("collapse", p)) 12665 result = PRAGMA_OMP_CLAUSE_COLLAPSE; 12666 else if (!strcmp ("copy", p)) 12667 result = PRAGMA_OACC_CLAUSE_COPY; 12668 else if (!strcmp ("copyin", p)) 12669 result = PRAGMA_OMP_CLAUSE_COPYIN; 12670 else if (!strcmp ("copyout", p)) 12671 result = PRAGMA_OACC_CLAUSE_COPYOUT; 12672 else if (!strcmp ("copyprivate", p)) 12673 result = PRAGMA_OMP_CLAUSE_COPYPRIVATE; 12674 else if (!strcmp ("create", p)) 12675 result = PRAGMA_OACC_CLAUSE_CREATE; 12676 break; 12677 case 'd': 12678 if (!strcmp ("defaultmap", p)) 12679 result = PRAGMA_OMP_CLAUSE_DEFAULTMAP; 12680 else if (!strcmp ("delete", p)) 12681 result = PRAGMA_OACC_CLAUSE_DELETE; 12682 else if (!strcmp ("depend", p)) 12683 result = PRAGMA_OMP_CLAUSE_DEPEND; 12684 else if (!strcmp ("detach", p)) 12685 result = PRAGMA_OACC_CLAUSE_DETACH; 12686 else if (!strcmp ("device", p)) 12687 result = PRAGMA_OMP_CLAUSE_DEVICE; 12688 else if (!strcmp ("deviceptr", p)) 12689 result = PRAGMA_OACC_CLAUSE_DEVICEPTR; 12690 else if (!strcmp ("device_resident", p)) 12691 result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT; 12692 else if (!strcmp ("device_type", p)) 12693 result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE; 12694 else if (!strcmp ("dist_schedule", p)) 12695 result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE; 12696 break; 12697 case 'f': 12698 if (!strcmp ("final", p)) 12699 result = PRAGMA_OMP_CLAUSE_FINAL; 12700 else if (!strcmp ("finalize", p)) 12701 result = PRAGMA_OACC_CLAUSE_FINALIZE; 12702 else if (!strcmp ("firstprivate", p)) 12703 result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE; 12704 else if (!strcmp ("from", p)) 12705 result = PRAGMA_OMP_CLAUSE_FROM; 12706 break; 12707 case 'g': 12708 if (!strcmp ("gang", p)) 12709 result = PRAGMA_OACC_CLAUSE_GANG; 12710 else if (!strcmp ("grainsize", p)) 12711 result = PRAGMA_OMP_CLAUSE_GRAINSIZE; 12712 break; 12713 case 'h': 12714 if (!strcmp ("hint", p)) 12715 result = PRAGMA_OMP_CLAUSE_HINT; 12716 else if (!strcmp ("host", p)) 12717 result = PRAGMA_OACC_CLAUSE_HOST; 12718 break; 12719 case 'i': 12720 if (!strcmp ("if_present", p)) 12721 result = PRAGMA_OACC_CLAUSE_IF_PRESENT; 12722 else if (!strcmp ("in_reduction", p)) 12723 result = PRAGMA_OMP_CLAUSE_IN_REDUCTION; 12724 else if (!strcmp ("inbranch", p)) 12725 result = PRAGMA_OMP_CLAUSE_INBRANCH; 12726 else if (!strcmp ("independent", p)) 12727 result = PRAGMA_OACC_CLAUSE_INDEPENDENT; 12728 else if (!strcmp ("is_device_ptr", p)) 12729 result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR; 12730 break; 12731 case 'l': 12732 if (!strcmp ("lastprivate", p)) 12733 result = PRAGMA_OMP_CLAUSE_LASTPRIVATE; 12734 else if (!strcmp ("linear", p)) 12735 result = PRAGMA_OMP_CLAUSE_LINEAR; 12736 else if (!strcmp ("link", p)) 12737 result = PRAGMA_OMP_CLAUSE_LINK; 12738 break; 12739 case 'm': 12740 if (!strcmp ("map", p)) 12741 result = PRAGMA_OMP_CLAUSE_MAP; 12742 else if (!strcmp ("mergeable", p)) 12743 result = PRAGMA_OMP_CLAUSE_MERGEABLE; 12744 break; 12745 case 'n': 12746 if (!strcmp ("no_create", p)) 12747 result = PRAGMA_OACC_CLAUSE_NO_CREATE; 12748 else if (!strcmp ("nogroup", p)) 12749 result = PRAGMA_OMP_CLAUSE_NOGROUP; 12750 else if (!strcmp ("nontemporal", p)) 12751 result = PRAGMA_OMP_CLAUSE_NONTEMPORAL; 12752 else if (!strcmp ("notinbranch", p)) 12753 result = PRAGMA_OMP_CLAUSE_NOTINBRANCH; 12754 else if (!strcmp ("nowait", p)) 12755 result = PRAGMA_OMP_CLAUSE_NOWAIT; 12756 else if (!strcmp ("num_gangs", p)) 12757 result = PRAGMA_OACC_CLAUSE_NUM_GANGS; 12758 else if (!strcmp ("num_tasks", p)) 12759 result = PRAGMA_OMP_CLAUSE_NUM_TASKS; 12760 else if (!strcmp ("num_teams", p)) 12761 result = PRAGMA_OMP_CLAUSE_NUM_TEAMS; 12762 else if (!strcmp ("num_threads", p)) 12763 result = PRAGMA_OMP_CLAUSE_NUM_THREADS; 12764 else if (!strcmp ("num_workers", p)) 12765 result = PRAGMA_OACC_CLAUSE_NUM_WORKERS; 12766 break; 12767 case 'o': 12768 if (!strcmp ("ordered", p)) 12769 result = PRAGMA_OMP_CLAUSE_ORDERED; 12770 else if (!strcmp ("order", p)) 12771 result = PRAGMA_OMP_CLAUSE_ORDER; 12772 break; 12773 case 'p': 12774 if (!strcmp ("parallel", p)) 12775 result = PRAGMA_OMP_CLAUSE_PARALLEL; 12776 else if (!strcmp ("present", p)) 12777 result = PRAGMA_OACC_CLAUSE_PRESENT; 12778 /* As of OpenACC 2.5, these are now aliases of the non-present_or 12779 clauses. */ 12780 else if (!strcmp ("present_or_copy", p) 12781 || !strcmp ("pcopy", p)) 12782 result = PRAGMA_OACC_CLAUSE_COPY; 12783 else if (!strcmp ("present_or_copyin", p) 12784 || !strcmp ("pcopyin", p)) 12785 result = PRAGMA_OACC_CLAUSE_COPYIN; 12786 else if (!strcmp ("present_or_copyout", p) 12787 || !strcmp ("pcopyout", p)) 12788 result = PRAGMA_OACC_CLAUSE_COPYOUT; 12789 else if (!strcmp ("present_or_create", p) 12790 || !strcmp ("pcreate", p)) 12791 result = PRAGMA_OACC_CLAUSE_CREATE; 12792 else if (!strcmp ("priority", p)) 12793 result = PRAGMA_OMP_CLAUSE_PRIORITY; 12794 else if (!strcmp ("private", p)) 12795 result = PRAGMA_OMP_CLAUSE_PRIVATE; 12796 else if (!strcmp ("proc_bind", p)) 12797 result = PRAGMA_OMP_CLAUSE_PROC_BIND; 12798 break; 12799 case 'r': 12800 if (!strcmp ("reduction", p)) 12801 result = PRAGMA_OMP_CLAUSE_REDUCTION; 12802 break; 12803 case 's': 12804 if (!strcmp ("safelen", p)) 12805 result = PRAGMA_OMP_CLAUSE_SAFELEN; 12806 else if (!strcmp ("schedule", p)) 12807 result = PRAGMA_OMP_CLAUSE_SCHEDULE; 12808 else if (!strcmp ("sections", p)) 12809 result = PRAGMA_OMP_CLAUSE_SECTIONS; 12810 else if (!strcmp ("self", p)) /* "self" is a synonym for "host". */ 12811 result = PRAGMA_OACC_CLAUSE_HOST; 12812 else if (!strcmp ("seq", p)) 12813 result = PRAGMA_OACC_CLAUSE_SEQ; 12814 else if (!strcmp ("shared", p)) 12815 result = PRAGMA_OMP_CLAUSE_SHARED; 12816 else if (!strcmp ("simd", p)) 12817 result = PRAGMA_OMP_CLAUSE_SIMD; 12818 else if (!strcmp ("simdlen", p)) 12819 result = PRAGMA_OMP_CLAUSE_SIMDLEN; 12820 break; 12821 case 't': 12822 if (!strcmp ("task_reduction", p)) 12823 result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION; 12824 else if (!strcmp ("taskgroup", p)) 12825 result = PRAGMA_OMP_CLAUSE_TASKGROUP; 12826 else if (!strcmp ("thread_limit", p)) 12827 result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT; 12828 else if (!strcmp ("threads", p)) 12829 result = PRAGMA_OMP_CLAUSE_THREADS; 12830 else if (!strcmp ("tile", p)) 12831 result = PRAGMA_OACC_CLAUSE_TILE; 12832 else if (!strcmp ("to", p)) 12833 result = PRAGMA_OMP_CLAUSE_TO; 12834 break; 12835 case 'u': 12836 if (!strcmp ("uniform", p)) 12837 result = PRAGMA_OMP_CLAUSE_UNIFORM; 12838 else if (!strcmp ("untied", p)) 12839 result = PRAGMA_OMP_CLAUSE_UNTIED; 12840 else if (!strcmp ("use_device", p)) 12841 result = PRAGMA_OACC_CLAUSE_USE_DEVICE; 12842 else if (!strcmp ("use_device_addr", p)) 12843 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR; 12844 else if (!strcmp ("use_device_ptr", p)) 12845 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR; 12846 break; 12847 case 'v': 12848 if (!strcmp ("vector", p)) 12849 result = PRAGMA_OACC_CLAUSE_VECTOR; 12850 else if (!strcmp ("vector_length", p)) 12851 result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH; 12852 break; 12853 case 'w': 12854 if (!strcmp ("wait", p)) 12855 result = PRAGMA_OACC_CLAUSE_WAIT; 12856 else if (!strcmp ("worker", p)) 12857 result = PRAGMA_OACC_CLAUSE_WORKER; 12858 break; 12859 } 12860 } 12861 12862 if (result != PRAGMA_OMP_CLAUSE_NONE) 12863 c_parser_consume_token (parser); 12864 12865 return result; 12866 } 12867 12868 /* Validate that a clause of the given type does not already exist. */ 12869 12870 static void 12871 check_no_duplicate_clause (tree clauses, enum omp_clause_code code, 12872 const char *name) 12873 { 12874 if (tree c = omp_find_clause (clauses, code)) 12875 error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name); 12876 } 12877 12878 /* OpenACC 2.0 12879 Parse wait clause or wait directive parameters. */ 12880 12881 static tree 12882 c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list) 12883 { 12884 vec<tree, va_gc> *args; 12885 tree t, args_tree; 12886 12887 matching_parens parens; 12888 if (!parens.require_open (parser)) 12889 return list; 12890 12891 args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL); 12892 args_tree = build_tree_list_vec (args); 12893 12894 for (t = args_tree; t; t = TREE_CHAIN (t)) 12895 { 12896 tree targ = TREE_VALUE (t); 12897 12898 if (targ != error_mark_node) 12899 { 12900 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ))) 12901 { 12902 c_parser_error (parser, "expression must be integral"); 12903 targ = error_mark_node; 12904 } 12905 else 12906 { 12907 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT); 12908 12909 OMP_CLAUSE_DECL (c) = targ; 12910 OMP_CLAUSE_CHAIN (c) = list; 12911 list = c; 12912 } 12913 } 12914 } 12915 12916 release_tree_vector (args); 12917 parens.require_close (parser); 12918 return list; 12919 } 12920 12921 /* OpenACC 2.0, OpenMP 2.5: 12922 variable-list: 12923 identifier 12924 variable-list , identifier 12925 12926 If KIND is nonzero, create the appropriate node and install the 12927 decl in OMP_CLAUSE_DECL and add the node to the head of the list. 12928 If KIND is nonzero, CLAUSE_LOC is the location of the clause. 12929 12930 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE; 12931 return the list created. 12932 12933 The optional ALLOW_DEREF argument is true if list items can use the deref 12934 (->) operator. */ 12935 12936 static tree 12937 c_parser_omp_variable_list (c_parser *parser, 12938 location_t clause_loc, 12939 enum omp_clause_code kind, tree list, 12940 bool allow_deref = false) 12941 { 12942 auto_vec<c_token> tokens; 12943 unsigned int tokens_avail = 0; 12944 bool first = true; 12945 12946 while (1) 12947 { 12948 bool array_section_p = false; 12949 if (kind == OMP_CLAUSE_DEPEND) 12950 { 12951 if (c_parser_next_token_is_not (parser, CPP_NAME) 12952 || c_parser_peek_token (parser)->id_kind != C_ID_ID) 12953 { 12954 struct c_expr expr = c_parser_expr_no_commas (parser, NULL); 12955 if (expr.value != error_mark_node) 12956 { 12957 tree u = build_omp_clause (clause_loc, kind); 12958 OMP_CLAUSE_DECL (u) = expr.value; 12959 OMP_CLAUSE_CHAIN (u) = list; 12960 list = u; 12961 } 12962 12963 if (c_parser_next_token_is_not (parser, CPP_COMMA)) 12964 break; 12965 12966 c_parser_consume_token (parser); 12967 first = false; 12968 continue; 12969 } 12970 12971 tokens.truncate (0); 12972 unsigned int nesting_depth = 0; 12973 while (1) 12974 { 12975 c_token *token = c_parser_peek_token (parser); 12976 switch (token->type) 12977 { 12978 case CPP_EOF: 12979 case CPP_PRAGMA_EOL: 12980 break; 12981 case CPP_OPEN_BRACE: 12982 case CPP_OPEN_PAREN: 12983 case CPP_OPEN_SQUARE: 12984 ++nesting_depth; 12985 goto add; 12986 case CPP_CLOSE_BRACE: 12987 case CPP_CLOSE_PAREN: 12988 case CPP_CLOSE_SQUARE: 12989 if (nesting_depth-- == 0) 12990 break; 12991 goto add; 12992 case CPP_COMMA: 12993 if (nesting_depth == 0) 12994 break; 12995 goto add; 12996 default: 12997 add: 12998 tokens.safe_push (*token); 12999 c_parser_consume_token (parser); 13000 continue; 13001 } 13002 break; 13003 } 13004 13005 /* Make sure nothing tries to read past the end of the tokens. */ 13006 c_token eof_token; 13007 memset (&eof_token, 0, sizeof (eof_token)); 13008 eof_token.type = CPP_EOF; 13009 tokens.safe_push (eof_token); 13010 tokens.safe_push (eof_token); 13011 13012 tokens_avail = parser->tokens_avail; 13013 gcc_assert (parser->tokens == &parser->tokens_buf[0]); 13014 parser->tokens = tokens.address (); 13015 parser->tokens_avail = tokens.length (); 13016 } 13017 13018 tree t = NULL_TREE; 13019 13020 if (c_parser_next_token_is (parser, CPP_NAME) 13021 && c_parser_peek_token (parser)->id_kind == C_ID_ID) 13022 { 13023 t = lookup_name (c_parser_peek_token (parser)->value); 13024 13025 if (t == NULL_TREE) 13026 { 13027 undeclared_variable (c_parser_peek_token (parser)->location, 13028 c_parser_peek_token (parser)->value); 13029 t = error_mark_node; 13030 } 13031 13032 c_parser_consume_token (parser); 13033 } 13034 else if (c_parser_next_token_is (parser, CPP_KEYWORD) 13035 && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME 13036 || (c_parser_peek_token (parser)->keyword 13037 == RID_PRETTY_FUNCTION_NAME) 13038 || (c_parser_peek_token (parser)->keyword 13039 == RID_C99_FUNCTION_NAME))) 13040 t = c_parser_predefined_identifier (parser).value; 13041 else 13042 { 13043 if (first) 13044 c_parser_error (parser, "expected identifier"); 13045 break; 13046 } 13047 13048 if (t == error_mark_node) 13049 ; 13050 else if (kind != 0) 13051 { 13052 switch (kind) 13053 { 13054 case OMP_CLAUSE__CACHE_: 13055 /* The OpenACC cache directive explicitly only allows "array 13056 elements or subarrays". */ 13057 if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE) 13058 { 13059 c_parser_error (parser, "expected %<[%>"); 13060 t = error_mark_node; 13061 break; 13062 } 13063 /* FALLTHROUGH */ 13064 case OMP_CLAUSE_MAP: 13065 case OMP_CLAUSE_FROM: 13066 case OMP_CLAUSE_TO: 13067 while (c_parser_next_token_is (parser, CPP_DOT) 13068 || (allow_deref 13069 && c_parser_next_token_is (parser, CPP_DEREF))) 13070 { 13071 location_t op_loc = c_parser_peek_token (parser)->location; 13072 if (c_parser_next_token_is (parser, CPP_DEREF)) 13073 t = build_simple_mem_ref (t); 13074 c_parser_consume_token (parser); 13075 if (!c_parser_next_token_is (parser, CPP_NAME)) 13076 { 13077 c_parser_error (parser, "expected identifier"); 13078 t = error_mark_node; 13079 break; 13080 } 13081 13082 c_token *comp_tok = c_parser_peek_token (parser); 13083 tree ident = comp_tok->value; 13084 location_t comp_loc = comp_tok->location; 13085 c_parser_consume_token (parser); 13086 t = build_component_ref (op_loc, t, ident, comp_loc); 13087 } 13088 /* FALLTHROUGH */ 13089 case OMP_CLAUSE_DEPEND: 13090 case OMP_CLAUSE_REDUCTION: 13091 case OMP_CLAUSE_IN_REDUCTION: 13092 case OMP_CLAUSE_TASK_REDUCTION: 13093 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)) 13094 { 13095 tree low_bound = NULL_TREE, length = NULL_TREE; 13096 13097 c_parser_consume_token (parser); 13098 if (!c_parser_next_token_is (parser, CPP_COLON)) 13099 { 13100 location_t expr_loc 13101 = c_parser_peek_token (parser)->location; 13102 c_expr expr = c_parser_expression (parser); 13103 expr = convert_lvalue_to_rvalue (expr_loc, expr, 13104 false, true); 13105 low_bound = expr.value; 13106 } 13107 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) 13108 length = integer_one_node; 13109 else 13110 { 13111 /* Look for `:'. */ 13112 if (!c_parser_require (parser, CPP_COLON, 13113 "expected %<:%>")) 13114 { 13115 t = error_mark_node; 13116 break; 13117 } 13118 array_section_p = true; 13119 if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) 13120 { 13121 location_t expr_loc 13122 = c_parser_peek_token (parser)->location; 13123 c_expr expr = c_parser_expression (parser); 13124 expr = convert_lvalue_to_rvalue (expr_loc, expr, 13125 false, true); 13126 length = expr.value; 13127 } 13128 } 13129 /* Look for the closing `]'. */ 13130 if (!c_parser_require (parser, CPP_CLOSE_SQUARE, 13131 "expected %<]%>")) 13132 { 13133 t = error_mark_node; 13134 break; 13135 } 13136 13137 t = tree_cons (low_bound, length, t); 13138 } 13139 if (kind == OMP_CLAUSE_DEPEND 13140 && t != error_mark_node 13141 && parser->tokens_avail != 2) 13142 { 13143 if (array_section_p) 13144 { 13145 error_at (c_parser_peek_token (parser)->location, 13146 "expected %<)%> or %<,%>"); 13147 t = error_mark_node; 13148 } 13149 else 13150 { 13151 parser->tokens = tokens.address (); 13152 parser->tokens_avail = tokens.length (); 13153 13154 t = c_parser_expr_no_commas (parser, NULL).value; 13155 if (t != error_mark_node && parser->tokens_avail != 2) 13156 { 13157 error_at (c_parser_peek_token (parser)->location, 13158 "expected %<)%> or %<,%>"); 13159 t = error_mark_node; 13160 } 13161 } 13162 } 13163 break; 13164 default: 13165 break; 13166 } 13167 13168 if (t != error_mark_node) 13169 { 13170 tree u = build_omp_clause (clause_loc, kind); 13171 OMP_CLAUSE_DECL (u) = t; 13172 OMP_CLAUSE_CHAIN (u) = list; 13173 list = u; 13174 } 13175 } 13176 else 13177 list = tree_cons (t, NULL_TREE, list); 13178 13179 if (kind == OMP_CLAUSE_DEPEND) 13180 { 13181 parser->tokens = &parser->tokens_buf[0]; 13182 parser->tokens_avail = tokens_avail; 13183 } 13184 if (c_parser_next_token_is_not (parser, CPP_COMMA)) 13185 break; 13186 13187 c_parser_consume_token (parser); 13188 first = false; 13189 } 13190 13191 return list; 13192 } 13193 13194 /* Similarly, but expect leading and trailing parenthesis. This is a very 13195 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF 13196 argument is true if list items can use the deref (->) operator. */ 13197 13198 static tree 13199 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind, 13200 tree list, bool allow_deref = false) 13201 { 13202 /* The clauses location. */ 13203 location_t loc = c_parser_peek_token (parser)->location; 13204 13205 matching_parens parens; 13206 if (parens.require_open (parser)) 13207 { 13208 list = c_parser_omp_variable_list (parser, loc, kind, list, allow_deref); 13209 parens.skip_until_found_close (parser); 13210 } 13211 return list; 13212 } 13213 13214 /* OpenACC 2.0: 13215 copy ( variable-list ) 13216 copyin ( variable-list ) 13217 copyout ( variable-list ) 13218 create ( variable-list ) 13219 delete ( variable-list ) 13220 present ( variable-list ) 13221 13222 OpenACC 2.6: 13223 no_create ( variable-list ) 13224 attach ( variable-list ) 13225 detach ( variable-list ) */ 13226 13227 static tree 13228 c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind, 13229 tree list) 13230 { 13231 enum gomp_map_kind kind; 13232 switch (c_kind) 13233 { 13234 case PRAGMA_OACC_CLAUSE_ATTACH: 13235 kind = GOMP_MAP_ATTACH; 13236 break; 13237 case PRAGMA_OACC_CLAUSE_COPY: 13238 kind = GOMP_MAP_TOFROM; 13239 break; 13240 case PRAGMA_OACC_CLAUSE_COPYIN: 13241 kind = GOMP_MAP_TO; 13242 break; 13243 case PRAGMA_OACC_CLAUSE_COPYOUT: 13244 kind = GOMP_MAP_FROM; 13245 break; 13246 case PRAGMA_OACC_CLAUSE_CREATE: 13247 kind = GOMP_MAP_ALLOC; 13248 break; 13249 case PRAGMA_OACC_CLAUSE_DELETE: 13250 kind = GOMP_MAP_RELEASE; 13251 break; 13252 case PRAGMA_OACC_CLAUSE_DETACH: 13253 kind = GOMP_MAP_DETACH; 13254 break; 13255 case PRAGMA_OACC_CLAUSE_DEVICE: 13256 kind = GOMP_MAP_FORCE_TO; 13257 break; 13258 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT: 13259 kind = GOMP_MAP_DEVICE_RESIDENT; 13260 break; 13261 case PRAGMA_OACC_CLAUSE_HOST: 13262 kind = GOMP_MAP_FORCE_FROM; 13263 break; 13264 case PRAGMA_OACC_CLAUSE_LINK: 13265 kind = GOMP_MAP_LINK; 13266 break; 13267 case PRAGMA_OACC_CLAUSE_NO_CREATE: 13268 kind = GOMP_MAP_IF_PRESENT; 13269 break; 13270 case PRAGMA_OACC_CLAUSE_PRESENT: 13271 kind = GOMP_MAP_FORCE_PRESENT; 13272 break; 13273 default: 13274 gcc_unreachable (); 13275 } 13276 tree nl, c; 13277 nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, true); 13278 13279 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) 13280 OMP_CLAUSE_SET_MAP_KIND (c, kind); 13281 13282 return nl; 13283 } 13284 13285 /* OpenACC 2.0: 13286 deviceptr ( variable-list ) */ 13287 13288 static tree 13289 c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list) 13290 { 13291 location_t loc = c_parser_peek_token (parser)->location; 13292 tree vars, t; 13293 13294 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic 13295 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR, 13296 variable-list must only allow for pointer variables. */ 13297 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL); 13298 for (t = vars; t && t; t = TREE_CHAIN (t)) 13299 { 13300 tree v = TREE_PURPOSE (t); 13301 13302 /* FIXME diagnostics: Ideally we should keep individual 13303 locations for all the variables in the var list to make the 13304 following errors more precise. Perhaps 13305 c_parser_omp_var_list_parens() should construct a list of 13306 locations to go along with the var list. */ 13307 13308 if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL) 13309 error_at (loc, "%qD is not a variable", v); 13310 else if (TREE_TYPE (v) == error_mark_node) 13311 ; 13312 else if (!POINTER_TYPE_P (TREE_TYPE (v))) 13313 error_at (loc, "%qD is not a pointer variable", v); 13314 13315 tree u = build_omp_clause (loc, OMP_CLAUSE_MAP); 13316 OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR); 13317 OMP_CLAUSE_DECL (u) = v; 13318 OMP_CLAUSE_CHAIN (u) = list; 13319 list = u; 13320 } 13321 13322 return list; 13323 } 13324 13325 /* OpenACC 2.0, OpenMP 3.0: 13326 collapse ( constant-expression ) */ 13327 13328 static tree 13329 c_parser_omp_clause_collapse (c_parser *parser, tree list) 13330 { 13331 tree c, num = error_mark_node; 13332 HOST_WIDE_INT n; 13333 location_t loc; 13334 13335 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse"); 13336 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile"); 13337 13338 loc = c_parser_peek_token (parser)->location; 13339 matching_parens parens; 13340 if (parens.require_open (parser)) 13341 { 13342 num = c_parser_expr_no_commas (parser, NULL).value; 13343 parens.skip_until_found_close (parser); 13344 } 13345 if (num == error_mark_node) 13346 return list; 13347 mark_exp_read (num); 13348 num = c_fully_fold (num, false, NULL); 13349 if (!INTEGRAL_TYPE_P (TREE_TYPE (num)) 13350 || !tree_fits_shwi_p (num) 13351 || (n = tree_to_shwi (num)) <= 0 13352 || (int) n != n) 13353 { 13354 error_at (loc, 13355 "collapse argument needs positive constant integer expression"); 13356 return list; 13357 } 13358 c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE); 13359 OMP_CLAUSE_COLLAPSE_EXPR (c) = num; 13360 OMP_CLAUSE_CHAIN (c) = list; 13361 return c; 13362 } 13363 13364 /* OpenMP 2.5: 13365 copyin ( variable-list ) */ 13366 13367 static tree 13368 c_parser_omp_clause_copyin (c_parser *parser, tree list) 13369 { 13370 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list); 13371 } 13372 13373 /* OpenMP 2.5: 13374 copyprivate ( variable-list ) */ 13375 13376 static tree 13377 c_parser_omp_clause_copyprivate (c_parser *parser, tree list) 13378 { 13379 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list); 13380 } 13381 13382 /* OpenMP 2.5: 13383 default ( none | shared ) 13384 13385 OpenACC: 13386 default ( none | present ) */ 13387 13388 static tree 13389 c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc) 13390 { 13391 enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED; 13392 location_t loc = c_parser_peek_token (parser)->location; 13393 tree c; 13394 13395 matching_parens parens; 13396 if (!parens.require_open (parser)) 13397 return list; 13398 if (c_parser_next_token_is (parser, CPP_NAME)) 13399 { 13400 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 13401 13402 switch (p[0]) 13403 { 13404 case 'n': 13405 if (strcmp ("none", p) != 0) 13406 goto invalid_kind; 13407 kind = OMP_CLAUSE_DEFAULT_NONE; 13408 break; 13409 13410 case 'p': 13411 if (strcmp ("present", p) != 0 || !is_oacc) 13412 goto invalid_kind; 13413 kind = OMP_CLAUSE_DEFAULT_PRESENT; 13414 break; 13415 13416 case 's': 13417 if (strcmp ("shared", p) != 0 || is_oacc) 13418 goto invalid_kind; 13419 kind = OMP_CLAUSE_DEFAULT_SHARED; 13420 break; 13421 13422 default: 13423 goto invalid_kind; 13424 } 13425 13426 c_parser_consume_token (parser); 13427 } 13428 else 13429 { 13430 invalid_kind: 13431 if (is_oacc) 13432 c_parser_error (parser, "expected %<none%> or %<present%>"); 13433 else 13434 c_parser_error (parser, "expected %<none%> or %<shared%>"); 13435 } 13436 parens.skip_until_found_close (parser); 13437 13438 if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED) 13439 return list; 13440 13441 check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default"); 13442 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT); 13443 OMP_CLAUSE_CHAIN (c) = list; 13444 OMP_CLAUSE_DEFAULT_KIND (c) = kind; 13445 13446 return c; 13447 } 13448 13449 /* OpenMP 2.5: 13450 firstprivate ( variable-list ) */ 13451 13452 static tree 13453 c_parser_omp_clause_firstprivate (c_parser *parser, tree list) 13454 { 13455 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list); 13456 } 13457 13458 /* OpenMP 3.1: 13459 final ( expression ) */ 13460 13461 static tree 13462 c_parser_omp_clause_final (c_parser *parser, tree list) 13463 { 13464 location_t loc = c_parser_peek_token (parser)->location; 13465 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 13466 { 13467 matching_parens parens; 13468 tree t, c; 13469 if (!parens.require_open (parser)) 13470 t = error_mark_node; 13471 else 13472 { 13473 location_t eloc = c_parser_peek_token (parser)->location; 13474 c_expr expr = c_parser_expr_no_commas (parser, NULL); 13475 t = convert_lvalue_to_rvalue (eloc, expr, true, true).value; 13476 t = c_objc_common_truthvalue_conversion (eloc, t); 13477 t = c_fully_fold (t, false, NULL); 13478 parens.skip_until_found_close (parser); 13479 } 13480 13481 check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final"); 13482 13483 c = build_omp_clause (loc, OMP_CLAUSE_FINAL); 13484 OMP_CLAUSE_FINAL_EXPR (c) = t; 13485 OMP_CLAUSE_CHAIN (c) = list; 13486 list = c; 13487 } 13488 else 13489 c_parser_error (parser, "expected %<(%>"); 13490 13491 return list; 13492 } 13493 13494 /* OpenACC, OpenMP 2.5: 13495 if ( expression ) 13496 13497 OpenMP 4.5: 13498 if ( directive-name-modifier : expression ) 13499 13500 directive-name-modifier: 13501 parallel | task | taskloop | target data | target | target update 13502 | target enter data | target exit data 13503 13504 OpenMP 5.0: 13505 directive-name-modifier: 13506 ... | simd | cancel */ 13507 13508 static tree 13509 c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp) 13510 { 13511 location_t location = c_parser_peek_token (parser)->location; 13512 enum tree_code if_modifier = ERROR_MARK; 13513 13514 matching_parens parens; 13515 if (!parens.require_open (parser)) 13516 return list; 13517 13518 if (is_omp && c_parser_next_token_is (parser, CPP_NAME)) 13519 { 13520 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 13521 int n = 2; 13522 if (strcmp (p, "cancel") == 0) 13523 if_modifier = VOID_CST; 13524 else if (strcmp (p, "parallel") == 0) 13525 if_modifier = OMP_PARALLEL; 13526 else if (strcmp (p, "simd") == 0) 13527 if_modifier = OMP_SIMD; 13528 else if (strcmp (p, "task") == 0) 13529 if_modifier = OMP_TASK; 13530 else if (strcmp (p, "taskloop") == 0) 13531 if_modifier = OMP_TASKLOOP; 13532 else if (strcmp (p, "target") == 0) 13533 { 13534 if_modifier = OMP_TARGET; 13535 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME) 13536 { 13537 p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value); 13538 if (strcmp ("data", p) == 0) 13539 if_modifier = OMP_TARGET_DATA; 13540 else if (strcmp ("update", p) == 0) 13541 if_modifier = OMP_TARGET_UPDATE; 13542 else if (strcmp ("enter", p) == 0) 13543 if_modifier = OMP_TARGET_ENTER_DATA; 13544 else if (strcmp ("exit", p) == 0) 13545 if_modifier = OMP_TARGET_EXIT_DATA; 13546 if (if_modifier != OMP_TARGET) 13547 { 13548 n = 3; 13549 c_parser_consume_token (parser); 13550 } 13551 else 13552 { 13553 location_t loc = c_parser_peek_2nd_token (parser)->location; 13554 error_at (loc, "expected %<data%>, %<update%>, %<enter%> " 13555 "or %<exit%>"); 13556 if_modifier = ERROR_MARK; 13557 } 13558 if (if_modifier == OMP_TARGET_ENTER_DATA 13559 || if_modifier == OMP_TARGET_EXIT_DATA) 13560 { 13561 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME) 13562 { 13563 p = IDENTIFIER_POINTER 13564 (c_parser_peek_2nd_token (parser)->value); 13565 if (strcmp ("data", p) == 0) 13566 n = 4; 13567 } 13568 if (n == 4) 13569 c_parser_consume_token (parser); 13570 else 13571 { 13572 location_t loc 13573 = c_parser_peek_2nd_token (parser)->location; 13574 error_at (loc, "expected %<data%>"); 13575 if_modifier = ERROR_MARK; 13576 } 13577 } 13578 } 13579 } 13580 if (if_modifier != ERROR_MARK) 13581 { 13582 if (c_parser_peek_2nd_token (parser)->type == CPP_COLON) 13583 { 13584 c_parser_consume_token (parser); 13585 c_parser_consume_token (parser); 13586 } 13587 else 13588 { 13589 if (n > 2) 13590 { 13591 location_t loc = c_parser_peek_2nd_token (parser)->location; 13592 error_at (loc, "expected %<:%>"); 13593 } 13594 if_modifier = ERROR_MARK; 13595 } 13596 } 13597 } 13598 13599 location_t loc = c_parser_peek_token (parser)->location; 13600 c_expr expr = c_parser_expr_no_commas (parser, NULL); 13601 expr = convert_lvalue_to_rvalue (loc, expr, true, true); 13602 tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c; 13603 t = c_fully_fold (t, false, NULL); 13604 parens.skip_until_found_close (parser); 13605 13606 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c)) 13607 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF) 13608 { 13609 if (if_modifier != ERROR_MARK 13610 && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier) 13611 { 13612 const char *p = NULL; 13613 switch (if_modifier) 13614 { 13615 case VOID_CST: p = "cancel"; break; 13616 case OMP_PARALLEL: p = "parallel"; break; 13617 case OMP_SIMD: p = "simd"; break; 13618 case OMP_TASK: p = "task"; break; 13619 case OMP_TASKLOOP: p = "taskloop"; break; 13620 case OMP_TARGET_DATA: p = "target data"; break; 13621 case OMP_TARGET: p = "target"; break; 13622 case OMP_TARGET_UPDATE: p = "target update"; break; 13623 case OMP_TARGET_ENTER_DATA: p = "target enter data"; break; 13624 case OMP_TARGET_EXIT_DATA: p = "target exit data"; break; 13625 default: gcc_unreachable (); 13626 } 13627 error_at (location, "too many %<if%> clauses with %qs modifier", 13628 p); 13629 return list; 13630 } 13631 else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier) 13632 { 13633 if (!is_omp) 13634 error_at (location, "too many %<if%> clauses"); 13635 else 13636 error_at (location, "too many %<if%> clauses without modifier"); 13637 return list; 13638 } 13639 else if (if_modifier == ERROR_MARK 13640 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK) 13641 { 13642 error_at (location, "if any %<if%> clause has modifier, then all " 13643 "%<if%> clauses have to use modifier"); 13644 return list; 13645 } 13646 } 13647 13648 c = build_omp_clause (location, OMP_CLAUSE_IF); 13649 OMP_CLAUSE_IF_MODIFIER (c) = if_modifier; 13650 OMP_CLAUSE_IF_EXPR (c) = t; 13651 OMP_CLAUSE_CHAIN (c) = list; 13652 return c; 13653 } 13654 13655 /* OpenMP 2.5: 13656 lastprivate ( variable-list ) 13657 13658 OpenMP 5.0: 13659 lastprivate ( [ lastprivate-modifier : ] variable-list ) */ 13660 13661 static tree 13662 c_parser_omp_clause_lastprivate (c_parser *parser, tree list) 13663 { 13664 /* The clauses location. */ 13665 location_t loc = c_parser_peek_token (parser)->location; 13666 13667 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 13668 { 13669 bool conditional = false; 13670 if (c_parser_next_token_is (parser, CPP_NAME) 13671 && c_parser_peek_2nd_token (parser)->type == CPP_COLON) 13672 { 13673 const char *p 13674 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 13675 if (strcmp (p, "conditional") == 0) 13676 { 13677 conditional = true; 13678 c_parser_consume_token (parser); 13679 c_parser_consume_token (parser); 13680 } 13681 } 13682 tree nlist = c_parser_omp_variable_list (parser, loc, 13683 OMP_CLAUSE_LASTPRIVATE, list); 13684 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 13685 if (conditional) 13686 for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c)) 13687 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1; 13688 return nlist; 13689 } 13690 return list; 13691 } 13692 13693 /* OpenMP 3.1: 13694 mergeable */ 13695 13696 static tree 13697 c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list) 13698 { 13699 tree c; 13700 13701 /* FIXME: Should we allow duplicates? */ 13702 check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable"); 13703 13704 c = build_omp_clause (c_parser_peek_token (parser)->location, 13705 OMP_CLAUSE_MERGEABLE); 13706 OMP_CLAUSE_CHAIN (c) = list; 13707 13708 return c; 13709 } 13710 13711 /* OpenMP 2.5: 13712 nowait */ 13713 13714 static tree 13715 c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list) 13716 { 13717 tree c; 13718 location_t loc = c_parser_peek_token (parser)->location; 13719 13720 check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait"); 13721 13722 c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT); 13723 OMP_CLAUSE_CHAIN (c) = list; 13724 return c; 13725 } 13726 13727 /* OpenMP 2.5: 13728 num_threads ( expression ) */ 13729 13730 static tree 13731 c_parser_omp_clause_num_threads (c_parser *parser, tree list) 13732 { 13733 location_t num_threads_loc = c_parser_peek_token (parser)->location; 13734 matching_parens parens; 13735 if (parens.require_open (parser)) 13736 { 13737 location_t expr_loc = c_parser_peek_token (parser)->location; 13738 c_expr expr = c_parser_expr_no_commas (parser, NULL); 13739 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 13740 tree c, t = expr.value; 13741 t = c_fully_fold (t, false, NULL); 13742 13743 parens.skip_until_found_close (parser); 13744 13745 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 13746 { 13747 c_parser_error (parser, "expected integer expression"); 13748 return list; 13749 } 13750 13751 /* Attempt to statically determine when the number isn't positive. */ 13752 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t, 13753 build_int_cst (TREE_TYPE (t), 0)); 13754 protected_set_expr_location (c, expr_loc); 13755 if (c == boolean_true_node) 13756 { 13757 warning_at (expr_loc, 0, 13758 "%<num_threads%> value must be positive"); 13759 t = integer_one_node; 13760 } 13761 13762 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads"); 13763 13764 c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS); 13765 OMP_CLAUSE_NUM_THREADS_EXPR (c) = t; 13766 OMP_CLAUSE_CHAIN (c) = list; 13767 list = c; 13768 } 13769 13770 return list; 13771 } 13772 13773 /* OpenMP 4.5: 13774 num_tasks ( expression ) */ 13775 13776 static tree 13777 c_parser_omp_clause_num_tasks (c_parser *parser, tree list) 13778 { 13779 location_t num_tasks_loc = c_parser_peek_token (parser)->location; 13780 matching_parens parens; 13781 if (parens.require_open (parser)) 13782 { 13783 location_t expr_loc = c_parser_peek_token (parser)->location; 13784 c_expr expr = c_parser_expr_no_commas (parser, NULL); 13785 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 13786 tree c, t = expr.value; 13787 t = c_fully_fold (t, false, NULL); 13788 13789 parens.skip_until_found_close (parser); 13790 13791 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 13792 { 13793 c_parser_error (parser, "expected integer expression"); 13794 return list; 13795 } 13796 13797 /* Attempt to statically determine when the number isn't positive. */ 13798 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t, 13799 build_int_cst (TREE_TYPE (t), 0)); 13800 if (CAN_HAVE_LOCATION_P (c)) 13801 SET_EXPR_LOCATION (c, expr_loc); 13802 if (c == boolean_true_node) 13803 { 13804 warning_at (expr_loc, 0, "%<num_tasks%> value must be positive"); 13805 t = integer_one_node; 13806 } 13807 13808 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks"); 13809 13810 c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS); 13811 OMP_CLAUSE_NUM_TASKS_EXPR (c) = t; 13812 OMP_CLAUSE_CHAIN (c) = list; 13813 list = c; 13814 } 13815 13816 return list; 13817 } 13818 13819 /* OpenMP 4.5: 13820 grainsize ( expression ) */ 13821 13822 static tree 13823 c_parser_omp_clause_grainsize (c_parser *parser, tree list) 13824 { 13825 location_t grainsize_loc = c_parser_peek_token (parser)->location; 13826 matching_parens parens; 13827 if (parens.require_open (parser)) 13828 { 13829 location_t expr_loc = c_parser_peek_token (parser)->location; 13830 c_expr expr = c_parser_expr_no_commas (parser, NULL); 13831 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 13832 tree c, t = expr.value; 13833 t = c_fully_fold (t, false, NULL); 13834 13835 parens.skip_until_found_close (parser); 13836 13837 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 13838 { 13839 c_parser_error (parser, "expected integer expression"); 13840 return list; 13841 } 13842 13843 /* Attempt to statically determine when the number isn't positive. */ 13844 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t, 13845 build_int_cst (TREE_TYPE (t), 0)); 13846 if (CAN_HAVE_LOCATION_P (c)) 13847 SET_EXPR_LOCATION (c, expr_loc); 13848 if (c == boolean_true_node) 13849 { 13850 warning_at (expr_loc, 0, "%<grainsize%> value must be positive"); 13851 t = integer_one_node; 13852 } 13853 13854 check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize"); 13855 13856 c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE); 13857 OMP_CLAUSE_GRAINSIZE_EXPR (c) = t; 13858 OMP_CLAUSE_CHAIN (c) = list; 13859 list = c; 13860 } 13861 13862 return list; 13863 } 13864 13865 /* OpenMP 4.5: 13866 priority ( expression ) */ 13867 13868 static tree 13869 c_parser_omp_clause_priority (c_parser *parser, tree list) 13870 { 13871 location_t priority_loc = c_parser_peek_token (parser)->location; 13872 matching_parens parens; 13873 if (parens.require_open (parser)) 13874 { 13875 location_t expr_loc = c_parser_peek_token (parser)->location; 13876 c_expr expr = c_parser_expr_no_commas (parser, NULL); 13877 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 13878 tree c, t = expr.value; 13879 t = c_fully_fold (t, false, NULL); 13880 13881 parens.skip_until_found_close (parser); 13882 13883 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 13884 { 13885 c_parser_error (parser, "expected integer expression"); 13886 return list; 13887 } 13888 13889 /* Attempt to statically determine when the number isn't 13890 non-negative. */ 13891 c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t, 13892 build_int_cst (TREE_TYPE (t), 0)); 13893 if (CAN_HAVE_LOCATION_P (c)) 13894 SET_EXPR_LOCATION (c, expr_loc); 13895 if (c == boolean_true_node) 13896 { 13897 warning_at (expr_loc, 0, "%<priority%> value must be non-negative"); 13898 t = integer_one_node; 13899 } 13900 13901 check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority"); 13902 13903 c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY); 13904 OMP_CLAUSE_PRIORITY_EXPR (c) = t; 13905 OMP_CLAUSE_CHAIN (c) = list; 13906 list = c; 13907 } 13908 13909 return list; 13910 } 13911 13912 /* OpenMP 4.5: 13913 hint ( expression ) */ 13914 13915 static tree 13916 c_parser_omp_clause_hint (c_parser *parser, tree list) 13917 { 13918 location_t hint_loc = c_parser_peek_token (parser)->location; 13919 matching_parens parens; 13920 if (parens.require_open (parser)) 13921 { 13922 location_t expr_loc = c_parser_peek_token (parser)->location; 13923 c_expr expr = c_parser_expr_no_commas (parser, NULL); 13924 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 13925 tree c, t = expr.value; 13926 t = c_fully_fold (t, false, NULL); 13927 13928 parens.skip_until_found_close (parser); 13929 13930 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)) 13931 || TREE_CODE (t) != INTEGER_CST) 13932 { 13933 c_parser_error (parser, "expected constant integer expression"); 13934 return list; 13935 } 13936 13937 check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint"); 13938 13939 c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT); 13940 OMP_CLAUSE_HINT_EXPR (c) = t; 13941 OMP_CLAUSE_CHAIN (c) = list; 13942 list = c; 13943 } 13944 13945 return list; 13946 } 13947 13948 /* OpenMP 4.5: 13949 defaultmap ( tofrom : scalar ) 13950 13951 OpenMP 5.0: 13952 defaultmap ( implicit-behavior [ : variable-category ] ) */ 13953 13954 static tree 13955 c_parser_omp_clause_defaultmap (c_parser *parser, tree list) 13956 { 13957 location_t loc = c_parser_peek_token (parser)->location; 13958 tree c; 13959 const char *p; 13960 enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT; 13961 enum omp_clause_defaultmap_kind category 13962 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED; 13963 13964 matching_parens parens; 13965 if (!parens.require_open (parser)) 13966 return list; 13967 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)) 13968 p = "default"; 13969 else if (!c_parser_next_token_is (parser, CPP_NAME)) 13970 { 13971 invalid_behavior: 13972 c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, " 13973 "%<tofrom%>, %<firstprivate%>, %<none%> " 13974 "or %<default%>"); 13975 goto out_err; 13976 } 13977 else 13978 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 13979 13980 switch (p[0]) 13981 { 13982 case 'a': 13983 if (strcmp ("alloc", p) == 0) 13984 behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC; 13985 else 13986 goto invalid_behavior; 13987 break; 13988 13989 case 'd': 13990 if (strcmp ("default", p) == 0) 13991 behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT; 13992 else 13993 goto invalid_behavior; 13994 break; 13995 13996 case 'f': 13997 if (strcmp ("firstprivate", p) == 0) 13998 behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE; 13999 else if (strcmp ("from", p) == 0) 14000 behavior = OMP_CLAUSE_DEFAULTMAP_FROM; 14001 else 14002 goto invalid_behavior; 14003 break; 14004 14005 case 'n': 14006 if (strcmp ("none", p) == 0) 14007 behavior = OMP_CLAUSE_DEFAULTMAP_NONE; 14008 else 14009 goto invalid_behavior; 14010 break; 14011 14012 case 't': 14013 if (strcmp ("tofrom", p) == 0) 14014 behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM; 14015 else if (strcmp ("to", p) == 0) 14016 behavior = OMP_CLAUSE_DEFAULTMAP_TO; 14017 else 14018 goto invalid_behavior; 14019 break; 14020 14021 default: 14022 goto invalid_behavior; 14023 } 14024 c_parser_consume_token (parser); 14025 14026 if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 14027 { 14028 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 14029 goto out_err; 14030 if (!c_parser_next_token_is (parser, CPP_NAME)) 14031 { 14032 invalid_category: 14033 c_parser_error (parser, "expected %<scalar%>, %<aggregate%> or " 14034 "%<pointer%>"); 14035 goto out_err; 14036 } 14037 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 14038 switch (p[0]) 14039 { 14040 case 'a': 14041 if (strcmp ("aggregate", p) == 0) 14042 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE; 14043 else 14044 goto invalid_category; 14045 break; 14046 14047 case 'p': 14048 if (strcmp ("pointer", p) == 0) 14049 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER; 14050 else 14051 goto invalid_category; 14052 break; 14053 14054 case 's': 14055 if (strcmp ("scalar", p) == 0) 14056 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR; 14057 else 14058 goto invalid_category; 14059 break; 14060 14061 default: 14062 goto invalid_category; 14063 } 14064 14065 c_parser_consume_token (parser); 14066 } 14067 parens.skip_until_found_close (parser); 14068 14069 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c)) 14070 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP 14071 && (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED 14072 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category 14073 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) 14074 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED))) 14075 { 14076 enum omp_clause_defaultmap_kind cat = category; 14077 location_t loc = OMP_CLAUSE_LOCATION (c); 14078 if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED) 14079 cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c); 14080 p = NULL; 14081 switch (cat) 14082 { 14083 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED: 14084 p = NULL; 14085 break; 14086 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE: 14087 p = "aggregate"; 14088 break; 14089 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER: 14090 p = "pointer"; 14091 break; 14092 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR: 14093 p = "scalar"; 14094 break; 14095 default: 14096 gcc_unreachable (); 14097 } 14098 if (p) 14099 error_at (loc, "too many %<defaultmap%> clauses with %qs category", 14100 p); 14101 else 14102 error_at (loc, "too many %<defaultmap%> clauses with unspecified " 14103 "category"); 14104 break; 14105 } 14106 14107 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP); 14108 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category); 14109 OMP_CLAUSE_CHAIN (c) = list; 14110 return c; 14111 14112 out_err: 14113 parens.skip_until_found_close (parser); 14114 return list; 14115 } 14116 14117 /* OpenACC 2.0: 14118 use_device ( variable-list ) 14119 14120 OpenMP 4.5: 14121 use_device_ptr ( variable-list ) */ 14122 14123 static tree 14124 c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list) 14125 { 14126 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR, 14127 list); 14128 } 14129 14130 /* OpenMP 5.0: 14131 use_device_addr ( variable-list ) */ 14132 14133 static tree 14134 c_parser_omp_clause_use_device_addr (c_parser *parser, tree list) 14135 { 14136 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR, 14137 list); 14138 } 14139 14140 /* OpenMP 4.5: 14141 is_device_ptr ( variable-list ) */ 14142 14143 static tree 14144 c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list) 14145 { 14146 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list); 14147 } 14148 14149 /* OpenACC: 14150 num_gangs ( expression ) 14151 num_workers ( expression ) 14152 vector_length ( expression ) */ 14153 14154 static tree 14155 c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code, 14156 tree list) 14157 { 14158 location_t loc = c_parser_peek_token (parser)->location; 14159 14160 matching_parens parens; 14161 if (!parens.require_open (parser)) 14162 return list; 14163 14164 location_t expr_loc = c_parser_peek_token (parser)->location; 14165 c_expr expr = c_parser_expression (parser); 14166 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 14167 tree c, t = expr.value; 14168 t = c_fully_fold (t, false, NULL); 14169 14170 parens.skip_until_found_close (parser); 14171 14172 if (t == error_mark_node) 14173 return list; 14174 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 14175 { 14176 error_at (expr_loc, "%qs expression must be integral", 14177 omp_clause_code_name[code]); 14178 return list; 14179 } 14180 14181 /* Attempt to statically determine when the number isn't positive. */ 14182 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t, 14183 build_int_cst (TREE_TYPE (t), 0)); 14184 protected_set_expr_location (c, expr_loc); 14185 if (c == boolean_true_node) 14186 { 14187 warning_at (expr_loc, 0, 14188 "%qs value must be positive", 14189 omp_clause_code_name[code]); 14190 t = integer_one_node; 14191 } 14192 14193 check_no_duplicate_clause (list, code, omp_clause_code_name[code]); 14194 14195 c = build_omp_clause (loc, code); 14196 OMP_CLAUSE_OPERAND (c, 0) = t; 14197 OMP_CLAUSE_CHAIN (c) = list; 14198 return c; 14199 } 14200 14201 /* OpenACC: 14202 14203 gang [( gang-arg-list )] 14204 worker [( [num:] int-expr )] 14205 vector [( [length:] int-expr )] 14206 14207 where gang-arg is one of: 14208 14209 [num:] int-expr 14210 static: size-expr 14211 14212 and size-expr may be: 14213 14214 * 14215 int-expr 14216 */ 14217 14218 static tree 14219 c_parser_oacc_shape_clause (c_parser *parser, location_t loc, 14220 omp_clause_code kind, 14221 const char *str, tree list) 14222 { 14223 const char *id = "num"; 14224 tree ops[2] = { NULL_TREE, NULL_TREE }, c; 14225 14226 if (kind == OMP_CLAUSE_VECTOR) 14227 id = "length"; 14228 14229 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 14230 { 14231 c_parser_consume_token (parser); 14232 14233 do 14234 { 14235 c_token *next = c_parser_peek_token (parser); 14236 int idx = 0; 14237 14238 /* Gang static argument. */ 14239 if (kind == OMP_CLAUSE_GANG 14240 && c_parser_next_token_is_keyword (parser, RID_STATIC)) 14241 { 14242 c_parser_consume_token (parser); 14243 14244 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 14245 goto cleanup_error; 14246 14247 idx = 1; 14248 if (ops[idx] != NULL_TREE) 14249 { 14250 c_parser_error (parser, "too many %<static%> arguments"); 14251 goto cleanup_error; 14252 } 14253 14254 /* Check for the '*' argument. */ 14255 if (c_parser_next_token_is (parser, CPP_MULT) 14256 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA 14257 || c_parser_peek_2nd_token (parser)->type 14258 == CPP_CLOSE_PAREN)) 14259 { 14260 c_parser_consume_token (parser); 14261 ops[idx] = integer_minus_one_node; 14262 14263 if (c_parser_next_token_is (parser, CPP_COMMA)) 14264 { 14265 c_parser_consume_token (parser); 14266 continue; 14267 } 14268 else 14269 break; 14270 } 14271 } 14272 /* Worker num: argument and vector length: arguments. */ 14273 else if (c_parser_next_token_is (parser, CPP_NAME) 14274 && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0 14275 && c_parser_peek_2nd_token (parser)->type == CPP_COLON) 14276 { 14277 c_parser_consume_token (parser); /* id */ 14278 c_parser_consume_token (parser); /* ':' */ 14279 } 14280 14281 /* Now collect the actual argument. */ 14282 if (ops[idx] != NULL_TREE) 14283 { 14284 c_parser_error (parser, "unexpected argument"); 14285 goto cleanup_error; 14286 } 14287 14288 location_t expr_loc = c_parser_peek_token (parser)->location; 14289 c_expr cexpr = c_parser_expr_no_commas (parser, NULL); 14290 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true); 14291 tree expr = cexpr.value; 14292 if (expr == error_mark_node) 14293 goto cleanup_error; 14294 14295 expr = c_fully_fold (expr, false, NULL); 14296 14297 /* Attempt to statically determine when the number isn't a 14298 positive integer. */ 14299 14300 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))) 14301 { 14302 c_parser_error (parser, "expected integer expression"); 14303 return list; 14304 } 14305 14306 tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr, 14307 build_int_cst (TREE_TYPE (expr), 0)); 14308 if (c == boolean_true_node) 14309 { 14310 warning_at (loc, 0, 14311 "%qs value must be positive", str); 14312 expr = integer_one_node; 14313 } 14314 14315 ops[idx] = expr; 14316 14317 if (kind == OMP_CLAUSE_GANG 14318 && c_parser_next_token_is (parser, CPP_COMMA)) 14319 { 14320 c_parser_consume_token (parser); 14321 continue; 14322 } 14323 break; 14324 } 14325 while (1); 14326 14327 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) 14328 goto cleanup_error; 14329 } 14330 14331 check_no_duplicate_clause (list, kind, str); 14332 14333 c = build_omp_clause (loc, kind); 14334 14335 if (ops[1]) 14336 OMP_CLAUSE_OPERAND (c, 1) = ops[1]; 14337 14338 OMP_CLAUSE_OPERAND (c, 0) = ops[0]; 14339 OMP_CLAUSE_CHAIN (c) = list; 14340 14341 return c; 14342 14343 cleanup_error: 14344 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0); 14345 return list; 14346 } 14347 14348 /* OpenACC 2.5: 14349 auto 14350 finalize 14351 independent 14352 nohost 14353 seq */ 14354 14355 static tree 14356 c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code, 14357 tree list) 14358 { 14359 check_no_duplicate_clause (list, code, omp_clause_code_name[code]); 14360 14361 tree c = build_omp_clause (loc, code); 14362 OMP_CLAUSE_CHAIN (c) = list; 14363 14364 return c; 14365 } 14366 14367 /* OpenACC: 14368 async [( int-expr )] */ 14369 14370 static tree 14371 c_parser_oacc_clause_async (c_parser *parser, tree list) 14372 { 14373 tree c, t; 14374 location_t loc = c_parser_peek_token (parser)->location; 14375 14376 t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL); 14377 14378 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN) 14379 { 14380 c_parser_consume_token (parser); 14381 14382 t = c_parser_expr_no_commas (parser, NULL).value; 14383 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 14384 c_parser_error (parser, "expected integer expression"); 14385 else if (t == error_mark_node 14386 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) 14387 return list; 14388 } 14389 else 14390 t = c_fully_fold (t, false, NULL); 14391 14392 check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async"); 14393 14394 c = build_omp_clause (loc, OMP_CLAUSE_ASYNC); 14395 OMP_CLAUSE_ASYNC_EXPR (c) = t; 14396 OMP_CLAUSE_CHAIN (c) = list; 14397 list = c; 14398 14399 return list; 14400 } 14401 14402 /* OpenACC 2.0: 14403 tile ( size-expr-list ) */ 14404 14405 static tree 14406 c_parser_oacc_clause_tile (c_parser *parser, tree list) 14407 { 14408 tree c, expr = error_mark_node; 14409 location_t loc; 14410 tree tile = NULL_TREE; 14411 14412 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile"); 14413 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse"); 14414 14415 loc = c_parser_peek_token (parser)->location; 14416 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 14417 return list; 14418 14419 do 14420 { 14421 if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>")) 14422 return list; 14423 14424 if (c_parser_next_token_is (parser, CPP_MULT) 14425 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA 14426 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN)) 14427 { 14428 c_parser_consume_token (parser); 14429 expr = integer_zero_node; 14430 } 14431 else 14432 { 14433 location_t expr_loc = c_parser_peek_token (parser)->location; 14434 c_expr cexpr = c_parser_expr_no_commas (parser, NULL); 14435 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true); 14436 expr = cexpr.value; 14437 14438 if (expr == error_mark_node) 14439 { 14440 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 14441 "expected %<)%>"); 14442 return list; 14443 } 14444 14445 expr = c_fully_fold (expr, false, NULL); 14446 14447 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)) 14448 || !tree_fits_shwi_p (expr) 14449 || tree_to_shwi (expr) <= 0) 14450 { 14451 error_at (expr_loc, "%<tile%> argument needs positive" 14452 " integral constant"); 14453 expr = integer_zero_node; 14454 } 14455 } 14456 14457 tile = tree_cons (NULL_TREE, expr, tile); 14458 } 14459 while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN)); 14460 14461 /* Consume the trailing ')'. */ 14462 c_parser_consume_token (parser); 14463 14464 c = build_omp_clause (loc, OMP_CLAUSE_TILE); 14465 tile = nreverse (tile); 14466 OMP_CLAUSE_TILE_LIST (c) = tile; 14467 OMP_CLAUSE_CHAIN (c) = list; 14468 return c; 14469 } 14470 14471 /* OpenACC: 14472 wait [( int-expr-list )] */ 14473 14474 static tree 14475 c_parser_oacc_clause_wait (c_parser *parser, tree list) 14476 { 14477 location_t clause_loc = c_parser_peek_token (parser)->location; 14478 14479 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN) 14480 list = c_parser_oacc_wait_list (parser, clause_loc, list); 14481 else 14482 { 14483 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT); 14484 14485 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL); 14486 OMP_CLAUSE_CHAIN (c) = list; 14487 list = c; 14488 } 14489 14490 return list; 14491 } 14492 14493 14494 /* OpenMP 5.0: 14495 order ( concurrent ) */ 14496 14497 static tree 14498 c_parser_omp_clause_order (c_parser *parser, tree list) 14499 { 14500 location_t loc = c_parser_peek_token (parser)->location; 14501 tree c; 14502 const char *p; 14503 14504 matching_parens parens; 14505 if (!parens.require_open (parser)) 14506 return list; 14507 if (!c_parser_next_token_is (parser, CPP_NAME)) 14508 { 14509 c_parser_error (parser, "expected %<concurrent%>"); 14510 goto out_err; 14511 } 14512 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 14513 if (strcmp (p, "concurrent") != 0) 14514 { 14515 c_parser_error (parser, "expected %<concurrent%>"); 14516 goto out_err; 14517 } 14518 c_parser_consume_token (parser); 14519 parens.skip_until_found_close (parser); 14520 /* check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order"); */ 14521 c = build_omp_clause (loc, OMP_CLAUSE_ORDER); 14522 OMP_CLAUSE_CHAIN (c) = list; 14523 return c; 14524 14525 out_err: 14526 parens.skip_until_found_close (parser); 14527 return list; 14528 } 14529 14530 14531 /* OpenMP 5.0: 14532 bind ( teams | parallel | thread ) */ 14533 14534 static tree 14535 c_parser_omp_clause_bind (c_parser *parser, tree list) 14536 { 14537 location_t loc = c_parser_peek_token (parser)->location; 14538 tree c; 14539 const char *p; 14540 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD; 14541 14542 matching_parens parens; 14543 if (!parens.require_open (parser)) 14544 return list; 14545 if (!c_parser_next_token_is (parser, CPP_NAME)) 14546 { 14547 invalid: 14548 c_parser_error (parser, 14549 "expected %<teams%>, %<parallel%> or %<thread%>"); 14550 parens.skip_until_found_close (parser); 14551 return list; 14552 } 14553 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 14554 if (strcmp (p, "teams") == 0) 14555 kind = OMP_CLAUSE_BIND_TEAMS; 14556 else if (strcmp (p, "parallel") == 0) 14557 kind = OMP_CLAUSE_BIND_PARALLEL; 14558 else if (strcmp (p, "thread") != 0) 14559 goto invalid; 14560 c_parser_consume_token (parser); 14561 parens.skip_until_found_close (parser); 14562 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */ 14563 c = build_omp_clause (loc, OMP_CLAUSE_BIND); 14564 OMP_CLAUSE_BIND_KIND (c) = kind; 14565 OMP_CLAUSE_CHAIN (c) = list; 14566 return c; 14567 } 14568 14569 14570 /* OpenMP 2.5: 14571 ordered 14572 14573 OpenMP 4.5: 14574 ordered ( constant-expression ) */ 14575 14576 static tree 14577 c_parser_omp_clause_ordered (c_parser *parser, tree list) 14578 { 14579 check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered"); 14580 14581 tree c, num = NULL_TREE; 14582 HOST_WIDE_INT n; 14583 location_t loc = c_parser_peek_token (parser)->location; 14584 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 14585 { 14586 matching_parens parens; 14587 parens.consume_open (parser); 14588 num = c_parser_expr_no_commas (parser, NULL).value; 14589 parens.skip_until_found_close (parser); 14590 } 14591 if (num == error_mark_node) 14592 return list; 14593 if (num) 14594 { 14595 mark_exp_read (num); 14596 num = c_fully_fold (num, false, NULL); 14597 if (!INTEGRAL_TYPE_P (TREE_TYPE (num)) 14598 || !tree_fits_shwi_p (num) 14599 || (n = tree_to_shwi (num)) <= 0 14600 || (int) n != n) 14601 { 14602 error_at (loc, "ordered argument needs positive " 14603 "constant integer expression"); 14604 return list; 14605 } 14606 } 14607 c = build_omp_clause (loc, OMP_CLAUSE_ORDERED); 14608 OMP_CLAUSE_ORDERED_EXPR (c) = num; 14609 OMP_CLAUSE_CHAIN (c) = list; 14610 return c; 14611 } 14612 14613 /* OpenMP 2.5: 14614 private ( variable-list ) */ 14615 14616 static tree 14617 c_parser_omp_clause_private (c_parser *parser, tree list) 14618 { 14619 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list); 14620 } 14621 14622 /* OpenMP 2.5: 14623 reduction ( reduction-operator : variable-list ) 14624 14625 reduction-operator: 14626 One of: + * - & ^ | && || 14627 14628 OpenMP 3.1: 14629 14630 reduction-operator: 14631 One of: + * - & ^ | && || max min 14632 14633 OpenMP 4.0: 14634 14635 reduction-operator: 14636 One of: + * - & ^ | && || 14637 identifier 14638 14639 OpenMP 5.0: 14640 reduction ( reduction-modifier, reduction-operator : variable-list ) 14641 in_reduction ( reduction-operator : variable-list ) 14642 task_reduction ( reduction-operator : variable-list ) */ 14643 14644 static tree 14645 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind, 14646 bool is_omp, tree list) 14647 { 14648 location_t clause_loc = c_parser_peek_token (parser)->location; 14649 matching_parens parens; 14650 if (parens.require_open (parser)) 14651 { 14652 bool task = false; 14653 bool inscan = false; 14654 enum tree_code code = ERROR_MARK; 14655 tree reduc_id = NULL_TREE; 14656 14657 if (kind == OMP_CLAUSE_REDUCTION && is_omp) 14658 { 14659 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT) 14660 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA) 14661 { 14662 c_parser_consume_token (parser); 14663 c_parser_consume_token (parser); 14664 } 14665 else if (c_parser_next_token_is (parser, CPP_NAME) 14666 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA) 14667 { 14668 const char *p 14669 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 14670 if (strcmp (p, "task") == 0) 14671 task = true; 14672 else if (strcmp (p, "inscan") == 0) 14673 inscan = true; 14674 if (task || inscan) 14675 { 14676 c_parser_consume_token (parser); 14677 c_parser_consume_token (parser); 14678 } 14679 } 14680 } 14681 14682 switch (c_parser_peek_token (parser)->type) 14683 { 14684 case CPP_PLUS: 14685 code = PLUS_EXPR; 14686 break; 14687 case CPP_MULT: 14688 code = MULT_EXPR; 14689 break; 14690 case CPP_MINUS: 14691 code = MINUS_EXPR; 14692 break; 14693 case CPP_AND: 14694 code = BIT_AND_EXPR; 14695 break; 14696 case CPP_XOR: 14697 code = BIT_XOR_EXPR; 14698 break; 14699 case CPP_OR: 14700 code = BIT_IOR_EXPR; 14701 break; 14702 case CPP_AND_AND: 14703 code = TRUTH_ANDIF_EXPR; 14704 break; 14705 case CPP_OR_OR: 14706 code = TRUTH_ORIF_EXPR; 14707 break; 14708 case CPP_NAME: 14709 { 14710 const char *p 14711 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 14712 if (strcmp (p, "min") == 0) 14713 { 14714 code = MIN_EXPR; 14715 break; 14716 } 14717 if (strcmp (p, "max") == 0) 14718 { 14719 code = MAX_EXPR; 14720 break; 14721 } 14722 reduc_id = c_parser_peek_token (parser)->value; 14723 break; 14724 } 14725 default: 14726 c_parser_error (parser, 14727 "expected %<+%>, %<*%>, %<-%>, %<&%>, " 14728 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier"); 14729 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0); 14730 return list; 14731 } 14732 c_parser_consume_token (parser); 14733 reduc_id = c_omp_reduction_id (code, reduc_id); 14734 if (c_parser_require (parser, CPP_COLON, "expected %<:%>")) 14735 { 14736 tree nl, c; 14737 14738 nl = c_parser_omp_variable_list (parser, clause_loc, kind, list); 14739 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) 14740 { 14741 tree d = OMP_CLAUSE_DECL (c), type; 14742 if (TREE_CODE (d) != TREE_LIST) 14743 type = TREE_TYPE (d); 14744 else 14745 { 14746 int cnt = 0; 14747 tree t; 14748 for (t = d; TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t)) 14749 cnt++; 14750 type = TREE_TYPE (t); 14751 while (cnt > 0) 14752 { 14753 if (TREE_CODE (type) != POINTER_TYPE 14754 && TREE_CODE (type) != ARRAY_TYPE) 14755 break; 14756 type = TREE_TYPE (type); 14757 cnt--; 14758 } 14759 } 14760 while (TREE_CODE (type) == ARRAY_TYPE) 14761 type = TREE_TYPE (type); 14762 OMP_CLAUSE_REDUCTION_CODE (c) = code; 14763 if (task) 14764 OMP_CLAUSE_REDUCTION_TASK (c) = 1; 14765 else if (inscan) 14766 OMP_CLAUSE_REDUCTION_INSCAN (c) = 1; 14767 if (code == ERROR_MARK 14768 || !(INTEGRAL_TYPE_P (type) 14769 || TREE_CODE (type) == REAL_TYPE 14770 || TREE_CODE (type) == COMPLEX_TYPE)) 14771 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) 14772 = c_omp_reduction_lookup (reduc_id, 14773 TYPE_MAIN_VARIANT (type)); 14774 } 14775 14776 list = nl; 14777 } 14778 parens.skip_until_found_close (parser); 14779 } 14780 return list; 14781 } 14782 14783 /* OpenMP 2.5: 14784 schedule ( schedule-kind ) 14785 schedule ( schedule-kind , expression ) 14786 14787 schedule-kind: 14788 static | dynamic | guided | runtime | auto 14789 14790 OpenMP 4.5: 14791 schedule ( schedule-modifier : schedule-kind ) 14792 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression ) 14793 14794 schedule-modifier: 14795 simd 14796 monotonic 14797 nonmonotonic */ 14798 14799 static tree 14800 c_parser_omp_clause_schedule (c_parser *parser, tree list) 14801 { 14802 tree c, t; 14803 location_t loc = c_parser_peek_token (parser)->location; 14804 int modifiers = 0, nmodifiers = 0; 14805 14806 matching_parens parens; 14807 if (!parens.require_open (parser)) 14808 return list; 14809 14810 c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE); 14811 14812 while (c_parser_next_token_is (parser, CPP_NAME)) 14813 { 14814 tree kind = c_parser_peek_token (parser)->value; 14815 const char *p = IDENTIFIER_POINTER (kind); 14816 if (strcmp ("simd", p) == 0) 14817 OMP_CLAUSE_SCHEDULE_SIMD (c) = 1; 14818 else if (strcmp ("monotonic", p) == 0) 14819 modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC; 14820 else if (strcmp ("nonmonotonic", p) == 0) 14821 modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC; 14822 else 14823 break; 14824 c_parser_consume_token (parser); 14825 if (nmodifiers++ == 0 14826 && c_parser_next_token_is (parser, CPP_COMMA)) 14827 c_parser_consume_token (parser); 14828 else 14829 { 14830 c_parser_require (parser, CPP_COLON, "expected %<:%>"); 14831 break; 14832 } 14833 } 14834 14835 if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC 14836 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC)) 14837 == (OMP_CLAUSE_SCHEDULE_MONOTONIC 14838 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC)) 14839 { 14840 error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers " 14841 "specified"); 14842 modifiers = 0; 14843 } 14844 14845 if (c_parser_next_token_is (parser, CPP_NAME)) 14846 { 14847 tree kind = c_parser_peek_token (parser)->value; 14848 const char *p = IDENTIFIER_POINTER (kind); 14849 14850 switch (p[0]) 14851 { 14852 case 'd': 14853 if (strcmp ("dynamic", p) != 0) 14854 goto invalid_kind; 14855 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC; 14856 break; 14857 14858 case 'g': 14859 if (strcmp ("guided", p) != 0) 14860 goto invalid_kind; 14861 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED; 14862 break; 14863 14864 case 'r': 14865 if (strcmp ("runtime", p) != 0) 14866 goto invalid_kind; 14867 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME; 14868 break; 14869 14870 default: 14871 goto invalid_kind; 14872 } 14873 } 14874 else if (c_parser_next_token_is_keyword (parser, RID_STATIC)) 14875 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC; 14876 else if (c_parser_next_token_is_keyword (parser, RID_AUTO)) 14877 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO; 14878 else 14879 goto invalid_kind; 14880 14881 c_parser_consume_token (parser); 14882 if (c_parser_next_token_is (parser, CPP_COMMA)) 14883 { 14884 location_t here; 14885 c_parser_consume_token (parser); 14886 14887 here = c_parser_peek_token (parser)->location; 14888 c_expr expr = c_parser_expr_no_commas (parser, NULL); 14889 expr = convert_lvalue_to_rvalue (here, expr, false, true); 14890 t = expr.value; 14891 t = c_fully_fold (t, false, NULL); 14892 14893 if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME) 14894 error_at (here, "schedule %<runtime%> does not take " 14895 "a %<chunk_size%> parameter"); 14896 else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO) 14897 error_at (here, 14898 "schedule %<auto%> does not take " 14899 "a %<chunk_size%> parameter"); 14900 else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE) 14901 { 14902 /* Attempt to statically determine when the number isn't 14903 positive. */ 14904 tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t, 14905 build_int_cst (TREE_TYPE (t), 0)); 14906 protected_set_expr_location (s, loc); 14907 if (s == boolean_true_node) 14908 { 14909 warning_at (loc, 0, 14910 "chunk size value must be positive"); 14911 t = integer_one_node; 14912 } 14913 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t; 14914 } 14915 else 14916 c_parser_error (parser, "expected integer expression"); 14917 14918 parens.skip_until_found_close (parser); 14919 } 14920 else 14921 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 14922 "expected %<,%> or %<)%>"); 14923 14924 OMP_CLAUSE_SCHEDULE_KIND (c) 14925 = (enum omp_clause_schedule_kind) 14926 (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers); 14927 14928 check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule"); 14929 OMP_CLAUSE_CHAIN (c) = list; 14930 return c; 14931 14932 invalid_kind: 14933 c_parser_error (parser, "invalid schedule kind"); 14934 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0); 14935 return list; 14936 } 14937 14938 /* OpenMP 2.5: 14939 shared ( variable-list ) */ 14940 14941 static tree 14942 c_parser_omp_clause_shared (c_parser *parser, tree list) 14943 { 14944 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list); 14945 } 14946 14947 /* OpenMP 3.0: 14948 untied */ 14949 14950 static tree 14951 c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list) 14952 { 14953 tree c; 14954 14955 /* FIXME: Should we allow duplicates? */ 14956 check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied"); 14957 14958 c = build_omp_clause (c_parser_peek_token (parser)->location, 14959 OMP_CLAUSE_UNTIED); 14960 OMP_CLAUSE_CHAIN (c) = list; 14961 14962 return c; 14963 } 14964 14965 /* OpenMP 4.0: 14966 inbranch 14967 notinbranch */ 14968 14969 static tree 14970 c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED, 14971 enum omp_clause_code code, tree list) 14972 { 14973 check_no_duplicate_clause (list, code, omp_clause_code_name[code]); 14974 14975 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code); 14976 OMP_CLAUSE_CHAIN (c) = list; 14977 14978 return c; 14979 } 14980 14981 /* OpenMP 4.0: 14982 parallel 14983 for 14984 sections 14985 taskgroup */ 14986 14987 static tree 14988 c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED, 14989 enum omp_clause_code code, tree list) 14990 { 14991 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code); 14992 OMP_CLAUSE_CHAIN (c) = list; 14993 14994 return c; 14995 } 14996 14997 /* OpenMP 4.5: 14998 nogroup */ 14999 15000 static tree 15001 c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list) 15002 { 15003 check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup"); 15004 tree c = build_omp_clause (c_parser_peek_token (parser)->location, 15005 OMP_CLAUSE_NOGROUP); 15006 OMP_CLAUSE_CHAIN (c) = list; 15007 return c; 15008 } 15009 15010 /* OpenMP 4.5: 15011 simd 15012 threads */ 15013 15014 static tree 15015 c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED, 15016 enum omp_clause_code code, tree list) 15017 { 15018 check_no_duplicate_clause (list, code, omp_clause_code_name[code]); 15019 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code); 15020 OMP_CLAUSE_CHAIN (c) = list; 15021 return c; 15022 } 15023 15024 /* OpenMP 4.0: 15025 num_teams ( expression ) */ 15026 15027 static tree 15028 c_parser_omp_clause_num_teams (c_parser *parser, tree list) 15029 { 15030 location_t num_teams_loc = c_parser_peek_token (parser)->location; 15031 matching_parens parens; 15032 if (parens.require_open (parser)) 15033 { 15034 location_t expr_loc = c_parser_peek_token (parser)->location; 15035 c_expr expr = c_parser_expr_no_commas (parser, NULL); 15036 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 15037 tree c, t = expr.value; 15038 t = c_fully_fold (t, false, NULL); 15039 15040 parens.skip_until_found_close (parser); 15041 15042 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 15043 { 15044 c_parser_error (parser, "expected integer expression"); 15045 return list; 15046 } 15047 15048 /* Attempt to statically determine when the number isn't positive. */ 15049 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t, 15050 build_int_cst (TREE_TYPE (t), 0)); 15051 protected_set_expr_location (c, expr_loc); 15052 if (c == boolean_true_node) 15053 { 15054 warning_at (expr_loc, 0, "%<num_teams%> value must be positive"); 15055 t = integer_one_node; 15056 } 15057 15058 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams"); 15059 15060 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS); 15061 OMP_CLAUSE_NUM_TEAMS_EXPR (c) = t; 15062 OMP_CLAUSE_CHAIN (c) = list; 15063 list = c; 15064 } 15065 15066 return list; 15067 } 15068 15069 /* OpenMP 4.0: 15070 thread_limit ( expression ) */ 15071 15072 static tree 15073 c_parser_omp_clause_thread_limit (c_parser *parser, tree list) 15074 { 15075 location_t num_thread_limit_loc = c_parser_peek_token (parser)->location; 15076 matching_parens parens; 15077 if (parens.require_open (parser)) 15078 { 15079 location_t expr_loc = c_parser_peek_token (parser)->location; 15080 c_expr expr = c_parser_expr_no_commas (parser, NULL); 15081 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 15082 tree c, t = expr.value; 15083 t = c_fully_fold (t, false, NULL); 15084 15085 parens.skip_until_found_close (parser); 15086 15087 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 15088 { 15089 c_parser_error (parser, "expected integer expression"); 15090 return list; 15091 } 15092 15093 /* Attempt to statically determine when the number isn't positive. */ 15094 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t, 15095 build_int_cst (TREE_TYPE (t), 0)); 15096 protected_set_expr_location (c, expr_loc); 15097 if (c == boolean_true_node) 15098 { 15099 warning_at (expr_loc, 0, "%<thread_limit%> value must be positive"); 15100 t = integer_one_node; 15101 } 15102 15103 check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT, 15104 "thread_limit"); 15105 15106 c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT); 15107 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t; 15108 OMP_CLAUSE_CHAIN (c) = list; 15109 list = c; 15110 } 15111 15112 return list; 15113 } 15114 15115 /* OpenMP 4.0: 15116 aligned ( variable-list ) 15117 aligned ( variable-list : constant-expression ) */ 15118 15119 static tree 15120 c_parser_omp_clause_aligned (c_parser *parser, tree list) 15121 { 15122 location_t clause_loc = c_parser_peek_token (parser)->location; 15123 tree nl, c; 15124 15125 matching_parens parens; 15126 if (!parens.require_open (parser)) 15127 return list; 15128 15129 nl = c_parser_omp_variable_list (parser, clause_loc, 15130 OMP_CLAUSE_ALIGNED, list); 15131 15132 if (c_parser_next_token_is (parser, CPP_COLON)) 15133 { 15134 c_parser_consume_token (parser); 15135 location_t expr_loc = c_parser_peek_token (parser)->location; 15136 c_expr expr = c_parser_expr_no_commas (parser, NULL); 15137 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 15138 tree alignment = expr.value; 15139 alignment = c_fully_fold (alignment, false, NULL); 15140 if (TREE_CODE (alignment) != INTEGER_CST 15141 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment)) 15142 || tree_int_cst_sgn (alignment) != 1) 15143 { 15144 error_at (clause_loc, "%<aligned%> clause alignment expression must " 15145 "be positive constant integer expression"); 15146 alignment = NULL_TREE; 15147 } 15148 15149 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) 15150 OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment; 15151 } 15152 15153 parens.skip_until_found_close (parser); 15154 return nl; 15155 } 15156 15157 /* OpenMP 4.0: 15158 linear ( variable-list ) 15159 linear ( variable-list : expression ) 15160 15161 OpenMP 4.5: 15162 linear ( modifier ( variable-list ) ) 15163 linear ( modifier ( variable-list ) : expression ) */ 15164 15165 static tree 15166 c_parser_omp_clause_linear (c_parser *parser, tree list) 15167 { 15168 location_t clause_loc = c_parser_peek_token (parser)->location; 15169 tree nl, c, step; 15170 enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT; 15171 15172 matching_parens parens; 15173 if (!parens.require_open (parser)) 15174 return list; 15175 15176 if (c_parser_next_token_is (parser, CPP_NAME)) 15177 { 15178 c_token *tok = c_parser_peek_token (parser); 15179 const char *p = IDENTIFIER_POINTER (tok->value); 15180 if (strcmp ("val", p) == 0) 15181 kind = OMP_CLAUSE_LINEAR_VAL; 15182 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN) 15183 kind = OMP_CLAUSE_LINEAR_DEFAULT; 15184 if (kind != OMP_CLAUSE_LINEAR_DEFAULT) 15185 { 15186 c_parser_consume_token (parser); 15187 c_parser_consume_token (parser); 15188 } 15189 } 15190 15191 nl = c_parser_omp_variable_list (parser, clause_loc, 15192 OMP_CLAUSE_LINEAR, list); 15193 15194 if (kind != OMP_CLAUSE_LINEAR_DEFAULT) 15195 parens.skip_until_found_close (parser); 15196 15197 if (c_parser_next_token_is (parser, CPP_COLON)) 15198 { 15199 c_parser_consume_token (parser); 15200 location_t expr_loc = c_parser_peek_token (parser)->location; 15201 c_expr expr = c_parser_expr_no_commas (parser, NULL); 15202 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 15203 step = expr.value; 15204 step = c_fully_fold (step, false, NULL); 15205 if (!INTEGRAL_TYPE_P (TREE_TYPE (step))) 15206 { 15207 error_at (clause_loc, "%<linear%> clause step expression must " 15208 "be integral"); 15209 step = integer_one_node; 15210 } 15211 15212 } 15213 else 15214 step = integer_one_node; 15215 15216 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) 15217 { 15218 OMP_CLAUSE_LINEAR_STEP (c) = step; 15219 OMP_CLAUSE_LINEAR_KIND (c) = kind; 15220 } 15221 15222 parens.skip_until_found_close (parser); 15223 return nl; 15224 } 15225 15226 /* OpenMP 5.0: 15227 nontemporal ( variable-list ) */ 15228 15229 static tree 15230 c_parser_omp_clause_nontemporal (c_parser *parser, tree list) 15231 { 15232 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list); 15233 } 15234 15235 /* OpenMP 4.0: 15236 safelen ( constant-expression ) */ 15237 15238 static tree 15239 c_parser_omp_clause_safelen (c_parser *parser, tree list) 15240 { 15241 location_t clause_loc = c_parser_peek_token (parser)->location; 15242 tree c, t; 15243 15244 matching_parens parens; 15245 if (!parens.require_open (parser)) 15246 return list; 15247 15248 location_t expr_loc = c_parser_peek_token (parser)->location; 15249 c_expr expr = c_parser_expr_no_commas (parser, NULL); 15250 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 15251 t = expr.value; 15252 t = c_fully_fold (t, false, NULL); 15253 if (TREE_CODE (t) != INTEGER_CST 15254 || !INTEGRAL_TYPE_P (TREE_TYPE (t)) 15255 || tree_int_cst_sgn (t) != 1) 15256 { 15257 error_at (clause_loc, "%<safelen%> clause expression must " 15258 "be positive constant integer expression"); 15259 t = NULL_TREE; 15260 } 15261 15262 parens.skip_until_found_close (parser); 15263 if (t == NULL_TREE || t == error_mark_node) 15264 return list; 15265 15266 check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen"); 15267 15268 c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN); 15269 OMP_CLAUSE_SAFELEN_EXPR (c) = t; 15270 OMP_CLAUSE_CHAIN (c) = list; 15271 return c; 15272 } 15273 15274 /* OpenMP 4.0: 15275 simdlen ( constant-expression ) */ 15276 15277 static tree 15278 c_parser_omp_clause_simdlen (c_parser *parser, tree list) 15279 { 15280 location_t clause_loc = c_parser_peek_token (parser)->location; 15281 tree c, t; 15282 15283 matching_parens parens; 15284 if (!parens.require_open (parser)) 15285 return list; 15286 15287 location_t expr_loc = c_parser_peek_token (parser)->location; 15288 c_expr expr = c_parser_expr_no_commas (parser, NULL); 15289 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 15290 t = expr.value; 15291 t = c_fully_fold (t, false, NULL); 15292 if (TREE_CODE (t) != INTEGER_CST 15293 || !INTEGRAL_TYPE_P (TREE_TYPE (t)) 15294 || tree_int_cst_sgn (t) != 1) 15295 { 15296 error_at (clause_loc, "%<simdlen%> clause expression must " 15297 "be positive constant integer expression"); 15298 t = NULL_TREE; 15299 } 15300 15301 parens.skip_until_found_close (parser); 15302 if (t == NULL_TREE || t == error_mark_node) 15303 return list; 15304 15305 check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen"); 15306 15307 c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN); 15308 OMP_CLAUSE_SIMDLEN_EXPR (c) = t; 15309 OMP_CLAUSE_CHAIN (c) = list; 15310 return c; 15311 } 15312 15313 /* OpenMP 4.5: 15314 vec: 15315 identifier [+/- integer] 15316 vec , identifier [+/- integer] 15317 */ 15318 15319 static tree 15320 c_parser_omp_clause_depend_sink (c_parser *parser, location_t clause_loc, 15321 tree list) 15322 { 15323 tree vec = NULL; 15324 if (c_parser_next_token_is_not (parser, CPP_NAME) 15325 || c_parser_peek_token (parser)->id_kind != C_ID_ID) 15326 { 15327 c_parser_error (parser, "expected identifier"); 15328 return list; 15329 } 15330 15331 while (c_parser_next_token_is (parser, CPP_NAME) 15332 && c_parser_peek_token (parser)->id_kind == C_ID_ID) 15333 { 15334 tree t = lookup_name (c_parser_peek_token (parser)->value); 15335 tree addend = NULL; 15336 15337 if (t == NULL_TREE) 15338 { 15339 undeclared_variable (c_parser_peek_token (parser)->location, 15340 c_parser_peek_token (parser)->value); 15341 t = error_mark_node; 15342 } 15343 15344 c_parser_consume_token (parser); 15345 15346 bool neg = false; 15347 if (c_parser_next_token_is (parser, CPP_MINUS)) 15348 neg = true; 15349 else if (!c_parser_next_token_is (parser, CPP_PLUS)) 15350 { 15351 addend = integer_zero_node; 15352 neg = false; 15353 goto add_to_vector; 15354 } 15355 c_parser_consume_token (parser); 15356 15357 if (c_parser_next_token_is_not (parser, CPP_NUMBER)) 15358 { 15359 c_parser_error (parser, "expected integer"); 15360 return list; 15361 } 15362 15363 addend = c_parser_peek_token (parser)->value; 15364 if (TREE_CODE (addend) != INTEGER_CST) 15365 { 15366 c_parser_error (parser, "expected integer"); 15367 return list; 15368 } 15369 c_parser_consume_token (parser); 15370 15371 add_to_vector: 15372 if (t != error_mark_node) 15373 { 15374 vec = tree_cons (addend, t, vec); 15375 if (neg) 15376 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1; 15377 } 15378 15379 if (c_parser_next_token_is_not (parser, CPP_COMMA)) 15380 break; 15381 15382 c_parser_consume_token (parser); 15383 } 15384 15385 if (vec == NULL_TREE) 15386 return list; 15387 15388 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND); 15389 OMP_CLAUSE_DEPEND_KIND (u) = OMP_CLAUSE_DEPEND_SINK; 15390 OMP_CLAUSE_DECL (u) = nreverse (vec); 15391 OMP_CLAUSE_CHAIN (u) = list; 15392 return u; 15393 } 15394 15395 /* OpenMP 5.0: 15396 iterators ( iterators-definition ) 15397 15398 iterators-definition: 15399 iterator-specifier 15400 iterator-specifier , iterators-definition 15401 15402 iterator-specifier: 15403 identifier = range-specification 15404 iterator-type identifier = range-specification 15405 15406 range-specification: 15407 begin : end 15408 begin : end : step */ 15409 15410 static tree 15411 c_parser_omp_iterators (c_parser *parser) 15412 { 15413 tree ret = NULL_TREE, *last = &ret; 15414 c_parser_consume_token (parser); 15415 15416 push_scope (); 15417 15418 matching_parens parens; 15419 if (!parens.require_open (parser)) 15420 return error_mark_node; 15421 15422 do 15423 { 15424 tree iter_type = NULL_TREE, type_expr = NULL_TREE; 15425 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id)) 15426 { 15427 struct c_type_name *type = c_parser_type_name (parser); 15428 if (type != NULL) 15429 iter_type = groktypename (type, &type_expr, NULL); 15430 } 15431 if (iter_type == NULL_TREE) 15432 iter_type = integer_type_node; 15433 15434 location_t loc = c_parser_peek_token (parser)->location; 15435 if (!c_parser_next_token_is (parser, CPP_NAME)) 15436 { 15437 c_parser_error (parser, "expected identifier"); 15438 break; 15439 } 15440 15441 tree id = c_parser_peek_token (parser)->value; 15442 c_parser_consume_token (parser); 15443 15444 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) 15445 break; 15446 15447 location_t eloc = c_parser_peek_token (parser)->location; 15448 c_expr expr = c_parser_expr_no_commas (parser, NULL); 15449 expr = convert_lvalue_to_rvalue (eloc, expr, true, false); 15450 tree begin = expr.value; 15451 15452 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 15453 break; 15454 15455 eloc = c_parser_peek_token (parser)->location; 15456 expr = c_parser_expr_no_commas (parser, NULL); 15457 expr = convert_lvalue_to_rvalue (eloc, expr, true, false); 15458 tree end = expr.value; 15459 15460 tree step = integer_one_node; 15461 if (c_parser_next_token_is (parser, CPP_COLON)) 15462 { 15463 c_parser_consume_token (parser); 15464 eloc = c_parser_peek_token (parser)->location; 15465 expr = c_parser_expr_no_commas (parser, NULL); 15466 expr = convert_lvalue_to_rvalue (eloc, expr, true, false); 15467 step = expr.value; 15468 } 15469 15470 tree iter_var = build_decl (loc, VAR_DECL, id, iter_type); 15471 DECL_ARTIFICIAL (iter_var) = 1; 15472 DECL_CONTEXT (iter_var) = current_function_decl; 15473 pushdecl (iter_var); 15474 15475 *last = make_tree_vec (6); 15476 TREE_VEC_ELT (*last, 0) = iter_var; 15477 TREE_VEC_ELT (*last, 1) = begin; 15478 TREE_VEC_ELT (*last, 2) = end; 15479 TREE_VEC_ELT (*last, 3) = step; 15480 last = &TREE_CHAIN (*last); 15481 15482 if (c_parser_next_token_is (parser, CPP_COMMA)) 15483 { 15484 c_parser_consume_token (parser); 15485 continue; 15486 } 15487 break; 15488 } 15489 while (1); 15490 15491 parens.skip_until_found_close (parser); 15492 return ret ? ret : error_mark_node; 15493 } 15494 15495 /* OpenMP 4.0: 15496 depend ( depend-kind: variable-list ) 15497 15498 depend-kind: 15499 in | out | inout 15500 15501 OpenMP 4.5: 15502 depend ( source ) 15503 15504 depend ( sink : vec ) 15505 15506 OpenMP 5.0: 15507 depend ( depend-modifier , depend-kind: variable-list ) 15508 15509 depend-kind: 15510 in | out | inout | mutexinoutset | depobj 15511 15512 depend-modifier: 15513 iterator ( iterators-definition ) */ 15514 15515 static tree 15516 c_parser_omp_clause_depend (c_parser *parser, tree list) 15517 { 15518 location_t clause_loc = c_parser_peek_token (parser)->location; 15519 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST; 15520 tree nl, c, iterators = NULL_TREE; 15521 15522 matching_parens parens; 15523 if (!parens.require_open (parser)) 15524 return list; 15525 15526 do 15527 { 15528 if (c_parser_next_token_is_not (parser, CPP_NAME)) 15529 goto invalid_kind; 15530 15531 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 15532 if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE) 15533 { 15534 iterators = c_parser_omp_iterators (parser); 15535 c_parser_require (parser, CPP_COMMA, "expected %<,%>"); 15536 continue; 15537 } 15538 if (strcmp ("in", p) == 0) 15539 kind = OMP_CLAUSE_DEPEND_IN; 15540 else if (strcmp ("inout", p) == 0) 15541 kind = OMP_CLAUSE_DEPEND_INOUT; 15542 else if (strcmp ("mutexinoutset", p) == 0) 15543 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET; 15544 else if (strcmp ("out", p) == 0) 15545 kind = OMP_CLAUSE_DEPEND_OUT; 15546 else if (strcmp ("depobj", p) == 0) 15547 kind = OMP_CLAUSE_DEPEND_DEPOBJ; 15548 else if (strcmp ("sink", p) == 0) 15549 kind = OMP_CLAUSE_DEPEND_SINK; 15550 else if (strcmp ("source", p) == 0) 15551 kind = OMP_CLAUSE_DEPEND_SOURCE; 15552 else 15553 goto invalid_kind; 15554 break; 15555 } 15556 while (1); 15557 15558 c_parser_consume_token (parser); 15559 15560 if (iterators 15561 && (kind == OMP_CLAUSE_DEPEND_SOURCE || kind == OMP_CLAUSE_DEPEND_SINK)) 15562 { 15563 pop_scope (); 15564 error_at (clause_loc, "%<iterator%> modifier incompatible with %qs", 15565 kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink"); 15566 iterators = NULL_TREE; 15567 } 15568 15569 if (kind == OMP_CLAUSE_DEPEND_SOURCE) 15570 { 15571 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND); 15572 OMP_CLAUSE_DEPEND_KIND (c) = kind; 15573 OMP_CLAUSE_DECL (c) = NULL_TREE; 15574 OMP_CLAUSE_CHAIN (c) = list; 15575 parens.skip_until_found_close (parser); 15576 return c; 15577 } 15578 15579 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 15580 goto resync_fail; 15581 15582 if (kind == OMP_CLAUSE_DEPEND_SINK) 15583 nl = c_parser_omp_clause_depend_sink (parser, clause_loc, list); 15584 else 15585 { 15586 nl = c_parser_omp_variable_list (parser, clause_loc, 15587 OMP_CLAUSE_DEPEND, list); 15588 15589 if (iterators) 15590 { 15591 tree block = pop_scope (); 15592 if (iterators == error_mark_node) 15593 iterators = NULL_TREE; 15594 else 15595 TREE_VEC_ELT (iterators, 5) = block; 15596 } 15597 15598 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) 15599 { 15600 OMP_CLAUSE_DEPEND_KIND (c) = kind; 15601 if (iterators) 15602 OMP_CLAUSE_DECL (c) 15603 = build_tree_list (iterators, OMP_CLAUSE_DECL (c)); 15604 } 15605 } 15606 15607 parens.skip_until_found_close (parser); 15608 return nl; 15609 15610 invalid_kind: 15611 c_parser_error (parser, "invalid depend kind"); 15612 resync_fail: 15613 parens.skip_until_found_close (parser); 15614 if (iterators) 15615 pop_scope (); 15616 return list; 15617 } 15618 15619 /* OpenMP 4.0: 15620 map ( map-kind: variable-list ) 15621 map ( variable-list ) 15622 15623 map-kind: 15624 alloc | to | from | tofrom 15625 15626 OpenMP 4.5: 15627 map-kind: 15628 alloc | to | from | tofrom | release | delete 15629 15630 map ( always [,] map-kind: variable-list ) */ 15631 15632 static tree 15633 c_parser_omp_clause_map (c_parser *parser, tree list) 15634 { 15635 location_t clause_loc = c_parser_peek_token (parser)->location; 15636 enum gomp_map_kind kind = GOMP_MAP_TOFROM; 15637 int always = 0; 15638 enum c_id_kind always_id_kind = C_ID_NONE; 15639 location_t always_loc = UNKNOWN_LOCATION; 15640 tree always_id = NULL_TREE; 15641 tree nl, c; 15642 15643 matching_parens parens; 15644 if (!parens.require_open (parser)) 15645 return list; 15646 15647 if (c_parser_next_token_is (parser, CPP_NAME)) 15648 { 15649 c_token *tok = c_parser_peek_token (parser); 15650 const char *p = IDENTIFIER_POINTER (tok->value); 15651 always_id_kind = tok->id_kind; 15652 always_loc = tok->location; 15653 always_id = tok->value; 15654 if (strcmp ("always", p) == 0) 15655 { 15656 c_token *sectok = c_parser_peek_2nd_token (parser); 15657 if (sectok->type == CPP_COMMA) 15658 { 15659 c_parser_consume_token (parser); 15660 c_parser_consume_token (parser); 15661 always = 2; 15662 } 15663 else if (sectok->type == CPP_NAME) 15664 { 15665 p = IDENTIFIER_POINTER (sectok->value); 15666 if (strcmp ("alloc", p) == 0 15667 || strcmp ("to", p) == 0 15668 || strcmp ("from", p) == 0 15669 || strcmp ("tofrom", p) == 0 15670 || strcmp ("release", p) == 0 15671 || strcmp ("delete", p) == 0) 15672 { 15673 c_parser_consume_token (parser); 15674 always = 1; 15675 } 15676 } 15677 } 15678 } 15679 15680 if (c_parser_next_token_is (parser, CPP_NAME) 15681 && c_parser_peek_2nd_token (parser)->type == CPP_COLON) 15682 { 15683 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 15684 if (strcmp ("alloc", p) == 0) 15685 kind = GOMP_MAP_ALLOC; 15686 else if (strcmp ("to", p) == 0) 15687 kind = always ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO; 15688 else if (strcmp ("from", p) == 0) 15689 kind = always ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM; 15690 else if (strcmp ("tofrom", p) == 0) 15691 kind = always ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM; 15692 else if (strcmp ("release", p) == 0) 15693 kind = GOMP_MAP_RELEASE; 15694 else if (strcmp ("delete", p) == 0) 15695 kind = GOMP_MAP_DELETE; 15696 else 15697 { 15698 c_parser_error (parser, "invalid map kind"); 15699 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 15700 "expected %<)%>"); 15701 return list; 15702 } 15703 c_parser_consume_token (parser); 15704 c_parser_consume_token (parser); 15705 } 15706 else if (always) 15707 { 15708 if (always_id_kind != C_ID_ID) 15709 { 15710 c_parser_error (parser, "expected identifier"); 15711 parens.skip_until_found_close (parser); 15712 return list; 15713 } 15714 15715 tree t = lookup_name (always_id); 15716 if (t == NULL_TREE) 15717 { 15718 undeclared_variable (always_loc, always_id); 15719 t = error_mark_node; 15720 } 15721 if (t != error_mark_node) 15722 { 15723 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_MAP); 15724 OMP_CLAUSE_DECL (u) = t; 15725 OMP_CLAUSE_CHAIN (u) = list; 15726 OMP_CLAUSE_SET_MAP_KIND (u, kind); 15727 list = u; 15728 } 15729 if (always == 1) 15730 { 15731 parens.skip_until_found_close (parser); 15732 return list; 15733 } 15734 } 15735 15736 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list); 15737 15738 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) 15739 OMP_CLAUSE_SET_MAP_KIND (c, kind); 15740 15741 parens.skip_until_found_close (parser); 15742 return nl; 15743 } 15744 15745 /* OpenMP 4.0: 15746 device ( expression ) */ 15747 15748 static tree 15749 c_parser_omp_clause_device (c_parser *parser, tree list) 15750 { 15751 location_t clause_loc = c_parser_peek_token (parser)->location; 15752 matching_parens parens; 15753 if (parens.require_open (parser)) 15754 { 15755 location_t expr_loc = c_parser_peek_token (parser)->location; 15756 c_expr expr = c_parser_expr_no_commas (parser, NULL); 15757 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 15758 tree c, t = expr.value; 15759 t = c_fully_fold (t, false, NULL); 15760 15761 parens.skip_until_found_close (parser); 15762 15763 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 15764 { 15765 c_parser_error (parser, "expected integer expression"); 15766 return list; 15767 } 15768 15769 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device"); 15770 15771 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE); 15772 OMP_CLAUSE_DEVICE_ID (c) = t; 15773 OMP_CLAUSE_CHAIN (c) = list; 15774 list = c; 15775 } 15776 15777 return list; 15778 } 15779 15780 /* OpenMP 4.0: 15781 dist_schedule ( static ) 15782 dist_schedule ( static , expression ) */ 15783 15784 static tree 15785 c_parser_omp_clause_dist_schedule (c_parser *parser, tree list) 15786 { 15787 tree c, t = NULL_TREE; 15788 location_t loc = c_parser_peek_token (parser)->location; 15789 15790 matching_parens parens; 15791 if (!parens.require_open (parser)) 15792 return list; 15793 15794 if (!c_parser_next_token_is_keyword (parser, RID_STATIC)) 15795 { 15796 c_parser_error (parser, "invalid dist_schedule kind"); 15797 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 15798 "expected %<)%>"); 15799 return list; 15800 } 15801 15802 c_parser_consume_token (parser); 15803 if (c_parser_next_token_is (parser, CPP_COMMA)) 15804 { 15805 c_parser_consume_token (parser); 15806 15807 location_t expr_loc = c_parser_peek_token (parser)->location; 15808 c_expr expr = c_parser_expr_no_commas (parser, NULL); 15809 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 15810 t = expr.value; 15811 t = c_fully_fold (t, false, NULL); 15812 parens.skip_until_found_close (parser); 15813 } 15814 else 15815 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 15816 "expected %<,%> or %<)%>"); 15817 15818 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE, 15819 "dist_schedule"); */ 15820 if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE)) 15821 warning_at (loc, 0, "too many %qs clauses", "dist_schedule"); 15822 if (t == error_mark_node) 15823 return list; 15824 15825 c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE); 15826 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t; 15827 OMP_CLAUSE_CHAIN (c) = list; 15828 return c; 15829 } 15830 15831 /* OpenMP 4.0: 15832 proc_bind ( proc-bind-kind ) 15833 15834 proc-bind-kind: 15835 master | close | spread */ 15836 15837 static tree 15838 c_parser_omp_clause_proc_bind (c_parser *parser, tree list) 15839 { 15840 location_t clause_loc = c_parser_peek_token (parser)->location; 15841 enum omp_clause_proc_bind_kind kind; 15842 tree c; 15843 15844 matching_parens parens; 15845 if (!parens.require_open (parser)) 15846 return list; 15847 15848 if (c_parser_next_token_is (parser, CPP_NAME)) 15849 { 15850 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 15851 if (strcmp ("master", p) == 0) 15852 kind = OMP_CLAUSE_PROC_BIND_MASTER; 15853 else if (strcmp ("close", p) == 0) 15854 kind = OMP_CLAUSE_PROC_BIND_CLOSE; 15855 else if (strcmp ("spread", p) == 0) 15856 kind = OMP_CLAUSE_PROC_BIND_SPREAD; 15857 else 15858 goto invalid_kind; 15859 } 15860 else 15861 goto invalid_kind; 15862 15863 check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind"); 15864 c_parser_consume_token (parser); 15865 parens.skip_until_found_close (parser); 15866 c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND); 15867 OMP_CLAUSE_PROC_BIND_KIND (c) = kind; 15868 OMP_CLAUSE_CHAIN (c) = list; 15869 return c; 15870 15871 invalid_kind: 15872 c_parser_error (parser, "invalid proc_bind kind"); 15873 parens.skip_until_found_close (parser); 15874 return list; 15875 } 15876 15877 /* OpenMP 5.0: 15878 device_type ( host | nohost | any ) */ 15879 15880 static tree 15881 c_parser_omp_clause_device_type (c_parser *parser, tree list) 15882 { 15883 location_t clause_loc = c_parser_peek_token (parser)->location; 15884 enum omp_clause_device_type_kind kind; 15885 tree c; 15886 15887 matching_parens parens; 15888 if (!parens.require_open (parser)) 15889 return list; 15890 15891 if (c_parser_next_token_is (parser, CPP_NAME)) 15892 { 15893 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 15894 if (strcmp ("host", p) == 0) 15895 kind = OMP_CLAUSE_DEVICE_TYPE_HOST; 15896 else if (strcmp ("nohost", p) == 0) 15897 kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST; 15898 else if (strcmp ("any", p) == 0) 15899 kind = OMP_CLAUSE_DEVICE_TYPE_ANY; 15900 else 15901 goto invalid_kind; 15902 } 15903 else 15904 goto invalid_kind; 15905 15906 /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE, 15907 "device_type"); */ 15908 c_parser_consume_token (parser); 15909 parens.skip_until_found_close (parser); 15910 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE); 15911 OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind; 15912 OMP_CLAUSE_CHAIN (c) = list; 15913 return c; 15914 15915 invalid_kind: 15916 c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>"); 15917 parens.skip_until_found_close (parser); 15918 return list; 15919 } 15920 15921 /* OpenMP 4.0: 15922 to ( variable-list ) */ 15923 15924 static tree 15925 c_parser_omp_clause_to (c_parser *parser, tree list) 15926 { 15927 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO, list); 15928 } 15929 15930 /* OpenMP 4.0: 15931 from ( variable-list ) */ 15932 15933 static tree 15934 c_parser_omp_clause_from (c_parser *parser, tree list) 15935 { 15936 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FROM, list); 15937 } 15938 15939 /* OpenMP 4.0: 15940 uniform ( variable-list ) */ 15941 15942 static tree 15943 c_parser_omp_clause_uniform (c_parser *parser, tree list) 15944 { 15945 /* The clauses location. */ 15946 location_t loc = c_parser_peek_token (parser)->location; 15947 15948 matching_parens parens; 15949 if (parens.require_open (parser)) 15950 { 15951 list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM, 15952 list); 15953 parens.skip_until_found_close (parser); 15954 } 15955 return list; 15956 } 15957 15958 /* Parse all OpenACC clauses. The set clauses allowed by the directive 15959 is a bitmask in MASK. Return the list of clauses found. */ 15960 15961 static tree 15962 c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask, 15963 const char *where, bool finish_p = true) 15964 { 15965 tree clauses = NULL; 15966 bool first = true; 15967 15968 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 15969 { 15970 location_t here; 15971 pragma_omp_clause c_kind; 15972 const char *c_name; 15973 tree prev = clauses; 15974 15975 if (!first && c_parser_next_token_is (parser, CPP_COMMA)) 15976 c_parser_consume_token (parser); 15977 15978 here = c_parser_peek_token (parser)->location; 15979 c_kind = c_parser_omp_clause_name (parser); 15980 15981 switch (c_kind) 15982 { 15983 case PRAGMA_OACC_CLAUSE_ASYNC: 15984 clauses = c_parser_oacc_clause_async (parser, clauses); 15985 c_name = "async"; 15986 break; 15987 case PRAGMA_OACC_CLAUSE_AUTO: 15988 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO, 15989 clauses); 15990 c_name = "auto"; 15991 break; 15992 case PRAGMA_OACC_CLAUSE_ATTACH: 15993 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 15994 c_name = "attach"; 15995 break; 15996 case PRAGMA_OACC_CLAUSE_COLLAPSE: 15997 clauses = c_parser_omp_clause_collapse (parser, clauses); 15998 c_name = "collapse"; 15999 break; 16000 case PRAGMA_OACC_CLAUSE_COPY: 16001 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 16002 c_name = "copy"; 16003 break; 16004 case PRAGMA_OACC_CLAUSE_COPYIN: 16005 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 16006 c_name = "copyin"; 16007 break; 16008 case PRAGMA_OACC_CLAUSE_COPYOUT: 16009 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 16010 c_name = "copyout"; 16011 break; 16012 case PRAGMA_OACC_CLAUSE_CREATE: 16013 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 16014 c_name = "create"; 16015 break; 16016 case PRAGMA_OACC_CLAUSE_DELETE: 16017 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 16018 c_name = "delete"; 16019 break; 16020 case PRAGMA_OMP_CLAUSE_DEFAULT: 16021 clauses = c_parser_omp_clause_default (parser, clauses, true); 16022 c_name = "default"; 16023 break; 16024 case PRAGMA_OACC_CLAUSE_DETACH: 16025 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 16026 c_name = "detach"; 16027 break; 16028 case PRAGMA_OACC_CLAUSE_DEVICE: 16029 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 16030 c_name = "device"; 16031 break; 16032 case PRAGMA_OACC_CLAUSE_DEVICEPTR: 16033 clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses); 16034 c_name = "deviceptr"; 16035 break; 16036 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT: 16037 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 16038 c_name = "device_resident"; 16039 break; 16040 case PRAGMA_OACC_CLAUSE_FINALIZE: 16041 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE, 16042 clauses); 16043 c_name = "finalize"; 16044 break; 16045 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE: 16046 clauses = c_parser_omp_clause_firstprivate (parser, clauses); 16047 c_name = "firstprivate"; 16048 break; 16049 case PRAGMA_OACC_CLAUSE_GANG: 16050 c_name = "gang"; 16051 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG, 16052 c_name, clauses); 16053 break; 16054 case PRAGMA_OACC_CLAUSE_HOST: 16055 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 16056 c_name = "host"; 16057 break; 16058 case PRAGMA_OACC_CLAUSE_IF: 16059 clauses = c_parser_omp_clause_if (parser, clauses, false); 16060 c_name = "if"; 16061 break; 16062 case PRAGMA_OACC_CLAUSE_IF_PRESENT: 16063 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT, 16064 clauses); 16065 c_name = "if_present"; 16066 break; 16067 case PRAGMA_OACC_CLAUSE_INDEPENDENT: 16068 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT, 16069 clauses); 16070 c_name = "independent"; 16071 break; 16072 case PRAGMA_OACC_CLAUSE_LINK: 16073 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 16074 c_name = "link"; 16075 break; 16076 case PRAGMA_OACC_CLAUSE_NO_CREATE: 16077 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 16078 c_name = "no_create"; 16079 break; 16080 case PRAGMA_OACC_CLAUSE_NUM_GANGS: 16081 clauses = c_parser_oacc_single_int_clause (parser, 16082 OMP_CLAUSE_NUM_GANGS, 16083 clauses); 16084 c_name = "num_gangs"; 16085 break; 16086 case PRAGMA_OACC_CLAUSE_NUM_WORKERS: 16087 clauses = c_parser_oacc_single_int_clause (parser, 16088 OMP_CLAUSE_NUM_WORKERS, 16089 clauses); 16090 c_name = "num_workers"; 16091 break; 16092 case PRAGMA_OACC_CLAUSE_PRESENT: 16093 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 16094 c_name = "present"; 16095 break; 16096 case PRAGMA_OACC_CLAUSE_PRIVATE: 16097 clauses = c_parser_omp_clause_private (parser, clauses); 16098 c_name = "private"; 16099 break; 16100 case PRAGMA_OACC_CLAUSE_REDUCTION: 16101 clauses 16102 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION, 16103 false, clauses); 16104 c_name = "reduction"; 16105 break; 16106 case PRAGMA_OACC_CLAUSE_SEQ: 16107 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ, 16108 clauses); 16109 c_name = "seq"; 16110 break; 16111 case PRAGMA_OACC_CLAUSE_TILE: 16112 clauses = c_parser_oacc_clause_tile (parser, clauses); 16113 c_name = "tile"; 16114 break; 16115 case PRAGMA_OACC_CLAUSE_USE_DEVICE: 16116 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses); 16117 c_name = "use_device"; 16118 break; 16119 case PRAGMA_OACC_CLAUSE_VECTOR: 16120 c_name = "vector"; 16121 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR, 16122 c_name, clauses); 16123 break; 16124 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH: 16125 clauses = c_parser_oacc_single_int_clause (parser, 16126 OMP_CLAUSE_VECTOR_LENGTH, 16127 clauses); 16128 c_name = "vector_length"; 16129 break; 16130 case PRAGMA_OACC_CLAUSE_WAIT: 16131 clauses = c_parser_oacc_clause_wait (parser, clauses); 16132 c_name = "wait"; 16133 break; 16134 case PRAGMA_OACC_CLAUSE_WORKER: 16135 c_name = "worker"; 16136 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER, 16137 c_name, clauses); 16138 break; 16139 default: 16140 c_parser_error (parser, "expected %<#pragma acc%> clause"); 16141 goto saw_error; 16142 } 16143 16144 first = false; 16145 16146 if (((mask >> c_kind) & 1) == 0) 16147 { 16148 /* Remove the invalid clause(s) from the list to avoid 16149 confusing the rest of the compiler. */ 16150 clauses = prev; 16151 error_at (here, "%qs is not valid for %qs", c_name, where); 16152 } 16153 } 16154 16155 saw_error: 16156 c_parser_skip_to_pragma_eol (parser); 16157 16158 if (finish_p) 16159 return c_finish_omp_clauses (clauses, C_ORT_ACC); 16160 16161 return clauses; 16162 } 16163 16164 /* Parse all OpenMP clauses. The set clauses allowed by the directive 16165 is a bitmask in MASK. Return the list of clauses found. 16166 FINISH_P set if c_finish_omp_clauses should be called. 16167 NESTED non-zero if clauses should be terminated by closing paren instead 16168 of end of pragma. If it is 2, additionally commas are required in between 16169 the clauses. */ 16170 16171 static tree 16172 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask, 16173 const char *where, bool finish_p = true, 16174 int nested = 0) 16175 { 16176 tree clauses = NULL; 16177 bool first = true; 16178 16179 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 16180 { 16181 location_t here; 16182 pragma_omp_clause c_kind; 16183 const char *c_name; 16184 tree prev = clauses; 16185 16186 if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 16187 break; 16188 16189 if (!first) 16190 { 16191 if (c_parser_next_token_is (parser, CPP_COMMA)) 16192 c_parser_consume_token (parser); 16193 else if (nested == 2) 16194 error_at (c_parser_peek_token (parser)->location, 16195 "clauses in %<simd%> trait should be separated " 16196 "by %<,%>"); 16197 } 16198 16199 here = c_parser_peek_token (parser)->location; 16200 c_kind = c_parser_omp_clause_name (parser); 16201 16202 switch (c_kind) 16203 { 16204 case PRAGMA_OMP_CLAUSE_BIND: 16205 clauses = c_parser_omp_clause_bind (parser, clauses); 16206 c_name = "bind"; 16207 break; 16208 case PRAGMA_OMP_CLAUSE_COLLAPSE: 16209 clauses = c_parser_omp_clause_collapse (parser, clauses); 16210 c_name = "collapse"; 16211 break; 16212 case PRAGMA_OMP_CLAUSE_COPYIN: 16213 clauses = c_parser_omp_clause_copyin (parser, clauses); 16214 c_name = "copyin"; 16215 break; 16216 case PRAGMA_OMP_CLAUSE_COPYPRIVATE: 16217 clauses = c_parser_omp_clause_copyprivate (parser, clauses); 16218 c_name = "copyprivate"; 16219 break; 16220 case PRAGMA_OMP_CLAUSE_DEFAULT: 16221 clauses = c_parser_omp_clause_default (parser, clauses, false); 16222 c_name = "default"; 16223 break; 16224 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE: 16225 clauses = c_parser_omp_clause_firstprivate (parser, clauses); 16226 c_name = "firstprivate"; 16227 break; 16228 case PRAGMA_OMP_CLAUSE_FINAL: 16229 clauses = c_parser_omp_clause_final (parser, clauses); 16230 c_name = "final"; 16231 break; 16232 case PRAGMA_OMP_CLAUSE_GRAINSIZE: 16233 clauses = c_parser_omp_clause_grainsize (parser, clauses); 16234 c_name = "grainsize"; 16235 break; 16236 case PRAGMA_OMP_CLAUSE_HINT: 16237 clauses = c_parser_omp_clause_hint (parser, clauses); 16238 c_name = "hint"; 16239 break; 16240 case PRAGMA_OMP_CLAUSE_DEFAULTMAP: 16241 clauses = c_parser_omp_clause_defaultmap (parser, clauses); 16242 c_name = "defaultmap"; 16243 break; 16244 case PRAGMA_OMP_CLAUSE_IF: 16245 clauses = c_parser_omp_clause_if (parser, clauses, true); 16246 c_name = "if"; 16247 break; 16248 case PRAGMA_OMP_CLAUSE_IN_REDUCTION: 16249 clauses 16250 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION, 16251 true, clauses); 16252 c_name = "in_reduction"; 16253 break; 16254 case PRAGMA_OMP_CLAUSE_LASTPRIVATE: 16255 clauses = c_parser_omp_clause_lastprivate (parser, clauses); 16256 c_name = "lastprivate"; 16257 break; 16258 case PRAGMA_OMP_CLAUSE_MERGEABLE: 16259 clauses = c_parser_omp_clause_mergeable (parser, clauses); 16260 c_name = "mergeable"; 16261 break; 16262 case PRAGMA_OMP_CLAUSE_NOWAIT: 16263 clauses = c_parser_omp_clause_nowait (parser, clauses); 16264 c_name = "nowait"; 16265 break; 16266 case PRAGMA_OMP_CLAUSE_NUM_TASKS: 16267 clauses = c_parser_omp_clause_num_tasks (parser, clauses); 16268 c_name = "num_tasks"; 16269 break; 16270 case PRAGMA_OMP_CLAUSE_NUM_THREADS: 16271 clauses = c_parser_omp_clause_num_threads (parser, clauses); 16272 c_name = "num_threads"; 16273 break; 16274 case PRAGMA_OMP_CLAUSE_ORDER: 16275 clauses = c_parser_omp_clause_order (parser, clauses); 16276 c_name = "order"; 16277 break; 16278 case PRAGMA_OMP_CLAUSE_ORDERED: 16279 clauses = c_parser_omp_clause_ordered (parser, clauses); 16280 c_name = "ordered"; 16281 break; 16282 case PRAGMA_OMP_CLAUSE_PRIORITY: 16283 clauses = c_parser_omp_clause_priority (parser, clauses); 16284 c_name = "priority"; 16285 break; 16286 case PRAGMA_OMP_CLAUSE_PRIVATE: 16287 clauses = c_parser_omp_clause_private (parser, clauses); 16288 c_name = "private"; 16289 break; 16290 case PRAGMA_OMP_CLAUSE_REDUCTION: 16291 clauses 16292 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION, 16293 true, clauses); 16294 c_name = "reduction"; 16295 break; 16296 case PRAGMA_OMP_CLAUSE_SCHEDULE: 16297 clauses = c_parser_omp_clause_schedule (parser, clauses); 16298 c_name = "schedule"; 16299 break; 16300 case PRAGMA_OMP_CLAUSE_SHARED: 16301 clauses = c_parser_omp_clause_shared (parser, clauses); 16302 c_name = "shared"; 16303 break; 16304 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION: 16305 clauses 16306 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION, 16307 true, clauses); 16308 c_name = "task_reduction"; 16309 break; 16310 case PRAGMA_OMP_CLAUSE_UNTIED: 16311 clauses = c_parser_omp_clause_untied (parser, clauses); 16312 c_name = "untied"; 16313 break; 16314 case PRAGMA_OMP_CLAUSE_INBRANCH: 16315 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH, 16316 clauses); 16317 c_name = "inbranch"; 16318 break; 16319 case PRAGMA_OMP_CLAUSE_NONTEMPORAL: 16320 clauses = c_parser_omp_clause_nontemporal (parser, clauses); 16321 c_name = "nontemporal"; 16322 break; 16323 case PRAGMA_OMP_CLAUSE_NOTINBRANCH: 16324 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH, 16325 clauses); 16326 c_name = "notinbranch"; 16327 break; 16328 case PRAGMA_OMP_CLAUSE_PARALLEL: 16329 clauses 16330 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL, 16331 clauses); 16332 c_name = "parallel"; 16333 if (!first) 16334 { 16335 clause_not_first: 16336 error_at (here, "%qs must be the first clause of %qs", 16337 c_name, where); 16338 clauses = prev; 16339 } 16340 break; 16341 case PRAGMA_OMP_CLAUSE_FOR: 16342 clauses 16343 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR, 16344 clauses); 16345 c_name = "for"; 16346 if (!first) 16347 goto clause_not_first; 16348 break; 16349 case PRAGMA_OMP_CLAUSE_SECTIONS: 16350 clauses 16351 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS, 16352 clauses); 16353 c_name = "sections"; 16354 if (!first) 16355 goto clause_not_first; 16356 break; 16357 case PRAGMA_OMP_CLAUSE_TASKGROUP: 16358 clauses 16359 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP, 16360 clauses); 16361 c_name = "taskgroup"; 16362 if (!first) 16363 goto clause_not_first; 16364 break; 16365 case PRAGMA_OMP_CLAUSE_LINK: 16366 clauses 16367 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses); 16368 c_name = "link"; 16369 break; 16370 case PRAGMA_OMP_CLAUSE_TO: 16371 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0) 16372 clauses 16373 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE, 16374 clauses); 16375 else 16376 clauses = c_parser_omp_clause_to (parser, clauses); 16377 c_name = "to"; 16378 break; 16379 case PRAGMA_OMP_CLAUSE_FROM: 16380 clauses = c_parser_omp_clause_from (parser, clauses); 16381 c_name = "from"; 16382 break; 16383 case PRAGMA_OMP_CLAUSE_UNIFORM: 16384 clauses = c_parser_omp_clause_uniform (parser, clauses); 16385 c_name = "uniform"; 16386 break; 16387 case PRAGMA_OMP_CLAUSE_NUM_TEAMS: 16388 clauses = c_parser_omp_clause_num_teams (parser, clauses); 16389 c_name = "num_teams"; 16390 break; 16391 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT: 16392 clauses = c_parser_omp_clause_thread_limit (parser, clauses); 16393 c_name = "thread_limit"; 16394 break; 16395 case PRAGMA_OMP_CLAUSE_ALIGNED: 16396 clauses = c_parser_omp_clause_aligned (parser, clauses); 16397 c_name = "aligned"; 16398 break; 16399 case PRAGMA_OMP_CLAUSE_LINEAR: 16400 clauses = c_parser_omp_clause_linear (parser, clauses); 16401 c_name = "linear"; 16402 break; 16403 case PRAGMA_OMP_CLAUSE_DEPEND: 16404 clauses = c_parser_omp_clause_depend (parser, clauses); 16405 c_name = "depend"; 16406 break; 16407 case PRAGMA_OMP_CLAUSE_MAP: 16408 clauses = c_parser_omp_clause_map (parser, clauses); 16409 c_name = "map"; 16410 break; 16411 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR: 16412 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses); 16413 c_name = "use_device_ptr"; 16414 break; 16415 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR: 16416 clauses = c_parser_omp_clause_use_device_addr (parser, clauses); 16417 c_name = "use_device_addr"; 16418 break; 16419 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR: 16420 clauses = c_parser_omp_clause_is_device_ptr (parser, clauses); 16421 c_name = "is_device_ptr"; 16422 break; 16423 case PRAGMA_OMP_CLAUSE_DEVICE: 16424 clauses = c_parser_omp_clause_device (parser, clauses); 16425 c_name = "device"; 16426 break; 16427 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE: 16428 clauses = c_parser_omp_clause_dist_schedule (parser, clauses); 16429 c_name = "dist_schedule"; 16430 break; 16431 case PRAGMA_OMP_CLAUSE_PROC_BIND: 16432 clauses = c_parser_omp_clause_proc_bind (parser, clauses); 16433 c_name = "proc_bind"; 16434 break; 16435 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE: 16436 clauses = c_parser_omp_clause_device_type (parser, clauses); 16437 c_name = "device_type"; 16438 break; 16439 case PRAGMA_OMP_CLAUSE_SAFELEN: 16440 clauses = c_parser_omp_clause_safelen (parser, clauses); 16441 c_name = "safelen"; 16442 break; 16443 case PRAGMA_OMP_CLAUSE_SIMDLEN: 16444 clauses = c_parser_omp_clause_simdlen (parser, clauses); 16445 c_name = "simdlen"; 16446 break; 16447 case PRAGMA_OMP_CLAUSE_NOGROUP: 16448 clauses = c_parser_omp_clause_nogroup (parser, clauses); 16449 c_name = "nogroup"; 16450 break; 16451 case PRAGMA_OMP_CLAUSE_THREADS: 16452 clauses 16453 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS, 16454 clauses); 16455 c_name = "threads"; 16456 break; 16457 case PRAGMA_OMP_CLAUSE_SIMD: 16458 clauses 16459 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD, 16460 clauses); 16461 c_name = "simd"; 16462 break; 16463 default: 16464 c_parser_error (parser, "expected %<#pragma omp%> clause"); 16465 goto saw_error; 16466 } 16467 16468 first = false; 16469 16470 if (((mask >> c_kind) & 1) == 0) 16471 { 16472 /* Remove the invalid clause(s) from the list to avoid 16473 confusing the rest of the compiler. */ 16474 clauses = prev; 16475 error_at (here, "%qs is not valid for %qs", c_name, where); 16476 } 16477 } 16478 16479 saw_error: 16480 if (!nested) 16481 c_parser_skip_to_pragma_eol (parser); 16482 16483 if (finish_p) 16484 { 16485 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0) 16486 return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD); 16487 return c_finish_omp_clauses (clauses, C_ORT_OMP); 16488 } 16489 16490 return clauses; 16491 } 16492 16493 /* OpenACC 2.0, OpenMP 2.5: 16494 structured-block: 16495 statement 16496 16497 In practice, we're also interested in adding the statement to an 16498 outer node. So it is convenient if we work around the fact that 16499 c_parser_statement calls add_stmt. */ 16500 16501 static tree 16502 c_parser_omp_structured_block (c_parser *parser, bool *if_p) 16503 { 16504 tree stmt = push_stmt_list (); 16505 c_parser_statement (parser, if_p); 16506 return pop_stmt_list (stmt); 16507 } 16508 16509 /* OpenACC 2.0: 16510 # pragma acc cache (variable-list) new-line 16511 16512 LOC is the location of the #pragma token. 16513 */ 16514 16515 static tree 16516 c_parser_oacc_cache (location_t loc, c_parser *parser) 16517 { 16518 tree stmt, clauses; 16519 16520 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL); 16521 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC); 16522 16523 c_parser_skip_to_pragma_eol (parser); 16524 16525 stmt = make_node (OACC_CACHE); 16526 TREE_TYPE (stmt) = void_type_node; 16527 OACC_CACHE_CLAUSES (stmt) = clauses; 16528 SET_EXPR_LOCATION (stmt, loc); 16529 add_stmt (stmt); 16530 16531 return stmt; 16532 } 16533 16534 /* OpenACC 2.0: 16535 # pragma acc data oacc-data-clause[optseq] new-line 16536 structured-block 16537 16538 LOC is the location of the #pragma token. 16539 */ 16540 16541 #define OACC_DATA_CLAUSE_MASK \ 16542 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \ 16543 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \ 16544 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \ 16545 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \ 16546 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \ 16547 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \ 16548 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \ 16549 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \ 16550 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)) 16551 16552 static tree 16553 c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p) 16554 { 16555 tree stmt, clauses, block; 16556 16557 clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK, 16558 "#pragma acc data"); 16559 16560 block = c_begin_omp_parallel (); 16561 add_stmt (c_parser_omp_structured_block (parser, if_p)); 16562 16563 stmt = c_finish_oacc_data (loc, clauses, block); 16564 16565 return stmt; 16566 } 16567 16568 /* OpenACC 2.0: 16569 # pragma acc declare oacc-data-clause[optseq] new-line 16570 */ 16571 16572 #define OACC_DECLARE_CLAUSE_MASK \ 16573 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \ 16574 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \ 16575 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \ 16576 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \ 16577 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \ 16578 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \ 16579 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \ 16580 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)) 16581 16582 static void 16583 c_parser_oacc_declare (c_parser *parser) 16584 { 16585 location_t pragma_loc = c_parser_peek_token (parser)->location; 16586 tree clauses, stmt, t, decl; 16587 16588 bool error = false; 16589 16590 c_parser_consume_pragma (parser); 16591 16592 clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK, 16593 "#pragma acc declare"); 16594 if (!clauses) 16595 { 16596 error_at (pragma_loc, 16597 "no valid clauses specified in %<#pragma acc declare%>"); 16598 return; 16599 } 16600 16601 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t)) 16602 { 16603 location_t loc = OMP_CLAUSE_LOCATION (t); 16604 decl = OMP_CLAUSE_DECL (t); 16605 if (!DECL_P (decl)) 16606 { 16607 error_at (loc, "array section in %<#pragma acc declare%>"); 16608 error = true; 16609 continue; 16610 } 16611 16612 switch (OMP_CLAUSE_MAP_KIND (t)) 16613 { 16614 case GOMP_MAP_FIRSTPRIVATE_POINTER: 16615 case GOMP_MAP_ALLOC: 16616 case GOMP_MAP_TO: 16617 case GOMP_MAP_FORCE_DEVICEPTR: 16618 case GOMP_MAP_DEVICE_RESIDENT: 16619 break; 16620 16621 case GOMP_MAP_LINK: 16622 if (!global_bindings_p () 16623 && (TREE_STATIC (decl) 16624 || !DECL_EXTERNAL (decl))) 16625 { 16626 error_at (loc, 16627 "%qD must be a global variable in " 16628 "%<#pragma acc declare link%>", 16629 decl); 16630 error = true; 16631 continue; 16632 } 16633 break; 16634 16635 default: 16636 if (global_bindings_p ()) 16637 { 16638 error_at (loc, "invalid OpenACC clause at file scope"); 16639 error = true; 16640 continue; 16641 } 16642 if (DECL_EXTERNAL (decl)) 16643 { 16644 error_at (loc, 16645 "invalid use of %<extern%> variable %qD " 16646 "in %<#pragma acc declare%>", decl); 16647 error = true; 16648 continue; 16649 } 16650 else if (TREE_PUBLIC (decl)) 16651 { 16652 error_at (loc, 16653 "invalid use of %<global%> variable %qD " 16654 "in %<#pragma acc declare%>", decl); 16655 error = true; 16656 continue; 16657 } 16658 break; 16659 } 16660 16661 if (!c_check_in_current_scope (decl)) 16662 { 16663 error_at (loc, 16664 "%qD must be a variable declared in the same scope as " 16665 "%<#pragma acc declare%>", decl); 16666 error = true; 16667 continue; 16668 } 16669 16670 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)) 16671 || lookup_attribute ("omp declare target link", 16672 DECL_ATTRIBUTES (decl))) 16673 { 16674 error_at (loc, "variable %qD used more than once with " 16675 "%<#pragma acc declare%>", decl); 16676 error = true; 16677 continue; 16678 } 16679 16680 if (!error) 16681 { 16682 tree id; 16683 16684 if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK) 16685 id = get_identifier ("omp declare target link"); 16686 else 16687 id = get_identifier ("omp declare target"); 16688 16689 DECL_ATTRIBUTES (decl) 16690 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl)); 16691 16692 if (global_bindings_p ()) 16693 { 16694 symtab_node *node = symtab_node::get (decl); 16695 if (node != NULL) 16696 { 16697 node->offloadable = 1; 16698 if (ENABLE_OFFLOADING) 16699 { 16700 g->have_offload = true; 16701 if (is_a <varpool_node *> (node)) 16702 vec_safe_push (offload_vars, decl); 16703 } 16704 } 16705 } 16706 } 16707 } 16708 16709 if (error || global_bindings_p ()) 16710 return; 16711 16712 stmt = make_node (OACC_DECLARE); 16713 TREE_TYPE (stmt) = void_type_node; 16714 OACC_DECLARE_CLAUSES (stmt) = clauses; 16715 SET_EXPR_LOCATION (stmt, pragma_loc); 16716 16717 add_stmt (stmt); 16718 16719 return; 16720 } 16721 16722 /* OpenACC 2.0: 16723 # pragma acc enter data oacc-enter-data-clause[optseq] new-line 16724 16725 or 16726 16727 # pragma acc exit data oacc-exit-data-clause[optseq] new-line 16728 16729 16730 LOC is the location of the #pragma token. 16731 */ 16732 16733 #define OACC_ENTER_DATA_CLAUSE_MASK \ 16734 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \ 16735 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \ 16736 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \ 16737 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \ 16738 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \ 16739 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) ) 16740 16741 #define OACC_EXIT_DATA_CLAUSE_MASK \ 16742 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \ 16743 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \ 16744 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \ 16745 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \ 16746 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \ 16747 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \ 16748 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) ) 16749 16750 static void 16751 c_parser_oacc_enter_exit_data (c_parser *parser, bool enter) 16752 { 16753 location_t loc = c_parser_peek_token (parser)->location; 16754 tree clauses, stmt; 16755 const char *p = ""; 16756 16757 c_parser_consume_pragma (parser); 16758 16759 if (c_parser_next_token_is (parser, CPP_NAME)) 16760 { 16761 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 16762 c_parser_consume_token (parser); 16763 } 16764 16765 if (strcmp (p, "data") != 0) 16766 { 16767 error_at (loc, "expected %<data%> after %<#pragma acc %s%>", 16768 enter ? "enter" : "exit"); 16769 parser->error = true; 16770 c_parser_skip_to_pragma_eol (parser); 16771 return; 16772 } 16773 16774 if (enter) 16775 clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK, 16776 "#pragma acc enter data"); 16777 else 16778 clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK, 16779 "#pragma acc exit data"); 16780 16781 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE) 16782 { 16783 error_at (loc, "%<#pragma acc %s data%> has no data movement clause", 16784 enter ? "enter" : "exit"); 16785 return; 16786 } 16787 16788 stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA); 16789 TREE_TYPE (stmt) = void_type_node; 16790 OMP_STANDALONE_CLAUSES (stmt) = clauses; 16791 SET_EXPR_LOCATION (stmt, loc); 16792 add_stmt (stmt); 16793 } 16794 16795 16796 /* OpenACC 2.0: 16797 # pragma acc host_data oacc-data-clause[optseq] new-line 16798 structured-block 16799 */ 16800 16801 #define OACC_HOST_DATA_CLAUSE_MASK \ 16802 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \ 16803 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \ 16804 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) ) 16805 16806 static tree 16807 c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p) 16808 { 16809 tree stmt, clauses, block; 16810 16811 clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK, 16812 "#pragma acc host_data"); 16813 16814 block = c_begin_omp_parallel (); 16815 add_stmt (c_parser_omp_structured_block (parser, if_p)); 16816 stmt = c_finish_oacc_host_data (loc, clauses, block); 16817 return stmt; 16818 } 16819 16820 16821 /* OpenACC 2.0: 16822 16823 # pragma acc loop oacc-loop-clause[optseq] new-line 16824 structured-block 16825 16826 LOC is the location of the #pragma token. 16827 */ 16828 16829 #define OACC_LOOP_CLAUSE_MASK \ 16830 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \ 16831 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \ 16832 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \ 16833 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \ 16834 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \ 16835 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \ 16836 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \ 16837 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \ 16838 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \ 16839 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) ) 16840 static tree 16841 c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name, 16842 omp_clause_mask mask, tree *cclauses, bool *if_p) 16843 { 16844 bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1; 16845 16846 strcat (p_name, " loop"); 16847 mask |= OACC_LOOP_CLAUSE_MASK; 16848 16849 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name, 16850 cclauses == NULL); 16851 if (cclauses) 16852 { 16853 clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel); 16854 if (*cclauses) 16855 *cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC); 16856 if (clauses) 16857 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC); 16858 } 16859 16860 tree block = c_begin_compound_stmt (true); 16861 tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL, 16862 if_p); 16863 block = c_end_compound_stmt (loc, block, true); 16864 add_stmt (block); 16865 16866 return stmt; 16867 } 16868 16869 /* OpenACC 2.0: 16870 # pragma acc kernels oacc-kernels-clause[optseq] new-line 16871 structured-block 16872 16873 or 16874 16875 # pragma acc parallel oacc-parallel-clause[optseq] new-line 16876 structured-block 16877 16878 OpenACC 2.6: 16879 16880 # pragma acc serial oacc-serial-clause[optseq] new-line 16881 structured-block 16882 16883 LOC is the location of the #pragma token. 16884 */ 16885 16886 #define OACC_KERNELS_CLAUSE_MASK \ 16887 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \ 16888 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \ 16889 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \ 16890 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \ 16891 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \ 16892 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \ 16893 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \ 16894 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \ 16895 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \ 16896 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \ 16897 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \ 16898 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \ 16899 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \ 16900 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \ 16901 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) ) 16902 16903 #define OACC_PARALLEL_CLAUSE_MASK \ 16904 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \ 16905 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \ 16906 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \ 16907 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \ 16908 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \ 16909 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \ 16910 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \ 16911 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \ 16912 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \ 16913 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \ 16914 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \ 16915 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \ 16916 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \ 16917 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \ 16918 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \ 16919 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \ 16920 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \ 16921 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) ) 16922 16923 #define OACC_SERIAL_CLAUSE_MASK \ 16924 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \ 16925 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \ 16926 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \ 16927 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \ 16928 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \ 16929 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \ 16930 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \ 16931 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \ 16932 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \ 16933 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \ 16934 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \ 16935 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \ 16936 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \ 16937 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \ 16938 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) ) 16939 16940 static tree 16941 c_parser_oacc_compute (location_t loc, c_parser *parser, 16942 enum pragma_kind p_kind, char *p_name, bool *if_p) 16943 { 16944 omp_clause_mask mask; 16945 enum tree_code code; 16946 switch (p_kind) 16947 { 16948 case PRAGMA_OACC_KERNELS: 16949 strcat (p_name, " kernels"); 16950 mask = OACC_KERNELS_CLAUSE_MASK; 16951 code = OACC_KERNELS; 16952 break; 16953 case PRAGMA_OACC_PARALLEL: 16954 strcat (p_name, " parallel"); 16955 mask = OACC_PARALLEL_CLAUSE_MASK; 16956 code = OACC_PARALLEL; 16957 break; 16958 case PRAGMA_OACC_SERIAL: 16959 strcat (p_name, " serial"); 16960 mask = OACC_SERIAL_CLAUSE_MASK; 16961 code = OACC_SERIAL; 16962 break; 16963 default: 16964 gcc_unreachable (); 16965 } 16966 16967 if (c_parser_next_token_is (parser, CPP_NAME)) 16968 { 16969 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 16970 if (strcmp (p, "loop") == 0) 16971 { 16972 c_parser_consume_token (parser); 16973 tree block = c_begin_omp_parallel (); 16974 tree clauses; 16975 c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p); 16976 return c_finish_omp_construct (loc, code, block, clauses); 16977 } 16978 } 16979 16980 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name); 16981 16982 tree block = c_begin_omp_parallel (); 16983 add_stmt (c_parser_omp_structured_block (parser, if_p)); 16984 16985 return c_finish_omp_construct (loc, code, block, clauses); 16986 } 16987 16988 /* OpenACC 2.0: 16989 # pragma acc routine oacc-routine-clause[optseq] new-line 16990 function-definition 16991 16992 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line 16993 */ 16994 16995 #define OACC_ROUTINE_CLAUSE_MASK \ 16996 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \ 16997 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \ 16998 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \ 16999 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) ) 17000 17001 /* Parse an OpenACC routine directive. For named directives, we apply 17002 immediately to the named function. For unnamed ones we then parse 17003 a declaration or definition, which must be for a function. */ 17004 17005 static void 17006 c_parser_oacc_routine (c_parser *parser, enum pragma_context context) 17007 { 17008 gcc_checking_assert (context == pragma_external); 17009 17010 oacc_routine_data data; 17011 data.error_seen = false; 17012 data.fndecl_seen = false; 17013 data.loc = c_parser_peek_token (parser)->location; 17014 17015 c_parser_consume_pragma (parser); 17016 17017 /* Look for optional '( name )'. */ 17018 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 17019 { 17020 c_parser_consume_token (parser); /* '(' */ 17021 17022 tree decl = NULL_TREE; 17023 c_token *name_token = c_parser_peek_token (parser); 17024 location_t name_loc = name_token->location; 17025 if (name_token->type == CPP_NAME 17026 && (name_token->id_kind == C_ID_ID 17027 || name_token->id_kind == C_ID_TYPENAME)) 17028 { 17029 decl = lookup_name (name_token->value); 17030 if (!decl) 17031 error_at (name_loc, 17032 "%qE has not been declared", name_token->value); 17033 c_parser_consume_token (parser); 17034 } 17035 else 17036 c_parser_error (parser, "expected function name"); 17037 17038 if (!decl 17039 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) 17040 { 17041 c_parser_skip_to_pragma_eol (parser, false); 17042 return; 17043 } 17044 17045 data.clauses 17046 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK, 17047 "#pragma acc routine"); 17048 /* The clauses are in reverse order; fix that to make later diagnostic 17049 emission easier. */ 17050 data.clauses = nreverse (data.clauses); 17051 17052 if (TREE_CODE (decl) != FUNCTION_DECL) 17053 { 17054 error_at (name_loc, "%qD does not refer to a function", decl); 17055 return; 17056 } 17057 17058 c_finish_oacc_routine (&data, decl, false); 17059 } 17060 else /* No optional '( name )'. */ 17061 { 17062 data.clauses 17063 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK, 17064 "#pragma acc routine"); 17065 /* The clauses are in reverse order; fix that to make later diagnostic 17066 emission easier. */ 17067 data.clauses = nreverse (data.clauses); 17068 17069 /* Emit a helpful diagnostic if there's another pragma following this 17070 one. Also don't allow a static assertion declaration, as in the 17071 following we'll just parse a *single* "declaration or function 17072 definition", and the static assertion counts an one. */ 17073 if (c_parser_next_token_is (parser, CPP_PRAGMA) 17074 || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT)) 17075 { 17076 error_at (data.loc, 17077 "%<#pragma acc routine%> not immediately followed by" 17078 " function declaration or definition"); 17079 /* ..., and then just keep going. */ 17080 return; 17081 } 17082 17083 /* We only have to consider the pragma_external case here. */ 17084 if (c_parser_next_token_is (parser, CPP_KEYWORD) 17085 && c_parser_peek_token (parser)->keyword == RID_EXTENSION) 17086 { 17087 int ext = disable_extension_diagnostics (); 17088 do 17089 c_parser_consume_token (parser); 17090 while (c_parser_next_token_is (parser, CPP_KEYWORD) 17091 && c_parser_peek_token (parser)->keyword == RID_EXTENSION); 17092 c_parser_declaration_or_fndef (parser, true, true, true, false, true, 17093 NULL, vNULL, false, NULL, &data); 17094 restore_extension_diagnostics (ext); 17095 } 17096 else 17097 c_parser_declaration_or_fndef (parser, true, true, true, false, true, 17098 NULL, vNULL, false, NULL, &data); 17099 } 17100 } 17101 17102 /* Finalize an OpenACC routine pragma, applying it to FNDECL. 17103 IS_DEFN is true if we're applying it to the definition. */ 17104 17105 static void 17106 c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl, 17107 bool is_defn) 17108 { 17109 /* Keep going if we're in error reporting mode. */ 17110 if (data->error_seen 17111 || fndecl == error_mark_node) 17112 return; 17113 17114 if (data->fndecl_seen) 17115 { 17116 error_at (data->loc, 17117 "%<#pragma acc routine%> not immediately followed by" 17118 " a single function declaration or definition"); 17119 data->error_seen = true; 17120 return; 17121 } 17122 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL) 17123 { 17124 error_at (data->loc, 17125 "%<#pragma acc routine%> not immediately followed by" 17126 " function declaration or definition"); 17127 data->error_seen = true; 17128 return; 17129 } 17130 17131 int compatible 17132 = oacc_verify_routine_clauses (fndecl, &data->clauses, data->loc, 17133 "#pragma acc routine"); 17134 if (compatible < 0) 17135 { 17136 data->error_seen = true; 17137 return; 17138 } 17139 if (compatible > 0) 17140 { 17141 } 17142 else 17143 { 17144 if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl))) 17145 { 17146 error_at (data->loc, 17147 TREE_USED (fndecl) 17148 ? G_("%<#pragma acc routine%> must be applied before use") 17149 : G_("%<#pragma acc routine%> must be applied before" 17150 " definition")); 17151 data->error_seen = true; 17152 return; 17153 } 17154 17155 /* Set the routine's level of parallelism. */ 17156 tree dims = oacc_build_routine_dims (data->clauses); 17157 oacc_replace_fn_attrib (fndecl, dims); 17158 17159 /* Add an "omp declare target" attribute. */ 17160 DECL_ATTRIBUTES (fndecl) 17161 = tree_cons (get_identifier ("omp declare target"), 17162 data->clauses, DECL_ATTRIBUTES (fndecl)); 17163 } 17164 17165 /* Remember that we've used this "#pragma acc routine". */ 17166 data->fndecl_seen = true; 17167 } 17168 17169 /* OpenACC 2.0: 17170 # pragma acc update oacc-update-clause[optseq] new-line 17171 */ 17172 17173 #define OACC_UPDATE_CLAUSE_MASK \ 17174 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \ 17175 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \ 17176 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \ 17177 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \ 17178 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \ 17179 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) ) 17180 17181 static void 17182 c_parser_oacc_update (c_parser *parser) 17183 { 17184 location_t loc = c_parser_peek_token (parser)->location; 17185 17186 c_parser_consume_pragma (parser); 17187 17188 tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK, 17189 "#pragma acc update"); 17190 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE) 17191 { 17192 error_at (loc, 17193 "%<#pragma acc update%> must contain at least one " 17194 "%<device%> or %<host%> or %<self%> clause"); 17195 return; 17196 } 17197 17198 if (parser->error) 17199 return; 17200 17201 tree stmt = make_node (OACC_UPDATE); 17202 TREE_TYPE (stmt) = void_type_node; 17203 OACC_UPDATE_CLAUSES (stmt) = clauses; 17204 SET_EXPR_LOCATION (stmt, loc); 17205 add_stmt (stmt); 17206 } 17207 17208 /* OpenACC 2.0: 17209 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line 17210 17211 LOC is the location of the #pragma token. 17212 */ 17213 17214 #define OACC_WAIT_CLAUSE_MASK \ 17215 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) ) 17216 17217 static tree 17218 c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name) 17219 { 17220 tree clauses, list = NULL_TREE, stmt = NULL_TREE; 17221 17222 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN) 17223 list = c_parser_oacc_wait_list (parser, loc, list); 17224 17225 strcpy (p_name, " wait"); 17226 clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name); 17227 stmt = c_finish_oacc_wait (loc, list, clauses); 17228 add_stmt (stmt); 17229 17230 return stmt; 17231 } 17232 17233 /* OpenMP 2.5: 17234 # pragma omp atomic new-line 17235 expression-stmt 17236 17237 expression-stmt: 17238 x binop= expr | x++ | ++x | x-- | --x 17239 binop: 17240 +, *, -, /, &, ^, |, <<, >> 17241 17242 where x is an lvalue expression with scalar type. 17243 17244 OpenMP 3.1: 17245 # pragma omp atomic new-line 17246 update-stmt 17247 17248 # pragma omp atomic read new-line 17249 read-stmt 17250 17251 # pragma omp atomic write new-line 17252 write-stmt 17253 17254 # pragma omp atomic update new-line 17255 update-stmt 17256 17257 # pragma omp atomic capture new-line 17258 capture-stmt 17259 17260 # pragma omp atomic capture new-line 17261 capture-block 17262 17263 read-stmt: 17264 v = x 17265 write-stmt: 17266 x = expr 17267 update-stmt: 17268 expression-stmt | x = x binop expr 17269 capture-stmt: 17270 v = expression-stmt 17271 capture-block: 17272 { v = x; update-stmt; } | { update-stmt; v = x; } 17273 17274 OpenMP 4.0: 17275 update-stmt: 17276 expression-stmt | x = x binop expr | x = expr binop x 17277 capture-stmt: 17278 v = update-stmt 17279 capture-block: 17280 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; } 17281 17282 where x and v are lvalue expressions with scalar type. 17283 17284 LOC is the location of the #pragma token. */ 17285 17286 static void 17287 c_parser_omp_atomic (location_t loc, c_parser *parser) 17288 { 17289 tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE; 17290 tree lhs1 = NULL_TREE, rhs1 = NULL_TREE; 17291 tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE; 17292 enum tree_code code = ERROR_MARK, opcode = NOP_EXPR; 17293 enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED; 17294 struct c_expr expr; 17295 location_t eloc; 17296 bool structured_block = false; 17297 bool swapped = false; 17298 bool non_lvalue_p; 17299 bool first = true; 17300 tree clauses = NULL_TREE; 17301 17302 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 17303 { 17304 if (!first && c_parser_next_token_is (parser, CPP_COMMA)) 17305 c_parser_consume_token (parser); 17306 17307 first = false; 17308 17309 if (c_parser_next_token_is (parser, CPP_NAME)) 17310 { 17311 const char *p 17312 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 17313 location_t cloc = c_parser_peek_token (parser)->location; 17314 enum tree_code new_code = ERROR_MARK; 17315 enum omp_memory_order new_memory_order 17316 = OMP_MEMORY_ORDER_UNSPECIFIED; 17317 17318 if (!strcmp (p, "read")) 17319 new_code = OMP_ATOMIC_READ; 17320 else if (!strcmp (p, "write")) 17321 new_code = NOP_EXPR; 17322 else if (!strcmp (p, "update")) 17323 new_code = OMP_ATOMIC; 17324 else if (!strcmp (p, "capture")) 17325 new_code = OMP_ATOMIC_CAPTURE_NEW; 17326 else if (!strcmp (p, "seq_cst")) 17327 new_memory_order = OMP_MEMORY_ORDER_SEQ_CST; 17328 else if (!strcmp (p, "acq_rel")) 17329 new_memory_order = OMP_MEMORY_ORDER_ACQ_REL; 17330 else if (!strcmp (p, "release")) 17331 new_memory_order = OMP_MEMORY_ORDER_RELEASE; 17332 else if (!strcmp (p, "acquire")) 17333 new_memory_order = OMP_MEMORY_ORDER_ACQUIRE; 17334 else if (!strcmp (p, "relaxed")) 17335 new_memory_order = OMP_MEMORY_ORDER_RELAXED; 17336 else if (!strcmp (p, "hint")) 17337 { 17338 c_parser_consume_token (parser); 17339 clauses = c_parser_omp_clause_hint (parser, clauses); 17340 continue; 17341 } 17342 else 17343 { 17344 p = NULL; 17345 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, " 17346 "%<capture%>, %<seq_cst%>, %<acq_rel%>, " 17347 "%<release%>, %<relaxed%> or %<hint%> clause"); 17348 } 17349 if (p) 17350 { 17351 if (new_code != ERROR_MARK) 17352 { 17353 if (code != ERROR_MARK) 17354 error_at (cloc, "too many atomic clauses"); 17355 else 17356 code = new_code; 17357 } 17358 else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED) 17359 { 17360 if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED) 17361 error_at (cloc, "too many memory order clauses"); 17362 else 17363 memory_order = new_memory_order; 17364 } 17365 c_parser_consume_token (parser); 17366 continue; 17367 } 17368 } 17369 break; 17370 } 17371 c_parser_skip_to_pragma_eol (parser); 17372 17373 if (code == ERROR_MARK) 17374 code = OMP_ATOMIC; 17375 if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED) 17376 { 17377 omp_requires_mask 17378 = (enum omp_requires) (omp_requires_mask 17379 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED); 17380 switch ((enum omp_memory_order) 17381 (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER)) 17382 { 17383 case OMP_MEMORY_ORDER_UNSPECIFIED: 17384 case OMP_MEMORY_ORDER_RELAXED: 17385 memory_order = OMP_MEMORY_ORDER_RELAXED; 17386 break; 17387 case OMP_MEMORY_ORDER_SEQ_CST: 17388 memory_order = OMP_MEMORY_ORDER_SEQ_CST; 17389 break; 17390 case OMP_MEMORY_ORDER_ACQ_REL: 17391 switch (code) 17392 { 17393 case OMP_ATOMIC_READ: 17394 memory_order = OMP_MEMORY_ORDER_ACQUIRE; 17395 break; 17396 case NOP_EXPR: /* atomic write */ 17397 case OMP_ATOMIC: 17398 memory_order = OMP_MEMORY_ORDER_RELEASE; 17399 break; 17400 default: 17401 memory_order = OMP_MEMORY_ORDER_ACQ_REL; 17402 break; 17403 } 17404 break; 17405 default: 17406 gcc_unreachable (); 17407 } 17408 } 17409 else 17410 switch (code) 17411 { 17412 case OMP_ATOMIC_READ: 17413 if (memory_order == OMP_MEMORY_ORDER_ACQ_REL 17414 || memory_order == OMP_MEMORY_ORDER_RELEASE) 17415 { 17416 error_at (loc, "%<#pragma omp atomic read%> incompatible with " 17417 "%<acq_rel%> or %<release%> clauses"); 17418 memory_order = OMP_MEMORY_ORDER_SEQ_CST; 17419 } 17420 break; 17421 case NOP_EXPR: /* atomic write */ 17422 if (memory_order == OMP_MEMORY_ORDER_ACQ_REL 17423 || memory_order == OMP_MEMORY_ORDER_ACQUIRE) 17424 { 17425 error_at (loc, "%<#pragma omp atomic write%> incompatible with " 17426 "%<acq_rel%> or %<acquire%> clauses"); 17427 memory_order = OMP_MEMORY_ORDER_SEQ_CST; 17428 } 17429 break; 17430 case OMP_ATOMIC: 17431 if (memory_order == OMP_MEMORY_ORDER_ACQ_REL 17432 || memory_order == OMP_MEMORY_ORDER_ACQUIRE) 17433 { 17434 error_at (loc, "%<#pragma omp atomic update%> incompatible with " 17435 "%<acq_rel%> or %<acquire%> clauses"); 17436 memory_order = OMP_MEMORY_ORDER_SEQ_CST; 17437 } 17438 break; 17439 default: 17440 break; 17441 } 17442 17443 switch (code) 17444 { 17445 case OMP_ATOMIC_READ: 17446 case NOP_EXPR: /* atomic write */ 17447 v = c_parser_cast_expression (parser, NULL).value; 17448 non_lvalue_p = !lvalue_p (v); 17449 v = c_fully_fold (v, false, NULL, true); 17450 if (v == error_mark_node) 17451 goto saw_error; 17452 if (non_lvalue_p) 17453 v = non_lvalue (v); 17454 loc = c_parser_peek_token (parser)->location; 17455 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) 17456 goto saw_error; 17457 if (code == NOP_EXPR) 17458 { 17459 lhs = c_parser_expression (parser).value; 17460 lhs = c_fully_fold (lhs, false, NULL); 17461 if (lhs == error_mark_node) 17462 goto saw_error; 17463 } 17464 else 17465 { 17466 lhs = c_parser_cast_expression (parser, NULL).value; 17467 non_lvalue_p = !lvalue_p (lhs); 17468 lhs = c_fully_fold (lhs, false, NULL, true); 17469 if (lhs == error_mark_node) 17470 goto saw_error; 17471 if (non_lvalue_p) 17472 lhs = non_lvalue (lhs); 17473 } 17474 if (code == NOP_EXPR) 17475 { 17476 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR 17477 opcode. */ 17478 code = OMP_ATOMIC; 17479 rhs = lhs; 17480 lhs = v; 17481 v = NULL_TREE; 17482 } 17483 goto done; 17484 case OMP_ATOMIC_CAPTURE_NEW: 17485 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 17486 { 17487 c_parser_consume_token (parser); 17488 structured_block = true; 17489 } 17490 else 17491 { 17492 v = c_parser_cast_expression (parser, NULL).value; 17493 non_lvalue_p = !lvalue_p (v); 17494 v = c_fully_fold (v, false, NULL, true); 17495 if (v == error_mark_node) 17496 goto saw_error; 17497 if (non_lvalue_p) 17498 v = non_lvalue (v); 17499 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) 17500 goto saw_error; 17501 } 17502 break; 17503 default: 17504 break; 17505 } 17506 17507 /* For structured_block case we don't know yet whether 17508 old or new x should be captured. */ 17509 restart: 17510 eloc = c_parser_peek_token (parser)->location; 17511 expr = c_parser_cast_expression (parser, NULL); 17512 lhs = expr.value; 17513 expr = default_function_array_conversion (eloc, expr); 17514 unfolded_lhs = expr.value; 17515 lhs = c_fully_fold (lhs, false, NULL, true); 17516 orig_lhs = lhs; 17517 switch (TREE_CODE (lhs)) 17518 { 17519 case ERROR_MARK: 17520 saw_error: 17521 c_parser_skip_to_end_of_block_or_statement (parser); 17522 if (structured_block) 17523 { 17524 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 17525 c_parser_consume_token (parser); 17526 else if (code == OMP_ATOMIC_CAPTURE_NEW) 17527 { 17528 c_parser_skip_to_end_of_block_or_statement (parser); 17529 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 17530 c_parser_consume_token (parser); 17531 } 17532 } 17533 return; 17534 17535 case POSTINCREMENT_EXPR: 17536 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block) 17537 code = OMP_ATOMIC_CAPTURE_OLD; 17538 /* FALLTHROUGH */ 17539 case PREINCREMENT_EXPR: 17540 lhs = TREE_OPERAND (lhs, 0); 17541 unfolded_lhs = NULL_TREE; 17542 opcode = PLUS_EXPR; 17543 rhs = integer_one_node; 17544 break; 17545 17546 case POSTDECREMENT_EXPR: 17547 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block) 17548 code = OMP_ATOMIC_CAPTURE_OLD; 17549 /* FALLTHROUGH */ 17550 case PREDECREMENT_EXPR: 17551 lhs = TREE_OPERAND (lhs, 0); 17552 unfolded_lhs = NULL_TREE; 17553 opcode = MINUS_EXPR; 17554 rhs = integer_one_node; 17555 break; 17556 17557 case COMPOUND_EXPR: 17558 if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR 17559 && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR 17560 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR 17561 && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0) 17562 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND 17563 (TREE_OPERAND (lhs, 1), 0), 0))) 17564 == BOOLEAN_TYPE) 17565 /* Undo effects of boolean_increment for post {in,de}crement. */ 17566 lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0); 17567 /* FALLTHRU */ 17568 case MODIFY_EXPR: 17569 if (TREE_CODE (lhs) == MODIFY_EXPR 17570 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE) 17571 { 17572 /* Undo effects of boolean_increment. */ 17573 if (integer_onep (TREE_OPERAND (lhs, 1))) 17574 { 17575 /* This is pre or post increment. */ 17576 rhs = TREE_OPERAND (lhs, 1); 17577 lhs = TREE_OPERAND (lhs, 0); 17578 unfolded_lhs = NULL_TREE; 17579 opcode = NOP_EXPR; 17580 if (code == OMP_ATOMIC_CAPTURE_NEW 17581 && !structured_block 17582 && TREE_CODE (orig_lhs) == COMPOUND_EXPR) 17583 code = OMP_ATOMIC_CAPTURE_OLD; 17584 break; 17585 } 17586 if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR 17587 && TREE_OPERAND (lhs, 0) 17588 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) 17589 { 17590 /* This is pre or post decrement. */ 17591 rhs = TREE_OPERAND (lhs, 1); 17592 lhs = TREE_OPERAND (lhs, 0); 17593 unfolded_lhs = NULL_TREE; 17594 opcode = NOP_EXPR; 17595 if (code == OMP_ATOMIC_CAPTURE_NEW 17596 && !structured_block 17597 && TREE_CODE (orig_lhs) == COMPOUND_EXPR) 17598 code = OMP_ATOMIC_CAPTURE_OLD; 17599 break; 17600 } 17601 } 17602 /* FALLTHRU */ 17603 default: 17604 if (!lvalue_p (unfolded_lhs)) 17605 lhs = non_lvalue (lhs); 17606 switch (c_parser_peek_token (parser)->type) 17607 { 17608 case CPP_MULT_EQ: 17609 opcode = MULT_EXPR; 17610 break; 17611 case CPP_DIV_EQ: 17612 opcode = TRUNC_DIV_EXPR; 17613 break; 17614 case CPP_PLUS_EQ: 17615 opcode = PLUS_EXPR; 17616 break; 17617 case CPP_MINUS_EQ: 17618 opcode = MINUS_EXPR; 17619 break; 17620 case CPP_LSHIFT_EQ: 17621 opcode = LSHIFT_EXPR; 17622 break; 17623 case CPP_RSHIFT_EQ: 17624 opcode = RSHIFT_EXPR; 17625 break; 17626 case CPP_AND_EQ: 17627 opcode = BIT_AND_EXPR; 17628 break; 17629 case CPP_OR_EQ: 17630 opcode = BIT_IOR_EXPR; 17631 break; 17632 case CPP_XOR_EQ: 17633 opcode = BIT_XOR_EXPR; 17634 break; 17635 case CPP_EQ: 17636 c_parser_consume_token (parser); 17637 eloc = c_parser_peek_token (parser)->location; 17638 expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs); 17639 rhs1 = expr.value; 17640 switch (TREE_CODE (rhs1)) 17641 { 17642 case MULT_EXPR: 17643 case TRUNC_DIV_EXPR: 17644 case RDIV_EXPR: 17645 case PLUS_EXPR: 17646 case MINUS_EXPR: 17647 case LSHIFT_EXPR: 17648 case RSHIFT_EXPR: 17649 case BIT_AND_EXPR: 17650 case BIT_IOR_EXPR: 17651 case BIT_XOR_EXPR: 17652 if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs)) 17653 { 17654 opcode = TREE_CODE (rhs1); 17655 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL, 17656 true); 17657 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL, 17658 true); 17659 goto stmt_done; 17660 } 17661 if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs)) 17662 { 17663 opcode = TREE_CODE (rhs1); 17664 rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL, 17665 true); 17666 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL, 17667 true); 17668 swapped = !commutative_tree_code (opcode); 17669 goto stmt_done; 17670 } 17671 break; 17672 case ERROR_MARK: 17673 goto saw_error; 17674 default: 17675 break; 17676 } 17677 if (c_parser_peek_token (parser)->type == CPP_SEMICOLON) 17678 { 17679 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW) 17680 { 17681 code = OMP_ATOMIC_CAPTURE_OLD; 17682 v = lhs; 17683 lhs = NULL_TREE; 17684 expr = default_function_array_read_conversion (eloc, expr); 17685 unfolded_lhs1 = expr.value; 17686 lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true); 17687 rhs1 = NULL_TREE; 17688 c_parser_consume_token (parser); 17689 goto restart; 17690 } 17691 if (structured_block) 17692 { 17693 opcode = NOP_EXPR; 17694 expr = default_function_array_read_conversion (eloc, expr); 17695 rhs = c_fully_fold (expr.value, false, NULL, true); 17696 rhs1 = NULL_TREE; 17697 goto stmt_done; 17698 } 17699 } 17700 c_parser_error (parser, "invalid form of %<#pragma omp atomic%>"); 17701 goto saw_error; 17702 default: 17703 c_parser_error (parser, 17704 "invalid operator for %<#pragma omp atomic%>"); 17705 goto saw_error; 17706 } 17707 17708 /* Arrange to pass the location of the assignment operator to 17709 c_finish_omp_atomic. */ 17710 loc = c_parser_peek_token (parser)->location; 17711 c_parser_consume_token (parser); 17712 eloc = c_parser_peek_token (parser)->location; 17713 expr = c_parser_expression (parser); 17714 expr = default_function_array_read_conversion (eloc, expr); 17715 rhs = expr.value; 17716 rhs = c_fully_fold (rhs, false, NULL, true); 17717 break; 17718 } 17719 stmt_done: 17720 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW) 17721 { 17722 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>")) 17723 goto saw_error; 17724 v = c_parser_cast_expression (parser, NULL).value; 17725 non_lvalue_p = !lvalue_p (v); 17726 v = c_fully_fold (v, false, NULL, true); 17727 if (v == error_mark_node) 17728 goto saw_error; 17729 if (non_lvalue_p) 17730 v = non_lvalue (v); 17731 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) 17732 goto saw_error; 17733 eloc = c_parser_peek_token (parser)->location; 17734 expr = c_parser_cast_expression (parser, NULL); 17735 lhs1 = expr.value; 17736 expr = default_function_array_read_conversion (eloc, expr); 17737 unfolded_lhs1 = expr.value; 17738 lhs1 = c_fully_fold (lhs1, false, NULL, true); 17739 if (lhs1 == error_mark_node) 17740 goto saw_error; 17741 if (!lvalue_p (unfolded_lhs1)) 17742 lhs1 = non_lvalue (lhs1); 17743 } 17744 if (structured_block) 17745 { 17746 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 17747 c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"); 17748 } 17749 done: 17750 if (unfolded_lhs && unfolded_lhs1 17751 && !c_tree_equal (unfolded_lhs, unfolded_lhs1)) 17752 { 17753 error ("%<#pragma omp atomic capture%> uses two different " 17754 "expressions for memory"); 17755 stmt = error_mark_node; 17756 } 17757 else 17758 stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1, 17759 swapped, memory_order); 17760 if (stmt != error_mark_node) 17761 add_stmt (stmt); 17762 17763 if (!structured_block) 17764 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 17765 } 17766 17767 17768 /* OpenMP 2.5: 17769 # pragma omp barrier new-line 17770 */ 17771 17772 static void 17773 c_parser_omp_barrier (c_parser *parser) 17774 { 17775 location_t loc = c_parser_peek_token (parser)->location; 17776 c_parser_consume_pragma (parser); 17777 c_parser_skip_to_pragma_eol (parser); 17778 17779 c_finish_omp_barrier (loc); 17780 } 17781 17782 /* OpenMP 2.5: 17783 # pragma omp critical [(name)] new-line 17784 structured-block 17785 17786 OpenMP 4.5: 17787 # pragma omp critical [(name) [hint(expression)]] new-line 17788 17789 LOC is the location of the #pragma itself. */ 17790 17791 #define OMP_CRITICAL_CLAUSE_MASK \ 17792 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) ) 17793 17794 static tree 17795 c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p) 17796 { 17797 tree stmt, name = NULL_TREE, clauses = NULL_TREE; 17798 17799 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 17800 { 17801 c_parser_consume_token (parser); 17802 if (c_parser_next_token_is (parser, CPP_NAME)) 17803 { 17804 name = c_parser_peek_token (parser)->value; 17805 c_parser_consume_token (parser); 17806 c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 17807 } 17808 else 17809 c_parser_error (parser, "expected identifier"); 17810 17811 if (c_parser_next_token_is (parser, CPP_COMMA) 17812 && c_parser_peek_2nd_token (parser)->type == CPP_NAME) 17813 c_parser_consume_token (parser); 17814 17815 clauses = c_parser_omp_all_clauses (parser, 17816 OMP_CRITICAL_CLAUSE_MASK, 17817 "#pragma omp critical"); 17818 } 17819 else 17820 { 17821 if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 17822 c_parser_error (parser, "expected %<(%> or end of line"); 17823 c_parser_skip_to_pragma_eol (parser); 17824 } 17825 17826 stmt = c_parser_omp_structured_block (parser, if_p); 17827 return c_finish_omp_critical (loc, stmt, name, clauses); 17828 } 17829 17830 /* OpenMP 5.0: 17831 # pragma omp depobj ( depobj ) depobj-clause new-line 17832 17833 depobj-clause: 17834 depend (dependence-type : locator) 17835 destroy 17836 update (dependence-type) 17837 17838 dependence-type: 17839 in 17840 out 17841 inout 17842 mutexinout */ 17843 17844 static void 17845 c_parser_omp_depobj (c_parser *parser) 17846 { 17847 location_t loc = c_parser_peek_token (parser)->location; 17848 c_parser_consume_pragma (parser); 17849 matching_parens parens; 17850 if (!parens.require_open (parser)) 17851 { 17852 c_parser_skip_to_pragma_eol (parser); 17853 return; 17854 } 17855 17856 tree depobj = c_parser_expr_no_commas (parser, NULL).value; 17857 if (depobj != error_mark_node) 17858 { 17859 if (!lvalue_p (depobj)) 17860 { 17861 error_at (EXPR_LOC_OR_LOC (depobj, loc), 17862 "%<depobj%> expression is not lvalue expression"); 17863 depobj = error_mark_node; 17864 } 17865 else 17866 { 17867 tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR, 17868 depobj, false); 17869 if (addr == error_mark_node) 17870 depobj = error_mark_node; 17871 else 17872 depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc), 17873 addr, RO_UNARY_STAR); 17874 } 17875 } 17876 17877 parens.skip_until_found_close (parser); 17878 tree clause = NULL_TREE; 17879 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_SOURCE; 17880 location_t c_loc = c_parser_peek_token (parser)->location; 17881 if (c_parser_next_token_is (parser, CPP_NAME)) 17882 { 17883 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 17884 17885 c_parser_consume_token (parser); 17886 if (!strcmp ("depend", p)) 17887 { 17888 clause = c_parser_omp_clause_depend (parser, NULL_TREE); 17889 clause = c_finish_omp_clauses (clause, C_ORT_OMP); 17890 if (!clause) 17891 clause = error_mark_node; 17892 } 17893 else if (!strcmp ("destroy", p)) 17894 kind = OMP_CLAUSE_DEPEND_LAST; 17895 else if (!strcmp ("update", p)) 17896 { 17897 matching_parens c_parens; 17898 if (c_parens.require_open (parser)) 17899 { 17900 location_t c2_loc = c_parser_peek_token (parser)->location; 17901 if (c_parser_next_token_is (parser, CPP_NAME)) 17902 { 17903 const char *p2 17904 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 17905 17906 c_parser_consume_token (parser); 17907 if (!strcmp ("in", p2)) 17908 kind = OMP_CLAUSE_DEPEND_IN; 17909 else if (!strcmp ("out", p2)) 17910 kind = OMP_CLAUSE_DEPEND_OUT; 17911 else if (!strcmp ("inout", p2)) 17912 kind = OMP_CLAUSE_DEPEND_INOUT; 17913 else if (!strcmp ("mutexinoutset", p2)) 17914 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET; 17915 } 17916 if (kind == OMP_CLAUSE_DEPEND_SOURCE) 17917 { 17918 clause = error_mark_node; 17919 error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%> or " 17920 "%<mutexinoutset%>"); 17921 } 17922 c_parens.skip_until_found_close (parser); 17923 } 17924 else 17925 clause = error_mark_node; 17926 } 17927 } 17928 if (!clause && kind == OMP_CLAUSE_DEPEND_SOURCE) 17929 { 17930 clause = error_mark_node; 17931 error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause"); 17932 } 17933 c_parser_skip_to_pragma_eol (parser); 17934 17935 c_finish_omp_depobj (loc, depobj, kind, clause); 17936 } 17937 17938 17939 /* OpenMP 2.5: 17940 # pragma omp flush flush-vars[opt] new-line 17941 17942 flush-vars: 17943 ( variable-list ) 17944 17945 OpenMP 5.0: 17946 # pragma omp flush memory-order-clause new-line */ 17947 17948 static void 17949 c_parser_omp_flush (c_parser *parser) 17950 { 17951 location_t loc = c_parser_peek_token (parser)->location; 17952 c_parser_consume_pragma (parser); 17953 enum memmodel mo = MEMMODEL_LAST; 17954 if (c_parser_next_token_is (parser, CPP_NAME)) 17955 { 17956 const char *p 17957 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 17958 17959 if (!strcmp (p, "acq_rel")) 17960 mo = MEMMODEL_ACQ_REL; 17961 else if (!strcmp (p, "release")) 17962 mo = MEMMODEL_RELEASE; 17963 else if (!strcmp (p, "acquire")) 17964 mo = MEMMODEL_ACQUIRE; 17965 else 17966 error_at (c_parser_peek_token (parser)->location, 17967 "expected %<acq_rel%>, %<release%> or %<acquire%>"); 17968 c_parser_consume_token (parser); 17969 } 17970 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 17971 { 17972 if (mo != MEMMODEL_LAST) 17973 error_at (c_parser_peek_token (parser)->location, 17974 "%<flush%> list specified together with memory order " 17975 "clause"); 17976 c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL); 17977 } 17978 else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 17979 c_parser_error (parser, "expected %<(%> or end of line"); 17980 c_parser_skip_to_pragma_eol (parser); 17981 17982 c_finish_omp_flush (loc, mo); 17983 } 17984 17985 /* OpenMP 5.0: 17986 17987 scan-loop-body: 17988 { structured-block scan-directive structured-block } */ 17989 17990 static void 17991 c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed) 17992 { 17993 tree substmt; 17994 location_t loc; 17995 tree clauses = NULL_TREE; 17996 17997 loc = c_parser_peek_token (parser)->location; 17998 if (!open_brace_parsed 17999 && !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) 18000 { 18001 /* Avoid skipping until the end of the block. */ 18002 parser->error = false; 18003 return; 18004 } 18005 18006 substmt = c_parser_omp_structured_block (parser, NULL); 18007 substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE); 18008 SET_EXPR_LOCATION (substmt, loc); 18009 add_stmt (substmt); 18010 18011 loc = c_parser_peek_token (parser)->location; 18012 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN) 18013 { 18014 enum omp_clause_code clause = OMP_CLAUSE_ERROR; 18015 18016 c_parser_consume_pragma (parser); 18017 18018 if (c_parser_next_token_is (parser, CPP_NAME)) 18019 { 18020 const char *p 18021 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 18022 if (strcmp (p, "inclusive") == 0) 18023 clause = OMP_CLAUSE_INCLUSIVE; 18024 else if (strcmp (p, "exclusive") == 0) 18025 clause = OMP_CLAUSE_EXCLUSIVE; 18026 } 18027 if (clause != OMP_CLAUSE_ERROR) 18028 { 18029 c_parser_consume_token (parser); 18030 clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE); 18031 } 18032 else 18033 c_parser_error (parser, "expected %<inclusive%> or " 18034 "%<exclusive%> clause"); 18035 c_parser_skip_to_pragma_eol (parser); 18036 } 18037 else 18038 error ("expected %<#pragma omp scan%>"); 18039 18040 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP); 18041 substmt = c_parser_omp_structured_block (parser, NULL); 18042 substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses); 18043 SET_EXPR_LOCATION (substmt, loc); 18044 add_stmt (substmt); 18045 18046 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, 18047 "expected %<}%>"); 18048 } 18049 18050 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP. 18051 The real trick here is to determine the loop control variable early 18052 so that we can push a new decl if necessary to make it private. 18053 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp", 18054 respectively. */ 18055 18056 static tree 18057 c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code, 18058 tree clauses, tree *cclauses, bool *if_p) 18059 { 18060 tree decl, cond, incr, save_break, save_cont, body, init, stmt, cl; 18061 tree declv, condv, incrv, initv, ret = NULL_TREE; 18062 tree pre_body = NULL_TREE, this_pre_body; 18063 tree ordered_cl = NULL_TREE; 18064 bool fail = false, open_brace_parsed = false; 18065 int i, collapse = 1, ordered = 0, count, nbraces = 0; 18066 location_t for_loc; 18067 bool tiling = false; 18068 bool inscan = false; 18069 vec<tree, va_gc> *for_block = make_tree_vector (); 18070 18071 for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl)) 18072 if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE) 18073 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl)); 18074 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE) 18075 { 18076 tiling = true; 18077 collapse = list_length (OMP_CLAUSE_TILE_LIST (cl)); 18078 } 18079 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED 18080 && OMP_CLAUSE_ORDERED_EXPR (cl)) 18081 { 18082 ordered_cl = cl; 18083 ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl)); 18084 } 18085 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION 18086 && OMP_CLAUSE_REDUCTION_INSCAN (cl) 18087 && (code == OMP_SIMD || code == OMP_FOR)) 18088 inscan = true; 18089 18090 if (ordered && ordered < collapse) 18091 { 18092 error_at (OMP_CLAUSE_LOCATION (ordered_cl), 18093 "%<ordered%> clause parameter is less than %<collapse%>"); 18094 OMP_CLAUSE_ORDERED_EXPR (ordered_cl) 18095 = build_int_cst (NULL_TREE, collapse); 18096 ordered = collapse; 18097 } 18098 if (ordered) 18099 { 18100 for (tree *pc = &clauses; *pc; ) 18101 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR) 18102 { 18103 error_at (OMP_CLAUSE_LOCATION (*pc), 18104 "%<linear%> clause may not be specified together " 18105 "with %<ordered%> clause with a parameter"); 18106 *pc = OMP_CLAUSE_CHAIN (*pc); 18107 } 18108 else 18109 pc = &OMP_CLAUSE_CHAIN (*pc); 18110 } 18111 18112 gcc_assert (tiling || (collapse >= 1 && ordered >= 0)); 18113 count = ordered ? ordered : collapse; 18114 18115 declv = make_tree_vec (count); 18116 initv = make_tree_vec (count); 18117 condv = make_tree_vec (count); 18118 incrv = make_tree_vec (count); 18119 18120 if (!c_parser_next_token_is_keyword (parser, RID_FOR)) 18121 { 18122 c_parser_error (parser, "for statement expected"); 18123 return NULL; 18124 } 18125 for_loc = c_parser_peek_token (parser)->location; 18126 c_parser_consume_token (parser); 18127 18128 for (i = 0; i < count; i++) 18129 { 18130 int bracecount = 0; 18131 18132 matching_parens parens; 18133 if (!parens.require_open (parser)) 18134 goto pop_scopes; 18135 18136 /* Parse the initialization declaration or expression. */ 18137 if (c_parser_next_tokens_start_declaration (parser)) 18138 { 18139 if (i > 0) 18140 vec_safe_push (for_block, c_begin_compound_stmt (true)); 18141 this_pre_body = push_stmt_list (); 18142 c_parser_declaration_or_fndef (parser, true, true, true, true, true, 18143 NULL, vNULL); 18144 if (this_pre_body) 18145 { 18146 this_pre_body = pop_stmt_list (this_pre_body); 18147 if (pre_body) 18148 { 18149 tree t = pre_body; 18150 pre_body = push_stmt_list (); 18151 add_stmt (t); 18152 add_stmt (this_pre_body); 18153 pre_body = pop_stmt_list (pre_body); 18154 } 18155 else 18156 pre_body = this_pre_body; 18157 } 18158 decl = check_for_loop_decls (for_loc, flag_isoc99); 18159 if (decl == NULL) 18160 goto error_init; 18161 if (DECL_INITIAL (decl) == error_mark_node) 18162 decl = error_mark_node; 18163 init = decl; 18164 } 18165 else if (c_parser_next_token_is (parser, CPP_NAME) 18166 && c_parser_peek_2nd_token (parser)->type == CPP_EQ) 18167 { 18168 struct c_expr decl_exp; 18169 struct c_expr init_exp; 18170 location_t init_loc; 18171 18172 decl_exp = c_parser_postfix_expression (parser); 18173 decl = decl_exp.value; 18174 18175 c_parser_require (parser, CPP_EQ, "expected %<=%>"); 18176 18177 init_loc = c_parser_peek_token (parser)->location; 18178 init_exp = c_parser_expr_no_commas (parser, NULL); 18179 init_exp = default_function_array_read_conversion (init_loc, 18180 init_exp); 18181 init = build_modify_expr (init_loc, decl, decl_exp.original_type, 18182 NOP_EXPR, init_loc, init_exp.value, 18183 init_exp.original_type); 18184 init = c_process_expr_stmt (init_loc, init); 18185 18186 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 18187 } 18188 else 18189 { 18190 error_init: 18191 c_parser_error (parser, 18192 "expected iteration declaration or initialization"); 18193 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 18194 "expected %<)%>"); 18195 fail = true; 18196 goto parse_next; 18197 } 18198 18199 /* Parse the loop condition. */ 18200 cond = NULL_TREE; 18201 if (c_parser_next_token_is_not (parser, CPP_SEMICOLON)) 18202 { 18203 location_t cond_loc = c_parser_peek_token (parser)->location; 18204 struct c_expr cond_expr 18205 = c_parser_binary_expression (parser, NULL, NULL_TREE); 18206 18207 cond = cond_expr.value; 18208 cond = c_objc_common_truthvalue_conversion (cond_loc, cond); 18209 if (COMPARISON_CLASS_P (cond)) 18210 { 18211 tree op0 = TREE_OPERAND (cond, 0), op1 = TREE_OPERAND (cond, 1); 18212 op0 = c_fully_fold (op0, false, NULL); 18213 op1 = c_fully_fold (op1, false, NULL); 18214 TREE_OPERAND (cond, 0) = op0; 18215 TREE_OPERAND (cond, 1) = op1; 18216 } 18217 switch (cond_expr.original_code) 18218 { 18219 case GT_EXPR: 18220 case GE_EXPR: 18221 case LT_EXPR: 18222 case LE_EXPR: 18223 break; 18224 case NE_EXPR: 18225 if (code != OACC_LOOP) 18226 break; 18227 /* FALLTHRU. */ 18228 default: 18229 /* Can't be cond = error_mark_node, because we want to preserve 18230 the location until c_finish_omp_for. */ 18231 cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node); 18232 break; 18233 } 18234 protected_set_expr_location (cond, cond_loc); 18235 } 18236 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 18237 18238 /* Parse the increment expression. */ 18239 incr = NULL_TREE; 18240 if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN)) 18241 { 18242 location_t incr_loc = c_parser_peek_token (parser)->location; 18243 18244 incr = c_process_expr_stmt (incr_loc, 18245 c_parser_expression (parser).value); 18246 } 18247 parens.skip_until_found_close (parser); 18248 18249 if (decl == NULL || decl == error_mark_node || init == error_mark_node) 18250 fail = true; 18251 else 18252 { 18253 TREE_VEC_ELT (declv, i) = decl; 18254 TREE_VEC_ELT (initv, i) = init; 18255 TREE_VEC_ELT (condv, i) = cond; 18256 TREE_VEC_ELT (incrv, i) = incr; 18257 } 18258 18259 parse_next: 18260 if (i == count - 1) 18261 break; 18262 18263 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed 18264 in between the collapsed for loops to be still considered perfectly 18265 nested. Hopefully the final version clarifies this. 18266 For now handle (multiple) {'s and empty statements. */ 18267 do 18268 { 18269 if (c_parser_next_token_is_keyword (parser, RID_FOR)) 18270 { 18271 c_parser_consume_token (parser); 18272 break; 18273 } 18274 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 18275 { 18276 c_parser_consume_token (parser); 18277 bracecount++; 18278 } 18279 else if (bracecount 18280 && c_parser_next_token_is (parser, CPP_SEMICOLON)) 18281 c_parser_consume_token (parser); 18282 else 18283 { 18284 c_parser_error (parser, "not enough perfectly nested loops"); 18285 if (bracecount) 18286 { 18287 open_brace_parsed = true; 18288 bracecount--; 18289 } 18290 fail = true; 18291 count = 0; 18292 break; 18293 } 18294 } 18295 while (1); 18296 18297 nbraces += bracecount; 18298 } 18299 18300 if (nbraces) 18301 if_p = NULL; 18302 18303 save_break = c_break_label; 18304 c_break_label = size_one_node; 18305 save_cont = c_cont_label; 18306 c_cont_label = NULL_TREE; 18307 body = push_stmt_list (); 18308 18309 if (inscan) 18310 c_parser_omp_scan_loop_body (parser, open_brace_parsed); 18311 else if (open_brace_parsed) 18312 { 18313 location_t here = c_parser_peek_token (parser)->location; 18314 stmt = c_begin_compound_stmt (true); 18315 c_parser_compound_statement_nostart (parser); 18316 add_stmt (c_end_compound_stmt (here, stmt, true)); 18317 } 18318 else 18319 add_stmt (c_parser_c99_block_statement (parser, if_p)); 18320 if (c_cont_label) 18321 { 18322 tree t = build1 (LABEL_EXPR, void_type_node, c_cont_label); 18323 SET_EXPR_LOCATION (t, loc); 18324 add_stmt (t); 18325 } 18326 18327 body = pop_stmt_list (body); 18328 c_break_label = save_break; 18329 c_cont_label = save_cont; 18330 18331 while (nbraces) 18332 { 18333 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 18334 { 18335 c_parser_consume_token (parser); 18336 nbraces--; 18337 } 18338 else if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 18339 c_parser_consume_token (parser); 18340 else 18341 { 18342 c_parser_error (parser, "collapsed loops not perfectly nested"); 18343 while (nbraces) 18344 { 18345 location_t here = c_parser_peek_token (parser)->location; 18346 stmt = c_begin_compound_stmt (true); 18347 add_stmt (body); 18348 c_parser_compound_statement_nostart (parser); 18349 body = c_end_compound_stmt (here, stmt, true); 18350 nbraces--; 18351 } 18352 goto pop_scopes; 18353 } 18354 } 18355 18356 /* Only bother calling c_finish_omp_for if we haven't already generated 18357 an error from the initialization parsing. */ 18358 if (!fail) 18359 { 18360 stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv, 18361 incrv, body, pre_body, true); 18362 18363 /* Check for iterators appearing in lb, b or incr expressions. */ 18364 if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL)) 18365 stmt = NULL_TREE; 18366 18367 if (stmt) 18368 { 18369 add_stmt (stmt); 18370 18371 if (cclauses != NULL 18372 && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL) 18373 { 18374 tree *c; 18375 for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; ) 18376 if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE 18377 && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE) 18378 c = &OMP_CLAUSE_CHAIN (*c); 18379 else 18380 { 18381 for (i = 0; i < count; i++) 18382 if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c)) 18383 break; 18384 if (i == count) 18385 c = &OMP_CLAUSE_CHAIN (*c); 18386 else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE) 18387 { 18388 error_at (loc, 18389 "iteration variable %qD should not be firstprivate", 18390 OMP_CLAUSE_DECL (*c)); 18391 *c = OMP_CLAUSE_CHAIN (*c); 18392 } 18393 else 18394 { 18395 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */ 18396 tree l = *c; 18397 *c = OMP_CLAUSE_CHAIN (*c); 18398 if (code == OMP_SIMD) 18399 { 18400 OMP_CLAUSE_CHAIN (l) 18401 = cclauses[C_OMP_CLAUSE_SPLIT_FOR]; 18402 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l; 18403 } 18404 else 18405 { 18406 OMP_CLAUSE_CHAIN (l) = clauses; 18407 clauses = l; 18408 } 18409 } 18410 } 18411 } 18412 OMP_FOR_CLAUSES (stmt) = clauses; 18413 } 18414 ret = stmt; 18415 } 18416 pop_scopes: 18417 while (!for_block->is_empty ()) 18418 { 18419 /* FIXME diagnostics: LOC below should be the actual location of 18420 this particular for block. We need to build a list of 18421 locations to go along with FOR_BLOCK. */ 18422 stmt = c_end_compound_stmt (loc, for_block->pop (), true); 18423 add_stmt (stmt); 18424 } 18425 release_tree_vector (for_block); 18426 return ret; 18427 } 18428 18429 /* Helper function for OpenMP parsing, split clauses and call 18430 finish_omp_clauses on each of the set of clauses afterwards. */ 18431 18432 static void 18433 omp_split_clauses (location_t loc, enum tree_code code, 18434 omp_clause_mask mask, tree clauses, tree *cclauses) 18435 { 18436 int i; 18437 c_omp_split_clauses (loc, code, mask, clauses, cclauses); 18438 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++) 18439 if (cclauses[i]) 18440 cclauses[i] = c_finish_omp_clauses (cclauses[i], C_ORT_OMP); 18441 } 18442 18443 /* OpenMP 5.0: 18444 #pragma omp loop loop-clause[optseq] new-line 18445 for-loop 18446 18447 LOC is the location of the #pragma token. 18448 */ 18449 18450 #define OMP_LOOP_CLAUSE_MASK \ 18451 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 18452 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ 18453 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ 18454 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \ 18455 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \ 18456 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER)) 18457 18458 static tree 18459 c_parser_omp_loop (location_t loc, c_parser *parser, 18460 char *p_name, omp_clause_mask mask, tree *cclauses, 18461 bool *if_p) 18462 { 18463 tree block, clauses, ret; 18464 18465 strcat (p_name, " loop"); 18466 mask |= OMP_LOOP_CLAUSE_MASK; 18467 18468 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); 18469 if (cclauses) 18470 { 18471 omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses); 18472 clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP]; 18473 } 18474 18475 block = c_begin_compound_stmt (true); 18476 ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p); 18477 block = c_end_compound_stmt (loc, block, true); 18478 add_stmt (block); 18479 18480 return ret; 18481 } 18482 18483 /* OpenMP 4.0: 18484 #pragma omp simd simd-clause[optseq] new-line 18485 for-loop 18486 18487 LOC is the location of the #pragma token. 18488 */ 18489 18490 #define OMP_SIMD_CLAUSE_MASK \ 18491 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \ 18492 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \ 18493 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \ 18494 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \ 18495 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 18496 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ 18497 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ 18498 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \ 18499 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 18500 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \ 18501 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER)) 18502 18503 static tree 18504 c_parser_omp_simd (location_t loc, c_parser *parser, 18505 char *p_name, omp_clause_mask mask, tree *cclauses, 18506 bool *if_p) 18507 { 18508 tree block, clauses, ret; 18509 18510 strcat (p_name, " simd"); 18511 mask |= OMP_SIMD_CLAUSE_MASK; 18512 18513 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); 18514 if (cclauses) 18515 { 18516 omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses); 18517 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD]; 18518 tree c = omp_find_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR], 18519 OMP_CLAUSE_ORDERED); 18520 if (c && OMP_CLAUSE_ORDERED_EXPR (c)) 18521 { 18522 error_at (OMP_CLAUSE_LOCATION (c), 18523 "%<ordered%> clause with parameter may not be specified " 18524 "on %qs construct", p_name); 18525 OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE; 18526 } 18527 } 18528 18529 block = c_begin_compound_stmt (true); 18530 ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p); 18531 block = c_end_compound_stmt (loc, block, true); 18532 add_stmt (block); 18533 18534 return ret; 18535 } 18536 18537 /* OpenMP 2.5: 18538 #pragma omp for for-clause[optseq] new-line 18539 for-loop 18540 18541 OpenMP 4.0: 18542 #pragma omp for simd for-simd-clause[optseq] new-line 18543 for-loop 18544 18545 LOC is the location of the #pragma token. 18546 */ 18547 18548 #define OMP_FOR_CLAUSE_MASK \ 18549 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 18550 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 18551 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ 18552 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \ 18553 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ 18554 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \ 18555 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \ 18556 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \ 18557 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \ 18558 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER)) 18559 18560 static tree 18561 c_parser_omp_for (location_t loc, c_parser *parser, 18562 char *p_name, omp_clause_mask mask, tree *cclauses, 18563 bool *if_p) 18564 { 18565 tree block, clauses, ret; 18566 18567 strcat (p_name, " for"); 18568 mask |= OMP_FOR_CLAUSE_MASK; 18569 /* parallel for{, simd} disallows nowait clause, but for 18570 target {teams distribute ,}parallel for{, simd} it should be accepted. */ 18571 if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0) 18572 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT); 18573 /* Composite distribute parallel for{, simd} disallows ordered clause. */ 18574 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0) 18575 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED); 18576 18577 if (c_parser_next_token_is (parser, CPP_NAME)) 18578 { 18579 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 18580 18581 if (strcmp (p, "simd") == 0) 18582 { 18583 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 18584 if (cclauses == NULL) 18585 cclauses = cclauses_buf; 18586 18587 c_parser_consume_token (parser); 18588 if (!flag_openmp) /* flag_openmp_simd */ 18589 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses, 18590 if_p); 18591 block = c_begin_compound_stmt (true); 18592 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p); 18593 block = c_end_compound_stmt (loc, block, true); 18594 if (ret == NULL_TREE) 18595 return ret; 18596 ret = make_node (OMP_FOR); 18597 TREE_TYPE (ret) = void_type_node; 18598 OMP_FOR_BODY (ret) = block; 18599 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR]; 18600 SET_EXPR_LOCATION (ret, loc); 18601 add_stmt (ret); 18602 return ret; 18603 } 18604 } 18605 if (!flag_openmp) /* flag_openmp_simd */ 18606 { 18607 c_parser_skip_to_pragma_eol (parser, false); 18608 return NULL_TREE; 18609 } 18610 18611 /* Composite distribute parallel for disallows linear clause. */ 18612 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0) 18613 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR); 18614 18615 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); 18616 if (cclauses) 18617 { 18618 omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses); 18619 clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR]; 18620 } 18621 18622 block = c_begin_compound_stmt (true); 18623 ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p); 18624 block = c_end_compound_stmt (loc, block, true); 18625 add_stmt (block); 18626 18627 return ret; 18628 } 18629 18630 static tree c_parser_omp_taskloop (location_t, c_parser *, char *, 18631 omp_clause_mask, tree *, bool *); 18632 18633 /* OpenMP 2.5: 18634 # pragma omp master new-line 18635 structured-block 18636 18637 LOC is the location of the #pragma token. 18638 */ 18639 18640 static tree 18641 c_parser_omp_master (location_t loc, c_parser *parser, 18642 char *p_name, omp_clause_mask mask, tree *cclauses, 18643 bool *if_p) 18644 { 18645 tree block, clauses, ret; 18646 18647 strcat (p_name, " master"); 18648 18649 if (c_parser_next_token_is (parser, CPP_NAME)) 18650 { 18651 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 18652 18653 if (strcmp (p, "taskloop") == 0) 18654 { 18655 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 18656 if (cclauses == NULL) 18657 cclauses = cclauses_buf; 18658 18659 c_parser_consume_token (parser); 18660 if (!flag_openmp) /* flag_openmp_simd */ 18661 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses, 18662 if_p); 18663 block = c_begin_compound_stmt (true); 18664 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses, 18665 if_p); 18666 block = c_end_compound_stmt (loc, block, true); 18667 if (ret == NULL_TREE) 18668 return ret; 18669 ret = c_finish_omp_master (loc, block); 18670 return ret; 18671 } 18672 } 18673 if (!flag_openmp) /* flag_openmp_simd */ 18674 { 18675 c_parser_skip_to_pragma_eol (parser, false); 18676 return NULL_TREE; 18677 } 18678 18679 if (cclauses) 18680 { 18681 clauses = c_parser_omp_all_clauses (parser, mask, p_name, false); 18682 omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses); 18683 } 18684 else 18685 c_parser_skip_to_pragma_eol (parser); 18686 18687 return c_finish_omp_master (loc, c_parser_omp_structured_block (parser, 18688 if_p)); 18689 } 18690 18691 /* OpenMP 2.5: 18692 # pragma omp ordered new-line 18693 structured-block 18694 18695 OpenMP 4.5: 18696 # pragma omp ordered ordered-clauses new-line 18697 structured-block 18698 18699 # pragma omp ordered depend-clauses new-line */ 18700 18701 #define OMP_ORDERED_CLAUSE_MASK \ 18702 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \ 18703 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD)) 18704 18705 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \ 18706 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) 18707 18708 static bool 18709 c_parser_omp_ordered (c_parser *parser, enum pragma_context context, 18710 bool *if_p) 18711 { 18712 location_t loc = c_parser_peek_token (parser)->location; 18713 c_parser_consume_pragma (parser); 18714 18715 if (context != pragma_stmt && context != pragma_compound) 18716 { 18717 c_parser_error (parser, "expected declaration specifiers"); 18718 c_parser_skip_to_pragma_eol (parser, false); 18719 return false; 18720 } 18721 18722 if (c_parser_next_token_is (parser, CPP_NAME)) 18723 { 18724 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 18725 18726 if (!strcmp ("depend", p)) 18727 { 18728 if (!flag_openmp) /* flag_openmp_simd */ 18729 { 18730 c_parser_skip_to_pragma_eol (parser, false); 18731 return false; 18732 } 18733 if (context == pragma_stmt) 18734 { 18735 error_at (loc, 18736 "%<#pragma omp ordered%> with %<depend%> clause may " 18737 "only be used in compound statements"); 18738 c_parser_skip_to_pragma_eol (parser, false); 18739 return false; 18740 } 18741 18742 tree clauses 18743 = c_parser_omp_all_clauses (parser, 18744 OMP_ORDERED_DEPEND_CLAUSE_MASK, 18745 "#pragma omp ordered"); 18746 c_finish_omp_ordered (loc, clauses, NULL_TREE); 18747 return false; 18748 } 18749 } 18750 18751 tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK, 18752 "#pragma omp ordered"); 18753 18754 if (!flag_openmp /* flag_openmp_simd */ 18755 && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE) 18756 return false; 18757 18758 c_finish_omp_ordered (loc, clauses, 18759 c_parser_omp_structured_block (parser, if_p)); 18760 return true; 18761 } 18762 18763 /* OpenMP 2.5: 18764 18765 section-scope: 18766 { section-sequence } 18767 18768 section-sequence: 18769 section-directive[opt] structured-block 18770 section-sequence section-directive structured-block 18771 18772 SECTIONS_LOC is the location of the #pragma omp sections. */ 18773 18774 static tree 18775 c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser) 18776 { 18777 tree stmt, substmt; 18778 bool error_suppress = false; 18779 location_t loc; 18780 18781 loc = c_parser_peek_token (parser)->location; 18782 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) 18783 { 18784 /* Avoid skipping until the end of the block. */ 18785 parser->error = false; 18786 return NULL_TREE; 18787 } 18788 18789 stmt = push_stmt_list (); 18790 18791 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION) 18792 { 18793 substmt = c_parser_omp_structured_block (parser, NULL); 18794 substmt = build1 (OMP_SECTION, void_type_node, substmt); 18795 SET_EXPR_LOCATION (substmt, loc); 18796 add_stmt (substmt); 18797 } 18798 18799 while (1) 18800 { 18801 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 18802 break; 18803 if (c_parser_next_token_is (parser, CPP_EOF)) 18804 break; 18805 18806 loc = c_parser_peek_token (parser)->location; 18807 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION) 18808 { 18809 c_parser_consume_pragma (parser); 18810 c_parser_skip_to_pragma_eol (parser); 18811 error_suppress = false; 18812 } 18813 else if (!error_suppress) 18814 { 18815 error_at (loc, "expected %<#pragma omp section%> or %<}%>"); 18816 error_suppress = true; 18817 } 18818 18819 substmt = c_parser_omp_structured_block (parser, NULL); 18820 substmt = build1 (OMP_SECTION, void_type_node, substmt); 18821 SET_EXPR_LOCATION (substmt, loc); 18822 add_stmt (substmt); 18823 } 18824 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, 18825 "expected %<#pragma omp section%> or %<}%>"); 18826 18827 substmt = pop_stmt_list (stmt); 18828 18829 stmt = make_node (OMP_SECTIONS); 18830 SET_EXPR_LOCATION (stmt, sections_loc); 18831 TREE_TYPE (stmt) = void_type_node; 18832 OMP_SECTIONS_BODY (stmt) = substmt; 18833 18834 return add_stmt (stmt); 18835 } 18836 18837 /* OpenMP 2.5: 18838 # pragma omp sections sections-clause[optseq] newline 18839 sections-scope 18840 18841 LOC is the location of the #pragma token. 18842 */ 18843 18844 #define OMP_SECTIONS_CLAUSE_MASK \ 18845 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 18846 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 18847 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ 18848 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ 18849 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)) 18850 18851 static tree 18852 c_parser_omp_sections (location_t loc, c_parser *parser, 18853 char *p_name, omp_clause_mask mask, tree *cclauses) 18854 { 18855 tree block, clauses, ret; 18856 18857 strcat (p_name, " sections"); 18858 mask |= OMP_SECTIONS_CLAUSE_MASK; 18859 if (cclauses) 18860 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT); 18861 18862 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); 18863 if (cclauses) 18864 { 18865 omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses); 18866 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS]; 18867 } 18868 18869 block = c_begin_compound_stmt (true); 18870 ret = c_parser_omp_sections_scope (loc, parser); 18871 if (ret) 18872 OMP_SECTIONS_CLAUSES (ret) = clauses; 18873 block = c_end_compound_stmt (loc, block, true); 18874 add_stmt (block); 18875 18876 return ret; 18877 } 18878 18879 /* OpenMP 2.5: 18880 # pragma omp parallel parallel-clause[optseq] new-line 18881 structured-block 18882 # pragma omp parallel for parallel-for-clause[optseq] new-line 18883 structured-block 18884 # pragma omp parallel sections parallel-sections-clause[optseq] new-line 18885 structured-block 18886 18887 OpenMP 4.0: 18888 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line 18889 structured-block 18890 18891 LOC is the location of the #pragma token. 18892 */ 18893 18894 #define OMP_PARALLEL_CLAUSE_MASK \ 18895 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 18896 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 18897 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 18898 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \ 18899 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \ 18900 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \ 18901 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ 18902 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \ 18903 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND)) 18904 18905 static tree 18906 c_parser_omp_parallel (location_t loc, c_parser *parser, 18907 char *p_name, omp_clause_mask mask, tree *cclauses, 18908 bool *if_p) 18909 { 18910 tree stmt, clauses, block; 18911 18912 strcat (p_name, " parallel"); 18913 mask |= OMP_PARALLEL_CLAUSE_MASK; 18914 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */ 18915 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0 18916 && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0) 18917 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN); 18918 18919 if (c_parser_next_token_is_keyword (parser, RID_FOR)) 18920 { 18921 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 18922 if (cclauses == NULL) 18923 cclauses = cclauses_buf; 18924 18925 c_parser_consume_token (parser); 18926 if (!flag_openmp) /* flag_openmp_simd */ 18927 return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p); 18928 block = c_begin_omp_parallel (); 18929 tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p); 18930 stmt 18931 = c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL], 18932 block); 18933 if (ret == NULL_TREE) 18934 return ret; 18935 OMP_PARALLEL_COMBINED (stmt) = 1; 18936 return stmt; 18937 } 18938 /* When combined with distribute, parallel has to be followed by for. 18939 #pragma omp target parallel is allowed though. */ 18940 else if (cclauses 18941 && (mask & (OMP_CLAUSE_MASK_1 18942 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0) 18943 { 18944 error_at (loc, "expected %<for%> after %qs", p_name); 18945 c_parser_skip_to_pragma_eol (parser); 18946 return NULL_TREE; 18947 } 18948 else if (c_parser_next_token_is (parser, CPP_NAME)) 18949 { 18950 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 18951 if (cclauses == NULL && strcmp (p, "master") == 0) 18952 { 18953 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 18954 cclauses = cclauses_buf; 18955 18956 c_parser_consume_token (parser); 18957 if (!flag_openmp) /* flag_openmp_simd */ 18958 return c_parser_omp_master (loc, parser, p_name, mask, cclauses, 18959 if_p); 18960 block = c_begin_omp_parallel (); 18961 tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses, 18962 if_p); 18963 stmt = c_finish_omp_parallel (loc, 18964 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL], 18965 block); 18966 if (ret == NULL) 18967 return ret; 18968 OMP_PARALLEL_COMBINED (stmt) = 1; 18969 return stmt; 18970 } 18971 else if (strcmp (p, "loop") == 0) 18972 { 18973 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 18974 if (cclauses == NULL) 18975 cclauses = cclauses_buf; 18976 18977 c_parser_consume_token (parser); 18978 if (!flag_openmp) /* flag_openmp_simd */ 18979 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses, 18980 if_p); 18981 block = c_begin_omp_parallel (); 18982 tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, 18983 if_p); 18984 stmt 18985 = c_finish_omp_parallel (loc, 18986 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL], 18987 block); 18988 if (ret == NULL_TREE) 18989 return ret; 18990 OMP_PARALLEL_COMBINED (stmt) = 1; 18991 return stmt; 18992 } 18993 else if (!flag_openmp) /* flag_openmp_simd */ 18994 { 18995 c_parser_skip_to_pragma_eol (parser, false); 18996 return NULL_TREE; 18997 } 18998 else if (cclauses == NULL && strcmp (p, "sections") == 0) 18999 { 19000 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 19001 cclauses = cclauses_buf; 19002 19003 c_parser_consume_token (parser); 19004 block = c_begin_omp_parallel (); 19005 c_parser_omp_sections (loc, parser, p_name, mask, cclauses); 19006 stmt = c_finish_omp_parallel (loc, 19007 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL], 19008 block); 19009 OMP_PARALLEL_COMBINED (stmt) = 1; 19010 return stmt; 19011 } 19012 } 19013 else if (!flag_openmp) /* flag_openmp_simd */ 19014 { 19015 c_parser_skip_to_pragma_eol (parser, false); 19016 return NULL_TREE; 19017 } 19018 19019 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); 19020 if (cclauses) 19021 { 19022 omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses); 19023 clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; 19024 } 19025 19026 block = c_begin_omp_parallel (); 19027 c_parser_statement (parser, if_p); 19028 stmt = c_finish_omp_parallel (loc, clauses, block); 19029 19030 return stmt; 19031 } 19032 19033 /* OpenMP 2.5: 19034 # pragma omp single single-clause[optseq] new-line 19035 structured-block 19036 19037 LOC is the location of the #pragma. 19038 */ 19039 19040 #define OMP_SINGLE_CLAUSE_MASK \ 19041 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 19042 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 19043 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \ 19044 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)) 19045 19046 static tree 19047 c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p) 19048 { 19049 tree stmt = make_node (OMP_SINGLE); 19050 SET_EXPR_LOCATION (stmt, loc); 19051 TREE_TYPE (stmt) = void_type_node; 19052 19053 OMP_SINGLE_CLAUSES (stmt) 19054 = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK, 19055 "#pragma omp single"); 19056 OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p); 19057 19058 return add_stmt (stmt); 19059 } 19060 19061 /* OpenMP 3.0: 19062 # pragma omp task task-clause[optseq] new-line 19063 19064 LOC is the location of the #pragma. 19065 */ 19066 19067 #define OMP_TASK_CLAUSE_MASK \ 19068 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 19069 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \ 19070 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \ 19071 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 19072 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 19073 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \ 19074 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \ 19075 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \ 19076 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \ 19077 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \ 19078 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION)) 19079 19080 static tree 19081 c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p) 19082 { 19083 tree clauses, block; 19084 19085 clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK, 19086 "#pragma omp task"); 19087 19088 block = c_begin_omp_task (); 19089 c_parser_statement (parser, if_p); 19090 return c_finish_omp_task (loc, clauses, block); 19091 } 19092 19093 /* OpenMP 3.0: 19094 # pragma omp taskwait new-line 19095 19096 OpenMP 5.0: 19097 # pragma omp taskwait taskwait-clause[optseq] new-line 19098 */ 19099 19100 #define OMP_TASKWAIT_CLAUSE_MASK \ 19101 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) 19102 19103 static void 19104 c_parser_omp_taskwait (c_parser *parser) 19105 { 19106 location_t loc = c_parser_peek_token (parser)->location; 19107 c_parser_consume_pragma (parser); 19108 19109 tree clauses 19110 = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK, 19111 "#pragma omp taskwait"); 19112 19113 if (clauses) 19114 { 19115 tree stmt = make_node (OMP_TASK); 19116 TREE_TYPE (stmt) = void_node; 19117 OMP_TASK_CLAUSES (stmt) = clauses; 19118 OMP_TASK_BODY (stmt) = NULL_TREE; 19119 SET_EXPR_LOCATION (stmt, loc); 19120 add_stmt (stmt); 19121 } 19122 else 19123 c_finish_omp_taskwait (loc); 19124 } 19125 19126 /* OpenMP 3.1: 19127 # pragma omp taskyield new-line 19128 */ 19129 19130 static void 19131 c_parser_omp_taskyield (c_parser *parser) 19132 { 19133 location_t loc = c_parser_peek_token (parser)->location; 19134 c_parser_consume_pragma (parser); 19135 c_parser_skip_to_pragma_eol (parser); 19136 19137 c_finish_omp_taskyield (loc); 19138 } 19139 19140 /* OpenMP 4.0: 19141 # pragma omp taskgroup new-line 19142 19143 OpenMP 5.0: 19144 # pragma omp taskgroup taskgroup-clause[optseq] new-line 19145 */ 19146 19147 #define OMP_TASKGROUP_CLAUSE_MASK \ 19148 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION)) 19149 19150 static tree 19151 c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p) 19152 { 19153 tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK, 19154 "#pragma omp taskgroup"); 19155 19156 tree body = c_parser_omp_structured_block (parser, if_p); 19157 return c_finish_omp_taskgroup (loc, body, clauses); 19158 } 19159 19160 /* OpenMP 4.0: 19161 # pragma omp cancel cancel-clause[optseq] new-line 19162 19163 LOC is the location of the #pragma. 19164 */ 19165 19166 #define OMP_CANCEL_CLAUSE_MASK \ 19167 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \ 19168 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \ 19169 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \ 19170 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \ 19171 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)) 19172 19173 static void 19174 c_parser_omp_cancel (c_parser *parser) 19175 { 19176 location_t loc = c_parser_peek_token (parser)->location; 19177 19178 c_parser_consume_pragma (parser); 19179 tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK, 19180 "#pragma omp cancel"); 19181 19182 c_finish_omp_cancel (loc, clauses); 19183 } 19184 19185 /* OpenMP 4.0: 19186 # pragma omp cancellation point cancelpt-clause[optseq] new-line 19187 19188 LOC is the location of the #pragma. 19189 */ 19190 19191 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \ 19192 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \ 19193 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \ 19194 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \ 19195 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP)) 19196 19197 static void 19198 c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context) 19199 { 19200 location_t loc = c_parser_peek_token (parser)->location; 19201 tree clauses; 19202 bool point_seen = false; 19203 19204 c_parser_consume_pragma (parser); 19205 if (c_parser_next_token_is (parser, CPP_NAME)) 19206 { 19207 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 19208 if (strcmp (p, "point") == 0) 19209 { 19210 c_parser_consume_token (parser); 19211 point_seen = true; 19212 } 19213 } 19214 if (!point_seen) 19215 { 19216 c_parser_error (parser, "expected %<point%>"); 19217 c_parser_skip_to_pragma_eol (parser); 19218 return; 19219 } 19220 19221 if (context != pragma_compound) 19222 { 19223 if (context == pragma_stmt) 19224 error_at (loc, 19225 "%<#pragma %s%> may only be used in compound statements", 19226 "omp cancellation point"); 19227 else 19228 c_parser_error (parser, "expected declaration specifiers"); 19229 c_parser_skip_to_pragma_eol (parser, false); 19230 return; 19231 } 19232 19233 clauses 19234 = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK, 19235 "#pragma omp cancellation point"); 19236 19237 c_finish_omp_cancellation_point (loc, clauses); 19238 } 19239 19240 /* OpenMP 4.0: 19241 #pragma omp distribute distribute-clause[optseq] new-line 19242 for-loop */ 19243 19244 #define OMP_DISTRIBUTE_CLAUSE_MASK \ 19245 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 19246 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 19247 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ 19248 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\ 19249 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)) 19250 19251 static tree 19252 c_parser_omp_distribute (location_t loc, c_parser *parser, 19253 char *p_name, omp_clause_mask mask, tree *cclauses, 19254 bool *if_p) 19255 { 19256 tree clauses, block, ret; 19257 19258 strcat (p_name, " distribute"); 19259 mask |= OMP_DISTRIBUTE_CLAUSE_MASK; 19260 19261 if (c_parser_next_token_is (parser, CPP_NAME)) 19262 { 19263 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 19264 bool simd = false; 19265 bool parallel = false; 19266 19267 if (strcmp (p, "simd") == 0) 19268 simd = true; 19269 else 19270 parallel = strcmp (p, "parallel") == 0; 19271 if (parallel || simd) 19272 { 19273 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 19274 if (cclauses == NULL) 19275 cclauses = cclauses_buf; 19276 c_parser_consume_token (parser); 19277 if (!flag_openmp) /* flag_openmp_simd */ 19278 { 19279 if (simd) 19280 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses, 19281 if_p); 19282 else 19283 return c_parser_omp_parallel (loc, parser, p_name, mask, 19284 cclauses, if_p); 19285 } 19286 block = c_begin_compound_stmt (true); 19287 if (simd) 19288 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, 19289 if_p); 19290 else 19291 ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses, 19292 if_p); 19293 block = c_end_compound_stmt (loc, block, true); 19294 if (ret == NULL) 19295 return ret; 19296 ret = make_node (OMP_DISTRIBUTE); 19297 TREE_TYPE (ret) = void_type_node; 19298 OMP_FOR_BODY (ret) = block; 19299 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE]; 19300 SET_EXPR_LOCATION (ret, loc); 19301 add_stmt (ret); 19302 return ret; 19303 } 19304 } 19305 if (!flag_openmp) /* flag_openmp_simd */ 19306 { 19307 c_parser_skip_to_pragma_eol (parser, false); 19308 return NULL_TREE; 19309 } 19310 19311 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); 19312 if (cclauses) 19313 { 19314 omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses); 19315 clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE]; 19316 } 19317 19318 block = c_begin_compound_stmt (true); 19319 ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL, 19320 if_p); 19321 block = c_end_compound_stmt (loc, block, true); 19322 add_stmt (block); 19323 19324 return ret; 19325 } 19326 19327 /* OpenMP 4.0: 19328 # pragma omp teams teams-clause[optseq] new-line 19329 structured-block */ 19330 19331 #define OMP_TEAMS_CLAUSE_MASK \ 19332 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 19333 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 19334 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \ 19335 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ 19336 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \ 19337 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \ 19338 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT)) 19339 19340 static tree 19341 c_parser_omp_teams (location_t loc, c_parser *parser, 19342 char *p_name, omp_clause_mask mask, tree *cclauses, 19343 bool *if_p) 19344 { 19345 tree clauses, block, ret; 19346 19347 strcat (p_name, " teams"); 19348 mask |= OMP_TEAMS_CLAUSE_MASK; 19349 19350 if (c_parser_next_token_is (parser, CPP_NAME)) 19351 { 19352 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 19353 if (strcmp (p, "distribute") == 0) 19354 { 19355 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 19356 if (cclauses == NULL) 19357 cclauses = cclauses_buf; 19358 19359 c_parser_consume_token (parser); 19360 if (!flag_openmp) /* flag_openmp_simd */ 19361 return c_parser_omp_distribute (loc, parser, p_name, mask, 19362 cclauses, if_p); 19363 block = c_begin_omp_parallel (); 19364 ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses, 19365 if_p); 19366 block = c_end_compound_stmt (loc, block, true); 19367 if (ret == NULL) 19368 return ret; 19369 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS]; 19370 ret = make_node (OMP_TEAMS); 19371 TREE_TYPE (ret) = void_type_node; 19372 OMP_TEAMS_CLAUSES (ret) = clauses; 19373 OMP_TEAMS_BODY (ret) = block; 19374 OMP_TEAMS_COMBINED (ret) = 1; 19375 SET_EXPR_LOCATION (ret, loc); 19376 return add_stmt (ret); 19377 } 19378 else if (strcmp (p, "loop") == 0) 19379 { 19380 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 19381 if (cclauses == NULL) 19382 cclauses = cclauses_buf; 19383 19384 c_parser_consume_token (parser); 19385 if (!flag_openmp) /* flag_openmp_simd */ 19386 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses, 19387 if_p); 19388 block = c_begin_omp_parallel (); 19389 ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p); 19390 block = c_end_compound_stmt (loc, block, true); 19391 if (ret == NULL) 19392 return ret; 19393 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS]; 19394 ret = make_node (OMP_TEAMS); 19395 TREE_TYPE (ret) = void_type_node; 19396 OMP_TEAMS_CLAUSES (ret) = clauses; 19397 OMP_TEAMS_BODY (ret) = block; 19398 OMP_TEAMS_COMBINED (ret) = 1; 19399 SET_EXPR_LOCATION (ret, loc); 19400 return add_stmt (ret); 19401 } 19402 } 19403 if (!flag_openmp) /* flag_openmp_simd */ 19404 { 19405 c_parser_skip_to_pragma_eol (parser, false); 19406 return NULL_TREE; 19407 } 19408 19409 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); 19410 if (cclauses) 19411 { 19412 omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses); 19413 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS]; 19414 } 19415 19416 tree stmt = make_node (OMP_TEAMS); 19417 TREE_TYPE (stmt) = void_type_node; 19418 OMP_TEAMS_CLAUSES (stmt) = clauses; 19419 block = c_begin_omp_parallel (); 19420 add_stmt (c_parser_omp_structured_block (parser, if_p)); 19421 OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true); 19422 SET_EXPR_LOCATION (stmt, loc); 19423 19424 return add_stmt (stmt); 19425 } 19426 19427 /* OpenMP 4.0: 19428 # pragma omp target data target-data-clause[optseq] new-line 19429 structured-block */ 19430 19431 #define OMP_TARGET_DATA_CLAUSE_MASK \ 19432 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \ 19433 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \ 19434 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 19435 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \ 19436 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR)) 19437 19438 static tree 19439 c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p) 19440 { 19441 tree clauses 19442 = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK, 19443 "#pragma omp target data"); 19444 int map_seen = 0; 19445 for (tree *pc = &clauses; *pc;) 19446 { 19447 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP) 19448 switch (OMP_CLAUSE_MAP_KIND (*pc)) 19449 { 19450 case GOMP_MAP_TO: 19451 case GOMP_MAP_ALWAYS_TO: 19452 case GOMP_MAP_FROM: 19453 case GOMP_MAP_ALWAYS_FROM: 19454 case GOMP_MAP_TOFROM: 19455 case GOMP_MAP_ALWAYS_TOFROM: 19456 case GOMP_MAP_ALLOC: 19457 map_seen = 3; 19458 break; 19459 case GOMP_MAP_FIRSTPRIVATE_POINTER: 19460 case GOMP_MAP_ALWAYS_POINTER: 19461 break; 19462 default: 19463 map_seen |= 1; 19464 error_at (OMP_CLAUSE_LOCATION (*pc), 19465 "%<#pragma omp target data%> with map-type other " 19466 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> " 19467 "on %<map%> clause"); 19468 *pc = OMP_CLAUSE_CHAIN (*pc); 19469 continue; 19470 } 19471 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR 19472 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR) 19473 map_seen = 3; 19474 pc = &OMP_CLAUSE_CHAIN (*pc); 19475 } 19476 19477 if (map_seen != 3) 19478 { 19479 if (map_seen == 0) 19480 error_at (loc, 19481 "%<#pragma omp target data%> must contain at least " 19482 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> " 19483 "clause"); 19484 return NULL_TREE; 19485 } 19486 19487 tree stmt = make_node (OMP_TARGET_DATA); 19488 TREE_TYPE (stmt) = void_type_node; 19489 OMP_TARGET_DATA_CLAUSES (stmt) = clauses; 19490 keep_next_level (); 19491 tree block = c_begin_compound_stmt (true); 19492 add_stmt (c_parser_omp_structured_block (parser, if_p)); 19493 OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true); 19494 19495 SET_EXPR_LOCATION (stmt, loc); 19496 return add_stmt (stmt); 19497 } 19498 19499 /* OpenMP 4.0: 19500 # pragma omp target update target-update-clause[optseq] new-line */ 19501 19502 #define OMP_TARGET_UPDATE_CLAUSE_MASK \ 19503 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \ 19504 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \ 19505 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \ 19506 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 19507 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \ 19508 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)) 19509 19510 static bool 19511 c_parser_omp_target_update (location_t loc, c_parser *parser, 19512 enum pragma_context context) 19513 { 19514 if (context == pragma_stmt) 19515 { 19516 error_at (loc, "%<#pragma %s%> may only be used in compound statements", 19517 "omp target update"); 19518 c_parser_skip_to_pragma_eol (parser, false); 19519 return false; 19520 } 19521 19522 tree clauses 19523 = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK, 19524 "#pragma omp target update"); 19525 if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE 19526 && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE) 19527 { 19528 error_at (loc, 19529 "%<#pragma omp target update%> must contain at least one " 19530 "%<from%> or %<to%> clauses"); 19531 return false; 19532 } 19533 19534 tree stmt = make_node (OMP_TARGET_UPDATE); 19535 TREE_TYPE (stmt) = void_type_node; 19536 OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses; 19537 SET_EXPR_LOCATION (stmt, loc); 19538 add_stmt (stmt); 19539 return false; 19540 } 19541 19542 /* OpenMP 4.5: 19543 # pragma omp target enter data target-data-clause[optseq] new-line */ 19544 19545 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \ 19546 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \ 19547 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \ 19548 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 19549 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \ 19550 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)) 19551 19552 static tree 19553 c_parser_omp_target_enter_data (location_t loc, c_parser *parser, 19554 enum pragma_context context) 19555 { 19556 bool data_seen = false; 19557 if (c_parser_next_token_is (parser, CPP_NAME)) 19558 { 19559 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 19560 if (strcmp (p, "data") == 0) 19561 { 19562 c_parser_consume_token (parser); 19563 data_seen = true; 19564 } 19565 } 19566 if (!data_seen) 19567 { 19568 c_parser_error (parser, "expected %<data%>"); 19569 c_parser_skip_to_pragma_eol (parser); 19570 return NULL_TREE; 19571 } 19572 19573 if (context == pragma_stmt) 19574 { 19575 error_at (loc, "%<#pragma %s%> may only be used in compound statements", 19576 "omp target enter data"); 19577 c_parser_skip_to_pragma_eol (parser, false); 19578 return NULL_TREE; 19579 } 19580 19581 tree clauses 19582 = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK, 19583 "#pragma omp target enter data"); 19584 int map_seen = 0; 19585 for (tree *pc = &clauses; *pc;) 19586 { 19587 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP) 19588 switch (OMP_CLAUSE_MAP_KIND (*pc)) 19589 { 19590 case GOMP_MAP_TO: 19591 case GOMP_MAP_ALWAYS_TO: 19592 case GOMP_MAP_ALLOC: 19593 map_seen = 3; 19594 break; 19595 case GOMP_MAP_FIRSTPRIVATE_POINTER: 19596 case GOMP_MAP_ALWAYS_POINTER: 19597 break; 19598 default: 19599 map_seen |= 1; 19600 error_at (OMP_CLAUSE_LOCATION (*pc), 19601 "%<#pragma omp target enter data%> with map-type other " 19602 "than %<to%> or %<alloc%> on %<map%> clause"); 19603 *pc = OMP_CLAUSE_CHAIN (*pc); 19604 continue; 19605 } 19606 pc = &OMP_CLAUSE_CHAIN (*pc); 19607 } 19608 19609 if (map_seen != 3) 19610 { 19611 if (map_seen == 0) 19612 error_at (loc, 19613 "%<#pragma omp target enter data%> must contain at least " 19614 "one %<map%> clause"); 19615 return NULL_TREE; 19616 } 19617 19618 tree stmt = make_node (OMP_TARGET_ENTER_DATA); 19619 TREE_TYPE (stmt) = void_type_node; 19620 OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses; 19621 SET_EXPR_LOCATION (stmt, loc); 19622 add_stmt (stmt); 19623 return stmt; 19624 } 19625 19626 /* OpenMP 4.5: 19627 # pragma omp target exit data target-data-clause[optseq] new-line */ 19628 19629 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \ 19630 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \ 19631 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \ 19632 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 19633 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \ 19634 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)) 19635 19636 static tree 19637 c_parser_omp_target_exit_data (location_t loc, c_parser *parser, 19638 enum pragma_context context) 19639 { 19640 bool data_seen = false; 19641 if (c_parser_next_token_is (parser, CPP_NAME)) 19642 { 19643 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 19644 if (strcmp (p, "data") == 0) 19645 { 19646 c_parser_consume_token (parser); 19647 data_seen = true; 19648 } 19649 } 19650 if (!data_seen) 19651 { 19652 c_parser_error (parser, "expected %<data%>"); 19653 c_parser_skip_to_pragma_eol (parser); 19654 return NULL_TREE; 19655 } 19656 19657 if (context == pragma_stmt) 19658 { 19659 error_at (loc, "%<#pragma %s%> may only be used in compound statements", 19660 "omp target exit data"); 19661 c_parser_skip_to_pragma_eol (parser, false); 19662 return NULL_TREE; 19663 } 19664 19665 tree clauses 19666 = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK, 19667 "#pragma omp target exit data"); 19668 19669 int map_seen = 0; 19670 for (tree *pc = &clauses; *pc;) 19671 { 19672 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP) 19673 switch (OMP_CLAUSE_MAP_KIND (*pc)) 19674 { 19675 case GOMP_MAP_FROM: 19676 case GOMP_MAP_ALWAYS_FROM: 19677 case GOMP_MAP_RELEASE: 19678 case GOMP_MAP_DELETE: 19679 map_seen = 3; 19680 break; 19681 case GOMP_MAP_FIRSTPRIVATE_POINTER: 19682 case GOMP_MAP_ALWAYS_POINTER: 19683 break; 19684 default: 19685 map_seen |= 1; 19686 error_at (OMP_CLAUSE_LOCATION (*pc), 19687 "%<#pragma omp target exit data%> with map-type other " 19688 "than %<from%>, %<release%> or %<delete%> on %<map%>" 19689 " clause"); 19690 *pc = OMP_CLAUSE_CHAIN (*pc); 19691 continue; 19692 } 19693 pc = &OMP_CLAUSE_CHAIN (*pc); 19694 } 19695 19696 if (map_seen != 3) 19697 { 19698 if (map_seen == 0) 19699 error_at (loc, 19700 "%<#pragma omp target exit data%> must contain at least one " 19701 "%<map%> clause"); 19702 return NULL_TREE; 19703 } 19704 19705 tree stmt = make_node (OMP_TARGET_EXIT_DATA); 19706 TREE_TYPE (stmt) = void_type_node; 19707 OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses; 19708 SET_EXPR_LOCATION (stmt, loc); 19709 add_stmt (stmt); 19710 return stmt; 19711 } 19712 19713 /* OpenMP 4.0: 19714 # pragma omp target target-clause[optseq] new-line 19715 structured-block */ 19716 19717 #define OMP_TARGET_CLAUSE_MASK \ 19718 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \ 19719 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \ 19720 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 19721 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \ 19722 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \ 19723 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 19724 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 19725 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \ 19726 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)) 19727 19728 static bool 19729 c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p) 19730 { 19731 location_t loc = c_parser_peek_token (parser)->location; 19732 c_parser_consume_pragma (parser); 19733 tree *pc = NULL, stmt, block; 19734 19735 if (context != pragma_stmt && context != pragma_compound) 19736 { 19737 c_parser_error (parser, "expected declaration specifiers"); 19738 c_parser_skip_to_pragma_eol (parser); 19739 return false; 19740 } 19741 19742 if (flag_openmp) 19743 omp_requires_mask 19744 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED); 19745 19746 if (c_parser_next_token_is (parser, CPP_NAME)) 19747 { 19748 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 19749 enum tree_code ccode = ERROR_MARK; 19750 19751 if (strcmp (p, "teams") == 0) 19752 ccode = OMP_TEAMS; 19753 else if (strcmp (p, "parallel") == 0) 19754 ccode = OMP_PARALLEL; 19755 else if (strcmp (p, "simd") == 0) 19756 ccode = OMP_SIMD; 19757 if (ccode != ERROR_MARK) 19758 { 19759 tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT]; 19760 char p_name[sizeof ("#pragma omp target teams distribute " 19761 "parallel for simd")]; 19762 19763 c_parser_consume_token (parser); 19764 strcpy (p_name, "#pragma omp target"); 19765 if (!flag_openmp) /* flag_openmp_simd */ 19766 { 19767 tree stmt; 19768 switch (ccode) 19769 { 19770 case OMP_TEAMS: 19771 stmt = c_parser_omp_teams (loc, parser, p_name, 19772 OMP_TARGET_CLAUSE_MASK, 19773 cclauses, if_p); 19774 break; 19775 case OMP_PARALLEL: 19776 stmt = c_parser_omp_parallel (loc, parser, p_name, 19777 OMP_TARGET_CLAUSE_MASK, 19778 cclauses, if_p); 19779 break; 19780 case OMP_SIMD: 19781 stmt = c_parser_omp_simd (loc, parser, p_name, 19782 OMP_TARGET_CLAUSE_MASK, 19783 cclauses, if_p); 19784 break; 19785 default: 19786 gcc_unreachable (); 19787 } 19788 return stmt != NULL_TREE; 19789 } 19790 keep_next_level (); 19791 tree block = c_begin_compound_stmt (true), ret; 19792 switch (ccode) 19793 { 19794 case OMP_TEAMS: 19795 ret = c_parser_omp_teams (loc, parser, p_name, 19796 OMP_TARGET_CLAUSE_MASK, cclauses, 19797 if_p); 19798 break; 19799 case OMP_PARALLEL: 19800 ret = c_parser_omp_parallel (loc, parser, p_name, 19801 OMP_TARGET_CLAUSE_MASK, cclauses, 19802 if_p); 19803 break; 19804 case OMP_SIMD: 19805 ret = c_parser_omp_simd (loc, parser, p_name, 19806 OMP_TARGET_CLAUSE_MASK, cclauses, 19807 if_p); 19808 break; 19809 default: 19810 gcc_unreachable (); 19811 } 19812 block = c_end_compound_stmt (loc, block, true); 19813 if (ret == NULL_TREE) 19814 return false; 19815 if (ccode == OMP_TEAMS) 19816 { 19817 /* For combined target teams, ensure the num_teams and 19818 thread_limit clause expressions are evaluated on the host, 19819 before entering the target construct. */ 19820 tree c; 19821 for (c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS]; 19822 c; c = OMP_CLAUSE_CHAIN (c)) 19823 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS 19824 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT) 19825 && TREE_CODE (OMP_CLAUSE_OPERAND (c, 0)) != INTEGER_CST) 19826 { 19827 tree expr = OMP_CLAUSE_OPERAND (c, 0); 19828 tree tmp = create_tmp_var_raw (TREE_TYPE (expr)); 19829 expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp, 19830 expr, NULL_TREE, NULL_TREE); 19831 add_stmt (expr); 19832 OMP_CLAUSE_OPERAND (c, 0) = expr; 19833 tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c), 19834 OMP_CLAUSE_FIRSTPRIVATE); 19835 OMP_CLAUSE_DECL (tc) = tmp; 19836 OMP_CLAUSE_CHAIN (tc) 19837 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET]; 19838 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc; 19839 } 19840 } 19841 tree stmt = make_node (OMP_TARGET); 19842 TREE_TYPE (stmt) = void_type_node; 19843 OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET]; 19844 OMP_TARGET_BODY (stmt) = block; 19845 OMP_TARGET_COMBINED (stmt) = 1; 19846 SET_EXPR_LOCATION (stmt, loc); 19847 add_stmt (stmt); 19848 pc = &OMP_TARGET_CLAUSES (stmt); 19849 goto check_clauses; 19850 } 19851 else if (!flag_openmp) /* flag_openmp_simd */ 19852 { 19853 c_parser_skip_to_pragma_eol (parser, false); 19854 return false; 19855 } 19856 else if (strcmp (p, "data") == 0) 19857 { 19858 c_parser_consume_token (parser); 19859 c_parser_omp_target_data (loc, parser, if_p); 19860 return true; 19861 } 19862 else if (strcmp (p, "enter") == 0) 19863 { 19864 c_parser_consume_token (parser); 19865 c_parser_omp_target_enter_data (loc, parser, context); 19866 return false; 19867 } 19868 else if (strcmp (p, "exit") == 0) 19869 { 19870 c_parser_consume_token (parser); 19871 c_parser_omp_target_exit_data (loc, parser, context); 19872 return false; 19873 } 19874 else if (strcmp (p, "update") == 0) 19875 { 19876 c_parser_consume_token (parser); 19877 return c_parser_omp_target_update (loc, parser, context); 19878 } 19879 } 19880 if (!flag_openmp) /* flag_openmp_simd */ 19881 { 19882 c_parser_skip_to_pragma_eol (parser, false); 19883 return false; 19884 } 19885 19886 stmt = make_node (OMP_TARGET); 19887 TREE_TYPE (stmt) = void_type_node; 19888 19889 OMP_TARGET_CLAUSES (stmt) 19890 = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK, 19891 "#pragma omp target"); 19892 pc = &OMP_TARGET_CLAUSES (stmt); 19893 keep_next_level (); 19894 block = c_begin_compound_stmt (true); 19895 add_stmt (c_parser_omp_structured_block (parser, if_p)); 19896 OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true); 19897 19898 SET_EXPR_LOCATION (stmt, loc); 19899 add_stmt (stmt); 19900 19901 check_clauses: 19902 while (*pc) 19903 { 19904 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP) 19905 switch (OMP_CLAUSE_MAP_KIND (*pc)) 19906 { 19907 case GOMP_MAP_TO: 19908 case GOMP_MAP_ALWAYS_TO: 19909 case GOMP_MAP_FROM: 19910 case GOMP_MAP_ALWAYS_FROM: 19911 case GOMP_MAP_TOFROM: 19912 case GOMP_MAP_ALWAYS_TOFROM: 19913 case GOMP_MAP_ALLOC: 19914 case GOMP_MAP_FIRSTPRIVATE_POINTER: 19915 case GOMP_MAP_ALWAYS_POINTER: 19916 break; 19917 default: 19918 error_at (OMP_CLAUSE_LOCATION (*pc), 19919 "%<#pragma omp target%> with map-type other " 19920 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> " 19921 "on %<map%> clause"); 19922 *pc = OMP_CLAUSE_CHAIN (*pc); 19923 continue; 19924 } 19925 pc = &OMP_CLAUSE_CHAIN (*pc); 19926 } 19927 return true; 19928 } 19929 19930 /* OpenMP 4.0: 19931 # pragma omp declare simd declare-simd-clauses[optseq] new-line 19932 19933 OpenMP 5.0: 19934 # pragma omp declare variant (identifier) match(context-selector) new-line 19935 */ 19936 19937 #define OMP_DECLARE_SIMD_CLAUSE_MASK \ 19938 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \ 19939 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \ 19940 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \ 19941 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \ 19942 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \ 19943 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH)) 19944 19945 static void 19946 c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context) 19947 { 19948 c_token *token = c_parser_peek_token (parser); 19949 gcc_assert (token->type == CPP_NAME); 19950 tree kind = token->value; 19951 gcc_assert (strcmp (IDENTIFIER_POINTER (kind), "simd") == 0 19952 || strcmp (IDENTIFIER_POINTER (kind), "variant") == 0); 19953 19954 auto_vec<c_token> clauses; 19955 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 19956 { 19957 c_token *token = c_parser_peek_token (parser); 19958 if (token->type == CPP_EOF) 19959 { 19960 c_parser_skip_to_pragma_eol (parser); 19961 return; 19962 } 19963 clauses.safe_push (*token); 19964 c_parser_consume_token (parser); 19965 } 19966 clauses.safe_push (*c_parser_peek_token (parser)); 19967 c_parser_skip_to_pragma_eol (parser); 19968 19969 while (c_parser_next_token_is (parser, CPP_PRAGMA)) 19970 { 19971 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_DECLARE 19972 || c_parser_peek_2nd_token (parser)->type != CPP_NAME 19973 || c_parser_peek_2nd_token (parser)->value != kind) 19974 { 19975 error ("%<#pragma omp declare %s%> must be followed by " 19976 "function declaration or definition or another " 19977 "%<#pragma omp declare %s%>", 19978 IDENTIFIER_POINTER (kind), IDENTIFIER_POINTER (kind)); 19979 return; 19980 } 19981 c_parser_consume_pragma (parser); 19982 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 19983 { 19984 c_token *token = c_parser_peek_token (parser); 19985 if (token->type == CPP_EOF) 19986 { 19987 c_parser_skip_to_pragma_eol (parser); 19988 return; 19989 } 19990 clauses.safe_push (*token); 19991 c_parser_consume_token (parser); 19992 } 19993 clauses.safe_push (*c_parser_peek_token (parser)); 19994 c_parser_skip_to_pragma_eol (parser); 19995 } 19996 19997 /* Make sure nothing tries to read past the end of the tokens. */ 19998 c_token eof_token; 19999 memset (&eof_token, 0, sizeof (eof_token)); 20000 eof_token.type = CPP_EOF; 20001 clauses.safe_push (eof_token); 20002 clauses.safe_push (eof_token); 20003 20004 switch (context) 20005 { 20006 case pragma_external: 20007 if (c_parser_next_token_is (parser, CPP_KEYWORD) 20008 && c_parser_peek_token (parser)->keyword == RID_EXTENSION) 20009 { 20010 int ext = disable_extension_diagnostics (); 20011 do 20012 c_parser_consume_token (parser); 20013 while (c_parser_next_token_is (parser, CPP_KEYWORD) 20014 && c_parser_peek_token (parser)->keyword == RID_EXTENSION); 20015 c_parser_declaration_or_fndef (parser, true, true, true, false, true, 20016 NULL, clauses); 20017 restore_extension_diagnostics (ext); 20018 } 20019 else 20020 c_parser_declaration_or_fndef (parser, true, true, true, false, true, 20021 NULL, clauses); 20022 break; 20023 case pragma_struct: 20024 case pragma_param: 20025 case pragma_stmt: 20026 error ("%<#pragma omp declare %s%> must be followed by " 20027 "function declaration or definition", 20028 IDENTIFIER_POINTER (kind)); 20029 break; 20030 case pragma_compound: 20031 if (c_parser_next_token_is (parser, CPP_KEYWORD) 20032 && c_parser_peek_token (parser)->keyword == RID_EXTENSION) 20033 { 20034 int ext = disable_extension_diagnostics (); 20035 do 20036 c_parser_consume_token (parser); 20037 while (c_parser_next_token_is (parser, CPP_KEYWORD) 20038 && c_parser_peek_token (parser)->keyword == RID_EXTENSION); 20039 if (c_parser_next_tokens_start_declaration (parser)) 20040 { 20041 c_parser_declaration_or_fndef (parser, true, true, true, true, 20042 true, NULL, clauses); 20043 restore_extension_diagnostics (ext); 20044 break; 20045 } 20046 restore_extension_diagnostics (ext); 20047 } 20048 else if (c_parser_next_tokens_start_declaration (parser)) 20049 { 20050 c_parser_declaration_or_fndef (parser, true, true, true, true, true, 20051 NULL, clauses); 20052 break; 20053 } 20054 error ("%<#pragma omp declare %s%> must be followed by " 20055 "function declaration or definition", 20056 IDENTIFIER_POINTER (kind)); 20057 break; 20058 default: 20059 gcc_unreachable (); 20060 } 20061 } 20062 20063 static const char *const omp_construct_selectors[] = { 20064 "simd", "target", "teams", "parallel", "for", NULL }; 20065 static const char *const omp_device_selectors[] = { 20066 "kind", "isa", "arch", NULL }; 20067 static const char *const omp_implementation_selectors[] = { 20068 "vendor", "extension", "atomic_default_mem_order", "unified_address", 20069 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL }; 20070 static const char *const omp_user_selectors[] = { 20071 "condition", NULL }; 20072 20073 /* OpenMP 5.0: 20074 20075 trait-selector: 20076 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])] 20077 20078 trait-score: 20079 score(score-expression) */ 20080 20081 static tree 20082 c_parser_omp_context_selector (c_parser *parser, tree set, tree parms) 20083 { 20084 tree ret = NULL_TREE; 20085 do 20086 { 20087 tree selector; 20088 if (c_parser_next_token_is (parser, CPP_KEYWORD) 20089 || c_parser_next_token_is (parser, CPP_NAME)) 20090 selector = c_parser_peek_token (parser)->value; 20091 else 20092 { 20093 c_parser_error (parser, "expected trait selector name"); 20094 return error_mark_node; 20095 } 20096 20097 tree properties = NULL_TREE; 20098 const char *const *selectors = NULL; 20099 bool allow_score = true; 20100 bool allow_user = false; 20101 int property_limit = 0; 20102 enum { CTX_PROPERTY_NONE, CTX_PROPERTY_USER, CTX_PROPERTY_NAME_LIST, 20103 CTX_PROPERTY_ID, CTX_PROPERTY_EXPR, 20104 CTX_PROPERTY_SIMD } property_kind = CTX_PROPERTY_NONE; 20105 switch (IDENTIFIER_POINTER (set)[0]) 20106 { 20107 case 'c': /* construct */ 20108 selectors = omp_construct_selectors; 20109 allow_score = false; 20110 property_limit = 1; 20111 property_kind = CTX_PROPERTY_SIMD; 20112 break; 20113 case 'd': /* device */ 20114 selectors = omp_device_selectors; 20115 allow_score = false; 20116 allow_user = true; 20117 property_limit = 3; 20118 property_kind = CTX_PROPERTY_NAME_LIST; 20119 break; 20120 case 'i': /* implementation */ 20121 selectors = omp_implementation_selectors; 20122 allow_user = true; 20123 property_limit = 3; 20124 property_kind = CTX_PROPERTY_NAME_LIST; 20125 break; 20126 case 'u': /* user */ 20127 selectors = omp_user_selectors; 20128 property_limit = 1; 20129 property_kind = CTX_PROPERTY_EXPR; 20130 break; 20131 default: 20132 gcc_unreachable (); 20133 } 20134 for (int i = 0; ; i++) 20135 { 20136 if (selectors[i] == NULL) 20137 { 20138 if (allow_user) 20139 { 20140 property_kind = CTX_PROPERTY_USER; 20141 break; 20142 } 20143 else 20144 { 20145 error_at (c_parser_peek_token (parser)->location, 20146 "selector %qs not allowed for context selector " 20147 "set %qs", IDENTIFIER_POINTER (selector), 20148 IDENTIFIER_POINTER (set)); 20149 c_parser_consume_token (parser); 20150 return error_mark_node; 20151 } 20152 } 20153 if (i == property_limit) 20154 property_kind = CTX_PROPERTY_NONE; 20155 if (strcmp (selectors[i], IDENTIFIER_POINTER (selector)) == 0) 20156 break; 20157 } 20158 if (property_kind == CTX_PROPERTY_NAME_LIST 20159 && IDENTIFIER_POINTER (set)[0] == 'i' 20160 && strcmp (IDENTIFIER_POINTER (selector), 20161 "atomic_default_mem_order") == 0) 20162 property_kind = CTX_PROPERTY_ID; 20163 20164 c_parser_consume_token (parser); 20165 20166 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 20167 { 20168 if (property_kind == CTX_PROPERTY_NONE) 20169 { 20170 error_at (c_parser_peek_token (parser)->location, 20171 "selector %qs does not accept any properties", 20172 IDENTIFIER_POINTER (selector)); 20173 return error_mark_node; 20174 } 20175 20176 matching_parens parens; 20177 parens.require_open (parser); 20178 20179 c_token *token = c_parser_peek_token (parser); 20180 if (allow_score 20181 && c_parser_next_token_is (parser, CPP_NAME) 20182 && strcmp (IDENTIFIER_POINTER (token->value), "score") == 0 20183 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN) 20184 { 20185 c_parser_consume_token (parser); 20186 20187 matching_parens parens2; 20188 parens2.require_open (parser); 20189 tree score = c_parser_expr_no_commas (parser, NULL).value; 20190 parens2.skip_until_found_close (parser); 20191 c_parser_require (parser, CPP_COLON, "expected %<:%>"); 20192 if (score != error_mark_node) 20193 { 20194 mark_exp_read (score); 20195 score = c_fully_fold (score, false, NULL); 20196 if (!INTEGRAL_TYPE_P (TREE_TYPE (score)) 20197 || TREE_CODE (score) != INTEGER_CST) 20198 error_at (token->location, "score argument must be " 20199 "constant integer expression"); 20200 else if (tree_int_cst_sgn (score) < 0) 20201 error_at (token->location, "score argument must be " 20202 "non-negative"); 20203 else 20204 properties = tree_cons (get_identifier (" score"), 20205 score, properties); 20206 } 20207 token = c_parser_peek_token (parser); 20208 } 20209 20210 switch (property_kind) 20211 { 20212 tree t; 20213 case CTX_PROPERTY_USER: 20214 do 20215 { 20216 t = c_parser_expr_no_commas (parser, NULL).value; 20217 if (TREE_CODE (t) == STRING_CST) 20218 properties = tree_cons (NULL_TREE, t, properties); 20219 else if (t != error_mark_node) 20220 { 20221 mark_exp_read (t); 20222 t = c_fully_fold (t, false, NULL); 20223 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)) 20224 || !tree_fits_shwi_p (t)) 20225 error_at (token->location, "property must be " 20226 "constant integer expression or string " 20227 "literal"); 20228 else 20229 properties = tree_cons (NULL_TREE, t, properties); 20230 } 20231 else 20232 return error_mark_node; 20233 20234 if (c_parser_next_token_is (parser, CPP_COMMA)) 20235 c_parser_consume_token (parser); 20236 else 20237 break; 20238 } 20239 while (1); 20240 break; 20241 case CTX_PROPERTY_ID: 20242 if (c_parser_next_token_is (parser, CPP_KEYWORD) 20243 || c_parser_next_token_is (parser, CPP_NAME)) 20244 { 20245 tree prop = c_parser_peek_token (parser)->value; 20246 c_parser_consume_token (parser); 20247 properties = tree_cons (prop, NULL_TREE, properties); 20248 } 20249 else 20250 { 20251 c_parser_error (parser, "expected identifier"); 20252 return error_mark_node; 20253 } 20254 break; 20255 case CTX_PROPERTY_NAME_LIST: 20256 do 20257 { 20258 tree prop = NULL_TREE, value = NULL_TREE; 20259 if (c_parser_next_token_is (parser, CPP_KEYWORD) 20260 || c_parser_next_token_is (parser, CPP_NAME)) 20261 { 20262 prop = c_parser_peek_token (parser)->value; 20263 c_parser_consume_token (parser); 20264 } 20265 else if (c_parser_next_token_is (parser, CPP_STRING)) 20266 value = c_parser_string_literal (parser, false, 20267 false).value; 20268 else 20269 { 20270 c_parser_error (parser, "expected identifier or " 20271 "string literal"); 20272 return error_mark_node; 20273 } 20274 20275 properties = tree_cons (prop, value, properties); 20276 20277 if (c_parser_next_token_is (parser, CPP_COMMA)) 20278 c_parser_consume_token (parser); 20279 else 20280 break; 20281 } 20282 while (1); 20283 break; 20284 case CTX_PROPERTY_EXPR: 20285 t = c_parser_expr_no_commas (parser, NULL).value; 20286 if (t != error_mark_node) 20287 { 20288 mark_exp_read (t); 20289 t = c_fully_fold (t, false, NULL); 20290 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)) 20291 || !tree_fits_shwi_p (t)) 20292 error_at (token->location, "property must be " 20293 "constant integer expression"); 20294 else 20295 properties = tree_cons (NULL_TREE, t, properties); 20296 } 20297 else 20298 return error_mark_node; 20299 break; 20300 case CTX_PROPERTY_SIMD: 20301 if (parms == NULL_TREE) 20302 { 20303 error_at (token->location, "properties for %<simd%> " 20304 "selector may not be specified in " 20305 "%<metadirective%>"); 20306 return error_mark_node; 20307 } 20308 tree c; 20309 c = c_parser_omp_all_clauses (parser, 20310 OMP_DECLARE_SIMD_CLAUSE_MASK, 20311 "simd", true, 2); 20312 c = c_omp_declare_simd_clauses_to_numbers (parms 20313 == error_mark_node 20314 ? NULL_TREE : parms, 20315 c); 20316 properties = c; 20317 break; 20318 default: 20319 gcc_unreachable (); 20320 } 20321 20322 parens.skip_until_found_close (parser); 20323 properties = nreverse (properties); 20324 } 20325 else if (property_kind == CTX_PROPERTY_NAME_LIST 20326 || property_kind == CTX_PROPERTY_ID 20327 || property_kind == CTX_PROPERTY_EXPR) 20328 { 20329 c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"); 20330 return error_mark_node; 20331 } 20332 20333 ret = tree_cons (selector, properties, ret); 20334 20335 if (c_parser_next_token_is (parser, CPP_COMMA)) 20336 c_parser_consume_token (parser); 20337 else 20338 break; 20339 } 20340 while (1); 20341 20342 return nreverse (ret); 20343 } 20344 20345 /* OpenMP 5.0: 20346 20347 trait-set-selector[,trait-set-selector[,...]] 20348 20349 trait-set-selector: 20350 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] } 20351 20352 trait-set-selector-name: 20353 constructor 20354 device 20355 implementation 20356 user */ 20357 20358 static tree 20359 c_parser_omp_context_selector_specification (c_parser *parser, tree parms) 20360 { 20361 tree ret = NULL_TREE; 20362 do 20363 { 20364 const char *setp = ""; 20365 if (c_parser_next_token_is (parser, CPP_NAME)) 20366 setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 20367 switch (setp[0]) 20368 { 20369 case 'c': 20370 if (strcmp (setp, "construct") == 0) 20371 setp = NULL; 20372 break; 20373 case 'd': 20374 if (strcmp (setp, "device") == 0) 20375 setp = NULL; 20376 break; 20377 case 'i': 20378 if (strcmp (setp, "implementation") == 0) 20379 setp = NULL; 20380 break; 20381 case 'u': 20382 if (strcmp (setp, "user") == 0) 20383 setp = NULL; 20384 break; 20385 default: 20386 break; 20387 } 20388 if (setp) 20389 { 20390 c_parser_error (parser, "expected %<construct%>, %<device%>, " 20391 "%<implementation%> or %<user%>"); 20392 return error_mark_node; 20393 } 20394 20395 tree set = c_parser_peek_token (parser)->value; 20396 c_parser_consume_token (parser); 20397 20398 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) 20399 return error_mark_node; 20400 20401 matching_braces braces; 20402 if (!braces.require_open (parser)) 20403 return error_mark_node; 20404 20405 tree selectors = c_parser_omp_context_selector (parser, set, parms); 20406 if (selectors == error_mark_node) 20407 ret = error_mark_node; 20408 else if (ret != error_mark_node) 20409 ret = tree_cons (set, selectors, ret); 20410 20411 braces.skip_until_found_close (parser); 20412 20413 if (c_parser_next_token_is (parser, CPP_COMMA)) 20414 c_parser_consume_token (parser); 20415 else 20416 break; 20417 } 20418 while (1); 20419 20420 if (ret == error_mark_node) 20421 return ret; 20422 return nreverse (ret); 20423 } 20424 20425 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put 20426 that into "omp declare variant base" attribute. */ 20427 20428 static void 20429 c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms) 20430 { 20431 matching_parens parens; 20432 if (!parens.require_open (parser)) 20433 { 20434 fail: 20435 c_parser_skip_to_pragma_eol (parser, false); 20436 return; 20437 } 20438 20439 if (c_parser_next_token_is_not (parser, CPP_NAME) 20440 || c_parser_peek_token (parser)->id_kind != C_ID_ID) 20441 { 20442 c_parser_error (parser, "expected identifier"); 20443 goto fail; 20444 } 20445 20446 c_token *token = c_parser_peek_token (parser); 20447 tree variant = lookup_name (token->value); 20448 20449 if (variant == NULL_TREE) 20450 { 20451 undeclared_variable (token->location, token->value); 20452 variant = error_mark_node; 20453 } 20454 20455 c_parser_consume_token (parser); 20456 20457 parens.require_close (parser); 20458 20459 const char *clause = ""; 20460 location_t match_loc = c_parser_peek_token (parser)->location; 20461 if (c_parser_next_token_is (parser, CPP_NAME)) 20462 clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 20463 if (strcmp (clause, "match")) 20464 { 20465 c_parser_error (parser, "expected %<match%>"); 20466 goto fail; 20467 } 20468 20469 c_parser_consume_token (parser); 20470 20471 if (!parens.require_open (parser)) 20472 goto fail; 20473 20474 if (parms == NULL_TREE) 20475 parms = error_mark_node; 20476 20477 tree ctx = c_parser_omp_context_selector_specification (parser, parms); 20478 if (ctx == error_mark_node) 20479 goto fail; 20480 ctx = c_omp_check_context_selector (match_loc, ctx); 20481 if (ctx != error_mark_node && variant != error_mark_node) 20482 { 20483 if (TREE_CODE (variant) != FUNCTION_DECL) 20484 { 20485 error_at (token->location, "variant %qD is not a function", variant); 20486 variant = error_mark_node; 20487 } 20488 else if (omp_get_context_selector (ctx, "construct", "simd") == NULL_TREE 20489 && !comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant))) 20490 { 20491 error_at (token->location, "variant %qD and base %qD have " 20492 "incompatible types", variant, fndecl); 20493 variant = error_mark_node; 20494 } 20495 else if (fndecl_built_in_p (variant) 20496 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)), 20497 "__builtin_", strlen ("__builtin_")) == 0 20498 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)), 20499 "__sync_", strlen ("__sync_")) == 0 20500 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)), 20501 "__atomic_", strlen ("__atomic_")) == 0)) 20502 { 20503 error_at (token->location, "variant %qD is a built-in", variant); 20504 variant = error_mark_node; 20505 } 20506 if (variant != error_mark_node) 20507 { 20508 C_DECL_USED (variant) = 1; 20509 tree construct = omp_get_context_selector (ctx, "construct", NULL); 20510 c_omp_mark_declare_variant (match_loc, variant, construct); 20511 if (omp_context_selector_matches (ctx)) 20512 { 20513 tree attr 20514 = tree_cons (get_identifier ("omp declare variant base"), 20515 build_tree_list (variant, ctx), 20516 DECL_ATTRIBUTES (fndecl)); 20517 DECL_ATTRIBUTES (fndecl) = attr; 20518 } 20519 } 20520 } 20521 20522 parens.require_close (parser); 20523 c_parser_skip_to_pragma_eol (parser); 20524 } 20525 20526 /* Finalize #pragma omp declare simd or #pragma omp declare variant 20527 clauses after FNDECL has been parsed, and put that into "omp declare simd" 20528 or "omp declare variant base" attribute. */ 20529 20530 static void 20531 c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms, 20532 vec<c_token> clauses) 20533 { 20534 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there 20535 indicates error has been reported and CPP_PRAGMA that 20536 c_finish_omp_declare_simd has already processed the tokens. */ 20537 if (clauses.exists () && clauses[0].type == CPP_EOF) 20538 return; 20539 const char *kind = "simd"; 20540 if (clauses.exists () 20541 && (clauses[0].type == CPP_NAME || clauses[0].type == CPP_PRAGMA)) 20542 kind = IDENTIFIER_POINTER (clauses[0].value); 20543 gcc_assert (strcmp (kind, "simd") == 0 || strcmp (kind, "variant") == 0); 20544 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL) 20545 { 20546 error ("%<#pragma omp declare %s%> not immediately followed by " 20547 "a function declaration or definition", kind); 20548 clauses[0].type = CPP_EOF; 20549 return; 20550 } 20551 if (clauses.exists () && clauses[0].type != CPP_NAME) 20552 { 20553 error_at (DECL_SOURCE_LOCATION (fndecl), 20554 "%<#pragma omp declare %s%> not immediately followed by " 20555 "a single function declaration or definition", kind); 20556 clauses[0].type = CPP_EOF; 20557 return; 20558 } 20559 20560 if (parms == NULL_TREE) 20561 parms = DECL_ARGUMENTS (fndecl); 20562 20563 unsigned int tokens_avail = parser->tokens_avail; 20564 gcc_assert (parser->tokens == &parser->tokens_buf[0]); 20565 20566 parser->tokens = clauses.address (); 20567 parser->tokens_avail = clauses.length (); 20568 20569 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */ 20570 while (parser->tokens_avail > 3) 20571 { 20572 c_token *token = c_parser_peek_token (parser); 20573 gcc_assert (token->type == CPP_NAME 20574 && strcmp (IDENTIFIER_POINTER (token->value), kind) == 0); 20575 c_parser_consume_token (parser); 20576 parser->in_pragma = true; 20577 20578 if (strcmp (kind, "simd") == 0) 20579 { 20580 tree c; 20581 c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK, 20582 "#pragma omp declare simd"); 20583 c = c_omp_declare_simd_clauses_to_numbers (parms, c); 20584 if (c != NULL_TREE) 20585 c = tree_cons (NULL_TREE, c, NULL_TREE); 20586 c = build_tree_list (get_identifier ("omp declare simd"), c); 20587 TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl); 20588 DECL_ATTRIBUTES (fndecl) = c; 20589 } 20590 else 20591 { 20592 gcc_assert (strcmp (kind, "variant") == 0); 20593 c_finish_omp_declare_variant (parser, fndecl, parms); 20594 } 20595 } 20596 20597 parser->tokens = &parser->tokens_buf[0]; 20598 parser->tokens_avail = tokens_avail; 20599 if (clauses.exists ()) 20600 clauses[0].type = CPP_PRAGMA; 20601 } 20602 20603 20604 /* OpenMP 4.0: 20605 # pragma omp declare target new-line 20606 declarations and definitions 20607 # pragma omp end declare target new-line 20608 20609 OpenMP 4.5: 20610 # pragma omp declare target ( extended-list ) new-line 20611 20612 # pragma omp declare target declare-target-clauses[seq] new-line */ 20613 20614 #define OMP_DECLARE_TARGET_CLAUSE_MASK \ 20615 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \ 20616 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \ 20617 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE)) 20618 20619 static void 20620 c_parser_omp_declare_target (c_parser *parser) 20621 { 20622 tree clauses = NULL_TREE; 20623 int device_type = 0; 20624 bool only_device_type = true; 20625 if (c_parser_next_token_is (parser, CPP_NAME)) 20626 clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK, 20627 "#pragma omp declare target"); 20628 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 20629 { 20630 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE, 20631 clauses); 20632 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP); 20633 c_parser_skip_to_pragma_eol (parser); 20634 } 20635 else 20636 { 20637 c_parser_skip_to_pragma_eol (parser); 20638 current_omp_declare_target_attribute++; 20639 return; 20640 } 20641 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c)) 20642 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE) 20643 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c); 20644 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c)) 20645 { 20646 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE) 20647 continue; 20648 tree t = OMP_CLAUSE_DECL (c), id; 20649 tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t)); 20650 tree at2 = lookup_attribute ("omp declare target link", 20651 DECL_ATTRIBUTES (t)); 20652 only_device_type = false; 20653 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK) 20654 { 20655 id = get_identifier ("omp declare target link"); 20656 std::swap (at1, at2); 20657 } 20658 else 20659 id = get_identifier ("omp declare target"); 20660 if (at2) 20661 { 20662 error_at (OMP_CLAUSE_LOCATION (c), 20663 "%qD specified both in declare target %<link%> and %<to%>" 20664 " clauses", t); 20665 continue; 20666 } 20667 if (!at1) 20668 { 20669 DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t)); 20670 if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t)) 20671 continue; 20672 20673 symtab_node *node = symtab_node::get (t); 20674 if (node != NULL) 20675 { 20676 node->offloadable = 1; 20677 if (ENABLE_OFFLOADING) 20678 { 20679 g->have_offload = true; 20680 if (is_a <varpool_node *> (node)) 20681 vec_safe_push (offload_vars, t); 20682 } 20683 } 20684 } 20685 if (TREE_CODE (t) != FUNCTION_DECL) 20686 continue; 20687 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0) 20688 { 20689 tree at3 = lookup_attribute ("omp declare target host", 20690 DECL_ATTRIBUTES (t)); 20691 if (at3 == NULL_TREE) 20692 { 20693 id = get_identifier ("omp declare target host"); 20694 DECL_ATTRIBUTES (t) 20695 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t)); 20696 } 20697 } 20698 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0) 20699 { 20700 tree at3 = lookup_attribute ("omp declare target nohost", 20701 DECL_ATTRIBUTES (t)); 20702 if (at3 == NULL_TREE) 20703 { 20704 id = get_identifier ("omp declare target nohost"); 20705 DECL_ATTRIBUTES (t) 20706 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t)); 20707 } 20708 } 20709 } 20710 if (device_type && only_device_type) 20711 warning_at (OMP_CLAUSE_LOCATION (clauses), 0, 20712 "directive with only %<device_type%> clauses ignored"); 20713 } 20714 20715 static void 20716 c_parser_omp_end_declare_target (c_parser *parser) 20717 { 20718 location_t loc = c_parser_peek_token (parser)->location; 20719 c_parser_consume_pragma (parser); 20720 if (c_parser_next_token_is (parser, CPP_NAME) 20721 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value), 20722 "declare") == 0) 20723 { 20724 c_parser_consume_token (parser); 20725 if (c_parser_next_token_is (parser, CPP_NAME) 20726 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value), 20727 "target") == 0) 20728 c_parser_consume_token (parser); 20729 else 20730 { 20731 c_parser_error (parser, "expected %<target%>"); 20732 c_parser_skip_to_pragma_eol (parser); 20733 return; 20734 } 20735 } 20736 else 20737 { 20738 c_parser_error (parser, "expected %<declare%>"); 20739 c_parser_skip_to_pragma_eol (parser); 20740 return; 20741 } 20742 c_parser_skip_to_pragma_eol (parser); 20743 if (!current_omp_declare_target_attribute) 20744 error_at (loc, "%<#pragma omp end declare target%> without corresponding " 20745 "%<#pragma omp declare target%>"); 20746 else 20747 current_omp_declare_target_attribute--; 20748 } 20749 20750 20751 /* OpenMP 4.0 20752 #pragma omp declare reduction (reduction-id : typename-list : expression) \ 20753 initializer-clause[opt] new-line 20754 20755 initializer-clause: 20756 initializer (omp_priv = initializer) 20757 initializer (function-name (argument-list)) */ 20758 20759 static void 20760 c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context) 20761 { 20762 unsigned int tokens_avail = 0, i; 20763 vec<tree> types = vNULL; 20764 vec<c_token> clauses = vNULL; 20765 enum tree_code reduc_code = ERROR_MARK; 20766 tree reduc_id = NULL_TREE; 20767 tree type; 20768 location_t rloc = c_parser_peek_token (parser)->location; 20769 20770 if (context == pragma_struct || context == pragma_param) 20771 { 20772 error ("%<#pragma omp declare reduction%> not at file or block scope"); 20773 goto fail; 20774 } 20775 20776 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 20777 goto fail; 20778 20779 switch (c_parser_peek_token (parser)->type) 20780 { 20781 case CPP_PLUS: 20782 reduc_code = PLUS_EXPR; 20783 break; 20784 case CPP_MULT: 20785 reduc_code = MULT_EXPR; 20786 break; 20787 case CPP_MINUS: 20788 reduc_code = MINUS_EXPR; 20789 break; 20790 case CPP_AND: 20791 reduc_code = BIT_AND_EXPR; 20792 break; 20793 case CPP_XOR: 20794 reduc_code = BIT_XOR_EXPR; 20795 break; 20796 case CPP_OR: 20797 reduc_code = BIT_IOR_EXPR; 20798 break; 20799 case CPP_AND_AND: 20800 reduc_code = TRUTH_ANDIF_EXPR; 20801 break; 20802 case CPP_OR_OR: 20803 reduc_code = TRUTH_ORIF_EXPR; 20804 break; 20805 case CPP_NAME: 20806 const char *p; 20807 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 20808 if (strcmp (p, "min") == 0) 20809 { 20810 reduc_code = MIN_EXPR; 20811 break; 20812 } 20813 if (strcmp (p, "max") == 0) 20814 { 20815 reduc_code = MAX_EXPR; 20816 break; 20817 } 20818 reduc_id = c_parser_peek_token (parser)->value; 20819 break; 20820 default: 20821 c_parser_error (parser, 20822 "expected %<+%>, %<*%>, %<-%>, %<&%>, " 20823 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier"); 20824 goto fail; 20825 } 20826 20827 tree orig_reduc_id, reduc_decl; 20828 orig_reduc_id = reduc_id; 20829 reduc_id = c_omp_reduction_id (reduc_code, reduc_id); 20830 reduc_decl = c_omp_reduction_decl (reduc_id); 20831 c_parser_consume_token (parser); 20832 20833 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 20834 goto fail; 20835 20836 while (true) 20837 { 20838 location_t loc = c_parser_peek_token (parser)->location; 20839 struct c_type_name *ctype = c_parser_type_name (parser); 20840 if (ctype != NULL) 20841 { 20842 type = groktypename (ctype, NULL, NULL); 20843 if (type == error_mark_node) 20844 ; 20845 else if ((INTEGRAL_TYPE_P (type) 20846 || TREE_CODE (type) == REAL_TYPE 20847 || TREE_CODE (type) == COMPLEX_TYPE) 20848 && orig_reduc_id == NULL_TREE) 20849 error_at (loc, "predeclared arithmetic type in " 20850 "%<#pragma omp declare reduction%>"); 20851 else if (TREE_CODE (type) == FUNCTION_TYPE 20852 || TREE_CODE (type) == ARRAY_TYPE) 20853 error_at (loc, "function or array type in " 20854 "%<#pragma omp declare reduction%>"); 20855 else if (TYPE_ATOMIC (type)) 20856 error_at (loc, "%<_Atomic%> qualified type in " 20857 "%<#pragma omp declare reduction%>"); 20858 else if (TYPE_QUALS_NO_ADDR_SPACE (type)) 20859 error_at (loc, "const, volatile or restrict qualified type in " 20860 "%<#pragma omp declare reduction%>"); 20861 else 20862 { 20863 tree t; 20864 for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t)) 20865 if (comptypes (TREE_PURPOSE (t), type)) 20866 { 20867 error_at (loc, "redeclaration of %qs " 20868 "%<#pragma omp declare reduction%> for " 20869 "type %qT", 20870 IDENTIFIER_POINTER (reduc_id) 20871 + sizeof ("omp declare reduction ") - 1, 20872 type); 20873 location_t ploc 20874 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t), 20875 0)); 20876 error_at (ploc, "previous %<#pragma omp declare " 20877 "reduction%>"); 20878 break; 20879 } 20880 if (t == NULL_TREE) 20881 types.safe_push (type); 20882 } 20883 if (c_parser_next_token_is (parser, CPP_COMMA)) 20884 c_parser_consume_token (parser); 20885 else 20886 break; 20887 } 20888 else 20889 break; 20890 } 20891 20892 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>") 20893 || types.is_empty ()) 20894 { 20895 fail: 20896 clauses.release (); 20897 types.release (); 20898 while (true) 20899 { 20900 c_token *token = c_parser_peek_token (parser); 20901 if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL) 20902 break; 20903 c_parser_consume_token (parser); 20904 } 20905 c_parser_skip_to_pragma_eol (parser); 20906 return; 20907 } 20908 20909 if (types.length () > 1) 20910 { 20911 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 20912 { 20913 c_token *token = c_parser_peek_token (parser); 20914 if (token->type == CPP_EOF) 20915 goto fail; 20916 clauses.safe_push (*token); 20917 c_parser_consume_token (parser); 20918 } 20919 clauses.safe_push (*c_parser_peek_token (parser)); 20920 c_parser_skip_to_pragma_eol (parser); 20921 20922 /* Make sure nothing tries to read past the end of the tokens. */ 20923 c_token eof_token; 20924 memset (&eof_token, 0, sizeof (eof_token)); 20925 eof_token.type = CPP_EOF; 20926 clauses.safe_push (eof_token); 20927 clauses.safe_push (eof_token); 20928 } 20929 20930 int errs = errorcount; 20931 FOR_EACH_VEC_ELT (types, i, type) 20932 { 20933 tokens_avail = parser->tokens_avail; 20934 gcc_assert (parser->tokens == &parser->tokens_buf[0]); 20935 if (!clauses.is_empty ()) 20936 { 20937 parser->tokens = clauses.address (); 20938 parser->tokens_avail = clauses.length (); 20939 parser->in_pragma = true; 20940 } 20941 20942 bool nested = current_function_decl != NULL_TREE; 20943 if (nested) 20944 c_push_function_context (); 20945 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, 20946 reduc_id, default_function_type); 20947 current_function_decl = fndecl; 20948 allocate_struct_function (fndecl, true); 20949 push_scope (); 20950 tree stmt = push_stmt_list (); 20951 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't 20952 warn about these. */ 20953 tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL, 20954 get_identifier ("omp_out"), type); 20955 DECL_ARTIFICIAL (omp_out) = 1; 20956 DECL_CONTEXT (omp_out) = fndecl; 20957 pushdecl (omp_out); 20958 tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL, 20959 get_identifier ("omp_in"), type); 20960 DECL_ARTIFICIAL (omp_in) = 1; 20961 DECL_CONTEXT (omp_in) = fndecl; 20962 pushdecl (omp_in); 20963 struct c_expr combiner = c_parser_expression (parser); 20964 struct c_expr initializer; 20965 tree omp_priv = NULL_TREE, omp_orig = NULL_TREE; 20966 bool bad = false; 20967 initializer.set_error (); 20968 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) 20969 bad = true; 20970 else if (c_parser_next_token_is (parser, CPP_NAME) 20971 && strcmp (IDENTIFIER_POINTER 20972 (c_parser_peek_token (parser)->value), 20973 "initializer") == 0) 20974 { 20975 c_parser_consume_token (parser); 20976 pop_scope (); 20977 push_scope (); 20978 omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL, 20979 get_identifier ("omp_priv"), type); 20980 DECL_ARTIFICIAL (omp_priv) = 1; 20981 DECL_INITIAL (omp_priv) = error_mark_node; 20982 DECL_CONTEXT (omp_priv) = fndecl; 20983 pushdecl (omp_priv); 20984 omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL, 20985 get_identifier ("omp_orig"), type); 20986 DECL_ARTIFICIAL (omp_orig) = 1; 20987 DECL_CONTEXT (omp_orig) = fndecl; 20988 pushdecl (omp_orig); 20989 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 20990 bad = true; 20991 else if (!c_parser_next_token_is (parser, CPP_NAME)) 20992 { 20993 c_parser_error (parser, "expected %<omp_priv%> or " 20994 "function-name"); 20995 bad = true; 20996 } 20997 else if (strcmp (IDENTIFIER_POINTER 20998 (c_parser_peek_token (parser)->value), 20999 "omp_priv") != 0) 21000 { 21001 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN 21002 || c_parser_peek_token (parser)->id_kind != C_ID_ID) 21003 { 21004 c_parser_error (parser, "expected function-name %<(%>"); 21005 bad = true; 21006 } 21007 else 21008 initializer = c_parser_postfix_expression (parser); 21009 if (initializer.value 21010 && TREE_CODE (initializer.value) == CALL_EXPR) 21011 { 21012 int j; 21013 tree c = initializer.value; 21014 for (j = 0; j < call_expr_nargs (c); j++) 21015 { 21016 tree a = CALL_EXPR_ARG (c, j); 21017 STRIP_NOPS (a); 21018 if (TREE_CODE (a) == ADDR_EXPR 21019 && TREE_OPERAND (a, 0) == omp_priv) 21020 break; 21021 } 21022 if (j == call_expr_nargs (c)) 21023 error ("one of the initializer call arguments should be " 21024 "%<&omp_priv%>"); 21025 } 21026 } 21027 else 21028 { 21029 c_parser_consume_token (parser); 21030 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) 21031 bad = true; 21032 else 21033 { 21034 tree st = push_stmt_list (); 21035 location_t loc = c_parser_peek_token (parser)->location; 21036 rich_location richloc (line_table, loc); 21037 start_init (omp_priv, NULL_TREE, 0, &richloc); 21038 struct c_expr init = c_parser_initializer (parser); 21039 finish_init (); 21040 finish_decl (omp_priv, loc, init.value, 21041 init.original_type, NULL_TREE); 21042 pop_stmt_list (st); 21043 } 21044 } 21045 if (!bad 21046 && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) 21047 bad = true; 21048 } 21049 21050 if (!bad) 21051 { 21052 c_parser_skip_to_pragma_eol (parser); 21053 21054 tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3), 21055 DECL_INITIAL (reduc_decl)); 21056 DECL_INITIAL (reduc_decl) = t; 21057 DECL_SOURCE_LOCATION (omp_out) = rloc; 21058 TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out; 21059 TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in; 21060 TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value; 21061 walk_tree (&combiner.value, c_check_omp_declare_reduction_r, 21062 &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL); 21063 if (omp_priv) 21064 { 21065 DECL_SOURCE_LOCATION (omp_priv) = rloc; 21066 TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv; 21067 TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig; 21068 TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value; 21069 walk_tree (&initializer.value, c_check_omp_declare_reduction_r, 21070 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL); 21071 walk_tree (&DECL_INITIAL (omp_priv), 21072 c_check_omp_declare_reduction_r, 21073 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL); 21074 } 21075 } 21076 21077 pop_stmt_list (stmt); 21078 pop_scope (); 21079 if (cfun->language != NULL) 21080 { 21081 ggc_free (cfun->language); 21082 cfun->language = NULL; 21083 } 21084 set_cfun (NULL); 21085 current_function_decl = NULL_TREE; 21086 if (nested) 21087 c_pop_function_context (); 21088 21089 if (!clauses.is_empty ()) 21090 { 21091 parser->tokens = &parser->tokens_buf[0]; 21092 parser->tokens_avail = tokens_avail; 21093 } 21094 if (bad) 21095 goto fail; 21096 if (errs != errorcount) 21097 break; 21098 } 21099 21100 clauses.release (); 21101 types.release (); 21102 } 21103 21104 21105 /* OpenMP 4.0 21106 #pragma omp declare simd declare-simd-clauses[optseq] new-line 21107 #pragma omp declare reduction (reduction-id : typename-list : expression) \ 21108 initializer-clause[opt] new-line 21109 #pragma omp declare target new-line 21110 21111 OpenMP 5.0 21112 #pragma omp declare variant (identifier) match (context-selector) */ 21113 21114 static void 21115 c_parser_omp_declare (c_parser *parser, enum pragma_context context) 21116 { 21117 c_parser_consume_pragma (parser); 21118 if (c_parser_next_token_is (parser, CPP_NAME)) 21119 { 21120 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 21121 if (strcmp (p, "simd") == 0) 21122 { 21123 /* c_parser_consume_token (parser); done in 21124 c_parser_omp_declare_simd. */ 21125 c_parser_omp_declare_simd (parser, context); 21126 return; 21127 } 21128 if (strcmp (p, "reduction") == 0) 21129 { 21130 c_parser_consume_token (parser); 21131 c_parser_omp_declare_reduction (parser, context); 21132 return; 21133 } 21134 if (!flag_openmp) /* flag_openmp_simd */ 21135 { 21136 c_parser_skip_to_pragma_eol (parser, false); 21137 return; 21138 } 21139 if (strcmp (p, "target") == 0) 21140 { 21141 c_parser_consume_token (parser); 21142 c_parser_omp_declare_target (parser); 21143 return; 21144 } 21145 if (strcmp (p, "variant") == 0) 21146 { 21147 /* c_parser_consume_token (parser); done in 21148 c_parser_omp_declare_simd. */ 21149 c_parser_omp_declare_simd (parser, context); 21150 return; 21151 } 21152 } 21153 21154 c_parser_error (parser, "expected %<simd%>, %<reduction%>, " 21155 "%<target%> or %<variant%>"); 21156 c_parser_skip_to_pragma_eol (parser); 21157 } 21158 21159 /* OpenMP 5.0 21160 #pragma omp requires clauses[optseq] new-line */ 21161 21162 static void 21163 c_parser_omp_requires (c_parser *parser) 21164 { 21165 bool first = true; 21166 enum omp_requires new_req = (enum omp_requires) 0; 21167 21168 c_parser_consume_pragma (parser); 21169 21170 location_t loc = c_parser_peek_token (parser)->location; 21171 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 21172 { 21173 if (!first && c_parser_next_token_is (parser, CPP_COMMA)) 21174 c_parser_consume_token (parser); 21175 21176 first = false; 21177 21178 if (c_parser_next_token_is (parser, CPP_NAME)) 21179 { 21180 const char *p 21181 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 21182 location_t cloc = c_parser_peek_token (parser)->location; 21183 enum omp_requires this_req = (enum omp_requires) 0; 21184 21185 if (!strcmp (p, "unified_address")) 21186 this_req = OMP_REQUIRES_UNIFIED_ADDRESS; 21187 else if (!strcmp (p, "unified_shared_memory")) 21188 this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY; 21189 else if (!strcmp (p, "dynamic_allocators")) 21190 this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS; 21191 else if (!strcmp (p, "reverse_offload")) 21192 this_req = OMP_REQUIRES_REVERSE_OFFLOAD; 21193 else if (!strcmp (p, "atomic_default_mem_order")) 21194 { 21195 c_parser_consume_token (parser); 21196 21197 matching_parens parens; 21198 if (parens.require_open (parser)) 21199 { 21200 if (c_parser_next_token_is (parser, CPP_NAME)) 21201 { 21202 tree v = c_parser_peek_token (parser)->value; 21203 p = IDENTIFIER_POINTER (v); 21204 21205 if (!strcmp (p, "seq_cst")) 21206 this_req 21207 = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST; 21208 else if (!strcmp (p, "relaxed")) 21209 this_req 21210 = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED; 21211 else if (!strcmp (p, "acq_rel")) 21212 this_req 21213 = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL; 21214 } 21215 if (this_req == 0) 21216 { 21217 error_at (c_parser_peek_token (parser)->location, 21218 "expected %<seq_cst%>, %<relaxed%> or " 21219 "%<acq_rel%>"); 21220 if (c_parser_peek_2nd_token (parser)->type 21221 == CPP_CLOSE_PAREN) 21222 c_parser_consume_token (parser); 21223 } 21224 else 21225 c_parser_consume_token (parser); 21226 21227 parens.skip_until_found_close (parser); 21228 if (this_req == 0) 21229 { 21230 c_parser_skip_to_pragma_eol (parser, false); 21231 return; 21232 } 21233 } 21234 p = NULL; 21235 } 21236 else 21237 { 21238 error_at (cloc, "expected %<unified_address%>, " 21239 "%<unified_shared_memory%>, " 21240 "%<dynamic_allocators%>, " 21241 "%<reverse_offload%> " 21242 "or %<atomic_default_mem_order%> clause"); 21243 c_parser_skip_to_pragma_eol (parser, false); 21244 return; 21245 } 21246 if (p) 21247 sorry_at (cloc, "%qs clause on %<requires%> directive not " 21248 "supported yet", p); 21249 if (p) 21250 c_parser_consume_token (parser); 21251 if (this_req) 21252 { 21253 if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0) 21254 { 21255 if ((this_req & new_req) != 0) 21256 error_at (cloc, "too many %qs clauses", p); 21257 if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS 21258 && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0) 21259 error_at (cloc, "%qs clause used lexically after first " 21260 "target construct or offloading API", p); 21261 } 21262 else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0) 21263 { 21264 error_at (cloc, "too many %qs clauses", 21265 "atomic_default_mem_order"); 21266 this_req = (enum omp_requires) 0; 21267 } 21268 else if ((omp_requires_mask 21269 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0) 21270 { 21271 error_at (cloc, "more than one %<atomic_default_mem_order%>" 21272 " clause in a single compilation unit"); 21273 this_req 21274 = (enum omp_requires) 21275 (omp_requires_mask 21276 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER); 21277 } 21278 else if ((omp_requires_mask 21279 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0) 21280 error_at (cloc, "%<atomic_default_mem_order%> clause used " 21281 "lexically after first %<atomic%> construct " 21282 "without memory order clause"); 21283 new_req = (enum omp_requires) (new_req | this_req); 21284 omp_requires_mask 21285 = (enum omp_requires) (omp_requires_mask | this_req); 21286 continue; 21287 } 21288 } 21289 break; 21290 } 21291 c_parser_skip_to_pragma_eol (parser); 21292 21293 if (new_req == 0) 21294 error_at (loc, "%<pragma omp requires%> requires at least one clause"); 21295 } 21296 21297 /* Helper function for c_parser_omp_taskloop. 21298 Disallow zero sized or potentially zero sized task reductions. */ 21299 21300 static tree 21301 c_finish_taskloop_clauses (tree clauses) 21302 { 21303 tree *pc = &clauses; 21304 for (tree c = clauses; c; c = *pc) 21305 { 21306 bool remove = false; 21307 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION) 21308 { 21309 tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c))); 21310 if (integer_zerop (TYPE_SIZE_UNIT (type))) 21311 { 21312 error_at (OMP_CLAUSE_LOCATION (c), 21313 "zero sized type %qT in %<reduction%> clause", type); 21314 remove = true; 21315 } 21316 else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST) 21317 { 21318 error_at (OMP_CLAUSE_LOCATION (c), 21319 "variable sized type %qT in %<reduction%> clause", 21320 type); 21321 remove = true; 21322 } 21323 } 21324 if (remove) 21325 *pc = OMP_CLAUSE_CHAIN (c); 21326 else 21327 pc = &OMP_CLAUSE_CHAIN (c); 21328 } 21329 return clauses; 21330 } 21331 21332 /* OpenMP 4.5: 21333 #pragma omp taskloop taskloop-clause[optseq] new-line 21334 for-loop 21335 21336 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line 21337 for-loop */ 21338 21339 #define OMP_TASKLOOP_CLAUSE_MASK \ 21340 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \ 21341 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 21342 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 21343 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ 21344 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \ 21345 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \ 21346 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \ 21347 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \ 21348 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \ 21349 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 21350 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \ 21351 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \ 21352 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \ 21353 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \ 21354 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ 21355 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION)) 21356 21357 static tree 21358 c_parser_omp_taskloop (location_t loc, c_parser *parser, 21359 char *p_name, omp_clause_mask mask, tree *cclauses, 21360 bool *if_p) 21361 { 21362 tree clauses, block, ret; 21363 21364 strcat (p_name, " taskloop"); 21365 mask |= OMP_TASKLOOP_CLAUSE_MASK; 21366 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction 21367 clause. */ 21368 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0) 21369 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION); 21370 21371 if (c_parser_next_token_is (parser, CPP_NAME)) 21372 { 21373 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 21374 21375 if (strcmp (p, "simd") == 0) 21376 { 21377 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 21378 if (cclauses == NULL) 21379 cclauses = cclauses_buf; 21380 c_parser_consume_token (parser); 21381 if (!flag_openmp) /* flag_openmp_simd */ 21382 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses, 21383 if_p); 21384 block = c_begin_compound_stmt (true); 21385 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p); 21386 block = c_end_compound_stmt (loc, block, true); 21387 if (ret == NULL) 21388 return ret; 21389 ret = make_node (OMP_TASKLOOP); 21390 TREE_TYPE (ret) = void_type_node; 21391 OMP_FOR_BODY (ret) = block; 21392 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP]; 21393 OMP_FOR_CLAUSES (ret) 21394 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret)); 21395 SET_EXPR_LOCATION (ret, loc); 21396 add_stmt (ret); 21397 return ret; 21398 } 21399 } 21400 if (!flag_openmp) /* flag_openmp_simd */ 21401 { 21402 c_parser_skip_to_pragma_eol (parser, false); 21403 return NULL_TREE; 21404 } 21405 21406 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); 21407 if (cclauses) 21408 { 21409 omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses); 21410 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP]; 21411 } 21412 21413 clauses = c_finish_taskloop_clauses (clauses); 21414 block = c_begin_compound_stmt (true); 21415 ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p); 21416 block = c_end_compound_stmt (loc, block, true); 21417 add_stmt (block); 21418 21419 return ret; 21420 } 21421 21422 /* Main entry point to parsing most OpenMP pragmas. */ 21423 21424 static void 21425 c_parser_omp_construct (c_parser *parser, bool *if_p) 21426 { 21427 enum pragma_kind p_kind; 21428 location_t loc; 21429 tree stmt; 21430 char p_name[sizeof "#pragma omp teams distribute parallel for simd"]; 21431 omp_clause_mask mask (0); 21432 21433 loc = c_parser_peek_token (parser)->location; 21434 p_kind = c_parser_peek_token (parser)->pragma_kind; 21435 c_parser_consume_pragma (parser); 21436 21437 switch (p_kind) 21438 { 21439 case PRAGMA_OACC_ATOMIC: 21440 c_parser_omp_atomic (loc, parser); 21441 return; 21442 case PRAGMA_OACC_CACHE: 21443 strcpy (p_name, "#pragma acc"); 21444 stmt = c_parser_oacc_cache (loc, parser); 21445 break; 21446 case PRAGMA_OACC_DATA: 21447 stmt = c_parser_oacc_data (loc, parser, if_p); 21448 break; 21449 case PRAGMA_OACC_HOST_DATA: 21450 stmt = c_parser_oacc_host_data (loc, parser, if_p); 21451 break; 21452 case PRAGMA_OACC_KERNELS: 21453 case PRAGMA_OACC_PARALLEL: 21454 case PRAGMA_OACC_SERIAL: 21455 strcpy (p_name, "#pragma acc"); 21456 stmt = c_parser_oacc_compute (loc, parser, p_kind, p_name, if_p); 21457 break; 21458 case PRAGMA_OACC_LOOP: 21459 strcpy (p_name, "#pragma acc"); 21460 stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p); 21461 break; 21462 case PRAGMA_OACC_WAIT: 21463 strcpy (p_name, "#pragma wait"); 21464 stmt = c_parser_oacc_wait (loc, parser, p_name); 21465 break; 21466 case PRAGMA_OMP_ATOMIC: 21467 c_parser_omp_atomic (loc, parser); 21468 return; 21469 case PRAGMA_OMP_CRITICAL: 21470 stmt = c_parser_omp_critical (loc, parser, if_p); 21471 break; 21472 case PRAGMA_OMP_DISTRIBUTE: 21473 strcpy (p_name, "#pragma omp"); 21474 stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p); 21475 break; 21476 case PRAGMA_OMP_FOR: 21477 strcpy (p_name, "#pragma omp"); 21478 stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p); 21479 break; 21480 case PRAGMA_OMP_LOOP: 21481 strcpy (p_name, "#pragma omp"); 21482 stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p); 21483 break; 21484 case PRAGMA_OMP_MASTER: 21485 strcpy (p_name, "#pragma omp"); 21486 stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p); 21487 break; 21488 case PRAGMA_OMP_PARALLEL: 21489 strcpy (p_name, "#pragma omp"); 21490 stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p); 21491 break; 21492 case PRAGMA_OMP_SECTIONS: 21493 strcpy (p_name, "#pragma omp"); 21494 stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL); 21495 break; 21496 case PRAGMA_OMP_SIMD: 21497 strcpy (p_name, "#pragma omp"); 21498 stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p); 21499 break; 21500 case PRAGMA_OMP_SINGLE: 21501 stmt = c_parser_omp_single (loc, parser, if_p); 21502 break; 21503 case PRAGMA_OMP_TASK: 21504 stmt = c_parser_omp_task (loc, parser, if_p); 21505 break; 21506 case PRAGMA_OMP_TASKGROUP: 21507 stmt = c_parser_omp_taskgroup (loc, parser, if_p); 21508 break; 21509 case PRAGMA_OMP_TASKLOOP: 21510 strcpy (p_name, "#pragma omp"); 21511 stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p); 21512 break; 21513 case PRAGMA_OMP_TEAMS: 21514 strcpy (p_name, "#pragma omp"); 21515 stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p); 21516 break; 21517 default: 21518 gcc_unreachable (); 21519 } 21520 21521 if (stmt) 21522 gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION); 21523 } 21524 21525 21526 /* OpenMP 2.5: 21527 # pragma omp threadprivate (variable-list) */ 21528 21529 static void 21530 c_parser_omp_threadprivate (c_parser *parser) 21531 { 21532 tree vars, t; 21533 location_t loc; 21534 21535 c_parser_consume_pragma (parser); 21536 loc = c_parser_peek_token (parser)->location; 21537 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL); 21538 21539 /* Mark every variable in VARS to be assigned thread local storage. */ 21540 for (t = vars; t; t = TREE_CHAIN (t)) 21541 { 21542 tree v = TREE_PURPOSE (t); 21543 21544 /* FIXME diagnostics: Ideally we should keep individual 21545 locations for all the variables in the var list to make the 21546 following errors more precise. Perhaps 21547 c_parser_omp_var_list_parens() should construct a list of 21548 locations to go along with the var list. */ 21549 21550 /* If V had already been marked threadprivate, it doesn't matter 21551 whether it had been used prior to this point. */ 21552 if (!VAR_P (v)) 21553 error_at (loc, "%qD is not a variable", v); 21554 else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v)) 21555 error_at (loc, "%qE declared %<threadprivate%> after first use", v); 21556 else if (! is_global_var (v)) 21557 error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v); 21558 else if (TREE_TYPE (v) == error_mark_node) 21559 ; 21560 else if (! COMPLETE_TYPE_P (TREE_TYPE (v))) 21561 error_at (loc, "%<threadprivate%> %qE has incomplete type", v); 21562 else 21563 { 21564 if (! DECL_THREAD_LOCAL_P (v)) 21565 { 21566 set_decl_tls_model (v, decl_default_tls_model (v)); 21567 /* If rtl has been already set for this var, call 21568 make_decl_rtl once again, so that encode_section_info 21569 has a chance to look at the new decl flags. */ 21570 if (DECL_RTL_SET_P (v)) 21571 make_decl_rtl (v); 21572 } 21573 C_DECL_THREADPRIVATE_P (v) = 1; 21574 } 21575 } 21576 21577 c_parser_skip_to_pragma_eol (parser); 21578 } 21579 21580 /* Parse a transaction attribute (GCC Extension). 21581 21582 transaction-attribute: 21583 gnu-attributes 21584 attribute-specifier 21585 */ 21586 21587 static tree 21588 c_parser_transaction_attributes (c_parser *parser) 21589 { 21590 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 21591 return c_parser_gnu_attributes (parser); 21592 21593 if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE)) 21594 return NULL_TREE; 21595 return c_parser_std_attribute_specifier (parser, true); 21596 } 21597 21598 /* Parse a __transaction_atomic or __transaction_relaxed statement 21599 (GCC Extension). 21600 21601 transaction-statement: 21602 __transaction_atomic transaction-attribute[opt] compound-statement 21603 __transaction_relaxed compound-statement 21604 21605 Note that the only valid attribute is: "outer". 21606 */ 21607 21608 static tree 21609 c_parser_transaction (c_parser *parser, enum rid keyword) 21610 { 21611 unsigned int old_in = parser->in_transaction; 21612 unsigned int this_in = 1, new_in; 21613 location_t loc = c_parser_peek_token (parser)->location; 21614 tree stmt, attrs; 21615 21616 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC 21617 || keyword == RID_TRANSACTION_RELAXED) 21618 && c_parser_next_token_is_keyword (parser, keyword)); 21619 c_parser_consume_token (parser); 21620 21621 if (keyword == RID_TRANSACTION_RELAXED) 21622 this_in |= TM_STMT_ATTR_RELAXED; 21623 else 21624 { 21625 attrs = c_parser_transaction_attributes (parser); 21626 if (attrs) 21627 this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER); 21628 } 21629 21630 /* Keep track if we're in the lexical scope of an outer transaction. */ 21631 new_in = this_in | (old_in & TM_STMT_ATTR_OUTER); 21632 21633 parser->in_transaction = new_in; 21634 stmt = c_parser_compound_statement (parser); 21635 parser->in_transaction = old_in; 21636 21637 if (flag_tm) 21638 stmt = c_finish_transaction (loc, stmt, this_in); 21639 else 21640 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ? 21641 "%<__transaction_atomic%> without transactional memory support enabled" 21642 : "%<__transaction_relaxed %> " 21643 "without transactional memory support enabled")); 21644 21645 return stmt; 21646 } 21647 21648 /* Parse a __transaction_atomic or __transaction_relaxed expression 21649 (GCC Extension). 21650 21651 transaction-expression: 21652 __transaction_atomic ( expression ) 21653 __transaction_relaxed ( expression ) 21654 */ 21655 21656 static struct c_expr 21657 c_parser_transaction_expression (c_parser *parser, enum rid keyword) 21658 { 21659 struct c_expr ret; 21660 unsigned int old_in = parser->in_transaction; 21661 unsigned int this_in = 1; 21662 location_t loc = c_parser_peek_token (parser)->location; 21663 tree attrs; 21664 21665 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC 21666 || keyword == RID_TRANSACTION_RELAXED) 21667 && c_parser_next_token_is_keyword (parser, keyword)); 21668 c_parser_consume_token (parser); 21669 21670 if (keyword == RID_TRANSACTION_RELAXED) 21671 this_in |= TM_STMT_ATTR_RELAXED; 21672 else 21673 { 21674 attrs = c_parser_transaction_attributes (parser); 21675 if (attrs) 21676 this_in |= parse_tm_stmt_attr (attrs, 0); 21677 } 21678 21679 parser->in_transaction = this_in; 21680 matching_parens parens; 21681 if (parens.require_open (parser)) 21682 { 21683 tree expr = c_parser_expression (parser).value; 21684 ret.original_type = TREE_TYPE (expr); 21685 ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr); 21686 if (this_in & TM_STMT_ATTR_RELAXED) 21687 TRANSACTION_EXPR_RELAXED (ret.value) = 1; 21688 SET_EXPR_LOCATION (ret.value, loc); 21689 ret.original_code = TRANSACTION_EXPR; 21690 if (!parens.require_close (parser)) 21691 { 21692 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 21693 goto error; 21694 } 21695 } 21696 else 21697 { 21698 error: 21699 ret.set_error (); 21700 ret.original_code = ERROR_MARK; 21701 ret.original_type = NULL; 21702 } 21703 parser->in_transaction = old_in; 21704 21705 if (!flag_tm) 21706 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ? 21707 "%<__transaction_atomic%> without transactional memory support enabled" 21708 : "%<__transaction_relaxed %> " 21709 "without transactional memory support enabled")); 21710 21711 set_c_expr_source_range (&ret, loc, loc); 21712 21713 return ret; 21714 } 21715 21716 /* Parse a __transaction_cancel statement (GCC Extension). 21717 21718 transaction-cancel-statement: 21719 __transaction_cancel transaction-attribute[opt] ; 21720 21721 Note that the only valid attribute is "outer". 21722 */ 21723 21724 static tree 21725 c_parser_transaction_cancel (c_parser *parser) 21726 { 21727 location_t loc = c_parser_peek_token (parser)->location; 21728 tree attrs; 21729 bool is_outer = false; 21730 21731 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL)); 21732 c_parser_consume_token (parser); 21733 21734 attrs = c_parser_transaction_attributes (parser); 21735 if (attrs) 21736 is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0); 21737 21738 if (!flag_tm) 21739 { 21740 error_at (loc, "%<__transaction_cancel%> without " 21741 "transactional memory support enabled"); 21742 goto ret_error; 21743 } 21744 else if (parser->in_transaction & TM_STMT_ATTR_RELAXED) 21745 { 21746 error_at (loc, "%<__transaction_cancel%> within a " 21747 "%<__transaction_relaxed%>"); 21748 goto ret_error; 21749 } 21750 else if (is_outer) 21751 { 21752 if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0 21753 && !is_tm_may_cancel_outer (current_function_decl)) 21754 { 21755 error_at (loc, "outer %<__transaction_cancel%> not " 21756 "within outer %<__transaction_atomic%> or " 21757 "a %<transaction_may_cancel_outer%> function"); 21758 goto ret_error; 21759 } 21760 } 21761 else if (parser->in_transaction == 0) 21762 { 21763 error_at (loc, "%<__transaction_cancel%> not within " 21764 "%<__transaction_atomic%>"); 21765 goto ret_error; 21766 } 21767 21768 return add_stmt (build_tm_abort_call (loc, is_outer)); 21769 21770 ret_error: 21771 return build1 (NOP_EXPR, void_type_node, error_mark_node); 21772 } 21773 21774 /* Parse a single source file. */ 21775 21776 void 21777 c_parse_file (void) 21778 { 21779 /* Use local storage to begin. If the first token is a pragma, parse it. 21780 If it is #pragma GCC pch_preprocess, then this will load a PCH file 21781 which will cause garbage collection. */ 21782 c_parser tparser; 21783 21784 memset (&tparser, 0, sizeof tparser); 21785 tparser.translate_strings_p = true; 21786 tparser.tokens = &tparser.tokens_buf[0]; 21787 the_parser = &tparser; 21788 21789 if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS) 21790 c_parser_pragma_pch_preprocess (&tparser); 21791 else 21792 c_common_no_more_pch (); 21793 21794 the_parser = ggc_alloc<c_parser> (); 21795 *the_parser = tparser; 21796 if (tparser.tokens == &tparser.tokens_buf[0]) 21797 the_parser->tokens = &the_parser->tokens_buf[0]; 21798 21799 /* Initialize EH, if we've been told to do so. */ 21800 if (flag_exceptions) 21801 using_eh_for_cleanups (); 21802 21803 c_parser_translation_unit (the_parser); 21804 the_parser = NULL; 21805 } 21806 21807 /* Parse the body of a function declaration marked with "__RTL". 21808 21809 The RTL parser works on the level of characters read from a 21810 FILE *, whereas c_parser works at the level of tokens. 21811 Square this circle by consuming all of the tokens up to and 21812 including the closing brace, recording the start/end of the RTL 21813 fragment, and reopening the file and re-reading the relevant 21814 lines within the RTL parser. 21815 21816 This requires the opening and closing braces of the C function 21817 to be on separate lines from the RTL they wrap. 21818 21819 Take ownership of START_WITH_PASS, if non-NULL. */ 21820 21821 location_t 21822 c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass) 21823 { 21824 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) 21825 { 21826 free (start_with_pass); 21827 return c_parser_peek_token (parser)->location; 21828 } 21829 21830 location_t start_loc = c_parser_peek_token (parser)->location; 21831 21832 /* Consume all tokens, up to the closing brace, handling 21833 matching pairs of braces in the rtl dump. */ 21834 int num_open_braces = 1; 21835 while (1) 21836 { 21837 switch (c_parser_peek_token (parser)->type) 21838 { 21839 case CPP_OPEN_BRACE: 21840 num_open_braces++; 21841 break; 21842 case CPP_CLOSE_BRACE: 21843 if (--num_open_braces == 0) 21844 goto found_closing_brace; 21845 break; 21846 case CPP_EOF: 21847 error_at (start_loc, "no closing brace"); 21848 free (start_with_pass); 21849 return c_parser_peek_token (parser)->location; 21850 default: 21851 break; 21852 } 21853 c_parser_consume_token (parser); 21854 } 21855 21856 found_closing_brace: 21857 /* At the closing brace; record its location. */ 21858 location_t end_loc = c_parser_peek_token (parser)->location; 21859 21860 /* Consume the closing brace. */ 21861 c_parser_consume_token (parser); 21862 21863 /* Invoke the RTL parser. */ 21864 if (!read_rtl_function_body_from_file_range (start_loc, end_loc)) 21865 { 21866 free (start_with_pass); 21867 return end_loc; 21868 } 21869 21870 /* Run the backend on the cfun created above, transferring ownership of 21871 START_WITH_PASS. */ 21872 run_rtl_passes (start_with_pass); 21873 return end_loc; 21874 } 21875 21876 #include "gt-c-c-parser.h" 21877