1 //===--- ParseOpenMP.cpp - OpenMP directives parsing ----------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// \file 10 /// \brief This file implements parsing of all OpenMP directives and clauses. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/AST/ASTContext.h" 15 #include "clang/AST/StmtOpenMP.h" 16 #include "clang/Parse/ParseDiagnostic.h" 17 #include "clang/Parse/Parser.h" 18 #include "clang/Parse/RAIIObjectsForParser.h" 19 #include "clang/Sema/Scope.h" 20 #include "llvm/ADT/PointerIntPair.h" 21 22 using namespace clang; 23 24 //===----------------------------------------------------------------------===// 25 // OpenMP declarative directives. 26 //===----------------------------------------------------------------------===// 27 28 namespace { 29 enum OpenMPDirectiveKindEx { 30 OMPD_cancellation = OMPD_unknown + 1, 31 OMPD_data, 32 OMPD_declare, 33 OMPD_end, 34 OMPD_end_declare, 35 OMPD_enter, 36 OMPD_exit, 37 OMPD_point, 38 OMPD_reduction, 39 OMPD_target_enter, 40 OMPD_target_exit, 41 OMPD_update, 42 OMPD_distribute_parallel, 43 OMPD_teams_distribute_parallel, 44 OMPD_target_teams_distribute_parallel 45 }; 46 47 class ThreadprivateListParserHelper final { 48 SmallVector<Expr *, 4> Identifiers; 49 Parser *P; 50 51 public: 52 ThreadprivateListParserHelper(Parser *P) : P(P) {} 53 void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) { 54 ExprResult Res = 55 P->getActions().ActOnOpenMPIdExpression(P->getCurScope(), SS, NameInfo); 56 if (Res.isUsable()) 57 Identifiers.push_back(Res.get()); 58 } 59 llvm::ArrayRef<Expr *> getIdentifiers() const { return Identifiers; } 60 }; 61 } // namespace 62 63 // Map token string to extended OMP token kind that are 64 // OpenMPDirectiveKind + OpenMPDirectiveKindEx. 65 static unsigned getOpenMPDirectiveKindEx(StringRef S) { 66 auto DKind = getOpenMPDirectiveKind(S); 67 if (DKind != OMPD_unknown) 68 return DKind; 69 70 return llvm::StringSwitch<unsigned>(S) 71 .Case("cancellation", OMPD_cancellation) 72 .Case("data", OMPD_data) 73 .Case("declare", OMPD_declare) 74 .Case("end", OMPD_end) 75 .Case("enter", OMPD_enter) 76 .Case("exit", OMPD_exit) 77 .Case("point", OMPD_point) 78 .Case("reduction", OMPD_reduction) 79 .Case("update", OMPD_update) 80 .Default(OMPD_unknown); 81 } 82 83 static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P) { 84 // Array of foldings: F[i][0] F[i][1] ===> F[i][2]. 85 // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd 86 // TODO: add other combined directives in topological order. 87 static const unsigned F[][3] = { 88 { OMPD_cancellation, OMPD_point, OMPD_cancellation_point }, 89 { OMPD_declare, OMPD_reduction, OMPD_declare_reduction }, 90 { OMPD_declare, OMPD_simd, OMPD_declare_simd }, 91 { OMPD_declare, OMPD_target, OMPD_declare_target }, 92 { OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel }, 93 { OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for }, 94 { OMPD_distribute_parallel_for, OMPD_simd, 95 OMPD_distribute_parallel_for_simd }, 96 { OMPD_distribute, OMPD_simd, OMPD_distribute_simd }, 97 { OMPD_end, OMPD_declare, OMPD_end_declare }, 98 { OMPD_end_declare, OMPD_target, OMPD_end_declare_target }, 99 { OMPD_target, OMPD_data, OMPD_target_data }, 100 { OMPD_target, OMPD_enter, OMPD_target_enter }, 101 { OMPD_target, OMPD_exit, OMPD_target_exit }, 102 { OMPD_target, OMPD_update, OMPD_target_update }, 103 { OMPD_target_enter, OMPD_data, OMPD_target_enter_data }, 104 { OMPD_target_exit, OMPD_data, OMPD_target_exit_data }, 105 { OMPD_for, OMPD_simd, OMPD_for_simd }, 106 { OMPD_parallel, OMPD_for, OMPD_parallel_for }, 107 { OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd }, 108 { OMPD_parallel, OMPD_sections, OMPD_parallel_sections }, 109 { OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd }, 110 { OMPD_target, OMPD_parallel, OMPD_target_parallel }, 111 { OMPD_target, OMPD_simd, OMPD_target_simd }, 112 { OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for }, 113 { OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd }, 114 { OMPD_teams, OMPD_distribute, OMPD_teams_distribute }, 115 { OMPD_teams_distribute, OMPD_simd, OMPD_teams_distribute_simd }, 116 { OMPD_teams_distribute, OMPD_parallel, OMPD_teams_distribute_parallel }, 117 { OMPD_teams_distribute_parallel, OMPD_for, OMPD_teams_distribute_parallel_for }, 118 { OMPD_teams_distribute_parallel_for, OMPD_simd, OMPD_teams_distribute_parallel_for_simd }, 119 { OMPD_target, OMPD_teams, OMPD_target_teams }, 120 { OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute }, 121 { OMPD_target_teams_distribute, OMPD_parallel, OMPD_target_teams_distribute_parallel }, 122 { OMPD_target_teams_distribute, OMPD_simd, OMPD_target_teams_distribute_simd }, 123 { OMPD_target_teams_distribute_parallel, OMPD_for, OMPD_target_teams_distribute_parallel_for }, 124 { OMPD_target_teams_distribute_parallel_for, OMPD_simd, OMPD_target_teams_distribute_parallel_for_simd } 125 }; 126 enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 }; 127 auto Tok = P.getCurToken(); 128 unsigned DKind = 129 Tok.isAnnotation() 130 ? static_cast<unsigned>(OMPD_unknown) 131 : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok)); 132 if (DKind == OMPD_unknown) 133 return OMPD_unknown; 134 135 for (unsigned i = 0; i < llvm::array_lengthof(F); ++i) { 136 if (DKind != F[i][0]) 137 continue; 138 139 Tok = P.getPreprocessor().LookAhead(0); 140 unsigned SDKind = 141 Tok.isAnnotation() 142 ? static_cast<unsigned>(OMPD_unknown) 143 : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok)); 144 if (SDKind == OMPD_unknown) 145 continue; 146 147 if (SDKind == F[i][1]) { 148 P.ConsumeToken(); 149 DKind = F[i][2]; 150 } 151 } 152 return DKind < OMPD_unknown ? static_cast<OpenMPDirectiveKind>(DKind) 153 : OMPD_unknown; 154 } 155 156 static DeclarationName parseOpenMPReductionId(Parser &P) { 157 Token Tok = P.getCurToken(); 158 Sema &Actions = P.getActions(); 159 OverloadedOperatorKind OOK = OO_None; 160 // Allow to use 'operator' keyword for C++ operators 161 bool WithOperator = false; 162 if (Tok.is(tok::kw_operator)) { 163 P.ConsumeToken(); 164 Tok = P.getCurToken(); 165 WithOperator = true; 166 } 167 switch (Tok.getKind()) { 168 case tok::plus: // '+' 169 OOK = OO_Plus; 170 break; 171 case tok::minus: // '-' 172 OOK = OO_Minus; 173 break; 174 case tok::star: // '*' 175 OOK = OO_Star; 176 break; 177 case tok::amp: // '&' 178 OOK = OO_Amp; 179 break; 180 case tok::pipe: // '|' 181 OOK = OO_Pipe; 182 break; 183 case tok::caret: // '^' 184 OOK = OO_Caret; 185 break; 186 case tok::ampamp: // '&&' 187 OOK = OO_AmpAmp; 188 break; 189 case tok::pipepipe: // '||' 190 OOK = OO_PipePipe; 191 break; 192 case tok::identifier: // identifier 193 if (!WithOperator) 194 break; 195 LLVM_FALLTHROUGH; 196 default: 197 P.Diag(Tok.getLocation(), diag::err_omp_expected_reduction_identifier); 198 P.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end, 199 Parser::StopBeforeMatch); 200 return DeclarationName(); 201 } 202 P.ConsumeToken(); 203 auto &DeclNames = Actions.getASTContext().DeclarationNames; 204 return OOK == OO_None ? DeclNames.getIdentifier(Tok.getIdentifierInfo()) 205 : DeclNames.getCXXOperatorName(OOK); 206 } 207 208 /// \brief Parse 'omp declare reduction' construct. 209 /// 210 /// declare-reduction-directive: 211 /// annot_pragma_openmp 'declare' 'reduction' 212 /// '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')' 213 /// ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')'] 214 /// annot_pragma_openmp_end 215 /// <reduction_id> is either a base language identifier or one of the following 216 /// operators: '+', '-', '*', '&', '|', '^', '&&' and '||'. 217 /// 218 Parser::DeclGroupPtrTy 219 Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) { 220 // Parse '('. 221 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); 222 if (T.expectAndConsume(diag::err_expected_lparen_after, 223 getOpenMPDirectiveName(OMPD_declare_reduction))) { 224 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 225 return DeclGroupPtrTy(); 226 } 227 228 DeclarationName Name = parseOpenMPReductionId(*this); 229 if (Name.isEmpty() && Tok.is(tok::annot_pragma_openmp_end)) 230 return DeclGroupPtrTy(); 231 232 // Consume ':'. 233 bool IsCorrect = !ExpectAndConsume(tok::colon); 234 235 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end)) 236 return DeclGroupPtrTy(); 237 238 IsCorrect = IsCorrect && !Name.isEmpty(); 239 240 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) { 241 Diag(Tok.getLocation(), diag::err_expected_type); 242 IsCorrect = false; 243 } 244 245 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end)) 246 return DeclGroupPtrTy(); 247 248 SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes; 249 // Parse list of types until ':' token. 250 do { 251 ColonProtectionRAIIObject ColonRAII(*this); 252 SourceRange Range; 253 TypeResult TR = 254 ParseTypeName(&Range, DeclaratorContext::PrototypeContext, AS); 255 if (TR.isUsable()) { 256 auto ReductionType = 257 Actions.ActOnOpenMPDeclareReductionType(Range.getBegin(), TR); 258 if (!ReductionType.isNull()) { 259 ReductionTypes.push_back( 260 std::make_pair(ReductionType, Range.getBegin())); 261 } 262 } else { 263 SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end, 264 StopBeforeMatch); 265 } 266 267 if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) 268 break; 269 270 // Consume ','. 271 if (ExpectAndConsume(tok::comma)) { 272 IsCorrect = false; 273 if (Tok.is(tok::annot_pragma_openmp_end)) { 274 Diag(Tok.getLocation(), diag::err_expected_type); 275 return DeclGroupPtrTy(); 276 } 277 } 278 } while (Tok.isNot(tok::annot_pragma_openmp_end)); 279 280 if (ReductionTypes.empty()) { 281 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 282 return DeclGroupPtrTy(); 283 } 284 285 if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end)) 286 return DeclGroupPtrTy(); 287 288 // Consume ':'. 289 if (ExpectAndConsume(tok::colon)) 290 IsCorrect = false; 291 292 if (Tok.is(tok::annot_pragma_openmp_end)) { 293 Diag(Tok.getLocation(), diag::err_expected_expression); 294 return DeclGroupPtrTy(); 295 } 296 297 DeclGroupPtrTy DRD = Actions.ActOnOpenMPDeclareReductionDirectiveStart( 298 getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes, AS); 299 300 // Parse <combiner> expression and then parse initializer if any for each 301 // correct type. 302 unsigned I = 0, E = ReductionTypes.size(); 303 for (auto *D : DRD.get()) { 304 TentativeParsingAction TPA(*this); 305 ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope | 306 Scope::CompoundStmtScope | 307 Scope::OpenMPDirectiveScope); 308 // Parse <combiner> expression. 309 Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D); 310 ExprResult CombinerResult = 311 Actions.ActOnFinishFullExpr(ParseAssignmentExpression().get(), 312 D->getLocation(), /*DiscardedValue=*/true); 313 Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get()); 314 315 if (CombinerResult.isInvalid() && Tok.isNot(tok::r_paren) && 316 Tok.isNot(tok::annot_pragma_openmp_end)) { 317 TPA.Commit(); 318 IsCorrect = false; 319 break; 320 } 321 IsCorrect = !T.consumeClose() && IsCorrect && CombinerResult.isUsable(); 322 ExprResult InitializerResult; 323 if (Tok.isNot(tok::annot_pragma_openmp_end)) { 324 // Parse <initializer> expression. 325 if (Tok.is(tok::identifier) && 326 Tok.getIdentifierInfo()->isStr("initializer")) 327 ConsumeToken(); 328 else { 329 Diag(Tok.getLocation(), diag::err_expected) << "'initializer'"; 330 TPA.Commit(); 331 IsCorrect = false; 332 break; 333 } 334 // Parse '('. 335 BalancedDelimiterTracker T(*this, tok::l_paren, 336 tok::annot_pragma_openmp_end); 337 IsCorrect = 338 !T.expectAndConsume(diag::err_expected_lparen_after, "initializer") && 339 IsCorrect; 340 if (Tok.isNot(tok::annot_pragma_openmp_end)) { 341 ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope | 342 Scope::CompoundStmtScope | 343 Scope::OpenMPDirectiveScope); 344 // Parse expression. 345 VarDecl *OmpPrivParm = 346 Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(), 347 D); 348 // Check if initializer is omp_priv <init_expr> or something else. 349 if (Tok.is(tok::identifier) && 350 Tok.getIdentifierInfo()->isStr("omp_priv")) { 351 ConsumeToken(); 352 ParseOpenMPReductionInitializerForDecl(OmpPrivParm); 353 } else { 354 InitializerResult = Actions.ActOnFinishFullExpr( 355 ParseAssignmentExpression().get(), D->getLocation(), 356 /*DiscardedValue=*/true); 357 } 358 Actions.ActOnOpenMPDeclareReductionInitializerEnd( 359 D, InitializerResult.get(), OmpPrivParm); 360 if (InitializerResult.isInvalid() && Tok.isNot(tok::r_paren) && 361 Tok.isNot(tok::annot_pragma_openmp_end)) { 362 TPA.Commit(); 363 IsCorrect = false; 364 break; 365 } 366 IsCorrect = 367 !T.consumeClose() && IsCorrect && !InitializerResult.isInvalid(); 368 } 369 } 370 371 ++I; 372 // Revert parsing if not the last type, otherwise accept it, we're done with 373 // parsing. 374 if (I != E) 375 TPA.Revert(); 376 else 377 TPA.Commit(); 378 } 379 return Actions.ActOnOpenMPDeclareReductionDirectiveEnd(getCurScope(), DRD, 380 IsCorrect); 381 } 382 383 void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) { 384 // Parse declarator '=' initializer. 385 // If a '==' or '+=' is found, suggest a fixit to '='. 386 if (isTokenEqualOrEqualTypo()) { 387 ConsumeToken(); 388 389 if (Tok.is(tok::code_completion)) { 390 Actions.CodeCompleteInitializer(getCurScope(), OmpPrivParm); 391 Actions.FinalizeDeclaration(OmpPrivParm); 392 cutOffParsing(); 393 return; 394 } 395 396 ExprResult Init(ParseInitializer()); 397 398 if (Init.isInvalid()) { 399 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch); 400 Actions.ActOnInitializerError(OmpPrivParm); 401 } else { 402 Actions.AddInitializerToDecl(OmpPrivParm, Init.get(), 403 /*DirectInit=*/false); 404 } 405 } else if (Tok.is(tok::l_paren)) { 406 // Parse C++ direct initializer: '(' expression-list ')' 407 BalancedDelimiterTracker T(*this, tok::l_paren); 408 T.consumeOpen(); 409 410 ExprVector Exprs; 411 CommaLocsTy CommaLocs; 412 413 if (ParseExpressionList(Exprs, CommaLocs, [this, OmpPrivParm, &Exprs] { 414 Actions.CodeCompleteConstructor( 415 getCurScope(), OmpPrivParm->getType()->getCanonicalTypeInternal(), 416 OmpPrivParm->getLocation(), Exprs); 417 })) { 418 Actions.ActOnInitializerError(OmpPrivParm); 419 SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch); 420 } else { 421 // Match the ')'. 422 T.consumeClose(); 423 424 assert(!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size() && 425 "Unexpected number of commas!"); 426 427 ExprResult Initializer = Actions.ActOnParenListExpr( 428 T.getOpenLocation(), T.getCloseLocation(), Exprs); 429 Actions.AddInitializerToDecl(OmpPrivParm, Initializer.get(), 430 /*DirectInit=*/true); 431 } 432 } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { 433 // Parse C++0x braced-init-list. 434 Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); 435 436 ExprResult Init(ParseBraceInitializer()); 437 438 if (Init.isInvalid()) { 439 Actions.ActOnInitializerError(OmpPrivParm); 440 } else { 441 Actions.AddInitializerToDecl(OmpPrivParm, Init.get(), 442 /*DirectInit=*/true); 443 } 444 } else { 445 Actions.ActOnUninitializedDecl(OmpPrivParm); 446 } 447 } 448 449 namespace { 450 /// RAII that recreates function context for correct parsing of clauses of 451 /// 'declare simd' construct. 452 /// OpenMP, 2.8.2 declare simd Construct 453 /// The expressions appearing in the clauses of this directive are evaluated in 454 /// the scope of the arguments of the function declaration or definition. 455 class FNContextRAII final { 456 Parser &P; 457 Sema::CXXThisScopeRAII *ThisScope; 458 Parser::ParseScope *TempScope; 459 Parser::ParseScope *FnScope; 460 bool HasTemplateScope = false; 461 bool HasFunScope = false; 462 FNContextRAII() = delete; 463 FNContextRAII(const FNContextRAII &) = delete; 464 FNContextRAII &operator=(const FNContextRAII &) = delete; 465 466 public: 467 FNContextRAII(Parser &P, Parser::DeclGroupPtrTy Ptr) : P(P) { 468 Decl *D = *Ptr.get().begin(); 469 NamedDecl *ND = dyn_cast<NamedDecl>(D); 470 RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext()); 471 Sema &Actions = P.getActions(); 472 473 // Allow 'this' within late-parsed attributes. 474 ThisScope = new Sema::CXXThisScopeRAII(Actions, RD, /*TypeQuals=*/0, 475 ND && ND->isCXXInstanceMember()); 476 477 // If the Decl is templatized, add template parameters to scope. 478 HasTemplateScope = D->isTemplateDecl(); 479 TempScope = 480 new Parser::ParseScope(&P, Scope::TemplateParamScope, HasTemplateScope); 481 if (HasTemplateScope) 482 Actions.ActOnReenterTemplateScope(Actions.getCurScope(), D); 483 484 // If the Decl is on a function, add function parameters to the scope. 485 HasFunScope = D->isFunctionOrFunctionTemplate(); 486 FnScope = new Parser::ParseScope( 487 &P, Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope, 488 HasFunScope); 489 if (HasFunScope) 490 Actions.ActOnReenterFunctionContext(Actions.getCurScope(), D); 491 } 492 ~FNContextRAII() { 493 if (HasFunScope) { 494 P.getActions().ActOnExitFunctionContext(); 495 FnScope->Exit(); // Pop scope, and remove Decls from IdResolver 496 } 497 if (HasTemplateScope) 498 TempScope->Exit(); 499 delete FnScope; 500 delete TempScope; 501 delete ThisScope; 502 } 503 }; 504 } // namespace 505 506 /// Parses clauses for 'declare simd' directive. 507 /// clause: 508 /// 'inbranch' | 'notinbranch' 509 /// 'simdlen' '(' <expr> ')' 510 /// { 'uniform' '(' <argument_list> ')' } 511 /// { 'aligned '(' <argument_list> [ ':' <alignment> ] ')' } 512 /// { 'linear '(' <argument_list> [ ':' <step> ] ')' } 513 static bool parseDeclareSimdClauses( 514 Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, ExprResult &SimdLen, 515 SmallVectorImpl<Expr *> &Uniforms, SmallVectorImpl<Expr *> &Aligneds, 516 SmallVectorImpl<Expr *> &Alignments, SmallVectorImpl<Expr *> &Linears, 517 SmallVectorImpl<unsigned> &LinModifiers, SmallVectorImpl<Expr *> &Steps) { 518 SourceRange BSRange; 519 const Token &Tok = P.getCurToken(); 520 bool IsError = false; 521 while (Tok.isNot(tok::annot_pragma_openmp_end)) { 522 if (Tok.isNot(tok::identifier)) 523 break; 524 OMPDeclareSimdDeclAttr::BranchStateTy Out; 525 IdentifierInfo *II = Tok.getIdentifierInfo(); 526 StringRef ClauseName = II->getName(); 527 // Parse 'inranch|notinbranch' clauses. 528 if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) { 529 if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) { 530 P.Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch) 531 << ClauseName 532 << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange; 533 IsError = true; 534 } 535 BS = Out; 536 BSRange = SourceRange(Tok.getLocation(), Tok.getEndLoc()); 537 P.ConsumeToken(); 538 } else if (ClauseName.equals("simdlen")) { 539 if (SimdLen.isUsable()) { 540 P.Diag(Tok, diag::err_omp_more_one_clause) 541 << getOpenMPDirectiveName(OMPD_declare_simd) << ClauseName << 0; 542 IsError = true; 543 } 544 P.ConsumeToken(); 545 SourceLocation RLoc; 546 SimdLen = P.ParseOpenMPParensExpr(ClauseName, RLoc); 547 if (SimdLen.isInvalid()) 548 IsError = true; 549 } else { 550 OpenMPClauseKind CKind = getOpenMPClauseKind(ClauseName); 551 if (CKind == OMPC_uniform || CKind == OMPC_aligned || 552 CKind == OMPC_linear) { 553 Parser::OpenMPVarListDataTy Data; 554 auto *Vars = &Uniforms; 555 if (CKind == OMPC_aligned) 556 Vars = &Aligneds; 557 else if (CKind == OMPC_linear) 558 Vars = &Linears; 559 560 P.ConsumeToken(); 561 if (P.ParseOpenMPVarList(OMPD_declare_simd, 562 getOpenMPClauseKind(ClauseName), *Vars, Data)) 563 IsError = true; 564 if (CKind == OMPC_aligned) 565 Alignments.append(Aligneds.size() - Alignments.size(), Data.TailExpr); 566 else if (CKind == OMPC_linear) { 567 if (P.getActions().CheckOpenMPLinearModifier(Data.LinKind, 568 Data.DepLinMapLoc)) 569 Data.LinKind = OMPC_LINEAR_val; 570 LinModifiers.append(Linears.size() - LinModifiers.size(), 571 Data.LinKind); 572 Steps.append(Linears.size() - Steps.size(), Data.TailExpr); 573 } 574 } else 575 // TODO: add parsing of other clauses. 576 break; 577 } 578 // Skip ',' if any. 579 if (Tok.is(tok::comma)) 580 P.ConsumeToken(); 581 } 582 return IsError; 583 } 584 585 /// Parse clauses for '#pragma omp declare simd'. 586 Parser::DeclGroupPtrTy 587 Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr, 588 CachedTokens &Toks, SourceLocation Loc) { 589 PP.EnterToken(Tok); 590 PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true); 591 // Consume the previously pushed token. 592 ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); 593 594 FNContextRAII FnContext(*this, Ptr); 595 OMPDeclareSimdDeclAttr::BranchStateTy BS = 596 OMPDeclareSimdDeclAttr::BS_Undefined; 597 ExprResult Simdlen; 598 SmallVector<Expr *, 4> Uniforms; 599 SmallVector<Expr *, 4> Aligneds; 600 SmallVector<Expr *, 4> Alignments; 601 SmallVector<Expr *, 4> Linears; 602 SmallVector<unsigned, 4> LinModifiers; 603 SmallVector<Expr *, 4> Steps; 604 bool IsError = 605 parseDeclareSimdClauses(*this, BS, Simdlen, Uniforms, Aligneds, 606 Alignments, Linears, LinModifiers, Steps); 607 // Need to check for extra tokens. 608 if (Tok.isNot(tok::annot_pragma_openmp_end)) { 609 Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 610 << getOpenMPDirectiveName(OMPD_declare_simd); 611 while (Tok.isNot(tok::annot_pragma_openmp_end)) 612 ConsumeAnyToken(); 613 } 614 // Skip the last annot_pragma_openmp_end. 615 SourceLocation EndLoc = ConsumeAnnotationToken(); 616 if (!IsError) { 617 return Actions.ActOnOpenMPDeclareSimdDirective( 618 Ptr, BS, Simdlen.get(), Uniforms, Aligneds, Alignments, Linears, 619 LinModifiers, Steps, SourceRange(Loc, EndLoc)); 620 } 621 return Ptr; 622 } 623 624 /// \brief Parsing of declarative OpenMP directives. 625 /// 626 /// threadprivate-directive: 627 /// annot_pragma_openmp 'threadprivate' simple-variable-list 628 /// annot_pragma_openmp_end 629 /// 630 /// declare-reduction-directive: 631 /// annot_pragma_openmp 'declare' 'reduction' [...] 632 /// annot_pragma_openmp_end 633 /// 634 /// declare-simd-directive: 635 /// annot_pragma_openmp 'declare simd' {<clause> [,]} 636 /// annot_pragma_openmp_end 637 /// <function declaration/definition> 638 /// 639 Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( 640 AccessSpecifier &AS, ParsedAttributesWithRange &Attrs, 641 DeclSpec::TST TagType, Decl *Tag) { 642 assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!"); 643 ParenBraceBracketBalancer BalancerRAIIObj(*this); 644 645 SourceLocation Loc = ConsumeAnnotationToken(); 646 auto DKind = ParseOpenMPDirectiveKind(*this); 647 648 switch (DKind) { 649 case OMPD_threadprivate: { 650 ConsumeToken(); 651 ThreadprivateListParserHelper Helper(this); 652 if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Helper, true)) { 653 // The last seen token is annot_pragma_openmp_end - need to check for 654 // extra tokens. 655 if (Tok.isNot(tok::annot_pragma_openmp_end)) { 656 Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 657 << getOpenMPDirectiveName(OMPD_threadprivate); 658 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 659 } 660 // Skip the last annot_pragma_openmp_end. 661 ConsumeAnnotationToken(); 662 return Actions.ActOnOpenMPThreadprivateDirective(Loc, 663 Helper.getIdentifiers()); 664 } 665 break; 666 } 667 case OMPD_declare_reduction: 668 ConsumeToken(); 669 if (auto Res = ParseOpenMPDeclareReductionDirective(AS)) { 670 // The last seen token is annot_pragma_openmp_end - need to check for 671 // extra tokens. 672 if (Tok.isNot(tok::annot_pragma_openmp_end)) { 673 Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 674 << getOpenMPDirectiveName(OMPD_declare_reduction); 675 while (Tok.isNot(tok::annot_pragma_openmp_end)) 676 ConsumeAnyToken(); 677 } 678 // Skip the last annot_pragma_openmp_end. 679 ConsumeAnnotationToken(); 680 return Res; 681 } 682 break; 683 case OMPD_declare_simd: { 684 // The syntax is: 685 // { #pragma omp declare simd } 686 // <function-declaration-or-definition> 687 // 688 ConsumeToken(); 689 CachedTokens Toks; 690 while(Tok.isNot(tok::annot_pragma_openmp_end)) { 691 Toks.push_back(Tok); 692 ConsumeAnyToken(); 693 } 694 Toks.push_back(Tok); 695 ConsumeAnyToken(); 696 697 DeclGroupPtrTy Ptr; 698 if (Tok.is(tok::annot_pragma_openmp)) 699 Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, TagType, Tag); 700 else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) { 701 // Here we expect to see some function declaration. 702 if (AS == AS_none) { 703 assert(TagType == DeclSpec::TST_unspecified); 704 MaybeParseCXX11Attributes(Attrs); 705 ParsingDeclSpec PDS(*this); 706 Ptr = ParseExternalDeclaration(Attrs, &PDS); 707 } else { 708 Ptr = 709 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag); 710 } 711 } 712 if (!Ptr) { 713 Diag(Loc, diag::err_omp_decl_in_declare_simd); 714 return DeclGroupPtrTy(); 715 } 716 return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc); 717 } 718 case OMPD_declare_target: { 719 SourceLocation DTLoc = ConsumeAnyToken(); 720 if (Tok.isNot(tok::annot_pragma_openmp_end)) { 721 // OpenMP 4.5 syntax with list of entities. 722 llvm::SmallSetVector<const NamedDecl*, 16> SameDirectiveDecls; 723 while (Tok.isNot(tok::annot_pragma_openmp_end)) { 724 OMPDeclareTargetDeclAttr::MapTypeTy MT = 725 OMPDeclareTargetDeclAttr::MT_To; 726 if (Tok.is(tok::identifier)) { 727 IdentifierInfo *II = Tok.getIdentifierInfo(); 728 StringRef ClauseName = II->getName(); 729 // Parse 'to|link' clauses. 730 if (!OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, 731 MT)) { 732 Diag(Tok, diag::err_omp_declare_target_unexpected_clause) 733 << ClauseName; 734 break; 735 } 736 ConsumeToken(); 737 } 738 auto Callback = [this, MT, &SameDirectiveDecls]( 739 CXXScopeSpec &SS, DeclarationNameInfo NameInfo) { 740 Actions.ActOnOpenMPDeclareTargetName(getCurScope(), SS, NameInfo, MT, 741 SameDirectiveDecls); 742 }; 743 if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback, true)) 744 break; 745 746 // Consume optional ','. 747 if (Tok.is(tok::comma)) 748 ConsumeToken(); 749 } 750 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 751 ConsumeAnyToken(); 752 return DeclGroupPtrTy(); 753 } 754 755 // Skip the last annot_pragma_openmp_end. 756 ConsumeAnyToken(); 757 758 if (!Actions.ActOnStartOpenMPDeclareTargetDirective(DTLoc)) 759 return DeclGroupPtrTy(); 760 761 DKind = ParseOpenMPDirectiveKind(*this); 762 while (DKind != OMPD_end_declare_target && DKind != OMPD_declare_target && 763 Tok.isNot(tok::eof) && Tok.isNot(tok::r_brace)) { 764 DeclGroupPtrTy Ptr; 765 // Here we expect to see some function declaration. 766 if (AS == AS_none) { 767 assert(TagType == DeclSpec::TST_unspecified); 768 MaybeParseCXX11Attributes(Attrs); 769 ParsingDeclSpec PDS(*this); 770 Ptr = ParseExternalDeclaration(Attrs, &PDS); 771 } else { 772 Ptr = 773 ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag); 774 } 775 if (Tok.isAnnotation() && Tok.is(tok::annot_pragma_openmp)) { 776 TentativeParsingAction TPA(*this); 777 ConsumeAnnotationToken(); 778 DKind = ParseOpenMPDirectiveKind(*this); 779 if (DKind != OMPD_end_declare_target) 780 TPA.Revert(); 781 else 782 TPA.Commit(); 783 } 784 } 785 786 if (DKind == OMPD_end_declare_target) { 787 ConsumeAnyToken(); 788 if (Tok.isNot(tok::annot_pragma_openmp_end)) { 789 Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 790 << getOpenMPDirectiveName(OMPD_end_declare_target); 791 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 792 } 793 // Skip the last annot_pragma_openmp_end. 794 ConsumeAnyToken(); 795 } else { 796 Diag(Tok, diag::err_expected_end_declare_target); 797 Diag(DTLoc, diag::note_matching) << "'#pragma omp declare target'"; 798 } 799 Actions.ActOnFinishOpenMPDeclareTargetDirective(); 800 return DeclGroupPtrTy(); 801 } 802 case OMPD_unknown: 803 Diag(Tok, diag::err_omp_unknown_directive); 804 break; 805 case OMPD_parallel: 806 case OMPD_simd: 807 case OMPD_task: 808 case OMPD_taskyield: 809 case OMPD_barrier: 810 case OMPD_taskwait: 811 case OMPD_taskgroup: 812 case OMPD_flush: 813 case OMPD_for: 814 case OMPD_for_simd: 815 case OMPD_sections: 816 case OMPD_section: 817 case OMPD_single: 818 case OMPD_master: 819 case OMPD_ordered: 820 case OMPD_critical: 821 case OMPD_parallel_for: 822 case OMPD_parallel_for_simd: 823 case OMPD_parallel_sections: 824 case OMPD_atomic: 825 case OMPD_target: 826 case OMPD_teams: 827 case OMPD_cancellation_point: 828 case OMPD_cancel: 829 case OMPD_target_data: 830 case OMPD_target_enter_data: 831 case OMPD_target_exit_data: 832 case OMPD_target_parallel: 833 case OMPD_target_parallel_for: 834 case OMPD_taskloop: 835 case OMPD_taskloop_simd: 836 case OMPD_distribute: 837 case OMPD_end_declare_target: 838 case OMPD_target_update: 839 case OMPD_distribute_parallel_for: 840 case OMPD_distribute_parallel_for_simd: 841 case OMPD_distribute_simd: 842 case OMPD_target_parallel_for_simd: 843 case OMPD_target_simd: 844 case OMPD_teams_distribute: 845 case OMPD_teams_distribute_simd: 846 case OMPD_teams_distribute_parallel_for_simd: 847 case OMPD_teams_distribute_parallel_for: 848 case OMPD_target_teams: 849 case OMPD_target_teams_distribute: 850 case OMPD_target_teams_distribute_parallel_for: 851 case OMPD_target_teams_distribute_parallel_for_simd: 852 case OMPD_target_teams_distribute_simd: 853 Diag(Tok, diag::err_omp_unexpected_directive) 854 << 1 << getOpenMPDirectiveName(DKind); 855 break; 856 } 857 while (Tok.isNot(tok::annot_pragma_openmp_end)) 858 ConsumeAnyToken(); 859 ConsumeAnyToken(); 860 return nullptr; 861 } 862 863 /// \brief Parsing of declarative or executable OpenMP directives. 864 /// 865 /// threadprivate-directive: 866 /// annot_pragma_openmp 'threadprivate' simple-variable-list 867 /// annot_pragma_openmp_end 868 /// 869 /// declare-reduction-directive: 870 /// annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':' 871 /// <type> {',' <type>} ':' <expression> ')' ['initializer' '(' 872 /// ('omp_priv' '=' <expression>|<function_call>) ')'] 873 /// annot_pragma_openmp_end 874 /// 875 /// executable-directive: 876 /// annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' | 877 /// 'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] | 878 /// 'parallel for' | 'parallel sections' | 'task' | 'taskyield' | 879 /// 'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' | 880 /// 'for simd' | 'parallel for simd' | 'target' | 'target data' | 881 /// 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' | 882 /// 'distribute' | 'target enter data' | 'target exit data' | 883 /// 'target parallel' | 'target parallel for' | 884 /// 'target update' | 'distribute parallel for' | 885 /// 'distribute paralle for simd' | 'distribute simd' | 886 /// 'target parallel for simd' | 'target simd' | 887 /// 'teams distribute' | 'teams distribute simd' | 888 /// 'teams distribute parallel for simd' | 889 /// 'teams distribute parallel for' | 'target teams' | 890 /// 'target teams distribute' | 891 /// 'target teams distribute parallel for' | 892 /// 'target teams distribute parallel for simd' | 893 /// 'target teams distribute simd' {clause} 894 /// annot_pragma_openmp_end 895 /// 896 StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( 897 AllowedConstructsKind Allowed) { 898 assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!"); 899 ParenBraceBracketBalancer BalancerRAIIObj(*this); 900 SmallVector<OMPClause *, 5> Clauses; 901 SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1> 902 FirstClauses(OMPC_unknown + 1); 903 unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope | 904 Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope; 905 SourceLocation Loc = ConsumeAnnotationToken(), EndLoc; 906 auto DKind = ParseOpenMPDirectiveKind(*this); 907 OpenMPDirectiveKind CancelRegion = OMPD_unknown; 908 // Name of critical directive. 909 DeclarationNameInfo DirName; 910 StmtResult Directive = StmtError(); 911 bool HasAssociatedStatement = true; 912 bool FlushHasClause = false; 913 914 switch (DKind) { 915 case OMPD_threadprivate: { 916 if (Allowed != ACK_Any) { 917 Diag(Tok, diag::err_omp_immediate_directive) 918 << getOpenMPDirectiveName(DKind) << 0; 919 } 920 ConsumeToken(); 921 ThreadprivateListParserHelper Helper(this); 922 if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Helper, false)) { 923 // The last seen token is annot_pragma_openmp_end - need to check for 924 // extra tokens. 925 if (Tok.isNot(tok::annot_pragma_openmp_end)) { 926 Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 927 << getOpenMPDirectiveName(OMPD_threadprivate); 928 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 929 } 930 DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective( 931 Loc, Helper.getIdentifiers()); 932 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation()); 933 } 934 SkipUntil(tok::annot_pragma_openmp_end); 935 break; 936 } 937 case OMPD_declare_reduction: 938 ConsumeToken(); 939 if (auto Res = ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) { 940 // The last seen token is annot_pragma_openmp_end - need to check for 941 // extra tokens. 942 if (Tok.isNot(tok::annot_pragma_openmp_end)) { 943 Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 944 << getOpenMPDirectiveName(OMPD_declare_reduction); 945 while (Tok.isNot(tok::annot_pragma_openmp_end)) 946 ConsumeAnyToken(); 947 } 948 ConsumeAnyToken(); 949 Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation()); 950 } else 951 SkipUntil(tok::annot_pragma_openmp_end); 952 break; 953 case OMPD_flush: 954 if (PP.LookAhead(0).is(tok::l_paren)) { 955 FlushHasClause = true; 956 // Push copy of the current token back to stream to properly parse 957 // pseudo-clause OMPFlushClause. 958 PP.EnterToken(Tok); 959 } 960 LLVM_FALLTHROUGH; 961 case OMPD_taskyield: 962 case OMPD_barrier: 963 case OMPD_taskwait: 964 case OMPD_cancellation_point: 965 case OMPD_cancel: 966 case OMPD_target_enter_data: 967 case OMPD_target_exit_data: 968 case OMPD_target_update: 969 if (Allowed == ACK_StatementsOpenMPNonStandalone) { 970 Diag(Tok, diag::err_omp_immediate_directive) 971 << getOpenMPDirectiveName(DKind) << 0; 972 } 973 HasAssociatedStatement = false; 974 // Fall through for further analysis. 975 LLVM_FALLTHROUGH; 976 case OMPD_parallel: 977 case OMPD_simd: 978 case OMPD_for: 979 case OMPD_for_simd: 980 case OMPD_sections: 981 case OMPD_single: 982 case OMPD_section: 983 case OMPD_master: 984 case OMPD_critical: 985 case OMPD_parallel_for: 986 case OMPD_parallel_for_simd: 987 case OMPD_parallel_sections: 988 case OMPD_task: 989 case OMPD_ordered: 990 case OMPD_atomic: 991 case OMPD_target: 992 case OMPD_teams: 993 case OMPD_taskgroup: 994 case OMPD_target_data: 995 case OMPD_target_parallel: 996 case OMPD_target_parallel_for: 997 case OMPD_taskloop: 998 case OMPD_taskloop_simd: 999 case OMPD_distribute: 1000 case OMPD_distribute_parallel_for: 1001 case OMPD_distribute_parallel_for_simd: 1002 case OMPD_distribute_simd: 1003 case OMPD_target_parallel_for_simd: 1004 case OMPD_target_simd: 1005 case OMPD_teams_distribute: 1006 case OMPD_teams_distribute_simd: 1007 case OMPD_teams_distribute_parallel_for_simd: 1008 case OMPD_teams_distribute_parallel_for: 1009 case OMPD_target_teams: 1010 case OMPD_target_teams_distribute: 1011 case OMPD_target_teams_distribute_parallel_for: 1012 case OMPD_target_teams_distribute_parallel_for_simd: 1013 case OMPD_target_teams_distribute_simd: { 1014 ConsumeToken(); 1015 // Parse directive name of the 'critical' directive if any. 1016 if (DKind == OMPD_critical) { 1017 BalancedDelimiterTracker T(*this, tok::l_paren, 1018 tok::annot_pragma_openmp_end); 1019 if (!T.consumeOpen()) { 1020 if (Tok.isAnyIdentifier()) { 1021 DirName = 1022 DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation()); 1023 ConsumeAnyToken(); 1024 } else { 1025 Diag(Tok, diag::err_omp_expected_identifier_for_critical); 1026 } 1027 T.consumeClose(); 1028 } 1029 } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) { 1030 CancelRegion = ParseOpenMPDirectiveKind(*this); 1031 if (Tok.isNot(tok::annot_pragma_openmp_end)) 1032 ConsumeToken(); 1033 } 1034 1035 if (isOpenMPLoopDirective(DKind)) 1036 ScopeFlags |= Scope::OpenMPLoopDirectiveScope; 1037 if (isOpenMPSimdDirective(DKind)) 1038 ScopeFlags |= Scope::OpenMPSimdDirectiveScope; 1039 ParseScope OMPDirectiveScope(this, ScopeFlags); 1040 Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc); 1041 1042 while (Tok.isNot(tok::annot_pragma_openmp_end)) { 1043 OpenMPClauseKind CKind = 1044 Tok.isAnnotation() 1045 ? OMPC_unknown 1046 : FlushHasClause ? OMPC_flush 1047 : getOpenMPClauseKind(PP.getSpelling(Tok)); 1048 Actions.StartOpenMPClause(CKind); 1049 FlushHasClause = false; 1050 OMPClause *Clause = 1051 ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt()); 1052 FirstClauses[CKind].setInt(true); 1053 if (Clause) { 1054 FirstClauses[CKind].setPointer(Clause); 1055 Clauses.push_back(Clause); 1056 } 1057 1058 // Skip ',' if any. 1059 if (Tok.is(tok::comma)) 1060 ConsumeToken(); 1061 Actions.EndOpenMPClause(); 1062 } 1063 // End location of the directive. 1064 EndLoc = Tok.getLocation(); 1065 // Consume final annot_pragma_openmp_end. 1066 ConsumeAnnotationToken(); 1067 1068 // OpenMP [2.13.8, ordered Construct, Syntax] 1069 // If the depend clause is specified, the ordered construct is a stand-alone 1070 // directive. 1071 if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) { 1072 if (Allowed == ACK_StatementsOpenMPNonStandalone) { 1073 Diag(Loc, diag::err_omp_immediate_directive) 1074 << getOpenMPDirectiveName(DKind) << 1 1075 << getOpenMPClauseName(OMPC_depend); 1076 } 1077 HasAssociatedStatement = false; 1078 } 1079 1080 StmtResult AssociatedStmt; 1081 if (HasAssociatedStatement) { 1082 // The body is a block scope like in Lambdas and Blocks. 1083 Actions.ActOnOpenMPRegionStart(DKind, getCurScope()); 1084 // FIXME: We create a bogus CompoundStmt scope to hold the contents of 1085 // the captured region. Code elsewhere assumes that any FunctionScopeInfo 1086 // should have at least one compound statement scope within it. 1087 AssociatedStmt = (Sema::CompoundScopeRAII(Actions), ParseStatement()); 1088 AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses); 1089 } else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data || 1090 DKind == OMPD_target_exit_data) { 1091 Actions.ActOnOpenMPRegionStart(DKind, getCurScope()); 1092 AssociatedStmt = (Sema::CompoundScopeRAII(Actions), 1093 Actions.ActOnCompoundStmt(Loc, Loc, llvm::None, 1094 /*isStmtExpr=*/false)); 1095 AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses); 1096 } 1097 Directive = Actions.ActOnOpenMPExecutableDirective( 1098 DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc, 1099 EndLoc); 1100 1101 // Exit scope. 1102 Actions.EndOpenMPDSABlock(Directive.get()); 1103 OMPDirectiveScope.Exit(); 1104 break; 1105 } 1106 case OMPD_declare_simd: 1107 case OMPD_declare_target: 1108 case OMPD_end_declare_target: 1109 Diag(Tok, diag::err_omp_unexpected_directive) 1110 << 1 << getOpenMPDirectiveName(DKind); 1111 SkipUntil(tok::annot_pragma_openmp_end); 1112 break; 1113 case OMPD_unknown: 1114 Diag(Tok, diag::err_omp_unknown_directive); 1115 SkipUntil(tok::annot_pragma_openmp_end); 1116 break; 1117 } 1118 return Directive; 1119 } 1120 1121 // Parses simple list: 1122 // simple-variable-list: 1123 // '(' id-expression {, id-expression} ')' 1124 // 1125 bool Parser::ParseOpenMPSimpleVarList( 1126 OpenMPDirectiveKind Kind, 1127 const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> & 1128 Callback, 1129 bool AllowScopeSpecifier) { 1130 // Parse '('. 1131 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); 1132 if (T.expectAndConsume(diag::err_expected_lparen_after, 1133 getOpenMPDirectiveName(Kind))) 1134 return true; 1135 bool IsCorrect = true; 1136 bool NoIdentIsFound = true; 1137 1138 // Read tokens while ')' or annot_pragma_openmp_end is not found. 1139 while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) { 1140 CXXScopeSpec SS; 1141 SourceLocation TemplateKWLoc; 1142 UnqualifiedId Name; 1143 // Read var name. 1144 Token PrevTok = Tok; 1145 NoIdentIsFound = false; 1146 1147 if (AllowScopeSpecifier && getLangOpts().CPlusPlus && 1148 ParseOptionalCXXScopeSpecifier(SS, nullptr, false)) { 1149 IsCorrect = false; 1150 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, 1151 StopBeforeMatch); 1152 } else if (ParseUnqualifiedId(SS, false, false, false, false, nullptr, 1153 TemplateKWLoc, Name)) { 1154 IsCorrect = false; 1155 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, 1156 StopBeforeMatch); 1157 } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) && 1158 Tok.isNot(tok::annot_pragma_openmp_end)) { 1159 IsCorrect = false; 1160 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, 1161 StopBeforeMatch); 1162 Diag(PrevTok.getLocation(), diag::err_expected) 1163 << tok::identifier 1164 << SourceRange(PrevTok.getLocation(), PrevTokLocation); 1165 } else { 1166 Callback(SS, Actions.GetNameFromUnqualifiedId(Name)); 1167 } 1168 // Consume ','. 1169 if (Tok.is(tok::comma)) { 1170 ConsumeToken(); 1171 } 1172 } 1173 1174 if (NoIdentIsFound) { 1175 Diag(Tok, diag::err_expected) << tok::identifier; 1176 IsCorrect = false; 1177 } 1178 1179 // Parse ')'. 1180 IsCorrect = !T.consumeClose() && IsCorrect; 1181 1182 return !IsCorrect; 1183 } 1184 1185 /// \brief Parsing of OpenMP clauses. 1186 /// 1187 /// clause: 1188 /// if-clause | final-clause | num_threads-clause | safelen-clause | 1189 /// default-clause | private-clause | firstprivate-clause | shared-clause 1190 /// | linear-clause | aligned-clause | collapse-clause | 1191 /// lastprivate-clause | reduction-clause | proc_bind-clause | 1192 /// schedule-clause | copyin-clause | copyprivate-clause | untied-clause | 1193 /// mergeable-clause | flush-clause | read-clause | write-clause | 1194 /// update-clause | capture-clause | seq_cst-clause | device-clause | 1195 /// simdlen-clause | threads-clause | simd-clause | num_teams-clause | 1196 /// thread_limit-clause | priority-clause | grainsize-clause | 1197 /// nogroup-clause | num_tasks-clause | hint-clause | to-clause | 1198 /// from-clause | is_device_ptr-clause | task_reduction-clause | 1199 /// in_reduction-clause 1200 /// 1201 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, 1202 OpenMPClauseKind CKind, bool FirstClause) { 1203 OMPClause *Clause = nullptr; 1204 bool ErrorFound = false; 1205 bool WrongDirective = false; 1206 // Check if clause is allowed for the given directive. 1207 if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) { 1208 Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind) 1209 << getOpenMPDirectiveName(DKind); 1210 ErrorFound = true; 1211 WrongDirective = true; 1212 } 1213 1214 switch (CKind) { 1215 case OMPC_final: 1216 case OMPC_num_threads: 1217 case OMPC_safelen: 1218 case OMPC_simdlen: 1219 case OMPC_collapse: 1220 case OMPC_ordered: 1221 case OMPC_device: 1222 case OMPC_num_teams: 1223 case OMPC_thread_limit: 1224 case OMPC_priority: 1225 case OMPC_grainsize: 1226 case OMPC_num_tasks: 1227 case OMPC_hint: 1228 // OpenMP [2.5, Restrictions] 1229 // At most one num_threads clause can appear on the directive. 1230 // OpenMP [2.8.1, simd construct, Restrictions] 1231 // Only one safelen clause can appear on a simd directive. 1232 // Only one simdlen clause can appear on a simd directive. 1233 // Only one collapse clause can appear on a simd directive. 1234 // OpenMP [2.9.1, target data construct, Restrictions] 1235 // At most one device clause can appear on the directive. 1236 // OpenMP [2.11.1, task Construct, Restrictions] 1237 // At most one if clause can appear on the directive. 1238 // At most one final clause can appear on the directive. 1239 // OpenMP [teams Construct, Restrictions] 1240 // At most one num_teams clause can appear on the directive. 1241 // At most one thread_limit clause can appear on the directive. 1242 // OpenMP [2.9.1, task Construct, Restrictions] 1243 // At most one priority clause can appear on the directive. 1244 // OpenMP [2.9.2, taskloop Construct, Restrictions] 1245 // At most one grainsize clause can appear on the directive. 1246 // OpenMP [2.9.2, taskloop Construct, Restrictions] 1247 // At most one num_tasks clause can appear on the directive. 1248 if (!FirstClause) { 1249 Diag(Tok, diag::err_omp_more_one_clause) 1250 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; 1251 ErrorFound = true; 1252 } 1253 1254 if (CKind == OMPC_ordered && PP.LookAhead(/*N=*/0).isNot(tok::l_paren)) 1255 Clause = ParseOpenMPClause(CKind, WrongDirective); 1256 else 1257 Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective); 1258 break; 1259 case OMPC_default: 1260 case OMPC_proc_bind: 1261 // OpenMP [2.14.3.1, Restrictions] 1262 // Only a single default clause may be specified on a parallel, task or 1263 // teams directive. 1264 // OpenMP [2.5, parallel Construct, Restrictions] 1265 // At most one proc_bind clause can appear on the directive. 1266 if (!FirstClause) { 1267 Diag(Tok, diag::err_omp_more_one_clause) 1268 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; 1269 ErrorFound = true; 1270 } 1271 1272 Clause = ParseOpenMPSimpleClause(CKind, WrongDirective); 1273 break; 1274 case OMPC_schedule: 1275 case OMPC_dist_schedule: 1276 case OMPC_defaultmap: 1277 // OpenMP [2.7.1, Restrictions, p. 3] 1278 // Only one schedule clause can appear on a loop directive. 1279 // OpenMP [2.10.4, Restrictions, p. 106] 1280 // At most one defaultmap clause can appear on the directive. 1281 if (!FirstClause) { 1282 Diag(Tok, diag::err_omp_more_one_clause) 1283 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; 1284 ErrorFound = true; 1285 } 1286 LLVM_FALLTHROUGH; 1287 1288 case OMPC_if: 1289 Clause = ParseOpenMPSingleExprWithArgClause(CKind, WrongDirective); 1290 break; 1291 case OMPC_nowait: 1292 case OMPC_untied: 1293 case OMPC_mergeable: 1294 case OMPC_read: 1295 case OMPC_write: 1296 case OMPC_update: 1297 case OMPC_capture: 1298 case OMPC_seq_cst: 1299 case OMPC_threads: 1300 case OMPC_simd: 1301 case OMPC_nogroup: 1302 // OpenMP [2.7.1, Restrictions, p. 9] 1303 // Only one ordered clause can appear on a loop directive. 1304 // OpenMP [2.7.1, Restrictions, C/C++, p. 4] 1305 // Only one nowait clause can appear on a for directive. 1306 if (!FirstClause) { 1307 Diag(Tok, diag::err_omp_more_one_clause) 1308 << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; 1309 ErrorFound = true; 1310 } 1311 1312 Clause = ParseOpenMPClause(CKind, WrongDirective); 1313 break; 1314 case OMPC_private: 1315 case OMPC_firstprivate: 1316 case OMPC_lastprivate: 1317 case OMPC_shared: 1318 case OMPC_reduction: 1319 case OMPC_task_reduction: 1320 case OMPC_in_reduction: 1321 case OMPC_linear: 1322 case OMPC_aligned: 1323 case OMPC_copyin: 1324 case OMPC_copyprivate: 1325 case OMPC_flush: 1326 case OMPC_depend: 1327 case OMPC_map: 1328 case OMPC_to: 1329 case OMPC_from: 1330 case OMPC_use_device_ptr: 1331 case OMPC_is_device_ptr: 1332 Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective); 1333 break; 1334 case OMPC_unknown: 1335 Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 1336 << getOpenMPDirectiveName(DKind); 1337 SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 1338 break; 1339 case OMPC_threadprivate: 1340 case OMPC_uniform: 1341 if (!WrongDirective) 1342 Diag(Tok, diag::err_omp_unexpected_clause) 1343 << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind); 1344 SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch); 1345 break; 1346 } 1347 return ErrorFound ? nullptr : Clause; 1348 } 1349 1350 /// Parses simple expression in parens for single-expression clauses of OpenMP 1351 /// constructs. 1352 /// \param RLoc Returned location of right paren. 1353 ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName, 1354 SourceLocation &RLoc) { 1355 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); 1356 if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data())) 1357 return ExprError(); 1358 1359 SourceLocation ELoc = Tok.getLocation(); 1360 ExprResult LHS(ParseCastExpression( 1361 /*isUnaryExpression=*/false, /*isAddressOfOperand=*/false, NotTypeCast)); 1362 ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional)); 1363 Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc); 1364 1365 // Parse ')'. 1366 T.consumeClose(); 1367 1368 RLoc = T.getCloseLocation(); 1369 return Val; 1370 } 1371 1372 /// \brief Parsing of OpenMP clauses with single expressions like 'final', 1373 /// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams', 1374 /// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks' or 'hint'. 1375 /// 1376 /// final-clause: 1377 /// 'final' '(' expression ')' 1378 /// 1379 /// num_threads-clause: 1380 /// 'num_threads' '(' expression ')' 1381 /// 1382 /// safelen-clause: 1383 /// 'safelen' '(' expression ')' 1384 /// 1385 /// simdlen-clause: 1386 /// 'simdlen' '(' expression ')' 1387 /// 1388 /// collapse-clause: 1389 /// 'collapse' '(' expression ')' 1390 /// 1391 /// priority-clause: 1392 /// 'priority' '(' expression ')' 1393 /// 1394 /// grainsize-clause: 1395 /// 'grainsize' '(' expression ')' 1396 /// 1397 /// num_tasks-clause: 1398 /// 'num_tasks' '(' expression ')' 1399 /// 1400 /// hint-clause: 1401 /// 'hint' '(' expression ')' 1402 /// 1403 OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind, 1404 bool ParseOnly) { 1405 SourceLocation Loc = ConsumeToken(); 1406 SourceLocation LLoc = Tok.getLocation(); 1407 SourceLocation RLoc; 1408 1409 ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc); 1410 1411 if (Val.isInvalid()) 1412 return nullptr; 1413 1414 if (ParseOnly) 1415 return nullptr; 1416 return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc); 1417 } 1418 1419 /// \brief Parsing of simple OpenMP clauses like 'default' or 'proc_bind'. 1420 /// 1421 /// default-clause: 1422 /// 'default' '(' 'none' | 'shared' ') 1423 /// 1424 /// proc_bind-clause: 1425 /// 'proc_bind' '(' 'master' | 'close' | 'spread' ') 1426 /// 1427 OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind, 1428 bool ParseOnly) { 1429 SourceLocation Loc = Tok.getLocation(); 1430 SourceLocation LOpen = ConsumeToken(); 1431 // Parse '('. 1432 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); 1433 if (T.expectAndConsume(diag::err_expected_lparen_after, 1434 getOpenMPClauseName(Kind))) 1435 return nullptr; 1436 1437 unsigned Type = getOpenMPSimpleClauseType( 1438 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)); 1439 SourceLocation TypeLoc = Tok.getLocation(); 1440 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && 1441 Tok.isNot(tok::annot_pragma_openmp_end)) 1442 ConsumeAnyToken(); 1443 1444 // Parse ')'. 1445 T.consumeClose(); 1446 1447 if (ParseOnly) 1448 return nullptr; 1449 return Actions.ActOnOpenMPSimpleClause(Kind, Type, TypeLoc, LOpen, Loc, 1450 Tok.getLocation()); 1451 } 1452 1453 /// \brief Parsing of OpenMP clauses like 'ordered'. 1454 /// 1455 /// ordered-clause: 1456 /// 'ordered' 1457 /// 1458 /// nowait-clause: 1459 /// 'nowait' 1460 /// 1461 /// untied-clause: 1462 /// 'untied' 1463 /// 1464 /// mergeable-clause: 1465 /// 'mergeable' 1466 /// 1467 /// read-clause: 1468 /// 'read' 1469 /// 1470 /// threads-clause: 1471 /// 'threads' 1472 /// 1473 /// simd-clause: 1474 /// 'simd' 1475 /// 1476 /// nogroup-clause: 1477 /// 'nogroup' 1478 /// 1479 OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly) { 1480 SourceLocation Loc = Tok.getLocation(); 1481 ConsumeAnyToken(); 1482 1483 if (ParseOnly) 1484 return nullptr; 1485 return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation()); 1486 } 1487 1488 1489 /// \brief Parsing of OpenMP clauses with single expressions and some additional 1490 /// argument like 'schedule' or 'dist_schedule'. 1491 /// 1492 /// schedule-clause: 1493 /// 'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ] 1494 /// ')' 1495 /// 1496 /// if-clause: 1497 /// 'if' '(' [ directive-name-modifier ':' ] expression ')' 1498 /// 1499 /// defaultmap: 1500 /// 'defaultmap' '(' modifier ':' kind ')' 1501 /// 1502 OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, 1503 bool ParseOnly) { 1504 SourceLocation Loc = ConsumeToken(); 1505 SourceLocation DelimLoc; 1506 // Parse '('. 1507 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); 1508 if (T.expectAndConsume(diag::err_expected_lparen_after, 1509 getOpenMPClauseName(Kind))) 1510 return nullptr; 1511 1512 ExprResult Val; 1513 SmallVector<unsigned, 4> Arg; 1514 SmallVector<SourceLocation, 4> KLoc; 1515 if (Kind == OMPC_schedule) { 1516 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 1517 Arg.resize(NumberOfElements); 1518 KLoc.resize(NumberOfElements); 1519 Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown; 1520 Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown; 1521 Arg[ScheduleKind] = OMPC_SCHEDULE_unknown; 1522 auto KindModifier = getOpenMPSimpleClauseType( 1523 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)); 1524 if (KindModifier > OMPC_SCHEDULE_unknown) { 1525 // Parse 'modifier' 1526 Arg[Modifier1] = KindModifier; 1527 KLoc[Modifier1] = Tok.getLocation(); 1528 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && 1529 Tok.isNot(tok::annot_pragma_openmp_end)) 1530 ConsumeAnyToken(); 1531 if (Tok.is(tok::comma)) { 1532 // Parse ',' 'modifier' 1533 ConsumeAnyToken(); 1534 KindModifier = getOpenMPSimpleClauseType( 1535 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)); 1536 Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown 1537 ? KindModifier 1538 : (unsigned)OMPC_SCHEDULE_unknown; 1539 KLoc[Modifier2] = Tok.getLocation(); 1540 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && 1541 Tok.isNot(tok::annot_pragma_openmp_end)) 1542 ConsumeAnyToken(); 1543 } 1544 // Parse ':' 1545 if (Tok.is(tok::colon)) 1546 ConsumeAnyToken(); 1547 else 1548 Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier"; 1549 KindModifier = getOpenMPSimpleClauseType( 1550 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)); 1551 } 1552 Arg[ScheduleKind] = KindModifier; 1553 KLoc[ScheduleKind] = Tok.getLocation(); 1554 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && 1555 Tok.isNot(tok::annot_pragma_openmp_end)) 1556 ConsumeAnyToken(); 1557 if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static || 1558 Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic || 1559 Arg[ScheduleKind] == OMPC_SCHEDULE_guided) && 1560 Tok.is(tok::comma)) 1561 DelimLoc = ConsumeAnyToken(); 1562 } else if (Kind == OMPC_dist_schedule) { 1563 Arg.push_back(getOpenMPSimpleClauseType( 1564 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok))); 1565 KLoc.push_back(Tok.getLocation()); 1566 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && 1567 Tok.isNot(tok::annot_pragma_openmp_end)) 1568 ConsumeAnyToken(); 1569 if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma)) 1570 DelimLoc = ConsumeAnyToken(); 1571 } else if (Kind == OMPC_defaultmap) { 1572 // Get a defaultmap modifier 1573 Arg.push_back(getOpenMPSimpleClauseType( 1574 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok))); 1575 KLoc.push_back(Tok.getLocation()); 1576 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && 1577 Tok.isNot(tok::annot_pragma_openmp_end)) 1578 ConsumeAnyToken(); 1579 // Parse ':' 1580 if (Tok.is(tok::colon)) 1581 ConsumeAnyToken(); 1582 else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown) 1583 Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier"; 1584 // Get a defaultmap kind 1585 Arg.push_back(getOpenMPSimpleClauseType( 1586 Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok))); 1587 KLoc.push_back(Tok.getLocation()); 1588 if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && 1589 Tok.isNot(tok::annot_pragma_openmp_end)) 1590 ConsumeAnyToken(); 1591 } else { 1592 assert(Kind == OMPC_if); 1593 KLoc.push_back(Tok.getLocation()); 1594 TentativeParsingAction TPA(*this); 1595 Arg.push_back(ParseOpenMPDirectiveKind(*this)); 1596 if (Arg.back() != OMPD_unknown) { 1597 ConsumeToken(); 1598 if (Tok.is(tok::colon) && getLangOpts().OpenMP > 40) { 1599 TPA.Commit(); 1600 DelimLoc = ConsumeToken(); 1601 } else { 1602 TPA.Revert(); 1603 Arg.back() = OMPD_unknown; 1604 } 1605 } else 1606 TPA.Revert(); 1607 } 1608 1609 bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) || 1610 (Kind == OMPC_dist_schedule && DelimLoc.isValid()) || 1611 Kind == OMPC_if; 1612 if (NeedAnExpression) { 1613 SourceLocation ELoc = Tok.getLocation(); 1614 ExprResult LHS(ParseCastExpression(false, false, NotTypeCast)); 1615 Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional); 1616 Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc); 1617 } 1618 1619 // Parse ')'. 1620 T.consumeClose(); 1621 1622 if (NeedAnExpression && Val.isInvalid()) 1623 return nullptr; 1624 1625 if (ParseOnly) 1626 return nullptr; 1627 return Actions.ActOnOpenMPSingleExprWithArgClause( 1628 Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, 1629 T.getCloseLocation()); 1630 } 1631 1632 static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec, 1633 UnqualifiedId &ReductionId) { 1634 SourceLocation TemplateKWLoc; 1635 if (ReductionIdScopeSpec.isEmpty()) { 1636 auto OOK = OO_None; 1637 switch (P.getCurToken().getKind()) { 1638 case tok::plus: 1639 OOK = OO_Plus; 1640 break; 1641 case tok::minus: 1642 OOK = OO_Minus; 1643 break; 1644 case tok::star: 1645 OOK = OO_Star; 1646 break; 1647 case tok::amp: 1648 OOK = OO_Amp; 1649 break; 1650 case tok::pipe: 1651 OOK = OO_Pipe; 1652 break; 1653 case tok::caret: 1654 OOK = OO_Caret; 1655 break; 1656 case tok::ampamp: 1657 OOK = OO_AmpAmp; 1658 break; 1659 case tok::pipepipe: 1660 OOK = OO_PipePipe; 1661 break; 1662 default: 1663 break; 1664 } 1665 if (OOK != OO_None) { 1666 SourceLocation OpLoc = P.ConsumeToken(); 1667 SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()}; 1668 ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations); 1669 return false; 1670 } 1671 } 1672 return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false, 1673 /*AllowDestructorName*/ false, 1674 /*AllowConstructorName*/ false, 1675 /*AllowDeductionGuide*/ false, 1676 nullptr, TemplateKWLoc, ReductionId); 1677 } 1678 1679 /// Parses clauses with list. 1680 bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, 1681 OpenMPClauseKind Kind, 1682 SmallVectorImpl<Expr *> &Vars, 1683 OpenMPVarListDataTy &Data) { 1684 UnqualifiedId UnqualifiedReductionId; 1685 bool InvalidReductionId = false; 1686 bool MapTypeModifierSpecified = false; 1687 1688 // Parse '('. 1689 BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); 1690 if (T.expectAndConsume(diag::err_expected_lparen_after, 1691 getOpenMPClauseName(Kind))) 1692 return true; 1693 1694 bool NeedRParenForLinear = false; 1695 BalancedDelimiterTracker LinearT(*this, tok::l_paren, 1696 tok::annot_pragma_openmp_end); 1697 // Handle reduction-identifier for reduction clause. 1698 if (Kind == OMPC_reduction || Kind == OMPC_task_reduction || 1699 Kind == OMPC_in_reduction) { 1700 ColonProtectionRAIIObject ColonRAII(*this); 1701 if (getLangOpts().CPlusPlus) 1702 ParseOptionalCXXScopeSpecifier(Data.ReductionIdScopeSpec, 1703 /*ObjectType=*/nullptr, 1704 /*EnteringContext=*/false); 1705 InvalidReductionId = ParseReductionId(*this, Data.ReductionIdScopeSpec, 1706 UnqualifiedReductionId); 1707 if (InvalidReductionId) { 1708 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end, 1709 StopBeforeMatch); 1710 } 1711 if (Tok.is(tok::colon)) 1712 Data.ColonLoc = ConsumeToken(); 1713 else 1714 Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier"; 1715 if (!InvalidReductionId) 1716 Data.ReductionId = 1717 Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId); 1718 } else if (Kind == OMPC_depend) { 1719 // Handle dependency type for depend clause. 1720 ColonProtectionRAIIObject ColonRAII(*this); 1721 Data.DepKind = 1722 static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType( 1723 Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : "")); 1724 Data.DepLinMapLoc = Tok.getLocation(); 1725 1726 if (Data.DepKind == OMPC_DEPEND_unknown) { 1727 SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end, 1728 StopBeforeMatch); 1729 } else { 1730 ConsumeToken(); 1731 // Special processing for depend(source) clause. 1732 if (DKind == OMPD_ordered && Data.DepKind == OMPC_DEPEND_source) { 1733 // Parse ')'. 1734 T.consumeClose(); 1735 return false; 1736 } 1737 } 1738 if (Tok.is(tok::colon)) 1739 Data.ColonLoc = ConsumeToken(); 1740 else { 1741 Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren 1742 : diag::warn_pragma_expected_colon) 1743 << "dependency type"; 1744 } 1745 } else if (Kind == OMPC_linear) { 1746 // Try to parse modifier if any. 1747 if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) { 1748 Data.LinKind = static_cast<OpenMPLinearClauseKind>( 1749 getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))); 1750 Data.DepLinMapLoc = ConsumeToken(); 1751 LinearT.consumeOpen(); 1752 NeedRParenForLinear = true; 1753 } 1754 } else if (Kind == OMPC_map) { 1755 // Handle map type for map clause. 1756 ColonProtectionRAIIObject ColonRAII(*this); 1757 1758 /// The map clause modifier token can be either a identifier or the C++ 1759 /// delete keyword. 1760 auto &&IsMapClauseModifierToken = [](const Token &Tok) -> bool { 1761 return Tok.isOneOf(tok::identifier, tok::kw_delete); 1762 }; 1763 1764 // The first identifier may be a list item, a map-type or a 1765 // map-type-modifier. The map modifier can also be delete which has the same 1766 // spelling of the C++ delete keyword. 1767 Data.MapType = 1768 IsMapClauseModifierToken(Tok) 1769 ? static_cast<OpenMPMapClauseKind>( 1770 getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))) 1771 : OMPC_MAP_unknown; 1772 Data.DepLinMapLoc = Tok.getLocation(); 1773 bool ColonExpected = false; 1774 1775 if (IsMapClauseModifierToken(Tok)) { 1776 if (PP.LookAhead(0).is(tok::colon)) { 1777 if (Data.MapType == OMPC_MAP_unknown) 1778 Diag(Tok, diag::err_omp_unknown_map_type); 1779 else if (Data.MapType == OMPC_MAP_always) 1780 Diag(Tok, diag::err_omp_map_type_missing); 1781 ConsumeToken(); 1782 } else if (PP.LookAhead(0).is(tok::comma)) { 1783 if (IsMapClauseModifierToken(PP.LookAhead(1)) && 1784 PP.LookAhead(2).is(tok::colon)) { 1785 Data.MapTypeModifier = Data.MapType; 1786 if (Data.MapTypeModifier != OMPC_MAP_always) { 1787 Diag(Tok, diag::err_omp_unknown_map_type_modifier); 1788 Data.MapTypeModifier = OMPC_MAP_unknown; 1789 } else 1790 MapTypeModifierSpecified = true; 1791 1792 ConsumeToken(); 1793 ConsumeToken(); 1794 1795 Data.MapType = 1796 IsMapClauseModifierToken(Tok) 1797 ? static_cast<OpenMPMapClauseKind>( 1798 getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))) 1799 : OMPC_MAP_unknown; 1800 if (Data.MapType == OMPC_MAP_unknown || 1801 Data.MapType == OMPC_MAP_always) 1802 Diag(Tok, diag::err_omp_unknown_map_type); 1803 ConsumeToken(); 1804 } else { 1805 Data.MapType = OMPC_MAP_tofrom; 1806 Data.IsMapTypeImplicit = true; 1807 } 1808 } else if (IsMapClauseModifierToken(PP.LookAhead(0))) { 1809 if (PP.LookAhead(1).is(tok::colon)) { 1810 Data.MapTypeModifier = Data.MapType; 1811 if (Data.MapTypeModifier != OMPC_MAP_always) { 1812 Diag(Tok, diag::err_omp_unknown_map_type_modifier); 1813 Data.MapTypeModifier = OMPC_MAP_unknown; 1814 } else 1815 MapTypeModifierSpecified = true; 1816 1817 ConsumeToken(); 1818 1819 Data.MapType = 1820 IsMapClauseModifierToken(Tok) 1821 ? static_cast<OpenMPMapClauseKind>( 1822 getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))) 1823 : OMPC_MAP_unknown; 1824 if (Data.MapType == OMPC_MAP_unknown || 1825 Data.MapType == OMPC_MAP_always) 1826 Diag(Tok, diag::err_omp_unknown_map_type); 1827 ConsumeToken(); 1828 } else { 1829 Data.MapType = OMPC_MAP_tofrom; 1830 Data.IsMapTypeImplicit = true; 1831 } 1832 } else { 1833 Data.MapType = OMPC_MAP_tofrom; 1834 Data.IsMapTypeImplicit = true; 1835 } 1836 } else { 1837 Data.MapType = OMPC_MAP_tofrom; 1838 Data.IsMapTypeImplicit = true; 1839 } 1840 1841 if (Tok.is(tok::colon)) 1842 Data.ColonLoc = ConsumeToken(); 1843 else if (ColonExpected) 1844 Diag(Tok, diag::warn_pragma_expected_colon) << "map type"; 1845 } 1846 1847 bool IsComma = 1848 (Kind != OMPC_reduction && Kind != OMPC_task_reduction && 1849 Kind != OMPC_in_reduction && Kind != OMPC_depend && Kind != OMPC_map) || 1850 (Kind == OMPC_reduction && !InvalidReductionId) || 1851 (Kind == OMPC_map && Data.MapType != OMPC_MAP_unknown && 1852 (!MapTypeModifierSpecified || 1853 Data.MapTypeModifier == OMPC_MAP_always)) || 1854 (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown); 1855 const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned); 1856 while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) && 1857 Tok.isNot(tok::annot_pragma_openmp_end))) { 1858 ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail); 1859 // Parse variable 1860 ExprResult VarExpr = 1861 Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); 1862 if (VarExpr.isUsable()) 1863 Vars.push_back(VarExpr.get()); 1864 else { 1865 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, 1866 StopBeforeMatch); 1867 } 1868 // Skip ',' if any 1869 IsComma = Tok.is(tok::comma); 1870 if (IsComma) 1871 ConsumeToken(); 1872 else if (Tok.isNot(tok::r_paren) && 1873 Tok.isNot(tok::annot_pragma_openmp_end) && 1874 (!MayHaveTail || Tok.isNot(tok::colon))) 1875 Diag(Tok, diag::err_omp_expected_punc) 1876 << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush) 1877 : getOpenMPClauseName(Kind)) 1878 << (Kind == OMPC_flush); 1879 } 1880 1881 // Parse ')' for linear clause with modifier. 1882 if (NeedRParenForLinear) 1883 LinearT.consumeClose(); 1884 1885 // Parse ':' linear-step (or ':' alignment). 1886 const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon); 1887 if (MustHaveTail) { 1888 Data.ColonLoc = Tok.getLocation(); 1889 SourceLocation ELoc = ConsumeToken(); 1890 ExprResult Tail = ParseAssignmentExpression(); 1891 Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc); 1892 if (Tail.isUsable()) 1893 Data.TailExpr = Tail.get(); 1894 else 1895 SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, 1896 StopBeforeMatch); 1897 } 1898 1899 // Parse ')'. 1900 T.consumeClose(); 1901 if ((Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown && 1902 Vars.empty()) || 1903 (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) || 1904 (MustHaveTail && !Data.TailExpr) || InvalidReductionId) 1905 return true; 1906 return false; 1907 } 1908 1909 /// \brief Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate', 1910 /// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction' or 1911 /// 'in_reduction'. 1912 /// 1913 /// private-clause: 1914 /// 'private' '(' list ')' 1915 /// firstprivate-clause: 1916 /// 'firstprivate' '(' list ')' 1917 /// lastprivate-clause: 1918 /// 'lastprivate' '(' list ')' 1919 /// shared-clause: 1920 /// 'shared' '(' list ')' 1921 /// linear-clause: 1922 /// 'linear' '(' linear-list [ ':' linear-step ] ')' 1923 /// aligned-clause: 1924 /// 'aligned' '(' list [ ':' alignment ] ')' 1925 /// reduction-clause: 1926 /// 'reduction' '(' reduction-identifier ':' list ')' 1927 /// task_reduction-clause: 1928 /// 'task_reduction' '(' reduction-identifier ':' list ')' 1929 /// in_reduction-clause: 1930 /// 'in_reduction' '(' reduction-identifier ':' list ')' 1931 /// copyprivate-clause: 1932 /// 'copyprivate' '(' list ')' 1933 /// flush-clause: 1934 /// 'flush' '(' list ')' 1935 /// depend-clause: 1936 /// 'depend' '(' in | out | inout : list | source ')' 1937 /// map-clause: 1938 /// 'map' '(' [ [ always , ] 1939 /// to | from | tofrom | alloc | release | delete ':' ] list ')'; 1940 /// to-clause: 1941 /// 'to' '(' list ')' 1942 /// from-clause: 1943 /// 'from' '(' list ')' 1944 /// use_device_ptr-clause: 1945 /// 'use_device_ptr' '(' list ')' 1946 /// is_device_ptr-clause: 1947 /// 'is_device_ptr' '(' list ')' 1948 /// 1949 /// For 'linear' clause linear-list may have the following forms: 1950 /// list 1951 /// modifier(list) 1952 /// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++). 1953 OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind, 1954 OpenMPClauseKind Kind, 1955 bool ParseOnly) { 1956 SourceLocation Loc = Tok.getLocation(); 1957 SourceLocation LOpen = ConsumeToken(); 1958 SmallVector<Expr *, 4> Vars; 1959 OpenMPVarListDataTy Data; 1960 1961 if (ParseOpenMPVarList(DKind, Kind, Vars, Data)) 1962 return nullptr; 1963 1964 if (ParseOnly) 1965 return nullptr; 1966 return Actions.ActOnOpenMPVarListClause( 1967 Kind, Vars, Data.TailExpr, Loc, LOpen, Data.ColonLoc, Tok.getLocation(), 1968 Data.ReductionIdScopeSpec, Data.ReductionId, Data.DepKind, Data.LinKind, 1969 Data.MapTypeModifier, Data.MapType, Data.IsMapTypeImplicit, 1970 Data.DepLinMapLoc); 1971 } 1972 1973