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 id = c_parser_peek_token (parser)->pragma_kind; 12332 gcc_assert (id != PRAGMA_NONE); 12333 12334 switch (id) 12335 { 12336 case PRAGMA_OACC_DECLARE: 12337 c_parser_oacc_declare (parser); 12338 return false; 12339 12340 case PRAGMA_OACC_ENTER_DATA: 12341 if (context != pragma_compound) 12342 { 12343 construct = "acc enter data"; 12344 in_compound: 12345 if (context == pragma_stmt) 12346 { 12347 error_at (c_parser_peek_token (parser)->location, 12348 "%<#pragma %s%> may only be used in compound " 12349 "statements", construct); 12350 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); 12351 return false; 12352 } 12353 goto bad_stmt; 12354 } 12355 c_parser_oacc_enter_exit_data (parser, true); 12356 return false; 12357 12358 case PRAGMA_OACC_EXIT_DATA: 12359 if (context != pragma_compound) 12360 { 12361 construct = "acc exit data"; 12362 goto in_compound; 12363 } 12364 c_parser_oacc_enter_exit_data (parser, false); 12365 return false; 12366 12367 case PRAGMA_OACC_ROUTINE: 12368 if (context != pragma_external) 12369 { 12370 error_at (c_parser_peek_token (parser)->location, 12371 "%<#pragma acc routine%> must be at file scope"); 12372 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); 12373 return false; 12374 } 12375 c_parser_oacc_routine (parser, context); 12376 return false; 12377 12378 case PRAGMA_OACC_UPDATE: 12379 if (context != pragma_compound) 12380 { 12381 construct = "acc update"; 12382 goto in_compound; 12383 } 12384 c_parser_oacc_update (parser); 12385 return false; 12386 12387 case PRAGMA_OMP_BARRIER: 12388 if (context != pragma_compound) 12389 { 12390 construct = "omp barrier"; 12391 goto in_compound; 12392 } 12393 c_parser_omp_barrier (parser); 12394 return false; 12395 12396 case PRAGMA_OMP_DEPOBJ: 12397 if (context != pragma_compound) 12398 { 12399 construct = "omp depobj"; 12400 goto in_compound; 12401 } 12402 c_parser_omp_depobj (parser); 12403 return false; 12404 12405 case PRAGMA_OMP_FLUSH: 12406 if (context != pragma_compound) 12407 { 12408 construct = "omp flush"; 12409 goto in_compound; 12410 } 12411 c_parser_omp_flush (parser); 12412 return false; 12413 12414 case PRAGMA_OMP_TASKWAIT: 12415 if (context != pragma_compound) 12416 { 12417 construct = "omp taskwait"; 12418 goto in_compound; 12419 } 12420 c_parser_omp_taskwait (parser); 12421 return false; 12422 12423 case PRAGMA_OMP_TASKYIELD: 12424 if (context != pragma_compound) 12425 { 12426 construct = "omp taskyield"; 12427 goto in_compound; 12428 } 12429 c_parser_omp_taskyield (parser); 12430 return false; 12431 12432 case PRAGMA_OMP_CANCEL: 12433 if (context != pragma_compound) 12434 { 12435 construct = "omp cancel"; 12436 goto in_compound; 12437 } 12438 c_parser_omp_cancel (parser); 12439 return false; 12440 12441 case PRAGMA_OMP_CANCELLATION_POINT: 12442 c_parser_omp_cancellation_point (parser, context); 12443 return false; 12444 12445 case PRAGMA_OMP_THREADPRIVATE: 12446 c_parser_omp_threadprivate (parser); 12447 return false; 12448 12449 case PRAGMA_OMP_TARGET: 12450 return c_parser_omp_target (parser, context, if_p); 12451 12452 case PRAGMA_OMP_END_DECLARE_TARGET: 12453 c_parser_omp_end_declare_target (parser); 12454 return false; 12455 12456 case PRAGMA_OMP_SCAN: 12457 error_at (c_parser_peek_token (parser)->location, 12458 "%<#pragma omp scan%> may only be used in " 12459 "a loop construct with %<inscan%> %<reduction%> clause"); 12460 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); 12461 return false; 12462 12463 case PRAGMA_OMP_SECTION: 12464 error_at (c_parser_peek_token (parser)->location, 12465 "%<#pragma omp section%> may only be used in " 12466 "%<#pragma omp sections%> construct"); 12467 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); 12468 return false; 12469 12470 case PRAGMA_OMP_DECLARE: 12471 c_parser_omp_declare (parser, context); 12472 return false; 12473 12474 case PRAGMA_OMP_REQUIRES: 12475 if (context != pragma_external) 12476 { 12477 error_at (c_parser_peek_token (parser)->location, 12478 "%<#pragma omp requires%> may only be used at file scope"); 12479 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); 12480 return false; 12481 } 12482 c_parser_omp_requires (parser); 12483 return false; 12484 12485 case PRAGMA_OMP_ORDERED: 12486 return c_parser_omp_ordered (parser, context, if_p); 12487 12488 case PRAGMA_IVDEP: 12489 { 12490 const bool ivdep = c_parse_pragma_ivdep (parser); 12491 unsigned short unroll; 12492 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_UNROLL) 12493 unroll = c_parser_pragma_unroll (parser); 12494 else 12495 unroll = 0; 12496 if (!c_parser_next_token_is_keyword (parser, RID_FOR) 12497 && !c_parser_next_token_is_keyword (parser, RID_WHILE) 12498 && !c_parser_next_token_is_keyword (parser, RID_DO)) 12499 { 12500 c_parser_error (parser, "for, while or do statement expected"); 12501 return false; 12502 } 12503 if (c_parser_next_token_is_keyword (parser, RID_FOR)) 12504 c_parser_for_statement (parser, ivdep, unroll, if_p); 12505 else if (c_parser_next_token_is_keyword (parser, RID_WHILE)) 12506 c_parser_while_statement (parser, ivdep, unroll, if_p); 12507 else 12508 c_parser_do_statement (parser, ivdep, unroll); 12509 } 12510 return false; 12511 12512 case PRAGMA_UNROLL: 12513 { 12514 unsigned short unroll = c_parser_pragma_unroll (parser); 12515 bool ivdep; 12516 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_IVDEP) 12517 ivdep = c_parse_pragma_ivdep (parser); 12518 else 12519 ivdep = false; 12520 if (!c_parser_next_token_is_keyword (parser, RID_FOR) 12521 && !c_parser_next_token_is_keyword (parser, RID_WHILE) 12522 && !c_parser_next_token_is_keyword (parser, RID_DO)) 12523 { 12524 c_parser_error (parser, "for, while or do statement expected"); 12525 return false; 12526 } 12527 if (c_parser_next_token_is_keyword (parser, RID_FOR)) 12528 c_parser_for_statement (parser, ivdep, unroll, if_p); 12529 else if (c_parser_next_token_is_keyword (parser, RID_WHILE)) 12530 c_parser_while_statement (parser, ivdep, unroll, if_p); 12531 else 12532 c_parser_do_statement (parser, ivdep, unroll); 12533 } 12534 return false; 12535 12536 case PRAGMA_GCC_PCH_PREPROCESS: 12537 c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first"); 12538 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); 12539 return false; 12540 12541 case PRAGMA_OACC_WAIT: 12542 if (context != pragma_compound) 12543 { 12544 construct = "acc wait"; 12545 goto in_compound; 12546 } 12547 /* FALL THROUGH. */ 12548 12549 default: 12550 if (id < PRAGMA_FIRST_EXTERNAL) 12551 { 12552 if (context != pragma_stmt && context != pragma_compound) 12553 { 12554 bad_stmt: 12555 c_parser_error (parser, "expected declaration specifiers"); 12556 c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL); 12557 return false; 12558 } 12559 c_parser_omp_construct (parser, if_p); 12560 return true; 12561 } 12562 break; 12563 } 12564 12565 c_parser_consume_pragma (parser); 12566 c_invoke_pragma_handler (id); 12567 12568 /* Skip to EOL, but suppress any error message. Those will have been 12569 generated by the handler routine through calling error, as opposed 12570 to calling c_parser_error. */ 12571 parser->error = true; 12572 c_parser_skip_to_pragma_eol (parser); 12573 12574 return false; 12575 } 12576 12577 /* The interface the pragma parsers have to the lexer. */ 12578 12579 enum cpp_ttype 12580 pragma_lex (tree *value, location_t *loc) 12581 { 12582 c_token *tok = c_parser_peek_token (the_parser); 12583 enum cpp_ttype ret = tok->type; 12584 12585 *value = tok->value; 12586 if (loc) 12587 *loc = tok->location; 12588 12589 if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF) 12590 ret = CPP_EOF; 12591 else if (ret == CPP_STRING) 12592 *value = c_parser_string_literal (the_parser, false, false).value; 12593 else 12594 { 12595 if (ret == CPP_KEYWORD) 12596 ret = CPP_NAME; 12597 c_parser_consume_token (the_parser); 12598 } 12599 12600 return ret; 12601 } 12602 12603 static void 12604 c_parser_pragma_pch_preprocess (c_parser *parser) 12605 { 12606 tree name = NULL; 12607 12608 parser->lex_joined_string = true; 12609 c_parser_consume_pragma (parser); 12610 if (c_parser_next_token_is (parser, CPP_STRING)) 12611 { 12612 name = c_parser_peek_token (parser)->value; 12613 c_parser_consume_token (parser); 12614 } 12615 else 12616 c_parser_error (parser, "expected string literal"); 12617 c_parser_skip_to_pragma_eol (parser); 12618 parser->lex_joined_string = false; 12619 12620 if (name) 12621 c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name)); 12622 } 12623 12624 /* OpenACC and OpenMP parsing routines. */ 12625 12626 /* Returns name of the next clause. 12627 If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and 12628 the token is not consumed. Otherwise appropriate pragma_omp_clause is 12629 returned and the token is consumed. */ 12630 12631 static pragma_omp_clause 12632 c_parser_omp_clause_name (c_parser *parser) 12633 { 12634 pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE; 12635 12636 if (c_parser_next_token_is_keyword (parser, RID_AUTO)) 12637 result = PRAGMA_OACC_CLAUSE_AUTO; 12638 else if (c_parser_next_token_is_keyword (parser, RID_IF)) 12639 result = PRAGMA_OMP_CLAUSE_IF; 12640 else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)) 12641 result = PRAGMA_OMP_CLAUSE_DEFAULT; 12642 else if (c_parser_next_token_is_keyword (parser, RID_FOR)) 12643 result = PRAGMA_OMP_CLAUSE_FOR; 12644 else if (c_parser_next_token_is (parser, CPP_NAME)) 12645 { 12646 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 12647 12648 switch (p[0]) 12649 { 12650 case 'a': 12651 if (!strcmp ("aligned", p)) 12652 result = PRAGMA_OMP_CLAUSE_ALIGNED; 12653 else if (!strcmp ("async", p)) 12654 result = PRAGMA_OACC_CLAUSE_ASYNC; 12655 else if (!strcmp ("attach", p)) 12656 result = PRAGMA_OACC_CLAUSE_ATTACH; 12657 break; 12658 case 'b': 12659 if (!strcmp ("bind", p)) 12660 result = PRAGMA_OMP_CLAUSE_BIND; 12661 break; 12662 case 'c': 12663 if (!strcmp ("collapse", p)) 12664 result = PRAGMA_OMP_CLAUSE_COLLAPSE; 12665 else if (!strcmp ("copy", p)) 12666 result = PRAGMA_OACC_CLAUSE_COPY; 12667 else if (!strcmp ("copyin", p)) 12668 result = PRAGMA_OMP_CLAUSE_COPYIN; 12669 else if (!strcmp ("copyout", p)) 12670 result = PRAGMA_OACC_CLAUSE_COPYOUT; 12671 else if (!strcmp ("copyprivate", p)) 12672 result = PRAGMA_OMP_CLAUSE_COPYPRIVATE; 12673 else if (!strcmp ("create", p)) 12674 result = PRAGMA_OACC_CLAUSE_CREATE; 12675 break; 12676 case 'd': 12677 if (!strcmp ("defaultmap", p)) 12678 result = PRAGMA_OMP_CLAUSE_DEFAULTMAP; 12679 else if (!strcmp ("delete", p)) 12680 result = PRAGMA_OACC_CLAUSE_DELETE; 12681 else if (!strcmp ("depend", p)) 12682 result = PRAGMA_OMP_CLAUSE_DEPEND; 12683 else if (!strcmp ("detach", p)) 12684 result = PRAGMA_OACC_CLAUSE_DETACH; 12685 else if (!strcmp ("device", p)) 12686 result = PRAGMA_OMP_CLAUSE_DEVICE; 12687 else if (!strcmp ("deviceptr", p)) 12688 result = PRAGMA_OACC_CLAUSE_DEVICEPTR; 12689 else if (!strcmp ("device_resident", p)) 12690 result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT; 12691 else if (!strcmp ("device_type", p)) 12692 result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE; 12693 else if (!strcmp ("dist_schedule", p)) 12694 result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE; 12695 break; 12696 case 'f': 12697 if (!strcmp ("final", p)) 12698 result = PRAGMA_OMP_CLAUSE_FINAL; 12699 else if (!strcmp ("finalize", p)) 12700 result = PRAGMA_OACC_CLAUSE_FINALIZE; 12701 else if (!strcmp ("firstprivate", p)) 12702 result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE; 12703 else if (!strcmp ("from", p)) 12704 result = PRAGMA_OMP_CLAUSE_FROM; 12705 break; 12706 case 'g': 12707 if (!strcmp ("gang", p)) 12708 result = PRAGMA_OACC_CLAUSE_GANG; 12709 else if (!strcmp ("grainsize", p)) 12710 result = PRAGMA_OMP_CLAUSE_GRAINSIZE; 12711 break; 12712 case 'h': 12713 if (!strcmp ("hint", p)) 12714 result = PRAGMA_OMP_CLAUSE_HINT; 12715 else if (!strcmp ("host", p)) 12716 result = PRAGMA_OACC_CLAUSE_HOST; 12717 break; 12718 case 'i': 12719 if (!strcmp ("if_present", p)) 12720 result = PRAGMA_OACC_CLAUSE_IF_PRESENT; 12721 else if (!strcmp ("in_reduction", p)) 12722 result = PRAGMA_OMP_CLAUSE_IN_REDUCTION; 12723 else if (!strcmp ("inbranch", p)) 12724 result = PRAGMA_OMP_CLAUSE_INBRANCH; 12725 else if (!strcmp ("independent", p)) 12726 result = PRAGMA_OACC_CLAUSE_INDEPENDENT; 12727 else if (!strcmp ("is_device_ptr", p)) 12728 result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR; 12729 break; 12730 case 'l': 12731 if (!strcmp ("lastprivate", p)) 12732 result = PRAGMA_OMP_CLAUSE_LASTPRIVATE; 12733 else if (!strcmp ("linear", p)) 12734 result = PRAGMA_OMP_CLAUSE_LINEAR; 12735 else if (!strcmp ("link", p)) 12736 result = PRAGMA_OMP_CLAUSE_LINK; 12737 break; 12738 case 'm': 12739 if (!strcmp ("map", p)) 12740 result = PRAGMA_OMP_CLAUSE_MAP; 12741 else if (!strcmp ("mergeable", p)) 12742 result = PRAGMA_OMP_CLAUSE_MERGEABLE; 12743 break; 12744 case 'n': 12745 if (!strcmp ("no_create", p)) 12746 result = PRAGMA_OACC_CLAUSE_NO_CREATE; 12747 else if (!strcmp ("nogroup", p)) 12748 result = PRAGMA_OMP_CLAUSE_NOGROUP; 12749 else if (!strcmp ("nontemporal", p)) 12750 result = PRAGMA_OMP_CLAUSE_NONTEMPORAL; 12751 else if (!strcmp ("notinbranch", p)) 12752 result = PRAGMA_OMP_CLAUSE_NOTINBRANCH; 12753 else if (!strcmp ("nowait", p)) 12754 result = PRAGMA_OMP_CLAUSE_NOWAIT; 12755 else if (!strcmp ("num_gangs", p)) 12756 result = PRAGMA_OACC_CLAUSE_NUM_GANGS; 12757 else if (!strcmp ("num_tasks", p)) 12758 result = PRAGMA_OMP_CLAUSE_NUM_TASKS; 12759 else if (!strcmp ("num_teams", p)) 12760 result = PRAGMA_OMP_CLAUSE_NUM_TEAMS; 12761 else if (!strcmp ("num_threads", p)) 12762 result = PRAGMA_OMP_CLAUSE_NUM_THREADS; 12763 else if (!strcmp ("num_workers", p)) 12764 result = PRAGMA_OACC_CLAUSE_NUM_WORKERS; 12765 break; 12766 case 'o': 12767 if (!strcmp ("ordered", p)) 12768 result = PRAGMA_OMP_CLAUSE_ORDERED; 12769 else if (!strcmp ("order", p)) 12770 result = PRAGMA_OMP_CLAUSE_ORDER; 12771 break; 12772 case 'p': 12773 if (!strcmp ("parallel", p)) 12774 result = PRAGMA_OMP_CLAUSE_PARALLEL; 12775 else if (!strcmp ("present", p)) 12776 result = PRAGMA_OACC_CLAUSE_PRESENT; 12777 /* As of OpenACC 2.5, these are now aliases of the non-present_or 12778 clauses. */ 12779 else if (!strcmp ("present_or_copy", p) 12780 || !strcmp ("pcopy", p)) 12781 result = PRAGMA_OACC_CLAUSE_COPY; 12782 else if (!strcmp ("present_or_copyin", p) 12783 || !strcmp ("pcopyin", p)) 12784 result = PRAGMA_OACC_CLAUSE_COPYIN; 12785 else if (!strcmp ("present_or_copyout", p) 12786 || !strcmp ("pcopyout", p)) 12787 result = PRAGMA_OACC_CLAUSE_COPYOUT; 12788 else if (!strcmp ("present_or_create", p) 12789 || !strcmp ("pcreate", p)) 12790 result = PRAGMA_OACC_CLAUSE_CREATE; 12791 else if (!strcmp ("priority", p)) 12792 result = PRAGMA_OMP_CLAUSE_PRIORITY; 12793 else if (!strcmp ("private", p)) 12794 result = PRAGMA_OMP_CLAUSE_PRIVATE; 12795 else if (!strcmp ("proc_bind", p)) 12796 result = PRAGMA_OMP_CLAUSE_PROC_BIND; 12797 break; 12798 case 'r': 12799 if (!strcmp ("reduction", p)) 12800 result = PRAGMA_OMP_CLAUSE_REDUCTION; 12801 break; 12802 case 's': 12803 if (!strcmp ("safelen", p)) 12804 result = PRAGMA_OMP_CLAUSE_SAFELEN; 12805 else if (!strcmp ("schedule", p)) 12806 result = PRAGMA_OMP_CLAUSE_SCHEDULE; 12807 else if (!strcmp ("sections", p)) 12808 result = PRAGMA_OMP_CLAUSE_SECTIONS; 12809 else if (!strcmp ("self", p)) /* "self" is a synonym for "host". */ 12810 result = PRAGMA_OACC_CLAUSE_HOST; 12811 else if (!strcmp ("seq", p)) 12812 result = PRAGMA_OACC_CLAUSE_SEQ; 12813 else if (!strcmp ("shared", p)) 12814 result = PRAGMA_OMP_CLAUSE_SHARED; 12815 else if (!strcmp ("simd", p)) 12816 result = PRAGMA_OMP_CLAUSE_SIMD; 12817 else if (!strcmp ("simdlen", p)) 12818 result = PRAGMA_OMP_CLAUSE_SIMDLEN; 12819 break; 12820 case 't': 12821 if (!strcmp ("task_reduction", p)) 12822 result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION; 12823 else if (!strcmp ("taskgroup", p)) 12824 result = PRAGMA_OMP_CLAUSE_TASKGROUP; 12825 else if (!strcmp ("thread_limit", p)) 12826 result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT; 12827 else if (!strcmp ("threads", p)) 12828 result = PRAGMA_OMP_CLAUSE_THREADS; 12829 else if (!strcmp ("tile", p)) 12830 result = PRAGMA_OACC_CLAUSE_TILE; 12831 else if (!strcmp ("to", p)) 12832 result = PRAGMA_OMP_CLAUSE_TO; 12833 break; 12834 case 'u': 12835 if (!strcmp ("uniform", p)) 12836 result = PRAGMA_OMP_CLAUSE_UNIFORM; 12837 else if (!strcmp ("untied", p)) 12838 result = PRAGMA_OMP_CLAUSE_UNTIED; 12839 else if (!strcmp ("use_device", p)) 12840 result = PRAGMA_OACC_CLAUSE_USE_DEVICE; 12841 else if (!strcmp ("use_device_addr", p)) 12842 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR; 12843 else if (!strcmp ("use_device_ptr", p)) 12844 result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR; 12845 break; 12846 case 'v': 12847 if (!strcmp ("vector", p)) 12848 result = PRAGMA_OACC_CLAUSE_VECTOR; 12849 else if (!strcmp ("vector_length", p)) 12850 result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH; 12851 break; 12852 case 'w': 12853 if (!strcmp ("wait", p)) 12854 result = PRAGMA_OACC_CLAUSE_WAIT; 12855 else if (!strcmp ("worker", p)) 12856 result = PRAGMA_OACC_CLAUSE_WORKER; 12857 break; 12858 } 12859 } 12860 12861 if (result != PRAGMA_OMP_CLAUSE_NONE) 12862 c_parser_consume_token (parser); 12863 12864 return result; 12865 } 12866 12867 /* Validate that a clause of the given type does not already exist. */ 12868 12869 static void 12870 check_no_duplicate_clause (tree clauses, enum omp_clause_code code, 12871 const char *name) 12872 { 12873 if (tree c = omp_find_clause (clauses, code)) 12874 error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name); 12875 } 12876 12877 /* OpenACC 2.0 12878 Parse wait clause or wait directive parameters. */ 12879 12880 static tree 12881 c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list) 12882 { 12883 vec<tree, va_gc> *args; 12884 tree t, args_tree; 12885 12886 matching_parens parens; 12887 if (!parens.require_open (parser)) 12888 return list; 12889 12890 args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL); 12891 args_tree = build_tree_list_vec (args); 12892 12893 for (t = args_tree; t; t = TREE_CHAIN (t)) 12894 { 12895 tree targ = TREE_VALUE (t); 12896 12897 if (targ != error_mark_node) 12898 { 12899 if (!INTEGRAL_TYPE_P (TREE_TYPE (targ))) 12900 { 12901 c_parser_error (parser, "expression must be integral"); 12902 targ = error_mark_node; 12903 } 12904 else 12905 { 12906 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT); 12907 12908 OMP_CLAUSE_DECL (c) = targ; 12909 OMP_CLAUSE_CHAIN (c) = list; 12910 list = c; 12911 } 12912 } 12913 } 12914 12915 release_tree_vector (args); 12916 parens.require_close (parser); 12917 return list; 12918 } 12919 12920 /* OpenACC 2.0, OpenMP 2.5: 12921 variable-list: 12922 identifier 12923 variable-list , identifier 12924 12925 If KIND is nonzero, create the appropriate node and install the 12926 decl in OMP_CLAUSE_DECL and add the node to the head of the list. 12927 If KIND is nonzero, CLAUSE_LOC is the location of the clause. 12928 12929 If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE; 12930 return the list created. 12931 12932 The optional ALLOW_DEREF argument is true if list items can use the deref 12933 (->) operator. */ 12934 12935 static tree 12936 c_parser_omp_variable_list (c_parser *parser, 12937 location_t clause_loc, 12938 enum omp_clause_code kind, tree list, 12939 bool allow_deref = false) 12940 { 12941 auto_vec<c_token> tokens; 12942 unsigned int tokens_avail = 0; 12943 bool first = true; 12944 12945 while (1) 12946 { 12947 bool array_section_p = false; 12948 if (kind == OMP_CLAUSE_DEPEND) 12949 { 12950 if (c_parser_next_token_is_not (parser, CPP_NAME) 12951 || c_parser_peek_token (parser)->id_kind != C_ID_ID) 12952 { 12953 struct c_expr expr = c_parser_expr_no_commas (parser, NULL); 12954 if (expr.value != error_mark_node) 12955 { 12956 tree u = build_omp_clause (clause_loc, kind); 12957 OMP_CLAUSE_DECL (u) = expr.value; 12958 OMP_CLAUSE_CHAIN (u) = list; 12959 list = u; 12960 } 12961 12962 if (c_parser_next_token_is_not (parser, CPP_COMMA)) 12963 break; 12964 12965 c_parser_consume_token (parser); 12966 first = false; 12967 continue; 12968 } 12969 12970 tokens.truncate (0); 12971 unsigned int nesting_depth = 0; 12972 while (1) 12973 { 12974 c_token *token = c_parser_peek_token (parser); 12975 switch (token->type) 12976 { 12977 case CPP_EOF: 12978 case CPP_PRAGMA_EOL: 12979 break; 12980 case CPP_OPEN_BRACE: 12981 case CPP_OPEN_PAREN: 12982 case CPP_OPEN_SQUARE: 12983 ++nesting_depth; 12984 goto add; 12985 case CPP_CLOSE_BRACE: 12986 case CPP_CLOSE_PAREN: 12987 case CPP_CLOSE_SQUARE: 12988 if (nesting_depth-- == 0) 12989 break; 12990 goto add; 12991 case CPP_COMMA: 12992 if (nesting_depth == 0) 12993 break; 12994 goto add; 12995 default: 12996 add: 12997 tokens.safe_push (*token); 12998 c_parser_consume_token (parser); 12999 continue; 13000 } 13001 break; 13002 } 13003 13004 /* Make sure nothing tries to read past the end of the tokens. */ 13005 c_token eof_token; 13006 memset (&eof_token, 0, sizeof (eof_token)); 13007 eof_token.type = CPP_EOF; 13008 tokens.safe_push (eof_token); 13009 tokens.safe_push (eof_token); 13010 13011 tokens_avail = parser->tokens_avail; 13012 gcc_assert (parser->tokens == &parser->tokens_buf[0]); 13013 parser->tokens = tokens.address (); 13014 parser->tokens_avail = tokens.length (); 13015 } 13016 13017 tree t = NULL_TREE; 13018 13019 if (c_parser_next_token_is (parser, CPP_NAME) 13020 && c_parser_peek_token (parser)->id_kind == C_ID_ID) 13021 { 13022 t = lookup_name (c_parser_peek_token (parser)->value); 13023 13024 if (t == NULL_TREE) 13025 { 13026 undeclared_variable (c_parser_peek_token (parser)->location, 13027 c_parser_peek_token (parser)->value); 13028 t = error_mark_node; 13029 } 13030 13031 c_parser_consume_token (parser); 13032 } 13033 else if (c_parser_next_token_is (parser, CPP_KEYWORD) 13034 && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME 13035 || (c_parser_peek_token (parser)->keyword 13036 == RID_PRETTY_FUNCTION_NAME) 13037 || (c_parser_peek_token (parser)->keyword 13038 == RID_C99_FUNCTION_NAME))) 13039 t = c_parser_predefined_identifier (parser).value; 13040 else 13041 { 13042 if (first) 13043 c_parser_error (parser, "expected identifier"); 13044 break; 13045 } 13046 13047 if (t == error_mark_node) 13048 ; 13049 else if (kind != 0) 13050 { 13051 switch (kind) 13052 { 13053 case OMP_CLAUSE__CACHE_: 13054 /* The OpenACC cache directive explicitly only allows "array 13055 elements or subarrays". */ 13056 if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE) 13057 { 13058 c_parser_error (parser, "expected %<[%>"); 13059 t = error_mark_node; 13060 break; 13061 } 13062 /* FALLTHROUGH */ 13063 case OMP_CLAUSE_MAP: 13064 case OMP_CLAUSE_FROM: 13065 case OMP_CLAUSE_TO: 13066 while (c_parser_next_token_is (parser, CPP_DOT) 13067 || (allow_deref 13068 && c_parser_next_token_is (parser, CPP_DEREF))) 13069 { 13070 location_t op_loc = c_parser_peek_token (parser)->location; 13071 if (c_parser_next_token_is (parser, CPP_DEREF)) 13072 t = build_simple_mem_ref (t); 13073 c_parser_consume_token (parser); 13074 if (!c_parser_next_token_is (parser, CPP_NAME)) 13075 { 13076 c_parser_error (parser, "expected identifier"); 13077 t = error_mark_node; 13078 break; 13079 } 13080 13081 c_token *comp_tok = c_parser_peek_token (parser); 13082 tree ident = comp_tok->value; 13083 location_t comp_loc = comp_tok->location; 13084 c_parser_consume_token (parser); 13085 t = build_component_ref (op_loc, t, ident, comp_loc); 13086 } 13087 /* FALLTHROUGH */ 13088 case OMP_CLAUSE_DEPEND: 13089 case OMP_CLAUSE_REDUCTION: 13090 case OMP_CLAUSE_IN_REDUCTION: 13091 case OMP_CLAUSE_TASK_REDUCTION: 13092 while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)) 13093 { 13094 tree low_bound = NULL_TREE, length = NULL_TREE; 13095 13096 c_parser_consume_token (parser); 13097 if (!c_parser_next_token_is (parser, CPP_COLON)) 13098 { 13099 location_t expr_loc 13100 = c_parser_peek_token (parser)->location; 13101 c_expr expr = c_parser_expression (parser); 13102 expr = convert_lvalue_to_rvalue (expr_loc, expr, 13103 false, true); 13104 low_bound = expr.value; 13105 } 13106 if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) 13107 length = integer_one_node; 13108 else 13109 { 13110 /* Look for `:'. */ 13111 if (!c_parser_require (parser, CPP_COLON, 13112 "expected %<:%>")) 13113 { 13114 t = error_mark_node; 13115 break; 13116 } 13117 array_section_p = true; 13118 if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE)) 13119 { 13120 location_t expr_loc 13121 = c_parser_peek_token (parser)->location; 13122 c_expr expr = c_parser_expression (parser); 13123 expr = convert_lvalue_to_rvalue (expr_loc, expr, 13124 false, true); 13125 length = expr.value; 13126 } 13127 } 13128 /* Look for the closing `]'. */ 13129 if (!c_parser_require (parser, CPP_CLOSE_SQUARE, 13130 "expected %<]%>")) 13131 { 13132 t = error_mark_node; 13133 break; 13134 } 13135 13136 t = tree_cons (low_bound, length, t); 13137 } 13138 if (kind == OMP_CLAUSE_DEPEND 13139 && t != error_mark_node 13140 && parser->tokens_avail != 2) 13141 { 13142 if (array_section_p) 13143 { 13144 error_at (c_parser_peek_token (parser)->location, 13145 "expected %<)%> or %<,%>"); 13146 t = error_mark_node; 13147 } 13148 else 13149 { 13150 parser->tokens = tokens.address (); 13151 parser->tokens_avail = tokens.length (); 13152 13153 t = c_parser_expr_no_commas (parser, NULL).value; 13154 if (t != error_mark_node && parser->tokens_avail != 2) 13155 { 13156 error_at (c_parser_peek_token (parser)->location, 13157 "expected %<)%> or %<,%>"); 13158 t = error_mark_node; 13159 } 13160 } 13161 } 13162 break; 13163 default: 13164 break; 13165 } 13166 13167 if (t != error_mark_node) 13168 { 13169 tree u = build_omp_clause (clause_loc, kind); 13170 OMP_CLAUSE_DECL (u) = t; 13171 OMP_CLAUSE_CHAIN (u) = list; 13172 list = u; 13173 } 13174 } 13175 else 13176 list = tree_cons (t, NULL_TREE, list); 13177 13178 if (kind == OMP_CLAUSE_DEPEND) 13179 { 13180 parser->tokens = &parser->tokens_buf[0]; 13181 parser->tokens_avail = tokens_avail; 13182 } 13183 if (c_parser_next_token_is_not (parser, CPP_COMMA)) 13184 break; 13185 13186 c_parser_consume_token (parser); 13187 first = false; 13188 } 13189 13190 return list; 13191 } 13192 13193 /* Similarly, but expect leading and trailing parenthesis. This is a very 13194 common case for OpenACC and OpenMP clauses. The optional ALLOW_DEREF 13195 argument is true if list items can use the deref (->) operator. */ 13196 13197 static tree 13198 c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind, 13199 tree list, bool allow_deref = false) 13200 { 13201 /* The clauses location. */ 13202 location_t loc = c_parser_peek_token (parser)->location; 13203 13204 matching_parens parens; 13205 if (parens.require_open (parser)) 13206 { 13207 list = c_parser_omp_variable_list (parser, loc, kind, list, allow_deref); 13208 parens.skip_until_found_close (parser); 13209 } 13210 return list; 13211 } 13212 13213 /* OpenACC 2.0: 13214 copy ( variable-list ) 13215 copyin ( variable-list ) 13216 copyout ( variable-list ) 13217 create ( variable-list ) 13218 delete ( variable-list ) 13219 present ( variable-list ) 13220 13221 OpenACC 2.6: 13222 no_create ( variable-list ) 13223 attach ( variable-list ) 13224 detach ( variable-list ) */ 13225 13226 static tree 13227 c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind, 13228 tree list) 13229 { 13230 enum gomp_map_kind kind; 13231 switch (c_kind) 13232 { 13233 case PRAGMA_OACC_CLAUSE_ATTACH: 13234 kind = GOMP_MAP_ATTACH; 13235 break; 13236 case PRAGMA_OACC_CLAUSE_COPY: 13237 kind = GOMP_MAP_TOFROM; 13238 break; 13239 case PRAGMA_OACC_CLAUSE_COPYIN: 13240 kind = GOMP_MAP_TO; 13241 break; 13242 case PRAGMA_OACC_CLAUSE_COPYOUT: 13243 kind = GOMP_MAP_FROM; 13244 break; 13245 case PRAGMA_OACC_CLAUSE_CREATE: 13246 kind = GOMP_MAP_ALLOC; 13247 break; 13248 case PRAGMA_OACC_CLAUSE_DELETE: 13249 kind = GOMP_MAP_RELEASE; 13250 break; 13251 case PRAGMA_OACC_CLAUSE_DETACH: 13252 kind = GOMP_MAP_DETACH; 13253 break; 13254 case PRAGMA_OACC_CLAUSE_DEVICE: 13255 kind = GOMP_MAP_FORCE_TO; 13256 break; 13257 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT: 13258 kind = GOMP_MAP_DEVICE_RESIDENT; 13259 break; 13260 case PRAGMA_OACC_CLAUSE_HOST: 13261 kind = GOMP_MAP_FORCE_FROM; 13262 break; 13263 case PRAGMA_OACC_CLAUSE_LINK: 13264 kind = GOMP_MAP_LINK; 13265 break; 13266 case PRAGMA_OACC_CLAUSE_NO_CREATE: 13267 kind = GOMP_MAP_IF_PRESENT; 13268 break; 13269 case PRAGMA_OACC_CLAUSE_PRESENT: 13270 kind = GOMP_MAP_FORCE_PRESENT; 13271 break; 13272 default: 13273 gcc_unreachable (); 13274 } 13275 tree nl, c; 13276 nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_MAP, list, true); 13277 13278 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) 13279 OMP_CLAUSE_SET_MAP_KIND (c, kind); 13280 13281 return nl; 13282 } 13283 13284 /* OpenACC 2.0: 13285 deviceptr ( variable-list ) */ 13286 13287 static tree 13288 c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list) 13289 { 13290 location_t loc = c_parser_peek_token (parser)->location; 13291 tree vars, t; 13292 13293 /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic 13294 c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR, 13295 variable-list must only allow for pointer variables. */ 13296 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL); 13297 for (t = vars; t && t; t = TREE_CHAIN (t)) 13298 { 13299 tree v = TREE_PURPOSE (t); 13300 13301 /* FIXME diagnostics: Ideally we should keep individual 13302 locations for all the variables in the var list to make the 13303 following errors more precise. Perhaps 13304 c_parser_omp_var_list_parens() should construct a list of 13305 locations to go along with the var list. */ 13306 13307 if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL) 13308 error_at (loc, "%qD is not a variable", v); 13309 else if (TREE_TYPE (v) == error_mark_node) 13310 ; 13311 else if (!POINTER_TYPE_P (TREE_TYPE (v))) 13312 error_at (loc, "%qD is not a pointer variable", v); 13313 13314 tree u = build_omp_clause (loc, OMP_CLAUSE_MAP); 13315 OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR); 13316 OMP_CLAUSE_DECL (u) = v; 13317 OMP_CLAUSE_CHAIN (u) = list; 13318 list = u; 13319 } 13320 13321 return list; 13322 } 13323 13324 /* OpenACC 2.0, OpenMP 3.0: 13325 collapse ( constant-expression ) */ 13326 13327 static tree 13328 c_parser_omp_clause_collapse (c_parser *parser, tree list) 13329 { 13330 tree c, num = error_mark_node; 13331 HOST_WIDE_INT n; 13332 location_t loc; 13333 13334 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse"); 13335 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile"); 13336 13337 loc = c_parser_peek_token (parser)->location; 13338 matching_parens parens; 13339 if (parens.require_open (parser)) 13340 { 13341 num = c_parser_expr_no_commas (parser, NULL).value; 13342 parens.skip_until_found_close (parser); 13343 } 13344 if (num == error_mark_node) 13345 return list; 13346 mark_exp_read (num); 13347 num = c_fully_fold (num, false, NULL); 13348 if (!INTEGRAL_TYPE_P (TREE_TYPE (num)) 13349 || !tree_fits_shwi_p (num) 13350 || (n = tree_to_shwi (num)) <= 0 13351 || (int) n != n) 13352 { 13353 error_at (loc, 13354 "collapse argument needs positive constant integer expression"); 13355 return list; 13356 } 13357 c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE); 13358 OMP_CLAUSE_COLLAPSE_EXPR (c) = num; 13359 OMP_CLAUSE_CHAIN (c) = list; 13360 return c; 13361 } 13362 13363 /* OpenMP 2.5: 13364 copyin ( variable-list ) */ 13365 13366 static tree 13367 c_parser_omp_clause_copyin (c_parser *parser, tree list) 13368 { 13369 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list); 13370 } 13371 13372 /* OpenMP 2.5: 13373 copyprivate ( variable-list ) */ 13374 13375 static tree 13376 c_parser_omp_clause_copyprivate (c_parser *parser, tree list) 13377 { 13378 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list); 13379 } 13380 13381 /* OpenMP 2.5: 13382 default ( none | shared ) 13383 13384 OpenACC: 13385 default ( none | present ) */ 13386 13387 static tree 13388 c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc) 13389 { 13390 enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED; 13391 location_t loc = c_parser_peek_token (parser)->location; 13392 tree c; 13393 13394 matching_parens parens; 13395 if (!parens.require_open (parser)) 13396 return list; 13397 if (c_parser_next_token_is (parser, CPP_NAME)) 13398 { 13399 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 13400 13401 switch (p[0]) 13402 { 13403 case 'n': 13404 if (strcmp ("none", p) != 0) 13405 goto invalid_kind; 13406 kind = OMP_CLAUSE_DEFAULT_NONE; 13407 break; 13408 13409 case 'p': 13410 if (strcmp ("present", p) != 0 || !is_oacc) 13411 goto invalid_kind; 13412 kind = OMP_CLAUSE_DEFAULT_PRESENT; 13413 break; 13414 13415 case 's': 13416 if (strcmp ("shared", p) != 0 || is_oacc) 13417 goto invalid_kind; 13418 kind = OMP_CLAUSE_DEFAULT_SHARED; 13419 break; 13420 13421 default: 13422 goto invalid_kind; 13423 } 13424 13425 c_parser_consume_token (parser); 13426 } 13427 else 13428 { 13429 invalid_kind: 13430 if (is_oacc) 13431 c_parser_error (parser, "expected %<none%> or %<present%>"); 13432 else 13433 c_parser_error (parser, "expected %<none%> or %<shared%>"); 13434 } 13435 parens.skip_until_found_close (parser); 13436 13437 if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED) 13438 return list; 13439 13440 check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default"); 13441 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT); 13442 OMP_CLAUSE_CHAIN (c) = list; 13443 OMP_CLAUSE_DEFAULT_KIND (c) = kind; 13444 13445 return c; 13446 } 13447 13448 /* OpenMP 2.5: 13449 firstprivate ( variable-list ) */ 13450 13451 static tree 13452 c_parser_omp_clause_firstprivate (c_parser *parser, tree list) 13453 { 13454 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list); 13455 } 13456 13457 /* OpenMP 3.1: 13458 final ( expression ) */ 13459 13460 static tree 13461 c_parser_omp_clause_final (c_parser *parser, tree list) 13462 { 13463 location_t loc = c_parser_peek_token (parser)->location; 13464 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 13465 { 13466 matching_parens parens; 13467 tree t, c; 13468 if (!parens.require_open (parser)) 13469 t = error_mark_node; 13470 else 13471 { 13472 location_t eloc = c_parser_peek_token (parser)->location; 13473 c_expr expr = c_parser_expr_no_commas (parser, NULL); 13474 t = convert_lvalue_to_rvalue (eloc, expr, true, true).value; 13475 t = c_objc_common_truthvalue_conversion (eloc, t); 13476 t = c_fully_fold (t, false, NULL); 13477 parens.skip_until_found_close (parser); 13478 } 13479 13480 check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final"); 13481 13482 c = build_omp_clause (loc, OMP_CLAUSE_FINAL); 13483 OMP_CLAUSE_FINAL_EXPR (c) = t; 13484 OMP_CLAUSE_CHAIN (c) = list; 13485 list = c; 13486 } 13487 else 13488 c_parser_error (parser, "expected %<(%>"); 13489 13490 return list; 13491 } 13492 13493 /* OpenACC, OpenMP 2.5: 13494 if ( expression ) 13495 13496 OpenMP 4.5: 13497 if ( directive-name-modifier : expression ) 13498 13499 directive-name-modifier: 13500 parallel | task | taskloop | target data | target | target update 13501 | target enter data | target exit data 13502 13503 OpenMP 5.0: 13504 directive-name-modifier: 13505 ... | simd | cancel */ 13506 13507 static tree 13508 c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp) 13509 { 13510 location_t location = c_parser_peek_token (parser)->location; 13511 enum tree_code if_modifier = ERROR_MARK; 13512 13513 matching_parens parens; 13514 if (!parens.require_open (parser)) 13515 return list; 13516 13517 if (is_omp && c_parser_next_token_is (parser, CPP_NAME)) 13518 { 13519 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 13520 int n = 2; 13521 if (strcmp (p, "cancel") == 0) 13522 if_modifier = VOID_CST; 13523 else if (strcmp (p, "parallel") == 0) 13524 if_modifier = OMP_PARALLEL; 13525 else if (strcmp (p, "simd") == 0) 13526 if_modifier = OMP_SIMD; 13527 else if (strcmp (p, "task") == 0) 13528 if_modifier = OMP_TASK; 13529 else if (strcmp (p, "taskloop") == 0) 13530 if_modifier = OMP_TASKLOOP; 13531 else if (strcmp (p, "target") == 0) 13532 { 13533 if_modifier = OMP_TARGET; 13534 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME) 13535 { 13536 p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value); 13537 if (strcmp ("data", p) == 0) 13538 if_modifier = OMP_TARGET_DATA; 13539 else if (strcmp ("update", p) == 0) 13540 if_modifier = OMP_TARGET_UPDATE; 13541 else if (strcmp ("enter", p) == 0) 13542 if_modifier = OMP_TARGET_ENTER_DATA; 13543 else if (strcmp ("exit", p) == 0) 13544 if_modifier = OMP_TARGET_EXIT_DATA; 13545 if (if_modifier != OMP_TARGET) 13546 { 13547 n = 3; 13548 c_parser_consume_token (parser); 13549 } 13550 else 13551 { 13552 location_t loc = c_parser_peek_2nd_token (parser)->location; 13553 error_at (loc, "expected %<data%>, %<update%>, %<enter%> " 13554 "or %<exit%>"); 13555 if_modifier = ERROR_MARK; 13556 } 13557 if (if_modifier == OMP_TARGET_ENTER_DATA 13558 || if_modifier == OMP_TARGET_EXIT_DATA) 13559 { 13560 if (c_parser_peek_2nd_token (parser)->type == CPP_NAME) 13561 { 13562 p = IDENTIFIER_POINTER 13563 (c_parser_peek_2nd_token (parser)->value); 13564 if (strcmp ("data", p) == 0) 13565 n = 4; 13566 } 13567 if (n == 4) 13568 c_parser_consume_token (parser); 13569 else 13570 { 13571 location_t loc 13572 = c_parser_peek_2nd_token (parser)->location; 13573 error_at (loc, "expected %<data%>"); 13574 if_modifier = ERROR_MARK; 13575 } 13576 } 13577 } 13578 } 13579 if (if_modifier != ERROR_MARK) 13580 { 13581 if (c_parser_peek_2nd_token (parser)->type == CPP_COLON) 13582 { 13583 c_parser_consume_token (parser); 13584 c_parser_consume_token (parser); 13585 } 13586 else 13587 { 13588 if (n > 2) 13589 { 13590 location_t loc = c_parser_peek_2nd_token (parser)->location; 13591 error_at (loc, "expected %<:%>"); 13592 } 13593 if_modifier = ERROR_MARK; 13594 } 13595 } 13596 } 13597 13598 location_t loc = c_parser_peek_token (parser)->location; 13599 c_expr expr = c_parser_expr_no_commas (parser, NULL); 13600 expr = convert_lvalue_to_rvalue (loc, expr, true, true); 13601 tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c; 13602 t = c_fully_fold (t, false, NULL); 13603 parens.skip_until_found_close (parser); 13604 13605 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c)) 13606 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF) 13607 { 13608 if (if_modifier != ERROR_MARK 13609 && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier) 13610 { 13611 const char *p = NULL; 13612 switch (if_modifier) 13613 { 13614 case VOID_CST: p = "cancel"; break; 13615 case OMP_PARALLEL: p = "parallel"; break; 13616 case OMP_SIMD: p = "simd"; break; 13617 case OMP_TASK: p = "task"; break; 13618 case OMP_TASKLOOP: p = "taskloop"; break; 13619 case OMP_TARGET_DATA: p = "target data"; break; 13620 case OMP_TARGET: p = "target"; break; 13621 case OMP_TARGET_UPDATE: p = "target update"; break; 13622 case OMP_TARGET_ENTER_DATA: p = "target enter data"; break; 13623 case OMP_TARGET_EXIT_DATA: p = "target exit data"; break; 13624 default: gcc_unreachable (); 13625 } 13626 error_at (location, "too many %<if%> clauses with %qs modifier", 13627 p); 13628 return list; 13629 } 13630 else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier) 13631 { 13632 if (!is_omp) 13633 error_at (location, "too many %<if%> clauses"); 13634 else 13635 error_at (location, "too many %<if%> clauses without modifier"); 13636 return list; 13637 } 13638 else if (if_modifier == ERROR_MARK 13639 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK) 13640 { 13641 error_at (location, "if any %<if%> clause has modifier, then all " 13642 "%<if%> clauses have to use modifier"); 13643 return list; 13644 } 13645 } 13646 13647 c = build_omp_clause (location, OMP_CLAUSE_IF); 13648 OMP_CLAUSE_IF_MODIFIER (c) = if_modifier; 13649 OMP_CLAUSE_IF_EXPR (c) = t; 13650 OMP_CLAUSE_CHAIN (c) = list; 13651 return c; 13652 } 13653 13654 /* OpenMP 2.5: 13655 lastprivate ( variable-list ) 13656 13657 OpenMP 5.0: 13658 lastprivate ( [ lastprivate-modifier : ] variable-list ) */ 13659 13660 static tree 13661 c_parser_omp_clause_lastprivate (c_parser *parser, tree list) 13662 { 13663 /* The clauses location. */ 13664 location_t loc = c_parser_peek_token (parser)->location; 13665 13666 if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 13667 { 13668 bool conditional = false; 13669 if (c_parser_next_token_is (parser, CPP_NAME) 13670 && c_parser_peek_2nd_token (parser)->type == CPP_COLON) 13671 { 13672 const char *p 13673 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 13674 if (strcmp (p, "conditional") == 0) 13675 { 13676 conditional = true; 13677 c_parser_consume_token (parser); 13678 c_parser_consume_token (parser); 13679 } 13680 } 13681 tree nlist = c_parser_omp_variable_list (parser, loc, 13682 OMP_CLAUSE_LASTPRIVATE, list); 13683 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 13684 if (conditional) 13685 for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c)) 13686 OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1; 13687 return nlist; 13688 } 13689 return list; 13690 } 13691 13692 /* OpenMP 3.1: 13693 mergeable */ 13694 13695 static tree 13696 c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list) 13697 { 13698 tree c; 13699 13700 /* FIXME: Should we allow duplicates? */ 13701 check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable"); 13702 13703 c = build_omp_clause (c_parser_peek_token (parser)->location, 13704 OMP_CLAUSE_MERGEABLE); 13705 OMP_CLAUSE_CHAIN (c) = list; 13706 13707 return c; 13708 } 13709 13710 /* OpenMP 2.5: 13711 nowait */ 13712 13713 static tree 13714 c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list) 13715 { 13716 tree c; 13717 location_t loc = c_parser_peek_token (parser)->location; 13718 13719 check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait"); 13720 13721 c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT); 13722 OMP_CLAUSE_CHAIN (c) = list; 13723 return c; 13724 } 13725 13726 /* OpenMP 2.5: 13727 num_threads ( expression ) */ 13728 13729 static tree 13730 c_parser_omp_clause_num_threads (c_parser *parser, tree list) 13731 { 13732 location_t num_threads_loc = c_parser_peek_token (parser)->location; 13733 matching_parens parens; 13734 if (parens.require_open (parser)) 13735 { 13736 location_t expr_loc = c_parser_peek_token (parser)->location; 13737 c_expr expr = c_parser_expr_no_commas (parser, NULL); 13738 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 13739 tree c, t = expr.value; 13740 t = c_fully_fold (t, false, NULL); 13741 13742 parens.skip_until_found_close (parser); 13743 13744 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 13745 { 13746 c_parser_error (parser, "expected integer expression"); 13747 return list; 13748 } 13749 13750 /* Attempt to statically determine when the number isn't positive. */ 13751 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t, 13752 build_int_cst (TREE_TYPE (t), 0)); 13753 protected_set_expr_location (c, expr_loc); 13754 if (c == boolean_true_node) 13755 { 13756 warning_at (expr_loc, 0, 13757 "%<num_threads%> value must be positive"); 13758 t = integer_one_node; 13759 } 13760 13761 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads"); 13762 13763 c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS); 13764 OMP_CLAUSE_NUM_THREADS_EXPR (c) = t; 13765 OMP_CLAUSE_CHAIN (c) = list; 13766 list = c; 13767 } 13768 13769 return list; 13770 } 13771 13772 /* OpenMP 4.5: 13773 num_tasks ( expression ) */ 13774 13775 static tree 13776 c_parser_omp_clause_num_tasks (c_parser *parser, tree list) 13777 { 13778 location_t num_tasks_loc = c_parser_peek_token (parser)->location; 13779 matching_parens parens; 13780 if (parens.require_open (parser)) 13781 { 13782 location_t expr_loc = c_parser_peek_token (parser)->location; 13783 c_expr expr = c_parser_expr_no_commas (parser, NULL); 13784 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 13785 tree c, t = expr.value; 13786 t = c_fully_fold (t, false, NULL); 13787 13788 parens.skip_until_found_close (parser); 13789 13790 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 13791 { 13792 c_parser_error (parser, "expected integer expression"); 13793 return list; 13794 } 13795 13796 /* Attempt to statically determine when the number isn't positive. */ 13797 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t, 13798 build_int_cst (TREE_TYPE (t), 0)); 13799 if (CAN_HAVE_LOCATION_P (c)) 13800 SET_EXPR_LOCATION (c, expr_loc); 13801 if (c == boolean_true_node) 13802 { 13803 warning_at (expr_loc, 0, "%<num_tasks%> value must be positive"); 13804 t = integer_one_node; 13805 } 13806 13807 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks"); 13808 13809 c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS); 13810 OMP_CLAUSE_NUM_TASKS_EXPR (c) = t; 13811 OMP_CLAUSE_CHAIN (c) = list; 13812 list = c; 13813 } 13814 13815 return list; 13816 } 13817 13818 /* OpenMP 4.5: 13819 grainsize ( expression ) */ 13820 13821 static tree 13822 c_parser_omp_clause_grainsize (c_parser *parser, tree list) 13823 { 13824 location_t grainsize_loc = c_parser_peek_token (parser)->location; 13825 matching_parens parens; 13826 if (parens.require_open (parser)) 13827 { 13828 location_t expr_loc = c_parser_peek_token (parser)->location; 13829 c_expr expr = c_parser_expr_no_commas (parser, NULL); 13830 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 13831 tree c, t = expr.value; 13832 t = c_fully_fold (t, false, NULL); 13833 13834 parens.skip_until_found_close (parser); 13835 13836 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 13837 { 13838 c_parser_error (parser, "expected integer expression"); 13839 return list; 13840 } 13841 13842 /* Attempt to statically determine when the number isn't positive. */ 13843 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t, 13844 build_int_cst (TREE_TYPE (t), 0)); 13845 if (CAN_HAVE_LOCATION_P (c)) 13846 SET_EXPR_LOCATION (c, expr_loc); 13847 if (c == boolean_true_node) 13848 { 13849 warning_at (expr_loc, 0, "%<grainsize%> value must be positive"); 13850 t = integer_one_node; 13851 } 13852 13853 check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize"); 13854 13855 c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE); 13856 OMP_CLAUSE_GRAINSIZE_EXPR (c) = t; 13857 OMP_CLAUSE_CHAIN (c) = list; 13858 list = c; 13859 } 13860 13861 return list; 13862 } 13863 13864 /* OpenMP 4.5: 13865 priority ( expression ) */ 13866 13867 static tree 13868 c_parser_omp_clause_priority (c_parser *parser, tree list) 13869 { 13870 location_t priority_loc = c_parser_peek_token (parser)->location; 13871 matching_parens parens; 13872 if (parens.require_open (parser)) 13873 { 13874 location_t expr_loc = c_parser_peek_token (parser)->location; 13875 c_expr expr = c_parser_expr_no_commas (parser, NULL); 13876 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 13877 tree c, t = expr.value; 13878 t = c_fully_fold (t, false, NULL); 13879 13880 parens.skip_until_found_close (parser); 13881 13882 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 13883 { 13884 c_parser_error (parser, "expected integer expression"); 13885 return list; 13886 } 13887 13888 /* Attempt to statically determine when the number isn't 13889 non-negative. */ 13890 c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t, 13891 build_int_cst (TREE_TYPE (t), 0)); 13892 if (CAN_HAVE_LOCATION_P (c)) 13893 SET_EXPR_LOCATION (c, expr_loc); 13894 if (c == boolean_true_node) 13895 { 13896 warning_at (expr_loc, 0, "%<priority%> value must be non-negative"); 13897 t = integer_one_node; 13898 } 13899 13900 check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority"); 13901 13902 c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY); 13903 OMP_CLAUSE_PRIORITY_EXPR (c) = t; 13904 OMP_CLAUSE_CHAIN (c) = list; 13905 list = c; 13906 } 13907 13908 return list; 13909 } 13910 13911 /* OpenMP 4.5: 13912 hint ( expression ) */ 13913 13914 static tree 13915 c_parser_omp_clause_hint (c_parser *parser, tree list) 13916 { 13917 location_t hint_loc = c_parser_peek_token (parser)->location; 13918 matching_parens parens; 13919 if (parens.require_open (parser)) 13920 { 13921 location_t expr_loc = c_parser_peek_token (parser)->location; 13922 c_expr expr = c_parser_expr_no_commas (parser, NULL); 13923 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 13924 tree c, t = expr.value; 13925 t = c_fully_fold (t, false, NULL); 13926 13927 parens.skip_until_found_close (parser); 13928 13929 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)) 13930 || TREE_CODE (t) != INTEGER_CST) 13931 { 13932 c_parser_error (parser, "expected constant integer expression"); 13933 return list; 13934 } 13935 13936 check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint"); 13937 13938 c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT); 13939 OMP_CLAUSE_HINT_EXPR (c) = t; 13940 OMP_CLAUSE_CHAIN (c) = list; 13941 list = c; 13942 } 13943 13944 return list; 13945 } 13946 13947 /* OpenMP 4.5: 13948 defaultmap ( tofrom : scalar ) 13949 13950 OpenMP 5.0: 13951 defaultmap ( implicit-behavior [ : variable-category ] ) */ 13952 13953 static tree 13954 c_parser_omp_clause_defaultmap (c_parser *parser, tree list) 13955 { 13956 location_t loc = c_parser_peek_token (parser)->location; 13957 tree c; 13958 const char *p; 13959 enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT; 13960 enum omp_clause_defaultmap_kind category 13961 = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED; 13962 13963 matching_parens parens; 13964 if (!parens.require_open (parser)) 13965 return list; 13966 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)) 13967 p = "default"; 13968 else if (!c_parser_next_token_is (parser, CPP_NAME)) 13969 { 13970 invalid_behavior: 13971 c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, " 13972 "%<tofrom%>, %<firstprivate%>, %<none%> " 13973 "or %<default%>"); 13974 goto out_err; 13975 } 13976 else 13977 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 13978 13979 switch (p[0]) 13980 { 13981 case 'a': 13982 if (strcmp ("alloc", p) == 0) 13983 behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC; 13984 else 13985 goto invalid_behavior; 13986 break; 13987 13988 case 'd': 13989 if (strcmp ("default", p) == 0) 13990 behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT; 13991 else 13992 goto invalid_behavior; 13993 break; 13994 13995 case 'f': 13996 if (strcmp ("firstprivate", p) == 0) 13997 behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE; 13998 else if (strcmp ("from", p) == 0) 13999 behavior = OMP_CLAUSE_DEFAULTMAP_FROM; 14000 else 14001 goto invalid_behavior; 14002 break; 14003 14004 case 'n': 14005 if (strcmp ("none", p) == 0) 14006 behavior = OMP_CLAUSE_DEFAULTMAP_NONE; 14007 else 14008 goto invalid_behavior; 14009 break; 14010 14011 case 't': 14012 if (strcmp ("tofrom", p) == 0) 14013 behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM; 14014 else if (strcmp ("to", p) == 0) 14015 behavior = OMP_CLAUSE_DEFAULTMAP_TO; 14016 else 14017 goto invalid_behavior; 14018 break; 14019 14020 default: 14021 goto invalid_behavior; 14022 } 14023 c_parser_consume_token (parser); 14024 14025 if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 14026 { 14027 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 14028 goto out_err; 14029 if (!c_parser_next_token_is (parser, CPP_NAME)) 14030 { 14031 invalid_category: 14032 c_parser_error (parser, "expected %<scalar%>, %<aggregate%> or " 14033 "%<pointer%>"); 14034 goto out_err; 14035 } 14036 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 14037 switch (p[0]) 14038 { 14039 case 'a': 14040 if (strcmp ("aggregate", p) == 0) 14041 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE; 14042 else 14043 goto invalid_category; 14044 break; 14045 14046 case 'p': 14047 if (strcmp ("pointer", p) == 0) 14048 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER; 14049 else 14050 goto invalid_category; 14051 break; 14052 14053 case 's': 14054 if (strcmp ("scalar", p) == 0) 14055 category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR; 14056 else 14057 goto invalid_category; 14058 break; 14059 14060 default: 14061 goto invalid_category; 14062 } 14063 14064 c_parser_consume_token (parser); 14065 } 14066 parens.skip_until_found_close (parser); 14067 14068 for (c = list; c ; c = OMP_CLAUSE_CHAIN (c)) 14069 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP 14070 && (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED 14071 || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category 14072 || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) 14073 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED))) 14074 { 14075 enum omp_clause_defaultmap_kind cat = category; 14076 location_t loc = OMP_CLAUSE_LOCATION (c); 14077 if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED) 14078 cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c); 14079 p = NULL; 14080 switch (cat) 14081 { 14082 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED: 14083 p = NULL; 14084 break; 14085 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE: 14086 p = "aggregate"; 14087 break; 14088 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER: 14089 p = "pointer"; 14090 break; 14091 case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR: 14092 p = "scalar"; 14093 break; 14094 default: 14095 gcc_unreachable (); 14096 } 14097 if (p) 14098 error_at (loc, "too many %<defaultmap%> clauses with %qs category", 14099 p); 14100 else 14101 error_at (loc, "too many %<defaultmap%> clauses with unspecified " 14102 "category"); 14103 break; 14104 } 14105 14106 c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP); 14107 OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category); 14108 OMP_CLAUSE_CHAIN (c) = list; 14109 return c; 14110 14111 out_err: 14112 parens.skip_until_found_close (parser); 14113 return list; 14114 } 14115 14116 /* OpenACC 2.0: 14117 use_device ( variable-list ) 14118 14119 OpenMP 4.5: 14120 use_device_ptr ( variable-list ) */ 14121 14122 static tree 14123 c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list) 14124 { 14125 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR, 14126 list); 14127 } 14128 14129 /* OpenMP 5.0: 14130 use_device_addr ( variable-list ) */ 14131 14132 static tree 14133 c_parser_omp_clause_use_device_addr (c_parser *parser, tree list) 14134 { 14135 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR, 14136 list); 14137 } 14138 14139 /* OpenMP 4.5: 14140 is_device_ptr ( variable-list ) */ 14141 14142 static tree 14143 c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list) 14144 { 14145 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list); 14146 } 14147 14148 /* OpenACC: 14149 num_gangs ( expression ) 14150 num_workers ( expression ) 14151 vector_length ( expression ) */ 14152 14153 static tree 14154 c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code, 14155 tree list) 14156 { 14157 location_t loc = c_parser_peek_token (parser)->location; 14158 14159 matching_parens parens; 14160 if (!parens.require_open (parser)) 14161 return list; 14162 14163 location_t expr_loc = c_parser_peek_token (parser)->location; 14164 c_expr expr = c_parser_expression (parser); 14165 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 14166 tree c, t = expr.value; 14167 t = c_fully_fold (t, false, NULL); 14168 14169 parens.skip_until_found_close (parser); 14170 14171 if (t == error_mark_node) 14172 return list; 14173 else if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 14174 { 14175 error_at (expr_loc, "%qs expression must be integral", 14176 omp_clause_code_name[code]); 14177 return list; 14178 } 14179 14180 /* Attempt to statically determine when the number isn't positive. */ 14181 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t, 14182 build_int_cst (TREE_TYPE (t), 0)); 14183 protected_set_expr_location (c, expr_loc); 14184 if (c == boolean_true_node) 14185 { 14186 warning_at (expr_loc, 0, 14187 "%qs value must be positive", 14188 omp_clause_code_name[code]); 14189 t = integer_one_node; 14190 } 14191 14192 check_no_duplicate_clause (list, code, omp_clause_code_name[code]); 14193 14194 c = build_omp_clause (loc, code); 14195 OMP_CLAUSE_OPERAND (c, 0) = t; 14196 OMP_CLAUSE_CHAIN (c) = list; 14197 return c; 14198 } 14199 14200 /* OpenACC: 14201 14202 gang [( gang-arg-list )] 14203 worker [( [num:] int-expr )] 14204 vector [( [length:] int-expr )] 14205 14206 where gang-arg is one of: 14207 14208 [num:] int-expr 14209 static: size-expr 14210 14211 and size-expr may be: 14212 14213 * 14214 int-expr 14215 */ 14216 14217 static tree 14218 c_parser_oacc_shape_clause (c_parser *parser, location_t loc, 14219 omp_clause_code kind, 14220 const char *str, tree list) 14221 { 14222 const char *id = "num"; 14223 tree ops[2] = { NULL_TREE, NULL_TREE }, c; 14224 14225 if (kind == OMP_CLAUSE_VECTOR) 14226 id = "length"; 14227 14228 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 14229 { 14230 c_parser_consume_token (parser); 14231 14232 do 14233 { 14234 c_token *next = c_parser_peek_token (parser); 14235 int idx = 0; 14236 14237 /* Gang static argument. */ 14238 if (kind == OMP_CLAUSE_GANG 14239 && c_parser_next_token_is_keyword (parser, RID_STATIC)) 14240 { 14241 c_parser_consume_token (parser); 14242 14243 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 14244 goto cleanup_error; 14245 14246 idx = 1; 14247 if (ops[idx] != NULL_TREE) 14248 { 14249 c_parser_error (parser, "too many %<static%> arguments"); 14250 goto cleanup_error; 14251 } 14252 14253 /* Check for the '*' argument. */ 14254 if (c_parser_next_token_is (parser, CPP_MULT) 14255 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA 14256 || c_parser_peek_2nd_token (parser)->type 14257 == CPP_CLOSE_PAREN)) 14258 { 14259 c_parser_consume_token (parser); 14260 ops[idx] = integer_minus_one_node; 14261 14262 if (c_parser_next_token_is (parser, CPP_COMMA)) 14263 { 14264 c_parser_consume_token (parser); 14265 continue; 14266 } 14267 else 14268 break; 14269 } 14270 } 14271 /* Worker num: argument and vector length: arguments. */ 14272 else if (c_parser_next_token_is (parser, CPP_NAME) 14273 && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0 14274 && c_parser_peek_2nd_token (parser)->type == CPP_COLON) 14275 { 14276 c_parser_consume_token (parser); /* id */ 14277 c_parser_consume_token (parser); /* ':' */ 14278 } 14279 14280 /* Now collect the actual argument. */ 14281 if (ops[idx] != NULL_TREE) 14282 { 14283 c_parser_error (parser, "unexpected argument"); 14284 goto cleanup_error; 14285 } 14286 14287 location_t expr_loc = c_parser_peek_token (parser)->location; 14288 c_expr cexpr = c_parser_expr_no_commas (parser, NULL); 14289 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true); 14290 tree expr = cexpr.value; 14291 if (expr == error_mark_node) 14292 goto cleanup_error; 14293 14294 expr = c_fully_fold (expr, false, NULL); 14295 14296 /* Attempt to statically determine when the number isn't a 14297 positive integer. */ 14298 14299 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))) 14300 { 14301 c_parser_error (parser, "expected integer expression"); 14302 return list; 14303 } 14304 14305 tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr, 14306 build_int_cst (TREE_TYPE (expr), 0)); 14307 if (c == boolean_true_node) 14308 { 14309 warning_at (loc, 0, 14310 "%qs value must be positive", str); 14311 expr = integer_one_node; 14312 } 14313 14314 ops[idx] = expr; 14315 14316 if (kind == OMP_CLAUSE_GANG 14317 && c_parser_next_token_is (parser, CPP_COMMA)) 14318 { 14319 c_parser_consume_token (parser); 14320 continue; 14321 } 14322 break; 14323 } 14324 while (1); 14325 14326 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) 14327 goto cleanup_error; 14328 } 14329 14330 check_no_duplicate_clause (list, kind, str); 14331 14332 c = build_omp_clause (loc, kind); 14333 14334 if (ops[1]) 14335 OMP_CLAUSE_OPERAND (c, 1) = ops[1]; 14336 14337 OMP_CLAUSE_OPERAND (c, 0) = ops[0]; 14338 OMP_CLAUSE_CHAIN (c) = list; 14339 14340 return c; 14341 14342 cleanup_error: 14343 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0); 14344 return list; 14345 } 14346 14347 /* OpenACC 2.5: 14348 auto 14349 finalize 14350 independent 14351 nohost 14352 seq */ 14353 14354 static tree 14355 c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code, 14356 tree list) 14357 { 14358 check_no_duplicate_clause (list, code, omp_clause_code_name[code]); 14359 14360 tree c = build_omp_clause (loc, code); 14361 OMP_CLAUSE_CHAIN (c) = list; 14362 14363 return c; 14364 } 14365 14366 /* OpenACC: 14367 async [( int-expr )] */ 14368 14369 static tree 14370 c_parser_oacc_clause_async (c_parser *parser, tree list) 14371 { 14372 tree c, t; 14373 location_t loc = c_parser_peek_token (parser)->location; 14374 14375 t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL); 14376 14377 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN) 14378 { 14379 c_parser_consume_token (parser); 14380 14381 t = c_parser_expr_no_commas (parser, NULL).value; 14382 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 14383 c_parser_error (parser, "expected integer expression"); 14384 else if (t == error_mark_node 14385 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) 14386 return list; 14387 } 14388 else 14389 t = c_fully_fold (t, false, NULL); 14390 14391 check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async"); 14392 14393 c = build_omp_clause (loc, OMP_CLAUSE_ASYNC); 14394 OMP_CLAUSE_ASYNC_EXPR (c) = t; 14395 OMP_CLAUSE_CHAIN (c) = list; 14396 list = c; 14397 14398 return list; 14399 } 14400 14401 /* OpenACC 2.0: 14402 tile ( size-expr-list ) */ 14403 14404 static tree 14405 c_parser_oacc_clause_tile (c_parser *parser, tree list) 14406 { 14407 tree c, expr = error_mark_node; 14408 location_t loc; 14409 tree tile = NULL_TREE; 14410 14411 check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile"); 14412 check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse"); 14413 14414 loc = c_parser_peek_token (parser)->location; 14415 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 14416 return list; 14417 14418 do 14419 { 14420 if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>")) 14421 return list; 14422 14423 if (c_parser_next_token_is (parser, CPP_MULT) 14424 && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA 14425 || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN)) 14426 { 14427 c_parser_consume_token (parser); 14428 expr = integer_zero_node; 14429 } 14430 else 14431 { 14432 location_t expr_loc = c_parser_peek_token (parser)->location; 14433 c_expr cexpr = c_parser_expr_no_commas (parser, NULL); 14434 cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true); 14435 expr = cexpr.value; 14436 14437 if (expr == error_mark_node) 14438 { 14439 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 14440 "expected %<)%>"); 14441 return list; 14442 } 14443 14444 expr = c_fully_fold (expr, false, NULL); 14445 14446 if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)) 14447 || !tree_fits_shwi_p (expr) 14448 || tree_to_shwi (expr) <= 0) 14449 { 14450 error_at (expr_loc, "%<tile%> argument needs positive" 14451 " integral constant"); 14452 expr = integer_zero_node; 14453 } 14454 } 14455 14456 tile = tree_cons (NULL_TREE, expr, tile); 14457 } 14458 while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN)); 14459 14460 /* Consume the trailing ')'. */ 14461 c_parser_consume_token (parser); 14462 14463 c = build_omp_clause (loc, OMP_CLAUSE_TILE); 14464 tile = nreverse (tile); 14465 OMP_CLAUSE_TILE_LIST (c) = tile; 14466 OMP_CLAUSE_CHAIN (c) = list; 14467 return c; 14468 } 14469 14470 /* OpenACC: 14471 wait [( int-expr-list )] */ 14472 14473 static tree 14474 c_parser_oacc_clause_wait (c_parser *parser, tree list) 14475 { 14476 location_t clause_loc = c_parser_peek_token (parser)->location; 14477 14478 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN) 14479 list = c_parser_oacc_wait_list (parser, clause_loc, list); 14480 else 14481 { 14482 tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT); 14483 14484 OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL); 14485 OMP_CLAUSE_CHAIN (c) = list; 14486 list = c; 14487 } 14488 14489 return list; 14490 } 14491 14492 14493 /* OpenMP 5.0: 14494 order ( concurrent ) */ 14495 14496 static tree 14497 c_parser_omp_clause_order (c_parser *parser, tree list) 14498 { 14499 location_t loc = c_parser_peek_token (parser)->location; 14500 tree c; 14501 const char *p; 14502 14503 matching_parens parens; 14504 if (!parens.require_open (parser)) 14505 return list; 14506 if (!c_parser_next_token_is (parser, CPP_NAME)) 14507 { 14508 c_parser_error (parser, "expected %<concurrent%>"); 14509 goto out_err; 14510 } 14511 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 14512 if (strcmp (p, "concurrent") != 0) 14513 { 14514 c_parser_error (parser, "expected %<concurrent%>"); 14515 goto out_err; 14516 } 14517 c_parser_consume_token (parser); 14518 parens.skip_until_found_close (parser); 14519 /* check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order"); */ 14520 c = build_omp_clause (loc, OMP_CLAUSE_ORDER); 14521 OMP_CLAUSE_CHAIN (c) = list; 14522 return c; 14523 14524 out_err: 14525 parens.skip_until_found_close (parser); 14526 return list; 14527 } 14528 14529 14530 /* OpenMP 5.0: 14531 bind ( teams | parallel | thread ) */ 14532 14533 static tree 14534 c_parser_omp_clause_bind (c_parser *parser, tree list) 14535 { 14536 location_t loc = c_parser_peek_token (parser)->location; 14537 tree c; 14538 const char *p; 14539 enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD; 14540 14541 matching_parens parens; 14542 if (!parens.require_open (parser)) 14543 return list; 14544 if (!c_parser_next_token_is (parser, CPP_NAME)) 14545 { 14546 invalid: 14547 c_parser_error (parser, 14548 "expected %<teams%>, %<parallel%> or %<thread%>"); 14549 parens.skip_until_found_close (parser); 14550 return list; 14551 } 14552 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 14553 if (strcmp (p, "teams") == 0) 14554 kind = OMP_CLAUSE_BIND_TEAMS; 14555 else if (strcmp (p, "parallel") == 0) 14556 kind = OMP_CLAUSE_BIND_PARALLEL; 14557 else if (strcmp (p, "thread") != 0) 14558 goto invalid; 14559 c_parser_consume_token (parser); 14560 parens.skip_until_found_close (parser); 14561 /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */ 14562 c = build_omp_clause (loc, OMP_CLAUSE_BIND); 14563 OMP_CLAUSE_BIND_KIND (c) = kind; 14564 OMP_CLAUSE_CHAIN (c) = list; 14565 return c; 14566 } 14567 14568 14569 /* OpenMP 2.5: 14570 ordered 14571 14572 OpenMP 4.5: 14573 ordered ( constant-expression ) */ 14574 14575 static tree 14576 c_parser_omp_clause_ordered (c_parser *parser, tree list) 14577 { 14578 check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered"); 14579 14580 tree c, num = NULL_TREE; 14581 HOST_WIDE_INT n; 14582 location_t loc = c_parser_peek_token (parser)->location; 14583 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 14584 { 14585 matching_parens parens; 14586 parens.consume_open (parser); 14587 num = c_parser_expr_no_commas (parser, NULL).value; 14588 parens.skip_until_found_close (parser); 14589 } 14590 if (num == error_mark_node) 14591 return list; 14592 if (num) 14593 { 14594 mark_exp_read (num); 14595 num = c_fully_fold (num, false, NULL); 14596 if (!INTEGRAL_TYPE_P (TREE_TYPE (num)) 14597 || !tree_fits_shwi_p (num) 14598 || (n = tree_to_shwi (num)) <= 0 14599 || (int) n != n) 14600 { 14601 error_at (loc, "ordered argument needs positive " 14602 "constant integer expression"); 14603 return list; 14604 } 14605 } 14606 c = build_omp_clause (loc, OMP_CLAUSE_ORDERED); 14607 OMP_CLAUSE_ORDERED_EXPR (c) = num; 14608 OMP_CLAUSE_CHAIN (c) = list; 14609 return c; 14610 } 14611 14612 /* OpenMP 2.5: 14613 private ( variable-list ) */ 14614 14615 static tree 14616 c_parser_omp_clause_private (c_parser *parser, tree list) 14617 { 14618 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list); 14619 } 14620 14621 /* OpenMP 2.5: 14622 reduction ( reduction-operator : variable-list ) 14623 14624 reduction-operator: 14625 One of: + * - & ^ | && || 14626 14627 OpenMP 3.1: 14628 14629 reduction-operator: 14630 One of: + * - & ^ | && || max min 14631 14632 OpenMP 4.0: 14633 14634 reduction-operator: 14635 One of: + * - & ^ | && || 14636 identifier 14637 14638 OpenMP 5.0: 14639 reduction ( reduction-modifier, reduction-operator : variable-list ) 14640 in_reduction ( reduction-operator : variable-list ) 14641 task_reduction ( reduction-operator : variable-list ) */ 14642 14643 static tree 14644 c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind, 14645 bool is_omp, tree list) 14646 { 14647 location_t clause_loc = c_parser_peek_token (parser)->location; 14648 matching_parens parens; 14649 if (parens.require_open (parser)) 14650 { 14651 bool task = false; 14652 bool inscan = false; 14653 enum tree_code code = ERROR_MARK; 14654 tree reduc_id = NULL_TREE; 14655 14656 if (kind == OMP_CLAUSE_REDUCTION && is_omp) 14657 { 14658 if (c_parser_next_token_is_keyword (parser, RID_DEFAULT) 14659 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA) 14660 { 14661 c_parser_consume_token (parser); 14662 c_parser_consume_token (parser); 14663 } 14664 else if (c_parser_next_token_is (parser, CPP_NAME) 14665 && c_parser_peek_2nd_token (parser)->type == CPP_COMMA) 14666 { 14667 const char *p 14668 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 14669 if (strcmp (p, "task") == 0) 14670 task = true; 14671 else if (strcmp (p, "inscan") == 0) 14672 inscan = true; 14673 if (task || inscan) 14674 { 14675 c_parser_consume_token (parser); 14676 c_parser_consume_token (parser); 14677 } 14678 } 14679 } 14680 14681 switch (c_parser_peek_token (parser)->type) 14682 { 14683 case CPP_PLUS: 14684 code = PLUS_EXPR; 14685 break; 14686 case CPP_MULT: 14687 code = MULT_EXPR; 14688 break; 14689 case CPP_MINUS: 14690 code = MINUS_EXPR; 14691 break; 14692 case CPP_AND: 14693 code = BIT_AND_EXPR; 14694 break; 14695 case CPP_XOR: 14696 code = BIT_XOR_EXPR; 14697 break; 14698 case CPP_OR: 14699 code = BIT_IOR_EXPR; 14700 break; 14701 case CPP_AND_AND: 14702 code = TRUTH_ANDIF_EXPR; 14703 break; 14704 case CPP_OR_OR: 14705 code = TRUTH_ORIF_EXPR; 14706 break; 14707 case CPP_NAME: 14708 { 14709 const char *p 14710 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 14711 if (strcmp (p, "min") == 0) 14712 { 14713 code = MIN_EXPR; 14714 break; 14715 } 14716 if (strcmp (p, "max") == 0) 14717 { 14718 code = MAX_EXPR; 14719 break; 14720 } 14721 reduc_id = c_parser_peek_token (parser)->value; 14722 break; 14723 } 14724 default: 14725 c_parser_error (parser, 14726 "expected %<+%>, %<*%>, %<-%>, %<&%>, " 14727 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier"); 14728 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0); 14729 return list; 14730 } 14731 c_parser_consume_token (parser); 14732 reduc_id = c_omp_reduction_id (code, reduc_id); 14733 if (c_parser_require (parser, CPP_COLON, "expected %<:%>")) 14734 { 14735 tree nl, c; 14736 14737 nl = c_parser_omp_variable_list (parser, clause_loc, kind, list); 14738 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) 14739 { 14740 tree d = OMP_CLAUSE_DECL (c), type; 14741 if (TREE_CODE (d) != TREE_LIST) 14742 type = TREE_TYPE (d); 14743 else 14744 { 14745 int cnt = 0; 14746 tree t; 14747 for (t = d; TREE_CODE (t) == TREE_LIST; t = TREE_CHAIN (t)) 14748 cnt++; 14749 type = TREE_TYPE (t); 14750 while (cnt > 0) 14751 { 14752 if (TREE_CODE (type) != POINTER_TYPE 14753 && TREE_CODE (type) != ARRAY_TYPE) 14754 break; 14755 type = TREE_TYPE (type); 14756 cnt--; 14757 } 14758 } 14759 while (TREE_CODE (type) == ARRAY_TYPE) 14760 type = TREE_TYPE (type); 14761 OMP_CLAUSE_REDUCTION_CODE (c) = code; 14762 if (task) 14763 OMP_CLAUSE_REDUCTION_TASK (c) = 1; 14764 else if (inscan) 14765 OMP_CLAUSE_REDUCTION_INSCAN (c) = 1; 14766 if (code == ERROR_MARK 14767 || !(INTEGRAL_TYPE_P (type) 14768 || TREE_CODE (type) == REAL_TYPE 14769 || TREE_CODE (type) == COMPLEX_TYPE)) 14770 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) 14771 = c_omp_reduction_lookup (reduc_id, 14772 TYPE_MAIN_VARIANT (type)); 14773 } 14774 14775 list = nl; 14776 } 14777 parens.skip_until_found_close (parser); 14778 } 14779 return list; 14780 } 14781 14782 /* OpenMP 2.5: 14783 schedule ( schedule-kind ) 14784 schedule ( schedule-kind , expression ) 14785 14786 schedule-kind: 14787 static | dynamic | guided | runtime | auto 14788 14789 OpenMP 4.5: 14790 schedule ( schedule-modifier : schedule-kind ) 14791 schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression ) 14792 14793 schedule-modifier: 14794 simd 14795 monotonic 14796 nonmonotonic */ 14797 14798 static tree 14799 c_parser_omp_clause_schedule (c_parser *parser, tree list) 14800 { 14801 tree c, t; 14802 location_t loc = c_parser_peek_token (parser)->location; 14803 int modifiers = 0, nmodifiers = 0; 14804 14805 matching_parens parens; 14806 if (!parens.require_open (parser)) 14807 return list; 14808 14809 c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE); 14810 14811 while (c_parser_next_token_is (parser, CPP_NAME)) 14812 { 14813 tree kind = c_parser_peek_token (parser)->value; 14814 const char *p = IDENTIFIER_POINTER (kind); 14815 if (strcmp ("simd", p) == 0) 14816 OMP_CLAUSE_SCHEDULE_SIMD (c) = 1; 14817 else if (strcmp ("monotonic", p) == 0) 14818 modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC; 14819 else if (strcmp ("nonmonotonic", p) == 0) 14820 modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC; 14821 else 14822 break; 14823 c_parser_consume_token (parser); 14824 if (nmodifiers++ == 0 14825 && c_parser_next_token_is (parser, CPP_COMMA)) 14826 c_parser_consume_token (parser); 14827 else 14828 { 14829 c_parser_require (parser, CPP_COLON, "expected %<:%>"); 14830 break; 14831 } 14832 } 14833 14834 if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC 14835 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC)) 14836 == (OMP_CLAUSE_SCHEDULE_MONOTONIC 14837 | OMP_CLAUSE_SCHEDULE_NONMONOTONIC)) 14838 { 14839 error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers " 14840 "specified"); 14841 modifiers = 0; 14842 } 14843 14844 if (c_parser_next_token_is (parser, CPP_NAME)) 14845 { 14846 tree kind = c_parser_peek_token (parser)->value; 14847 const char *p = IDENTIFIER_POINTER (kind); 14848 14849 switch (p[0]) 14850 { 14851 case 'd': 14852 if (strcmp ("dynamic", p) != 0) 14853 goto invalid_kind; 14854 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC; 14855 break; 14856 14857 case 'g': 14858 if (strcmp ("guided", p) != 0) 14859 goto invalid_kind; 14860 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED; 14861 break; 14862 14863 case 'r': 14864 if (strcmp ("runtime", p) != 0) 14865 goto invalid_kind; 14866 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME; 14867 break; 14868 14869 default: 14870 goto invalid_kind; 14871 } 14872 } 14873 else if (c_parser_next_token_is_keyword (parser, RID_STATIC)) 14874 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC; 14875 else if (c_parser_next_token_is_keyword (parser, RID_AUTO)) 14876 OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO; 14877 else 14878 goto invalid_kind; 14879 14880 c_parser_consume_token (parser); 14881 if (c_parser_next_token_is (parser, CPP_COMMA)) 14882 { 14883 location_t here; 14884 c_parser_consume_token (parser); 14885 14886 here = c_parser_peek_token (parser)->location; 14887 c_expr expr = c_parser_expr_no_commas (parser, NULL); 14888 expr = convert_lvalue_to_rvalue (here, expr, false, true); 14889 t = expr.value; 14890 t = c_fully_fold (t, false, NULL); 14891 14892 if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME) 14893 error_at (here, "schedule %<runtime%> does not take " 14894 "a %<chunk_size%> parameter"); 14895 else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO) 14896 error_at (here, 14897 "schedule %<auto%> does not take " 14898 "a %<chunk_size%> parameter"); 14899 else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE) 14900 { 14901 /* Attempt to statically determine when the number isn't 14902 positive. */ 14903 tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t, 14904 build_int_cst (TREE_TYPE (t), 0)); 14905 protected_set_expr_location (s, loc); 14906 if (s == boolean_true_node) 14907 { 14908 warning_at (loc, 0, 14909 "chunk size value must be positive"); 14910 t = integer_one_node; 14911 } 14912 OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t; 14913 } 14914 else 14915 c_parser_error (parser, "expected integer expression"); 14916 14917 parens.skip_until_found_close (parser); 14918 } 14919 else 14920 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 14921 "expected %<,%> or %<)%>"); 14922 14923 OMP_CLAUSE_SCHEDULE_KIND (c) 14924 = (enum omp_clause_schedule_kind) 14925 (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers); 14926 14927 check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule"); 14928 OMP_CLAUSE_CHAIN (c) = list; 14929 return c; 14930 14931 invalid_kind: 14932 c_parser_error (parser, "invalid schedule kind"); 14933 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0); 14934 return list; 14935 } 14936 14937 /* OpenMP 2.5: 14938 shared ( variable-list ) */ 14939 14940 static tree 14941 c_parser_omp_clause_shared (c_parser *parser, tree list) 14942 { 14943 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list); 14944 } 14945 14946 /* OpenMP 3.0: 14947 untied */ 14948 14949 static tree 14950 c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list) 14951 { 14952 tree c; 14953 14954 /* FIXME: Should we allow duplicates? */ 14955 check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied"); 14956 14957 c = build_omp_clause (c_parser_peek_token (parser)->location, 14958 OMP_CLAUSE_UNTIED); 14959 OMP_CLAUSE_CHAIN (c) = list; 14960 14961 return c; 14962 } 14963 14964 /* OpenMP 4.0: 14965 inbranch 14966 notinbranch */ 14967 14968 static tree 14969 c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED, 14970 enum omp_clause_code code, tree list) 14971 { 14972 check_no_duplicate_clause (list, code, omp_clause_code_name[code]); 14973 14974 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code); 14975 OMP_CLAUSE_CHAIN (c) = list; 14976 14977 return c; 14978 } 14979 14980 /* OpenMP 4.0: 14981 parallel 14982 for 14983 sections 14984 taskgroup */ 14985 14986 static tree 14987 c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED, 14988 enum omp_clause_code code, tree list) 14989 { 14990 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code); 14991 OMP_CLAUSE_CHAIN (c) = list; 14992 14993 return c; 14994 } 14995 14996 /* OpenMP 4.5: 14997 nogroup */ 14998 14999 static tree 15000 c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list) 15001 { 15002 check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup"); 15003 tree c = build_omp_clause (c_parser_peek_token (parser)->location, 15004 OMP_CLAUSE_NOGROUP); 15005 OMP_CLAUSE_CHAIN (c) = list; 15006 return c; 15007 } 15008 15009 /* OpenMP 4.5: 15010 simd 15011 threads */ 15012 15013 static tree 15014 c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED, 15015 enum omp_clause_code code, tree list) 15016 { 15017 check_no_duplicate_clause (list, code, omp_clause_code_name[code]); 15018 tree c = build_omp_clause (c_parser_peek_token (parser)->location, code); 15019 OMP_CLAUSE_CHAIN (c) = list; 15020 return c; 15021 } 15022 15023 /* OpenMP 4.0: 15024 num_teams ( expression ) */ 15025 15026 static tree 15027 c_parser_omp_clause_num_teams (c_parser *parser, tree list) 15028 { 15029 location_t num_teams_loc = c_parser_peek_token (parser)->location; 15030 matching_parens parens; 15031 if (parens.require_open (parser)) 15032 { 15033 location_t expr_loc = c_parser_peek_token (parser)->location; 15034 c_expr expr = c_parser_expr_no_commas (parser, NULL); 15035 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 15036 tree c, t = expr.value; 15037 t = c_fully_fold (t, false, NULL); 15038 15039 parens.skip_until_found_close (parser); 15040 15041 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 15042 { 15043 c_parser_error (parser, "expected integer expression"); 15044 return list; 15045 } 15046 15047 /* Attempt to statically determine when the number isn't positive. */ 15048 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t, 15049 build_int_cst (TREE_TYPE (t), 0)); 15050 protected_set_expr_location (c, expr_loc); 15051 if (c == boolean_true_node) 15052 { 15053 warning_at (expr_loc, 0, "%<num_teams%> value must be positive"); 15054 t = integer_one_node; 15055 } 15056 15057 check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams"); 15058 15059 c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS); 15060 OMP_CLAUSE_NUM_TEAMS_EXPR (c) = t; 15061 OMP_CLAUSE_CHAIN (c) = list; 15062 list = c; 15063 } 15064 15065 return list; 15066 } 15067 15068 /* OpenMP 4.0: 15069 thread_limit ( expression ) */ 15070 15071 static tree 15072 c_parser_omp_clause_thread_limit (c_parser *parser, tree list) 15073 { 15074 location_t num_thread_limit_loc = c_parser_peek_token (parser)->location; 15075 matching_parens parens; 15076 if (parens.require_open (parser)) 15077 { 15078 location_t expr_loc = c_parser_peek_token (parser)->location; 15079 c_expr expr = c_parser_expr_no_commas (parser, NULL); 15080 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 15081 tree c, t = expr.value; 15082 t = c_fully_fold (t, false, NULL); 15083 15084 parens.skip_until_found_close (parser); 15085 15086 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 15087 { 15088 c_parser_error (parser, "expected integer expression"); 15089 return list; 15090 } 15091 15092 /* Attempt to statically determine when the number isn't positive. */ 15093 c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t, 15094 build_int_cst (TREE_TYPE (t), 0)); 15095 protected_set_expr_location (c, expr_loc); 15096 if (c == boolean_true_node) 15097 { 15098 warning_at (expr_loc, 0, "%<thread_limit%> value must be positive"); 15099 t = integer_one_node; 15100 } 15101 15102 check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT, 15103 "thread_limit"); 15104 15105 c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT); 15106 OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t; 15107 OMP_CLAUSE_CHAIN (c) = list; 15108 list = c; 15109 } 15110 15111 return list; 15112 } 15113 15114 /* OpenMP 4.0: 15115 aligned ( variable-list ) 15116 aligned ( variable-list : constant-expression ) */ 15117 15118 static tree 15119 c_parser_omp_clause_aligned (c_parser *parser, tree list) 15120 { 15121 location_t clause_loc = c_parser_peek_token (parser)->location; 15122 tree nl, c; 15123 15124 matching_parens parens; 15125 if (!parens.require_open (parser)) 15126 return list; 15127 15128 nl = c_parser_omp_variable_list (parser, clause_loc, 15129 OMP_CLAUSE_ALIGNED, list); 15130 15131 if (c_parser_next_token_is (parser, CPP_COLON)) 15132 { 15133 c_parser_consume_token (parser); 15134 location_t expr_loc = c_parser_peek_token (parser)->location; 15135 c_expr expr = c_parser_expr_no_commas (parser, NULL); 15136 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 15137 tree alignment = expr.value; 15138 alignment = c_fully_fold (alignment, false, NULL); 15139 if (TREE_CODE (alignment) != INTEGER_CST 15140 || !INTEGRAL_TYPE_P (TREE_TYPE (alignment)) 15141 || tree_int_cst_sgn (alignment) != 1) 15142 { 15143 error_at (clause_loc, "%<aligned%> clause alignment expression must " 15144 "be positive constant integer expression"); 15145 alignment = NULL_TREE; 15146 } 15147 15148 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) 15149 OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment; 15150 } 15151 15152 parens.skip_until_found_close (parser); 15153 return nl; 15154 } 15155 15156 /* OpenMP 4.0: 15157 linear ( variable-list ) 15158 linear ( variable-list : expression ) 15159 15160 OpenMP 4.5: 15161 linear ( modifier ( variable-list ) ) 15162 linear ( modifier ( variable-list ) : expression ) */ 15163 15164 static tree 15165 c_parser_omp_clause_linear (c_parser *parser, tree list) 15166 { 15167 location_t clause_loc = c_parser_peek_token (parser)->location; 15168 tree nl, c, step; 15169 enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT; 15170 15171 matching_parens parens; 15172 if (!parens.require_open (parser)) 15173 return list; 15174 15175 if (c_parser_next_token_is (parser, CPP_NAME)) 15176 { 15177 c_token *tok = c_parser_peek_token (parser); 15178 const char *p = IDENTIFIER_POINTER (tok->value); 15179 if (strcmp ("val", p) == 0) 15180 kind = OMP_CLAUSE_LINEAR_VAL; 15181 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN) 15182 kind = OMP_CLAUSE_LINEAR_DEFAULT; 15183 if (kind != OMP_CLAUSE_LINEAR_DEFAULT) 15184 { 15185 c_parser_consume_token (parser); 15186 c_parser_consume_token (parser); 15187 } 15188 } 15189 15190 nl = c_parser_omp_variable_list (parser, clause_loc, 15191 OMP_CLAUSE_LINEAR, list); 15192 15193 if (kind != OMP_CLAUSE_LINEAR_DEFAULT) 15194 parens.skip_until_found_close (parser); 15195 15196 if (c_parser_next_token_is (parser, CPP_COLON)) 15197 { 15198 c_parser_consume_token (parser); 15199 location_t expr_loc = c_parser_peek_token (parser)->location; 15200 c_expr expr = c_parser_expr_no_commas (parser, NULL); 15201 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 15202 step = expr.value; 15203 step = c_fully_fold (step, false, NULL); 15204 if (!INTEGRAL_TYPE_P (TREE_TYPE (step))) 15205 { 15206 error_at (clause_loc, "%<linear%> clause step expression must " 15207 "be integral"); 15208 step = integer_one_node; 15209 } 15210 15211 } 15212 else 15213 step = integer_one_node; 15214 15215 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) 15216 { 15217 OMP_CLAUSE_LINEAR_STEP (c) = step; 15218 OMP_CLAUSE_LINEAR_KIND (c) = kind; 15219 } 15220 15221 parens.skip_until_found_close (parser); 15222 return nl; 15223 } 15224 15225 /* OpenMP 5.0: 15226 nontemporal ( variable-list ) */ 15227 15228 static tree 15229 c_parser_omp_clause_nontemporal (c_parser *parser, tree list) 15230 { 15231 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list); 15232 } 15233 15234 /* OpenMP 4.0: 15235 safelen ( constant-expression ) */ 15236 15237 static tree 15238 c_parser_omp_clause_safelen (c_parser *parser, tree list) 15239 { 15240 location_t clause_loc = c_parser_peek_token (parser)->location; 15241 tree c, t; 15242 15243 matching_parens parens; 15244 if (!parens.require_open (parser)) 15245 return list; 15246 15247 location_t expr_loc = c_parser_peek_token (parser)->location; 15248 c_expr expr = c_parser_expr_no_commas (parser, NULL); 15249 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 15250 t = expr.value; 15251 t = c_fully_fold (t, false, NULL); 15252 if (TREE_CODE (t) != INTEGER_CST 15253 || !INTEGRAL_TYPE_P (TREE_TYPE (t)) 15254 || tree_int_cst_sgn (t) != 1) 15255 { 15256 error_at (clause_loc, "%<safelen%> clause expression must " 15257 "be positive constant integer expression"); 15258 t = NULL_TREE; 15259 } 15260 15261 parens.skip_until_found_close (parser); 15262 if (t == NULL_TREE || t == error_mark_node) 15263 return list; 15264 15265 check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen"); 15266 15267 c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN); 15268 OMP_CLAUSE_SAFELEN_EXPR (c) = t; 15269 OMP_CLAUSE_CHAIN (c) = list; 15270 return c; 15271 } 15272 15273 /* OpenMP 4.0: 15274 simdlen ( constant-expression ) */ 15275 15276 static tree 15277 c_parser_omp_clause_simdlen (c_parser *parser, tree list) 15278 { 15279 location_t clause_loc = c_parser_peek_token (parser)->location; 15280 tree c, t; 15281 15282 matching_parens parens; 15283 if (!parens.require_open (parser)) 15284 return list; 15285 15286 location_t expr_loc = c_parser_peek_token (parser)->location; 15287 c_expr expr = c_parser_expr_no_commas (parser, NULL); 15288 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 15289 t = expr.value; 15290 t = c_fully_fold (t, false, NULL); 15291 if (TREE_CODE (t) != INTEGER_CST 15292 || !INTEGRAL_TYPE_P (TREE_TYPE (t)) 15293 || tree_int_cst_sgn (t) != 1) 15294 { 15295 error_at (clause_loc, "%<simdlen%> clause expression must " 15296 "be positive constant integer expression"); 15297 t = NULL_TREE; 15298 } 15299 15300 parens.skip_until_found_close (parser); 15301 if (t == NULL_TREE || t == error_mark_node) 15302 return list; 15303 15304 check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen"); 15305 15306 c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN); 15307 OMP_CLAUSE_SIMDLEN_EXPR (c) = t; 15308 OMP_CLAUSE_CHAIN (c) = list; 15309 return c; 15310 } 15311 15312 /* OpenMP 4.5: 15313 vec: 15314 identifier [+/- integer] 15315 vec , identifier [+/- integer] 15316 */ 15317 15318 static tree 15319 c_parser_omp_clause_depend_sink (c_parser *parser, location_t clause_loc, 15320 tree list) 15321 { 15322 tree vec = NULL; 15323 if (c_parser_next_token_is_not (parser, CPP_NAME) 15324 || c_parser_peek_token (parser)->id_kind != C_ID_ID) 15325 { 15326 c_parser_error (parser, "expected identifier"); 15327 return list; 15328 } 15329 15330 while (c_parser_next_token_is (parser, CPP_NAME) 15331 && c_parser_peek_token (parser)->id_kind == C_ID_ID) 15332 { 15333 tree t = lookup_name (c_parser_peek_token (parser)->value); 15334 tree addend = NULL; 15335 15336 if (t == NULL_TREE) 15337 { 15338 undeclared_variable (c_parser_peek_token (parser)->location, 15339 c_parser_peek_token (parser)->value); 15340 t = error_mark_node; 15341 } 15342 15343 c_parser_consume_token (parser); 15344 15345 bool neg = false; 15346 if (c_parser_next_token_is (parser, CPP_MINUS)) 15347 neg = true; 15348 else if (!c_parser_next_token_is (parser, CPP_PLUS)) 15349 { 15350 addend = integer_zero_node; 15351 neg = false; 15352 goto add_to_vector; 15353 } 15354 c_parser_consume_token (parser); 15355 15356 if (c_parser_next_token_is_not (parser, CPP_NUMBER)) 15357 { 15358 c_parser_error (parser, "expected integer"); 15359 return list; 15360 } 15361 15362 addend = c_parser_peek_token (parser)->value; 15363 if (TREE_CODE (addend) != INTEGER_CST) 15364 { 15365 c_parser_error (parser, "expected integer"); 15366 return list; 15367 } 15368 c_parser_consume_token (parser); 15369 15370 add_to_vector: 15371 if (t != error_mark_node) 15372 { 15373 vec = tree_cons (addend, t, vec); 15374 if (neg) 15375 OMP_CLAUSE_DEPEND_SINK_NEGATIVE (vec) = 1; 15376 } 15377 15378 if (c_parser_next_token_is_not (parser, CPP_COMMA)) 15379 break; 15380 15381 c_parser_consume_token (parser); 15382 } 15383 15384 if (vec == NULL_TREE) 15385 return list; 15386 15387 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND); 15388 OMP_CLAUSE_DEPEND_KIND (u) = OMP_CLAUSE_DEPEND_SINK; 15389 OMP_CLAUSE_DECL (u) = nreverse (vec); 15390 OMP_CLAUSE_CHAIN (u) = list; 15391 return u; 15392 } 15393 15394 /* OpenMP 5.0: 15395 iterators ( iterators-definition ) 15396 15397 iterators-definition: 15398 iterator-specifier 15399 iterator-specifier , iterators-definition 15400 15401 iterator-specifier: 15402 identifier = range-specification 15403 iterator-type identifier = range-specification 15404 15405 range-specification: 15406 begin : end 15407 begin : end : step */ 15408 15409 static tree 15410 c_parser_omp_iterators (c_parser *parser) 15411 { 15412 tree ret = NULL_TREE, *last = &ret; 15413 c_parser_consume_token (parser); 15414 15415 push_scope (); 15416 15417 matching_parens parens; 15418 if (!parens.require_open (parser)) 15419 return error_mark_node; 15420 15421 do 15422 { 15423 tree iter_type = NULL_TREE, type_expr = NULL_TREE; 15424 if (c_parser_next_tokens_start_typename (parser, cla_prefer_id)) 15425 { 15426 struct c_type_name *type = c_parser_type_name (parser); 15427 if (type != NULL) 15428 iter_type = groktypename (type, &type_expr, NULL); 15429 } 15430 if (iter_type == NULL_TREE) 15431 iter_type = integer_type_node; 15432 15433 location_t loc = c_parser_peek_token (parser)->location; 15434 if (!c_parser_next_token_is (parser, CPP_NAME)) 15435 { 15436 c_parser_error (parser, "expected identifier"); 15437 break; 15438 } 15439 15440 tree id = c_parser_peek_token (parser)->value; 15441 c_parser_consume_token (parser); 15442 15443 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) 15444 break; 15445 15446 location_t eloc = c_parser_peek_token (parser)->location; 15447 c_expr expr = c_parser_expr_no_commas (parser, NULL); 15448 expr = convert_lvalue_to_rvalue (eloc, expr, true, false); 15449 tree begin = expr.value; 15450 15451 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 15452 break; 15453 15454 eloc = c_parser_peek_token (parser)->location; 15455 expr = c_parser_expr_no_commas (parser, NULL); 15456 expr = convert_lvalue_to_rvalue (eloc, expr, true, false); 15457 tree end = expr.value; 15458 15459 tree step = integer_one_node; 15460 if (c_parser_next_token_is (parser, CPP_COLON)) 15461 { 15462 c_parser_consume_token (parser); 15463 eloc = c_parser_peek_token (parser)->location; 15464 expr = c_parser_expr_no_commas (parser, NULL); 15465 expr = convert_lvalue_to_rvalue (eloc, expr, true, false); 15466 step = expr.value; 15467 } 15468 15469 tree iter_var = build_decl (loc, VAR_DECL, id, iter_type); 15470 DECL_ARTIFICIAL (iter_var) = 1; 15471 DECL_CONTEXT (iter_var) = current_function_decl; 15472 pushdecl (iter_var); 15473 15474 *last = make_tree_vec (6); 15475 TREE_VEC_ELT (*last, 0) = iter_var; 15476 TREE_VEC_ELT (*last, 1) = begin; 15477 TREE_VEC_ELT (*last, 2) = end; 15478 TREE_VEC_ELT (*last, 3) = step; 15479 last = &TREE_CHAIN (*last); 15480 15481 if (c_parser_next_token_is (parser, CPP_COMMA)) 15482 { 15483 c_parser_consume_token (parser); 15484 continue; 15485 } 15486 break; 15487 } 15488 while (1); 15489 15490 parens.skip_until_found_close (parser); 15491 return ret ? ret : error_mark_node; 15492 } 15493 15494 /* OpenMP 4.0: 15495 depend ( depend-kind: variable-list ) 15496 15497 depend-kind: 15498 in | out | inout 15499 15500 OpenMP 4.5: 15501 depend ( source ) 15502 15503 depend ( sink : vec ) 15504 15505 OpenMP 5.0: 15506 depend ( depend-modifier , depend-kind: variable-list ) 15507 15508 depend-kind: 15509 in | out | inout | mutexinoutset | depobj 15510 15511 depend-modifier: 15512 iterator ( iterators-definition ) */ 15513 15514 static tree 15515 c_parser_omp_clause_depend (c_parser *parser, tree list) 15516 { 15517 location_t clause_loc = c_parser_peek_token (parser)->location; 15518 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST; 15519 tree nl, c, iterators = NULL_TREE; 15520 15521 matching_parens parens; 15522 if (!parens.require_open (parser)) 15523 return list; 15524 15525 do 15526 { 15527 if (c_parser_next_token_is_not (parser, CPP_NAME)) 15528 goto invalid_kind; 15529 15530 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 15531 if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE) 15532 { 15533 iterators = c_parser_omp_iterators (parser); 15534 c_parser_require (parser, CPP_COMMA, "expected %<,%>"); 15535 continue; 15536 } 15537 if (strcmp ("in", p) == 0) 15538 kind = OMP_CLAUSE_DEPEND_IN; 15539 else if (strcmp ("inout", p) == 0) 15540 kind = OMP_CLAUSE_DEPEND_INOUT; 15541 else if (strcmp ("mutexinoutset", p) == 0) 15542 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET; 15543 else if (strcmp ("out", p) == 0) 15544 kind = OMP_CLAUSE_DEPEND_OUT; 15545 else if (strcmp ("depobj", p) == 0) 15546 kind = OMP_CLAUSE_DEPEND_DEPOBJ; 15547 else if (strcmp ("sink", p) == 0) 15548 kind = OMP_CLAUSE_DEPEND_SINK; 15549 else if (strcmp ("source", p) == 0) 15550 kind = OMP_CLAUSE_DEPEND_SOURCE; 15551 else 15552 goto invalid_kind; 15553 break; 15554 } 15555 while (1); 15556 15557 c_parser_consume_token (parser); 15558 15559 if (iterators 15560 && (kind == OMP_CLAUSE_DEPEND_SOURCE || kind == OMP_CLAUSE_DEPEND_SINK)) 15561 { 15562 pop_scope (); 15563 error_at (clause_loc, "%<iterator%> modifier incompatible with %qs", 15564 kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink"); 15565 iterators = NULL_TREE; 15566 } 15567 15568 if (kind == OMP_CLAUSE_DEPEND_SOURCE) 15569 { 15570 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEPEND); 15571 OMP_CLAUSE_DEPEND_KIND (c) = kind; 15572 OMP_CLAUSE_DECL (c) = NULL_TREE; 15573 OMP_CLAUSE_CHAIN (c) = list; 15574 parens.skip_until_found_close (parser); 15575 return c; 15576 } 15577 15578 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 15579 goto resync_fail; 15580 15581 if (kind == OMP_CLAUSE_DEPEND_SINK) 15582 nl = c_parser_omp_clause_depend_sink (parser, clause_loc, list); 15583 else 15584 { 15585 nl = c_parser_omp_variable_list (parser, clause_loc, 15586 OMP_CLAUSE_DEPEND, list); 15587 15588 if (iterators) 15589 { 15590 tree block = pop_scope (); 15591 if (iterators == error_mark_node) 15592 iterators = NULL_TREE; 15593 else 15594 TREE_VEC_ELT (iterators, 5) = block; 15595 } 15596 15597 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) 15598 { 15599 OMP_CLAUSE_DEPEND_KIND (c) = kind; 15600 if (iterators) 15601 OMP_CLAUSE_DECL (c) 15602 = build_tree_list (iterators, OMP_CLAUSE_DECL (c)); 15603 } 15604 } 15605 15606 parens.skip_until_found_close (parser); 15607 return nl; 15608 15609 invalid_kind: 15610 c_parser_error (parser, "invalid depend kind"); 15611 resync_fail: 15612 parens.skip_until_found_close (parser); 15613 if (iterators) 15614 pop_scope (); 15615 return list; 15616 } 15617 15618 /* OpenMP 4.0: 15619 map ( map-kind: variable-list ) 15620 map ( variable-list ) 15621 15622 map-kind: 15623 alloc | to | from | tofrom 15624 15625 OpenMP 4.5: 15626 map-kind: 15627 alloc | to | from | tofrom | release | delete 15628 15629 map ( always [,] map-kind: variable-list ) */ 15630 15631 static tree 15632 c_parser_omp_clause_map (c_parser *parser, tree list) 15633 { 15634 location_t clause_loc = c_parser_peek_token (parser)->location; 15635 enum gomp_map_kind kind = GOMP_MAP_TOFROM; 15636 int always = 0; 15637 enum c_id_kind always_id_kind = C_ID_NONE; 15638 location_t always_loc = UNKNOWN_LOCATION; 15639 tree always_id = NULL_TREE; 15640 tree nl, c; 15641 15642 matching_parens parens; 15643 if (!parens.require_open (parser)) 15644 return list; 15645 15646 if (c_parser_next_token_is (parser, CPP_NAME)) 15647 { 15648 c_token *tok = c_parser_peek_token (parser); 15649 const char *p = IDENTIFIER_POINTER (tok->value); 15650 always_id_kind = tok->id_kind; 15651 always_loc = tok->location; 15652 always_id = tok->value; 15653 if (strcmp ("always", p) == 0) 15654 { 15655 c_token *sectok = c_parser_peek_2nd_token (parser); 15656 if (sectok->type == CPP_COMMA) 15657 { 15658 c_parser_consume_token (parser); 15659 c_parser_consume_token (parser); 15660 always = 2; 15661 } 15662 else if (sectok->type == CPP_NAME) 15663 { 15664 p = IDENTIFIER_POINTER (sectok->value); 15665 if (strcmp ("alloc", p) == 0 15666 || strcmp ("to", p) == 0 15667 || strcmp ("from", p) == 0 15668 || strcmp ("tofrom", p) == 0 15669 || strcmp ("release", p) == 0 15670 || strcmp ("delete", p) == 0) 15671 { 15672 c_parser_consume_token (parser); 15673 always = 1; 15674 } 15675 } 15676 } 15677 } 15678 15679 if (c_parser_next_token_is (parser, CPP_NAME) 15680 && c_parser_peek_2nd_token (parser)->type == CPP_COLON) 15681 { 15682 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 15683 if (strcmp ("alloc", p) == 0) 15684 kind = GOMP_MAP_ALLOC; 15685 else if (strcmp ("to", p) == 0) 15686 kind = always ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO; 15687 else if (strcmp ("from", p) == 0) 15688 kind = always ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM; 15689 else if (strcmp ("tofrom", p) == 0) 15690 kind = always ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM; 15691 else if (strcmp ("release", p) == 0) 15692 kind = GOMP_MAP_RELEASE; 15693 else if (strcmp ("delete", p) == 0) 15694 kind = GOMP_MAP_DELETE; 15695 else 15696 { 15697 c_parser_error (parser, "invalid map kind"); 15698 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 15699 "expected %<)%>"); 15700 return list; 15701 } 15702 c_parser_consume_token (parser); 15703 c_parser_consume_token (parser); 15704 } 15705 else if (always) 15706 { 15707 if (always_id_kind != C_ID_ID) 15708 { 15709 c_parser_error (parser, "expected identifier"); 15710 parens.skip_until_found_close (parser); 15711 return list; 15712 } 15713 15714 tree t = lookup_name (always_id); 15715 if (t == NULL_TREE) 15716 { 15717 undeclared_variable (always_loc, always_id); 15718 t = error_mark_node; 15719 } 15720 if (t != error_mark_node) 15721 { 15722 tree u = build_omp_clause (clause_loc, OMP_CLAUSE_MAP); 15723 OMP_CLAUSE_DECL (u) = t; 15724 OMP_CLAUSE_CHAIN (u) = list; 15725 OMP_CLAUSE_SET_MAP_KIND (u, kind); 15726 list = u; 15727 } 15728 if (always == 1) 15729 { 15730 parens.skip_until_found_close (parser); 15731 return list; 15732 } 15733 } 15734 15735 nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list); 15736 15737 for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c)) 15738 OMP_CLAUSE_SET_MAP_KIND (c, kind); 15739 15740 parens.skip_until_found_close (parser); 15741 return nl; 15742 } 15743 15744 /* OpenMP 4.0: 15745 device ( expression ) */ 15746 15747 static tree 15748 c_parser_omp_clause_device (c_parser *parser, tree list) 15749 { 15750 location_t clause_loc = c_parser_peek_token (parser)->location; 15751 matching_parens parens; 15752 if (parens.require_open (parser)) 15753 { 15754 location_t expr_loc = c_parser_peek_token (parser)->location; 15755 c_expr expr = c_parser_expr_no_commas (parser, NULL); 15756 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 15757 tree c, t = expr.value; 15758 t = c_fully_fold (t, false, NULL); 15759 15760 parens.skip_until_found_close (parser); 15761 15762 if (!INTEGRAL_TYPE_P (TREE_TYPE (t))) 15763 { 15764 c_parser_error (parser, "expected integer expression"); 15765 return list; 15766 } 15767 15768 check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device"); 15769 15770 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE); 15771 OMP_CLAUSE_DEVICE_ID (c) = t; 15772 OMP_CLAUSE_CHAIN (c) = list; 15773 list = c; 15774 } 15775 15776 return list; 15777 } 15778 15779 /* OpenMP 4.0: 15780 dist_schedule ( static ) 15781 dist_schedule ( static , expression ) */ 15782 15783 static tree 15784 c_parser_omp_clause_dist_schedule (c_parser *parser, tree list) 15785 { 15786 tree c, t = NULL_TREE; 15787 location_t loc = c_parser_peek_token (parser)->location; 15788 15789 matching_parens parens; 15790 if (!parens.require_open (parser)) 15791 return list; 15792 15793 if (!c_parser_next_token_is_keyword (parser, RID_STATIC)) 15794 { 15795 c_parser_error (parser, "invalid dist_schedule kind"); 15796 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 15797 "expected %<)%>"); 15798 return list; 15799 } 15800 15801 c_parser_consume_token (parser); 15802 if (c_parser_next_token_is (parser, CPP_COMMA)) 15803 { 15804 c_parser_consume_token (parser); 15805 15806 location_t expr_loc = c_parser_peek_token (parser)->location; 15807 c_expr expr = c_parser_expr_no_commas (parser, NULL); 15808 expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true); 15809 t = expr.value; 15810 t = c_fully_fold (t, false, NULL); 15811 parens.skip_until_found_close (parser); 15812 } 15813 else 15814 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 15815 "expected %<,%> or %<)%>"); 15816 15817 /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE, 15818 "dist_schedule"); */ 15819 if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE)) 15820 warning_at (loc, 0, "too many %qs clauses", "dist_schedule"); 15821 if (t == error_mark_node) 15822 return list; 15823 15824 c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE); 15825 OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t; 15826 OMP_CLAUSE_CHAIN (c) = list; 15827 return c; 15828 } 15829 15830 /* OpenMP 4.0: 15831 proc_bind ( proc-bind-kind ) 15832 15833 proc-bind-kind: 15834 master | close | spread */ 15835 15836 static tree 15837 c_parser_omp_clause_proc_bind (c_parser *parser, tree list) 15838 { 15839 location_t clause_loc = c_parser_peek_token (parser)->location; 15840 enum omp_clause_proc_bind_kind kind; 15841 tree c; 15842 15843 matching_parens parens; 15844 if (!parens.require_open (parser)) 15845 return list; 15846 15847 if (c_parser_next_token_is (parser, CPP_NAME)) 15848 { 15849 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 15850 if (strcmp ("master", p) == 0) 15851 kind = OMP_CLAUSE_PROC_BIND_MASTER; 15852 else if (strcmp ("close", p) == 0) 15853 kind = OMP_CLAUSE_PROC_BIND_CLOSE; 15854 else if (strcmp ("spread", p) == 0) 15855 kind = OMP_CLAUSE_PROC_BIND_SPREAD; 15856 else 15857 goto invalid_kind; 15858 } 15859 else 15860 goto invalid_kind; 15861 15862 check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind"); 15863 c_parser_consume_token (parser); 15864 parens.skip_until_found_close (parser); 15865 c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND); 15866 OMP_CLAUSE_PROC_BIND_KIND (c) = kind; 15867 OMP_CLAUSE_CHAIN (c) = list; 15868 return c; 15869 15870 invalid_kind: 15871 c_parser_error (parser, "invalid proc_bind kind"); 15872 parens.skip_until_found_close (parser); 15873 return list; 15874 } 15875 15876 /* OpenMP 5.0: 15877 device_type ( host | nohost | any ) */ 15878 15879 static tree 15880 c_parser_omp_clause_device_type (c_parser *parser, tree list) 15881 { 15882 location_t clause_loc = c_parser_peek_token (parser)->location; 15883 enum omp_clause_device_type_kind kind; 15884 tree c; 15885 15886 matching_parens parens; 15887 if (!parens.require_open (parser)) 15888 return list; 15889 15890 if (c_parser_next_token_is (parser, CPP_NAME)) 15891 { 15892 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 15893 if (strcmp ("host", p) == 0) 15894 kind = OMP_CLAUSE_DEVICE_TYPE_HOST; 15895 else if (strcmp ("nohost", p) == 0) 15896 kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST; 15897 else if (strcmp ("any", p) == 0) 15898 kind = OMP_CLAUSE_DEVICE_TYPE_ANY; 15899 else 15900 goto invalid_kind; 15901 } 15902 else 15903 goto invalid_kind; 15904 15905 /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE, 15906 "device_type"); */ 15907 c_parser_consume_token (parser); 15908 parens.skip_until_found_close (parser); 15909 c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE); 15910 OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind; 15911 OMP_CLAUSE_CHAIN (c) = list; 15912 return c; 15913 15914 invalid_kind: 15915 c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>"); 15916 parens.skip_until_found_close (parser); 15917 return list; 15918 } 15919 15920 /* OpenMP 4.0: 15921 to ( variable-list ) */ 15922 15923 static tree 15924 c_parser_omp_clause_to (c_parser *parser, tree list) 15925 { 15926 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO, list); 15927 } 15928 15929 /* OpenMP 4.0: 15930 from ( variable-list ) */ 15931 15932 static tree 15933 c_parser_omp_clause_from (c_parser *parser, tree list) 15934 { 15935 return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FROM, list); 15936 } 15937 15938 /* OpenMP 4.0: 15939 uniform ( variable-list ) */ 15940 15941 static tree 15942 c_parser_omp_clause_uniform (c_parser *parser, tree list) 15943 { 15944 /* The clauses location. */ 15945 location_t loc = c_parser_peek_token (parser)->location; 15946 15947 matching_parens parens; 15948 if (parens.require_open (parser)) 15949 { 15950 list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM, 15951 list); 15952 parens.skip_until_found_close (parser); 15953 } 15954 return list; 15955 } 15956 15957 /* Parse all OpenACC clauses. The set clauses allowed by the directive 15958 is a bitmask in MASK. Return the list of clauses found. */ 15959 15960 static tree 15961 c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask, 15962 const char *where, bool finish_p = true) 15963 { 15964 tree clauses = NULL; 15965 bool first = true; 15966 15967 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 15968 { 15969 location_t here; 15970 pragma_omp_clause c_kind; 15971 const char *c_name; 15972 tree prev = clauses; 15973 15974 if (!first && c_parser_next_token_is (parser, CPP_COMMA)) 15975 c_parser_consume_token (parser); 15976 15977 here = c_parser_peek_token (parser)->location; 15978 c_kind = c_parser_omp_clause_name (parser); 15979 15980 switch (c_kind) 15981 { 15982 case PRAGMA_OACC_CLAUSE_ASYNC: 15983 clauses = c_parser_oacc_clause_async (parser, clauses); 15984 c_name = "async"; 15985 break; 15986 case PRAGMA_OACC_CLAUSE_AUTO: 15987 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO, 15988 clauses); 15989 c_name = "auto"; 15990 break; 15991 case PRAGMA_OACC_CLAUSE_ATTACH: 15992 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 15993 c_name = "attach"; 15994 break; 15995 case PRAGMA_OACC_CLAUSE_COLLAPSE: 15996 clauses = c_parser_omp_clause_collapse (parser, clauses); 15997 c_name = "collapse"; 15998 break; 15999 case PRAGMA_OACC_CLAUSE_COPY: 16000 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 16001 c_name = "copy"; 16002 break; 16003 case PRAGMA_OACC_CLAUSE_COPYIN: 16004 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 16005 c_name = "copyin"; 16006 break; 16007 case PRAGMA_OACC_CLAUSE_COPYOUT: 16008 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 16009 c_name = "copyout"; 16010 break; 16011 case PRAGMA_OACC_CLAUSE_CREATE: 16012 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 16013 c_name = "create"; 16014 break; 16015 case PRAGMA_OACC_CLAUSE_DELETE: 16016 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 16017 c_name = "delete"; 16018 break; 16019 case PRAGMA_OMP_CLAUSE_DEFAULT: 16020 clauses = c_parser_omp_clause_default (parser, clauses, true); 16021 c_name = "default"; 16022 break; 16023 case PRAGMA_OACC_CLAUSE_DETACH: 16024 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 16025 c_name = "detach"; 16026 break; 16027 case PRAGMA_OACC_CLAUSE_DEVICE: 16028 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 16029 c_name = "device"; 16030 break; 16031 case PRAGMA_OACC_CLAUSE_DEVICEPTR: 16032 clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses); 16033 c_name = "deviceptr"; 16034 break; 16035 case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT: 16036 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 16037 c_name = "device_resident"; 16038 break; 16039 case PRAGMA_OACC_CLAUSE_FINALIZE: 16040 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE, 16041 clauses); 16042 c_name = "finalize"; 16043 break; 16044 case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE: 16045 clauses = c_parser_omp_clause_firstprivate (parser, clauses); 16046 c_name = "firstprivate"; 16047 break; 16048 case PRAGMA_OACC_CLAUSE_GANG: 16049 c_name = "gang"; 16050 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG, 16051 c_name, clauses); 16052 break; 16053 case PRAGMA_OACC_CLAUSE_HOST: 16054 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 16055 c_name = "host"; 16056 break; 16057 case PRAGMA_OACC_CLAUSE_IF: 16058 clauses = c_parser_omp_clause_if (parser, clauses, false); 16059 c_name = "if"; 16060 break; 16061 case PRAGMA_OACC_CLAUSE_IF_PRESENT: 16062 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT, 16063 clauses); 16064 c_name = "if_present"; 16065 break; 16066 case PRAGMA_OACC_CLAUSE_INDEPENDENT: 16067 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT, 16068 clauses); 16069 c_name = "independent"; 16070 break; 16071 case PRAGMA_OACC_CLAUSE_LINK: 16072 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 16073 c_name = "link"; 16074 break; 16075 case PRAGMA_OACC_CLAUSE_NO_CREATE: 16076 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 16077 c_name = "no_create"; 16078 break; 16079 case PRAGMA_OACC_CLAUSE_NUM_GANGS: 16080 clauses = c_parser_oacc_single_int_clause (parser, 16081 OMP_CLAUSE_NUM_GANGS, 16082 clauses); 16083 c_name = "num_gangs"; 16084 break; 16085 case PRAGMA_OACC_CLAUSE_NUM_WORKERS: 16086 clauses = c_parser_oacc_single_int_clause (parser, 16087 OMP_CLAUSE_NUM_WORKERS, 16088 clauses); 16089 c_name = "num_workers"; 16090 break; 16091 case PRAGMA_OACC_CLAUSE_PRESENT: 16092 clauses = c_parser_oacc_data_clause (parser, c_kind, clauses); 16093 c_name = "present"; 16094 break; 16095 case PRAGMA_OACC_CLAUSE_PRIVATE: 16096 clauses = c_parser_omp_clause_private (parser, clauses); 16097 c_name = "private"; 16098 break; 16099 case PRAGMA_OACC_CLAUSE_REDUCTION: 16100 clauses 16101 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION, 16102 false, clauses); 16103 c_name = "reduction"; 16104 break; 16105 case PRAGMA_OACC_CLAUSE_SEQ: 16106 clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ, 16107 clauses); 16108 c_name = "seq"; 16109 break; 16110 case PRAGMA_OACC_CLAUSE_TILE: 16111 clauses = c_parser_oacc_clause_tile (parser, clauses); 16112 c_name = "tile"; 16113 break; 16114 case PRAGMA_OACC_CLAUSE_USE_DEVICE: 16115 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses); 16116 c_name = "use_device"; 16117 break; 16118 case PRAGMA_OACC_CLAUSE_VECTOR: 16119 c_name = "vector"; 16120 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR, 16121 c_name, clauses); 16122 break; 16123 case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH: 16124 clauses = c_parser_oacc_single_int_clause (parser, 16125 OMP_CLAUSE_VECTOR_LENGTH, 16126 clauses); 16127 c_name = "vector_length"; 16128 break; 16129 case PRAGMA_OACC_CLAUSE_WAIT: 16130 clauses = c_parser_oacc_clause_wait (parser, clauses); 16131 c_name = "wait"; 16132 break; 16133 case PRAGMA_OACC_CLAUSE_WORKER: 16134 c_name = "worker"; 16135 clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER, 16136 c_name, clauses); 16137 break; 16138 default: 16139 c_parser_error (parser, "expected %<#pragma acc%> clause"); 16140 goto saw_error; 16141 } 16142 16143 first = false; 16144 16145 if (((mask >> c_kind) & 1) == 0) 16146 { 16147 /* Remove the invalid clause(s) from the list to avoid 16148 confusing the rest of the compiler. */ 16149 clauses = prev; 16150 error_at (here, "%qs is not valid for %qs", c_name, where); 16151 } 16152 } 16153 16154 saw_error: 16155 c_parser_skip_to_pragma_eol (parser); 16156 16157 if (finish_p) 16158 return c_finish_omp_clauses (clauses, C_ORT_ACC); 16159 16160 return clauses; 16161 } 16162 16163 /* Parse all OpenMP clauses. The set clauses allowed by the directive 16164 is a bitmask in MASK. Return the list of clauses found. 16165 FINISH_P set if c_finish_omp_clauses should be called. 16166 NESTED non-zero if clauses should be terminated by closing paren instead 16167 of end of pragma. If it is 2, additionally commas are required in between 16168 the clauses. */ 16169 16170 static tree 16171 c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask, 16172 const char *where, bool finish_p = true, 16173 int nested = 0) 16174 { 16175 tree clauses = NULL; 16176 bool first = true; 16177 16178 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 16179 { 16180 location_t here; 16181 pragma_omp_clause c_kind; 16182 const char *c_name; 16183 tree prev = clauses; 16184 16185 if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN)) 16186 break; 16187 16188 if (!first) 16189 { 16190 if (c_parser_next_token_is (parser, CPP_COMMA)) 16191 c_parser_consume_token (parser); 16192 else if (nested == 2) 16193 error_at (c_parser_peek_token (parser)->location, 16194 "clauses in %<simd%> trait should be separated " 16195 "by %<,%>"); 16196 } 16197 16198 here = c_parser_peek_token (parser)->location; 16199 c_kind = c_parser_omp_clause_name (parser); 16200 16201 switch (c_kind) 16202 { 16203 case PRAGMA_OMP_CLAUSE_BIND: 16204 clauses = c_parser_omp_clause_bind (parser, clauses); 16205 c_name = "bind"; 16206 break; 16207 case PRAGMA_OMP_CLAUSE_COLLAPSE: 16208 clauses = c_parser_omp_clause_collapse (parser, clauses); 16209 c_name = "collapse"; 16210 break; 16211 case PRAGMA_OMP_CLAUSE_COPYIN: 16212 clauses = c_parser_omp_clause_copyin (parser, clauses); 16213 c_name = "copyin"; 16214 break; 16215 case PRAGMA_OMP_CLAUSE_COPYPRIVATE: 16216 clauses = c_parser_omp_clause_copyprivate (parser, clauses); 16217 c_name = "copyprivate"; 16218 break; 16219 case PRAGMA_OMP_CLAUSE_DEFAULT: 16220 clauses = c_parser_omp_clause_default (parser, clauses, false); 16221 c_name = "default"; 16222 break; 16223 case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE: 16224 clauses = c_parser_omp_clause_firstprivate (parser, clauses); 16225 c_name = "firstprivate"; 16226 break; 16227 case PRAGMA_OMP_CLAUSE_FINAL: 16228 clauses = c_parser_omp_clause_final (parser, clauses); 16229 c_name = "final"; 16230 break; 16231 case PRAGMA_OMP_CLAUSE_GRAINSIZE: 16232 clauses = c_parser_omp_clause_grainsize (parser, clauses); 16233 c_name = "grainsize"; 16234 break; 16235 case PRAGMA_OMP_CLAUSE_HINT: 16236 clauses = c_parser_omp_clause_hint (parser, clauses); 16237 c_name = "hint"; 16238 break; 16239 case PRAGMA_OMP_CLAUSE_DEFAULTMAP: 16240 clauses = c_parser_omp_clause_defaultmap (parser, clauses); 16241 c_name = "defaultmap"; 16242 break; 16243 case PRAGMA_OMP_CLAUSE_IF: 16244 clauses = c_parser_omp_clause_if (parser, clauses, true); 16245 c_name = "if"; 16246 break; 16247 case PRAGMA_OMP_CLAUSE_IN_REDUCTION: 16248 clauses 16249 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION, 16250 true, clauses); 16251 c_name = "in_reduction"; 16252 break; 16253 case PRAGMA_OMP_CLAUSE_LASTPRIVATE: 16254 clauses = c_parser_omp_clause_lastprivate (parser, clauses); 16255 c_name = "lastprivate"; 16256 break; 16257 case PRAGMA_OMP_CLAUSE_MERGEABLE: 16258 clauses = c_parser_omp_clause_mergeable (parser, clauses); 16259 c_name = "mergeable"; 16260 break; 16261 case PRAGMA_OMP_CLAUSE_NOWAIT: 16262 clauses = c_parser_omp_clause_nowait (parser, clauses); 16263 c_name = "nowait"; 16264 break; 16265 case PRAGMA_OMP_CLAUSE_NUM_TASKS: 16266 clauses = c_parser_omp_clause_num_tasks (parser, clauses); 16267 c_name = "num_tasks"; 16268 break; 16269 case PRAGMA_OMP_CLAUSE_NUM_THREADS: 16270 clauses = c_parser_omp_clause_num_threads (parser, clauses); 16271 c_name = "num_threads"; 16272 break; 16273 case PRAGMA_OMP_CLAUSE_ORDER: 16274 clauses = c_parser_omp_clause_order (parser, clauses); 16275 c_name = "order"; 16276 break; 16277 case PRAGMA_OMP_CLAUSE_ORDERED: 16278 clauses = c_parser_omp_clause_ordered (parser, clauses); 16279 c_name = "ordered"; 16280 break; 16281 case PRAGMA_OMP_CLAUSE_PRIORITY: 16282 clauses = c_parser_omp_clause_priority (parser, clauses); 16283 c_name = "priority"; 16284 break; 16285 case PRAGMA_OMP_CLAUSE_PRIVATE: 16286 clauses = c_parser_omp_clause_private (parser, clauses); 16287 c_name = "private"; 16288 break; 16289 case PRAGMA_OMP_CLAUSE_REDUCTION: 16290 clauses 16291 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION, 16292 true, clauses); 16293 c_name = "reduction"; 16294 break; 16295 case PRAGMA_OMP_CLAUSE_SCHEDULE: 16296 clauses = c_parser_omp_clause_schedule (parser, clauses); 16297 c_name = "schedule"; 16298 break; 16299 case PRAGMA_OMP_CLAUSE_SHARED: 16300 clauses = c_parser_omp_clause_shared (parser, clauses); 16301 c_name = "shared"; 16302 break; 16303 case PRAGMA_OMP_CLAUSE_TASK_REDUCTION: 16304 clauses 16305 = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION, 16306 true, clauses); 16307 c_name = "task_reduction"; 16308 break; 16309 case PRAGMA_OMP_CLAUSE_UNTIED: 16310 clauses = c_parser_omp_clause_untied (parser, clauses); 16311 c_name = "untied"; 16312 break; 16313 case PRAGMA_OMP_CLAUSE_INBRANCH: 16314 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH, 16315 clauses); 16316 c_name = "inbranch"; 16317 break; 16318 case PRAGMA_OMP_CLAUSE_NONTEMPORAL: 16319 clauses = c_parser_omp_clause_nontemporal (parser, clauses); 16320 c_name = "nontemporal"; 16321 break; 16322 case PRAGMA_OMP_CLAUSE_NOTINBRANCH: 16323 clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH, 16324 clauses); 16325 c_name = "notinbranch"; 16326 break; 16327 case PRAGMA_OMP_CLAUSE_PARALLEL: 16328 clauses 16329 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL, 16330 clauses); 16331 c_name = "parallel"; 16332 if (!first) 16333 { 16334 clause_not_first: 16335 error_at (here, "%qs must be the first clause of %qs", 16336 c_name, where); 16337 clauses = prev; 16338 } 16339 break; 16340 case PRAGMA_OMP_CLAUSE_FOR: 16341 clauses 16342 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR, 16343 clauses); 16344 c_name = "for"; 16345 if (!first) 16346 goto clause_not_first; 16347 break; 16348 case PRAGMA_OMP_CLAUSE_SECTIONS: 16349 clauses 16350 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS, 16351 clauses); 16352 c_name = "sections"; 16353 if (!first) 16354 goto clause_not_first; 16355 break; 16356 case PRAGMA_OMP_CLAUSE_TASKGROUP: 16357 clauses 16358 = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP, 16359 clauses); 16360 c_name = "taskgroup"; 16361 if (!first) 16362 goto clause_not_first; 16363 break; 16364 case PRAGMA_OMP_CLAUSE_LINK: 16365 clauses 16366 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses); 16367 c_name = "link"; 16368 break; 16369 case PRAGMA_OMP_CLAUSE_TO: 16370 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0) 16371 clauses 16372 = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE, 16373 clauses); 16374 else 16375 clauses = c_parser_omp_clause_to (parser, clauses); 16376 c_name = "to"; 16377 break; 16378 case PRAGMA_OMP_CLAUSE_FROM: 16379 clauses = c_parser_omp_clause_from (parser, clauses); 16380 c_name = "from"; 16381 break; 16382 case PRAGMA_OMP_CLAUSE_UNIFORM: 16383 clauses = c_parser_omp_clause_uniform (parser, clauses); 16384 c_name = "uniform"; 16385 break; 16386 case PRAGMA_OMP_CLAUSE_NUM_TEAMS: 16387 clauses = c_parser_omp_clause_num_teams (parser, clauses); 16388 c_name = "num_teams"; 16389 break; 16390 case PRAGMA_OMP_CLAUSE_THREAD_LIMIT: 16391 clauses = c_parser_omp_clause_thread_limit (parser, clauses); 16392 c_name = "thread_limit"; 16393 break; 16394 case PRAGMA_OMP_CLAUSE_ALIGNED: 16395 clauses = c_parser_omp_clause_aligned (parser, clauses); 16396 c_name = "aligned"; 16397 break; 16398 case PRAGMA_OMP_CLAUSE_LINEAR: 16399 clauses = c_parser_omp_clause_linear (parser, clauses); 16400 c_name = "linear"; 16401 break; 16402 case PRAGMA_OMP_CLAUSE_DEPEND: 16403 clauses = c_parser_omp_clause_depend (parser, clauses); 16404 c_name = "depend"; 16405 break; 16406 case PRAGMA_OMP_CLAUSE_MAP: 16407 clauses = c_parser_omp_clause_map (parser, clauses); 16408 c_name = "map"; 16409 break; 16410 case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR: 16411 clauses = c_parser_omp_clause_use_device_ptr (parser, clauses); 16412 c_name = "use_device_ptr"; 16413 break; 16414 case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR: 16415 clauses = c_parser_omp_clause_use_device_addr (parser, clauses); 16416 c_name = "use_device_addr"; 16417 break; 16418 case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR: 16419 clauses = c_parser_omp_clause_is_device_ptr (parser, clauses); 16420 c_name = "is_device_ptr"; 16421 break; 16422 case PRAGMA_OMP_CLAUSE_DEVICE: 16423 clauses = c_parser_omp_clause_device (parser, clauses); 16424 c_name = "device"; 16425 break; 16426 case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE: 16427 clauses = c_parser_omp_clause_dist_schedule (parser, clauses); 16428 c_name = "dist_schedule"; 16429 break; 16430 case PRAGMA_OMP_CLAUSE_PROC_BIND: 16431 clauses = c_parser_omp_clause_proc_bind (parser, clauses); 16432 c_name = "proc_bind"; 16433 break; 16434 case PRAGMA_OMP_CLAUSE_DEVICE_TYPE: 16435 clauses = c_parser_omp_clause_device_type (parser, clauses); 16436 c_name = "device_type"; 16437 break; 16438 case PRAGMA_OMP_CLAUSE_SAFELEN: 16439 clauses = c_parser_omp_clause_safelen (parser, clauses); 16440 c_name = "safelen"; 16441 break; 16442 case PRAGMA_OMP_CLAUSE_SIMDLEN: 16443 clauses = c_parser_omp_clause_simdlen (parser, clauses); 16444 c_name = "simdlen"; 16445 break; 16446 case PRAGMA_OMP_CLAUSE_NOGROUP: 16447 clauses = c_parser_omp_clause_nogroup (parser, clauses); 16448 c_name = "nogroup"; 16449 break; 16450 case PRAGMA_OMP_CLAUSE_THREADS: 16451 clauses 16452 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS, 16453 clauses); 16454 c_name = "threads"; 16455 break; 16456 case PRAGMA_OMP_CLAUSE_SIMD: 16457 clauses 16458 = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD, 16459 clauses); 16460 c_name = "simd"; 16461 break; 16462 default: 16463 c_parser_error (parser, "expected %<#pragma omp%> clause"); 16464 goto saw_error; 16465 } 16466 16467 first = false; 16468 16469 if (((mask >> c_kind) & 1) == 0) 16470 { 16471 /* Remove the invalid clause(s) from the list to avoid 16472 confusing the rest of the compiler. */ 16473 clauses = prev; 16474 error_at (here, "%qs is not valid for %qs", c_name, where); 16475 } 16476 } 16477 16478 saw_error: 16479 if (!nested) 16480 c_parser_skip_to_pragma_eol (parser); 16481 16482 if (finish_p) 16483 { 16484 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0) 16485 return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD); 16486 return c_finish_omp_clauses (clauses, C_ORT_OMP); 16487 } 16488 16489 return clauses; 16490 } 16491 16492 /* OpenACC 2.0, OpenMP 2.5: 16493 structured-block: 16494 statement 16495 16496 In practice, we're also interested in adding the statement to an 16497 outer node. So it is convenient if we work around the fact that 16498 c_parser_statement calls add_stmt. */ 16499 16500 static tree 16501 c_parser_omp_structured_block (c_parser *parser, bool *if_p) 16502 { 16503 tree stmt = push_stmt_list (); 16504 c_parser_statement (parser, if_p); 16505 return pop_stmt_list (stmt); 16506 } 16507 16508 /* OpenACC 2.0: 16509 # pragma acc cache (variable-list) new-line 16510 16511 LOC is the location of the #pragma token. 16512 */ 16513 16514 static tree 16515 c_parser_oacc_cache (location_t loc, c_parser *parser) 16516 { 16517 tree stmt, clauses; 16518 16519 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL); 16520 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC); 16521 16522 c_parser_skip_to_pragma_eol (parser); 16523 16524 stmt = make_node (OACC_CACHE); 16525 TREE_TYPE (stmt) = void_type_node; 16526 OACC_CACHE_CLAUSES (stmt) = clauses; 16527 SET_EXPR_LOCATION (stmt, loc); 16528 add_stmt (stmt); 16529 16530 return stmt; 16531 } 16532 16533 /* OpenACC 2.0: 16534 # pragma acc data oacc-data-clause[optseq] new-line 16535 structured-block 16536 16537 LOC is the location of the #pragma token. 16538 */ 16539 16540 #define OACC_DATA_CLAUSE_MASK \ 16541 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \ 16542 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \ 16543 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \ 16544 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \ 16545 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \ 16546 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \ 16547 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \ 16548 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \ 16549 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)) 16550 16551 static tree 16552 c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p) 16553 { 16554 tree stmt, clauses, block; 16555 16556 clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK, 16557 "#pragma acc data"); 16558 16559 block = c_begin_omp_parallel (); 16560 add_stmt (c_parser_omp_structured_block (parser, if_p)); 16561 16562 stmt = c_finish_oacc_data (loc, clauses, block); 16563 16564 return stmt; 16565 } 16566 16567 /* OpenACC 2.0: 16568 # pragma acc declare oacc-data-clause[optseq] new-line 16569 */ 16570 16571 #define OACC_DECLARE_CLAUSE_MASK \ 16572 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \ 16573 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \ 16574 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \ 16575 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \ 16576 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \ 16577 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT) \ 16578 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK) \ 16579 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)) 16580 16581 static void 16582 c_parser_oacc_declare (c_parser *parser) 16583 { 16584 location_t pragma_loc = c_parser_peek_token (parser)->location; 16585 tree clauses, stmt, t, decl; 16586 16587 bool error = false; 16588 16589 c_parser_consume_pragma (parser); 16590 16591 clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK, 16592 "#pragma acc declare"); 16593 if (!clauses) 16594 { 16595 error_at (pragma_loc, 16596 "no valid clauses specified in %<#pragma acc declare%>"); 16597 return; 16598 } 16599 16600 for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t)) 16601 { 16602 location_t loc = OMP_CLAUSE_LOCATION (t); 16603 decl = OMP_CLAUSE_DECL (t); 16604 if (!DECL_P (decl)) 16605 { 16606 error_at (loc, "array section in %<#pragma acc declare%>"); 16607 error = true; 16608 continue; 16609 } 16610 16611 switch (OMP_CLAUSE_MAP_KIND (t)) 16612 { 16613 case GOMP_MAP_FIRSTPRIVATE_POINTER: 16614 case GOMP_MAP_ALLOC: 16615 case GOMP_MAP_TO: 16616 case GOMP_MAP_FORCE_DEVICEPTR: 16617 case GOMP_MAP_DEVICE_RESIDENT: 16618 break; 16619 16620 case GOMP_MAP_LINK: 16621 if (!global_bindings_p () 16622 && (TREE_STATIC (decl) 16623 || !DECL_EXTERNAL (decl))) 16624 { 16625 error_at (loc, 16626 "%qD must be a global variable in " 16627 "%<#pragma acc declare link%>", 16628 decl); 16629 error = true; 16630 continue; 16631 } 16632 break; 16633 16634 default: 16635 if (global_bindings_p ()) 16636 { 16637 error_at (loc, "invalid OpenACC clause at file scope"); 16638 error = true; 16639 continue; 16640 } 16641 if (DECL_EXTERNAL (decl)) 16642 { 16643 error_at (loc, 16644 "invalid use of %<extern%> variable %qD " 16645 "in %<#pragma acc declare%>", decl); 16646 error = true; 16647 continue; 16648 } 16649 else if (TREE_PUBLIC (decl)) 16650 { 16651 error_at (loc, 16652 "invalid use of %<global%> variable %qD " 16653 "in %<#pragma acc declare%>", decl); 16654 error = true; 16655 continue; 16656 } 16657 break; 16658 } 16659 16660 if (!c_check_in_current_scope (decl)) 16661 { 16662 error_at (loc, 16663 "%qD must be a variable declared in the same scope as " 16664 "%<#pragma acc declare%>", decl); 16665 error = true; 16666 continue; 16667 } 16668 16669 if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)) 16670 || lookup_attribute ("omp declare target link", 16671 DECL_ATTRIBUTES (decl))) 16672 { 16673 error_at (loc, "variable %qD used more than once with " 16674 "%<#pragma acc declare%>", decl); 16675 error = true; 16676 continue; 16677 } 16678 16679 if (!error) 16680 { 16681 tree id; 16682 16683 if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK) 16684 id = get_identifier ("omp declare target link"); 16685 else 16686 id = get_identifier ("omp declare target"); 16687 16688 DECL_ATTRIBUTES (decl) 16689 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl)); 16690 16691 if (global_bindings_p ()) 16692 { 16693 symtab_node *node = symtab_node::get (decl); 16694 if (node != NULL) 16695 { 16696 node->offloadable = 1; 16697 if (ENABLE_OFFLOADING) 16698 { 16699 g->have_offload = true; 16700 if (is_a <varpool_node *> (node)) 16701 vec_safe_push (offload_vars, decl); 16702 } 16703 } 16704 } 16705 } 16706 } 16707 16708 if (error || global_bindings_p ()) 16709 return; 16710 16711 stmt = make_node (OACC_DECLARE); 16712 TREE_TYPE (stmt) = void_type_node; 16713 OACC_DECLARE_CLAUSES (stmt) = clauses; 16714 SET_EXPR_LOCATION (stmt, pragma_loc); 16715 16716 add_stmt (stmt); 16717 16718 return; 16719 } 16720 16721 /* OpenACC 2.0: 16722 # pragma acc enter data oacc-enter-data-clause[optseq] new-line 16723 16724 or 16725 16726 # pragma acc exit data oacc-exit-data-clause[optseq] new-line 16727 16728 16729 LOC is the location of the #pragma token. 16730 */ 16731 16732 #define OACC_ENTER_DATA_CLAUSE_MASK \ 16733 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \ 16734 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \ 16735 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \ 16736 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \ 16737 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \ 16738 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) ) 16739 16740 #define OACC_EXIT_DATA_CLAUSE_MASK \ 16741 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \ 16742 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \ 16743 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \ 16744 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) \ 16745 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH) \ 16746 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) \ 16747 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) ) 16748 16749 static void 16750 c_parser_oacc_enter_exit_data (c_parser *parser, bool enter) 16751 { 16752 location_t loc = c_parser_peek_token (parser)->location; 16753 tree clauses, stmt; 16754 const char *p = ""; 16755 16756 c_parser_consume_pragma (parser); 16757 16758 if (c_parser_next_token_is (parser, CPP_NAME)) 16759 { 16760 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 16761 c_parser_consume_token (parser); 16762 } 16763 16764 if (strcmp (p, "data") != 0) 16765 { 16766 error_at (loc, "expected %<data%> after %<#pragma acc %s%>", 16767 enter ? "enter" : "exit"); 16768 parser->error = true; 16769 c_parser_skip_to_pragma_eol (parser); 16770 return; 16771 } 16772 16773 if (enter) 16774 clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK, 16775 "#pragma acc enter data"); 16776 else 16777 clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK, 16778 "#pragma acc exit data"); 16779 16780 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE) 16781 { 16782 error_at (loc, "%<#pragma acc %s data%> has no data movement clause", 16783 enter ? "enter" : "exit"); 16784 return; 16785 } 16786 16787 stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA); 16788 TREE_TYPE (stmt) = void_type_node; 16789 OMP_STANDALONE_CLAUSES (stmt) = clauses; 16790 SET_EXPR_LOCATION (stmt, loc); 16791 add_stmt (stmt); 16792 } 16793 16794 16795 /* OpenACC 2.0: 16796 # pragma acc host_data oacc-data-clause[optseq] new-line 16797 structured-block 16798 */ 16799 16800 #define OACC_HOST_DATA_CLAUSE_MASK \ 16801 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE) \ 16802 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \ 16803 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) ) 16804 16805 static tree 16806 c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p) 16807 { 16808 tree stmt, clauses, block; 16809 16810 clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK, 16811 "#pragma acc host_data"); 16812 16813 block = c_begin_omp_parallel (); 16814 add_stmt (c_parser_omp_structured_block (parser, if_p)); 16815 stmt = c_finish_oacc_host_data (loc, clauses, block); 16816 return stmt; 16817 } 16818 16819 16820 /* OpenACC 2.0: 16821 16822 # pragma acc loop oacc-loop-clause[optseq] new-line 16823 structured-block 16824 16825 LOC is the location of the #pragma token. 16826 */ 16827 16828 #define OACC_LOOP_CLAUSE_MASK \ 16829 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE) \ 16830 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \ 16831 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \ 16832 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \ 16833 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \ 16834 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \ 16835 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO) \ 16836 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT) \ 16837 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) \ 16838 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) ) 16839 static tree 16840 c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name, 16841 omp_clause_mask mask, tree *cclauses, bool *if_p) 16842 { 16843 bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1; 16844 16845 strcat (p_name, " loop"); 16846 mask |= OACC_LOOP_CLAUSE_MASK; 16847 16848 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name, 16849 cclauses == NULL); 16850 if (cclauses) 16851 { 16852 clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel); 16853 if (*cclauses) 16854 *cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC); 16855 if (clauses) 16856 clauses = c_finish_omp_clauses (clauses, C_ORT_ACC); 16857 } 16858 16859 tree block = c_begin_compound_stmt (true); 16860 tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL, 16861 if_p); 16862 block = c_end_compound_stmt (loc, block, true); 16863 add_stmt (block); 16864 16865 return stmt; 16866 } 16867 16868 /* OpenACC 2.0: 16869 # pragma acc kernels oacc-kernels-clause[optseq] new-line 16870 structured-block 16871 16872 or 16873 16874 # pragma acc parallel oacc-parallel-clause[optseq] new-line 16875 structured-block 16876 16877 OpenACC 2.6: 16878 16879 # pragma acc serial oacc-serial-clause[optseq] new-line 16880 structured-block 16881 16882 LOC is the location of the #pragma token. 16883 */ 16884 16885 #define OACC_KERNELS_CLAUSE_MASK \ 16886 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \ 16887 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \ 16888 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \ 16889 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \ 16890 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \ 16891 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \ 16892 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \ 16893 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \ 16894 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \ 16895 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \ 16896 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \ 16897 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \ 16898 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \ 16899 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \ 16900 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) ) 16901 16902 #define OACC_PARALLEL_CLAUSE_MASK \ 16903 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \ 16904 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \ 16905 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \ 16906 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \ 16907 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \ 16908 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \ 16909 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \ 16910 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \ 16911 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \ 16912 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \ 16913 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \ 16914 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \ 16915 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS) \ 16916 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS) \ 16917 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \ 16918 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \ 16919 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \ 16920 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) ) 16921 16922 #define OACC_SERIAL_CLAUSE_MASK \ 16923 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \ 16924 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH) \ 16925 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY) \ 16926 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN) \ 16927 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT) \ 16928 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE) \ 16929 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT) \ 16930 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR) \ 16931 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \ 16932 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE) \ 16933 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE) \ 16934 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE) \ 16935 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) \ 16936 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION) \ 16937 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) ) 16938 16939 static tree 16940 c_parser_oacc_compute (location_t loc, c_parser *parser, 16941 enum pragma_kind p_kind, char *p_name, bool *if_p) 16942 { 16943 omp_clause_mask mask; 16944 enum tree_code code; 16945 switch (p_kind) 16946 { 16947 case PRAGMA_OACC_KERNELS: 16948 strcat (p_name, " kernels"); 16949 mask = OACC_KERNELS_CLAUSE_MASK; 16950 code = OACC_KERNELS; 16951 break; 16952 case PRAGMA_OACC_PARALLEL: 16953 strcat (p_name, " parallel"); 16954 mask = OACC_PARALLEL_CLAUSE_MASK; 16955 code = OACC_PARALLEL; 16956 break; 16957 case PRAGMA_OACC_SERIAL: 16958 strcat (p_name, " serial"); 16959 mask = OACC_SERIAL_CLAUSE_MASK; 16960 code = OACC_SERIAL; 16961 break; 16962 default: 16963 gcc_unreachable (); 16964 } 16965 16966 if (c_parser_next_token_is (parser, CPP_NAME)) 16967 { 16968 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 16969 if (strcmp (p, "loop") == 0) 16970 { 16971 c_parser_consume_token (parser); 16972 tree block = c_begin_omp_parallel (); 16973 tree clauses; 16974 c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p); 16975 return c_finish_omp_construct (loc, code, block, clauses); 16976 } 16977 } 16978 16979 tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name); 16980 16981 tree block = c_begin_omp_parallel (); 16982 add_stmt (c_parser_omp_structured_block (parser, if_p)); 16983 16984 return c_finish_omp_construct (loc, code, block, clauses); 16985 } 16986 16987 /* OpenACC 2.0: 16988 # pragma acc routine oacc-routine-clause[optseq] new-line 16989 function-definition 16990 16991 # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line 16992 */ 16993 16994 #define OACC_ROUTINE_CLAUSE_MASK \ 16995 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG) \ 16996 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER) \ 16997 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR) \ 16998 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ) ) 16999 17000 /* Parse an OpenACC routine directive. For named directives, we apply 17001 immediately to the named function. For unnamed ones we then parse 17002 a declaration or definition, which must be for a function. */ 17003 17004 static void 17005 c_parser_oacc_routine (c_parser *parser, enum pragma_context context) 17006 { 17007 gcc_checking_assert (context == pragma_external); 17008 17009 oacc_routine_data data; 17010 data.error_seen = false; 17011 data.fndecl_seen = false; 17012 data.loc = c_parser_peek_token (parser)->location; 17013 17014 c_parser_consume_pragma (parser); 17015 17016 /* Look for optional '( name )'. */ 17017 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 17018 { 17019 c_parser_consume_token (parser); /* '(' */ 17020 17021 tree decl = NULL_TREE; 17022 c_token *name_token = c_parser_peek_token (parser); 17023 location_t name_loc = name_token->location; 17024 if (name_token->type == CPP_NAME 17025 && (name_token->id_kind == C_ID_ID 17026 || name_token->id_kind == C_ID_TYPENAME)) 17027 { 17028 decl = lookup_name (name_token->value); 17029 if (!decl) 17030 error_at (name_loc, 17031 "%qE has not been declared", name_token->value); 17032 c_parser_consume_token (parser); 17033 } 17034 else 17035 c_parser_error (parser, "expected function name"); 17036 17037 if (!decl 17038 || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) 17039 { 17040 c_parser_skip_to_pragma_eol (parser, false); 17041 return; 17042 } 17043 17044 data.clauses 17045 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK, 17046 "#pragma acc routine"); 17047 /* The clauses are in reverse order; fix that to make later diagnostic 17048 emission easier. */ 17049 data.clauses = nreverse (data.clauses); 17050 17051 if (TREE_CODE (decl) != FUNCTION_DECL) 17052 { 17053 error_at (name_loc, "%qD does not refer to a function", decl); 17054 return; 17055 } 17056 17057 c_finish_oacc_routine (&data, decl, false); 17058 } 17059 else /* No optional '( name )'. */ 17060 { 17061 data.clauses 17062 = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK, 17063 "#pragma acc routine"); 17064 /* The clauses are in reverse order; fix that to make later diagnostic 17065 emission easier. */ 17066 data.clauses = nreverse (data.clauses); 17067 17068 /* Emit a helpful diagnostic if there's another pragma following this 17069 one. Also don't allow a static assertion declaration, as in the 17070 following we'll just parse a *single* "declaration or function 17071 definition", and the static assertion counts an one. */ 17072 if (c_parser_next_token_is (parser, CPP_PRAGMA) 17073 || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT)) 17074 { 17075 error_at (data.loc, 17076 "%<#pragma acc routine%> not immediately followed by" 17077 " function declaration or definition"); 17078 /* ..., and then just keep going. */ 17079 return; 17080 } 17081 17082 /* We only have to consider the pragma_external case here. */ 17083 if (c_parser_next_token_is (parser, CPP_KEYWORD) 17084 && c_parser_peek_token (parser)->keyword == RID_EXTENSION) 17085 { 17086 int ext = disable_extension_diagnostics (); 17087 do 17088 c_parser_consume_token (parser); 17089 while (c_parser_next_token_is (parser, CPP_KEYWORD) 17090 && c_parser_peek_token (parser)->keyword == RID_EXTENSION); 17091 c_parser_declaration_or_fndef (parser, true, true, true, false, true, 17092 NULL, vNULL, false, NULL, &data); 17093 restore_extension_diagnostics (ext); 17094 } 17095 else 17096 c_parser_declaration_or_fndef (parser, true, true, true, false, true, 17097 NULL, vNULL, false, NULL, &data); 17098 } 17099 } 17100 17101 /* Finalize an OpenACC routine pragma, applying it to FNDECL. 17102 IS_DEFN is true if we're applying it to the definition. */ 17103 17104 static void 17105 c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl, 17106 bool is_defn) 17107 { 17108 /* Keep going if we're in error reporting mode. */ 17109 if (data->error_seen 17110 || fndecl == error_mark_node) 17111 return; 17112 17113 if (data->fndecl_seen) 17114 { 17115 error_at (data->loc, 17116 "%<#pragma acc routine%> not immediately followed by" 17117 " a single function declaration or definition"); 17118 data->error_seen = true; 17119 return; 17120 } 17121 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL) 17122 { 17123 error_at (data->loc, 17124 "%<#pragma acc routine%> not immediately followed by" 17125 " function declaration or definition"); 17126 data->error_seen = true; 17127 return; 17128 } 17129 17130 int compatible 17131 = oacc_verify_routine_clauses (fndecl, &data->clauses, data->loc, 17132 "#pragma acc routine"); 17133 if (compatible < 0) 17134 { 17135 data->error_seen = true; 17136 return; 17137 } 17138 if (compatible > 0) 17139 { 17140 } 17141 else 17142 { 17143 if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl))) 17144 { 17145 error_at (data->loc, 17146 TREE_USED (fndecl) 17147 ? G_("%<#pragma acc routine%> must be applied before use") 17148 : G_("%<#pragma acc routine%> must be applied before" 17149 " definition")); 17150 data->error_seen = true; 17151 return; 17152 } 17153 17154 /* Set the routine's level of parallelism. */ 17155 tree dims = oacc_build_routine_dims (data->clauses); 17156 oacc_replace_fn_attrib (fndecl, dims); 17157 17158 /* Add an "omp declare target" attribute. */ 17159 DECL_ATTRIBUTES (fndecl) 17160 = tree_cons (get_identifier ("omp declare target"), 17161 data->clauses, DECL_ATTRIBUTES (fndecl)); 17162 } 17163 17164 /* Remember that we've used this "#pragma acc routine". */ 17165 data->fndecl_seen = true; 17166 } 17167 17168 /* OpenACC 2.0: 17169 # pragma acc update oacc-update-clause[optseq] new-line 17170 */ 17171 17172 #define OACC_UPDATE_CLAUSE_MASK \ 17173 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) \ 17174 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE) \ 17175 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST) \ 17176 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) \ 17177 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) \ 17178 | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) ) 17179 17180 static void 17181 c_parser_oacc_update (c_parser *parser) 17182 { 17183 location_t loc = c_parser_peek_token (parser)->location; 17184 17185 c_parser_consume_pragma (parser); 17186 17187 tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK, 17188 "#pragma acc update"); 17189 if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE) 17190 { 17191 error_at (loc, 17192 "%<#pragma acc update%> must contain at least one " 17193 "%<device%> or %<host%> or %<self%> clause"); 17194 return; 17195 } 17196 17197 if (parser->error) 17198 return; 17199 17200 tree stmt = make_node (OACC_UPDATE); 17201 TREE_TYPE (stmt) = void_type_node; 17202 OACC_UPDATE_CLAUSES (stmt) = clauses; 17203 SET_EXPR_LOCATION (stmt, loc); 17204 add_stmt (stmt); 17205 } 17206 17207 /* OpenACC 2.0: 17208 # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line 17209 17210 LOC is the location of the #pragma token. 17211 */ 17212 17213 #define OACC_WAIT_CLAUSE_MASK \ 17214 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC) ) 17215 17216 static tree 17217 c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name) 17218 { 17219 tree clauses, list = NULL_TREE, stmt = NULL_TREE; 17220 17221 if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN) 17222 list = c_parser_oacc_wait_list (parser, loc, list); 17223 17224 strcpy (p_name, " wait"); 17225 clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name); 17226 stmt = c_finish_oacc_wait (loc, list, clauses); 17227 add_stmt (stmt); 17228 17229 return stmt; 17230 } 17231 17232 /* OpenMP 2.5: 17233 # pragma omp atomic new-line 17234 expression-stmt 17235 17236 expression-stmt: 17237 x binop= expr | x++ | ++x | x-- | --x 17238 binop: 17239 +, *, -, /, &, ^, |, <<, >> 17240 17241 where x is an lvalue expression with scalar type. 17242 17243 OpenMP 3.1: 17244 # pragma omp atomic new-line 17245 update-stmt 17246 17247 # pragma omp atomic read new-line 17248 read-stmt 17249 17250 # pragma omp atomic write new-line 17251 write-stmt 17252 17253 # pragma omp atomic update new-line 17254 update-stmt 17255 17256 # pragma omp atomic capture new-line 17257 capture-stmt 17258 17259 # pragma omp atomic capture new-line 17260 capture-block 17261 17262 read-stmt: 17263 v = x 17264 write-stmt: 17265 x = expr 17266 update-stmt: 17267 expression-stmt | x = x binop expr 17268 capture-stmt: 17269 v = expression-stmt 17270 capture-block: 17271 { v = x; update-stmt; } | { update-stmt; v = x; } 17272 17273 OpenMP 4.0: 17274 update-stmt: 17275 expression-stmt | x = x binop expr | x = expr binop x 17276 capture-stmt: 17277 v = update-stmt 17278 capture-block: 17279 { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; } 17280 17281 where x and v are lvalue expressions with scalar type. 17282 17283 LOC is the location of the #pragma token. */ 17284 17285 static void 17286 c_parser_omp_atomic (location_t loc, c_parser *parser) 17287 { 17288 tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE; 17289 tree lhs1 = NULL_TREE, rhs1 = NULL_TREE; 17290 tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE; 17291 enum tree_code code = ERROR_MARK, opcode = NOP_EXPR; 17292 enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED; 17293 struct c_expr expr; 17294 location_t eloc; 17295 bool structured_block = false; 17296 bool swapped = false; 17297 bool non_lvalue_p; 17298 bool first = true; 17299 tree clauses = NULL_TREE; 17300 17301 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 17302 { 17303 if (!first && c_parser_next_token_is (parser, CPP_COMMA)) 17304 c_parser_consume_token (parser); 17305 17306 first = false; 17307 17308 if (c_parser_next_token_is (parser, CPP_NAME)) 17309 { 17310 const char *p 17311 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 17312 location_t cloc = c_parser_peek_token (parser)->location; 17313 enum tree_code new_code = ERROR_MARK; 17314 enum omp_memory_order new_memory_order 17315 = OMP_MEMORY_ORDER_UNSPECIFIED; 17316 17317 if (!strcmp (p, "read")) 17318 new_code = OMP_ATOMIC_READ; 17319 else if (!strcmp (p, "write")) 17320 new_code = NOP_EXPR; 17321 else if (!strcmp (p, "update")) 17322 new_code = OMP_ATOMIC; 17323 else if (!strcmp (p, "capture")) 17324 new_code = OMP_ATOMIC_CAPTURE_NEW; 17325 else if (!strcmp (p, "seq_cst")) 17326 new_memory_order = OMP_MEMORY_ORDER_SEQ_CST; 17327 else if (!strcmp (p, "acq_rel")) 17328 new_memory_order = OMP_MEMORY_ORDER_ACQ_REL; 17329 else if (!strcmp (p, "release")) 17330 new_memory_order = OMP_MEMORY_ORDER_RELEASE; 17331 else if (!strcmp (p, "acquire")) 17332 new_memory_order = OMP_MEMORY_ORDER_ACQUIRE; 17333 else if (!strcmp (p, "relaxed")) 17334 new_memory_order = OMP_MEMORY_ORDER_RELAXED; 17335 else if (!strcmp (p, "hint")) 17336 { 17337 c_parser_consume_token (parser); 17338 clauses = c_parser_omp_clause_hint (parser, clauses); 17339 continue; 17340 } 17341 else 17342 { 17343 p = NULL; 17344 error_at (cloc, "expected %<read%>, %<write%>, %<update%>, " 17345 "%<capture%>, %<seq_cst%>, %<acq_rel%>, " 17346 "%<release%>, %<relaxed%> or %<hint%> clause"); 17347 } 17348 if (p) 17349 { 17350 if (new_code != ERROR_MARK) 17351 { 17352 if (code != ERROR_MARK) 17353 error_at (cloc, "too many atomic clauses"); 17354 else 17355 code = new_code; 17356 } 17357 else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED) 17358 { 17359 if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED) 17360 error_at (cloc, "too many memory order clauses"); 17361 else 17362 memory_order = new_memory_order; 17363 } 17364 c_parser_consume_token (parser); 17365 continue; 17366 } 17367 } 17368 break; 17369 } 17370 c_parser_skip_to_pragma_eol (parser); 17371 17372 if (code == ERROR_MARK) 17373 code = OMP_ATOMIC; 17374 if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED) 17375 { 17376 omp_requires_mask 17377 = (enum omp_requires) (omp_requires_mask 17378 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED); 17379 switch ((enum omp_memory_order) 17380 (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER)) 17381 { 17382 case OMP_MEMORY_ORDER_UNSPECIFIED: 17383 case OMP_MEMORY_ORDER_RELAXED: 17384 memory_order = OMP_MEMORY_ORDER_RELAXED; 17385 break; 17386 case OMP_MEMORY_ORDER_SEQ_CST: 17387 memory_order = OMP_MEMORY_ORDER_SEQ_CST; 17388 break; 17389 case OMP_MEMORY_ORDER_ACQ_REL: 17390 switch (code) 17391 { 17392 case OMP_ATOMIC_READ: 17393 memory_order = OMP_MEMORY_ORDER_ACQUIRE; 17394 break; 17395 case NOP_EXPR: /* atomic write */ 17396 case OMP_ATOMIC: 17397 memory_order = OMP_MEMORY_ORDER_RELEASE; 17398 break; 17399 default: 17400 memory_order = OMP_MEMORY_ORDER_ACQ_REL; 17401 break; 17402 } 17403 break; 17404 default: 17405 gcc_unreachable (); 17406 } 17407 } 17408 else 17409 switch (code) 17410 { 17411 case OMP_ATOMIC_READ: 17412 if (memory_order == OMP_MEMORY_ORDER_ACQ_REL 17413 || memory_order == OMP_MEMORY_ORDER_RELEASE) 17414 { 17415 error_at (loc, "%<#pragma omp atomic read%> incompatible with " 17416 "%<acq_rel%> or %<release%> clauses"); 17417 memory_order = OMP_MEMORY_ORDER_SEQ_CST; 17418 } 17419 break; 17420 case NOP_EXPR: /* atomic write */ 17421 if (memory_order == OMP_MEMORY_ORDER_ACQ_REL 17422 || memory_order == OMP_MEMORY_ORDER_ACQUIRE) 17423 { 17424 error_at (loc, "%<#pragma omp atomic write%> incompatible with " 17425 "%<acq_rel%> or %<acquire%> clauses"); 17426 memory_order = OMP_MEMORY_ORDER_SEQ_CST; 17427 } 17428 break; 17429 case OMP_ATOMIC: 17430 if (memory_order == OMP_MEMORY_ORDER_ACQ_REL 17431 || memory_order == OMP_MEMORY_ORDER_ACQUIRE) 17432 { 17433 error_at (loc, "%<#pragma omp atomic update%> incompatible with " 17434 "%<acq_rel%> or %<acquire%> clauses"); 17435 memory_order = OMP_MEMORY_ORDER_SEQ_CST; 17436 } 17437 break; 17438 default: 17439 break; 17440 } 17441 17442 switch (code) 17443 { 17444 case OMP_ATOMIC_READ: 17445 case NOP_EXPR: /* atomic write */ 17446 v = c_parser_cast_expression (parser, NULL).value; 17447 non_lvalue_p = !lvalue_p (v); 17448 v = c_fully_fold (v, false, NULL, true); 17449 if (v == error_mark_node) 17450 goto saw_error; 17451 if (non_lvalue_p) 17452 v = non_lvalue (v); 17453 loc = c_parser_peek_token (parser)->location; 17454 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) 17455 goto saw_error; 17456 if (code == NOP_EXPR) 17457 { 17458 lhs = c_parser_expression (parser).value; 17459 lhs = c_fully_fold (lhs, false, NULL); 17460 if (lhs == error_mark_node) 17461 goto saw_error; 17462 } 17463 else 17464 { 17465 lhs = c_parser_cast_expression (parser, NULL).value; 17466 non_lvalue_p = !lvalue_p (lhs); 17467 lhs = c_fully_fold (lhs, false, NULL, true); 17468 if (lhs == error_mark_node) 17469 goto saw_error; 17470 if (non_lvalue_p) 17471 lhs = non_lvalue (lhs); 17472 } 17473 if (code == NOP_EXPR) 17474 { 17475 /* atomic write is represented by OMP_ATOMIC with NOP_EXPR 17476 opcode. */ 17477 code = OMP_ATOMIC; 17478 rhs = lhs; 17479 lhs = v; 17480 v = NULL_TREE; 17481 } 17482 goto done; 17483 case OMP_ATOMIC_CAPTURE_NEW: 17484 if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 17485 { 17486 c_parser_consume_token (parser); 17487 structured_block = true; 17488 } 17489 else 17490 { 17491 v = c_parser_cast_expression (parser, NULL).value; 17492 non_lvalue_p = !lvalue_p (v); 17493 v = c_fully_fold (v, false, NULL, true); 17494 if (v == error_mark_node) 17495 goto saw_error; 17496 if (non_lvalue_p) 17497 v = non_lvalue (v); 17498 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) 17499 goto saw_error; 17500 } 17501 break; 17502 default: 17503 break; 17504 } 17505 17506 /* For structured_block case we don't know yet whether 17507 old or new x should be captured. */ 17508 restart: 17509 eloc = c_parser_peek_token (parser)->location; 17510 expr = c_parser_cast_expression (parser, NULL); 17511 lhs = expr.value; 17512 expr = default_function_array_conversion (eloc, expr); 17513 unfolded_lhs = expr.value; 17514 lhs = c_fully_fold (lhs, false, NULL, true); 17515 orig_lhs = lhs; 17516 switch (TREE_CODE (lhs)) 17517 { 17518 case ERROR_MARK: 17519 saw_error: 17520 c_parser_skip_to_end_of_block_or_statement (parser); 17521 if (structured_block) 17522 { 17523 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 17524 c_parser_consume_token (parser); 17525 else if (code == OMP_ATOMIC_CAPTURE_NEW) 17526 { 17527 c_parser_skip_to_end_of_block_or_statement (parser); 17528 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 17529 c_parser_consume_token (parser); 17530 } 17531 } 17532 return; 17533 17534 case POSTINCREMENT_EXPR: 17535 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block) 17536 code = OMP_ATOMIC_CAPTURE_OLD; 17537 /* FALLTHROUGH */ 17538 case PREINCREMENT_EXPR: 17539 lhs = TREE_OPERAND (lhs, 0); 17540 unfolded_lhs = NULL_TREE; 17541 opcode = PLUS_EXPR; 17542 rhs = integer_one_node; 17543 break; 17544 17545 case POSTDECREMENT_EXPR: 17546 if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block) 17547 code = OMP_ATOMIC_CAPTURE_OLD; 17548 /* FALLTHROUGH */ 17549 case PREDECREMENT_EXPR: 17550 lhs = TREE_OPERAND (lhs, 0); 17551 unfolded_lhs = NULL_TREE; 17552 opcode = MINUS_EXPR; 17553 rhs = integer_one_node; 17554 break; 17555 17556 case COMPOUND_EXPR: 17557 if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR 17558 && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR 17559 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR 17560 && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0) 17561 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND 17562 (TREE_OPERAND (lhs, 1), 0), 0))) 17563 == BOOLEAN_TYPE) 17564 /* Undo effects of boolean_increment for post {in,de}crement. */ 17565 lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0); 17566 /* FALLTHRU */ 17567 case MODIFY_EXPR: 17568 if (TREE_CODE (lhs) == MODIFY_EXPR 17569 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE) 17570 { 17571 /* Undo effects of boolean_increment. */ 17572 if (integer_onep (TREE_OPERAND (lhs, 1))) 17573 { 17574 /* This is pre or post increment. */ 17575 rhs = TREE_OPERAND (lhs, 1); 17576 lhs = TREE_OPERAND (lhs, 0); 17577 unfolded_lhs = NULL_TREE; 17578 opcode = NOP_EXPR; 17579 if (code == OMP_ATOMIC_CAPTURE_NEW 17580 && !structured_block 17581 && TREE_CODE (orig_lhs) == COMPOUND_EXPR) 17582 code = OMP_ATOMIC_CAPTURE_OLD; 17583 break; 17584 } 17585 if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR 17586 && TREE_OPERAND (lhs, 0) 17587 == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) 17588 { 17589 /* This is pre or post decrement. */ 17590 rhs = TREE_OPERAND (lhs, 1); 17591 lhs = TREE_OPERAND (lhs, 0); 17592 unfolded_lhs = NULL_TREE; 17593 opcode = NOP_EXPR; 17594 if (code == OMP_ATOMIC_CAPTURE_NEW 17595 && !structured_block 17596 && TREE_CODE (orig_lhs) == COMPOUND_EXPR) 17597 code = OMP_ATOMIC_CAPTURE_OLD; 17598 break; 17599 } 17600 } 17601 /* FALLTHRU */ 17602 default: 17603 if (!lvalue_p (unfolded_lhs)) 17604 lhs = non_lvalue (lhs); 17605 switch (c_parser_peek_token (parser)->type) 17606 { 17607 case CPP_MULT_EQ: 17608 opcode = MULT_EXPR; 17609 break; 17610 case CPP_DIV_EQ: 17611 opcode = TRUNC_DIV_EXPR; 17612 break; 17613 case CPP_PLUS_EQ: 17614 opcode = PLUS_EXPR; 17615 break; 17616 case CPP_MINUS_EQ: 17617 opcode = MINUS_EXPR; 17618 break; 17619 case CPP_LSHIFT_EQ: 17620 opcode = LSHIFT_EXPR; 17621 break; 17622 case CPP_RSHIFT_EQ: 17623 opcode = RSHIFT_EXPR; 17624 break; 17625 case CPP_AND_EQ: 17626 opcode = BIT_AND_EXPR; 17627 break; 17628 case CPP_OR_EQ: 17629 opcode = BIT_IOR_EXPR; 17630 break; 17631 case CPP_XOR_EQ: 17632 opcode = BIT_XOR_EXPR; 17633 break; 17634 case CPP_EQ: 17635 c_parser_consume_token (parser); 17636 eloc = c_parser_peek_token (parser)->location; 17637 expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs); 17638 rhs1 = expr.value; 17639 switch (TREE_CODE (rhs1)) 17640 { 17641 case MULT_EXPR: 17642 case TRUNC_DIV_EXPR: 17643 case RDIV_EXPR: 17644 case PLUS_EXPR: 17645 case MINUS_EXPR: 17646 case LSHIFT_EXPR: 17647 case RSHIFT_EXPR: 17648 case BIT_AND_EXPR: 17649 case BIT_IOR_EXPR: 17650 case BIT_XOR_EXPR: 17651 if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs)) 17652 { 17653 opcode = TREE_CODE (rhs1); 17654 rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL, 17655 true); 17656 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL, 17657 true); 17658 goto stmt_done; 17659 } 17660 if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs)) 17661 { 17662 opcode = TREE_CODE (rhs1); 17663 rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL, 17664 true); 17665 rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL, 17666 true); 17667 swapped = !commutative_tree_code (opcode); 17668 goto stmt_done; 17669 } 17670 break; 17671 case ERROR_MARK: 17672 goto saw_error; 17673 default: 17674 break; 17675 } 17676 if (c_parser_peek_token (parser)->type == CPP_SEMICOLON) 17677 { 17678 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW) 17679 { 17680 code = OMP_ATOMIC_CAPTURE_OLD; 17681 v = lhs; 17682 lhs = NULL_TREE; 17683 expr = default_function_array_read_conversion (eloc, expr); 17684 unfolded_lhs1 = expr.value; 17685 lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true); 17686 rhs1 = NULL_TREE; 17687 c_parser_consume_token (parser); 17688 goto restart; 17689 } 17690 if (structured_block) 17691 { 17692 opcode = NOP_EXPR; 17693 expr = default_function_array_read_conversion (eloc, expr); 17694 rhs = c_fully_fold (expr.value, false, NULL, true); 17695 rhs1 = NULL_TREE; 17696 goto stmt_done; 17697 } 17698 } 17699 c_parser_error (parser, "invalid form of %<#pragma omp atomic%>"); 17700 goto saw_error; 17701 default: 17702 c_parser_error (parser, 17703 "invalid operator for %<#pragma omp atomic%>"); 17704 goto saw_error; 17705 } 17706 17707 /* Arrange to pass the location of the assignment operator to 17708 c_finish_omp_atomic. */ 17709 loc = c_parser_peek_token (parser)->location; 17710 c_parser_consume_token (parser); 17711 eloc = c_parser_peek_token (parser)->location; 17712 expr = c_parser_expression (parser); 17713 expr = default_function_array_read_conversion (eloc, expr); 17714 rhs = expr.value; 17715 rhs = c_fully_fold (rhs, false, NULL, true); 17716 break; 17717 } 17718 stmt_done: 17719 if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW) 17720 { 17721 if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>")) 17722 goto saw_error; 17723 v = c_parser_cast_expression (parser, NULL).value; 17724 non_lvalue_p = !lvalue_p (v); 17725 v = c_fully_fold (v, false, NULL, true); 17726 if (v == error_mark_node) 17727 goto saw_error; 17728 if (non_lvalue_p) 17729 v = non_lvalue (v); 17730 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) 17731 goto saw_error; 17732 eloc = c_parser_peek_token (parser)->location; 17733 expr = c_parser_cast_expression (parser, NULL); 17734 lhs1 = expr.value; 17735 expr = default_function_array_read_conversion (eloc, expr); 17736 unfolded_lhs1 = expr.value; 17737 lhs1 = c_fully_fold (lhs1, false, NULL, true); 17738 if (lhs1 == error_mark_node) 17739 goto saw_error; 17740 if (!lvalue_p (unfolded_lhs1)) 17741 lhs1 = non_lvalue (lhs1); 17742 } 17743 if (structured_block) 17744 { 17745 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 17746 c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"); 17747 } 17748 done: 17749 if (unfolded_lhs && unfolded_lhs1 17750 && !c_tree_equal (unfolded_lhs, unfolded_lhs1)) 17751 { 17752 error ("%<#pragma omp atomic capture%> uses two different " 17753 "expressions for memory"); 17754 stmt = error_mark_node; 17755 } 17756 else 17757 stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1, 17758 swapped, memory_order); 17759 if (stmt != error_mark_node) 17760 add_stmt (stmt); 17761 17762 if (!structured_block) 17763 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 17764 } 17765 17766 17767 /* OpenMP 2.5: 17768 # pragma omp barrier new-line 17769 */ 17770 17771 static void 17772 c_parser_omp_barrier (c_parser *parser) 17773 { 17774 location_t loc = c_parser_peek_token (parser)->location; 17775 c_parser_consume_pragma (parser); 17776 c_parser_skip_to_pragma_eol (parser); 17777 17778 c_finish_omp_barrier (loc); 17779 } 17780 17781 /* OpenMP 2.5: 17782 # pragma omp critical [(name)] new-line 17783 structured-block 17784 17785 OpenMP 4.5: 17786 # pragma omp critical [(name) [hint(expression)]] new-line 17787 17788 LOC is the location of the #pragma itself. */ 17789 17790 #define OMP_CRITICAL_CLAUSE_MASK \ 17791 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) ) 17792 17793 static tree 17794 c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p) 17795 { 17796 tree stmt, name = NULL_TREE, clauses = NULL_TREE; 17797 17798 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 17799 { 17800 c_parser_consume_token (parser); 17801 if (c_parser_next_token_is (parser, CPP_NAME)) 17802 { 17803 name = c_parser_peek_token (parser)->value; 17804 c_parser_consume_token (parser); 17805 c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"); 17806 } 17807 else 17808 c_parser_error (parser, "expected identifier"); 17809 17810 if (c_parser_next_token_is (parser, CPP_COMMA) 17811 && c_parser_peek_2nd_token (parser)->type == CPP_NAME) 17812 c_parser_consume_token (parser); 17813 17814 clauses = c_parser_omp_all_clauses (parser, 17815 OMP_CRITICAL_CLAUSE_MASK, 17816 "#pragma omp critical"); 17817 } 17818 else 17819 { 17820 if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 17821 c_parser_error (parser, "expected %<(%> or end of line"); 17822 c_parser_skip_to_pragma_eol (parser); 17823 } 17824 17825 stmt = c_parser_omp_structured_block (parser, if_p); 17826 return c_finish_omp_critical (loc, stmt, name, clauses); 17827 } 17828 17829 /* OpenMP 5.0: 17830 # pragma omp depobj ( depobj ) depobj-clause new-line 17831 17832 depobj-clause: 17833 depend (dependence-type : locator) 17834 destroy 17835 update (dependence-type) 17836 17837 dependence-type: 17838 in 17839 out 17840 inout 17841 mutexinout */ 17842 17843 static void 17844 c_parser_omp_depobj (c_parser *parser) 17845 { 17846 location_t loc = c_parser_peek_token (parser)->location; 17847 c_parser_consume_pragma (parser); 17848 matching_parens parens; 17849 if (!parens.require_open (parser)) 17850 { 17851 c_parser_skip_to_pragma_eol (parser); 17852 return; 17853 } 17854 17855 tree depobj = c_parser_expr_no_commas (parser, NULL).value; 17856 if (depobj != error_mark_node) 17857 { 17858 if (!lvalue_p (depobj)) 17859 { 17860 error_at (EXPR_LOC_OR_LOC (depobj, loc), 17861 "%<depobj%> expression is not lvalue expression"); 17862 depobj = error_mark_node; 17863 } 17864 else 17865 { 17866 tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR, 17867 depobj, false); 17868 if (addr == error_mark_node) 17869 depobj = error_mark_node; 17870 else 17871 depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc), 17872 addr, RO_UNARY_STAR); 17873 } 17874 } 17875 17876 parens.skip_until_found_close (parser); 17877 tree clause = NULL_TREE; 17878 enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_SOURCE; 17879 location_t c_loc = c_parser_peek_token (parser)->location; 17880 if (c_parser_next_token_is (parser, CPP_NAME)) 17881 { 17882 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 17883 17884 c_parser_consume_token (parser); 17885 if (!strcmp ("depend", p)) 17886 { 17887 clause = c_parser_omp_clause_depend (parser, NULL_TREE); 17888 clause = c_finish_omp_clauses (clause, C_ORT_OMP); 17889 if (!clause) 17890 clause = error_mark_node; 17891 } 17892 else if (!strcmp ("destroy", p)) 17893 kind = OMP_CLAUSE_DEPEND_LAST; 17894 else if (!strcmp ("update", p)) 17895 { 17896 matching_parens c_parens; 17897 if (c_parens.require_open (parser)) 17898 { 17899 location_t c2_loc = c_parser_peek_token (parser)->location; 17900 if (c_parser_next_token_is (parser, CPP_NAME)) 17901 { 17902 const char *p2 17903 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 17904 17905 c_parser_consume_token (parser); 17906 if (!strcmp ("in", p2)) 17907 kind = OMP_CLAUSE_DEPEND_IN; 17908 else if (!strcmp ("out", p2)) 17909 kind = OMP_CLAUSE_DEPEND_OUT; 17910 else if (!strcmp ("inout", p2)) 17911 kind = OMP_CLAUSE_DEPEND_INOUT; 17912 else if (!strcmp ("mutexinoutset", p2)) 17913 kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET; 17914 } 17915 if (kind == OMP_CLAUSE_DEPEND_SOURCE) 17916 { 17917 clause = error_mark_node; 17918 error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%> or " 17919 "%<mutexinoutset%>"); 17920 } 17921 c_parens.skip_until_found_close (parser); 17922 } 17923 else 17924 clause = error_mark_node; 17925 } 17926 } 17927 if (!clause && kind == OMP_CLAUSE_DEPEND_SOURCE) 17928 { 17929 clause = error_mark_node; 17930 error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause"); 17931 } 17932 c_parser_skip_to_pragma_eol (parser); 17933 17934 c_finish_omp_depobj (loc, depobj, kind, clause); 17935 } 17936 17937 17938 /* OpenMP 2.5: 17939 # pragma omp flush flush-vars[opt] new-line 17940 17941 flush-vars: 17942 ( variable-list ) 17943 17944 OpenMP 5.0: 17945 # pragma omp flush memory-order-clause new-line */ 17946 17947 static void 17948 c_parser_omp_flush (c_parser *parser) 17949 { 17950 location_t loc = c_parser_peek_token (parser)->location; 17951 c_parser_consume_pragma (parser); 17952 enum memmodel mo = MEMMODEL_LAST; 17953 if (c_parser_next_token_is (parser, CPP_NAME)) 17954 { 17955 const char *p 17956 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 17957 17958 if (!strcmp (p, "acq_rel")) 17959 mo = MEMMODEL_ACQ_REL; 17960 else if (!strcmp (p, "release")) 17961 mo = MEMMODEL_RELEASE; 17962 else if (!strcmp (p, "acquire")) 17963 mo = MEMMODEL_ACQUIRE; 17964 else 17965 error_at (c_parser_peek_token (parser)->location, 17966 "expected %<acq_rel%>, %<release%> or %<acquire%>"); 17967 c_parser_consume_token (parser); 17968 } 17969 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 17970 { 17971 if (mo != MEMMODEL_LAST) 17972 error_at (c_parser_peek_token (parser)->location, 17973 "%<flush%> list specified together with memory order " 17974 "clause"); 17975 c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL); 17976 } 17977 else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 17978 c_parser_error (parser, "expected %<(%> or end of line"); 17979 c_parser_skip_to_pragma_eol (parser); 17980 17981 c_finish_omp_flush (loc, mo); 17982 } 17983 17984 /* OpenMP 5.0: 17985 17986 scan-loop-body: 17987 { structured-block scan-directive structured-block } */ 17988 17989 static void 17990 c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed) 17991 { 17992 tree substmt; 17993 location_t loc; 17994 tree clauses = NULL_TREE; 17995 17996 loc = c_parser_peek_token (parser)->location; 17997 if (!open_brace_parsed 17998 && !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) 17999 { 18000 /* Avoid skipping until the end of the block. */ 18001 parser->error = false; 18002 return; 18003 } 18004 18005 substmt = c_parser_omp_structured_block (parser, NULL); 18006 substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE); 18007 SET_EXPR_LOCATION (substmt, loc); 18008 add_stmt (substmt); 18009 18010 loc = c_parser_peek_token (parser)->location; 18011 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN) 18012 { 18013 enum omp_clause_code clause = OMP_CLAUSE_ERROR; 18014 18015 c_parser_consume_pragma (parser); 18016 18017 if (c_parser_next_token_is (parser, CPP_NAME)) 18018 { 18019 const char *p 18020 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 18021 if (strcmp (p, "inclusive") == 0) 18022 clause = OMP_CLAUSE_INCLUSIVE; 18023 else if (strcmp (p, "exclusive") == 0) 18024 clause = OMP_CLAUSE_EXCLUSIVE; 18025 } 18026 if (clause != OMP_CLAUSE_ERROR) 18027 { 18028 c_parser_consume_token (parser); 18029 clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE); 18030 } 18031 else 18032 c_parser_error (parser, "expected %<inclusive%> or " 18033 "%<exclusive%> clause"); 18034 c_parser_skip_to_pragma_eol (parser); 18035 } 18036 else 18037 error ("expected %<#pragma omp scan%>"); 18038 18039 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP); 18040 substmt = c_parser_omp_structured_block (parser, NULL); 18041 substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses); 18042 SET_EXPR_LOCATION (substmt, loc); 18043 add_stmt (substmt); 18044 18045 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, 18046 "expected %<}%>"); 18047 } 18048 18049 /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP. 18050 The real trick here is to determine the loop control variable early 18051 so that we can push a new decl if necessary to make it private. 18052 LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp", 18053 respectively. */ 18054 18055 static tree 18056 c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code, 18057 tree clauses, tree *cclauses, bool *if_p) 18058 { 18059 tree decl, cond, incr, save_break, save_cont, body, init, stmt, cl; 18060 tree declv, condv, incrv, initv, ret = NULL_TREE; 18061 tree pre_body = NULL_TREE, this_pre_body; 18062 tree ordered_cl = NULL_TREE; 18063 bool fail = false, open_brace_parsed = false; 18064 int i, collapse = 1, ordered = 0, count, nbraces = 0; 18065 location_t for_loc; 18066 bool tiling = false; 18067 bool inscan = false; 18068 vec<tree, va_gc> *for_block = make_tree_vector (); 18069 18070 for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl)) 18071 if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE) 18072 collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl)); 18073 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE) 18074 { 18075 tiling = true; 18076 collapse = list_length (OMP_CLAUSE_TILE_LIST (cl)); 18077 } 18078 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED 18079 && OMP_CLAUSE_ORDERED_EXPR (cl)) 18080 { 18081 ordered_cl = cl; 18082 ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl)); 18083 } 18084 else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION 18085 && OMP_CLAUSE_REDUCTION_INSCAN (cl) 18086 && (code == OMP_SIMD || code == OMP_FOR)) 18087 inscan = true; 18088 18089 if (ordered && ordered < collapse) 18090 { 18091 error_at (OMP_CLAUSE_LOCATION (ordered_cl), 18092 "%<ordered%> clause parameter is less than %<collapse%>"); 18093 OMP_CLAUSE_ORDERED_EXPR (ordered_cl) 18094 = build_int_cst (NULL_TREE, collapse); 18095 ordered = collapse; 18096 } 18097 if (ordered) 18098 { 18099 for (tree *pc = &clauses; *pc; ) 18100 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR) 18101 { 18102 error_at (OMP_CLAUSE_LOCATION (*pc), 18103 "%<linear%> clause may not be specified together " 18104 "with %<ordered%> clause with a parameter"); 18105 *pc = OMP_CLAUSE_CHAIN (*pc); 18106 } 18107 else 18108 pc = &OMP_CLAUSE_CHAIN (*pc); 18109 } 18110 18111 gcc_assert (tiling || (collapse >= 1 && ordered >= 0)); 18112 count = ordered ? ordered : collapse; 18113 18114 declv = make_tree_vec (count); 18115 initv = make_tree_vec (count); 18116 condv = make_tree_vec (count); 18117 incrv = make_tree_vec (count); 18118 18119 if (!c_parser_next_token_is_keyword (parser, RID_FOR)) 18120 { 18121 c_parser_error (parser, "for statement expected"); 18122 return NULL; 18123 } 18124 for_loc = c_parser_peek_token (parser)->location; 18125 c_parser_consume_token (parser); 18126 18127 for (i = 0; i < count; i++) 18128 { 18129 int bracecount = 0; 18130 18131 matching_parens parens; 18132 if (!parens.require_open (parser)) 18133 goto pop_scopes; 18134 18135 /* Parse the initialization declaration or expression. */ 18136 if (c_parser_next_tokens_start_declaration (parser)) 18137 { 18138 if (i > 0) 18139 vec_safe_push (for_block, c_begin_compound_stmt (true)); 18140 this_pre_body = push_stmt_list (); 18141 c_parser_declaration_or_fndef (parser, true, true, true, true, true, 18142 NULL, vNULL); 18143 if (this_pre_body) 18144 { 18145 this_pre_body = pop_stmt_list (this_pre_body); 18146 if (pre_body) 18147 { 18148 tree t = pre_body; 18149 pre_body = push_stmt_list (); 18150 add_stmt (t); 18151 add_stmt (this_pre_body); 18152 pre_body = pop_stmt_list (pre_body); 18153 } 18154 else 18155 pre_body = this_pre_body; 18156 } 18157 decl = check_for_loop_decls (for_loc, flag_isoc99); 18158 if (decl == NULL) 18159 goto error_init; 18160 if (DECL_INITIAL (decl) == error_mark_node) 18161 decl = error_mark_node; 18162 init = decl; 18163 } 18164 else if (c_parser_next_token_is (parser, CPP_NAME) 18165 && c_parser_peek_2nd_token (parser)->type == CPP_EQ) 18166 { 18167 struct c_expr decl_exp; 18168 struct c_expr init_exp; 18169 location_t init_loc; 18170 18171 decl_exp = c_parser_postfix_expression (parser); 18172 decl = decl_exp.value; 18173 18174 c_parser_require (parser, CPP_EQ, "expected %<=%>"); 18175 18176 init_loc = c_parser_peek_token (parser)->location; 18177 init_exp = c_parser_expr_no_commas (parser, NULL); 18178 init_exp = default_function_array_read_conversion (init_loc, 18179 init_exp); 18180 init = build_modify_expr (init_loc, decl, decl_exp.original_type, 18181 NOP_EXPR, init_loc, init_exp.value, 18182 init_exp.original_type); 18183 init = c_process_expr_stmt (init_loc, init); 18184 18185 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 18186 } 18187 else 18188 { 18189 error_init: 18190 c_parser_error (parser, 18191 "expected iteration declaration or initialization"); 18192 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 18193 "expected %<)%>"); 18194 fail = true; 18195 goto parse_next; 18196 } 18197 18198 /* Parse the loop condition. */ 18199 cond = NULL_TREE; 18200 if (c_parser_next_token_is_not (parser, CPP_SEMICOLON)) 18201 { 18202 location_t cond_loc = c_parser_peek_token (parser)->location; 18203 struct c_expr cond_expr 18204 = c_parser_binary_expression (parser, NULL, NULL_TREE); 18205 18206 cond = cond_expr.value; 18207 cond = c_objc_common_truthvalue_conversion (cond_loc, cond); 18208 if (COMPARISON_CLASS_P (cond)) 18209 { 18210 tree op0 = TREE_OPERAND (cond, 0), op1 = TREE_OPERAND (cond, 1); 18211 op0 = c_fully_fold (op0, false, NULL); 18212 op1 = c_fully_fold (op1, false, NULL); 18213 TREE_OPERAND (cond, 0) = op0; 18214 TREE_OPERAND (cond, 1) = op1; 18215 } 18216 switch (cond_expr.original_code) 18217 { 18218 case GT_EXPR: 18219 case GE_EXPR: 18220 case LT_EXPR: 18221 case LE_EXPR: 18222 break; 18223 case NE_EXPR: 18224 if (code != OACC_LOOP) 18225 break; 18226 /* FALLTHRU. */ 18227 default: 18228 /* Can't be cond = error_mark_node, because we want to preserve 18229 the location until c_finish_omp_for. */ 18230 cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node); 18231 break; 18232 } 18233 protected_set_expr_location (cond, cond_loc); 18234 } 18235 c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>"); 18236 18237 /* Parse the increment expression. */ 18238 incr = NULL_TREE; 18239 if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN)) 18240 { 18241 location_t incr_loc = c_parser_peek_token (parser)->location; 18242 18243 incr = c_process_expr_stmt (incr_loc, 18244 c_parser_expression (parser).value); 18245 } 18246 parens.skip_until_found_close (parser); 18247 18248 if (decl == NULL || decl == error_mark_node || init == error_mark_node) 18249 fail = true; 18250 else 18251 { 18252 TREE_VEC_ELT (declv, i) = decl; 18253 TREE_VEC_ELT (initv, i) = init; 18254 TREE_VEC_ELT (condv, i) = cond; 18255 TREE_VEC_ELT (incrv, i) = incr; 18256 } 18257 18258 parse_next: 18259 if (i == count - 1) 18260 break; 18261 18262 /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed 18263 in between the collapsed for loops to be still considered perfectly 18264 nested. Hopefully the final version clarifies this. 18265 For now handle (multiple) {'s and empty statements. */ 18266 do 18267 { 18268 if (c_parser_next_token_is_keyword (parser, RID_FOR)) 18269 { 18270 c_parser_consume_token (parser); 18271 break; 18272 } 18273 else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) 18274 { 18275 c_parser_consume_token (parser); 18276 bracecount++; 18277 } 18278 else if (bracecount 18279 && c_parser_next_token_is (parser, CPP_SEMICOLON)) 18280 c_parser_consume_token (parser); 18281 else 18282 { 18283 c_parser_error (parser, "not enough perfectly nested loops"); 18284 if (bracecount) 18285 { 18286 open_brace_parsed = true; 18287 bracecount--; 18288 } 18289 fail = true; 18290 count = 0; 18291 break; 18292 } 18293 } 18294 while (1); 18295 18296 nbraces += bracecount; 18297 } 18298 18299 if (nbraces) 18300 if_p = NULL; 18301 18302 save_break = c_break_label; 18303 c_break_label = size_one_node; 18304 save_cont = c_cont_label; 18305 c_cont_label = NULL_TREE; 18306 body = push_stmt_list (); 18307 18308 if (inscan) 18309 c_parser_omp_scan_loop_body (parser, open_brace_parsed); 18310 else if (open_brace_parsed) 18311 { 18312 location_t here = c_parser_peek_token (parser)->location; 18313 stmt = c_begin_compound_stmt (true); 18314 c_parser_compound_statement_nostart (parser); 18315 add_stmt (c_end_compound_stmt (here, stmt, true)); 18316 } 18317 else 18318 add_stmt (c_parser_c99_block_statement (parser, if_p)); 18319 if (c_cont_label) 18320 { 18321 tree t = build1 (LABEL_EXPR, void_type_node, c_cont_label); 18322 SET_EXPR_LOCATION (t, loc); 18323 add_stmt (t); 18324 } 18325 18326 body = pop_stmt_list (body); 18327 c_break_label = save_break; 18328 c_cont_label = save_cont; 18329 18330 while (nbraces) 18331 { 18332 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 18333 { 18334 c_parser_consume_token (parser); 18335 nbraces--; 18336 } 18337 else if (c_parser_next_token_is (parser, CPP_SEMICOLON)) 18338 c_parser_consume_token (parser); 18339 else 18340 { 18341 c_parser_error (parser, "collapsed loops not perfectly nested"); 18342 while (nbraces) 18343 { 18344 location_t here = c_parser_peek_token (parser)->location; 18345 stmt = c_begin_compound_stmt (true); 18346 add_stmt (body); 18347 c_parser_compound_statement_nostart (parser); 18348 body = c_end_compound_stmt (here, stmt, true); 18349 nbraces--; 18350 } 18351 goto pop_scopes; 18352 } 18353 } 18354 18355 /* Only bother calling c_finish_omp_for if we haven't already generated 18356 an error from the initialization parsing. */ 18357 if (!fail) 18358 { 18359 stmt = c_finish_omp_for (loc, code, declv, NULL, initv, condv, 18360 incrv, body, pre_body, true); 18361 18362 /* Check for iterators appearing in lb, b or incr expressions. */ 18363 if (stmt && !c_omp_check_loop_iv (stmt, declv, NULL)) 18364 stmt = NULL_TREE; 18365 18366 if (stmt) 18367 { 18368 add_stmt (stmt); 18369 18370 if (cclauses != NULL 18371 && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL) 18372 { 18373 tree *c; 18374 for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; ) 18375 if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE 18376 && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE) 18377 c = &OMP_CLAUSE_CHAIN (*c); 18378 else 18379 { 18380 for (i = 0; i < count; i++) 18381 if (TREE_VEC_ELT (declv, i) == OMP_CLAUSE_DECL (*c)) 18382 break; 18383 if (i == count) 18384 c = &OMP_CLAUSE_CHAIN (*c); 18385 else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE) 18386 { 18387 error_at (loc, 18388 "iteration variable %qD should not be firstprivate", 18389 OMP_CLAUSE_DECL (*c)); 18390 *c = OMP_CLAUSE_CHAIN (*c); 18391 } 18392 else 18393 { 18394 /* Move lastprivate (decl) clause to OMP_FOR_CLAUSES. */ 18395 tree l = *c; 18396 *c = OMP_CLAUSE_CHAIN (*c); 18397 if (code == OMP_SIMD) 18398 { 18399 OMP_CLAUSE_CHAIN (l) 18400 = cclauses[C_OMP_CLAUSE_SPLIT_FOR]; 18401 cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l; 18402 } 18403 else 18404 { 18405 OMP_CLAUSE_CHAIN (l) = clauses; 18406 clauses = l; 18407 } 18408 } 18409 } 18410 } 18411 OMP_FOR_CLAUSES (stmt) = clauses; 18412 } 18413 ret = stmt; 18414 } 18415 pop_scopes: 18416 while (!for_block->is_empty ()) 18417 { 18418 /* FIXME diagnostics: LOC below should be the actual location of 18419 this particular for block. We need to build a list of 18420 locations to go along with FOR_BLOCK. */ 18421 stmt = c_end_compound_stmt (loc, for_block->pop (), true); 18422 add_stmt (stmt); 18423 } 18424 release_tree_vector (for_block); 18425 return ret; 18426 } 18427 18428 /* Helper function for OpenMP parsing, split clauses and call 18429 finish_omp_clauses on each of the set of clauses afterwards. */ 18430 18431 static void 18432 omp_split_clauses (location_t loc, enum tree_code code, 18433 omp_clause_mask mask, tree clauses, tree *cclauses) 18434 { 18435 int i; 18436 c_omp_split_clauses (loc, code, mask, clauses, cclauses); 18437 for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++) 18438 if (cclauses[i]) 18439 cclauses[i] = c_finish_omp_clauses (cclauses[i], C_ORT_OMP); 18440 } 18441 18442 /* OpenMP 5.0: 18443 #pragma omp loop loop-clause[optseq] new-line 18444 for-loop 18445 18446 LOC is the location of the #pragma token. 18447 */ 18448 18449 #define OMP_LOOP_CLAUSE_MASK \ 18450 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 18451 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ 18452 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ 18453 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \ 18454 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND) \ 18455 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER)) 18456 18457 static tree 18458 c_parser_omp_loop (location_t loc, c_parser *parser, 18459 char *p_name, omp_clause_mask mask, tree *cclauses, 18460 bool *if_p) 18461 { 18462 tree block, clauses, ret; 18463 18464 strcat (p_name, " loop"); 18465 mask |= OMP_LOOP_CLAUSE_MASK; 18466 18467 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); 18468 if (cclauses) 18469 { 18470 omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses); 18471 clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP]; 18472 } 18473 18474 block = c_begin_compound_stmt (true); 18475 ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p); 18476 block = c_end_compound_stmt (loc, block, true); 18477 add_stmt (block); 18478 18479 return ret; 18480 } 18481 18482 /* OpenMP 4.0: 18483 #pragma omp simd simd-clause[optseq] new-line 18484 for-loop 18485 18486 LOC is the location of the #pragma token. 18487 */ 18488 18489 #define OMP_SIMD_CLAUSE_MASK \ 18490 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN) \ 18491 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \ 18492 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \ 18493 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \ 18494 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 18495 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ 18496 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ 18497 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \ 18498 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 18499 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL) \ 18500 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER)) 18501 18502 static tree 18503 c_parser_omp_simd (location_t loc, c_parser *parser, 18504 char *p_name, omp_clause_mask mask, tree *cclauses, 18505 bool *if_p) 18506 { 18507 tree block, clauses, ret; 18508 18509 strcat (p_name, " simd"); 18510 mask |= OMP_SIMD_CLAUSE_MASK; 18511 18512 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); 18513 if (cclauses) 18514 { 18515 omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses); 18516 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD]; 18517 tree c = omp_find_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR], 18518 OMP_CLAUSE_ORDERED); 18519 if (c && OMP_CLAUSE_ORDERED_EXPR (c)) 18520 { 18521 error_at (OMP_CLAUSE_LOCATION (c), 18522 "%<ordered%> clause with parameter may not be specified " 18523 "on %qs construct", p_name); 18524 OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE; 18525 } 18526 } 18527 18528 block = c_begin_compound_stmt (true); 18529 ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p); 18530 block = c_end_compound_stmt (loc, block, true); 18531 add_stmt (block); 18532 18533 return ret; 18534 } 18535 18536 /* OpenMP 2.5: 18537 #pragma omp for for-clause[optseq] new-line 18538 for-loop 18539 18540 OpenMP 4.0: 18541 #pragma omp for simd for-simd-clause[optseq] new-line 18542 for-loop 18543 18544 LOC is the location of the #pragma token. 18545 */ 18546 18547 #define OMP_FOR_CLAUSE_MASK \ 18548 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 18549 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 18550 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ 18551 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \ 18552 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ 18553 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED) \ 18554 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE) \ 18555 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \ 18556 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \ 18557 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER)) 18558 18559 static tree 18560 c_parser_omp_for (location_t loc, c_parser *parser, 18561 char *p_name, omp_clause_mask mask, tree *cclauses, 18562 bool *if_p) 18563 { 18564 tree block, clauses, ret; 18565 18566 strcat (p_name, " for"); 18567 mask |= OMP_FOR_CLAUSE_MASK; 18568 /* parallel for{, simd} disallows nowait clause, but for 18569 target {teams distribute ,}parallel for{, simd} it should be accepted. */ 18570 if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0) 18571 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT); 18572 /* Composite distribute parallel for{, simd} disallows ordered clause. */ 18573 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0) 18574 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED); 18575 18576 if (c_parser_next_token_is (parser, CPP_NAME)) 18577 { 18578 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 18579 18580 if (strcmp (p, "simd") == 0) 18581 { 18582 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 18583 if (cclauses == NULL) 18584 cclauses = cclauses_buf; 18585 18586 c_parser_consume_token (parser); 18587 if (!flag_openmp) /* flag_openmp_simd */ 18588 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses, 18589 if_p); 18590 block = c_begin_compound_stmt (true); 18591 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p); 18592 block = c_end_compound_stmt (loc, block, true); 18593 if (ret == NULL_TREE) 18594 return ret; 18595 ret = make_node (OMP_FOR); 18596 TREE_TYPE (ret) = void_type_node; 18597 OMP_FOR_BODY (ret) = block; 18598 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR]; 18599 SET_EXPR_LOCATION (ret, loc); 18600 add_stmt (ret); 18601 return ret; 18602 } 18603 } 18604 if (!flag_openmp) /* flag_openmp_simd */ 18605 { 18606 c_parser_skip_to_pragma_eol (parser, false); 18607 return NULL_TREE; 18608 } 18609 18610 /* Composite distribute parallel for disallows linear clause. */ 18611 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0) 18612 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR); 18613 18614 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); 18615 if (cclauses) 18616 { 18617 omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses); 18618 clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR]; 18619 } 18620 18621 block = c_begin_compound_stmt (true); 18622 ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p); 18623 block = c_end_compound_stmt (loc, block, true); 18624 add_stmt (block); 18625 18626 return ret; 18627 } 18628 18629 static tree c_parser_omp_taskloop (location_t, c_parser *, char *, 18630 omp_clause_mask, tree *, bool *); 18631 18632 /* OpenMP 2.5: 18633 # pragma omp master new-line 18634 structured-block 18635 18636 LOC is the location of the #pragma token. 18637 */ 18638 18639 static tree 18640 c_parser_omp_master (location_t loc, c_parser *parser, 18641 char *p_name, omp_clause_mask mask, tree *cclauses, 18642 bool *if_p) 18643 { 18644 tree block, clauses, ret; 18645 18646 strcat (p_name, " master"); 18647 18648 if (c_parser_next_token_is (parser, CPP_NAME)) 18649 { 18650 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 18651 18652 if (strcmp (p, "taskloop") == 0) 18653 { 18654 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 18655 if (cclauses == NULL) 18656 cclauses = cclauses_buf; 18657 18658 c_parser_consume_token (parser); 18659 if (!flag_openmp) /* flag_openmp_simd */ 18660 return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses, 18661 if_p); 18662 block = c_begin_compound_stmt (true); 18663 ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses, 18664 if_p); 18665 block = c_end_compound_stmt (loc, block, true); 18666 if (ret == NULL_TREE) 18667 return ret; 18668 ret = c_finish_omp_master (loc, block); 18669 return ret; 18670 } 18671 } 18672 if (!flag_openmp) /* flag_openmp_simd */ 18673 { 18674 c_parser_skip_to_pragma_eol (parser, false); 18675 return NULL_TREE; 18676 } 18677 18678 if (cclauses) 18679 { 18680 clauses = c_parser_omp_all_clauses (parser, mask, p_name, false); 18681 omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses); 18682 } 18683 else 18684 c_parser_skip_to_pragma_eol (parser); 18685 18686 return c_finish_omp_master (loc, c_parser_omp_structured_block (parser, 18687 if_p)); 18688 } 18689 18690 /* OpenMP 2.5: 18691 # pragma omp ordered new-line 18692 structured-block 18693 18694 OpenMP 4.5: 18695 # pragma omp ordered ordered-clauses new-line 18696 structured-block 18697 18698 # pragma omp ordered depend-clauses new-line */ 18699 18700 #define OMP_ORDERED_CLAUSE_MASK \ 18701 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS) \ 18702 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD)) 18703 18704 #define OMP_ORDERED_DEPEND_CLAUSE_MASK \ 18705 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) 18706 18707 static bool 18708 c_parser_omp_ordered (c_parser *parser, enum pragma_context context, 18709 bool *if_p) 18710 { 18711 location_t loc = c_parser_peek_token (parser)->location; 18712 c_parser_consume_pragma (parser); 18713 18714 if (context != pragma_stmt && context != pragma_compound) 18715 { 18716 c_parser_error (parser, "expected declaration specifiers"); 18717 c_parser_skip_to_pragma_eol (parser, false); 18718 return false; 18719 } 18720 18721 if (c_parser_next_token_is (parser, CPP_NAME)) 18722 { 18723 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 18724 18725 if (!strcmp ("depend", p)) 18726 { 18727 if (!flag_openmp) /* flag_openmp_simd */ 18728 { 18729 c_parser_skip_to_pragma_eol (parser, false); 18730 return false; 18731 } 18732 if (context == pragma_stmt) 18733 { 18734 error_at (loc, 18735 "%<#pragma omp ordered%> with %<depend%> clause may " 18736 "only be used in compound statements"); 18737 c_parser_skip_to_pragma_eol (parser, false); 18738 return false; 18739 } 18740 18741 tree clauses 18742 = c_parser_omp_all_clauses (parser, 18743 OMP_ORDERED_DEPEND_CLAUSE_MASK, 18744 "#pragma omp ordered"); 18745 c_finish_omp_ordered (loc, clauses, NULL_TREE); 18746 return false; 18747 } 18748 } 18749 18750 tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK, 18751 "#pragma omp ordered"); 18752 18753 if (!flag_openmp /* flag_openmp_simd */ 18754 && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE) 18755 return false; 18756 18757 c_finish_omp_ordered (loc, clauses, 18758 c_parser_omp_structured_block (parser, if_p)); 18759 return true; 18760 } 18761 18762 /* OpenMP 2.5: 18763 18764 section-scope: 18765 { section-sequence } 18766 18767 section-sequence: 18768 section-directive[opt] structured-block 18769 section-sequence section-directive structured-block 18770 18771 SECTIONS_LOC is the location of the #pragma omp sections. */ 18772 18773 static tree 18774 c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser) 18775 { 18776 tree stmt, substmt; 18777 bool error_suppress = false; 18778 location_t loc; 18779 18780 loc = c_parser_peek_token (parser)->location; 18781 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) 18782 { 18783 /* Avoid skipping until the end of the block. */ 18784 parser->error = false; 18785 return NULL_TREE; 18786 } 18787 18788 stmt = push_stmt_list (); 18789 18790 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION) 18791 { 18792 substmt = c_parser_omp_structured_block (parser, NULL); 18793 substmt = build1 (OMP_SECTION, void_type_node, substmt); 18794 SET_EXPR_LOCATION (substmt, loc); 18795 add_stmt (substmt); 18796 } 18797 18798 while (1) 18799 { 18800 if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) 18801 break; 18802 if (c_parser_next_token_is (parser, CPP_EOF)) 18803 break; 18804 18805 loc = c_parser_peek_token (parser)->location; 18806 if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION) 18807 { 18808 c_parser_consume_pragma (parser); 18809 c_parser_skip_to_pragma_eol (parser); 18810 error_suppress = false; 18811 } 18812 else if (!error_suppress) 18813 { 18814 error_at (loc, "expected %<#pragma omp section%> or %<}%>"); 18815 error_suppress = true; 18816 } 18817 18818 substmt = c_parser_omp_structured_block (parser, NULL); 18819 substmt = build1 (OMP_SECTION, void_type_node, substmt); 18820 SET_EXPR_LOCATION (substmt, loc); 18821 add_stmt (substmt); 18822 } 18823 c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, 18824 "expected %<#pragma omp section%> or %<}%>"); 18825 18826 substmt = pop_stmt_list (stmt); 18827 18828 stmt = make_node (OMP_SECTIONS); 18829 SET_EXPR_LOCATION (stmt, sections_loc); 18830 TREE_TYPE (stmt) = void_type_node; 18831 OMP_SECTIONS_BODY (stmt) = substmt; 18832 18833 return add_stmt (stmt); 18834 } 18835 18836 /* OpenMP 2.5: 18837 # pragma omp sections sections-clause[optseq] newline 18838 sections-scope 18839 18840 LOC is the location of the #pragma token. 18841 */ 18842 18843 #define OMP_SECTIONS_CLAUSE_MASK \ 18844 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 18845 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 18846 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ 18847 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ 18848 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)) 18849 18850 static tree 18851 c_parser_omp_sections (location_t loc, c_parser *parser, 18852 char *p_name, omp_clause_mask mask, tree *cclauses) 18853 { 18854 tree block, clauses, ret; 18855 18856 strcat (p_name, " sections"); 18857 mask |= OMP_SECTIONS_CLAUSE_MASK; 18858 if (cclauses) 18859 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT); 18860 18861 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); 18862 if (cclauses) 18863 { 18864 omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses); 18865 clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS]; 18866 } 18867 18868 block = c_begin_compound_stmt (true); 18869 ret = c_parser_omp_sections_scope (loc, parser); 18870 if (ret) 18871 OMP_SECTIONS_CLAUSES (ret) = clauses; 18872 block = c_end_compound_stmt (loc, block, true); 18873 add_stmt (block); 18874 18875 return ret; 18876 } 18877 18878 /* OpenMP 2.5: 18879 # pragma omp parallel parallel-clause[optseq] new-line 18880 structured-block 18881 # pragma omp parallel for parallel-for-clause[optseq] new-line 18882 structured-block 18883 # pragma omp parallel sections parallel-sections-clause[optseq] new-line 18884 structured-block 18885 18886 OpenMP 4.0: 18887 # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line 18888 structured-block 18889 18890 LOC is the location of the #pragma token. 18891 */ 18892 18893 #define OMP_PARALLEL_CLAUSE_MASK \ 18894 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 18895 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 18896 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 18897 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \ 18898 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \ 18899 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \ 18900 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ 18901 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS) \ 18902 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND)) 18903 18904 static tree 18905 c_parser_omp_parallel (location_t loc, c_parser *parser, 18906 char *p_name, omp_clause_mask mask, tree *cclauses, 18907 bool *if_p) 18908 { 18909 tree stmt, clauses, block; 18910 18911 strcat (p_name, " parallel"); 18912 mask |= OMP_PARALLEL_CLAUSE_MASK; 18913 /* #pragma omp target parallel{, for, for simd} disallow copyin clause. */ 18914 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0 18915 && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0) 18916 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN); 18917 18918 if (c_parser_next_token_is_keyword (parser, RID_FOR)) 18919 { 18920 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 18921 if (cclauses == NULL) 18922 cclauses = cclauses_buf; 18923 18924 c_parser_consume_token (parser); 18925 if (!flag_openmp) /* flag_openmp_simd */ 18926 return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p); 18927 block = c_begin_omp_parallel (); 18928 tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p); 18929 stmt 18930 = c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL], 18931 block); 18932 if (ret == NULL_TREE) 18933 return ret; 18934 OMP_PARALLEL_COMBINED (stmt) = 1; 18935 return stmt; 18936 } 18937 /* When combined with distribute, parallel has to be followed by for. 18938 #pragma omp target parallel is allowed though. */ 18939 else if (cclauses 18940 && (mask & (OMP_CLAUSE_MASK_1 18941 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0) 18942 { 18943 error_at (loc, "expected %<for%> after %qs", p_name); 18944 c_parser_skip_to_pragma_eol (parser); 18945 return NULL_TREE; 18946 } 18947 else if (c_parser_next_token_is (parser, CPP_NAME)) 18948 { 18949 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 18950 if (cclauses == NULL && strcmp (p, "master") == 0) 18951 { 18952 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 18953 cclauses = cclauses_buf; 18954 18955 c_parser_consume_token (parser); 18956 if (!flag_openmp) /* flag_openmp_simd */ 18957 return c_parser_omp_master (loc, parser, p_name, mask, cclauses, 18958 if_p); 18959 block = c_begin_omp_parallel (); 18960 tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses, 18961 if_p); 18962 stmt = c_finish_omp_parallel (loc, 18963 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL], 18964 block); 18965 if (ret == NULL) 18966 return ret; 18967 OMP_PARALLEL_COMBINED (stmt) = 1; 18968 return stmt; 18969 } 18970 else if (strcmp (p, "loop") == 0) 18971 { 18972 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 18973 if (cclauses == NULL) 18974 cclauses = cclauses_buf; 18975 18976 c_parser_consume_token (parser); 18977 if (!flag_openmp) /* flag_openmp_simd */ 18978 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses, 18979 if_p); 18980 block = c_begin_omp_parallel (); 18981 tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, 18982 if_p); 18983 stmt 18984 = c_finish_omp_parallel (loc, 18985 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL], 18986 block); 18987 if (ret == NULL_TREE) 18988 return ret; 18989 OMP_PARALLEL_COMBINED (stmt) = 1; 18990 return stmt; 18991 } 18992 else if (!flag_openmp) /* flag_openmp_simd */ 18993 { 18994 c_parser_skip_to_pragma_eol (parser, false); 18995 return NULL_TREE; 18996 } 18997 else if (cclauses == NULL && strcmp (p, "sections") == 0) 18998 { 18999 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 19000 cclauses = cclauses_buf; 19001 19002 c_parser_consume_token (parser); 19003 block = c_begin_omp_parallel (); 19004 c_parser_omp_sections (loc, parser, p_name, mask, cclauses); 19005 stmt = c_finish_omp_parallel (loc, 19006 cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL], 19007 block); 19008 OMP_PARALLEL_COMBINED (stmt) = 1; 19009 return stmt; 19010 } 19011 } 19012 else if (!flag_openmp) /* flag_openmp_simd */ 19013 { 19014 c_parser_skip_to_pragma_eol (parser, false); 19015 return NULL_TREE; 19016 } 19017 19018 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); 19019 if (cclauses) 19020 { 19021 omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses); 19022 clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; 19023 } 19024 19025 block = c_begin_omp_parallel (); 19026 c_parser_statement (parser, if_p); 19027 stmt = c_finish_omp_parallel (loc, clauses, block); 19028 19029 return stmt; 19030 } 19031 19032 /* OpenMP 2.5: 19033 # pragma omp single single-clause[optseq] new-line 19034 structured-block 19035 19036 LOC is the location of the #pragma. 19037 */ 19038 19039 #define OMP_SINGLE_CLAUSE_MASK \ 19040 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 19041 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 19042 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE) \ 19043 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)) 19044 19045 static tree 19046 c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p) 19047 { 19048 tree stmt = make_node (OMP_SINGLE); 19049 SET_EXPR_LOCATION (stmt, loc); 19050 TREE_TYPE (stmt) = void_type_node; 19051 19052 OMP_SINGLE_CLAUSES (stmt) 19053 = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK, 19054 "#pragma omp single"); 19055 OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p); 19056 19057 return add_stmt (stmt); 19058 } 19059 19060 /* OpenMP 3.0: 19061 # pragma omp task task-clause[optseq] new-line 19062 19063 LOC is the location of the #pragma. 19064 */ 19065 19066 #define OMP_TASK_CLAUSE_MASK \ 19067 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 19068 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \ 19069 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \ 19070 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 19071 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 19072 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \ 19073 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \ 19074 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \ 19075 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \ 19076 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \ 19077 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION)) 19078 19079 static tree 19080 c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p) 19081 { 19082 tree clauses, block; 19083 19084 clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK, 19085 "#pragma omp task"); 19086 19087 block = c_begin_omp_task (); 19088 c_parser_statement (parser, if_p); 19089 return c_finish_omp_task (loc, clauses, block); 19090 } 19091 19092 /* OpenMP 3.0: 19093 # pragma omp taskwait new-line 19094 19095 OpenMP 5.0: 19096 # pragma omp taskwait taskwait-clause[optseq] new-line 19097 */ 19098 19099 #define OMP_TASKWAIT_CLAUSE_MASK \ 19100 (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) 19101 19102 static void 19103 c_parser_omp_taskwait (c_parser *parser) 19104 { 19105 location_t loc = c_parser_peek_token (parser)->location; 19106 c_parser_consume_pragma (parser); 19107 19108 tree clauses 19109 = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK, 19110 "#pragma omp taskwait"); 19111 19112 if (clauses) 19113 { 19114 tree stmt = make_node (OMP_TASK); 19115 TREE_TYPE (stmt) = void_node; 19116 OMP_TASK_CLAUSES (stmt) = clauses; 19117 OMP_TASK_BODY (stmt) = NULL_TREE; 19118 SET_EXPR_LOCATION (stmt, loc); 19119 add_stmt (stmt); 19120 } 19121 else 19122 c_finish_omp_taskwait (loc); 19123 } 19124 19125 /* OpenMP 3.1: 19126 # pragma omp taskyield new-line 19127 */ 19128 19129 static void 19130 c_parser_omp_taskyield (c_parser *parser) 19131 { 19132 location_t loc = c_parser_peek_token (parser)->location; 19133 c_parser_consume_pragma (parser); 19134 c_parser_skip_to_pragma_eol (parser); 19135 19136 c_finish_omp_taskyield (loc); 19137 } 19138 19139 /* OpenMP 4.0: 19140 # pragma omp taskgroup new-line 19141 19142 OpenMP 5.0: 19143 # pragma omp taskgroup taskgroup-clause[optseq] new-line 19144 */ 19145 19146 #define OMP_TASKGROUP_CLAUSE_MASK \ 19147 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION)) 19148 19149 static tree 19150 c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p) 19151 { 19152 tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK, 19153 "#pragma omp taskgroup"); 19154 19155 tree body = c_parser_omp_structured_block (parser, if_p); 19156 return c_finish_omp_taskgroup (loc, body, clauses); 19157 } 19158 19159 /* OpenMP 4.0: 19160 # pragma omp cancel cancel-clause[optseq] new-line 19161 19162 LOC is the location of the #pragma. 19163 */ 19164 19165 #define OMP_CANCEL_CLAUSE_MASK \ 19166 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \ 19167 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \ 19168 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \ 19169 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP) \ 19170 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)) 19171 19172 static void 19173 c_parser_omp_cancel (c_parser *parser) 19174 { 19175 location_t loc = c_parser_peek_token (parser)->location; 19176 19177 c_parser_consume_pragma (parser); 19178 tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK, 19179 "#pragma omp cancel"); 19180 19181 c_finish_omp_cancel (loc, clauses); 19182 } 19183 19184 /* OpenMP 4.0: 19185 # pragma omp cancellation point cancelpt-clause[optseq] new-line 19186 19187 LOC is the location of the #pragma. 19188 */ 19189 19190 #define OMP_CANCELLATION_POINT_CLAUSE_MASK \ 19191 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL) \ 19192 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR) \ 19193 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS) \ 19194 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP)) 19195 19196 static void 19197 c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context) 19198 { 19199 location_t loc = c_parser_peek_token (parser)->location; 19200 tree clauses; 19201 bool point_seen = false; 19202 19203 c_parser_consume_pragma (parser); 19204 if (c_parser_next_token_is (parser, CPP_NAME)) 19205 { 19206 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 19207 if (strcmp (p, "point") == 0) 19208 { 19209 c_parser_consume_token (parser); 19210 point_seen = true; 19211 } 19212 } 19213 if (!point_seen) 19214 { 19215 c_parser_error (parser, "expected %<point%>"); 19216 c_parser_skip_to_pragma_eol (parser); 19217 return; 19218 } 19219 19220 if (context != pragma_compound) 19221 { 19222 if (context == pragma_stmt) 19223 error_at (loc, 19224 "%<#pragma %s%> may only be used in compound statements", 19225 "omp cancellation point"); 19226 else 19227 c_parser_error (parser, "expected declaration specifiers"); 19228 c_parser_skip_to_pragma_eol (parser, false); 19229 return; 19230 } 19231 19232 clauses 19233 = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK, 19234 "#pragma omp cancellation point"); 19235 19236 c_finish_omp_cancellation_point (loc, clauses); 19237 } 19238 19239 /* OpenMP 4.0: 19240 #pragma omp distribute distribute-clause[optseq] new-line 19241 for-loop */ 19242 19243 #define OMP_DISTRIBUTE_CLAUSE_MASK \ 19244 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 19245 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 19246 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ 19247 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\ 19248 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)) 19249 19250 static tree 19251 c_parser_omp_distribute (location_t loc, c_parser *parser, 19252 char *p_name, omp_clause_mask mask, tree *cclauses, 19253 bool *if_p) 19254 { 19255 tree clauses, block, ret; 19256 19257 strcat (p_name, " distribute"); 19258 mask |= OMP_DISTRIBUTE_CLAUSE_MASK; 19259 19260 if (c_parser_next_token_is (parser, CPP_NAME)) 19261 { 19262 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 19263 bool simd = false; 19264 bool parallel = false; 19265 19266 if (strcmp (p, "simd") == 0) 19267 simd = true; 19268 else 19269 parallel = strcmp (p, "parallel") == 0; 19270 if (parallel || simd) 19271 { 19272 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 19273 if (cclauses == NULL) 19274 cclauses = cclauses_buf; 19275 c_parser_consume_token (parser); 19276 if (!flag_openmp) /* flag_openmp_simd */ 19277 { 19278 if (simd) 19279 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses, 19280 if_p); 19281 else 19282 return c_parser_omp_parallel (loc, parser, p_name, mask, 19283 cclauses, if_p); 19284 } 19285 block = c_begin_compound_stmt (true); 19286 if (simd) 19287 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, 19288 if_p); 19289 else 19290 ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses, 19291 if_p); 19292 block = c_end_compound_stmt (loc, block, true); 19293 if (ret == NULL) 19294 return ret; 19295 ret = make_node (OMP_DISTRIBUTE); 19296 TREE_TYPE (ret) = void_type_node; 19297 OMP_FOR_BODY (ret) = block; 19298 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE]; 19299 SET_EXPR_LOCATION (ret, loc); 19300 add_stmt (ret); 19301 return ret; 19302 } 19303 } 19304 if (!flag_openmp) /* flag_openmp_simd */ 19305 { 19306 c_parser_skip_to_pragma_eol (parser, false); 19307 return NULL_TREE; 19308 } 19309 19310 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); 19311 if (cclauses) 19312 { 19313 omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses); 19314 clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE]; 19315 } 19316 19317 block = c_begin_compound_stmt (true); 19318 ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL, 19319 if_p); 19320 block = c_end_compound_stmt (loc, block, true); 19321 add_stmt (block); 19322 19323 return ret; 19324 } 19325 19326 /* OpenMP 4.0: 19327 # pragma omp teams teams-clause[optseq] new-line 19328 structured-block */ 19329 19330 #define OMP_TEAMS_CLAUSE_MASK \ 19331 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 19332 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 19333 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \ 19334 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ 19335 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS) \ 19336 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT) \ 19337 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT)) 19338 19339 static tree 19340 c_parser_omp_teams (location_t loc, c_parser *parser, 19341 char *p_name, omp_clause_mask mask, tree *cclauses, 19342 bool *if_p) 19343 { 19344 tree clauses, block, ret; 19345 19346 strcat (p_name, " teams"); 19347 mask |= OMP_TEAMS_CLAUSE_MASK; 19348 19349 if (c_parser_next_token_is (parser, CPP_NAME)) 19350 { 19351 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 19352 if (strcmp (p, "distribute") == 0) 19353 { 19354 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 19355 if (cclauses == NULL) 19356 cclauses = cclauses_buf; 19357 19358 c_parser_consume_token (parser); 19359 if (!flag_openmp) /* flag_openmp_simd */ 19360 return c_parser_omp_distribute (loc, parser, p_name, mask, 19361 cclauses, if_p); 19362 block = c_begin_omp_parallel (); 19363 ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses, 19364 if_p); 19365 block = c_end_compound_stmt (loc, block, true); 19366 if (ret == NULL) 19367 return ret; 19368 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS]; 19369 ret = make_node (OMP_TEAMS); 19370 TREE_TYPE (ret) = void_type_node; 19371 OMP_TEAMS_CLAUSES (ret) = clauses; 19372 OMP_TEAMS_BODY (ret) = block; 19373 OMP_TEAMS_COMBINED (ret) = 1; 19374 SET_EXPR_LOCATION (ret, loc); 19375 return add_stmt (ret); 19376 } 19377 else if (strcmp (p, "loop") == 0) 19378 { 19379 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 19380 if (cclauses == NULL) 19381 cclauses = cclauses_buf; 19382 19383 c_parser_consume_token (parser); 19384 if (!flag_openmp) /* flag_openmp_simd */ 19385 return c_parser_omp_loop (loc, parser, p_name, mask, cclauses, 19386 if_p); 19387 block = c_begin_omp_parallel (); 19388 ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p); 19389 block = c_end_compound_stmt (loc, block, true); 19390 if (ret == NULL) 19391 return ret; 19392 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS]; 19393 ret = make_node (OMP_TEAMS); 19394 TREE_TYPE (ret) = void_type_node; 19395 OMP_TEAMS_CLAUSES (ret) = clauses; 19396 OMP_TEAMS_BODY (ret) = block; 19397 OMP_TEAMS_COMBINED (ret) = 1; 19398 SET_EXPR_LOCATION (ret, loc); 19399 return add_stmt (ret); 19400 } 19401 } 19402 if (!flag_openmp) /* flag_openmp_simd */ 19403 { 19404 c_parser_skip_to_pragma_eol (parser, false); 19405 return NULL_TREE; 19406 } 19407 19408 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); 19409 if (cclauses) 19410 { 19411 omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses); 19412 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS]; 19413 } 19414 19415 tree stmt = make_node (OMP_TEAMS); 19416 TREE_TYPE (stmt) = void_type_node; 19417 OMP_TEAMS_CLAUSES (stmt) = clauses; 19418 block = c_begin_omp_parallel (); 19419 add_stmt (c_parser_omp_structured_block (parser, if_p)); 19420 OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true); 19421 SET_EXPR_LOCATION (stmt, loc); 19422 19423 return add_stmt (stmt); 19424 } 19425 19426 /* OpenMP 4.0: 19427 # pragma omp target data target-data-clause[optseq] new-line 19428 structured-block */ 19429 19430 #define OMP_TARGET_DATA_CLAUSE_MASK \ 19431 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \ 19432 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \ 19433 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 19434 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \ 19435 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR)) 19436 19437 static tree 19438 c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p) 19439 { 19440 tree clauses 19441 = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK, 19442 "#pragma omp target data"); 19443 int map_seen = 0; 19444 for (tree *pc = &clauses; *pc;) 19445 { 19446 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP) 19447 switch (OMP_CLAUSE_MAP_KIND (*pc)) 19448 { 19449 case GOMP_MAP_TO: 19450 case GOMP_MAP_ALWAYS_TO: 19451 case GOMP_MAP_FROM: 19452 case GOMP_MAP_ALWAYS_FROM: 19453 case GOMP_MAP_TOFROM: 19454 case GOMP_MAP_ALWAYS_TOFROM: 19455 case GOMP_MAP_ALLOC: 19456 map_seen = 3; 19457 break; 19458 case GOMP_MAP_FIRSTPRIVATE_POINTER: 19459 case GOMP_MAP_ALWAYS_POINTER: 19460 break; 19461 default: 19462 map_seen |= 1; 19463 error_at (OMP_CLAUSE_LOCATION (*pc), 19464 "%<#pragma omp target data%> with map-type other " 19465 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> " 19466 "on %<map%> clause"); 19467 *pc = OMP_CLAUSE_CHAIN (*pc); 19468 continue; 19469 } 19470 else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR 19471 || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR) 19472 map_seen = 3; 19473 pc = &OMP_CLAUSE_CHAIN (*pc); 19474 } 19475 19476 if (map_seen != 3) 19477 { 19478 if (map_seen == 0) 19479 error_at (loc, 19480 "%<#pragma omp target data%> must contain at least " 19481 "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> " 19482 "clause"); 19483 return NULL_TREE; 19484 } 19485 19486 tree stmt = make_node (OMP_TARGET_DATA); 19487 TREE_TYPE (stmt) = void_type_node; 19488 OMP_TARGET_DATA_CLAUSES (stmt) = clauses; 19489 keep_next_level (); 19490 tree block = c_begin_compound_stmt (true); 19491 add_stmt (c_parser_omp_structured_block (parser, if_p)); 19492 OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true); 19493 19494 SET_EXPR_LOCATION (stmt, loc); 19495 return add_stmt (stmt); 19496 } 19497 19498 /* OpenMP 4.0: 19499 # pragma omp target update target-update-clause[optseq] new-line */ 19500 19501 #define OMP_TARGET_UPDATE_CLAUSE_MASK \ 19502 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM) \ 19503 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \ 19504 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \ 19505 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 19506 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \ 19507 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)) 19508 19509 static bool 19510 c_parser_omp_target_update (location_t loc, c_parser *parser, 19511 enum pragma_context context) 19512 { 19513 if (context == pragma_stmt) 19514 { 19515 error_at (loc, "%<#pragma %s%> may only be used in compound statements", 19516 "omp target update"); 19517 c_parser_skip_to_pragma_eol (parser, false); 19518 return false; 19519 } 19520 19521 tree clauses 19522 = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK, 19523 "#pragma omp target update"); 19524 if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE 19525 && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE) 19526 { 19527 error_at (loc, 19528 "%<#pragma omp target update%> must contain at least one " 19529 "%<from%> or %<to%> clauses"); 19530 return false; 19531 } 19532 19533 tree stmt = make_node (OMP_TARGET_UPDATE); 19534 TREE_TYPE (stmt) = void_type_node; 19535 OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses; 19536 SET_EXPR_LOCATION (stmt, loc); 19537 add_stmt (stmt); 19538 return false; 19539 } 19540 19541 /* OpenMP 4.5: 19542 # pragma omp target enter data target-data-clause[optseq] new-line */ 19543 19544 #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK \ 19545 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \ 19546 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \ 19547 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 19548 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \ 19549 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)) 19550 19551 static tree 19552 c_parser_omp_target_enter_data (location_t loc, c_parser *parser, 19553 enum pragma_context context) 19554 { 19555 bool data_seen = false; 19556 if (c_parser_next_token_is (parser, CPP_NAME)) 19557 { 19558 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 19559 if (strcmp (p, "data") == 0) 19560 { 19561 c_parser_consume_token (parser); 19562 data_seen = true; 19563 } 19564 } 19565 if (!data_seen) 19566 { 19567 c_parser_error (parser, "expected %<data%>"); 19568 c_parser_skip_to_pragma_eol (parser); 19569 return NULL_TREE; 19570 } 19571 19572 if (context == pragma_stmt) 19573 { 19574 error_at (loc, "%<#pragma %s%> may only be used in compound statements", 19575 "omp target enter data"); 19576 c_parser_skip_to_pragma_eol (parser, false); 19577 return NULL_TREE; 19578 } 19579 19580 tree clauses 19581 = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK, 19582 "#pragma omp target enter data"); 19583 int map_seen = 0; 19584 for (tree *pc = &clauses; *pc;) 19585 { 19586 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP) 19587 switch (OMP_CLAUSE_MAP_KIND (*pc)) 19588 { 19589 case GOMP_MAP_TO: 19590 case GOMP_MAP_ALWAYS_TO: 19591 case GOMP_MAP_ALLOC: 19592 map_seen = 3; 19593 break; 19594 case GOMP_MAP_FIRSTPRIVATE_POINTER: 19595 case GOMP_MAP_ALWAYS_POINTER: 19596 break; 19597 default: 19598 map_seen |= 1; 19599 error_at (OMP_CLAUSE_LOCATION (*pc), 19600 "%<#pragma omp target enter data%> with map-type other " 19601 "than %<to%> or %<alloc%> on %<map%> clause"); 19602 *pc = OMP_CLAUSE_CHAIN (*pc); 19603 continue; 19604 } 19605 pc = &OMP_CLAUSE_CHAIN (*pc); 19606 } 19607 19608 if (map_seen != 3) 19609 { 19610 if (map_seen == 0) 19611 error_at (loc, 19612 "%<#pragma omp target enter data%> must contain at least " 19613 "one %<map%> clause"); 19614 return NULL_TREE; 19615 } 19616 19617 tree stmt = make_node (OMP_TARGET_ENTER_DATA); 19618 TREE_TYPE (stmt) = void_type_node; 19619 OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses; 19620 SET_EXPR_LOCATION (stmt, loc); 19621 add_stmt (stmt); 19622 return stmt; 19623 } 19624 19625 /* OpenMP 4.5: 19626 # pragma omp target exit data target-data-clause[optseq] new-line */ 19627 19628 #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK \ 19629 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \ 19630 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \ 19631 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 19632 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \ 19633 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)) 19634 19635 static tree 19636 c_parser_omp_target_exit_data (location_t loc, c_parser *parser, 19637 enum pragma_context context) 19638 { 19639 bool data_seen = false; 19640 if (c_parser_next_token_is (parser, CPP_NAME)) 19641 { 19642 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 19643 if (strcmp (p, "data") == 0) 19644 { 19645 c_parser_consume_token (parser); 19646 data_seen = true; 19647 } 19648 } 19649 if (!data_seen) 19650 { 19651 c_parser_error (parser, "expected %<data%>"); 19652 c_parser_skip_to_pragma_eol (parser); 19653 return NULL_TREE; 19654 } 19655 19656 if (context == pragma_stmt) 19657 { 19658 error_at (loc, "%<#pragma %s%> may only be used in compound statements", 19659 "omp target exit data"); 19660 c_parser_skip_to_pragma_eol (parser, false); 19661 return NULL_TREE; 19662 } 19663 19664 tree clauses 19665 = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK, 19666 "#pragma omp target exit data"); 19667 19668 int map_seen = 0; 19669 for (tree *pc = &clauses; *pc;) 19670 { 19671 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP) 19672 switch (OMP_CLAUSE_MAP_KIND (*pc)) 19673 { 19674 case GOMP_MAP_FROM: 19675 case GOMP_MAP_ALWAYS_FROM: 19676 case GOMP_MAP_RELEASE: 19677 case GOMP_MAP_DELETE: 19678 map_seen = 3; 19679 break; 19680 case GOMP_MAP_FIRSTPRIVATE_POINTER: 19681 case GOMP_MAP_ALWAYS_POINTER: 19682 break; 19683 default: 19684 map_seen |= 1; 19685 error_at (OMP_CLAUSE_LOCATION (*pc), 19686 "%<#pragma omp target exit data%> with map-type other " 19687 "than %<from%>, %<release%> or %<delete%> on %<map%>" 19688 " clause"); 19689 *pc = OMP_CLAUSE_CHAIN (*pc); 19690 continue; 19691 } 19692 pc = &OMP_CLAUSE_CHAIN (*pc); 19693 } 19694 19695 if (map_seen != 3) 19696 { 19697 if (map_seen == 0) 19698 error_at (loc, 19699 "%<#pragma omp target exit data%> must contain at least one " 19700 "%<map%> clause"); 19701 return NULL_TREE; 19702 } 19703 19704 tree stmt = make_node (OMP_TARGET_EXIT_DATA); 19705 TREE_TYPE (stmt) = void_type_node; 19706 OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses; 19707 SET_EXPR_LOCATION (stmt, loc); 19708 add_stmt (stmt); 19709 return stmt; 19710 } 19711 19712 /* OpenMP 4.0: 19713 # pragma omp target target-clause[optseq] new-line 19714 structured-block */ 19715 19716 #define OMP_TARGET_CLAUSE_MASK \ 19717 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \ 19718 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \ 19719 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 19720 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \ 19721 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \ 19722 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 19723 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 19724 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP) \ 19725 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)) 19726 19727 static bool 19728 c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p) 19729 { 19730 location_t loc = c_parser_peek_token (parser)->location; 19731 c_parser_consume_pragma (parser); 19732 tree *pc = NULL, stmt, block; 19733 19734 if (context != pragma_stmt && context != pragma_compound) 19735 { 19736 c_parser_error (parser, "expected declaration specifiers"); 19737 c_parser_skip_to_pragma_eol (parser); 19738 return false; 19739 } 19740 19741 if (flag_openmp) 19742 omp_requires_mask 19743 = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED); 19744 19745 if (c_parser_next_token_is (parser, CPP_NAME)) 19746 { 19747 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 19748 enum tree_code ccode = ERROR_MARK; 19749 19750 if (strcmp (p, "teams") == 0) 19751 ccode = OMP_TEAMS; 19752 else if (strcmp (p, "parallel") == 0) 19753 ccode = OMP_PARALLEL; 19754 else if (strcmp (p, "simd") == 0) 19755 ccode = OMP_SIMD; 19756 if (ccode != ERROR_MARK) 19757 { 19758 tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT]; 19759 char p_name[sizeof ("#pragma omp target teams distribute " 19760 "parallel for simd")]; 19761 19762 c_parser_consume_token (parser); 19763 strcpy (p_name, "#pragma omp target"); 19764 if (!flag_openmp) /* flag_openmp_simd */ 19765 { 19766 tree stmt; 19767 switch (ccode) 19768 { 19769 case OMP_TEAMS: 19770 stmt = c_parser_omp_teams (loc, parser, p_name, 19771 OMP_TARGET_CLAUSE_MASK, 19772 cclauses, if_p); 19773 break; 19774 case OMP_PARALLEL: 19775 stmt = c_parser_omp_parallel (loc, parser, p_name, 19776 OMP_TARGET_CLAUSE_MASK, 19777 cclauses, if_p); 19778 break; 19779 case OMP_SIMD: 19780 stmt = c_parser_omp_simd (loc, parser, p_name, 19781 OMP_TARGET_CLAUSE_MASK, 19782 cclauses, if_p); 19783 break; 19784 default: 19785 gcc_unreachable (); 19786 } 19787 return stmt != NULL_TREE; 19788 } 19789 keep_next_level (); 19790 tree block = c_begin_compound_stmt (true), ret; 19791 switch (ccode) 19792 { 19793 case OMP_TEAMS: 19794 ret = c_parser_omp_teams (loc, parser, p_name, 19795 OMP_TARGET_CLAUSE_MASK, cclauses, 19796 if_p); 19797 break; 19798 case OMP_PARALLEL: 19799 ret = c_parser_omp_parallel (loc, parser, p_name, 19800 OMP_TARGET_CLAUSE_MASK, cclauses, 19801 if_p); 19802 break; 19803 case OMP_SIMD: 19804 ret = c_parser_omp_simd (loc, parser, p_name, 19805 OMP_TARGET_CLAUSE_MASK, cclauses, 19806 if_p); 19807 break; 19808 default: 19809 gcc_unreachable (); 19810 } 19811 block = c_end_compound_stmt (loc, block, true); 19812 if (ret == NULL_TREE) 19813 return false; 19814 if (ccode == OMP_TEAMS) 19815 { 19816 /* For combined target teams, ensure the num_teams and 19817 thread_limit clause expressions are evaluated on the host, 19818 before entering the target construct. */ 19819 tree c; 19820 for (c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS]; 19821 c; c = OMP_CLAUSE_CHAIN (c)) 19822 if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS 19823 || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT) 19824 && TREE_CODE (OMP_CLAUSE_OPERAND (c, 0)) != INTEGER_CST) 19825 { 19826 tree expr = OMP_CLAUSE_OPERAND (c, 0); 19827 tree tmp = create_tmp_var_raw (TREE_TYPE (expr)); 19828 expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp, 19829 expr, NULL_TREE, NULL_TREE); 19830 add_stmt (expr); 19831 OMP_CLAUSE_OPERAND (c, 0) = expr; 19832 tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c), 19833 OMP_CLAUSE_FIRSTPRIVATE); 19834 OMP_CLAUSE_DECL (tc) = tmp; 19835 OMP_CLAUSE_CHAIN (tc) 19836 = cclauses[C_OMP_CLAUSE_SPLIT_TARGET]; 19837 cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc; 19838 } 19839 } 19840 tree stmt = make_node (OMP_TARGET); 19841 TREE_TYPE (stmt) = void_type_node; 19842 OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET]; 19843 OMP_TARGET_BODY (stmt) = block; 19844 OMP_TARGET_COMBINED (stmt) = 1; 19845 SET_EXPR_LOCATION (stmt, loc); 19846 add_stmt (stmt); 19847 pc = &OMP_TARGET_CLAUSES (stmt); 19848 goto check_clauses; 19849 } 19850 else if (!flag_openmp) /* flag_openmp_simd */ 19851 { 19852 c_parser_skip_to_pragma_eol (parser, false); 19853 return false; 19854 } 19855 else if (strcmp (p, "data") == 0) 19856 { 19857 c_parser_consume_token (parser); 19858 c_parser_omp_target_data (loc, parser, if_p); 19859 return true; 19860 } 19861 else if (strcmp (p, "enter") == 0) 19862 { 19863 c_parser_consume_token (parser); 19864 c_parser_omp_target_enter_data (loc, parser, context); 19865 return false; 19866 } 19867 else if (strcmp (p, "exit") == 0) 19868 { 19869 c_parser_consume_token (parser); 19870 c_parser_omp_target_exit_data (loc, parser, context); 19871 return false; 19872 } 19873 else if (strcmp (p, "update") == 0) 19874 { 19875 c_parser_consume_token (parser); 19876 return c_parser_omp_target_update (loc, parser, context); 19877 } 19878 } 19879 if (!flag_openmp) /* flag_openmp_simd */ 19880 { 19881 c_parser_skip_to_pragma_eol (parser, false); 19882 return false; 19883 } 19884 19885 stmt = make_node (OMP_TARGET); 19886 TREE_TYPE (stmt) = void_type_node; 19887 19888 OMP_TARGET_CLAUSES (stmt) 19889 = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK, 19890 "#pragma omp target"); 19891 pc = &OMP_TARGET_CLAUSES (stmt); 19892 keep_next_level (); 19893 block = c_begin_compound_stmt (true); 19894 add_stmt (c_parser_omp_structured_block (parser, if_p)); 19895 OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true); 19896 19897 SET_EXPR_LOCATION (stmt, loc); 19898 add_stmt (stmt); 19899 19900 check_clauses: 19901 while (*pc) 19902 { 19903 if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP) 19904 switch (OMP_CLAUSE_MAP_KIND (*pc)) 19905 { 19906 case GOMP_MAP_TO: 19907 case GOMP_MAP_ALWAYS_TO: 19908 case GOMP_MAP_FROM: 19909 case GOMP_MAP_ALWAYS_FROM: 19910 case GOMP_MAP_TOFROM: 19911 case GOMP_MAP_ALWAYS_TOFROM: 19912 case GOMP_MAP_ALLOC: 19913 case GOMP_MAP_FIRSTPRIVATE_POINTER: 19914 case GOMP_MAP_ALWAYS_POINTER: 19915 break; 19916 default: 19917 error_at (OMP_CLAUSE_LOCATION (*pc), 19918 "%<#pragma omp target%> with map-type other " 19919 "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> " 19920 "on %<map%> clause"); 19921 *pc = OMP_CLAUSE_CHAIN (*pc); 19922 continue; 19923 } 19924 pc = &OMP_CLAUSE_CHAIN (*pc); 19925 } 19926 return true; 19927 } 19928 19929 /* OpenMP 4.0: 19930 # pragma omp declare simd declare-simd-clauses[optseq] new-line 19931 19932 OpenMP 5.0: 19933 # pragma omp declare variant (identifier) match(context-selector) new-line 19934 */ 19935 19936 #define OMP_DECLARE_SIMD_CLAUSE_MASK \ 19937 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN) \ 19938 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \ 19939 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED) \ 19940 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM) \ 19941 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH) \ 19942 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH)) 19943 19944 static void 19945 c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context) 19946 { 19947 c_token *token = c_parser_peek_token (parser); 19948 gcc_assert (token->type == CPP_NAME); 19949 tree kind = token->value; 19950 gcc_assert (strcmp (IDENTIFIER_POINTER (kind), "simd") == 0 19951 || strcmp (IDENTIFIER_POINTER (kind), "variant") == 0); 19952 19953 auto_vec<c_token> clauses; 19954 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 19955 { 19956 c_token *token = c_parser_peek_token (parser); 19957 if (token->type == CPP_EOF) 19958 { 19959 c_parser_skip_to_pragma_eol (parser); 19960 return; 19961 } 19962 clauses.safe_push (*token); 19963 c_parser_consume_token (parser); 19964 } 19965 clauses.safe_push (*c_parser_peek_token (parser)); 19966 c_parser_skip_to_pragma_eol (parser); 19967 19968 while (c_parser_next_token_is (parser, CPP_PRAGMA)) 19969 { 19970 if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_DECLARE 19971 || c_parser_peek_2nd_token (parser)->type != CPP_NAME 19972 || c_parser_peek_2nd_token (parser)->value != kind) 19973 { 19974 error ("%<#pragma omp declare %s%> must be followed by " 19975 "function declaration or definition or another " 19976 "%<#pragma omp declare %s%>", 19977 IDENTIFIER_POINTER (kind), IDENTIFIER_POINTER (kind)); 19978 return; 19979 } 19980 c_parser_consume_pragma (parser); 19981 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 19982 { 19983 c_token *token = c_parser_peek_token (parser); 19984 if (token->type == CPP_EOF) 19985 { 19986 c_parser_skip_to_pragma_eol (parser); 19987 return; 19988 } 19989 clauses.safe_push (*token); 19990 c_parser_consume_token (parser); 19991 } 19992 clauses.safe_push (*c_parser_peek_token (parser)); 19993 c_parser_skip_to_pragma_eol (parser); 19994 } 19995 19996 /* Make sure nothing tries to read past the end of the tokens. */ 19997 c_token eof_token; 19998 memset (&eof_token, 0, sizeof (eof_token)); 19999 eof_token.type = CPP_EOF; 20000 clauses.safe_push (eof_token); 20001 clauses.safe_push (eof_token); 20002 20003 switch (context) 20004 { 20005 case pragma_external: 20006 if (c_parser_next_token_is (parser, CPP_KEYWORD) 20007 && c_parser_peek_token (parser)->keyword == RID_EXTENSION) 20008 { 20009 int ext = disable_extension_diagnostics (); 20010 do 20011 c_parser_consume_token (parser); 20012 while (c_parser_next_token_is (parser, CPP_KEYWORD) 20013 && c_parser_peek_token (parser)->keyword == RID_EXTENSION); 20014 c_parser_declaration_or_fndef (parser, true, true, true, false, true, 20015 NULL, clauses); 20016 restore_extension_diagnostics (ext); 20017 } 20018 else 20019 c_parser_declaration_or_fndef (parser, true, true, true, false, true, 20020 NULL, clauses); 20021 break; 20022 case pragma_struct: 20023 case pragma_param: 20024 case pragma_stmt: 20025 error ("%<#pragma omp declare %s%> must be followed by " 20026 "function declaration or definition", 20027 IDENTIFIER_POINTER (kind)); 20028 break; 20029 case pragma_compound: 20030 if (c_parser_next_token_is (parser, CPP_KEYWORD) 20031 && c_parser_peek_token (parser)->keyword == RID_EXTENSION) 20032 { 20033 int ext = disable_extension_diagnostics (); 20034 do 20035 c_parser_consume_token (parser); 20036 while (c_parser_next_token_is (parser, CPP_KEYWORD) 20037 && c_parser_peek_token (parser)->keyword == RID_EXTENSION); 20038 if (c_parser_next_tokens_start_declaration (parser)) 20039 { 20040 c_parser_declaration_or_fndef (parser, true, true, true, true, 20041 true, NULL, clauses); 20042 restore_extension_diagnostics (ext); 20043 break; 20044 } 20045 restore_extension_diagnostics (ext); 20046 } 20047 else if (c_parser_next_tokens_start_declaration (parser)) 20048 { 20049 c_parser_declaration_or_fndef (parser, true, true, true, true, true, 20050 NULL, clauses); 20051 break; 20052 } 20053 error ("%<#pragma omp declare %s%> must be followed by " 20054 "function declaration or definition", 20055 IDENTIFIER_POINTER (kind)); 20056 break; 20057 default: 20058 gcc_unreachable (); 20059 } 20060 } 20061 20062 static const char *const omp_construct_selectors[] = { 20063 "simd", "target", "teams", "parallel", "for", NULL }; 20064 static const char *const omp_device_selectors[] = { 20065 "kind", "isa", "arch", NULL }; 20066 static const char *const omp_implementation_selectors[] = { 20067 "vendor", "extension", "atomic_default_mem_order", "unified_address", 20068 "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL }; 20069 static const char *const omp_user_selectors[] = { 20070 "condition", NULL }; 20071 20072 /* OpenMP 5.0: 20073 20074 trait-selector: 20075 trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])] 20076 20077 trait-score: 20078 score(score-expression) */ 20079 20080 static tree 20081 c_parser_omp_context_selector (c_parser *parser, tree set, tree parms) 20082 { 20083 tree ret = NULL_TREE; 20084 do 20085 { 20086 tree selector; 20087 if (c_parser_next_token_is (parser, CPP_KEYWORD) 20088 || c_parser_next_token_is (parser, CPP_NAME)) 20089 selector = c_parser_peek_token (parser)->value; 20090 else 20091 { 20092 c_parser_error (parser, "expected trait selector name"); 20093 return error_mark_node; 20094 } 20095 20096 tree properties = NULL_TREE; 20097 const char *const *selectors = NULL; 20098 bool allow_score = true; 20099 bool allow_user = false; 20100 int property_limit = 0; 20101 enum { CTX_PROPERTY_NONE, CTX_PROPERTY_USER, CTX_PROPERTY_NAME_LIST, 20102 CTX_PROPERTY_ID, CTX_PROPERTY_EXPR, 20103 CTX_PROPERTY_SIMD } property_kind = CTX_PROPERTY_NONE; 20104 switch (IDENTIFIER_POINTER (set)[0]) 20105 { 20106 case 'c': /* construct */ 20107 selectors = omp_construct_selectors; 20108 allow_score = false; 20109 property_limit = 1; 20110 property_kind = CTX_PROPERTY_SIMD; 20111 break; 20112 case 'd': /* device */ 20113 selectors = omp_device_selectors; 20114 allow_score = false; 20115 allow_user = true; 20116 property_limit = 3; 20117 property_kind = CTX_PROPERTY_NAME_LIST; 20118 break; 20119 case 'i': /* implementation */ 20120 selectors = omp_implementation_selectors; 20121 allow_user = true; 20122 property_limit = 3; 20123 property_kind = CTX_PROPERTY_NAME_LIST; 20124 break; 20125 case 'u': /* user */ 20126 selectors = omp_user_selectors; 20127 property_limit = 1; 20128 property_kind = CTX_PROPERTY_EXPR; 20129 break; 20130 default: 20131 gcc_unreachable (); 20132 } 20133 for (int i = 0; ; i++) 20134 { 20135 if (selectors[i] == NULL) 20136 { 20137 if (allow_user) 20138 { 20139 property_kind = CTX_PROPERTY_USER; 20140 break; 20141 } 20142 else 20143 { 20144 error_at (c_parser_peek_token (parser)->location, 20145 "selector %qs not allowed for context selector " 20146 "set %qs", IDENTIFIER_POINTER (selector), 20147 IDENTIFIER_POINTER (set)); 20148 c_parser_consume_token (parser); 20149 return error_mark_node; 20150 } 20151 } 20152 if (i == property_limit) 20153 property_kind = CTX_PROPERTY_NONE; 20154 if (strcmp (selectors[i], IDENTIFIER_POINTER (selector)) == 0) 20155 break; 20156 } 20157 if (property_kind == CTX_PROPERTY_NAME_LIST 20158 && IDENTIFIER_POINTER (set)[0] == 'i' 20159 && strcmp (IDENTIFIER_POINTER (selector), 20160 "atomic_default_mem_order") == 0) 20161 property_kind = CTX_PROPERTY_ID; 20162 20163 c_parser_consume_token (parser); 20164 20165 if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 20166 { 20167 if (property_kind == CTX_PROPERTY_NONE) 20168 { 20169 error_at (c_parser_peek_token (parser)->location, 20170 "selector %qs does not accept any properties", 20171 IDENTIFIER_POINTER (selector)); 20172 return error_mark_node; 20173 } 20174 20175 matching_parens parens; 20176 parens.require_open (parser); 20177 20178 c_token *token = c_parser_peek_token (parser); 20179 if (allow_score 20180 && c_parser_next_token_is (parser, CPP_NAME) 20181 && strcmp (IDENTIFIER_POINTER (token->value), "score") == 0 20182 && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN) 20183 { 20184 c_parser_consume_token (parser); 20185 20186 matching_parens parens2; 20187 parens2.require_open (parser); 20188 tree score = c_parser_expr_no_commas (parser, NULL).value; 20189 parens2.skip_until_found_close (parser); 20190 c_parser_require (parser, CPP_COLON, "expected %<:%>"); 20191 if (score != error_mark_node) 20192 { 20193 mark_exp_read (score); 20194 score = c_fully_fold (score, false, NULL); 20195 if (!INTEGRAL_TYPE_P (TREE_TYPE (score)) 20196 || TREE_CODE (score) != INTEGER_CST) 20197 error_at (token->location, "score argument must be " 20198 "constant integer expression"); 20199 else if (tree_int_cst_sgn (score) < 0) 20200 error_at (token->location, "score argument must be " 20201 "non-negative"); 20202 else 20203 properties = tree_cons (get_identifier (" score"), 20204 score, properties); 20205 } 20206 token = c_parser_peek_token (parser); 20207 } 20208 20209 switch (property_kind) 20210 { 20211 tree t; 20212 case CTX_PROPERTY_USER: 20213 do 20214 { 20215 t = c_parser_expr_no_commas (parser, NULL).value; 20216 if (TREE_CODE (t) == STRING_CST) 20217 properties = tree_cons (NULL_TREE, t, properties); 20218 else if (t != error_mark_node) 20219 { 20220 mark_exp_read (t); 20221 t = c_fully_fold (t, false, NULL); 20222 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)) 20223 || !tree_fits_shwi_p (t)) 20224 error_at (token->location, "property must be " 20225 "constant integer expression or string " 20226 "literal"); 20227 else 20228 properties = tree_cons (NULL_TREE, t, properties); 20229 } 20230 else 20231 return error_mark_node; 20232 20233 if (c_parser_next_token_is (parser, CPP_COMMA)) 20234 c_parser_consume_token (parser); 20235 else 20236 break; 20237 } 20238 while (1); 20239 break; 20240 case CTX_PROPERTY_ID: 20241 if (c_parser_next_token_is (parser, CPP_KEYWORD) 20242 || c_parser_next_token_is (parser, CPP_NAME)) 20243 { 20244 tree prop = c_parser_peek_token (parser)->value; 20245 c_parser_consume_token (parser); 20246 properties = tree_cons (prop, NULL_TREE, properties); 20247 } 20248 else 20249 { 20250 c_parser_error (parser, "expected identifier"); 20251 return error_mark_node; 20252 } 20253 break; 20254 case CTX_PROPERTY_NAME_LIST: 20255 do 20256 { 20257 tree prop = NULL_TREE, value = NULL_TREE; 20258 if (c_parser_next_token_is (parser, CPP_KEYWORD) 20259 || c_parser_next_token_is (parser, CPP_NAME)) 20260 { 20261 prop = c_parser_peek_token (parser)->value; 20262 c_parser_consume_token (parser); 20263 } 20264 else if (c_parser_next_token_is (parser, CPP_STRING)) 20265 value = c_parser_string_literal (parser, false, 20266 false).value; 20267 else 20268 { 20269 c_parser_error (parser, "expected identifier or " 20270 "string literal"); 20271 return error_mark_node; 20272 } 20273 20274 properties = tree_cons (prop, value, properties); 20275 20276 if (c_parser_next_token_is (parser, CPP_COMMA)) 20277 c_parser_consume_token (parser); 20278 else 20279 break; 20280 } 20281 while (1); 20282 break; 20283 case CTX_PROPERTY_EXPR: 20284 t = c_parser_expr_no_commas (parser, NULL).value; 20285 if (t != error_mark_node) 20286 { 20287 mark_exp_read (t); 20288 t = c_fully_fold (t, false, NULL); 20289 if (!INTEGRAL_TYPE_P (TREE_TYPE (t)) 20290 || !tree_fits_shwi_p (t)) 20291 error_at (token->location, "property must be " 20292 "constant integer expression"); 20293 else 20294 properties = tree_cons (NULL_TREE, t, properties); 20295 } 20296 else 20297 return error_mark_node; 20298 break; 20299 case CTX_PROPERTY_SIMD: 20300 if (parms == NULL_TREE) 20301 { 20302 error_at (token->location, "properties for %<simd%> " 20303 "selector may not be specified in " 20304 "%<metadirective%>"); 20305 return error_mark_node; 20306 } 20307 tree c; 20308 c = c_parser_omp_all_clauses (parser, 20309 OMP_DECLARE_SIMD_CLAUSE_MASK, 20310 "simd", true, 2); 20311 c = c_omp_declare_simd_clauses_to_numbers (parms 20312 == error_mark_node 20313 ? NULL_TREE : parms, 20314 c); 20315 properties = c; 20316 break; 20317 default: 20318 gcc_unreachable (); 20319 } 20320 20321 parens.skip_until_found_close (parser); 20322 properties = nreverse (properties); 20323 } 20324 else if (property_kind == CTX_PROPERTY_NAME_LIST 20325 || property_kind == CTX_PROPERTY_ID 20326 || property_kind == CTX_PROPERTY_EXPR) 20327 { 20328 c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"); 20329 return error_mark_node; 20330 } 20331 20332 ret = tree_cons (selector, properties, ret); 20333 20334 if (c_parser_next_token_is (parser, CPP_COMMA)) 20335 c_parser_consume_token (parser); 20336 else 20337 break; 20338 } 20339 while (1); 20340 20341 return nreverse (ret); 20342 } 20343 20344 /* OpenMP 5.0: 20345 20346 trait-set-selector[,trait-set-selector[,...]] 20347 20348 trait-set-selector: 20349 trait-set-selector-name = { trait-selector[, trait-selector[, ...]] } 20350 20351 trait-set-selector-name: 20352 constructor 20353 device 20354 implementation 20355 user */ 20356 20357 static tree 20358 c_parser_omp_context_selector_specification (c_parser *parser, tree parms) 20359 { 20360 tree ret = NULL_TREE; 20361 do 20362 { 20363 const char *setp = ""; 20364 if (c_parser_next_token_is (parser, CPP_NAME)) 20365 setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 20366 switch (setp[0]) 20367 { 20368 case 'c': 20369 if (strcmp (setp, "construct") == 0) 20370 setp = NULL; 20371 break; 20372 case 'd': 20373 if (strcmp (setp, "device") == 0) 20374 setp = NULL; 20375 break; 20376 case 'i': 20377 if (strcmp (setp, "implementation") == 0) 20378 setp = NULL; 20379 break; 20380 case 'u': 20381 if (strcmp (setp, "user") == 0) 20382 setp = NULL; 20383 break; 20384 default: 20385 break; 20386 } 20387 if (setp) 20388 { 20389 c_parser_error (parser, "expected %<construct%>, %<device%>, " 20390 "%<implementation%> or %<user%>"); 20391 return error_mark_node; 20392 } 20393 20394 tree set = c_parser_peek_token (parser)->value; 20395 c_parser_consume_token (parser); 20396 20397 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) 20398 return error_mark_node; 20399 20400 matching_braces braces; 20401 if (!braces.require_open (parser)) 20402 return error_mark_node; 20403 20404 tree selectors = c_parser_omp_context_selector (parser, set, parms); 20405 if (selectors == error_mark_node) 20406 ret = error_mark_node; 20407 else if (ret != error_mark_node) 20408 ret = tree_cons (set, selectors, ret); 20409 20410 braces.skip_until_found_close (parser); 20411 20412 if (c_parser_next_token_is (parser, CPP_COMMA)) 20413 c_parser_consume_token (parser); 20414 else 20415 break; 20416 } 20417 while (1); 20418 20419 if (ret == error_mark_node) 20420 return ret; 20421 return nreverse (ret); 20422 } 20423 20424 /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put 20425 that into "omp declare variant base" attribute. */ 20426 20427 static void 20428 c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms) 20429 { 20430 matching_parens parens; 20431 if (!parens.require_open (parser)) 20432 { 20433 fail: 20434 c_parser_skip_to_pragma_eol (parser, false); 20435 return; 20436 } 20437 20438 if (c_parser_next_token_is_not (parser, CPP_NAME) 20439 || c_parser_peek_token (parser)->id_kind != C_ID_ID) 20440 { 20441 c_parser_error (parser, "expected identifier"); 20442 goto fail; 20443 } 20444 20445 c_token *token = c_parser_peek_token (parser); 20446 tree variant = lookup_name (token->value); 20447 20448 if (variant == NULL_TREE) 20449 { 20450 undeclared_variable (token->location, token->value); 20451 variant = error_mark_node; 20452 } 20453 20454 c_parser_consume_token (parser); 20455 20456 parens.require_close (parser); 20457 20458 const char *clause = ""; 20459 location_t match_loc = c_parser_peek_token (parser)->location; 20460 if (c_parser_next_token_is (parser, CPP_NAME)) 20461 clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 20462 if (strcmp (clause, "match")) 20463 { 20464 c_parser_error (parser, "expected %<match%>"); 20465 goto fail; 20466 } 20467 20468 c_parser_consume_token (parser); 20469 20470 if (!parens.require_open (parser)) 20471 goto fail; 20472 20473 if (parms == NULL_TREE) 20474 parms = error_mark_node; 20475 20476 tree ctx = c_parser_omp_context_selector_specification (parser, parms); 20477 if (ctx == error_mark_node) 20478 goto fail; 20479 ctx = c_omp_check_context_selector (match_loc, ctx); 20480 if (ctx != error_mark_node && variant != error_mark_node) 20481 { 20482 if (TREE_CODE (variant) != FUNCTION_DECL) 20483 { 20484 error_at (token->location, "variant %qD is not a function", variant); 20485 variant = error_mark_node; 20486 } 20487 else if (omp_get_context_selector (ctx, "construct", "simd") == NULL_TREE 20488 && !comptypes (TREE_TYPE (fndecl), TREE_TYPE (variant))) 20489 { 20490 error_at (token->location, "variant %qD and base %qD have " 20491 "incompatible types", variant, fndecl); 20492 variant = error_mark_node; 20493 } 20494 else if (fndecl_built_in_p (variant) 20495 && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)), 20496 "__builtin_", strlen ("__builtin_")) == 0 20497 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)), 20498 "__sync_", strlen ("__sync_")) == 0 20499 || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)), 20500 "__atomic_", strlen ("__atomic_")) == 0)) 20501 { 20502 error_at (token->location, "variant %qD is a built-in", variant); 20503 variant = error_mark_node; 20504 } 20505 if (variant != error_mark_node) 20506 { 20507 C_DECL_USED (variant) = 1; 20508 tree construct = omp_get_context_selector (ctx, "construct", NULL); 20509 c_omp_mark_declare_variant (match_loc, variant, construct); 20510 if (omp_context_selector_matches (ctx)) 20511 { 20512 tree attr 20513 = tree_cons (get_identifier ("omp declare variant base"), 20514 build_tree_list (variant, ctx), 20515 DECL_ATTRIBUTES (fndecl)); 20516 DECL_ATTRIBUTES (fndecl) = attr; 20517 } 20518 } 20519 } 20520 20521 parens.require_close (parser); 20522 c_parser_skip_to_pragma_eol (parser); 20523 } 20524 20525 /* Finalize #pragma omp declare simd or #pragma omp declare variant 20526 clauses after FNDECL has been parsed, and put that into "omp declare simd" 20527 or "omp declare variant base" attribute. */ 20528 20529 static void 20530 c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms, 20531 vec<c_token> clauses) 20532 { 20533 /* Normally first token is CPP_NAME "simd" or "variant". CPP_EOF there 20534 indicates error has been reported and CPP_PRAGMA that 20535 c_finish_omp_declare_simd has already processed the tokens. */ 20536 if (clauses.exists () && clauses[0].type == CPP_EOF) 20537 return; 20538 const char *kind = "simd"; 20539 if (clauses.exists () 20540 && (clauses[0].type == CPP_NAME || clauses[0].type == CPP_PRAGMA)) 20541 kind = IDENTIFIER_POINTER (clauses[0].value); 20542 gcc_assert (strcmp (kind, "simd") == 0 || strcmp (kind, "variant") == 0); 20543 if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL) 20544 { 20545 error ("%<#pragma omp declare %s%> not immediately followed by " 20546 "a function declaration or definition", kind); 20547 clauses[0].type = CPP_EOF; 20548 return; 20549 } 20550 if (clauses.exists () && clauses[0].type != CPP_NAME) 20551 { 20552 error_at (DECL_SOURCE_LOCATION (fndecl), 20553 "%<#pragma omp declare %s%> not immediately followed by " 20554 "a single function declaration or definition", kind); 20555 clauses[0].type = CPP_EOF; 20556 return; 20557 } 20558 20559 if (parms == NULL_TREE) 20560 parms = DECL_ARGUMENTS (fndecl); 20561 20562 unsigned int tokens_avail = parser->tokens_avail; 20563 gcc_assert (parser->tokens == &parser->tokens_buf[0]); 20564 20565 parser->tokens = clauses.address (); 20566 parser->tokens_avail = clauses.length (); 20567 20568 /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end. */ 20569 while (parser->tokens_avail > 3) 20570 { 20571 c_token *token = c_parser_peek_token (parser); 20572 gcc_assert (token->type == CPP_NAME 20573 && strcmp (IDENTIFIER_POINTER (token->value), kind) == 0); 20574 c_parser_consume_token (parser); 20575 parser->in_pragma = true; 20576 20577 if (strcmp (kind, "simd") == 0) 20578 { 20579 tree c; 20580 c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK, 20581 "#pragma omp declare simd"); 20582 c = c_omp_declare_simd_clauses_to_numbers (parms, c); 20583 if (c != NULL_TREE) 20584 c = tree_cons (NULL_TREE, c, NULL_TREE); 20585 c = build_tree_list (get_identifier ("omp declare simd"), c); 20586 TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl); 20587 DECL_ATTRIBUTES (fndecl) = c; 20588 } 20589 else 20590 { 20591 gcc_assert (strcmp (kind, "variant") == 0); 20592 c_finish_omp_declare_variant (parser, fndecl, parms); 20593 } 20594 } 20595 20596 parser->tokens = &parser->tokens_buf[0]; 20597 parser->tokens_avail = tokens_avail; 20598 if (clauses.exists ()) 20599 clauses[0].type = CPP_PRAGMA; 20600 } 20601 20602 20603 /* OpenMP 4.0: 20604 # pragma omp declare target new-line 20605 declarations and definitions 20606 # pragma omp end declare target new-line 20607 20608 OpenMP 4.5: 20609 # pragma omp declare target ( extended-list ) new-line 20610 20611 # pragma omp declare target declare-target-clauses[seq] new-line */ 20612 20613 #define OMP_DECLARE_TARGET_CLAUSE_MASK \ 20614 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \ 20615 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \ 20616 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE)) 20617 20618 static void 20619 c_parser_omp_declare_target (c_parser *parser) 20620 { 20621 tree clauses = NULL_TREE; 20622 int device_type = 0; 20623 bool only_device_type = true; 20624 if (c_parser_next_token_is (parser, CPP_NAME)) 20625 clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK, 20626 "#pragma omp declare target"); 20627 else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) 20628 { 20629 clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE, 20630 clauses); 20631 clauses = c_finish_omp_clauses (clauses, C_ORT_OMP); 20632 c_parser_skip_to_pragma_eol (parser); 20633 } 20634 else 20635 { 20636 c_parser_skip_to_pragma_eol (parser); 20637 current_omp_declare_target_attribute++; 20638 return; 20639 } 20640 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c)) 20641 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE) 20642 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c); 20643 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c)) 20644 { 20645 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE) 20646 continue; 20647 tree t = OMP_CLAUSE_DECL (c), id; 20648 tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t)); 20649 tree at2 = lookup_attribute ("omp declare target link", 20650 DECL_ATTRIBUTES (t)); 20651 only_device_type = false; 20652 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK) 20653 { 20654 id = get_identifier ("omp declare target link"); 20655 std::swap (at1, at2); 20656 } 20657 else 20658 id = get_identifier ("omp declare target"); 20659 if (at2) 20660 { 20661 error_at (OMP_CLAUSE_LOCATION (c), 20662 "%qD specified both in declare target %<link%> and %<to%>" 20663 " clauses", t); 20664 continue; 20665 } 20666 if (!at1) 20667 { 20668 DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t)); 20669 if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t)) 20670 continue; 20671 20672 symtab_node *node = symtab_node::get (t); 20673 if (node != NULL) 20674 { 20675 node->offloadable = 1; 20676 if (ENABLE_OFFLOADING) 20677 { 20678 g->have_offload = true; 20679 if (is_a <varpool_node *> (node)) 20680 vec_safe_push (offload_vars, t); 20681 } 20682 } 20683 } 20684 if (TREE_CODE (t) != FUNCTION_DECL) 20685 continue; 20686 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0) 20687 { 20688 tree at3 = lookup_attribute ("omp declare target host", 20689 DECL_ATTRIBUTES (t)); 20690 if (at3 == NULL_TREE) 20691 { 20692 id = get_identifier ("omp declare target host"); 20693 DECL_ATTRIBUTES (t) 20694 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t)); 20695 } 20696 } 20697 if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0) 20698 { 20699 tree at3 = lookup_attribute ("omp declare target nohost", 20700 DECL_ATTRIBUTES (t)); 20701 if (at3 == NULL_TREE) 20702 { 20703 id = get_identifier ("omp declare target nohost"); 20704 DECL_ATTRIBUTES (t) 20705 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t)); 20706 } 20707 } 20708 } 20709 if (device_type && only_device_type) 20710 warning_at (OMP_CLAUSE_LOCATION (clauses), 0, 20711 "directive with only %<device_type%> clauses ignored"); 20712 } 20713 20714 static void 20715 c_parser_omp_end_declare_target (c_parser *parser) 20716 { 20717 location_t loc = c_parser_peek_token (parser)->location; 20718 c_parser_consume_pragma (parser); 20719 if (c_parser_next_token_is (parser, CPP_NAME) 20720 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value), 20721 "declare") == 0) 20722 { 20723 c_parser_consume_token (parser); 20724 if (c_parser_next_token_is (parser, CPP_NAME) 20725 && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value), 20726 "target") == 0) 20727 c_parser_consume_token (parser); 20728 else 20729 { 20730 c_parser_error (parser, "expected %<target%>"); 20731 c_parser_skip_to_pragma_eol (parser); 20732 return; 20733 } 20734 } 20735 else 20736 { 20737 c_parser_error (parser, "expected %<declare%>"); 20738 c_parser_skip_to_pragma_eol (parser); 20739 return; 20740 } 20741 c_parser_skip_to_pragma_eol (parser); 20742 if (!current_omp_declare_target_attribute) 20743 error_at (loc, "%<#pragma omp end declare target%> without corresponding " 20744 "%<#pragma omp declare target%>"); 20745 else 20746 current_omp_declare_target_attribute--; 20747 } 20748 20749 20750 /* OpenMP 4.0 20751 #pragma omp declare reduction (reduction-id : typename-list : expression) \ 20752 initializer-clause[opt] new-line 20753 20754 initializer-clause: 20755 initializer (omp_priv = initializer) 20756 initializer (function-name (argument-list)) */ 20757 20758 static void 20759 c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context) 20760 { 20761 unsigned int tokens_avail = 0, i; 20762 vec<tree> types = vNULL; 20763 vec<c_token> clauses = vNULL; 20764 enum tree_code reduc_code = ERROR_MARK; 20765 tree reduc_id = NULL_TREE; 20766 tree type; 20767 location_t rloc = c_parser_peek_token (parser)->location; 20768 20769 if (context == pragma_struct || context == pragma_param) 20770 { 20771 error ("%<#pragma omp declare reduction%> not at file or block scope"); 20772 goto fail; 20773 } 20774 20775 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 20776 goto fail; 20777 20778 switch (c_parser_peek_token (parser)->type) 20779 { 20780 case CPP_PLUS: 20781 reduc_code = PLUS_EXPR; 20782 break; 20783 case CPP_MULT: 20784 reduc_code = MULT_EXPR; 20785 break; 20786 case CPP_MINUS: 20787 reduc_code = MINUS_EXPR; 20788 break; 20789 case CPP_AND: 20790 reduc_code = BIT_AND_EXPR; 20791 break; 20792 case CPP_XOR: 20793 reduc_code = BIT_XOR_EXPR; 20794 break; 20795 case CPP_OR: 20796 reduc_code = BIT_IOR_EXPR; 20797 break; 20798 case CPP_AND_AND: 20799 reduc_code = TRUTH_ANDIF_EXPR; 20800 break; 20801 case CPP_OR_OR: 20802 reduc_code = TRUTH_ORIF_EXPR; 20803 break; 20804 case CPP_NAME: 20805 const char *p; 20806 p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 20807 if (strcmp (p, "min") == 0) 20808 { 20809 reduc_code = MIN_EXPR; 20810 break; 20811 } 20812 if (strcmp (p, "max") == 0) 20813 { 20814 reduc_code = MAX_EXPR; 20815 break; 20816 } 20817 reduc_id = c_parser_peek_token (parser)->value; 20818 break; 20819 default: 20820 c_parser_error (parser, 20821 "expected %<+%>, %<*%>, %<-%>, %<&%>, " 20822 "%<^%>, %<|%>, %<&&%>, %<||%> or identifier"); 20823 goto fail; 20824 } 20825 20826 tree orig_reduc_id, reduc_decl; 20827 orig_reduc_id = reduc_id; 20828 reduc_id = c_omp_reduction_id (reduc_code, reduc_id); 20829 reduc_decl = c_omp_reduction_decl (reduc_id); 20830 c_parser_consume_token (parser); 20831 20832 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")) 20833 goto fail; 20834 20835 while (true) 20836 { 20837 location_t loc = c_parser_peek_token (parser)->location; 20838 struct c_type_name *ctype = c_parser_type_name (parser); 20839 if (ctype != NULL) 20840 { 20841 type = groktypename (ctype, NULL, NULL); 20842 if (type == error_mark_node) 20843 ; 20844 else if ((INTEGRAL_TYPE_P (type) 20845 || TREE_CODE (type) == REAL_TYPE 20846 || TREE_CODE (type) == COMPLEX_TYPE) 20847 && orig_reduc_id == NULL_TREE) 20848 error_at (loc, "predeclared arithmetic type in " 20849 "%<#pragma omp declare reduction%>"); 20850 else if (TREE_CODE (type) == FUNCTION_TYPE 20851 || TREE_CODE (type) == ARRAY_TYPE) 20852 error_at (loc, "function or array type in " 20853 "%<#pragma omp declare reduction%>"); 20854 else if (TYPE_ATOMIC (type)) 20855 error_at (loc, "%<_Atomic%> qualified type in " 20856 "%<#pragma omp declare reduction%>"); 20857 else if (TYPE_QUALS_NO_ADDR_SPACE (type)) 20858 error_at (loc, "const, volatile or restrict qualified type in " 20859 "%<#pragma omp declare reduction%>"); 20860 else 20861 { 20862 tree t; 20863 for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t)) 20864 if (comptypes (TREE_PURPOSE (t), type)) 20865 { 20866 error_at (loc, "redeclaration of %qs " 20867 "%<#pragma omp declare reduction%> for " 20868 "type %qT", 20869 IDENTIFIER_POINTER (reduc_id) 20870 + sizeof ("omp declare reduction ") - 1, 20871 type); 20872 location_t ploc 20873 = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t), 20874 0)); 20875 error_at (ploc, "previous %<#pragma omp declare " 20876 "reduction%>"); 20877 break; 20878 } 20879 if (t == NULL_TREE) 20880 types.safe_push (type); 20881 } 20882 if (c_parser_next_token_is (parser, CPP_COMMA)) 20883 c_parser_consume_token (parser); 20884 else 20885 break; 20886 } 20887 else 20888 break; 20889 } 20890 20891 if (!c_parser_require (parser, CPP_COLON, "expected %<:%>") 20892 || types.is_empty ()) 20893 { 20894 fail: 20895 clauses.release (); 20896 types.release (); 20897 while (true) 20898 { 20899 c_token *token = c_parser_peek_token (parser); 20900 if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL) 20901 break; 20902 c_parser_consume_token (parser); 20903 } 20904 c_parser_skip_to_pragma_eol (parser); 20905 return; 20906 } 20907 20908 if (types.length () > 1) 20909 { 20910 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 20911 { 20912 c_token *token = c_parser_peek_token (parser); 20913 if (token->type == CPP_EOF) 20914 goto fail; 20915 clauses.safe_push (*token); 20916 c_parser_consume_token (parser); 20917 } 20918 clauses.safe_push (*c_parser_peek_token (parser)); 20919 c_parser_skip_to_pragma_eol (parser); 20920 20921 /* Make sure nothing tries to read past the end of the tokens. */ 20922 c_token eof_token; 20923 memset (&eof_token, 0, sizeof (eof_token)); 20924 eof_token.type = CPP_EOF; 20925 clauses.safe_push (eof_token); 20926 clauses.safe_push (eof_token); 20927 } 20928 20929 int errs = errorcount; 20930 FOR_EACH_VEC_ELT (types, i, type) 20931 { 20932 tokens_avail = parser->tokens_avail; 20933 gcc_assert (parser->tokens == &parser->tokens_buf[0]); 20934 if (!clauses.is_empty ()) 20935 { 20936 parser->tokens = clauses.address (); 20937 parser->tokens_avail = clauses.length (); 20938 parser->in_pragma = true; 20939 } 20940 20941 bool nested = current_function_decl != NULL_TREE; 20942 if (nested) 20943 c_push_function_context (); 20944 tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL, 20945 reduc_id, default_function_type); 20946 current_function_decl = fndecl; 20947 allocate_struct_function (fndecl, true); 20948 push_scope (); 20949 tree stmt = push_stmt_list (); 20950 /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't 20951 warn about these. */ 20952 tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL, 20953 get_identifier ("omp_out"), type); 20954 DECL_ARTIFICIAL (omp_out) = 1; 20955 DECL_CONTEXT (omp_out) = fndecl; 20956 pushdecl (omp_out); 20957 tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL, 20958 get_identifier ("omp_in"), type); 20959 DECL_ARTIFICIAL (omp_in) = 1; 20960 DECL_CONTEXT (omp_in) = fndecl; 20961 pushdecl (omp_in); 20962 struct c_expr combiner = c_parser_expression (parser); 20963 struct c_expr initializer; 20964 tree omp_priv = NULL_TREE, omp_orig = NULL_TREE; 20965 bool bad = false; 20966 initializer.set_error (); 20967 if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) 20968 bad = true; 20969 else if (c_parser_next_token_is (parser, CPP_NAME) 20970 && strcmp (IDENTIFIER_POINTER 20971 (c_parser_peek_token (parser)->value), 20972 "initializer") == 0) 20973 { 20974 c_parser_consume_token (parser); 20975 pop_scope (); 20976 push_scope (); 20977 omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL, 20978 get_identifier ("omp_priv"), type); 20979 DECL_ARTIFICIAL (omp_priv) = 1; 20980 DECL_INITIAL (omp_priv) = error_mark_node; 20981 DECL_CONTEXT (omp_priv) = fndecl; 20982 pushdecl (omp_priv); 20983 omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL, 20984 get_identifier ("omp_orig"), type); 20985 DECL_ARTIFICIAL (omp_orig) = 1; 20986 DECL_CONTEXT (omp_orig) = fndecl; 20987 pushdecl (omp_orig); 20988 if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) 20989 bad = true; 20990 else if (!c_parser_next_token_is (parser, CPP_NAME)) 20991 { 20992 c_parser_error (parser, "expected %<omp_priv%> or " 20993 "function-name"); 20994 bad = true; 20995 } 20996 else if (strcmp (IDENTIFIER_POINTER 20997 (c_parser_peek_token (parser)->value), 20998 "omp_priv") != 0) 20999 { 21000 if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN 21001 || c_parser_peek_token (parser)->id_kind != C_ID_ID) 21002 { 21003 c_parser_error (parser, "expected function-name %<(%>"); 21004 bad = true; 21005 } 21006 else 21007 initializer = c_parser_postfix_expression (parser); 21008 if (initializer.value 21009 && TREE_CODE (initializer.value) == CALL_EXPR) 21010 { 21011 int j; 21012 tree c = initializer.value; 21013 for (j = 0; j < call_expr_nargs (c); j++) 21014 { 21015 tree a = CALL_EXPR_ARG (c, j); 21016 STRIP_NOPS (a); 21017 if (TREE_CODE (a) == ADDR_EXPR 21018 && TREE_OPERAND (a, 0) == omp_priv) 21019 break; 21020 } 21021 if (j == call_expr_nargs (c)) 21022 error ("one of the initializer call arguments should be " 21023 "%<&omp_priv%>"); 21024 } 21025 } 21026 else 21027 { 21028 c_parser_consume_token (parser); 21029 if (!c_parser_require (parser, CPP_EQ, "expected %<=%>")) 21030 bad = true; 21031 else 21032 { 21033 tree st = push_stmt_list (); 21034 location_t loc = c_parser_peek_token (parser)->location; 21035 rich_location richloc (line_table, loc); 21036 start_init (omp_priv, NULL_TREE, 0, &richloc); 21037 struct c_expr init = c_parser_initializer (parser); 21038 finish_init (); 21039 finish_decl (omp_priv, loc, init.value, 21040 init.original_type, NULL_TREE); 21041 pop_stmt_list (st); 21042 } 21043 } 21044 if (!bad 21045 && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>")) 21046 bad = true; 21047 } 21048 21049 if (!bad) 21050 { 21051 c_parser_skip_to_pragma_eol (parser); 21052 21053 tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3), 21054 DECL_INITIAL (reduc_decl)); 21055 DECL_INITIAL (reduc_decl) = t; 21056 DECL_SOURCE_LOCATION (omp_out) = rloc; 21057 TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out; 21058 TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in; 21059 TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value; 21060 walk_tree (&combiner.value, c_check_omp_declare_reduction_r, 21061 &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL); 21062 if (omp_priv) 21063 { 21064 DECL_SOURCE_LOCATION (omp_priv) = rloc; 21065 TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv; 21066 TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig; 21067 TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value; 21068 walk_tree (&initializer.value, c_check_omp_declare_reduction_r, 21069 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL); 21070 walk_tree (&DECL_INITIAL (omp_priv), 21071 c_check_omp_declare_reduction_r, 21072 &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL); 21073 } 21074 } 21075 21076 pop_stmt_list (stmt); 21077 pop_scope (); 21078 if (cfun->language != NULL) 21079 { 21080 ggc_free (cfun->language); 21081 cfun->language = NULL; 21082 } 21083 set_cfun (NULL); 21084 current_function_decl = NULL_TREE; 21085 if (nested) 21086 c_pop_function_context (); 21087 21088 if (!clauses.is_empty ()) 21089 { 21090 parser->tokens = &parser->tokens_buf[0]; 21091 parser->tokens_avail = tokens_avail; 21092 } 21093 if (bad) 21094 goto fail; 21095 if (errs != errorcount) 21096 break; 21097 } 21098 21099 clauses.release (); 21100 types.release (); 21101 } 21102 21103 21104 /* OpenMP 4.0 21105 #pragma omp declare simd declare-simd-clauses[optseq] new-line 21106 #pragma omp declare reduction (reduction-id : typename-list : expression) \ 21107 initializer-clause[opt] new-line 21108 #pragma omp declare target new-line 21109 21110 OpenMP 5.0 21111 #pragma omp declare variant (identifier) match (context-selector) */ 21112 21113 static void 21114 c_parser_omp_declare (c_parser *parser, enum pragma_context context) 21115 { 21116 c_parser_consume_pragma (parser); 21117 if (c_parser_next_token_is (parser, CPP_NAME)) 21118 { 21119 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 21120 if (strcmp (p, "simd") == 0) 21121 { 21122 /* c_parser_consume_token (parser); done in 21123 c_parser_omp_declare_simd. */ 21124 c_parser_omp_declare_simd (parser, context); 21125 return; 21126 } 21127 if (strcmp (p, "reduction") == 0) 21128 { 21129 c_parser_consume_token (parser); 21130 c_parser_omp_declare_reduction (parser, context); 21131 return; 21132 } 21133 if (!flag_openmp) /* flag_openmp_simd */ 21134 { 21135 c_parser_skip_to_pragma_eol (parser, false); 21136 return; 21137 } 21138 if (strcmp (p, "target") == 0) 21139 { 21140 c_parser_consume_token (parser); 21141 c_parser_omp_declare_target (parser); 21142 return; 21143 } 21144 if (strcmp (p, "variant") == 0) 21145 { 21146 /* c_parser_consume_token (parser); done in 21147 c_parser_omp_declare_simd. */ 21148 c_parser_omp_declare_simd (parser, context); 21149 return; 21150 } 21151 } 21152 21153 c_parser_error (parser, "expected %<simd%>, %<reduction%>, " 21154 "%<target%> or %<variant%>"); 21155 c_parser_skip_to_pragma_eol (parser); 21156 } 21157 21158 /* OpenMP 5.0 21159 #pragma omp requires clauses[optseq] new-line */ 21160 21161 static void 21162 c_parser_omp_requires (c_parser *parser) 21163 { 21164 bool first = true; 21165 enum omp_requires new_req = (enum omp_requires) 0; 21166 21167 c_parser_consume_pragma (parser); 21168 21169 location_t loc = c_parser_peek_token (parser)->location; 21170 while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL)) 21171 { 21172 if (!first && c_parser_next_token_is (parser, CPP_COMMA)) 21173 c_parser_consume_token (parser); 21174 21175 first = false; 21176 21177 if (c_parser_next_token_is (parser, CPP_NAME)) 21178 { 21179 const char *p 21180 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 21181 location_t cloc = c_parser_peek_token (parser)->location; 21182 enum omp_requires this_req = (enum omp_requires) 0; 21183 21184 if (!strcmp (p, "unified_address")) 21185 this_req = OMP_REQUIRES_UNIFIED_ADDRESS; 21186 else if (!strcmp (p, "unified_shared_memory")) 21187 this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY; 21188 else if (!strcmp (p, "dynamic_allocators")) 21189 this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS; 21190 else if (!strcmp (p, "reverse_offload")) 21191 this_req = OMP_REQUIRES_REVERSE_OFFLOAD; 21192 else if (!strcmp (p, "atomic_default_mem_order")) 21193 { 21194 c_parser_consume_token (parser); 21195 21196 matching_parens parens; 21197 if (parens.require_open (parser)) 21198 { 21199 if (c_parser_next_token_is (parser, CPP_NAME)) 21200 { 21201 tree v = c_parser_peek_token (parser)->value; 21202 p = IDENTIFIER_POINTER (v); 21203 21204 if (!strcmp (p, "seq_cst")) 21205 this_req 21206 = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST; 21207 else if (!strcmp (p, "relaxed")) 21208 this_req 21209 = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED; 21210 else if (!strcmp (p, "acq_rel")) 21211 this_req 21212 = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL; 21213 } 21214 if (this_req == 0) 21215 { 21216 error_at (c_parser_peek_token (parser)->location, 21217 "expected %<seq_cst%>, %<relaxed%> or " 21218 "%<acq_rel%>"); 21219 if (c_parser_peek_2nd_token (parser)->type 21220 == CPP_CLOSE_PAREN) 21221 c_parser_consume_token (parser); 21222 } 21223 else 21224 c_parser_consume_token (parser); 21225 21226 parens.skip_until_found_close (parser); 21227 if (this_req == 0) 21228 { 21229 c_parser_skip_to_pragma_eol (parser, false); 21230 return; 21231 } 21232 } 21233 p = NULL; 21234 } 21235 else 21236 { 21237 error_at (cloc, "expected %<unified_address%>, " 21238 "%<unified_shared_memory%>, " 21239 "%<dynamic_allocators%>, " 21240 "%<reverse_offload%> " 21241 "or %<atomic_default_mem_order%> clause"); 21242 c_parser_skip_to_pragma_eol (parser, false); 21243 return; 21244 } 21245 if (p) 21246 sorry_at (cloc, "%qs clause on %<requires%> directive not " 21247 "supported yet", p); 21248 if (p) 21249 c_parser_consume_token (parser); 21250 if (this_req) 21251 { 21252 if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0) 21253 { 21254 if ((this_req & new_req) != 0) 21255 error_at (cloc, "too many %qs clauses", p); 21256 if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS 21257 && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0) 21258 error_at (cloc, "%qs clause used lexically after first " 21259 "target construct or offloading API", p); 21260 } 21261 else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0) 21262 { 21263 error_at (cloc, "too many %qs clauses", 21264 "atomic_default_mem_order"); 21265 this_req = (enum omp_requires) 0; 21266 } 21267 else if ((omp_requires_mask 21268 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0) 21269 { 21270 error_at (cloc, "more than one %<atomic_default_mem_order%>" 21271 " clause in a single compilation unit"); 21272 this_req 21273 = (enum omp_requires) 21274 (omp_requires_mask 21275 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER); 21276 } 21277 else if ((omp_requires_mask 21278 & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0) 21279 error_at (cloc, "%<atomic_default_mem_order%> clause used " 21280 "lexically after first %<atomic%> construct " 21281 "without memory order clause"); 21282 new_req = (enum omp_requires) (new_req | this_req); 21283 omp_requires_mask 21284 = (enum omp_requires) (omp_requires_mask | this_req); 21285 continue; 21286 } 21287 } 21288 break; 21289 } 21290 c_parser_skip_to_pragma_eol (parser); 21291 21292 if (new_req == 0) 21293 error_at (loc, "%<pragma omp requires%> requires at least one clause"); 21294 } 21295 21296 /* Helper function for c_parser_omp_taskloop. 21297 Disallow zero sized or potentially zero sized task reductions. */ 21298 21299 static tree 21300 c_finish_taskloop_clauses (tree clauses) 21301 { 21302 tree *pc = &clauses; 21303 for (tree c = clauses; c; c = *pc) 21304 { 21305 bool remove = false; 21306 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION) 21307 { 21308 tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c))); 21309 if (integer_zerop (TYPE_SIZE_UNIT (type))) 21310 { 21311 error_at (OMP_CLAUSE_LOCATION (c), 21312 "zero sized type %qT in %<reduction%> clause", type); 21313 remove = true; 21314 } 21315 else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST) 21316 { 21317 error_at (OMP_CLAUSE_LOCATION (c), 21318 "variable sized type %qT in %<reduction%> clause", 21319 type); 21320 remove = true; 21321 } 21322 } 21323 if (remove) 21324 *pc = OMP_CLAUSE_CHAIN (c); 21325 else 21326 pc = &OMP_CLAUSE_CHAIN (c); 21327 } 21328 return clauses; 21329 } 21330 21331 /* OpenMP 4.5: 21332 #pragma omp taskloop taskloop-clause[optseq] new-line 21333 for-loop 21334 21335 #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line 21336 for-loop */ 21337 21338 #define OMP_TASKLOOP_CLAUSE_MASK \ 21339 ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \ 21340 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE) \ 21341 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE) \ 21342 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE) \ 21343 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT) \ 21344 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE) \ 21345 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS) \ 21346 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE) \ 21347 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \ 21348 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \ 21349 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL) \ 21350 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE) \ 21351 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP) \ 21352 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY) \ 21353 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION) \ 21354 | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION)) 21355 21356 static tree 21357 c_parser_omp_taskloop (location_t loc, c_parser *parser, 21358 char *p_name, omp_clause_mask mask, tree *cclauses, 21359 bool *if_p) 21360 { 21361 tree clauses, block, ret; 21362 21363 strcat (p_name, " taskloop"); 21364 mask |= OMP_TASKLOOP_CLAUSE_MASK; 21365 /* #pragma omp parallel master taskloop{, simd} disallow in_reduction 21366 clause. */ 21367 if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0) 21368 mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION); 21369 21370 if (c_parser_next_token_is (parser, CPP_NAME)) 21371 { 21372 const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); 21373 21374 if (strcmp (p, "simd") == 0) 21375 { 21376 tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT]; 21377 if (cclauses == NULL) 21378 cclauses = cclauses_buf; 21379 c_parser_consume_token (parser); 21380 if (!flag_openmp) /* flag_openmp_simd */ 21381 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses, 21382 if_p); 21383 block = c_begin_compound_stmt (true); 21384 ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p); 21385 block = c_end_compound_stmt (loc, block, true); 21386 if (ret == NULL) 21387 return ret; 21388 ret = make_node (OMP_TASKLOOP); 21389 TREE_TYPE (ret) = void_type_node; 21390 OMP_FOR_BODY (ret) = block; 21391 OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP]; 21392 OMP_FOR_CLAUSES (ret) 21393 = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret)); 21394 SET_EXPR_LOCATION (ret, loc); 21395 add_stmt (ret); 21396 return ret; 21397 } 21398 } 21399 if (!flag_openmp) /* flag_openmp_simd */ 21400 { 21401 c_parser_skip_to_pragma_eol (parser, false); 21402 return NULL_TREE; 21403 } 21404 21405 clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL); 21406 if (cclauses) 21407 { 21408 omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses); 21409 clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP]; 21410 } 21411 21412 clauses = c_finish_taskloop_clauses (clauses); 21413 block = c_begin_compound_stmt (true); 21414 ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p); 21415 block = c_end_compound_stmt (loc, block, true); 21416 add_stmt (block); 21417 21418 return ret; 21419 } 21420 21421 /* Main entry point to parsing most OpenMP pragmas. */ 21422 21423 static void 21424 c_parser_omp_construct (c_parser *parser, bool *if_p) 21425 { 21426 enum pragma_kind p_kind; 21427 location_t loc; 21428 tree stmt; 21429 char p_name[sizeof "#pragma omp teams distribute parallel for simd"]; 21430 omp_clause_mask mask (0); 21431 21432 loc = c_parser_peek_token (parser)->location; 21433 p_kind = c_parser_peek_token (parser)->pragma_kind; 21434 c_parser_consume_pragma (parser); 21435 21436 switch (p_kind) 21437 { 21438 case PRAGMA_OACC_ATOMIC: 21439 c_parser_omp_atomic (loc, parser); 21440 return; 21441 case PRAGMA_OACC_CACHE: 21442 strcpy (p_name, "#pragma acc"); 21443 stmt = c_parser_oacc_cache (loc, parser); 21444 break; 21445 case PRAGMA_OACC_DATA: 21446 stmt = c_parser_oacc_data (loc, parser, if_p); 21447 break; 21448 case PRAGMA_OACC_HOST_DATA: 21449 stmt = c_parser_oacc_host_data (loc, parser, if_p); 21450 break; 21451 case PRAGMA_OACC_KERNELS: 21452 case PRAGMA_OACC_PARALLEL: 21453 case PRAGMA_OACC_SERIAL: 21454 strcpy (p_name, "#pragma acc"); 21455 stmt = c_parser_oacc_compute (loc, parser, p_kind, p_name, if_p); 21456 break; 21457 case PRAGMA_OACC_LOOP: 21458 strcpy (p_name, "#pragma acc"); 21459 stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p); 21460 break; 21461 case PRAGMA_OACC_WAIT: 21462 strcpy (p_name, "#pragma wait"); 21463 stmt = c_parser_oacc_wait (loc, parser, p_name); 21464 break; 21465 case PRAGMA_OMP_ATOMIC: 21466 c_parser_omp_atomic (loc, parser); 21467 return; 21468 case PRAGMA_OMP_CRITICAL: 21469 stmt = c_parser_omp_critical (loc, parser, if_p); 21470 break; 21471 case PRAGMA_OMP_DISTRIBUTE: 21472 strcpy (p_name, "#pragma omp"); 21473 stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p); 21474 break; 21475 case PRAGMA_OMP_FOR: 21476 strcpy (p_name, "#pragma omp"); 21477 stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p); 21478 break; 21479 case PRAGMA_OMP_LOOP: 21480 strcpy (p_name, "#pragma omp"); 21481 stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p); 21482 break; 21483 case PRAGMA_OMP_MASTER: 21484 strcpy (p_name, "#pragma omp"); 21485 stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p); 21486 break; 21487 case PRAGMA_OMP_PARALLEL: 21488 strcpy (p_name, "#pragma omp"); 21489 stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p); 21490 break; 21491 case PRAGMA_OMP_SECTIONS: 21492 strcpy (p_name, "#pragma omp"); 21493 stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL); 21494 break; 21495 case PRAGMA_OMP_SIMD: 21496 strcpy (p_name, "#pragma omp"); 21497 stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p); 21498 break; 21499 case PRAGMA_OMP_SINGLE: 21500 stmt = c_parser_omp_single (loc, parser, if_p); 21501 break; 21502 case PRAGMA_OMP_TASK: 21503 stmt = c_parser_omp_task (loc, parser, if_p); 21504 break; 21505 case PRAGMA_OMP_TASKGROUP: 21506 stmt = c_parser_omp_taskgroup (loc, parser, if_p); 21507 break; 21508 case PRAGMA_OMP_TASKLOOP: 21509 strcpy (p_name, "#pragma omp"); 21510 stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p); 21511 break; 21512 case PRAGMA_OMP_TEAMS: 21513 strcpy (p_name, "#pragma omp"); 21514 stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p); 21515 break; 21516 default: 21517 gcc_unreachable (); 21518 } 21519 21520 if (stmt) 21521 gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION); 21522 } 21523 21524 21525 /* OpenMP 2.5: 21526 # pragma omp threadprivate (variable-list) */ 21527 21528 static void 21529 c_parser_omp_threadprivate (c_parser *parser) 21530 { 21531 tree vars, t; 21532 location_t loc; 21533 21534 c_parser_consume_pragma (parser); 21535 loc = c_parser_peek_token (parser)->location; 21536 vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL); 21537 21538 /* Mark every variable in VARS to be assigned thread local storage. */ 21539 for (t = vars; t; t = TREE_CHAIN (t)) 21540 { 21541 tree v = TREE_PURPOSE (t); 21542 21543 /* FIXME diagnostics: Ideally we should keep individual 21544 locations for all the variables in the var list to make the 21545 following errors more precise. Perhaps 21546 c_parser_omp_var_list_parens() should construct a list of 21547 locations to go along with the var list. */ 21548 21549 /* If V had already been marked threadprivate, it doesn't matter 21550 whether it had been used prior to this point. */ 21551 if (!VAR_P (v)) 21552 error_at (loc, "%qD is not a variable", v); 21553 else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v)) 21554 error_at (loc, "%qE declared %<threadprivate%> after first use", v); 21555 else if (! is_global_var (v)) 21556 error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v); 21557 else if (TREE_TYPE (v) == error_mark_node) 21558 ; 21559 else if (! COMPLETE_TYPE_P (TREE_TYPE (v))) 21560 error_at (loc, "%<threadprivate%> %qE has incomplete type", v); 21561 else 21562 { 21563 if (! DECL_THREAD_LOCAL_P (v)) 21564 { 21565 set_decl_tls_model (v, decl_default_tls_model (v)); 21566 /* If rtl has been already set for this var, call 21567 make_decl_rtl once again, so that encode_section_info 21568 has a chance to look at the new decl flags. */ 21569 if (DECL_RTL_SET_P (v)) 21570 make_decl_rtl (v); 21571 } 21572 C_DECL_THREADPRIVATE_P (v) = 1; 21573 } 21574 } 21575 21576 c_parser_skip_to_pragma_eol (parser); 21577 } 21578 21579 /* Parse a transaction attribute (GCC Extension). 21580 21581 transaction-attribute: 21582 gnu-attributes 21583 attribute-specifier 21584 */ 21585 21586 static tree 21587 c_parser_transaction_attributes (c_parser *parser) 21588 { 21589 if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)) 21590 return c_parser_gnu_attributes (parser); 21591 21592 if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE)) 21593 return NULL_TREE; 21594 return c_parser_std_attribute_specifier (parser, true); 21595 } 21596 21597 /* Parse a __transaction_atomic or __transaction_relaxed statement 21598 (GCC Extension). 21599 21600 transaction-statement: 21601 __transaction_atomic transaction-attribute[opt] compound-statement 21602 __transaction_relaxed compound-statement 21603 21604 Note that the only valid attribute is: "outer". 21605 */ 21606 21607 static tree 21608 c_parser_transaction (c_parser *parser, enum rid keyword) 21609 { 21610 unsigned int old_in = parser->in_transaction; 21611 unsigned int this_in = 1, new_in; 21612 location_t loc = c_parser_peek_token (parser)->location; 21613 tree stmt, attrs; 21614 21615 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC 21616 || keyword == RID_TRANSACTION_RELAXED) 21617 && c_parser_next_token_is_keyword (parser, keyword)); 21618 c_parser_consume_token (parser); 21619 21620 if (keyword == RID_TRANSACTION_RELAXED) 21621 this_in |= TM_STMT_ATTR_RELAXED; 21622 else 21623 { 21624 attrs = c_parser_transaction_attributes (parser); 21625 if (attrs) 21626 this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER); 21627 } 21628 21629 /* Keep track if we're in the lexical scope of an outer transaction. */ 21630 new_in = this_in | (old_in & TM_STMT_ATTR_OUTER); 21631 21632 parser->in_transaction = new_in; 21633 stmt = c_parser_compound_statement (parser); 21634 parser->in_transaction = old_in; 21635 21636 if (flag_tm) 21637 stmt = c_finish_transaction (loc, stmt, this_in); 21638 else 21639 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ? 21640 "%<__transaction_atomic%> without transactional memory support enabled" 21641 : "%<__transaction_relaxed %> " 21642 "without transactional memory support enabled")); 21643 21644 return stmt; 21645 } 21646 21647 /* Parse a __transaction_atomic or __transaction_relaxed expression 21648 (GCC Extension). 21649 21650 transaction-expression: 21651 __transaction_atomic ( expression ) 21652 __transaction_relaxed ( expression ) 21653 */ 21654 21655 static struct c_expr 21656 c_parser_transaction_expression (c_parser *parser, enum rid keyword) 21657 { 21658 struct c_expr ret; 21659 unsigned int old_in = parser->in_transaction; 21660 unsigned int this_in = 1; 21661 location_t loc = c_parser_peek_token (parser)->location; 21662 tree attrs; 21663 21664 gcc_assert ((keyword == RID_TRANSACTION_ATOMIC 21665 || keyword == RID_TRANSACTION_RELAXED) 21666 && c_parser_next_token_is_keyword (parser, keyword)); 21667 c_parser_consume_token (parser); 21668 21669 if (keyword == RID_TRANSACTION_RELAXED) 21670 this_in |= TM_STMT_ATTR_RELAXED; 21671 else 21672 { 21673 attrs = c_parser_transaction_attributes (parser); 21674 if (attrs) 21675 this_in |= parse_tm_stmt_attr (attrs, 0); 21676 } 21677 21678 parser->in_transaction = this_in; 21679 matching_parens parens; 21680 if (parens.require_open (parser)) 21681 { 21682 tree expr = c_parser_expression (parser).value; 21683 ret.original_type = TREE_TYPE (expr); 21684 ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr); 21685 if (this_in & TM_STMT_ATTR_RELAXED) 21686 TRANSACTION_EXPR_RELAXED (ret.value) = 1; 21687 SET_EXPR_LOCATION (ret.value, loc); 21688 ret.original_code = TRANSACTION_EXPR; 21689 if (!parens.require_close (parser)) 21690 { 21691 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); 21692 goto error; 21693 } 21694 } 21695 else 21696 { 21697 error: 21698 ret.set_error (); 21699 ret.original_code = ERROR_MARK; 21700 ret.original_type = NULL; 21701 } 21702 parser->in_transaction = old_in; 21703 21704 if (!flag_tm) 21705 error_at (loc, (keyword == RID_TRANSACTION_ATOMIC ? 21706 "%<__transaction_atomic%> without transactional memory support enabled" 21707 : "%<__transaction_relaxed %> " 21708 "without transactional memory support enabled")); 21709 21710 set_c_expr_source_range (&ret, loc, loc); 21711 21712 return ret; 21713 } 21714 21715 /* Parse a __transaction_cancel statement (GCC Extension). 21716 21717 transaction-cancel-statement: 21718 __transaction_cancel transaction-attribute[opt] ; 21719 21720 Note that the only valid attribute is "outer". 21721 */ 21722 21723 static tree 21724 c_parser_transaction_cancel (c_parser *parser) 21725 { 21726 location_t loc = c_parser_peek_token (parser)->location; 21727 tree attrs; 21728 bool is_outer = false; 21729 21730 gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL)); 21731 c_parser_consume_token (parser); 21732 21733 attrs = c_parser_transaction_attributes (parser); 21734 if (attrs) 21735 is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0); 21736 21737 if (!flag_tm) 21738 { 21739 error_at (loc, "%<__transaction_cancel%> without " 21740 "transactional memory support enabled"); 21741 goto ret_error; 21742 } 21743 else if (parser->in_transaction & TM_STMT_ATTR_RELAXED) 21744 { 21745 error_at (loc, "%<__transaction_cancel%> within a " 21746 "%<__transaction_relaxed%>"); 21747 goto ret_error; 21748 } 21749 else if (is_outer) 21750 { 21751 if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0 21752 && !is_tm_may_cancel_outer (current_function_decl)) 21753 { 21754 error_at (loc, "outer %<__transaction_cancel%> not " 21755 "within outer %<__transaction_atomic%> or " 21756 "a %<transaction_may_cancel_outer%> function"); 21757 goto ret_error; 21758 } 21759 } 21760 else if (parser->in_transaction == 0) 21761 { 21762 error_at (loc, "%<__transaction_cancel%> not within " 21763 "%<__transaction_atomic%>"); 21764 goto ret_error; 21765 } 21766 21767 return add_stmt (build_tm_abort_call (loc, is_outer)); 21768 21769 ret_error: 21770 return build1 (NOP_EXPR, void_type_node, error_mark_node); 21771 } 21772 21773 /* Parse a single source file. */ 21774 21775 void 21776 c_parse_file (void) 21777 { 21778 /* Use local storage to begin. If the first token is a pragma, parse it. 21779 If it is #pragma GCC pch_preprocess, then this will load a PCH file 21780 which will cause garbage collection. */ 21781 c_parser tparser; 21782 21783 memset (&tparser, 0, sizeof tparser); 21784 tparser.translate_strings_p = true; 21785 tparser.tokens = &tparser.tokens_buf[0]; 21786 the_parser = &tparser; 21787 21788 if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS) 21789 c_parser_pragma_pch_preprocess (&tparser); 21790 else 21791 c_common_no_more_pch (); 21792 21793 the_parser = ggc_alloc<c_parser> (); 21794 *the_parser = tparser; 21795 if (tparser.tokens == &tparser.tokens_buf[0]) 21796 the_parser->tokens = &the_parser->tokens_buf[0]; 21797 21798 /* Initialize EH, if we've been told to do so. */ 21799 if (flag_exceptions) 21800 using_eh_for_cleanups (); 21801 21802 c_parser_translation_unit (the_parser); 21803 the_parser = NULL; 21804 } 21805 21806 /* Parse the body of a function declaration marked with "__RTL". 21807 21808 The RTL parser works on the level of characters read from a 21809 FILE *, whereas c_parser works at the level of tokens. 21810 Square this circle by consuming all of the tokens up to and 21811 including the closing brace, recording the start/end of the RTL 21812 fragment, and reopening the file and re-reading the relevant 21813 lines within the RTL parser. 21814 21815 This requires the opening and closing braces of the C function 21816 to be on separate lines from the RTL they wrap. 21817 21818 Take ownership of START_WITH_PASS, if non-NULL. */ 21819 21820 location_t 21821 c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass) 21822 { 21823 if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>")) 21824 { 21825 free (start_with_pass); 21826 return c_parser_peek_token (parser)->location; 21827 } 21828 21829 location_t start_loc = c_parser_peek_token (parser)->location; 21830 21831 /* Consume all tokens, up to the closing brace, handling 21832 matching pairs of braces in the rtl dump. */ 21833 int num_open_braces = 1; 21834 while (1) 21835 { 21836 switch (c_parser_peek_token (parser)->type) 21837 { 21838 case CPP_OPEN_BRACE: 21839 num_open_braces++; 21840 break; 21841 case CPP_CLOSE_BRACE: 21842 if (--num_open_braces == 0) 21843 goto found_closing_brace; 21844 break; 21845 case CPP_EOF: 21846 error_at (start_loc, "no closing brace"); 21847 free (start_with_pass); 21848 return c_parser_peek_token (parser)->location; 21849 default: 21850 break; 21851 } 21852 c_parser_consume_token (parser); 21853 } 21854 21855 found_closing_brace: 21856 /* At the closing brace; record its location. */ 21857 location_t end_loc = c_parser_peek_token (parser)->location; 21858 21859 /* Consume the closing brace. */ 21860 c_parser_consume_token (parser); 21861 21862 /* Invoke the RTL parser. */ 21863 if (!read_rtl_function_body_from_file_range (start_loc, end_loc)) 21864 { 21865 free (start_with_pass); 21866 return end_loc; 21867 } 21868 21869 /* Run the backend on the cfun created above, transferring ownership of 21870 START_WITH_PASS. */ 21871 run_rtl_passes (start_with_pass); 21872 return end_loc; 21873 } 21874 21875 #include "gt-c-c-parser.h" 21876