1 //===--- ParseOpenMP.cpp - OpenMP directives parsing ----------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements parsing of all OpenMP directives and clauses. 10 /// 11 //===----------------------------------------------------------------------===// 12 13 #include "clang/AST/ASTContext.h" 14 #include "clang/AST/StmtOpenMP.h" 15 #include "clang/Parse/ParseDiagnostic.h" 16 #include "clang/Parse/Parser.h" 17 #include "clang/Parse/RAIIObjectsForParser.h" 18 #include "clang/Sema/Scope.h" 19 #include "llvm/ADT/PointerIntPair.h" 20 21 using namespace clang; 22 23 //===----------------------------------------------------------------------===// 24 // OpenMP declarative directives. 25 //===----------------------------------------------------------------------===// 26 27 namespace { 28 enum OpenMPDirectiveKindEx { 29 OMPD_cancellation = OMPD_unknown + 1, 30 OMPD_data, 31 OMPD_declare, 32 OMPD_end, 33 OMPD_end_declare, 34 OMPD_enter, 35 OMPD_exit, 36 OMPD_point, 37 OMPD_reduction, 38 OMPD_target_enter, 39 OMPD_target_exit, 40 OMPD_update, 41 OMPD_distribute_parallel, 42 OMPD_teams_distribute_parallel, 43 OMPD_target_teams_distribute_parallel, 44 OMPD_mapper, 45 OMPD_variant, 46 }; 47 48 class DeclDirectiveListParserHelper final { 49 SmallVector<Expr *, 4> Identifiers; 50 Parser *P; 51 OpenMPDirectiveKind Kind; 52 53 public: 54 DeclDirectiveListParserHelper(Parser *P, OpenMPDirectiveKind Kind) 55 : P(P), Kind(Kind) {} 56 void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) { 57 ExprResult Res = P->getActions().ActOnOpenMPIdExpression( 58 P->getCurScope(), SS, NameInfo, Kind); 59 if (Res.isUsable()) 60 Identifiers.push_back(Res.get()); 61 } 62 llvm::ArrayRef<Expr *> getIdentifiers() const { return Identifiers; } 63 }; 64 } // namespace 65 66 // Map token string to extended OMP token kind that are 67 // OpenMPDirectiveKind + OpenMPDirectiveKindEx. 68 static unsigned getOpenMPDirectiveKindEx(StringRef S) { 69 auto DKind = getOpenMPDirectiveKind(S); 70 if (DKind != OMPD_unknown) 71 return DKind; 72 73 return llvm::StringSwitch<unsigned>(S) 74 .Case("cancellation", OMPD_cancellation) 75 .Case("data", OMPD_data) 76 .Case("declare", OMPD_declare) 77 .Case("end", OMPD_end) 78 .Case("enter", OMPD_enter) 79 .Case("exit", OMPD_exit) 80 .Case("point", OMPD_point) 81 .Case("reduction", OMPD_reduction) 82 .Case("update", OMPD_update) 83 .Case("mapper", OMPD_mapper) 84 .Case("variant", OMPD_variant) 85 .Default(OMPD_unknown); 86 } 87 88 static OpenMPDirectiveKind parseOpenMPDirectiveKind(Parser &P) { 89 // Array of foldings: F[i][0] F[i][1] ===> F[i][2]. 90 // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd 91 // TODO: add other combined directives in topological order. 92 static const unsigned F[][3] = { 93 {OMPD_cancellation, OMPD_point, OMPD_cancellation_point}, 94 {OMPD_declare, OMPD_reduction, OMPD_declare_reduction}, 95 {OMPD_declare, OMPD_mapper, OMPD_declare_mapper}, 96 {OMPD_declare, OMPD_simd, OMPD_declare_simd}, 97 {OMPD_declare, OMPD_target, OMPD_declare_target}, 98 {OMPD_declare, OMPD_variant, OMPD_declare_variant}, 99 {OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel}, 100 {OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for}, 101 {OMPD_distribute_parallel_for, OMPD_simd, 102 OMPD_distribute_parallel_for_simd}, 103 {OMPD_distribute, OMPD_simd, OMPD_distribute_simd}, 104 {OMPD_end, OMPD_declare, OMPD_end_declare}, 105 {OMPD_end_declare, OMPD_target, OMPD_end_declare_target}, 106 {OMPD_target, OMPD_data, OMPD_target_data}, 107 {OMPD_target, OMPD_enter, OMPD_target_enter}, 108 {OMPD_target, OMPD_exit, OMPD_target_exit}, 109 {OMPD_target, OMPD_update, OMPD_target_update}, 110 {OMPD_target_enter, OMPD_data, OMPD_target_enter_data}, 111 {OMPD_target_exit, OMPD_data, OMPD_target_exit_data}, 112 {OMPD_for, OMPD_simd, OMPD_for_simd}, 113 {OMPD_parallel, OMPD_for, OMPD_parallel_for}, 114 {OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd}, 115 {OMPD_parallel, OMPD_sections, OMPD_parallel_sections}, 116 {OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd}, 117 {OMPD_target, OMPD_parallel, OMPD_target_parallel}, 118 {OMPD_target, OMPD_simd, OMPD_target_simd}, 119 {OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for}, 120 {OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd}, 121 {OMPD_teams, OMPD_distribute, OMPD_teams_distribute}, 122 {OMPD_teams_distribute, OMPD_simd, OMPD_teams_distribute_simd}, 123 {OMPD_teams_distribute, OMPD_parallel, OMPD_teams_distribute_parallel}, 124 {OMPD_teams_distribute_parallel, OMPD_for, 125 OMPD_teams_distribute_parallel_for}, 126 {OMPD_teams_distribute_parallel_for, OMPD_simd, 127 OMPD_teams_distribute_parallel_for_simd}, 128 {OMPD_target, OMPD_teams, OMPD_target_teams}, 129 {OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute}, 130 {OMPD_target_teams_distribute, OMPD_parallel, 131 OMPD_target_teams_distribute_parallel}, 132 {OMPD_target_teams_distribute, OMPD_simd, 133 OMPD_target_teams_distribute_simd}, 134 {OMPD_target_teams_distribute_parallel, OMPD_for, 135 OMPD_target_teams_distribute_parallel_for}, 136 {OMPD_target_teams_distribute_parallel_for, OMPD_simd, 137 OMPD_target_teams_distribute_parallel_for_simd}}; 138 enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 }; 139 Token Tok = P.getCurToken(); 140 unsigned DKind = 141 Tok.isAnnotation() 142 ? static_cast<unsigned>(OMPD_unknown) 143 : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok)); 144 if (DKind == OMPD_unknown) 145 return OMPD_unknown; 146 147 for (unsigned I = 0; I < llvm::array_lengthof(F); ++I) { 148 if (DKind != F[I][0]) 149 continue; 150 151 Tok = P.getPreprocessor().LookAhead(0); 152 unsigned SDKind = 153 Tok.isAnnotation() 154 ? static_cast<unsigned>(OMPD_unknown) 155 : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok)); 156 if (SDKind == OMPD_unknown) 157 continue; 158 159 if (SDKind == F[I][1]) { 160 P.ConsumeToken(); 161 DKind = F[I][2]; 162 } 163 } 164 return DKind < OMPD_unknown ? static_cast<OpenMPDirectiveKind>(DKind) 165 : OMPD_unknown; 166 } 167 168 static DeclarationName parseOpenMPReductionId(Parser &P) { 169 Token Tok = P.getCurToken(); 170 Sema &Actions = P.getActions(); 171 OverloadedOperatorKind OOK = OO_None; 172 // Allow to use 'operator' keyword for C++ operators 173 bool WithOperator = false; 174 if (Tok.is(tok::kw_operator)) { 175 P.ConsumeToken(); 176 Tok = P.getCurToken(); 177 WithOperator = true; 178 } 179 switch (Tok.getKind()) { 180 case tok::plus: // '+' 181 OOK = OO_Plus; 182 break; 183 case tok::minus: // '-' 184 OOK = OO_Minus; 185 break; 186 case tok::star: // '*' 187 OOK = OO_Star; 188 break; 189 case tok::amp: // '&' 190 OOK = OO_Amp; 191 break; 192 case tok::pipe: // '|' 193 OOK = OO_Pipe; 194 break; 195 case tok::caret: // '^' 196 OOK = OO_Caret; 197 break; 198 case tok::ampamp: // '&&' 199 OOK = OO_AmpAmp; 200 break; 201 case tok::pipepipe: // '||' 202 OOK = OO_PipePipe; 203 break; 204 case tok::identifier: // identifier 205 if (!WithOperator) 206 break; 207 LLVM_FALLTHROUGH; 208 default: 209 P.Diag(Tok.getLocation(), diag::err_omp_expected_reduction_identifier); 210 P.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end, 211 Parser::StopBeforeMatch); 212 return DeclarationName(); 213 } 214 P.ConsumeToken(); 215 auto &DeclNames = Actions.getASTContext().DeclarationNames; 216 return OOK == OO_None ? DeclNames.getIdentifier(Tok.getIdentifierInfo()) 217 : DeclNames.getCXXOperatorName(OOK); 218 } 219 220 /// Parse 'omp declare reduction' construct. 221 /// 222 /// declare-reduction-directive: 223 /// annot_pragma_openmp 'declare' 'reduction' 224 /// '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')' 225 /// ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')'] 226 /// annot_pragma_openmp_end 227 /// <reduction_id> is either a base language identifier or one of the following 228 /// operators: '+', '-', '*', '&', '|', '^', '&&' and '||'. 229 /// 230 Parser::DeclGroupPtrTy 231 Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) { 232 // Parse '('. 233 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); 234 if (T.expectAndConsume(diag::err_expected_lparen_after, 235 getOpenMPDirectiveName(OMPD_declare_reduction))) { 236 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 237 return DeclGroupPtrTy(); 238 } 239 240 DeclarationName Name = parseOpenMPReductionId(*this); 241 if (Name.isEmpty() && Tok.is(tok::annot_pragma_openmp_end)) 242 return DeclGroupPtrTy(); 243 244 // Consume ':'. 245 bool IsCorrect = !ExpectAndConsume(tok::colon); 246 247 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end)) 248 return DeclGroupPtrTy(); 249 250 IsCorrect = IsCorrect && !Name.isEmpty(); 251 252 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) { 253 Diag(Tok.getLocation(), diag::err_expected_type); 254 IsCorrect = false; 255 } 256 257 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end)) 258 return DeclGroupPtrTy(); 259 260 SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes; 261 // Parse list of types until ':' token. 262 do { 263 ColonProtectionRAIIObject ColonRAII(*this); 264 SourceRange Range; 265 TypeResult TR = 266 ParseTypeName(&Range, DeclaratorContext::PrototypeContext, AS); 267 if (TR.isUsable()) { 268 QualType ReductionType = 269 Actions.ActOnOpenMPDeclareReductionType(Range.getBegin(), TR); 270 if (!ReductionType.isNull()) { 271 ReductionTypes.push_back( 272 std::make_pair(ReductionType, Range.getBegin())); 273 } 274 } else { 275 SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end, 276 StopBeforeMatch); 277 } 278 279 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) 280 break; 281 282 // Consume ','. 283 if (ExpectAndConsume(tok::comma)) { 284 IsCorrect = false; 285 if (Tok.is(tok::annot_pragma_openmp_end)) { 286 Diag(Tok.getLocation(), diag::err_expected_type); 287 return DeclGroupPtrTy(); 288 } 289 } 290 } while (Tok.isNot(tok::annot_pragma_openmp_end)); 291 292 if (ReductionTypes.empty()) { 293 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 294 return DeclGroupPtrTy(); 295 } 296 297 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end)) 298 return DeclGroupPtrTy(); 299 300 // Consume ':'. 301 if (ExpectAndConsume(tok::colon)) 302 IsCorrect = false; 303 304 if (Tok.is(tok::annot_pragma_openmp_end)) { 305 Diag(Tok.getLocation(), diag::err_expected_expression); 306 return DeclGroupPtrTy(); 307 } 308 309 DeclGroupPtrTy DRD = Actions.ActOnOpenMPDeclareReductionDirectiveStart( 310 getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes, AS); 311 312 // Parse <combiner> expression and then parse initializer if any for each 313 // correct type. 314 unsigned I = 0, E = ReductionTypes.size(); 315 for (Decl *D : DRD.get()) { 316 TentativeParsingAction TPA(*this); 317 ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope | 318 Scope::CompoundStmtScope | 319 Scope::OpenMPDirectiveScope); 320 // Parse <combiner> expression. 321 Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D); 322 ExprResult CombinerResult = 323 Actions.ActOnFinishFullExpr(ParseAssignmentExpression().get(), 324 D->getLocation(), /*DiscardedValue*/ false); 325 Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get()); 326 327 if (CombinerResult.isInvalid() && Tok.isNot(tok::r_paren) && 328 Tok.isNot(tok::annot_pragma_openmp_end)) { 329 TPA.Commit(); 330 IsCorrect = false; 331 break; 332 } 333 IsCorrect = !T.consumeClose() && IsCorrect && CombinerResult.isUsable(); 334 ExprResult InitializerResult; 335 if (Tok.isNot(tok::annot_pragma_openmp_end)) { 336 // Parse <initializer> expression. 337 if (Tok.is(tok::identifier) && 338 Tok.getIdentifierInfo()->isStr("initializer")) { 339 ConsumeToken(); 340 } else { 341 Diag(Tok.getLocation(), diag::err_expected) << "'initializer'"; 342 TPA.Commit(); 343 IsCorrect = false; 344 break; 345 } 346 // Parse '('. 347 BalancedDelimiterTracker T(*this, tok::l_paren, 348 tok::annot_pragma_openmp_end); 349 IsCorrect = 350 !T.expectAndConsume(diag::err_expected_lparen_after, "initializer") && 351 IsCorrect; 352 if (Tok.isNot(tok::annot_pragma_openmp_end)) { 353 ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope | 354 Scope::CompoundStmtScope | 355 Scope::OpenMPDirectiveScope); 356 // Parse expression. 357 VarDecl *OmpPrivParm = 358 Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(), 359 D); 360 // Check if initializer is omp_priv <init_expr> or something else. 361 if (Tok.is(tok::identifier) && 362 Tok.getIdentifierInfo()->isStr("omp_priv")) { 363 if (Actions.getLangOpts().CPlusPlus) { 364 InitializerResult = Actions.ActOnFinishFullExpr( 365 ParseAssignmentExpression().get(), D->getLocation(), 366 /*DiscardedValue*/ false); 367 } else { 368 ConsumeToken(); 369 ParseOpenMPReductionInitializerForDecl(OmpPrivParm); 370 } 371 } else { 372 InitializerResult = Actions.ActOnFinishFullExpr( 373 ParseAssignmentExpression().get(), D->getLocation(), 374 /*DiscardedValue*/ false); 375 } 376 Actions.ActOnOpenMPDeclareReductionInitializerEnd( 377 D, InitializerResult.get(), OmpPrivParm); 378 if (InitializerResult.isInvalid() && Tok.isNot(tok::r_paren) && 379 Tok.isNot(tok::annot_pragma_openmp_end)) { 380 TPA.Commit(); 381 IsCorrect = false; 382 break; 383 } 384 IsCorrect = 385 !T.consumeClose() && IsCorrect && !InitializerResult.isInvalid(); 386 } 387 } 388 389 ++I; 390 // Revert parsing if not the last type, otherwise accept it, we're done with 391 // parsing. 392 if (I != E) 393 TPA.Revert(); 394 else 395 TPA.Commit(); 396 } 397 return Actions.ActOnOpenMPDeclareReductionDirectiveEnd(getCurScope(), DRD, 398 IsCorrect); 399 } 400 401 void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) { 402 // Parse declarator '=' initializer. 403 // If a '==' or '+=' is found, suggest a fixit to '='. 404 if (isTokenEqualOrEqualTypo()) { 405 ConsumeToken(); 406 407 if (Tok.is(tok::code_completion)) { 408 Actions.CodeCompleteInitializer(getCurScope(), OmpPrivParm); 409 Actions.FinalizeDeclaration(OmpPrivParm); 410 cutOffParsing(); 411 return; 412 } 413 414 ExprResult Init(ParseInitializer()); 415 416 if (Init.isInvalid()) { 417 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch); 418 Actions.ActOnInitializerError(OmpPrivParm); 419 } else { 420 Actions.AddInitializerToDecl(OmpPrivParm, Init.get(), 421 /*DirectInit=*/false); 422 } 423 } else if (Tok.is(tok::l_paren)) { 424 // Parse C++ direct initializer: '(' expression-list ')' 425 BalancedDelimiterTracker T(*this, tok::l_paren); 426 T.consumeOpen(); 427 428 ExprVector Exprs; 429 CommaLocsTy CommaLocs; 430 431 SourceLocation LParLoc = T.getOpenLocation(); 432 auto RunSignatureHelp = [this, OmpPrivParm, LParLoc, &Exprs]() { 433 QualType PreferredType = Actions.ProduceConstructorSignatureHelp( 434 getCurScope(), OmpPrivParm->getType()->getCanonicalTypeInternal(), 435 OmpPrivParm->getLocation(), Exprs, LParLoc); 436 CalledSignatureHelp = true; 437 return PreferredType; 438 }; 439 if (ParseExpressionList(Exprs, CommaLocs, [&] { 440 PreferredType.enterFunctionArgument(Tok.getLocation(), 441 RunSignatureHelp); 442 })) { 443 if (PP.isCodeCompletionReached() && !CalledSignatureHelp) 444 RunSignatureHelp(); 445 Actions.ActOnInitializerError(OmpPrivParm); 446 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch); 447 } else { 448 // Match the ')'. 449 SourceLocation RLoc = Tok.getLocation(); 450 if (!T.consumeClose()) 451 RLoc = T.getCloseLocation(); 452 453 assert(!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size() && 454 "Unexpected number of commas!"); 455 456 ExprResult Initializer = 457 Actions.ActOnParenListExpr(T.getOpenLocation(), RLoc, Exprs); 458 Actions.AddInitializerToDecl(OmpPrivParm, Initializer.get(), 459 /*DirectInit=*/true); 460 } 461 } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 462 // Parse C++0x braced-init-list. 463 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 464 465 ExprResult Init(ParseBraceInitializer()); 466 467 if (Init.isInvalid()) { 468 Actions.ActOnInitializerError(OmpPrivParm); 469 } else { 470 Actions.AddInitializerToDecl(OmpPrivParm, Init.get(), 471 /*DirectInit=*/true); 472 } 473 } else { 474 Actions.ActOnUninitializedDecl(OmpPrivParm); 475 } 476 } 477 478 /// Parses 'omp declare mapper' directive. 479 /// 480 /// declare-mapper-directive: 481 /// annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifier> ':'] 482 /// <type> <var> ')' [<clause>[[,] <clause>] ... ] 483 /// annot_pragma_openmp_end 484 /// <mapper-identifier> and <var> are base language identifiers. 485 /// 486 Parser::DeclGroupPtrTy 487 Parser::ParseOpenMPDeclareMapperDirective(AccessSpecifier AS) { 488 bool IsCorrect = true; 489 // Parse '(' 490 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); 491 if (T.expectAndConsume(diag::err_expected_lparen_after, 492 getOpenMPDirectiveName(OMPD_declare_mapper))) { 493 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 494 return DeclGroupPtrTy(); 495 } 496 497 // Parse <mapper-identifier> 498 auto &DeclNames = Actions.getASTContext().DeclarationNames; 499 DeclarationName MapperId; 500 if (PP.LookAhead(0).is(tok::colon)) { 501 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) { 502 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier); 503 IsCorrect = false; 504 } else { 505 MapperId = DeclNames.getIdentifier(Tok.getIdentifierInfo()); 506 } 507 ConsumeToken(); 508 // Consume ':'. 509 ExpectAndConsume(tok::colon); 510 } else { 511 // If no mapper identifier is provided, its name is "default" by default 512 MapperId = 513 DeclNames.getIdentifier(&Actions.getASTContext().Idents.get("default")); 514 } 515 516 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end)) 517 return DeclGroupPtrTy(); 518 519 // Parse <type> <var> 520 DeclarationName VName; 521 QualType MapperType; 522 SourceRange Range; 523 TypeResult ParsedType = parseOpenMPDeclareMapperVarDecl(Range, VName, AS); 524 if (ParsedType.isUsable()) 525 MapperType = 526 Actions.ActOnOpenMPDeclareMapperType(Range.getBegin(), ParsedType); 527 if (MapperType.isNull()) 528 IsCorrect = false; 529 if (!IsCorrect) { 530 SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch); 531 return DeclGroupPtrTy(); 532 } 533 534 // Consume ')'. 535 IsCorrect &= !T.consumeClose(); 536 if (!IsCorrect) { 537 SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch); 538 return DeclGroupPtrTy(); 539 } 540 541 // Enter scope. 542 OMPDeclareMapperDecl *DMD = Actions.ActOnOpenMPDeclareMapperDirectiveStart( 543 getCurScope(), Actions.getCurLexicalContext(), MapperId, MapperType, 544 Range.getBegin(), VName, AS); 545 DeclarationNameInfo DirName; 546 SourceLocation Loc = Tok.getLocation(); 547 unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope | 548 Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope; 549 ParseScope OMPDirectiveScope(this, ScopeFlags); 550 Actions.StartOpenMPDSABlock(OMPD_declare_mapper, DirName, getCurScope(), Loc); 551 552 // Add the mapper variable declaration. 553 Actions.ActOnOpenMPDeclareMapperDirectiveVarDecl( 554 DMD, getCurScope(), MapperType, Range.getBegin(), VName); 555 556 // Parse map clauses. 557 SmallVector<OMPClause *, 6> Clauses; 558 while (Tok.isNot(tok::annot_pragma_openmp_end)) { 559 OpenMPClauseKind CKind = Tok.isAnnotation() 560 ? OMPC_unknown 561 : getOpenMPClauseKind(PP.getSpelling(Tok)); 562 Actions.StartOpenMPClause(CKind); 563 OMPClause *Clause = 564 ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.size() == 0); 565 if (Clause) 566 Clauses.push_back(Clause); 567 else 568 IsCorrect = false; 569 // Skip ',' if any. 570 if (Tok.is(tok::comma)) 571 ConsumeToken(); 572 Actions.EndOpenMPClause(); 573 } 574 if (Clauses.empty()) { 575 Diag(Tok, diag::err_omp_expected_clause) 576 << getOpenMPDirectiveName(OMPD_declare_mapper); 577 IsCorrect = false; 578 } 579 580 // Exit scope. 581 Actions.EndOpenMPDSABlock(nullptr); 582 OMPDirectiveScope.Exit(); 583 584 DeclGroupPtrTy DGP = 585 Actions.ActOnOpenMPDeclareMapperDirectiveEnd(DMD, getCurScope(), Clauses); 586 if (!IsCorrect) 587 return DeclGroupPtrTy(); 588 return DGP; 589 } 590 591 TypeResult Parser::parseOpenMPDeclareMapperVarDecl(SourceRange &Range, 592 DeclarationName &Name, 593 AccessSpecifier AS) { 594 // Parse the common declaration-specifiers piece. 595 Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier; 596 DeclSpec DS(AttrFactory); 597 ParseSpecifierQualifierList(DS, AS, DSC); 598 599 // Parse the declarator. 600 DeclaratorContext Context = DeclaratorContext::PrototypeContext; 601 Declarator DeclaratorInfo(DS, Context); 602 ParseDeclarator(DeclaratorInfo); 603 Range = DeclaratorInfo.getSourceRange(); 604 if (DeclaratorInfo.getIdentifier() == nullptr) { 605 Diag(Tok.getLocation(), diag::err_omp_mapper_expected_declarator); 606 return true; 607 } 608 Name = Actions.GetNameForDeclarator(DeclaratorInfo).getName(); 609 610 return Actions.ActOnOpenMPDeclareMapperVarDecl(getCurScope(), DeclaratorInfo); 611 } 612 613 namespace { 614 /// RAII that recreates function context for correct parsing of clauses of 615 /// 'declare simd' construct. 616 /// OpenMP, 2.8.2 declare simd Construct 617 /// The expressions appearing in the clauses of this directive are evaluated in 618 /// the scope of the arguments of the function declaration or definition. 619 class FNContextRAII final { 620 Parser &P; 621 Sema::CXXThisScopeRAII *ThisScope; 622 Parser::ParseScope *TempScope; 623 Parser::ParseScope *FnScope; 624 bool HasTemplateScope = false; 625 bool HasFunScope = false; 626 FNContextRAII() = delete; 627 FNContextRAII(const FNContextRAII &) = delete; 628 FNContextRAII &operator=(const FNContextRAII &) = delete; 629 630 public: 631 FNContextRAII(Parser &P, Parser::DeclGroupPtrTy Ptr) : P(P) { 632 Decl *D = *Ptr.get().begin(); 633 NamedDecl *ND = dyn_cast<NamedDecl>(D); 634 RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext()); 635 Sema &Actions = P.getActions(); 636 637 // Allow 'this' within late-parsed attributes. 638 ThisScope = new Sema::CXXThisScopeRAII(Actions, RD, Qualifiers(), 639 ND && ND->isCXXInstanceMember()); 640 641 // If the Decl is templatized, add template parameters to scope. 642 HasTemplateScope = D->isTemplateDecl(); 643 TempScope = 644 new Parser::ParseScope(&P, Scope::TemplateParamScope, HasTemplateScope); 645 if (HasTemplateScope) 646 Actions.ActOnReenterTemplateScope(Actions.getCurScope(), D); 647 648 // If the Decl is on a function, add function parameters to the scope. 649 HasFunScope = D->isFunctionOrFunctionTemplate(); 650 FnScope = new Parser::ParseScope( 651 &P, Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope, 652 HasFunScope); 653 if (HasFunScope) 654 Actions.ActOnReenterFunctionContext(Actions.getCurScope(), D); 655 } 656 ~FNContextRAII() { 657 if (HasFunScope) { 658 P.getActions().ActOnExitFunctionContext(); 659 FnScope->Exit(); // Pop scope, and remove Decls from IdResolver 660 } 661 if (HasTemplateScope) 662 TempScope->Exit(); 663 delete FnScope; 664 delete TempScope; 665 delete ThisScope; 666 } 667 }; 668 } // namespace 669 670 /// Parses clauses for 'declare simd' directive. 671 /// clause: 672 /// 'inbranch' | 'notinbranch' 673 /// 'simdlen' '(' <expr> ')' 674 /// { 'uniform' '(' <argument_list> ')' } 675 /// { 'aligned '(' <argument_list> [ ':' <alignment> ] ')' } 676 /// { 'linear '(' <argument_list> [ ':' <step> ] ')' } 677 static bool parseDeclareSimdClauses( 678 Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, ExprResult &SimdLen, 679 SmallVectorImpl<Expr *> &Uniforms, SmallVectorImpl<Expr *> &Aligneds, 680 SmallVectorImpl<Expr *> &Alignments, SmallVectorImpl<Expr *> &Linears, 681 SmallVectorImpl<unsigned> &LinModifiers, SmallVectorImpl<Expr *> &Steps) { 682 SourceRange BSRange; 683 const Token &Tok = P.getCurToken(); 684 bool IsError = false; 685 while (Tok.isNot(tok::annot_pragma_openmp_end)) { 686 if (Tok.isNot(tok::identifier)) 687 break; 688 OMPDeclareSimdDeclAttr::BranchStateTy Out; 689 IdentifierInfo *II = Tok.getIdentifierInfo(); 690 StringRef ClauseName = II->getName(); 691 // Parse 'inranch|notinbranch' clauses. 692 if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) { 693 if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) { 694 P.Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch) 695 << ClauseName 696 << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange; 697 IsError = true; 698 } 699 BS = Out; 700 BSRange = SourceRange(Tok.getLocation(), Tok.getEndLoc()); 701 P.ConsumeToken(); 702 } else if (ClauseName.equals("simdlen")) { 703 if (SimdLen.isUsable()) { 704 P.Diag(Tok, diag::err_omp_more_one_clause) 705 << getOpenMPDirectiveName(OMPD_declare_simd) << ClauseName << 0; 706 IsError = true; 707 } 708 P.ConsumeToken(); 709 SourceLocation RLoc; 710 SimdLen = P.ParseOpenMPParensExpr(ClauseName, RLoc); 711 if (SimdLen.isInvalid()) 712 IsError = true; 713 } else { 714 OpenMPClauseKind CKind = getOpenMPClauseKind(ClauseName); 715 if (CKind == OMPC_uniform || CKind == OMPC_aligned || 716 CKind == OMPC_linear) { 717 Parser::OpenMPVarListDataTy Data; 718 SmallVectorImpl<Expr *> *Vars = &Uniforms; 719 if (CKind == OMPC_aligned) 720 Vars = &Aligneds; 721 else if (CKind == OMPC_linear) 722 Vars = &Linears; 723 724 P.ConsumeToken(); 725 if (P.ParseOpenMPVarList(OMPD_declare_simd, 726 getOpenMPClauseKind(ClauseName), *Vars, Data)) 727 IsError = true; 728 if (CKind == OMPC_aligned) { 729 Alignments.append(Aligneds.size() - Alignments.size(), Data.TailExpr); 730 } else if (CKind == OMPC_linear) { 731 if (P.getActions().CheckOpenMPLinearModifier(Data.LinKind, 732 Data.DepLinMapLoc)) 733 Data.LinKind = OMPC_LINEAR_val; 734 LinModifiers.append(Linears.size() - LinModifiers.size(), 735 Data.LinKind); 736 Steps.append(Linears.size() - Steps.size(), Data.TailExpr); 737 } 738 } else 739 // TODO: add parsing of other clauses. 740 break; 741 } 742 // Skip ',' if any. 743 if (Tok.is(tok::comma)) 744 P.ConsumeToken(); 745 } 746 return IsError; 747 } 748 749 /// Parse clauses for '#pragma omp declare simd'. 750 Parser::DeclGroupPtrTy 751 Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr, 752 CachedTokens &Toks, SourceLocation Loc) { 753 PP.EnterToken(Tok, /*IsReinject*/ true); 754 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true, 755 /*IsReinject*/ true); 756 // Consume the previously pushed token. 757 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); 758 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); 759 760 FNContextRAII FnContext(*this, Ptr); 761 OMPDeclareSimdDeclAttr::BranchStateTy BS = 762 OMPDeclareSimdDeclAttr::BS_Undefined; 763 ExprResult Simdlen; 764 SmallVector<Expr *, 4> Uniforms; 765 SmallVector<Expr *, 4> Aligneds; 766 SmallVector<Expr *, 4> Alignments; 767 SmallVector<Expr *, 4> Linears; 768 SmallVector<unsigned, 4> LinModifiers; 769 SmallVector<Expr *, 4> Steps; 770 bool IsError = 771 parseDeclareSimdClauses(*this, BS, Simdlen, Uniforms, Aligneds, 772 Alignments, Linears, LinModifiers, Steps); 773 // Need to check for extra tokens. 774 if (Tok.isNot(tok::annot_pragma_openmp_end)) { 775 Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 776 << getOpenMPDirectiveName(OMPD_declare_simd); 777 while (Tok.isNot(tok::annot_pragma_openmp_end)) 778 ConsumeAnyToken(); 779 } 780 // Skip the last annot_pragma_openmp_end. 781 SourceLocation EndLoc = ConsumeAnnotationToken(); 782 if (IsError) 783 return Ptr; 784 return Actions.ActOnOpenMPDeclareSimdDirective( 785 Ptr, BS, Simdlen.get(), Uniforms, Aligneds, Alignments, Linears, 786 LinModifiers, Steps, SourceRange(Loc, EndLoc)); 787 } 788 789 /// Parse optional 'score' '(' <expr> ')' ':'. 790 static ExprResult parseContextScore(Parser &P) { 791 ExprResult ScoreExpr; 792 SmallString<16> Buffer; 793 StringRef SelectorName = 794 P.getPreprocessor().getSpelling(P.getCurToken(), Buffer); 795 OMPDeclareVariantAttr::ScoreType ScoreKind = 796 OMPDeclareVariantAttr::ScoreUnknown; 797 (void)OMPDeclareVariantAttr::ConvertStrToScoreType(SelectorName, ScoreKind); 798 if (ScoreKind == OMPDeclareVariantAttr::ScoreUnknown) 799 return ScoreExpr; 800 assert(ScoreKind == OMPDeclareVariantAttr::ScoreSpecified && 801 "Expected \"score\" clause."); 802 (void)P.ConsumeToken(); 803 SourceLocation RLoc; 804 ScoreExpr = P.ParseOpenMPParensExpr(SelectorName, RLoc); 805 // Parse ':' 806 if (P.getCurToken().is(tok::colon)) 807 (void)P.ConsumeAnyToken(); 808 else 809 P.Diag(P.getCurToken(), diag::warn_pragma_expected_colon) 810 << "context selector score clause"; 811 return ScoreExpr; 812 } 813 814 /// Parse context selector for 'implementation' selector set: 815 /// 'vendor' '(' [ 'score' '(' <score _expr> ')' ':' ] <vendor> { ',' <vendor> } 816 /// ')' 817 static void parseImplementationSelector( 818 Parser &P, SourceLocation Loc, 819 llvm::function_ref<void(SourceRange, 820 const Sema::OpenMPDeclareVariantCtsSelectorData &)> 821 Callback) { 822 const Token &Tok = P.getCurToken(); 823 // Parse inner context selector set name, if any. 824 if (!Tok.is(tok::identifier)) { 825 P.Diag(Tok.getLocation(), diag::warn_omp_declare_variant_cs_name_expected) 826 << "implementation"; 827 // Skip until either '}', ')', or end of directive. 828 while (!P.SkipUntil(tok::r_brace, tok::r_paren, 829 tok::annot_pragma_openmp_end, Parser::StopBeforeMatch)) 830 ; 831 return; 832 } 833 SmallString<16> Buffer; 834 StringRef CtxSelectorName = P.getPreprocessor().getSpelling(Tok, Buffer); 835 OMPDeclareVariantAttr::CtxSelectorType CSKind = 836 OMPDeclareVariantAttr::CtxUnknown; 837 (void)OMPDeclareVariantAttr::ConvertStrToCtxSelectorType(CtxSelectorName, 838 CSKind); 839 (void)P.ConsumeToken(); 840 switch (CSKind) { 841 case OMPDeclareVariantAttr::CtxVendor: { 842 // Parse '('. 843 BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openmp_end); 844 (void)T.expectAndConsume(diag::err_expected_lparen_after, 845 CtxSelectorName.data()); 846 const ExprResult Score = parseContextScore(P); 847 do { 848 // Parse <vendor>. 849 StringRef VendorName; 850 if (Tok.is(tok::identifier)) { 851 Buffer.clear(); 852 VendorName = P.getPreprocessor().getSpelling(P.getCurToken(), Buffer); 853 (void)P.ConsumeToken(); 854 } else { 855 P.Diag(Tok.getLocation(), diag::err_omp_declare_variant_item_expected) 856 << "vendor identifier" 857 << "vendor" 858 << "implementation"; 859 } 860 if (!VendorName.empty()) { 861 Sema::OpenMPDeclareVariantCtsSelectorData Data( 862 OMPDeclareVariantAttr::CtxSetImplementation, CSKind, VendorName, 863 Score); 864 Callback(SourceRange(Loc, Tok.getLocation()), Data); 865 } 866 if (!P.TryConsumeToken(tok::comma) && Tok.isNot(tok::r_paren)) { 867 P.Diag(Tok, diag::err_expected_punc) 868 << (VendorName.empty() ? "vendor name" : VendorName); 869 } 870 } while (Tok.is(tok::identifier)); 871 // Parse ')'. 872 (void)T.consumeClose(); 873 break; 874 } 875 case OMPDeclareVariantAttr::CtxUnknown: 876 P.Diag(Tok.getLocation(), diag::warn_omp_declare_variant_cs_name_expected) 877 << "implementation"; 878 // Skip until either '}', ')', or end of directive. 879 while (!P.SkipUntil(tok::r_brace, tok::r_paren, 880 tok::annot_pragma_openmp_end, Parser::StopBeforeMatch)) 881 ; 882 return; 883 } 884 } 885 886 /// Parses clauses for 'declare variant' directive. 887 /// clause: 888 /// <selector_set_name> '=' '{' <context_selectors> '}' 889 /// [ ',' <selector_set_name> '=' '{' <context_selectors> '}' ] 890 bool Parser::parseOpenMPContextSelectors( 891 SourceLocation Loc, 892 llvm::function_ref<void(SourceRange, 893 const Sema::OpenMPDeclareVariantCtsSelectorData &)> 894 Callback) { 895 do { 896 // Parse inner context selector set name. 897 if (!Tok.is(tok::identifier)) { 898 Diag(Tok.getLocation(), diag::err_omp_declare_variant_no_ctx_selector) 899 << getOpenMPClauseName(OMPC_match); 900 return true; 901 } 902 SmallString<16> Buffer; 903 StringRef CtxSelectorSetName = PP.getSpelling(Tok, Buffer); 904 // Parse '='. 905 (void)ConsumeToken(); 906 if (Tok.isNot(tok::equal)) { 907 Diag(Tok.getLocation(), diag::err_omp_declare_variant_equal_expected) 908 << CtxSelectorSetName; 909 return true; 910 } 911 (void)ConsumeToken(); 912 // TBD: add parsing of known context selectors. 913 // Unknown selector - just ignore it completely. 914 { 915 // Parse '{'. 916 BalancedDelimiterTracker TBr(*this, tok::l_brace, 917 tok::annot_pragma_openmp_end); 918 if (TBr.expectAndConsume(diag::err_expected_lbrace_after, "=")) 919 return true; 920 OMPDeclareVariantAttr::CtxSelectorSetType CSSKind = 921 OMPDeclareVariantAttr::CtxSetUnknown; 922 (void)OMPDeclareVariantAttr::ConvertStrToCtxSelectorSetType( 923 CtxSelectorSetName, CSSKind); 924 switch (CSSKind) { 925 case OMPDeclareVariantAttr::CtxSetImplementation: 926 parseImplementationSelector(*this, Loc, Callback); 927 break; 928 case OMPDeclareVariantAttr::CtxSetUnknown: 929 // Skip until either '}', ')', or end of directive. 930 while (!SkipUntil(tok::r_brace, tok::r_paren, 931 tok::annot_pragma_openmp_end, StopBeforeMatch)) 932 ; 933 break; 934 } 935 // Parse '}'. 936 (void)TBr.consumeClose(); 937 } 938 // Consume ',' 939 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) 940 (void)ExpectAndConsume(tok::comma); 941 } while (Tok.isAnyIdentifier()); 942 return false; 943 } 944 945 /// Parse clauses for '#pragma omp declare variant ( variant-func-id ) clause'. 946 void Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr, 947 CachedTokens &Toks, 948 SourceLocation Loc) { 949 PP.EnterToken(Tok, /*IsReinject*/ true); 950 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true, 951 /*IsReinject*/ true); 952 // Consume the previously pushed token. 953 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); 954 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); 955 956 FNContextRAII FnContext(*this, Ptr); 957 // Parse function declaration id. 958 SourceLocation RLoc; 959 // Parse with IsAddressOfOperand set to true to parse methods as DeclRefExprs 960 // instead of MemberExprs. 961 ExprResult AssociatedFunction = 962 ParseOpenMPParensExpr(getOpenMPDirectiveName(OMPD_declare_variant), RLoc, 963 /*IsAddressOfOperand=*/true); 964 if (!AssociatedFunction.isUsable()) { 965 if (!Tok.is(tok::annot_pragma_openmp_end)) 966 while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch)) 967 ; 968 // Skip the last annot_pragma_openmp_end. 969 (void)ConsumeAnnotationToken(); 970 return; 971 } 972 Optional<std::pair<FunctionDecl *, Expr *>> DeclVarData = 973 Actions.checkOpenMPDeclareVariantFunction( 974 Ptr, AssociatedFunction.get(), SourceRange(Loc, Tok.getLocation())); 975 976 // Parse 'match'. 977 OpenMPClauseKind CKind = Tok.isAnnotation() 978 ? OMPC_unknown 979 : getOpenMPClauseKind(PP.getSpelling(Tok)); 980 if (CKind != OMPC_match) { 981 Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause) 982 << getOpenMPClauseName(OMPC_match); 983 while (!SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch)) 984 ; 985 // Skip the last annot_pragma_openmp_end. 986 (void)ConsumeAnnotationToken(); 987 return; 988 } 989 (void)ConsumeToken(); 990 // Parse '('. 991 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); 992 if (T.expectAndConsume(diag::err_expected_lparen_after, 993 getOpenMPClauseName(OMPC_match))) { 994 while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch)) 995 ; 996 // Skip the last annot_pragma_openmp_end. 997 (void)ConsumeAnnotationToken(); 998 return; 999 } 1000 1001 // Parse inner context selectors. 1002 if (!parseOpenMPContextSelectors( 1003 Loc, [this, &DeclVarData]( 1004 SourceRange SR, 1005 const Sema::OpenMPDeclareVariantCtsSelectorData &Data) { 1006 if (DeclVarData.hasValue()) 1007 Actions.ActOnOpenMPDeclareVariantDirective( 1008 DeclVarData.getValue().first, DeclVarData.getValue().second, 1009 SR, Data); 1010 })) { 1011 // Parse ')'. 1012 (void)T.consumeClose(); 1013 // Need to check for extra tokens. 1014 if (Tok.isNot(tok::annot_pragma_openmp_end)) { 1015 Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 1016 << getOpenMPDirectiveName(OMPD_declare_variant); 1017 } 1018 } 1019 1020 // Skip last tokens. 1021 while (Tok.isNot(tok::annot_pragma_openmp_end)) 1022 ConsumeAnyToken(); 1023 // Skip the last annot_pragma_openmp_end. 1024 (void)ConsumeAnnotationToken(); 1025 } 1026 1027 /// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'. 1028 /// 1029 /// default-clause: 1030 /// 'default' '(' 'none' | 'shared' ') 1031 /// 1032 /// proc_bind-clause: 1033 /// 'proc_bind' '(' 'master' | 'close' | 'spread' ') 1034 /// 1035 /// device_type-clause: 1036 /// 'device_type' '(' 'host' | 'nohost' | 'any' )' 1037 namespace { 1038 struct SimpleClauseData { 1039 unsigned Type; 1040 SourceLocation Loc; 1041 SourceLocation LOpen; 1042 SourceLocation TypeLoc; 1043 SourceLocation RLoc; 1044 SimpleClauseData(unsigned Type, SourceLocation Loc, SourceLocation LOpen, 1045 SourceLocation TypeLoc, SourceLocation RLoc) 1046 : Type(Type), Loc(Loc), LOpen(LOpen), TypeLoc(TypeLoc), RLoc(RLoc) {} 1047 }; 1048 } // anonymous namespace 1049 1050 static Optional<SimpleClauseData> 1051 parseOpenMPSimpleClause(Parser &P, OpenMPClauseKind Kind) { 1052 const Token &Tok = P.getCurToken(); 1053 SourceLocation Loc = Tok.getLocation(); 1054 SourceLocation LOpen = P.ConsumeToken(); 1055 // Parse '('. 1056 BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openmp_end); 1057 if (T.expectAndConsume(diag::err_expected_lparen_after, 1058 getOpenMPClauseName(Kind))) 1059 return llvm::None; 1060 1061 unsigned Type = getOpenMPSimpleClauseType( 1062 Kind, Tok.isAnnotation() ? "" : P.getPreprocessor().getSpelling(Tok)); 1063 SourceLocation TypeLoc = Tok.getLocation(); 1064 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && 1065 Tok.isNot(tok::annot_pragma_openmp_end)) 1066 P.ConsumeAnyToken(); 1067 1068 // Parse ')'. 1069 SourceLocation RLoc = Tok.getLocation(); 1070 if (!T.consumeClose()) 1071 RLoc = T.getCloseLocation(); 1072 1073 return SimpleClauseData(Type, Loc, LOpen, TypeLoc, RLoc); 1074 } 1075 1076 Parser::DeclGroupPtrTy Parser::ParseOMPDeclareTargetClauses() { 1077 // OpenMP 4.5 syntax with list of entities. 1078 Sema::NamedDeclSetType SameDirectiveDecls; 1079 SmallVector<std::tuple<OMPDeclareTargetDeclAttr::MapTypeTy, SourceLocation, 1080 NamedDecl *>, 1081 4> 1082 DeclareTargetDecls; 1083 OMPDeclareTargetDeclAttr::DevTypeTy DT = OMPDeclareTargetDeclAttr::DT_Any; 1084 SourceLocation DeviceTypeLoc; 1085 while (Tok.isNot(tok::annot_pragma_openmp_end)) { 1086 OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To; 1087 if (Tok.is(tok::identifier)) { 1088 IdentifierInfo *II = Tok.getIdentifierInfo(); 1089 StringRef ClauseName = II->getName(); 1090 bool IsDeviceTypeClause = 1091 getLangOpts().OpenMP >= 50 && 1092 getOpenMPClauseKind(ClauseName) == OMPC_device_type; 1093 // Parse 'to|link|device_type' clauses. 1094 if (!OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT) && 1095 !IsDeviceTypeClause) { 1096 Diag(Tok, diag::err_omp_declare_target_unexpected_clause) 1097 << ClauseName << (getLangOpts().OpenMP >= 50 ? 1 : 0); 1098 break; 1099 } 1100 // Parse 'device_type' clause and go to next clause if any. 1101 if (IsDeviceTypeClause) { 1102 Optional<SimpleClauseData> DevTypeData = 1103 parseOpenMPSimpleClause(*this, OMPC_device_type); 1104 if (DevTypeData.hasValue()) { 1105 if (DeviceTypeLoc.isValid()) { 1106 // We already saw another device_type clause, diagnose it. 1107 Diag(DevTypeData.getValue().Loc, 1108 diag::warn_omp_more_one_device_type_clause); 1109 } 1110 switch(static_cast<OpenMPDeviceType>(DevTypeData.getValue().Type)) { 1111 case OMPC_DEVICE_TYPE_any: 1112 DT = OMPDeclareTargetDeclAttr::DT_Any; 1113 break; 1114 case OMPC_DEVICE_TYPE_host: 1115 DT = OMPDeclareTargetDeclAttr::DT_Host; 1116 break; 1117 case OMPC_DEVICE_TYPE_nohost: 1118 DT = OMPDeclareTargetDeclAttr::DT_NoHost; 1119 break; 1120 case OMPC_DEVICE_TYPE_unknown: 1121 llvm_unreachable("Unexpected device_type"); 1122 } 1123 DeviceTypeLoc = DevTypeData.getValue().Loc; 1124 } 1125 continue; 1126 } 1127 ConsumeToken(); 1128 } 1129 auto &&Callback = [this, MT, &DeclareTargetDecls, &SameDirectiveDecls]( 1130 CXXScopeSpec &SS, DeclarationNameInfo NameInfo) { 1131 NamedDecl *ND = Actions.lookupOpenMPDeclareTargetName( 1132 getCurScope(), SS, NameInfo, SameDirectiveDecls); 1133 if (ND) 1134 DeclareTargetDecls.emplace_back(MT, NameInfo.getLoc(), ND); 1135 }; 1136 if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback, 1137 /*AllowScopeSpecifier=*/true)) 1138 break; 1139 1140 // Consume optional ','. 1141 if (Tok.is(tok::comma)) 1142 ConsumeToken(); 1143 } 1144 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 1145 ConsumeAnyToken(); 1146 for (auto &MTLocDecl : DeclareTargetDecls) { 1147 OMPDeclareTargetDeclAttr::MapTypeTy MT; 1148 SourceLocation Loc; 1149 NamedDecl *ND; 1150 std::tie(MT, Loc, ND) = MTLocDecl; 1151 // device_type clause is applied only to functions. 1152 Actions.ActOnOpenMPDeclareTargetName( 1153 ND, Loc, MT, isa<VarDecl>(ND) ? OMPDeclareTargetDeclAttr::DT_Any : DT); 1154 } 1155 SmallVector<Decl *, 4> Decls(SameDirectiveDecls.begin(), 1156 SameDirectiveDecls.end()); 1157 if (Decls.empty()) 1158 return DeclGroupPtrTy(); 1159 return Actions.BuildDeclaratorGroup(Decls); 1160 } 1161 1162 void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind DKind, 1163 SourceLocation DTLoc) { 1164 if (DKind != OMPD_end_declare_target) { 1165 Diag(Tok, diag::err_expected_end_declare_target); 1166 Diag(DTLoc, diag::note_matching) << "'#pragma omp declare target'"; 1167 return; 1168 } 1169 ConsumeAnyToken(); 1170 if (Tok.isNot(tok::annot_pragma_openmp_end)) { 1171 Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 1172 << getOpenMPDirectiveName(OMPD_end_declare_target); 1173 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 1174 } 1175 // Skip the last annot_pragma_openmp_end. 1176 ConsumeAnyToken(); 1177 } 1178 1179 /// Parsing of declarative OpenMP directives. 1180 /// 1181 /// threadprivate-directive: 1182 /// annot_pragma_openmp 'threadprivate' simple-variable-list 1183 /// annot_pragma_openmp_end 1184 /// 1185 /// allocate-directive: 1186 /// annot_pragma_openmp 'allocate' simple-variable-list [<clause>] 1187 /// annot_pragma_openmp_end 1188 /// 1189 /// declare-reduction-directive: 1190 /// annot_pragma_openmp 'declare' 'reduction' [...] 1191 /// annot_pragma_openmp_end 1192 /// 1193 /// declare-mapper-directive: 1194 /// annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':'] 1195 /// <type> <var> ')' [<clause>[[,] <clause>] ... ] 1196 /// annot_pragma_openmp_end 1197 /// 1198 /// declare-simd-directive: 1199 /// annot_pragma_openmp 'declare simd' {<clause> [,]} 1200 /// annot_pragma_openmp_end 1201 /// <function declaration/definition> 1202 /// 1203 /// requires directive: 1204 /// annot_pragma_openmp 'requires' <clause> [[[,] <clause>] ... ] 1205 /// annot_pragma_openmp_end 1206 /// 1207 Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( 1208 AccessSpecifier &AS, ParsedAttributesWithRange &Attrs, 1209 DeclSpec::TST TagType, Decl *Tag) { 1210 assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!"); 1211 ParenBraceBracketBalancer BalancerRAIIObj(*this); 1212 1213 SourceLocation Loc = ConsumeAnnotationToken(); 1214 OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this); 1215 1216 switch (DKind) { 1217 case OMPD_threadprivate: { 1218 ConsumeToken(); 1219 DeclDirectiveListParserHelper Helper(this, DKind); 1220 if (!ParseOpenMPSimpleVarList(DKind, Helper, 1221 /*AllowScopeSpecifier=*/true)) { 1222 // The last seen token is annot_pragma_openmp_end - need to check for 1223 // extra tokens. 1224 if (Tok.isNot(tok::annot_pragma_openmp_end)) { 1225 Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 1226 << getOpenMPDirectiveName(DKind); 1227 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 1228 } 1229 // Skip the last annot_pragma_openmp_end. 1230 ConsumeAnnotationToken(); 1231 return Actions.ActOnOpenMPThreadprivateDirective(Loc, 1232 Helper.getIdentifiers()); 1233 } 1234 break; 1235 } 1236 case OMPD_allocate: { 1237 ConsumeToken(); 1238 DeclDirectiveListParserHelper Helper(this, DKind); 1239 if (!ParseOpenMPSimpleVarList(DKind, Helper, 1240 /*AllowScopeSpecifier=*/true)) { 1241 SmallVector<OMPClause *, 1> Clauses; 1242 if (Tok.isNot(tok::annot_pragma_openmp_end)) { 1243 SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, 1244 OMPC_unknown + 1> 1245 FirstClauses(OMPC_unknown + 1); 1246 while (Tok.isNot(tok::annot_pragma_openmp_end)) { 1247 OpenMPClauseKind CKind = 1248 Tok.isAnnotation() ? OMPC_unknown 1249 : getOpenMPClauseKind(PP.getSpelling(Tok)); 1250 Actions.StartOpenMPClause(CKind); 1251 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind, 1252 !FirstClauses[CKind].getInt()); 1253 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, 1254 StopBeforeMatch); 1255 FirstClauses[CKind].setInt(true); 1256 if (Clause != nullptr) 1257 Clauses.push_back(Clause); 1258 if (Tok.is(tok::annot_pragma_openmp_end)) { 1259 Actions.EndOpenMPClause(); 1260 break; 1261 } 1262 // Skip ',' if any. 1263 if (Tok.is(tok::comma)) 1264 ConsumeToken(); 1265 Actions.EndOpenMPClause(); 1266 } 1267 // The last seen token is annot_pragma_openmp_end - need to check for 1268 // extra tokens. 1269 if (Tok.isNot(tok::annot_pragma_openmp_end)) { 1270 Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 1271 << getOpenMPDirectiveName(DKind); 1272 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 1273 } 1274 } 1275 // Skip the last annot_pragma_openmp_end. 1276 ConsumeAnnotationToken(); 1277 return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers(), 1278 Clauses); 1279 } 1280 break; 1281 } 1282 case OMPD_requires: { 1283 SourceLocation StartLoc = ConsumeToken(); 1284 SmallVector<OMPClause *, 5> Clauses; 1285 SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1> 1286 FirstClauses(OMPC_unknown + 1); 1287 if (Tok.is(tok::annot_pragma_openmp_end)) { 1288 Diag(Tok, diag::err_omp_expected_clause) 1289 << getOpenMPDirectiveName(OMPD_requires); 1290 break; 1291 } 1292 while (Tok.isNot(tok::annot_pragma_openmp_end)) { 1293 OpenMPClauseKind CKind = Tok.isAnnotation() 1294 ? OMPC_unknown 1295 : getOpenMPClauseKind(PP.getSpelling(Tok)); 1296 Actions.StartOpenMPClause(CKind); 1297 OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind, 1298 !FirstClauses[CKind].getInt()); 1299 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, 1300 StopBeforeMatch); 1301 FirstClauses[CKind].setInt(true); 1302 if (Clause != nullptr) 1303 Clauses.push_back(Clause); 1304 if (Tok.is(tok::annot_pragma_openmp_end)) { 1305 Actions.EndOpenMPClause(); 1306 break; 1307 } 1308 // Skip ',' if any. 1309 if (Tok.is(tok::comma)) 1310 ConsumeToken(); 1311 Actions.EndOpenMPClause(); 1312 } 1313 // Consume final annot_pragma_openmp_end 1314 if (Clauses.size() == 0) { 1315 Diag(Tok, diag::err_omp_expected_clause) 1316 << getOpenMPDirectiveName(OMPD_requires); 1317 ConsumeAnnotationToken(); 1318 return nullptr; 1319 } 1320 ConsumeAnnotationToken(); 1321 return Actions.ActOnOpenMPRequiresDirective(StartLoc, Clauses); 1322 } 1323 case OMPD_declare_reduction: 1324 ConsumeToken(); 1325 if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) { 1326 // The last seen token is annot_pragma_openmp_end - need to check for 1327 // extra tokens. 1328 if (Tok.isNot(tok::annot_pragma_openmp_end)) { 1329 Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 1330 << getOpenMPDirectiveName(OMPD_declare_reduction); 1331 while (Tok.isNot(tok::annot_pragma_openmp_end)) 1332 ConsumeAnyToken(); 1333 } 1334 // Skip the last annot_pragma_openmp_end. 1335 ConsumeAnnotationToken(); 1336 return Res; 1337 } 1338 break; 1339 case OMPD_declare_mapper: { 1340 ConsumeToken(); 1341 if (DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) { 1342 // Skip the last annot_pragma_openmp_end. 1343 ConsumeAnnotationToken(); 1344 return Res; 1345 } 1346 break; 1347 } 1348 case OMPD_declare_variant: 1349 case OMPD_declare_simd: { 1350 // The syntax is: 1351 // { #pragma omp declare {simd|variant} } 1352 // <function-declaration-or-definition> 1353 // 1354 CachedTokens Toks; 1355 Toks.push_back(Tok); 1356 ConsumeToken(); 1357 while(Tok.isNot(tok::annot_pragma_openmp_end)) { 1358 Toks.push_back(Tok); 1359 ConsumeAnyToken(); 1360 } 1361 Toks.push_back(Tok); 1362 ConsumeAnyToken(); 1363 1364 DeclGroupPtrTy Ptr; 1365 if (Tok.is(tok::annot_pragma_openmp)) { 1366 Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, TagType, Tag); 1367 } else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) { 1368 // Here we expect to see some function declaration. 1369 if (AS == AS_none) { 1370 assert(TagType == DeclSpec::TST_unspecified); 1371 MaybeParseCXX11Attributes(Attrs); 1372 ParsingDeclSpec PDS(*this); 1373 Ptr = ParseExternalDeclaration(Attrs, &PDS); 1374 } else { 1375 Ptr = 1376 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag); 1377 } 1378 } 1379 if (!Ptr) { 1380 Diag(Loc, diag::err_omp_decl_in_declare_simd_variant) 1381 << (DKind == OMPD_declare_simd ? 0 : 1); 1382 return DeclGroupPtrTy(); 1383 } 1384 if (DKind == OMPD_declare_simd) 1385 return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc); 1386 assert(DKind == OMPD_declare_variant && 1387 "Expected declare variant directive only"); 1388 ParseOMPDeclareVariantClauses(Ptr, Toks, Loc); 1389 return Ptr; 1390 } 1391 case OMPD_declare_target: { 1392 SourceLocation DTLoc = ConsumeAnyToken(); 1393 if (Tok.isNot(tok::annot_pragma_openmp_end)) { 1394 return ParseOMPDeclareTargetClauses(); 1395 } 1396 1397 // Skip the last annot_pragma_openmp_end. 1398 ConsumeAnyToken(); 1399 1400 if (!Actions.ActOnStartOpenMPDeclareTargetDirective(DTLoc)) 1401 return DeclGroupPtrTy(); 1402 1403 llvm::SmallVector<Decl *, 4> Decls; 1404 DKind = parseOpenMPDirectiveKind(*this); 1405 while (DKind != OMPD_end_declare_target && Tok.isNot(tok::eof) && 1406 Tok.isNot(tok::r_brace)) { 1407 DeclGroupPtrTy Ptr; 1408 // Here we expect to see some function declaration. 1409 if (AS == AS_none) { 1410 assert(TagType == DeclSpec::TST_unspecified); 1411 MaybeParseCXX11Attributes(Attrs); 1412 ParsingDeclSpec PDS(*this); 1413 Ptr = ParseExternalDeclaration(Attrs, &PDS); 1414 } else { 1415 Ptr = 1416 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag); 1417 } 1418 if (Ptr) { 1419 DeclGroupRef Ref = Ptr.get(); 1420 Decls.append(Ref.begin(), Ref.end()); 1421 } 1422 if (Tok.isAnnotation() && Tok.is(tok::annot_pragma_openmp)) { 1423 TentativeParsingAction TPA(*this); 1424 ConsumeAnnotationToken(); 1425 DKind = parseOpenMPDirectiveKind(*this); 1426 if (DKind != OMPD_end_declare_target) 1427 TPA.Revert(); 1428 else 1429 TPA.Commit(); 1430 } 1431 } 1432 1433 ParseOMPEndDeclareTargetDirective(DKind, DTLoc); 1434 Actions.ActOnFinishOpenMPDeclareTargetDirective(); 1435 return Actions.BuildDeclaratorGroup(Decls); 1436 } 1437 case OMPD_unknown: 1438 Diag(Tok, diag::err_omp_unknown_directive); 1439 break; 1440 case OMPD_parallel: 1441 case OMPD_simd: 1442 case OMPD_task: 1443 case OMPD_taskyield: 1444 case OMPD_barrier: 1445 case OMPD_taskwait: 1446 case OMPD_taskgroup: 1447 case OMPD_flush: 1448 case OMPD_for: 1449 case OMPD_for_simd: 1450 case OMPD_sections: 1451 case OMPD_section: 1452 case OMPD_single: 1453 case OMPD_master: 1454 case OMPD_ordered: 1455 case OMPD_critical: 1456 case OMPD_parallel_for: 1457 case OMPD_parallel_for_simd: 1458 case OMPD_parallel_sections: 1459 case OMPD_atomic: 1460 case OMPD_target: 1461 case OMPD_teams: 1462 case OMPD_cancellation_point: 1463 case OMPD_cancel: 1464 case OMPD_target_data: 1465 case OMPD_target_enter_data: 1466 case OMPD_target_exit_data: 1467 case OMPD_target_parallel: 1468 case OMPD_target_parallel_for: 1469 case OMPD_taskloop: 1470 case OMPD_taskloop_simd: 1471 case OMPD_distribute: 1472 case OMPD_end_declare_target: 1473 case OMPD_target_update: 1474 case OMPD_distribute_parallel_for: 1475 case OMPD_distribute_parallel_for_simd: 1476 case OMPD_distribute_simd: 1477 case OMPD_target_parallel_for_simd: 1478 case OMPD_target_simd: 1479 case OMPD_teams_distribute: 1480 case OMPD_teams_distribute_simd: 1481 case OMPD_teams_distribute_parallel_for_simd: 1482 case OMPD_teams_distribute_parallel_for: 1483 case OMPD_target_teams: 1484 case OMPD_target_teams_distribute: 1485 case OMPD_target_teams_distribute_parallel_for: 1486 case OMPD_target_teams_distribute_parallel_for_simd: 1487 case OMPD_target_teams_distribute_simd: 1488 Diag(Tok, diag::err_omp_unexpected_directive) 1489 << 1 << getOpenMPDirectiveName(DKind); 1490 break; 1491 } 1492 while (Tok.isNot(tok::annot_pragma_openmp_end)) 1493 ConsumeAnyToken(); 1494 ConsumeAnyToken(); 1495 return nullptr; 1496 } 1497 1498 /// Parsing of declarative or executable OpenMP directives. 1499 /// 1500 /// threadprivate-directive: 1501 /// annot_pragma_openmp 'threadprivate' simple-variable-list 1502 /// annot_pragma_openmp_end 1503 /// 1504 /// allocate-directive: 1505 /// annot_pragma_openmp 'allocate' simple-variable-list 1506 /// annot_pragma_openmp_end 1507 /// 1508 /// declare-reduction-directive: 1509 /// annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':' 1510 /// <type> {',' <type>} ':' <expression> ')' ['initializer' '(' 1511 /// ('omp_priv' '=' <expression>|<function_call>) ')'] 1512 /// annot_pragma_openmp_end 1513 /// 1514 /// declare-mapper-directive: 1515 /// annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':'] 1516 /// <type> <var> ')' [<clause>[[,] <clause>] ... ] 1517 /// annot_pragma_openmp_end 1518 /// 1519 /// executable-directive: 1520 /// annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' | 1521 /// 'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] | 1522 /// 'parallel for' | 'parallel sections' | 'task' | 'taskyield' | 1523 /// 'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' | 1524 /// 'for simd' | 'parallel for simd' | 'target' | 'target data' | 1525 /// 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' | 1526 /// 'distribute' | 'target enter data' | 'target exit data' | 1527 /// 'target parallel' | 'target parallel for' | 1528 /// 'target update' | 'distribute parallel for' | 1529 /// 'distribute paralle for simd' | 'distribute simd' | 1530 /// 'target parallel for simd' | 'target simd' | 1531 /// 'teams distribute' | 'teams distribute simd' | 1532 /// 'teams distribute parallel for simd' | 1533 /// 'teams distribute parallel for' | 'target teams' | 1534 /// 'target teams distribute' | 1535 /// 'target teams distribute parallel for' | 1536 /// 'target teams distribute parallel for simd' | 1537 /// 'target teams distribute simd' {clause} 1538 /// annot_pragma_openmp_end 1539 /// 1540 StmtResult 1541 Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) { 1542 assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!"); 1543 ParenBraceBracketBalancer BalancerRAIIObj(*this); 1544 SmallVector<OMPClause *, 5> Clauses; 1545 SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1> 1546 FirstClauses(OMPC_unknown + 1); 1547 unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope | 1548 Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope; 1549 SourceLocation Loc = ConsumeAnnotationToken(), EndLoc; 1550 OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this); 1551 OpenMPDirectiveKind CancelRegion = OMPD_unknown; 1552 // Name of critical directive. 1553 DeclarationNameInfo DirName; 1554 StmtResult Directive = StmtError(); 1555 bool HasAssociatedStatement = true; 1556 bool FlushHasClause = false; 1557 1558 switch (DKind) { 1559 case OMPD_threadprivate: { 1560 // FIXME: Should this be permitted in C++? 1561 if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) == 1562 ParsedStmtContext()) { 1563 Diag(Tok, diag::err_omp_immediate_directive) 1564 << getOpenMPDirectiveName(DKind) << 0; 1565 } 1566 ConsumeToken(); 1567 DeclDirectiveListParserHelper Helper(this, DKind); 1568 if (!ParseOpenMPSimpleVarList(DKind, Helper, 1569 /*AllowScopeSpecifier=*/false)) { 1570 // The last seen token is annot_pragma_openmp_end - need to check for 1571 // extra tokens. 1572 if (Tok.isNot(tok::annot_pragma_openmp_end)) { 1573 Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 1574 << getOpenMPDirectiveName(DKind); 1575 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 1576 } 1577 DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective( 1578 Loc, Helper.getIdentifiers()); 1579 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation()); 1580 } 1581 SkipUntil(tok::annot_pragma_openmp_end); 1582 break; 1583 } 1584 case OMPD_allocate: { 1585 // FIXME: Should this be permitted in C++? 1586 if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) == 1587 ParsedStmtContext()) { 1588 Diag(Tok, diag::err_omp_immediate_directive) 1589 << getOpenMPDirectiveName(DKind) << 0; 1590 } 1591 ConsumeToken(); 1592 DeclDirectiveListParserHelper Helper(this, DKind); 1593 if (!ParseOpenMPSimpleVarList(DKind, Helper, 1594 /*AllowScopeSpecifier=*/false)) { 1595 SmallVector<OMPClause *, 1> Clauses; 1596 if (Tok.isNot(tok::annot_pragma_openmp_end)) { 1597 SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, 1598 OMPC_unknown + 1> 1599 FirstClauses(OMPC_unknown + 1); 1600 while (Tok.isNot(tok::annot_pragma_openmp_end)) { 1601 OpenMPClauseKind CKind = 1602 Tok.isAnnotation() ? OMPC_unknown 1603 : getOpenMPClauseKind(PP.getSpelling(Tok)); 1604 Actions.StartOpenMPClause(CKind); 1605 OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind, 1606 !FirstClauses[CKind].getInt()); 1607 SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, 1608 StopBeforeMatch); 1609 FirstClauses[CKind].setInt(true); 1610 if (Clause != nullptr) 1611 Clauses.push_back(Clause); 1612 if (Tok.is(tok::annot_pragma_openmp_end)) { 1613 Actions.EndOpenMPClause(); 1614 break; 1615 } 1616 // Skip ',' if any. 1617 if (Tok.is(tok::comma)) 1618 ConsumeToken(); 1619 Actions.EndOpenMPClause(); 1620 } 1621 // The last seen token is annot_pragma_openmp_end - need to check for 1622 // extra tokens. 1623 if (Tok.isNot(tok::annot_pragma_openmp_end)) { 1624 Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 1625 << getOpenMPDirectiveName(DKind); 1626 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 1627 } 1628 } 1629 DeclGroupPtrTy Res = Actions.ActOnOpenMPAllocateDirective( 1630 Loc, Helper.getIdentifiers(), Clauses); 1631 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation()); 1632 } 1633 SkipUntil(tok::annot_pragma_openmp_end); 1634 break; 1635 } 1636 case OMPD_declare_reduction: 1637 ConsumeToken(); 1638 if (DeclGroupPtrTy Res = 1639 ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) { 1640 // The last seen token is annot_pragma_openmp_end - need to check for 1641 // extra tokens. 1642 if (Tok.isNot(tok::annot_pragma_openmp_end)) { 1643 Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 1644 << getOpenMPDirectiveName(OMPD_declare_reduction); 1645 while (Tok.isNot(tok::annot_pragma_openmp_end)) 1646 ConsumeAnyToken(); 1647 } 1648 ConsumeAnyToken(); 1649 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation()); 1650 } else { 1651 SkipUntil(tok::annot_pragma_openmp_end); 1652 } 1653 break; 1654 case OMPD_declare_mapper: { 1655 ConsumeToken(); 1656 if (DeclGroupPtrTy Res = 1657 ParseOpenMPDeclareMapperDirective(/*AS=*/AS_none)) { 1658 // Skip the last annot_pragma_openmp_end. 1659 ConsumeAnnotationToken(); 1660 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation()); 1661 } else { 1662 SkipUntil(tok::annot_pragma_openmp_end); 1663 } 1664 break; 1665 } 1666 case OMPD_flush: 1667 if (PP.LookAhead(0).is(tok::l_paren)) { 1668 FlushHasClause = true; 1669 // Push copy of the current token back to stream to properly parse 1670 // pseudo-clause OMPFlushClause. 1671 PP.EnterToken(Tok, /*IsReinject*/ true); 1672 } 1673 LLVM_FALLTHROUGH; 1674 case OMPD_taskyield: 1675 case OMPD_barrier: 1676 case OMPD_taskwait: 1677 case OMPD_cancellation_point: 1678 case OMPD_cancel: 1679 case OMPD_target_enter_data: 1680 case OMPD_target_exit_data: 1681 case OMPD_target_update: 1682 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) == 1683 ParsedStmtContext()) { 1684 Diag(Tok, diag::err_omp_immediate_directive) 1685 << getOpenMPDirectiveName(DKind) << 0; 1686 } 1687 HasAssociatedStatement = false; 1688 // Fall through for further analysis. 1689 LLVM_FALLTHROUGH; 1690 case OMPD_parallel: 1691 case OMPD_simd: 1692 case OMPD_for: 1693 case OMPD_for_simd: 1694 case OMPD_sections: 1695 case OMPD_single: 1696 case OMPD_section: 1697 case OMPD_master: 1698 case OMPD_critical: 1699 case OMPD_parallel_for: 1700 case OMPD_parallel_for_simd: 1701 case OMPD_parallel_sections: 1702 case OMPD_task: 1703 case OMPD_ordered: 1704 case OMPD_atomic: 1705 case OMPD_target: 1706 case OMPD_teams: 1707 case OMPD_taskgroup: 1708 case OMPD_target_data: 1709 case OMPD_target_parallel: 1710 case OMPD_target_parallel_for: 1711 case OMPD_taskloop: 1712 case OMPD_taskloop_simd: 1713 case OMPD_distribute: 1714 case OMPD_distribute_parallel_for: 1715 case OMPD_distribute_parallel_for_simd: 1716 case OMPD_distribute_simd: 1717 case OMPD_target_parallel_for_simd: 1718 case OMPD_target_simd: 1719 case OMPD_teams_distribute: 1720 case OMPD_teams_distribute_simd: 1721 case OMPD_teams_distribute_parallel_for_simd: 1722 case OMPD_teams_distribute_parallel_for: 1723 case OMPD_target_teams: 1724 case OMPD_target_teams_distribute: 1725 case OMPD_target_teams_distribute_parallel_for: 1726 case OMPD_target_teams_distribute_parallel_for_simd: 1727 case OMPD_target_teams_distribute_simd: { 1728 ConsumeToken(); 1729 // Parse directive name of the 'critical' directive if any. 1730 if (DKind == OMPD_critical) { 1731 BalancedDelimiterTracker T(*this, tok::l_paren, 1732 tok::annot_pragma_openmp_end); 1733 if (!T.consumeOpen()) { 1734 if (Tok.isAnyIdentifier()) { 1735 DirName = 1736 DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation()); 1737 ConsumeAnyToken(); 1738 } else { 1739 Diag(Tok, diag::err_omp_expected_identifier_for_critical); 1740 } 1741 T.consumeClose(); 1742 } 1743 } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) { 1744 CancelRegion = parseOpenMPDirectiveKind(*this); 1745 if (Tok.isNot(tok::annot_pragma_openmp_end)) 1746 ConsumeToken(); 1747 } 1748 1749 if (isOpenMPLoopDirective(DKind)) 1750 ScopeFlags |= Scope::OpenMPLoopDirectiveScope; 1751 if (isOpenMPSimdDirective(DKind)) 1752 ScopeFlags |= Scope::OpenMPSimdDirectiveScope; 1753 ParseScope OMPDirectiveScope(this, ScopeFlags); 1754 Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc); 1755 1756 while (Tok.isNot(tok::annot_pragma_openmp_end)) { 1757 OpenMPClauseKind CKind = 1758 Tok.isAnnotation() 1759 ? OMPC_unknown 1760 : FlushHasClause ? OMPC_flush 1761 : getOpenMPClauseKind(PP.getSpelling(Tok)); 1762 Actions.StartOpenMPClause(CKind); 1763 FlushHasClause = false; 1764 OMPClause *Clause = 1765 ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt()); 1766 FirstClauses[CKind].setInt(true); 1767 if (Clause) { 1768 FirstClauses[CKind].setPointer(Clause); 1769 Clauses.push_back(Clause); 1770 } 1771 1772 // Skip ',' if any. 1773 if (Tok.is(tok::comma)) 1774 ConsumeToken(); 1775 Actions.EndOpenMPClause(); 1776 } 1777 // End location of the directive. 1778 EndLoc = Tok.getLocation(); 1779 // Consume final annot_pragma_openmp_end. 1780 ConsumeAnnotationToken(); 1781 1782 // OpenMP [2.13.8, ordered Construct, Syntax] 1783 // If the depend clause is specified, the ordered construct is a stand-alone 1784 // directive. 1785 if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) { 1786 if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) == 1787 ParsedStmtContext()) { 1788 Diag(Loc, diag::err_omp_immediate_directive) 1789 << getOpenMPDirectiveName(DKind) << 1 1790 << getOpenMPClauseName(OMPC_depend); 1791 } 1792 HasAssociatedStatement = false; 1793 } 1794 1795 StmtResult AssociatedStmt; 1796 if (HasAssociatedStatement) { 1797 // The body is a block scope like in Lambdas and Blocks. 1798 Actions.ActOnOpenMPRegionStart(DKind, getCurScope()); 1799 // FIXME: We create a bogus CompoundStmt scope to hold the contents of 1800 // the captured region. Code elsewhere assumes that any FunctionScopeInfo 1801 // should have at least one compound statement scope within it. 1802 AssociatedStmt = (Sema::CompoundScopeRAII(Actions), ParseStatement()); 1803 AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses); 1804 } else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data || 1805 DKind == OMPD_target_exit_data) { 1806 Actions.ActOnOpenMPRegionStart(DKind, getCurScope()); 1807 AssociatedStmt = (Sema::CompoundScopeRAII(Actions), 1808 Actions.ActOnCompoundStmt(Loc, Loc, llvm::None, 1809 /*isStmtExpr=*/false)); 1810 AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses); 1811 } 1812 Directive = Actions.ActOnOpenMPExecutableDirective( 1813 DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc, 1814 EndLoc); 1815 1816 // Exit scope. 1817 Actions.EndOpenMPDSABlock(Directive.get()); 1818 OMPDirectiveScope.Exit(); 1819 break; 1820 } 1821 case OMPD_declare_simd: 1822 case OMPD_declare_target: 1823 case OMPD_end_declare_target: 1824 case OMPD_requires: 1825 case OMPD_declare_variant: 1826 Diag(Tok, diag::err_omp_unexpected_directive) 1827 << 1 << getOpenMPDirectiveName(DKind); 1828 SkipUntil(tok::annot_pragma_openmp_end); 1829 break; 1830 case OMPD_unknown: 1831 Diag(Tok, diag::err_omp_unknown_directive); 1832 SkipUntil(tok::annot_pragma_openmp_end); 1833 break; 1834 } 1835 return Directive; 1836 } 1837 1838 // Parses simple list: 1839 // simple-variable-list: 1840 // '(' id-expression {, id-expression} ')' 1841 // 1842 bool Parser::ParseOpenMPSimpleVarList( 1843 OpenMPDirectiveKind Kind, 1844 const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> & 1845 Callback, 1846 bool AllowScopeSpecifier) { 1847 // Parse '('. 1848 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); 1849 if (T.expectAndConsume(diag::err_expected_lparen_after, 1850 getOpenMPDirectiveName(Kind))) 1851 return true; 1852 bool IsCorrect = true; 1853 bool NoIdentIsFound = true; 1854 1855 // Read tokens while ')' or annot_pragma_openmp_end is not found. 1856 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) { 1857 CXXScopeSpec SS; 1858 UnqualifiedId Name; 1859 // Read var name. 1860 Token PrevTok = Tok; 1861 NoIdentIsFound = false; 1862 1863 if (AllowScopeSpecifier && getLangOpts().CPlusPlus && 1864 ParseOptionalCXXScopeSpecifier(SS, nullptr, false)) { 1865 IsCorrect = false; 1866 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, 1867 StopBeforeMatch); 1868 } else if (ParseUnqualifiedId(SS, false, false, false, false, nullptr, 1869 nullptr, Name)) { 1870 IsCorrect = false; 1871 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, 1872 StopBeforeMatch); 1873 } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) && 1874 Tok.isNot(tok::annot_pragma_openmp_end)) { 1875 IsCorrect = false; 1876 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, 1877 StopBeforeMatch); 1878 Diag(PrevTok.getLocation(), diag::err_expected) 1879 << tok::identifier 1880 << SourceRange(PrevTok.getLocation(), PrevTokLocation); 1881 } else { 1882 Callback(SS, Actions.GetNameFromUnqualifiedId(Name)); 1883 } 1884 // Consume ','. 1885 if (Tok.is(tok::comma)) { 1886 ConsumeToken(); 1887 } 1888 } 1889 1890 if (NoIdentIsFound) { 1891 Diag(Tok, diag::err_expected) << tok::identifier; 1892 IsCorrect = false; 1893 } 1894 1895 // Parse ')'. 1896 IsCorrect = !T.consumeClose() && IsCorrect; 1897 1898 return !IsCorrect; 1899 } 1900 1901 /// Parsing of OpenMP clauses. 1902 /// 1903 /// clause: 1904 /// if-clause | final-clause | num_threads-clause | safelen-clause | 1905 /// default-clause | private-clause | firstprivate-clause | shared-clause 1906 /// | linear-clause | aligned-clause | collapse-clause | 1907 /// lastprivate-clause | reduction-clause | proc_bind-clause | 1908 /// schedule-clause | copyin-clause | copyprivate-clause | untied-clause | 1909 /// mergeable-clause | flush-clause | read-clause | write-clause | 1910 /// update-clause | capture-clause | seq_cst-clause | device-clause | 1911 /// simdlen-clause | threads-clause | simd-clause | num_teams-clause | 1912 /// thread_limit-clause | priority-clause | grainsize-clause | 1913 /// nogroup-clause | num_tasks-clause | hint-clause | to-clause | 1914 /// from-clause | is_device_ptr-clause | task_reduction-clause | 1915 /// in_reduction-clause | allocator-clause | allocate-clause 1916 /// 1917 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, 1918 OpenMPClauseKind CKind, bool FirstClause) { 1919 OMPClause *Clause = nullptr; 1920 bool ErrorFound = false; 1921 bool WrongDirective = false; 1922 // Check if clause is allowed for the given directive. 1923 if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) { 1924 Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind) 1925 << getOpenMPDirectiveName(DKind); 1926 ErrorFound = true; 1927 WrongDirective = true; 1928 } 1929 1930 switch (CKind) { 1931 case OMPC_final: 1932 case OMPC_num_threads: 1933 case OMPC_safelen: 1934 case OMPC_simdlen: 1935 case OMPC_collapse: 1936 case OMPC_ordered: 1937 case OMPC_device: 1938 case OMPC_num_teams: 1939 case OMPC_thread_limit: 1940 case OMPC_priority: 1941 case OMPC_grainsize: 1942 case OMPC_num_tasks: 1943 case OMPC_hint: 1944 case OMPC_allocator: 1945 // OpenMP [2.5, Restrictions] 1946 // At most one num_threads clause can appear on the directive. 1947 // OpenMP [2.8.1, simd construct, Restrictions] 1948 // Only one safelen clause can appear on a simd directive. 1949 // Only one simdlen clause can appear on a simd directive. 1950 // Only one collapse clause can appear on a simd directive. 1951 // OpenMP [2.9.1, target data construct, Restrictions] 1952 // At most one device clause can appear on the directive. 1953 // OpenMP [2.11.1, task Construct, Restrictions] 1954 // At most one if clause can appear on the directive. 1955 // At most one final clause can appear on the directive. 1956 // OpenMP [teams Construct, Restrictions] 1957 // At most one num_teams clause can appear on the directive. 1958 // At most one thread_limit clause can appear on the directive. 1959 // OpenMP [2.9.1, task Construct, Restrictions] 1960 // At most one priority clause can appear on the directive. 1961 // OpenMP [2.9.2, taskloop Construct, Restrictions] 1962 // At most one grainsize clause can appear on the directive. 1963 // OpenMP [2.9.2, taskloop Construct, Restrictions] 1964 // At most one num_tasks clause can appear on the directive. 1965 // OpenMP [2.11.3, allocate Directive, Restrictions] 1966 // At most one allocator clause can appear on the directive. 1967 if (!FirstClause) { 1968 Diag(Tok, diag::err_omp_more_one_clause) 1969 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; 1970 ErrorFound = true; 1971 } 1972 1973 if (CKind == OMPC_ordered && PP.LookAhead(/*N=*/0).isNot(tok::l_paren)) 1974 Clause = ParseOpenMPClause(CKind, WrongDirective); 1975 else 1976 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective); 1977 break; 1978 case OMPC_default: 1979 case OMPC_proc_bind: 1980 case OMPC_atomic_default_mem_order: 1981 // OpenMP [2.14.3.1, Restrictions] 1982 // Only a single default clause may be specified on a parallel, task or 1983 // teams directive. 1984 // OpenMP [2.5, parallel Construct, Restrictions] 1985 // At most one proc_bind clause can appear on the directive. 1986 // OpenMP [5.0, Requires directive, Restrictions] 1987 // At most one atomic_default_mem_order clause can appear 1988 // on the directive 1989 if (!FirstClause) { 1990 Diag(Tok, diag::err_omp_more_one_clause) 1991 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; 1992 ErrorFound = true; 1993 } 1994 1995 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective); 1996 break; 1997 case OMPC_schedule: 1998 case OMPC_dist_schedule: 1999 case OMPC_defaultmap: 2000 // OpenMP [2.7.1, Restrictions, p. 3] 2001 // Only one schedule clause can appear on a loop directive. 2002 // OpenMP [2.10.4, Restrictions, p. 106] 2003 // At most one defaultmap clause can appear on the directive. 2004 if (!FirstClause) { 2005 Diag(Tok, diag::err_omp_more_one_clause) 2006 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; 2007 ErrorFound = true; 2008 } 2009 LLVM_FALLTHROUGH; 2010 2011 case OMPC_if: 2012 Clause = ParseOpenMPSingleExprWithArgClause(CKind, WrongDirective); 2013 break; 2014 case OMPC_nowait: 2015 case OMPC_untied: 2016 case OMPC_mergeable: 2017 case OMPC_read: 2018 case OMPC_write: 2019 case OMPC_update: 2020 case OMPC_capture: 2021 case OMPC_seq_cst: 2022 case OMPC_threads: 2023 case OMPC_simd: 2024 case OMPC_nogroup: 2025 case OMPC_unified_address: 2026 case OMPC_unified_shared_memory: 2027 case OMPC_reverse_offload: 2028 case OMPC_dynamic_allocators: 2029 // OpenMP [2.7.1, Restrictions, p. 9] 2030 // Only one ordered clause can appear on a loop directive. 2031 // OpenMP [2.7.1, Restrictions, C/C++, p. 4] 2032 // Only one nowait clause can appear on a for directive. 2033 // OpenMP [5.0, Requires directive, Restrictions] 2034 // Each of the requires clauses can appear at most once on the directive. 2035 if (!FirstClause) { 2036 Diag(Tok, diag::err_omp_more_one_clause) 2037 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; 2038 ErrorFound = true; 2039 } 2040 2041 Clause = ParseOpenMPClause(CKind, WrongDirective); 2042 break; 2043 case OMPC_private: 2044 case OMPC_firstprivate: 2045 case OMPC_lastprivate: 2046 case OMPC_shared: 2047 case OMPC_reduction: 2048 case OMPC_task_reduction: 2049 case OMPC_in_reduction: 2050 case OMPC_linear: 2051 case OMPC_aligned: 2052 case OMPC_copyin: 2053 case OMPC_copyprivate: 2054 case OMPC_flush: 2055 case OMPC_depend: 2056 case OMPC_map: 2057 case OMPC_to: 2058 case OMPC_from: 2059 case OMPC_use_device_ptr: 2060 case OMPC_is_device_ptr: 2061 case OMPC_allocate: 2062 Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective); 2063 break; 2064 case OMPC_device_type: 2065 case OMPC_unknown: 2066 Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 2067 << getOpenMPDirectiveName(DKind); 2068 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 2069 break; 2070 case OMPC_threadprivate: 2071 case OMPC_uniform: 2072 case OMPC_match: 2073 if (!WrongDirective) 2074 Diag(Tok, diag::err_omp_unexpected_clause) 2075 << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind); 2076 SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch); 2077 break; 2078 } 2079 return ErrorFound ? nullptr : Clause; 2080 } 2081 2082 /// Parses simple expression in parens for single-expression clauses of OpenMP 2083 /// constructs. 2084 /// \param RLoc Returned location of right paren. 2085 ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName, 2086 SourceLocation &RLoc, 2087 bool IsAddressOfOperand) { 2088 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); 2089 if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data())) 2090 return ExprError(); 2091 2092 SourceLocation ELoc = Tok.getLocation(); 2093 ExprResult LHS(ParseCastExpression( 2094 /*isUnaryExpression=*/false, IsAddressOfOperand, NotTypeCast)); 2095 ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional)); 2096 Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false); 2097 2098 // Parse ')'. 2099 RLoc = Tok.getLocation(); 2100 if (!T.consumeClose()) 2101 RLoc = T.getCloseLocation(); 2102 2103 return Val; 2104 } 2105 2106 /// Parsing of OpenMP clauses with single expressions like 'final', 2107 /// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams', 2108 /// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks' or 'hint'. 2109 /// 2110 /// final-clause: 2111 /// 'final' '(' expression ')' 2112 /// 2113 /// num_threads-clause: 2114 /// 'num_threads' '(' expression ')' 2115 /// 2116 /// safelen-clause: 2117 /// 'safelen' '(' expression ')' 2118 /// 2119 /// simdlen-clause: 2120 /// 'simdlen' '(' expression ')' 2121 /// 2122 /// collapse-clause: 2123 /// 'collapse' '(' expression ')' 2124 /// 2125 /// priority-clause: 2126 /// 'priority' '(' expression ')' 2127 /// 2128 /// grainsize-clause: 2129 /// 'grainsize' '(' expression ')' 2130 /// 2131 /// num_tasks-clause: 2132 /// 'num_tasks' '(' expression ')' 2133 /// 2134 /// hint-clause: 2135 /// 'hint' '(' expression ')' 2136 /// 2137 /// allocator-clause: 2138 /// 'allocator' '(' expression ')' 2139 /// 2140 OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind, 2141 bool ParseOnly) { 2142 SourceLocation Loc = ConsumeToken(); 2143 SourceLocation LLoc = Tok.getLocation(); 2144 SourceLocation RLoc; 2145 2146 ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc); 2147 2148 if (Val.isInvalid()) 2149 return nullptr; 2150 2151 if (ParseOnly) 2152 return nullptr; 2153 return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc); 2154 } 2155 2156 /// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'. 2157 /// 2158 /// default-clause: 2159 /// 'default' '(' 'none' | 'shared' ') 2160 /// 2161 /// proc_bind-clause: 2162 /// 'proc_bind' '(' 'master' | 'close' | 'spread' ') 2163 /// 2164 OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind, 2165 bool ParseOnly) { 2166 llvm::Optional<SimpleClauseData> Val = parseOpenMPSimpleClause(*this, Kind); 2167 if (!Val || ParseOnly) 2168 return nullptr; 2169 return Actions.ActOnOpenMPSimpleClause( 2170 Kind, Val.getValue().Type, Val.getValue().TypeLoc, Val.getValue().LOpen, 2171 Val.getValue().Loc, Val.getValue().RLoc); 2172 } 2173 2174 /// Parsing of OpenMP clauses like 'ordered'. 2175 /// 2176 /// ordered-clause: 2177 /// 'ordered' 2178 /// 2179 /// nowait-clause: 2180 /// 'nowait' 2181 /// 2182 /// untied-clause: 2183 /// 'untied' 2184 /// 2185 /// mergeable-clause: 2186 /// 'mergeable' 2187 /// 2188 /// read-clause: 2189 /// 'read' 2190 /// 2191 /// threads-clause: 2192 /// 'threads' 2193 /// 2194 /// simd-clause: 2195 /// 'simd' 2196 /// 2197 /// nogroup-clause: 2198 /// 'nogroup' 2199 /// 2200 OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly) { 2201 SourceLocation Loc = Tok.getLocation(); 2202 ConsumeAnyToken(); 2203 2204 if (ParseOnly) 2205 return nullptr; 2206 return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation()); 2207 } 2208 2209 2210 /// Parsing of OpenMP clauses with single expressions and some additional 2211 /// argument like 'schedule' or 'dist_schedule'. 2212 /// 2213 /// schedule-clause: 2214 /// 'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ] 2215 /// ')' 2216 /// 2217 /// if-clause: 2218 /// 'if' '(' [ directive-name-modifier ':' ] expression ')' 2219 /// 2220 /// defaultmap: 2221 /// 'defaultmap' '(' modifier ':' kind ')' 2222 /// 2223 OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, 2224 bool ParseOnly) { 2225 SourceLocation Loc = ConsumeToken(); 2226 SourceLocation DelimLoc; 2227 // Parse '('. 2228 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); 2229 if (T.expectAndConsume(diag::err_expected_lparen_after, 2230 getOpenMPClauseName(Kind))) 2231 return nullptr; 2232 2233 ExprResult Val; 2234 SmallVector<unsigned, 4> Arg; 2235 SmallVector<SourceLocation, 4> KLoc; 2236 if (Kind == OMPC_schedule) { 2237 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 2238 Arg.resize(NumberOfElements); 2239 KLoc.resize(NumberOfElements); 2240 Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown; 2241 Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown; 2242 Arg[ScheduleKind] = OMPC_SCHEDULE_unknown; 2243 unsigned KindModifier = getOpenMPSimpleClauseType( 2244 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)); 2245 if (KindModifier > OMPC_SCHEDULE_unknown) { 2246 // Parse 'modifier' 2247 Arg[Modifier1] = KindModifier; 2248 KLoc[Modifier1] = Tok.getLocation(); 2249 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && 2250 Tok.isNot(tok::annot_pragma_openmp_end)) 2251 ConsumeAnyToken(); 2252 if (Tok.is(tok::comma)) { 2253 // Parse ',' 'modifier' 2254 ConsumeAnyToken(); 2255 KindModifier = getOpenMPSimpleClauseType( 2256 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)); 2257 Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown 2258 ? KindModifier 2259 : (unsigned)OMPC_SCHEDULE_unknown; 2260 KLoc[Modifier2] = Tok.getLocation(); 2261 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && 2262 Tok.isNot(tok::annot_pragma_openmp_end)) 2263 ConsumeAnyToken(); 2264 } 2265 // Parse ':' 2266 if (Tok.is(tok::colon)) 2267 ConsumeAnyToken(); 2268 else 2269 Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier"; 2270 KindModifier = getOpenMPSimpleClauseType( 2271 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)); 2272 } 2273 Arg[ScheduleKind] = KindModifier; 2274 KLoc[ScheduleKind] = Tok.getLocation(); 2275 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && 2276 Tok.isNot(tok::annot_pragma_openmp_end)) 2277 ConsumeAnyToken(); 2278 if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static || 2279 Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic || 2280 Arg[ScheduleKind] == OMPC_SCHEDULE_guided) && 2281 Tok.is(tok::comma)) 2282 DelimLoc = ConsumeAnyToken(); 2283 } else if (Kind == OMPC_dist_schedule) { 2284 Arg.push_back(getOpenMPSimpleClauseType( 2285 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok))); 2286 KLoc.push_back(Tok.getLocation()); 2287 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && 2288 Tok.isNot(tok::annot_pragma_openmp_end)) 2289 ConsumeAnyToken(); 2290 if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma)) 2291 DelimLoc = ConsumeAnyToken(); 2292 } else if (Kind == OMPC_defaultmap) { 2293 // Get a defaultmap modifier 2294 Arg.push_back(getOpenMPSimpleClauseType( 2295 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok))); 2296 KLoc.push_back(Tok.getLocation()); 2297 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && 2298 Tok.isNot(tok::annot_pragma_openmp_end)) 2299 ConsumeAnyToken(); 2300 // Parse ':' 2301 if (Tok.is(tok::colon)) 2302 ConsumeAnyToken(); 2303 else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown) 2304 Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier"; 2305 // Get a defaultmap kind 2306 Arg.push_back(getOpenMPSimpleClauseType( 2307 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok))); 2308 KLoc.push_back(Tok.getLocation()); 2309 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && 2310 Tok.isNot(tok::annot_pragma_openmp_end)) 2311 ConsumeAnyToken(); 2312 } else { 2313 assert(Kind == OMPC_if); 2314 KLoc.push_back(Tok.getLocation()); 2315 TentativeParsingAction TPA(*this); 2316 Arg.push_back(parseOpenMPDirectiveKind(*this)); 2317 if (Arg.back() != OMPD_unknown) { 2318 ConsumeToken(); 2319 if (Tok.is(tok::colon) && getLangOpts().OpenMP > 40) { 2320 TPA.Commit(); 2321 DelimLoc = ConsumeToken(); 2322 } else { 2323 TPA.Revert(); 2324 Arg.back() = OMPD_unknown; 2325 } 2326 } else { 2327 TPA.Revert(); 2328 } 2329 } 2330 2331 bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) || 2332 (Kind == OMPC_dist_schedule && DelimLoc.isValid()) || 2333 Kind == OMPC_if; 2334 if (NeedAnExpression) { 2335 SourceLocation ELoc = Tok.getLocation(); 2336 ExprResult LHS(ParseCastExpression(false, false, NotTypeCast)); 2337 Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional); 2338 Val = 2339 Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false); 2340 } 2341 2342 // Parse ')'. 2343 SourceLocation RLoc = Tok.getLocation(); 2344 if (!T.consumeClose()) 2345 RLoc = T.getCloseLocation(); 2346 2347 if (NeedAnExpression && Val.isInvalid()) 2348 return nullptr; 2349 2350 if (ParseOnly) 2351 return nullptr; 2352 return Actions.ActOnOpenMPSingleExprWithArgClause( 2353 Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc); 2354 } 2355 2356 static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec, 2357 UnqualifiedId &ReductionId) { 2358 if (ReductionIdScopeSpec.isEmpty()) { 2359 auto OOK = OO_None; 2360 switch (P.getCurToken().getKind()) { 2361 case tok::plus: 2362 OOK = OO_Plus; 2363 break; 2364 case tok::minus: 2365 OOK = OO_Minus; 2366 break; 2367 case tok::star: 2368 OOK = OO_Star; 2369 break; 2370 case tok::amp: 2371 OOK = OO_Amp; 2372 break; 2373 case tok::pipe: 2374 OOK = OO_Pipe; 2375 break; 2376 case tok::caret: 2377 OOK = OO_Caret; 2378 break; 2379 case tok::ampamp: 2380 OOK = OO_AmpAmp; 2381 break; 2382 case tok::pipepipe: 2383 OOK = OO_PipePipe; 2384 break; 2385 default: 2386 break; 2387 } 2388 if (OOK != OO_None) { 2389 SourceLocation OpLoc = P.ConsumeToken(); 2390 SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()}; 2391 ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations); 2392 return false; 2393 } 2394 } 2395 return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false, 2396 /*AllowDestructorName*/ false, 2397 /*AllowConstructorName*/ false, 2398 /*AllowDeductionGuide*/ false, 2399 nullptr, nullptr, ReductionId); 2400 } 2401 2402 /// Checks if the token is a valid map-type-modifier. 2403 static OpenMPMapModifierKind isMapModifier(Parser &P) { 2404 Token Tok = P.getCurToken(); 2405 if (!Tok.is(tok::identifier)) 2406 return OMPC_MAP_MODIFIER_unknown; 2407 2408 Preprocessor &PP = P.getPreprocessor(); 2409 OpenMPMapModifierKind TypeModifier = static_cast<OpenMPMapModifierKind>( 2410 getOpenMPSimpleClauseType(OMPC_map, PP.getSpelling(Tok))); 2411 return TypeModifier; 2412 } 2413 2414 /// Parse the mapper modifier in map, to, and from clauses. 2415 bool Parser::parseMapperModifier(OpenMPVarListDataTy &Data) { 2416 // Parse '('. 2417 BalancedDelimiterTracker T(*this, tok::l_paren, tok::colon); 2418 if (T.expectAndConsume(diag::err_expected_lparen_after, "mapper")) { 2419 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end, 2420 StopBeforeMatch); 2421 return true; 2422 } 2423 // Parse mapper-identifier 2424 if (getLangOpts().CPlusPlus) 2425 ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec, 2426 /*ObjectType=*/nullptr, 2427 /*EnteringContext=*/false); 2428 if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) { 2429 Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier); 2430 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end, 2431 StopBeforeMatch); 2432 return true; 2433 } 2434 auto &DeclNames = Actions.getASTContext().DeclarationNames; 2435 Data.ReductionOrMapperId = DeclarationNameInfo( 2436 DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation()); 2437 ConsumeToken(); 2438 // Parse ')'. 2439 return T.consumeClose(); 2440 } 2441 2442 /// Parse map-type-modifiers in map clause. 2443 /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list) 2444 /// where, map-type-modifier ::= always | close | mapper(mapper-identifier) 2445 bool Parser::parseMapTypeModifiers(OpenMPVarListDataTy &Data) { 2446 while (getCurToken().isNot(tok::colon)) { 2447 OpenMPMapModifierKind TypeModifier = isMapModifier(*this); 2448 if (TypeModifier == OMPC_MAP_MODIFIER_always || 2449 TypeModifier == OMPC_MAP_MODIFIER_close) { 2450 Data.MapTypeModifiers.push_back(TypeModifier); 2451 Data.MapTypeModifiersLoc.push_back(Tok.getLocation()); 2452 ConsumeToken(); 2453 } else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) { 2454 Data.MapTypeModifiers.push_back(TypeModifier); 2455 Data.MapTypeModifiersLoc.push_back(Tok.getLocation()); 2456 ConsumeToken(); 2457 if (parseMapperModifier(Data)) 2458 return true; 2459 } else { 2460 // For the case of unknown map-type-modifier or a map-type. 2461 // Map-type is followed by a colon; the function returns when it 2462 // encounters a token followed by a colon. 2463 if (Tok.is(tok::comma)) { 2464 Diag(Tok, diag::err_omp_map_type_modifier_missing); 2465 ConsumeToken(); 2466 continue; 2467 } 2468 // Potential map-type token as it is followed by a colon. 2469 if (PP.LookAhead(0).is(tok::colon)) 2470 return false; 2471 Diag(Tok, diag::err_omp_unknown_map_type_modifier); 2472 ConsumeToken(); 2473 } 2474 if (getCurToken().is(tok::comma)) 2475 ConsumeToken(); 2476 } 2477 return false; 2478 } 2479 2480 /// Checks if the token is a valid map-type. 2481 static OpenMPMapClauseKind isMapType(Parser &P) { 2482 Token Tok = P.getCurToken(); 2483 // The map-type token can be either an identifier or the C++ delete keyword. 2484 if (!Tok.isOneOf(tok::identifier, tok::kw_delete)) 2485 return OMPC_MAP_unknown; 2486 Preprocessor &PP = P.getPreprocessor(); 2487 OpenMPMapClauseKind MapType = static_cast<OpenMPMapClauseKind>( 2488 getOpenMPSimpleClauseType(OMPC_map, PP.getSpelling(Tok))); 2489 return MapType; 2490 } 2491 2492 /// Parse map-type in map clause. 2493 /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list) 2494 /// where, map-type ::= to | from | tofrom | alloc | release | delete 2495 static void parseMapType(Parser &P, Parser::OpenMPVarListDataTy &Data) { 2496 Token Tok = P.getCurToken(); 2497 if (Tok.is(tok::colon)) { 2498 P.Diag(Tok, diag::err_omp_map_type_missing); 2499 return; 2500 } 2501 Data.MapType = isMapType(P); 2502 if (Data.MapType == OMPC_MAP_unknown) 2503 P.Diag(Tok, diag::err_omp_unknown_map_type); 2504 P.ConsumeToken(); 2505 } 2506 2507 /// Parses clauses with list. 2508 bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, 2509 OpenMPClauseKind Kind, 2510 SmallVectorImpl<Expr *> &Vars, 2511 OpenMPVarListDataTy &Data) { 2512 UnqualifiedId UnqualifiedReductionId; 2513 bool InvalidReductionId = false; 2514 bool IsInvalidMapperModifier = false; 2515 2516 // Parse '('. 2517 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); 2518 if (T.expectAndConsume(diag::err_expected_lparen_after, 2519 getOpenMPClauseName(Kind))) 2520 return true; 2521 2522 bool NeedRParenForLinear = false; 2523 BalancedDelimiterTracker LinearT(*this, tok::l_paren, 2524 tok::annot_pragma_openmp_end); 2525 // Handle reduction-identifier for reduction clause. 2526 if (Kind == OMPC_reduction || Kind == OMPC_task_reduction || 2527 Kind == OMPC_in_reduction) { 2528 ColonProtectionRAIIObject ColonRAII(*this); 2529 if (getLangOpts().CPlusPlus) 2530 ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec, 2531 /*ObjectType=*/nullptr, 2532 /*EnteringContext=*/false); 2533 InvalidReductionId = ParseReductionId( 2534 *this, Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId); 2535 if (InvalidReductionId) { 2536 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end, 2537 StopBeforeMatch); 2538 } 2539 if (Tok.is(tok::colon)) 2540 Data.ColonLoc = ConsumeToken(); 2541 else 2542 Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier"; 2543 if (!InvalidReductionId) 2544 Data.ReductionOrMapperId = 2545 Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId); 2546 } else if (Kind == OMPC_depend) { 2547 // Handle dependency type for depend clause. 2548 ColonProtectionRAIIObject ColonRAII(*this); 2549 Data.DepKind = 2550 static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType( 2551 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : "")); 2552 Data.DepLinMapLoc = Tok.getLocation(); 2553 2554 if (Data.DepKind == OMPC_DEPEND_unknown) { 2555 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end, 2556 StopBeforeMatch); 2557 } else { 2558 ConsumeToken(); 2559 // Special processing for depend(source) clause. 2560 if (DKind == OMPD_ordered && Data.DepKind == OMPC_DEPEND_source) { 2561 // Parse ')'. 2562 T.consumeClose(); 2563 return false; 2564 } 2565 } 2566 if (Tok.is(tok::colon)) { 2567 Data.ColonLoc = ConsumeToken(); 2568 } else { 2569 Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren 2570 : diag::warn_pragma_expected_colon) 2571 << "dependency type"; 2572 } 2573 } else if (Kind == OMPC_linear) { 2574 // Try to parse modifier if any. 2575 if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) { 2576 Data.LinKind = static_cast<OpenMPLinearClauseKind>( 2577 getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))); 2578 Data.DepLinMapLoc = ConsumeToken(); 2579 LinearT.consumeOpen(); 2580 NeedRParenForLinear = true; 2581 } 2582 } else if (Kind == OMPC_map) { 2583 // Handle map type for map clause. 2584 ColonProtectionRAIIObject ColonRAII(*this); 2585 2586 // The first identifier may be a list item, a map-type or a 2587 // map-type-modifier. The map-type can also be delete which has the same 2588 // spelling of the C++ delete keyword. 2589 Data.DepLinMapLoc = Tok.getLocation(); 2590 2591 // Check for presence of a colon in the map clause. 2592 TentativeParsingAction TPA(*this); 2593 bool ColonPresent = false; 2594 if (SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end, 2595 StopBeforeMatch)) { 2596 if (Tok.is(tok::colon)) 2597 ColonPresent = true; 2598 } 2599 TPA.Revert(); 2600 // Only parse map-type-modifier[s] and map-type if a colon is present in 2601 // the map clause. 2602 if (ColonPresent) { 2603 IsInvalidMapperModifier = parseMapTypeModifiers(Data); 2604 if (!IsInvalidMapperModifier) 2605 parseMapType(*this, Data); 2606 else 2607 SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch); 2608 } 2609 if (Data.MapType == OMPC_MAP_unknown) { 2610 Data.MapType = OMPC_MAP_tofrom; 2611 Data.IsMapTypeImplicit = true; 2612 } 2613 2614 if (Tok.is(tok::colon)) 2615 Data.ColonLoc = ConsumeToken(); 2616 } else if (Kind == OMPC_to || Kind == OMPC_from) { 2617 if (Tok.is(tok::identifier)) { 2618 bool IsMapperModifier = false; 2619 if (Kind == OMPC_to) { 2620 auto Modifier = static_cast<OpenMPToModifierKind>( 2621 getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))); 2622 if (Modifier == OMPC_TO_MODIFIER_mapper) 2623 IsMapperModifier = true; 2624 } else { 2625 auto Modifier = static_cast<OpenMPFromModifierKind>( 2626 getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))); 2627 if (Modifier == OMPC_FROM_MODIFIER_mapper) 2628 IsMapperModifier = true; 2629 } 2630 if (IsMapperModifier) { 2631 // Parse the mapper modifier. 2632 ConsumeToken(); 2633 IsInvalidMapperModifier = parseMapperModifier(Data); 2634 if (Tok.isNot(tok::colon)) { 2635 if (!IsInvalidMapperModifier) 2636 Diag(Tok, diag::warn_pragma_expected_colon) << ")"; 2637 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end, 2638 StopBeforeMatch); 2639 } 2640 // Consume ':'. 2641 if (Tok.is(tok::colon)) 2642 ConsumeToken(); 2643 } 2644 } 2645 } else if (Kind == OMPC_allocate) { 2646 // Handle optional allocator expression followed by colon delimiter. 2647 ColonProtectionRAIIObject ColonRAII(*this); 2648 TentativeParsingAction TPA(*this); 2649 ExprResult Tail = 2650 Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); 2651 Tail = Actions.ActOnFinishFullExpr(Tail.get(), T.getOpenLocation(), 2652 /*DiscardedValue=*/false); 2653 if (Tail.isUsable()) { 2654 if (Tok.is(tok::colon)) { 2655 Data.TailExpr = Tail.get(); 2656 Data.ColonLoc = ConsumeToken(); 2657 TPA.Commit(); 2658 } else { 2659 // colon not found, no allocator specified, parse only list of 2660 // variables. 2661 TPA.Revert(); 2662 } 2663 } else { 2664 // Parsing was unsuccessfull, revert and skip to the end of clause or 2665 // directive. 2666 TPA.Revert(); 2667 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, 2668 StopBeforeMatch); 2669 } 2670 } 2671 2672 bool IsComma = 2673 (Kind != OMPC_reduction && Kind != OMPC_task_reduction && 2674 Kind != OMPC_in_reduction && Kind != OMPC_depend && Kind != OMPC_map) || 2675 (Kind == OMPC_reduction && !InvalidReductionId) || 2676 (Kind == OMPC_map && Data.MapType != OMPC_MAP_unknown) || 2677 (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown); 2678 const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned); 2679 while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) && 2680 Tok.isNot(tok::annot_pragma_openmp_end))) { 2681 ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail); 2682 // Parse variable 2683 ExprResult VarExpr = 2684 Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); 2685 if (VarExpr.isUsable()) { 2686 Vars.push_back(VarExpr.get()); 2687 } else { 2688 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, 2689 StopBeforeMatch); 2690 } 2691 // Skip ',' if any 2692 IsComma = Tok.is(tok::comma); 2693 if (IsComma) 2694 ConsumeToken(); 2695 else if (Tok.isNot(tok::r_paren) && 2696 Tok.isNot(tok::annot_pragma_openmp_end) && 2697 (!MayHaveTail || Tok.isNot(tok::colon))) 2698 Diag(Tok, diag::err_omp_expected_punc) 2699 << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush) 2700 : getOpenMPClauseName(Kind)) 2701 << (Kind == OMPC_flush); 2702 } 2703 2704 // Parse ')' for linear clause with modifier. 2705 if (NeedRParenForLinear) 2706 LinearT.consumeClose(); 2707 2708 // Parse ':' linear-step (or ':' alignment). 2709 const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon); 2710 if (MustHaveTail) { 2711 Data.ColonLoc = Tok.getLocation(); 2712 SourceLocation ELoc = ConsumeToken(); 2713 ExprResult Tail = ParseAssignmentExpression(); 2714 Tail = 2715 Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false); 2716 if (Tail.isUsable()) 2717 Data.TailExpr = Tail.get(); 2718 else 2719 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, 2720 StopBeforeMatch); 2721 } 2722 2723 // Parse ')'. 2724 Data.RLoc = Tok.getLocation(); 2725 if (!T.consumeClose()) 2726 Data.RLoc = T.getCloseLocation(); 2727 return (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown && 2728 Vars.empty()) || 2729 (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) || 2730 (MustHaveTail && !Data.TailExpr) || InvalidReductionId || 2731 IsInvalidMapperModifier; 2732 } 2733 2734 /// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate', 2735 /// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction' or 2736 /// 'in_reduction'. 2737 /// 2738 /// private-clause: 2739 /// 'private' '(' list ')' 2740 /// firstprivate-clause: 2741 /// 'firstprivate' '(' list ')' 2742 /// lastprivate-clause: 2743 /// 'lastprivate' '(' list ')' 2744 /// shared-clause: 2745 /// 'shared' '(' list ')' 2746 /// linear-clause: 2747 /// 'linear' '(' linear-list [ ':' linear-step ] ')' 2748 /// aligned-clause: 2749 /// 'aligned' '(' list [ ':' alignment ] ')' 2750 /// reduction-clause: 2751 /// 'reduction' '(' reduction-identifier ':' list ')' 2752 /// task_reduction-clause: 2753 /// 'task_reduction' '(' reduction-identifier ':' list ')' 2754 /// in_reduction-clause: 2755 /// 'in_reduction' '(' reduction-identifier ':' list ')' 2756 /// copyprivate-clause: 2757 /// 'copyprivate' '(' list ')' 2758 /// flush-clause: 2759 /// 'flush' '(' list ')' 2760 /// depend-clause: 2761 /// 'depend' '(' in | out | inout : list | source ')' 2762 /// map-clause: 2763 /// 'map' '(' [ [ always [,] ] [ close [,] ] 2764 /// [ mapper '(' mapper-identifier ')' [,] ] 2765 /// to | from | tofrom | alloc | release | delete ':' ] list ')'; 2766 /// to-clause: 2767 /// 'to' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')' 2768 /// from-clause: 2769 /// 'from' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')' 2770 /// use_device_ptr-clause: 2771 /// 'use_device_ptr' '(' list ')' 2772 /// is_device_ptr-clause: 2773 /// 'is_device_ptr' '(' list ')' 2774 /// allocate-clause: 2775 /// 'allocate' '(' [ allocator ':' ] list ')' 2776 /// 2777 /// For 'linear' clause linear-list may have the following forms: 2778 /// list 2779 /// modifier(list) 2780 /// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++). 2781 OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind, 2782 OpenMPClauseKind Kind, 2783 bool ParseOnly) { 2784 SourceLocation Loc = Tok.getLocation(); 2785 SourceLocation LOpen = ConsumeToken(); 2786 SmallVector<Expr *, 4> Vars; 2787 OpenMPVarListDataTy Data; 2788 2789 if (ParseOpenMPVarList(DKind, Kind, Vars, Data)) 2790 return nullptr; 2791 2792 if (ParseOnly) 2793 return nullptr; 2794 OMPVarListLocTy Locs(Loc, LOpen, Data.RLoc); 2795 return Actions.ActOnOpenMPVarListClause( 2796 Kind, Vars, Data.TailExpr, Locs, Data.ColonLoc, 2797 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId, Data.DepKind, 2798 Data.LinKind, Data.MapTypeModifiers, Data.MapTypeModifiersLoc, 2799 Data.MapType, Data.IsMapTypeImplicit, Data.DepLinMapLoc); 2800 } 2801 2802