ParseOpenMP.cpp revision 309124
1249261Sdim//===--- ParseOpenMP.cpp - OpenMP directives parsing ----------------------===// 2249261Sdim// 3249261Sdim// The LLVM Compiler Infrastructure 4249261Sdim// 5249261Sdim// This file is distributed under the University of Illinois Open Source 6249261Sdim// License. See LICENSE.TXT for details. 7249261Sdim// 8249261Sdim//===----------------------------------------------------------------------===// 9249261Sdim/// \file 10249261Sdim/// \brief This file implements parsing of all OpenMP directives and clauses. 11249261Sdim/// 12249261Sdim//===----------------------------------------------------------------------===// 13249261Sdim 14276479Sdim#include "RAIIObjectsForParser.h" 15249261Sdim#include "clang/AST/ASTConsumer.h" 16276479Sdim#include "clang/AST/ASTContext.h" 17261991Sdim#include "clang/AST/StmtOpenMP.h" 18261991Sdim#include "clang/Parse/ParseDiagnostic.h" 19249261Sdim#include "clang/Parse/Parser.h" 20261991Sdim#include "clang/Sema/Scope.h" 21261991Sdim#include "llvm/ADT/PointerIntPair.h" 22296417Sdim 23249261Sdimusing namespace clang; 24249261Sdim 25249261Sdim//===----------------------------------------------------------------------===// 26249261Sdim// OpenMP declarative directives. 27249261Sdim//===----------------------------------------------------------------------===// 28249261Sdim 29309124Sdimnamespace { 30309124Sdimenum OpenMPDirectiveKindEx { 31309124Sdim OMPD_cancellation = OMPD_unknown + 1, 32309124Sdim OMPD_data, 33309124Sdim OMPD_declare, 34309124Sdim OMPD_end, 35309124Sdim OMPD_end_declare, 36309124Sdim OMPD_enter, 37309124Sdim OMPD_exit, 38309124Sdim OMPD_point, 39309124Sdim OMPD_reduction, 40309124Sdim OMPD_target_enter, 41309124Sdim OMPD_target_exit, 42309124Sdim OMPD_update, 43309124Sdim OMPD_distribute_parallel 44309124Sdim}; 45309124Sdim 46309124Sdimclass ThreadprivateListParserHelper final { 47309124Sdim SmallVector<Expr *, 4> Identifiers; 48309124Sdim Parser *P; 49309124Sdim 50309124Sdimpublic: 51309124Sdim ThreadprivateListParserHelper(Parser *P) : P(P) {} 52309124Sdim void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) { 53309124Sdim ExprResult Res = 54309124Sdim P->getActions().ActOnOpenMPIdExpression(P->getCurScope(), SS, NameInfo); 55309124Sdim if (Res.isUsable()) 56309124Sdim Identifiers.push_back(Res.get()); 57309124Sdim } 58309124Sdim llvm::ArrayRef<Expr *> getIdentifiers() const { return Identifiers; } 59309124Sdim}; 60309124Sdim} // namespace 61309124Sdim 62309124Sdim// Map token string to extended OMP token kind that are 63309124Sdim// OpenMPDirectiveKind + OpenMPDirectiveKindEx. 64309124Sdimstatic unsigned getOpenMPDirectiveKindEx(StringRef S) { 65309124Sdim auto DKind = getOpenMPDirectiveKind(S); 66309124Sdim if (DKind != OMPD_unknown) 67309124Sdim return DKind; 68309124Sdim 69309124Sdim return llvm::StringSwitch<unsigned>(S) 70309124Sdim .Case("cancellation", OMPD_cancellation) 71309124Sdim .Case("data", OMPD_data) 72309124Sdim .Case("declare", OMPD_declare) 73309124Sdim .Case("end", OMPD_end) 74309124Sdim .Case("enter", OMPD_enter) 75309124Sdim .Case("exit", OMPD_exit) 76309124Sdim .Case("point", OMPD_point) 77309124Sdim .Case("reduction", OMPD_reduction) 78309124Sdim .Case("update", OMPD_update) 79309124Sdim .Default(OMPD_unknown); 80309124Sdim} 81309124Sdim 82276479Sdimstatic OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P) { 83280031Sdim // Array of foldings: F[i][0] F[i][1] ===> F[i][2]. 84280031Sdim // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd 85280031Sdim // TODO: add other combined directives in topological order. 86309124Sdim static const unsigned F[][3] = { 87309124Sdim { OMPD_cancellation, OMPD_point, OMPD_cancellation_point }, 88309124Sdim { OMPD_declare, OMPD_reduction, OMPD_declare_reduction }, 89309124Sdim { OMPD_declare, OMPD_simd, OMPD_declare_simd }, 90309124Sdim { OMPD_declare, OMPD_target, OMPD_declare_target }, 91309124Sdim { OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel }, 92309124Sdim { OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for }, 93309124Sdim { OMPD_distribute_parallel_for, OMPD_simd, 94309124Sdim OMPD_distribute_parallel_for_simd }, 95309124Sdim { OMPD_distribute, OMPD_simd, OMPD_distribute_simd }, 96309124Sdim { OMPD_end, OMPD_declare, OMPD_end_declare }, 97309124Sdim { OMPD_end_declare, OMPD_target, OMPD_end_declare_target }, 98309124Sdim { OMPD_target, OMPD_data, OMPD_target_data }, 99309124Sdim { OMPD_target, OMPD_enter, OMPD_target_enter }, 100309124Sdim { OMPD_target, OMPD_exit, OMPD_target_exit }, 101309124Sdim { OMPD_target, OMPD_update, OMPD_target_update }, 102309124Sdim { OMPD_target_enter, OMPD_data, OMPD_target_enter_data }, 103309124Sdim { OMPD_target_exit, OMPD_data, OMPD_target_exit_data }, 104309124Sdim { OMPD_for, OMPD_simd, OMPD_for_simd }, 105309124Sdim { OMPD_parallel, OMPD_for, OMPD_parallel_for }, 106309124Sdim { OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd }, 107309124Sdim { OMPD_parallel, OMPD_sections, OMPD_parallel_sections }, 108309124Sdim { OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd }, 109309124Sdim { OMPD_target, OMPD_parallel, OMPD_target_parallel }, 110309124Sdim { OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for }, 111309124Sdim { OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd } 112309124Sdim }; 113309124Sdim enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 }; 114276479Sdim auto Tok = P.getCurToken(); 115309124Sdim unsigned DKind = 116276479Sdim Tok.isAnnotation() 117309124Sdim ? static_cast<unsigned>(OMPD_unknown) 118309124Sdim : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok)); 119309124Sdim if (DKind == OMPD_unknown) 120309124Sdim return OMPD_unknown; 121296417Sdim 122280031Sdim for (unsigned i = 0; i < llvm::array_lengthof(F); ++i) { 123309124Sdim if (DKind != F[i][0]) 124309124Sdim continue; 125309124Sdim 126309124Sdim Tok = P.getPreprocessor().LookAhead(0); 127309124Sdim unsigned SDKind = 128309124Sdim Tok.isAnnotation() 129309124Sdim ? static_cast<unsigned>(OMPD_unknown) 130309124Sdim : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok)); 131309124Sdim if (SDKind == OMPD_unknown) 132309124Sdim continue; 133309124Sdim 134309124Sdim if (SDKind == F[i][1]) { 135309124Sdim P.ConsumeToken(); 136309124Sdim DKind = F[i][2]; 137309124Sdim } 138309124Sdim } 139309124Sdim return DKind < OMPD_unknown ? static_cast<OpenMPDirectiveKind>(DKind) 140309124Sdim : OMPD_unknown; 141309124Sdim} 142309124Sdim 143309124Sdimstatic DeclarationName parseOpenMPReductionId(Parser &P) { 144309124Sdim Token Tok = P.getCurToken(); 145309124Sdim Sema &Actions = P.getActions(); 146309124Sdim OverloadedOperatorKind OOK = OO_None; 147309124Sdim // Allow to use 'operator' keyword for C++ operators 148309124Sdim bool WithOperator = false; 149309124Sdim if (Tok.is(tok::kw_operator)) { 150309124Sdim P.ConsumeToken(); 151309124Sdim Tok = P.getCurToken(); 152309124Sdim WithOperator = true; 153309124Sdim } 154309124Sdim switch (Tok.getKind()) { 155309124Sdim case tok::plus: // '+' 156309124Sdim OOK = OO_Plus; 157309124Sdim break; 158309124Sdim case tok::minus: // '-' 159309124Sdim OOK = OO_Minus; 160309124Sdim break; 161309124Sdim case tok::star: // '*' 162309124Sdim OOK = OO_Star; 163309124Sdim break; 164309124Sdim case tok::amp: // '&' 165309124Sdim OOK = OO_Amp; 166309124Sdim break; 167309124Sdim case tok::pipe: // '|' 168309124Sdim OOK = OO_Pipe; 169309124Sdim break; 170309124Sdim case tok::caret: // '^' 171309124Sdim OOK = OO_Caret; 172309124Sdim break; 173309124Sdim case tok::ampamp: // '&&' 174309124Sdim OOK = OO_AmpAmp; 175309124Sdim break; 176309124Sdim case tok::pipepipe: // '||' 177309124Sdim OOK = OO_PipePipe; 178309124Sdim break; 179309124Sdim case tok::identifier: // identifier 180309124Sdim if (!WithOperator) 181309124Sdim break; 182309124Sdim default: 183309124Sdim P.Diag(Tok.getLocation(), diag::err_omp_expected_reduction_identifier); 184309124Sdim P.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end, 185309124Sdim Parser::StopBeforeMatch); 186309124Sdim return DeclarationName(); 187309124Sdim } 188309124Sdim P.ConsumeToken(); 189309124Sdim auto &DeclNames = Actions.getASTContext().DeclarationNames; 190309124Sdim return OOK == OO_None ? DeclNames.getIdentifier(Tok.getIdentifierInfo()) 191309124Sdim : DeclNames.getCXXOperatorName(OOK); 192309124Sdim} 193309124Sdim 194309124Sdim/// \brief Parse 'omp declare reduction' construct. 195309124Sdim/// 196309124Sdim/// declare-reduction-directive: 197309124Sdim/// annot_pragma_openmp 'declare' 'reduction' 198309124Sdim/// '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')' 199309124Sdim/// ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')'] 200309124Sdim/// annot_pragma_openmp_end 201309124Sdim/// <reduction_id> is either a base language identifier or one of the following 202309124Sdim/// operators: '+', '-', '*', '&', '|', '^', '&&' and '||'. 203309124Sdim/// 204309124SdimParser::DeclGroupPtrTy 205309124SdimParser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) { 206309124Sdim // Parse '('. 207309124Sdim BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); 208309124Sdim if (T.expectAndConsume(diag::err_expected_lparen_after, 209309124Sdim getOpenMPDirectiveName(OMPD_declare_reduction))) { 210309124Sdim SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 211309124Sdim return DeclGroupPtrTy(); 212309124Sdim } 213309124Sdim 214309124Sdim DeclarationName Name = parseOpenMPReductionId(*this); 215309124Sdim if (Name.isEmpty() && Tok.is(tok::annot_pragma_openmp_end)) 216309124Sdim return DeclGroupPtrTy(); 217309124Sdim 218309124Sdim // Consume ':'. 219309124Sdim bool IsCorrect = !ExpectAndConsume(tok::colon); 220309124Sdim 221309124Sdim if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end)) 222309124Sdim return DeclGroupPtrTy(); 223309124Sdim 224309124Sdim IsCorrect = IsCorrect && !Name.isEmpty(); 225309124Sdim 226309124Sdim if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) { 227309124Sdim Diag(Tok.getLocation(), diag::err_expected_type); 228309124Sdim IsCorrect = false; 229309124Sdim } 230309124Sdim 231309124Sdim if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end)) 232309124Sdim return DeclGroupPtrTy(); 233309124Sdim 234309124Sdim SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes; 235309124Sdim // Parse list of types until ':' token. 236309124Sdim do { 237309124Sdim ColonProtectionRAIIObject ColonRAII(*this); 238309124Sdim SourceRange Range; 239309124Sdim TypeResult TR = ParseTypeName(&Range, Declarator::PrototypeContext, AS); 240309124Sdim if (TR.isUsable()) { 241309124Sdim auto ReductionType = 242309124Sdim Actions.ActOnOpenMPDeclareReductionType(Range.getBegin(), TR); 243309124Sdim if (!ReductionType.isNull()) { 244309124Sdim ReductionTypes.push_back( 245309124Sdim std::make_pair(ReductionType, Range.getBegin())); 246309124Sdim } 247288943Sdim } else { 248309124Sdim SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end, 249309124Sdim StopBeforeMatch); 250288943Sdim } 251296417Sdim 252309124Sdim if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) 253309124Sdim break; 254296417Sdim 255309124Sdim // Consume ','. 256309124Sdim if (ExpectAndConsume(tok::comma)) { 257309124Sdim IsCorrect = false; 258309124Sdim if (Tok.is(tok::annot_pragma_openmp_end)) { 259309124Sdim Diag(Tok.getLocation(), diag::err_expected_type); 260309124Sdim return DeclGroupPtrTy(); 261288943Sdim } 262309124Sdim } 263309124Sdim } while (Tok.isNot(tok::annot_pragma_openmp_end)); 264296417Sdim 265309124Sdim if (ReductionTypes.empty()) { 266309124Sdim SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 267309124Sdim return DeclGroupPtrTy(); 268309124Sdim } 269309124Sdim 270309124Sdim if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end)) 271309124Sdim return DeclGroupPtrTy(); 272309124Sdim 273309124Sdim // Consume ':'. 274309124Sdim if (ExpectAndConsume(tok::colon)) 275309124Sdim IsCorrect = false; 276309124Sdim 277309124Sdim if (Tok.is(tok::annot_pragma_openmp_end)) { 278309124Sdim Diag(Tok.getLocation(), diag::err_expected_expression); 279309124Sdim return DeclGroupPtrTy(); 280309124Sdim } 281309124Sdim 282309124Sdim DeclGroupPtrTy DRD = Actions.ActOnOpenMPDeclareReductionDirectiveStart( 283309124Sdim getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes, AS); 284309124Sdim 285309124Sdim // Parse <combiner> expression and then parse initializer if any for each 286309124Sdim // correct type. 287309124Sdim unsigned I = 0, E = ReductionTypes.size(); 288309124Sdim for (auto *D : DRD.get()) { 289309124Sdim TentativeParsingAction TPA(*this); 290309124Sdim ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope | 291309124Sdim Scope::OpenMPDirectiveScope); 292309124Sdim // Parse <combiner> expression. 293309124Sdim Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D); 294309124Sdim ExprResult CombinerResult = 295309124Sdim Actions.ActOnFinishFullExpr(ParseAssignmentExpression().get(), 296309124Sdim D->getLocation(), /*DiscardedValue=*/true); 297309124Sdim Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get()); 298309124Sdim 299309124Sdim if (CombinerResult.isInvalid() && Tok.isNot(tok::r_paren) && 300309124Sdim Tok.isNot(tok::annot_pragma_openmp_end)) { 301309124Sdim TPA.Commit(); 302309124Sdim IsCorrect = false; 303309124Sdim break; 304309124Sdim } 305309124Sdim IsCorrect = !T.consumeClose() && IsCorrect && CombinerResult.isUsable(); 306309124Sdim ExprResult InitializerResult; 307309124Sdim if (Tok.isNot(tok::annot_pragma_openmp_end)) { 308309124Sdim // Parse <initializer> expression. 309309124Sdim if (Tok.is(tok::identifier) && 310309124Sdim Tok.getIdentifierInfo()->isStr("initializer")) 311309124Sdim ConsumeToken(); 312309124Sdim else { 313309124Sdim Diag(Tok.getLocation(), diag::err_expected) << "'initializer'"; 314309124Sdim TPA.Commit(); 315309124Sdim IsCorrect = false; 316309124Sdim break; 317280031Sdim } 318309124Sdim // Parse '('. 319309124Sdim BalancedDelimiterTracker T(*this, tok::l_paren, 320309124Sdim tok::annot_pragma_openmp_end); 321309124Sdim IsCorrect = 322309124Sdim !T.expectAndConsume(diag::err_expected_lparen_after, "initializer") && 323309124Sdim IsCorrect; 324309124Sdim if (Tok.isNot(tok::annot_pragma_openmp_end)) { 325309124Sdim ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope | 326309124Sdim Scope::OpenMPDirectiveScope); 327309124Sdim // Parse expression. 328309124Sdim Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(), D); 329309124Sdim InitializerResult = Actions.ActOnFinishFullExpr( 330309124Sdim ParseAssignmentExpression().get(), D->getLocation(), 331309124Sdim /*DiscardedValue=*/true); 332309124Sdim Actions.ActOnOpenMPDeclareReductionInitializerEnd( 333309124Sdim D, InitializerResult.get()); 334309124Sdim if (InitializerResult.isInvalid() && Tok.isNot(tok::r_paren) && 335309124Sdim Tok.isNot(tok::annot_pragma_openmp_end)) { 336309124Sdim TPA.Commit(); 337309124Sdim IsCorrect = false; 338309124Sdim break; 339309124Sdim } 340309124Sdim IsCorrect = 341309124Sdim !T.consumeClose() && IsCorrect && !InitializerResult.isInvalid(); 342309124Sdim } 343276479Sdim } 344309124Sdim 345309124Sdim ++I; 346309124Sdim // Revert parsing if not the last type, otherwise accept it, we're done with 347309124Sdim // parsing. 348309124Sdim if (I != E) 349309124Sdim TPA.Revert(); 350309124Sdim else 351309124Sdim TPA.Commit(); 352276479Sdim } 353309124Sdim return Actions.ActOnOpenMPDeclareReductionDirectiveEnd(getCurScope(), DRD, 354309124Sdim IsCorrect); 355276479Sdim} 356276479Sdim 357309124Sdimnamespace { 358309124Sdim/// RAII that recreates function context for correct parsing of clauses of 359309124Sdim/// 'declare simd' construct. 360309124Sdim/// OpenMP, 2.8.2 declare simd Construct 361309124Sdim/// The expressions appearing in the clauses of this directive are evaluated in 362309124Sdim/// the scope of the arguments of the function declaration or definition. 363309124Sdimclass FNContextRAII final { 364309124Sdim Parser &P; 365309124Sdim Sema::CXXThisScopeRAII *ThisScope; 366309124Sdim Parser::ParseScope *TempScope; 367309124Sdim Parser::ParseScope *FnScope; 368309124Sdim bool HasTemplateScope = false; 369309124Sdim bool HasFunScope = false; 370309124Sdim FNContextRAII() = delete; 371309124Sdim FNContextRAII(const FNContextRAII &) = delete; 372309124Sdim FNContextRAII &operator=(const FNContextRAII &) = delete; 373309124Sdim 374309124Sdimpublic: 375309124Sdim FNContextRAII(Parser &P, Parser::DeclGroupPtrTy Ptr) : P(P) { 376309124Sdim Decl *D = *Ptr.get().begin(); 377309124Sdim NamedDecl *ND = dyn_cast<NamedDecl>(D); 378309124Sdim RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext()); 379309124Sdim Sema &Actions = P.getActions(); 380309124Sdim 381309124Sdim // Allow 'this' within late-parsed attributes. 382309124Sdim ThisScope = new Sema::CXXThisScopeRAII(Actions, RD, /*TypeQuals=*/0, 383309124Sdim ND && ND->isCXXInstanceMember()); 384309124Sdim 385309124Sdim // If the Decl is templatized, add template parameters to scope. 386309124Sdim HasTemplateScope = D->isTemplateDecl(); 387309124Sdim TempScope = 388309124Sdim new Parser::ParseScope(&P, Scope::TemplateParamScope, HasTemplateScope); 389309124Sdim if (HasTemplateScope) 390309124Sdim Actions.ActOnReenterTemplateScope(Actions.getCurScope(), D); 391309124Sdim 392309124Sdim // If the Decl is on a function, add function parameters to the scope. 393309124Sdim HasFunScope = D->isFunctionOrFunctionTemplate(); 394309124Sdim FnScope = new Parser::ParseScope(&P, Scope::FnScope | Scope::DeclScope, 395309124Sdim HasFunScope); 396309124Sdim if (HasFunScope) 397309124Sdim Actions.ActOnReenterFunctionContext(Actions.getCurScope(), D); 398309124Sdim } 399309124Sdim ~FNContextRAII() { 400309124Sdim if (HasFunScope) { 401309124Sdim P.getActions().ActOnExitFunctionContext(); 402309124Sdim FnScope->Exit(); // Pop scope, and remove Decls from IdResolver 403309124Sdim } 404309124Sdim if (HasTemplateScope) 405309124Sdim TempScope->Exit(); 406309124Sdim delete FnScope; 407309124Sdim delete TempScope; 408309124Sdim delete ThisScope; 409309124Sdim } 410309124Sdim}; 411309124Sdim} // namespace 412309124Sdim 413309124Sdim/// Parses clauses for 'declare simd' directive. 414309124Sdim/// clause: 415309124Sdim/// 'inbranch' | 'notinbranch' 416309124Sdim/// 'simdlen' '(' <expr> ')' 417309124Sdim/// { 'uniform' '(' <argument_list> ')' } 418309124Sdim/// { 'aligned '(' <argument_list> [ ':' <alignment> ] ')' } 419309124Sdim/// { 'linear '(' <argument_list> [ ':' <step> ] ')' } 420309124Sdimstatic bool parseDeclareSimdClauses( 421309124Sdim Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, ExprResult &SimdLen, 422309124Sdim SmallVectorImpl<Expr *> &Uniforms, SmallVectorImpl<Expr *> &Aligneds, 423309124Sdim SmallVectorImpl<Expr *> &Alignments, SmallVectorImpl<Expr *> &Linears, 424309124Sdim SmallVectorImpl<unsigned> &LinModifiers, SmallVectorImpl<Expr *> &Steps) { 425309124Sdim SourceRange BSRange; 426309124Sdim const Token &Tok = P.getCurToken(); 427309124Sdim bool IsError = false; 428309124Sdim while (Tok.isNot(tok::annot_pragma_openmp_end)) { 429309124Sdim if (Tok.isNot(tok::identifier)) 430309124Sdim break; 431309124Sdim OMPDeclareSimdDeclAttr::BranchStateTy Out; 432309124Sdim IdentifierInfo *II = Tok.getIdentifierInfo(); 433309124Sdim StringRef ClauseName = II->getName(); 434309124Sdim // Parse 'inranch|notinbranch' clauses. 435309124Sdim if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) { 436309124Sdim if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) { 437309124Sdim P.Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch) 438309124Sdim << ClauseName 439309124Sdim << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange; 440309124Sdim IsError = true; 441309124Sdim } 442309124Sdim BS = Out; 443309124Sdim BSRange = SourceRange(Tok.getLocation(), Tok.getEndLoc()); 444309124Sdim P.ConsumeToken(); 445309124Sdim } else if (ClauseName.equals("simdlen")) { 446309124Sdim if (SimdLen.isUsable()) { 447309124Sdim P.Diag(Tok, diag::err_omp_more_one_clause) 448309124Sdim << getOpenMPDirectiveName(OMPD_declare_simd) << ClauseName << 0; 449309124Sdim IsError = true; 450309124Sdim } 451309124Sdim P.ConsumeToken(); 452309124Sdim SourceLocation RLoc; 453309124Sdim SimdLen = P.ParseOpenMPParensExpr(ClauseName, RLoc); 454309124Sdim if (SimdLen.isInvalid()) 455309124Sdim IsError = true; 456309124Sdim } else { 457309124Sdim OpenMPClauseKind CKind = getOpenMPClauseKind(ClauseName); 458309124Sdim if (CKind == OMPC_uniform || CKind == OMPC_aligned || 459309124Sdim CKind == OMPC_linear) { 460309124Sdim Parser::OpenMPVarListDataTy Data; 461309124Sdim auto *Vars = &Uniforms; 462309124Sdim if (CKind == OMPC_aligned) 463309124Sdim Vars = &Aligneds; 464309124Sdim else if (CKind == OMPC_linear) 465309124Sdim Vars = &Linears; 466309124Sdim 467309124Sdim P.ConsumeToken(); 468309124Sdim if (P.ParseOpenMPVarList(OMPD_declare_simd, 469309124Sdim getOpenMPClauseKind(ClauseName), *Vars, Data)) 470309124Sdim IsError = true; 471309124Sdim if (CKind == OMPC_aligned) 472309124Sdim Alignments.append(Aligneds.size() - Alignments.size(), Data.TailExpr); 473309124Sdim else if (CKind == OMPC_linear) { 474309124Sdim if (P.getActions().CheckOpenMPLinearModifier(Data.LinKind, 475309124Sdim Data.DepLinMapLoc)) 476309124Sdim Data.LinKind = OMPC_LINEAR_val; 477309124Sdim LinModifiers.append(Linears.size() - LinModifiers.size(), 478309124Sdim Data.LinKind); 479309124Sdim Steps.append(Linears.size() - Steps.size(), Data.TailExpr); 480309124Sdim } 481309124Sdim } else 482309124Sdim // TODO: add parsing of other clauses. 483309124Sdim break; 484309124Sdim } 485309124Sdim // Skip ',' if any. 486309124Sdim if (Tok.is(tok::comma)) 487309124Sdim P.ConsumeToken(); 488309124Sdim } 489309124Sdim return IsError; 490309124Sdim} 491309124Sdim 492309124Sdim/// Parse clauses for '#pragma omp declare simd'. 493309124SdimParser::DeclGroupPtrTy 494309124SdimParser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr, 495309124Sdim CachedTokens &Toks, SourceLocation Loc) { 496309124Sdim PP.EnterToken(Tok); 497309124Sdim PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true); 498309124Sdim // Consume the previously pushed token. 499309124Sdim ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true); 500309124Sdim 501309124Sdim FNContextRAII FnContext(*this, Ptr); 502309124Sdim OMPDeclareSimdDeclAttr::BranchStateTy BS = 503309124Sdim OMPDeclareSimdDeclAttr::BS_Undefined; 504309124Sdim ExprResult Simdlen; 505309124Sdim SmallVector<Expr *, 4> Uniforms; 506309124Sdim SmallVector<Expr *, 4> Aligneds; 507309124Sdim SmallVector<Expr *, 4> Alignments; 508309124Sdim SmallVector<Expr *, 4> Linears; 509309124Sdim SmallVector<unsigned, 4> LinModifiers; 510309124Sdim SmallVector<Expr *, 4> Steps; 511309124Sdim bool IsError = 512309124Sdim parseDeclareSimdClauses(*this, BS, Simdlen, Uniforms, Aligneds, 513309124Sdim Alignments, Linears, LinModifiers, Steps); 514309124Sdim // Need to check for extra tokens. 515309124Sdim if (Tok.isNot(tok::annot_pragma_openmp_end)) { 516309124Sdim Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 517309124Sdim << getOpenMPDirectiveName(OMPD_declare_simd); 518309124Sdim while (Tok.isNot(tok::annot_pragma_openmp_end)) 519309124Sdim ConsumeAnyToken(); 520309124Sdim } 521309124Sdim // Skip the last annot_pragma_openmp_end. 522309124Sdim SourceLocation EndLoc = ConsumeToken(); 523309124Sdim if (!IsError) { 524309124Sdim return Actions.ActOnOpenMPDeclareSimdDirective( 525309124Sdim Ptr, BS, Simdlen.get(), Uniforms, Aligneds, Alignments, Linears, 526309124Sdim LinModifiers, Steps, SourceRange(Loc, EndLoc)); 527309124Sdim } 528309124Sdim return Ptr; 529309124Sdim} 530309124Sdim 531261991Sdim/// \brief Parsing of declarative OpenMP directives. 532249261Sdim/// 533261991Sdim/// threadprivate-directive: 534261991Sdim/// annot_pragma_openmp 'threadprivate' simple-variable-list 535309124Sdim/// annot_pragma_openmp_end 536261991Sdim/// 537309124Sdim/// declare-reduction-directive: 538309124Sdim/// annot_pragma_openmp 'declare' 'reduction' [...] 539309124Sdim/// annot_pragma_openmp_end 540309124Sdim/// 541309124Sdim/// declare-simd-directive: 542309124Sdim/// annot_pragma_openmp 'declare simd' {<clause> [,]} 543309124Sdim/// annot_pragma_openmp_end 544309124Sdim/// <function declaration/definition> 545309124Sdim/// 546309124SdimParser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl( 547309124Sdim AccessSpecifier &AS, ParsedAttributesWithRange &Attrs, 548309124Sdim DeclSpec::TST TagType, Decl *Tag) { 549249261Sdim assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!"); 550261991Sdim ParenBraceBracketBalancer BalancerRAIIObj(*this); 551249261Sdim 552249261Sdim SourceLocation Loc = ConsumeToken(); 553276479Sdim auto DKind = ParseOpenMPDirectiveKind(*this); 554261991Sdim 555261991Sdim switch (DKind) { 556309124Sdim case OMPD_threadprivate: { 557249261Sdim ConsumeToken(); 558309124Sdim ThreadprivateListParserHelper Helper(this); 559309124Sdim if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Helper, true)) { 560249261Sdim // The last seen token is annot_pragma_openmp_end - need to check for 561249261Sdim // extra tokens. 562249261Sdim if (Tok.isNot(tok::annot_pragma_openmp_end)) { 563249261Sdim Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 564276479Sdim << getOpenMPDirectiveName(OMPD_threadprivate); 565261991Sdim SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 566249261Sdim } 567261991Sdim // Skip the last annot_pragma_openmp_end. 568249261Sdim ConsumeToken(); 569309124Sdim return Actions.ActOnOpenMPThreadprivateDirective(Loc, 570309124Sdim Helper.getIdentifiers()); 571249261Sdim } 572249261Sdim break; 573309124Sdim } 574309124Sdim case OMPD_declare_reduction: 575309124Sdim ConsumeToken(); 576309124Sdim if (auto Res = ParseOpenMPDeclareReductionDirective(AS)) { 577309124Sdim // The last seen token is annot_pragma_openmp_end - need to check for 578309124Sdim // extra tokens. 579309124Sdim if (Tok.isNot(tok::annot_pragma_openmp_end)) { 580309124Sdim Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 581309124Sdim << getOpenMPDirectiveName(OMPD_declare_reduction); 582309124Sdim while (Tok.isNot(tok::annot_pragma_openmp_end)) 583309124Sdim ConsumeAnyToken(); 584309124Sdim } 585309124Sdim // Skip the last annot_pragma_openmp_end. 586309124Sdim ConsumeToken(); 587309124Sdim return Res; 588309124Sdim } 589309124Sdim break; 590309124Sdim case OMPD_declare_simd: { 591309124Sdim // The syntax is: 592309124Sdim // { #pragma omp declare simd } 593309124Sdim // <function-declaration-or-definition> 594309124Sdim // 595309124Sdim ConsumeToken(); 596309124Sdim CachedTokens Toks; 597309124Sdim while(Tok.isNot(tok::annot_pragma_openmp_end)) { 598309124Sdim Toks.push_back(Tok); 599309124Sdim ConsumeAnyToken(); 600309124Sdim } 601309124Sdim Toks.push_back(Tok); 602309124Sdim ConsumeAnyToken(); 603309124Sdim 604309124Sdim DeclGroupPtrTy Ptr; 605309124Sdim if (Tok.is(tok::annot_pragma_openmp)) 606309124Sdim Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, TagType, Tag); 607309124Sdim else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) { 608309124Sdim // Here we expect to see some function declaration. 609309124Sdim if (AS == AS_none) { 610309124Sdim assert(TagType == DeclSpec::TST_unspecified); 611309124Sdim MaybeParseCXX11Attributes(Attrs); 612309124Sdim MaybeParseMicrosoftAttributes(Attrs); 613309124Sdim ParsingDeclSpec PDS(*this); 614309124Sdim Ptr = ParseExternalDeclaration(Attrs, &PDS); 615309124Sdim } else { 616309124Sdim Ptr = 617309124Sdim ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag); 618309124Sdim } 619309124Sdim } 620309124Sdim if (!Ptr) { 621309124Sdim Diag(Loc, diag::err_omp_decl_in_declare_simd); 622309124Sdim return DeclGroupPtrTy(); 623309124Sdim } 624309124Sdim return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc); 625309124Sdim } 626309124Sdim case OMPD_declare_target: { 627309124Sdim SourceLocation DTLoc = ConsumeAnyToken(); 628309124Sdim if (Tok.isNot(tok::annot_pragma_openmp_end)) { 629309124Sdim // OpenMP 4.5 syntax with list of entities. 630309124Sdim llvm::SmallSetVector<const NamedDecl*, 16> SameDirectiveDecls; 631309124Sdim while (Tok.isNot(tok::annot_pragma_openmp_end)) { 632309124Sdim OMPDeclareTargetDeclAttr::MapTypeTy MT = 633309124Sdim OMPDeclareTargetDeclAttr::MT_To; 634309124Sdim if (Tok.is(tok::identifier)) { 635309124Sdim IdentifierInfo *II = Tok.getIdentifierInfo(); 636309124Sdim StringRef ClauseName = II->getName(); 637309124Sdim // Parse 'to|link' clauses. 638309124Sdim if (!OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, 639309124Sdim MT)) { 640309124Sdim Diag(Tok, diag::err_omp_declare_target_unexpected_clause) 641309124Sdim << ClauseName; 642309124Sdim break; 643309124Sdim } 644309124Sdim ConsumeToken(); 645309124Sdim } 646309124Sdim auto Callback = [this, MT, &SameDirectiveDecls]( 647309124Sdim CXXScopeSpec &SS, DeclarationNameInfo NameInfo) { 648309124Sdim Actions.ActOnOpenMPDeclareTargetName(getCurScope(), SS, NameInfo, MT, 649309124Sdim SameDirectiveDecls); 650309124Sdim }; 651309124Sdim if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback, true)) 652309124Sdim break; 653309124Sdim 654309124Sdim // Consume optional ','. 655309124Sdim if (Tok.is(tok::comma)) 656309124Sdim ConsumeToken(); 657309124Sdim } 658309124Sdim SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 659309124Sdim ConsumeAnyToken(); 660309124Sdim return DeclGroupPtrTy(); 661309124Sdim } 662309124Sdim 663309124Sdim // Skip the last annot_pragma_openmp_end. 664309124Sdim ConsumeAnyToken(); 665309124Sdim 666309124Sdim if (!Actions.ActOnStartOpenMPDeclareTargetDirective(DTLoc)) 667309124Sdim return DeclGroupPtrTy(); 668309124Sdim 669309124Sdim DKind = ParseOpenMPDirectiveKind(*this); 670309124Sdim while (DKind != OMPD_end_declare_target && DKind != OMPD_declare_target && 671309124Sdim Tok.isNot(tok::eof) && Tok.isNot(tok::r_brace)) { 672309124Sdim ParsedAttributesWithRange attrs(AttrFactory); 673309124Sdim MaybeParseCXX11Attributes(attrs); 674309124Sdim MaybeParseMicrosoftAttributes(attrs); 675309124Sdim ParseExternalDeclaration(attrs); 676309124Sdim if (Tok.isAnnotation() && Tok.is(tok::annot_pragma_openmp)) { 677309124Sdim TentativeParsingAction TPA(*this); 678309124Sdim ConsumeToken(); 679309124Sdim DKind = ParseOpenMPDirectiveKind(*this); 680309124Sdim if (DKind != OMPD_end_declare_target) 681309124Sdim TPA.Revert(); 682309124Sdim else 683309124Sdim TPA.Commit(); 684309124Sdim } 685309124Sdim } 686309124Sdim 687309124Sdim if (DKind == OMPD_end_declare_target) { 688309124Sdim ConsumeAnyToken(); 689309124Sdim if (Tok.isNot(tok::annot_pragma_openmp_end)) { 690309124Sdim Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 691309124Sdim << getOpenMPDirectiveName(OMPD_end_declare_target); 692309124Sdim SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 693309124Sdim } 694309124Sdim // Skip the last annot_pragma_openmp_end. 695309124Sdim ConsumeAnyToken(); 696309124Sdim } else { 697309124Sdim Diag(Tok, diag::err_expected_end_declare_target); 698309124Sdim Diag(DTLoc, diag::note_matching) << "'#pragma omp declare target'"; 699309124Sdim } 700309124Sdim Actions.ActOnFinishOpenMPDeclareTargetDirective(); 701309124Sdim return DeclGroupPtrTy(); 702309124Sdim } 703249261Sdim case OMPD_unknown: 704249261Sdim Diag(Tok, diag::err_omp_unknown_directive); 705249261Sdim break; 706261991Sdim case OMPD_parallel: 707276479Sdim case OMPD_simd: 708261991Sdim case OMPD_task: 709276479Sdim case OMPD_taskyield: 710276479Sdim case OMPD_barrier: 711276479Sdim case OMPD_taskwait: 712288943Sdim case OMPD_taskgroup: 713276479Sdim case OMPD_flush: 714276479Sdim case OMPD_for: 715280031Sdim case OMPD_for_simd: 716276479Sdim case OMPD_sections: 717276479Sdim case OMPD_section: 718276479Sdim case OMPD_single: 719276479Sdim case OMPD_master: 720280031Sdim case OMPD_ordered: 721276479Sdim case OMPD_critical: 722276479Sdim case OMPD_parallel_for: 723280031Sdim case OMPD_parallel_for_simd: 724276479Sdim case OMPD_parallel_sections: 725280031Sdim case OMPD_atomic: 726280031Sdim case OMPD_target: 727280031Sdim case OMPD_teams: 728288943Sdim case OMPD_cancellation_point: 729288943Sdim case OMPD_cancel: 730296417Sdim case OMPD_target_data: 731309124Sdim case OMPD_target_enter_data: 732309124Sdim case OMPD_target_exit_data: 733309124Sdim case OMPD_target_parallel: 734309124Sdim case OMPD_target_parallel_for: 735296417Sdim case OMPD_taskloop: 736296417Sdim case OMPD_taskloop_simd: 737296417Sdim case OMPD_distribute: 738309124Sdim case OMPD_end_declare_target: 739309124Sdim case OMPD_target_update: 740309124Sdim case OMPD_distribute_parallel_for: 741309124Sdim case OMPD_distribute_parallel_for_simd: 742309124Sdim case OMPD_distribute_simd: 743309124Sdim case OMPD_target_parallel_for_simd: 744249261Sdim Diag(Tok, diag::err_omp_unexpected_directive) 745276479Sdim << getOpenMPDirectiveName(DKind); 746249261Sdim break; 747249261Sdim } 748309124Sdim while (Tok.isNot(tok::annot_pragma_openmp_end)) 749309124Sdim ConsumeAnyToken(); 750309124Sdim ConsumeAnyToken(); 751309124Sdim return nullptr; 752249261Sdim} 753249261Sdim 754261991Sdim/// \brief Parsing of declarative or executable OpenMP directives. 755261991Sdim/// 756261991Sdim/// threadprivate-directive: 757261991Sdim/// annot_pragma_openmp 'threadprivate' simple-variable-list 758261991Sdim/// annot_pragma_openmp_end 759261991Sdim/// 760309124Sdim/// declare-reduction-directive: 761309124Sdim/// annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':' 762309124Sdim/// <type> {',' <type>} ':' <expression> ')' ['initializer' '(' 763309124Sdim/// ('omp_priv' '=' <expression>|<function_call>) ')'] 764309124Sdim/// annot_pragma_openmp_end 765309124Sdim/// 766276479Sdim/// executable-directive: 767276479Sdim/// annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' | 768276479Sdim/// 'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] | 769276479Sdim/// 'parallel for' | 'parallel sections' | 'task' | 'taskyield' | 770280031Sdim/// 'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' | 771296417Sdim/// 'for simd' | 'parallel for simd' | 'target' | 'target data' | 772309124Sdim/// 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' | 773309124Sdim/// 'distribute' | 'target enter data' | 'target exit data' | 774309124Sdim/// 'target parallel' | 'target parallel for' | 775309124Sdim/// 'target update' | 'distribute parallel for' | 776309124Sdim/// 'distribute paralle for simd' | 'distribute simd' | 777309124Sdim/// 'target parallel for simd' {clause} 778280031Sdim/// annot_pragma_openmp_end 779261991Sdim/// 780296417SdimStmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective( 781296417Sdim AllowedContsructsKind Allowed) { 782261991Sdim assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!"); 783261991Sdim ParenBraceBracketBalancer BalancerRAIIObj(*this); 784261991Sdim SmallVector<OMPClause *, 5> Clauses; 785276479Sdim SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1> 786276479Sdim FirstClauses(OMPC_unknown + 1); 787276479Sdim unsigned ScopeFlags = 788276479Sdim Scope::FnScope | Scope::DeclScope | Scope::OpenMPDirectiveScope; 789261991Sdim SourceLocation Loc = ConsumeToken(), EndLoc; 790276479Sdim auto DKind = ParseOpenMPDirectiveKind(*this); 791288943Sdim OpenMPDirectiveKind CancelRegion = OMPD_unknown; 792261991Sdim // Name of critical directive. 793261991Sdim DeclarationNameInfo DirName; 794261991Sdim StmtResult Directive = StmtError(); 795276479Sdim bool HasAssociatedStatement = true; 796276479Sdim bool FlushHasClause = false; 797261991Sdim 798261991Sdim switch (DKind) { 799309124Sdim case OMPD_threadprivate: { 800296417Sdim if (Allowed != ACK_Any) { 801296417Sdim Diag(Tok, diag::err_omp_immediate_directive) 802296417Sdim << getOpenMPDirectiveName(DKind) << 0; 803296417Sdim } 804261991Sdim ConsumeToken(); 805309124Sdim ThreadprivateListParserHelper Helper(this); 806309124Sdim if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Helper, false)) { 807261991Sdim // The last seen token is annot_pragma_openmp_end - need to check for 808261991Sdim // extra tokens. 809261991Sdim if (Tok.isNot(tok::annot_pragma_openmp_end)) { 810261991Sdim Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 811276479Sdim << getOpenMPDirectiveName(OMPD_threadprivate); 812261991Sdim SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 813261991Sdim } 814309124Sdim DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective( 815309124Sdim Loc, Helper.getIdentifiers()); 816261991Sdim Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation()); 817261991Sdim } 818261991Sdim SkipUntil(tok::annot_pragma_openmp_end); 819261991Sdim break; 820309124Sdim } 821309124Sdim case OMPD_declare_reduction: 822309124Sdim ConsumeToken(); 823309124Sdim if (auto Res = ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) { 824309124Sdim // The last seen token is annot_pragma_openmp_end - need to check for 825309124Sdim // extra tokens. 826309124Sdim if (Tok.isNot(tok::annot_pragma_openmp_end)) { 827309124Sdim Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 828309124Sdim << getOpenMPDirectiveName(OMPD_declare_reduction); 829309124Sdim while (Tok.isNot(tok::annot_pragma_openmp_end)) 830309124Sdim ConsumeAnyToken(); 831309124Sdim } 832309124Sdim ConsumeAnyToken(); 833309124Sdim Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation()); 834309124Sdim } else 835309124Sdim SkipUntil(tok::annot_pragma_openmp_end); 836309124Sdim break; 837276479Sdim case OMPD_flush: 838276479Sdim if (PP.LookAhead(0).is(tok::l_paren)) { 839276479Sdim FlushHasClause = true; 840276479Sdim // Push copy of the current token back to stream to properly parse 841276479Sdim // pseudo-clause OMPFlushClause. 842276479Sdim PP.EnterToken(Tok); 843276479Sdim } 844276479Sdim case OMPD_taskyield: 845276479Sdim case OMPD_barrier: 846276479Sdim case OMPD_taskwait: 847288943Sdim case OMPD_cancellation_point: 848288943Sdim case OMPD_cancel: 849309124Sdim case OMPD_target_enter_data: 850309124Sdim case OMPD_target_exit_data: 851309124Sdim case OMPD_target_update: 852296417Sdim if (Allowed == ACK_StatementsOpenMPNonStandalone) { 853276479Sdim Diag(Tok, diag::err_omp_immediate_directive) 854296417Sdim << getOpenMPDirectiveName(DKind) << 0; 855276479Sdim } 856276479Sdim HasAssociatedStatement = false; 857276479Sdim // Fall through for further analysis. 858276479Sdim case OMPD_parallel: 859276479Sdim case OMPD_simd: 860276479Sdim case OMPD_for: 861280031Sdim case OMPD_for_simd: 862276479Sdim case OMPD_sections: 863276479Sdim case OMPD_single: 864276479Sdim case OMPD_section: 865276479Sdim case OMPD_master: 866276479Sdim case OMPD_critical: 867276479Sdim case OMPD_parallel_for: 868280031Sdim case OMPD_parallel_for_simd: 869276479Sdim case OMPD_parallel_sections: 870280031Sdim case OMPD_task: 871280031Sdim case OMPD_ordered: 872280031Sdim case OMPD_atomic: 873280031Sdim case OMPD_target: 874288943Sdim case OMPD_teams: 875296417Sdim case OMPD_taskgroup: 876296417Sdim case OMPD_target_data: 877309124Sdim case OMPD_target_parallel: 878309124Sdim case OMPD_target_parallel_for: 879296417Sdim case OMPD_taskloop: 880296417Sdim case OMPD_taskloop_simd: 881309124Sdim case OMPD_distribute: 882309124Sdim case OMPD_distribute_parallel_for: 883309124Sdim case OMPD_distribute_parallel_for_simd: 884309124Sdim case OMPD_distribute_simd: 885309124Sdim case OMPD_target_parallel_for_simd: { 886261991Sdim ConsumeToken(); 887276479Sdim // Parse directive name of the 'critical' directive if any. 888276479Sdim if (DKind == OMPD_critical) { 889276479Sdim BalancedDelimiterTracker T(*this, tok::l_paren, 890276479Sdim tok::annot_pragma_openmp_end); 891276479Sdim if (!T.consumeOpen()) { 892276479Sdim if (Tok.isAnyIdentifier()) { 893276479Sdim DirName = 894276479Sdim DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation()); 895276479Sdim ConsumeAnyToken(); 896276479Sdim } else { 897276479Sdim Diag(Tok, diag::err_omp_expected_identifier_for_critical); 898276479Sdim } 899276479Sdim T.consumeClose(); 900276479Sdim } 901288943Sdim } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) { 902288943Sdim CancelRegion = ParseOpenMPDirectiveKind(*this); 903288943Sdim if (Tok.isNot(tok::annot_pragma_openmp_end)) 904288943Sdim ConsumeToken(); 905276479Sdim } 906261991Sdim 907276479Sdim if (isOpenMPLoopDirective(DKind)) 908276479Sdim ScopeFlags |= Scope::OpenMPLoopDirectiveScope; 909276479Sdim if (isOpenMPSimdDirective(DKind)) 910276479Sdim ScopeFlags |= Scope::OpenMPSimdDirectiveScope; 911276479Sdim ParseScope OMPDirectiveScope(this, ScopeFlags); 912276479Sdim Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc); 913261991Sdim 914261991Sdim while (Tok.isNot(tok::annot_pragma_openmp_end)) { 915276479Sdim OpenMPClauseKind CKind = 916276479Sdim Tok.isAnnotation() 917276479Sdim ? OMPC_unknown 918276479Sdim : FlushHasClause ? OMPC_flush 919276479Sdim : getOpenMPClauseKind(PP.getSpelling(Tok)); 920288943Sdim Actions.StartOpenMPClause(CKind); 921276479Sdim FlushHasClause = false; 922276479Sdim OMPClause *Clause = 923276479Sdim ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt()); 924261991Sdim FirstClauses[CKind].setInt(true); 925261991Sdim if (Clause) { 926261991Sdim FirstClauses[CKind].setPointer(Clause); 927261991Sdim Clauses.push_back(Clause); 928261991Sdim } 929261991Sdim 930261991Sdim // Skip ',' if any. 931261991Sdim if (Tok.is(tok::comma)) 932261991Sdim ConsumeToken(); 933288943Sdim Actions.EndOpenMPClause(); 934261991Sdim } 935261991Sdim // End location of the directive. 936261991Sdim EndLoc = Tok.getLocation(); 937261991Sdim // Consume final annot_pragma_openmp_end. 938261991Sdim ConsumeToken(); 939261991Sdim 940296417Sdim // OpenMP [2.13.8, ordered Construct, Syntax] 941296417Sdim // If the depend clause is specified, the ordered construct is a stand-alone 942296417Sdim // directive. 943296417Sdim if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) { 944296417Sdim if (Allowed == ACK_StatementsOpenMPNonStandalone) { 945296417Sdim Diag(Loc, diag::err_omp_immediate_directive) 946296417Sdim << getOpenMPDirectiveName(DKind) << 1 947296417Sdim << getOpenMPClauseName(OMPC_depend); 948296417Sdim } 949296417Sdim HasAssociatedStatement = false; 950296417Sdim } 951296417Sdim 952261991Sdim StmtResult AssociatedStmt; 953276479Sdim if (HasAssociatedStatement) { 954261991Sdim // The body is a block scope like in Lambdas and Blocks. 955261991Sdim Sema::CompoundScopeRAII CompoundScope(Actions); 956276479Sdim Actions.ActOnOpenMPRegionStart(DKind, getCurScope()); 957261991Sdim Actions.ActOnStartOfCompoundStmt(); 958261991Sdim // Parse statement 959261991Sdim AssociatedStmt = ParseStatement(); 960261991Sdim Actions.ActOnFinishOfCompoundStmt(); 961288943Sdim AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses); 962261991Sdim } 963296417Sdim Directive = Actions.ActOnOpenMPExecutableDirective( 964296417Sdim DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc, 965296417Sdim EndLoc); 966261991Sdim 967261991Sdim // Exit scope. 968261991Sdim Actions.EndOpenMPDSABlock(Directive.get()); 969261991Sdim OMPDirectiveScope.Exit(); 970261991Sdim break; 971276479Sdim } 972309124Sdim case OMPD_declare_simd: 973309124Sdim case OMPD_declare_target: 974309124Sdim case OMPD_end_declare_target: 975309124Sdim Diag(Tok, diag::err_omp_unexpected_directive) 976309124Sdim << getOpenMPDirectiveName(DKind); 977309124Sdim SkipUntil(tok::annot_pragma_openmp_end); 978309124Sdim break; 979261991Sdim case OMPD_unknown: 980261991Sdim Diag(Tok, diag::err_omp_unknown_directive); 981261991Sdim SkipUntil(tok::annot_pragma_openmp_end); 982261991Sdim break; 983261991Sdim } 984261991Sdim return Directive; 985261991Sdim} 986261991Sdim 987309124Sdim// Parses simple list: 988309124Sdim// simple-variable-list: 989309124Sdim// '(' id-expression {, id-expression} ')' 990309124Sdim// 991309124Sdimbool Parser::ParseOpenMPSimpleVarList( 992309124Sdim OpenMPDirectiveKind Kind, 993309124Sdim const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> & 994309124Sdim Callback, 995309124Sdim bool AllowScopeSpecifier) { 996249261Sdim // Parse '('. 997261991Sdim BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); 998261991Sdim if (T.expectAndConsume(diag::err_expected_lparen_after, 999261991Sdim getOpenMPDirectiveName(Kind))) 1000261991Sdim return true; 1001249261Sdim bool IsCorrect = true; 1002261991Sdim bool NoIdentIsFound = true; 1003249261Sdim 1004249261Sdim // Read tokens while ')' or annot_pragma_openmp_end is not found. 1005261991Sdim while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) { 1006249261Sdim CXXScopeSpec SS; 1007249261Sdim SourceLocation TemplateKWLoc; 1008249261Sdim UnqualifiedId Name; 1009249261Sdim // Read var name. 1010249261Sdim Token PrevTok = Tok; 1011261991Sdim NoIdentIsFound = false; 1012249261Sdim 1013261991Sdim if (AllowScopeSpecifier && getLangOpts().CPlusPlus && 1014309124Sdim ParseOptionalCXXScopeSpecifier(SS, nullptr, false)) { 1015249261Sdim IsCorrect = false; 1016249261Sdim SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, 1017261991Sdim StopBeforeMatch); 1018309124Sdim } else if (ParseUnqualifiedId(SS, false, false, false, nullptr, 1019261991Sdim TemplateKWLoc, Name)) { 1020249261Sdim IsCorrect = false; 1021249261Sdim SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, 1022261991Sdim StopBeforeMatch); 1023261991Sdim } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) && 1024261991Sdim Tok.isNot(tok::annot_pragma_openmp_end)) { 1025261991Sdim IsCorrect = false; 1026261991Sdim SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, 1027261991Sdim StopBeforeMatch); 1028276479Sdim Diag(PrevTok.getLocation(), diag::err_expected) 1029276479Sdim << tok::identifier 1030276479Sdim << SourceRange(PrevTok.getLocation(), PrevTokLocation); 1031249261Sdim } else { 1032309124Sdim Callback(SS, Actions.GetNameFromUnqualifiedId(Name)); 1033249261Sdim } 1034249261Sdim // Consume ','. 1035249261Sdim if (Tok.is(tok::comma)) { 1036249261Sdim ConsumeToken(); 1037249261Sdim } 1038261991Sdim } 1039249261Sdim 1040261991Sdim if (NoIdentIsFound) { 1041276479Sdim Diag(Tok, diag::err_expected) << tok::identifier; 1042261991Sdim IsCorrect = false; 1043249261Sdim } 1044249261Sdim 1045261991Sdim // Parse ')'. 1046261991Sdim IsCorrect = !T.consumeClose() && IsCorrect; 1047261991Sdim 1048309124Sdim return !IsCorrect; 1049249261Sdim} 1050261991Sdim 1051261991Sdim/// \brief Parsing of OpenMP clauses. 1052261991Sdim/// 1053261991Sdim/// clause: 1054276479Sdim/// if-clause | final-clause | num_threads-clause | safelen-clause | 1055276479Sdim/// default-clause | private-clause | firstprivate-clause | shared-clause 1056276479Sdim/// | linear-clause | aligned-clause | collapse-clause | 1057276479Sdim/// lastprivate-clause | reduction-clause | proc_bind-clause | 1058276479Sdim/// schedule-clause | copyin-clause | copyprivate-clause | untied-clause | 1059280031Sdim/// mergeable-clause | flush-clause | read-clause | write-clause | 1060296417Sdim/// update-clause | capture-clause | seq_cst-clause | device-clause | 1061296417Sdim/// simdlen-clause | threads-clause | simd-clause | num_teams-clause | 1062296417Sdim/// thread_limit-clause | priority-clause | grainsize-clause | 1063309124Sdim/// nogroup-clause | num_tasks-clause | hint-clause | to-clause | 1064309124Sdim/// from-clause | is_device_ptr-clause 1065261991Sdim/// 1066261991SdimOMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, 1067261991Sdim OpenMPClauseKind CKind, bool FirstClause) { 1068276479Sdim OMPClause *Clause = nullptr; 1069261991Sdim bool ErrorFound = false; 1070261991Sdim // Check if clause is allowed for the given directive. 1071261991Sdim if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) { 1072276479Sdim Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind) 1073276479Sdim << getOpenMPDirectiveName(DKind); 1074261991Sdim ErrorFound = true; 1075261991Sdim } 1076261991Sdim 1077261991Sdim switch (CKind) { 1078276479Sdim case OMPC_final: 1079276479Sdim case OMPC_num_threads: 1080276479Sdim case OMPC_safelen: 1081296417Sdim case OMPC_simdlen: 1082276479Sdim case OMPC_collapse: 1083296417Sdim case OMPC_ordered: 1084296417Sdim case OMPC_device: 1085296417Sdim case OMPC_num_teams: 1086296417Sdim case OMPC_thread_limit: 1087296417Sdim case OMPC_priority: 1088296417Sdim case OMPC_grainsize: 1089296417Sdim case OMPC_num_tasks: 1090296417Sdim case OMPC_hint: 1091276479Sdim // OpenMP [2.5, Restrictions] 1092276479Sdim // At most one num_threads clause can appear on the directive. 1093276479Sdim // OpenMP [2.8.1, simd construct, Restrictions] 1094276479Sdim // Only one safelen clause can appear on a simd directive. 1095296417Sdim // Only one simdlen clause can appear on a simd directive. 1096276479Sdim // Only one collapse clause can appear on a simd directive. 1097296417Sdim // OpenMP [2.9.1, target data construct, Restrictions] 1098296417Sdim // At most one device clause can appear on the directive. 1099276479Sdim // OpenMP [2.11.1, task Construct, Restrictions] 1100276479Sdim // At most one if clause can appear on the directive. 1101276479Sdim // At most one final clause can appear on the directive. 1102296417Sdim // OpenMP [teams Construct, Restrictions] 1103296417Sdim // At most one num_teams clause can appear on the directive. 1104296417Sdim // At most one thread_limit clause can appear on the directive. 1105296417Sdim // OpenMP [2.9.1, task Construct, Restrictions] 1106296417Sdim // At most one priority clause can appear on the directive. 1107296417Sdim // OpenMP [2.9.2, taskloop Construct, Restrictions] 1108296417Sdim // At most one grainsize clause can appear on the directive. 1109296417Sdim // OpenMP [2.9.2, taskloop Construct, Restrictions] 1110296417Sdim // At most one num_tasks clause can appear on the directive. 1111276479Sdim if (!FirstClause) { 1112296417Sdim Diag(Tok, diag::err_omp_more_one_clause) 1113296417Sdim << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; 1114280031Sdim ErrorFound = true; 1115276479Sdim } 1116276479Sdim 1117296417Sdim if (CKind == OMPC_ordered && PP.LookAhead(/*N=*/0).isNot(tok::l_paren)) 1118296417Sdim Clause = ParseOpenMPClause(CKind); 1119296417Sdim else 1120296417Sdim Clause = ParseOpenMPSingleExprClause(CKind); 1121276479Sdim break; 1122261991Sdim case OMPC_default: 1123276479Sdim case OMPC_proc_bind: 1124276479Sdim // OpenMP [2.14.3.1, Restrictions] 1125276479Sdim // Only a single default clause may be specified on a parallel, task or 1126276479Sdim // teams directive. 1127276479Sdim // OpenMP [2.5, parallel Construct, Restrictions] 1128276479Sdim // At most one proc_bind clause can appear on the directive. 1129261991Sdim if (!FirstClause) { 1130296417Sdim Diag(Tok, diag::err_omp_more_one_clause) 1131296417Sdim << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; 1132280031Sdim ErrorFound = true; 1133261991Sdim } 1134261991Sdim 1135261991Sdim Clause = ParseOpenMPSimpleClause(CKind); 1136261991Sdim break; 1137276479Sdim case OMPC_schedule: 1138309124Sdim case OMPC_dist_schedule: 1139309124Sdim case OMPC_defaultmap: 1140276479Sdim // OpenMP [2.7.1, Restrictions, p. 3] 1141276479Sdim // Only one schedule clause can appear on a loop directive. 1142309124Sdim // OpenMP [2.10.4, Restrictions, p. 106] 1143309124Sdim // At most one defaultmap clause can appear on the directive. 1144276479Sdim if (!FirstClause) { 1145296417Sdim Diag(Tok, diag::err_omp_more_one_clause) 1146296417Sdim << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; 1147280031Sdim ErrorFound = true; 1148276479Sdim } 1149276479Sdim 1150296417Sdim case OMPC_if: 1151276479Sdim Clause = ParseOpenMPSingleExprWithArgClause(CKind); 1152276479Sdim break; 1153276479Sdim case OMPC_nowait: 1154276479Sdim case OMPC_untied: 1155276479Sdim case OMPC_mergeable: 1156280031Sdim case OMPC_read: 1157280031Sdim case OMPC_write: 1158280031Sdim case OMPC_update: 1159280031Sdim case OMPC_capture: 1160280031Sdim case OMPC_seq_cst: 1161296417Sdim case OMPC_threads: 1162296417Sdim case OMPC_simd: 1163296417Sdim case OMPC_nogroup: 1164276479Sdim // OpenMP [2.7.1, Restrictions, p. 9] 1165276479Sdim // Only one ordered clause can appear on a loop directive. 1166276479Sdim // OpenMP [2.7.1, Restrictions, C/C++, p. 4] 1167276479Sdim // Only one nowait clause can appear on a for directive. 1168276479Sdim if (!FirstClause) { 1169296417Sdim Diag(Tok, diag::err_omp_more_one_clause) 1170296417Sdim << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0; 1171280031Sdim ErrorFound = true; 1172276479Sdim } 1173276479Sdim 1174276479Sdim Clause = ParseOpenMPClause(CKind); 1175276479Sdim break; 1176261991Sdim case OMPC_private: 1177261991Sdim case OMPC_firstprivate: 1178276479Sdim case OMPC_lastprivate: 1179261991Sdim case OMPC_shared: 1180276479Sdim case OMPC_reduction: 1181276479Sdim case OMPC_linear: 1182276479Sdim case OMPC_aligned: 1183276479Sdim case OMPC_copyin: 1184276479Sdim case OMPC_copyprivate: 1185276479Sdim case OMPC_flush: 1186288943Sdim case OMPC_depend: 1187296417Sdim case OMPC_map: 1188309124Sdim case OMPC_to: 1189309124Sdim case OMPC_from: 1190309124Sdim case OMPC_use_device_ptr: 1191309124Sdim case OMPC_is_device_ptr: 1192296417Sdim Clause = ParseOpenMPVarListClause(DKind, CKind); 1193261991Sdim break; 1194261991Sdim case OMPC_unknown: 1195261991Sdim Diag(Tok, diag::warn_omp_extra_tokens_at_eol) 1196276479Sdim << getOpenMPDirectiveName(DKind); 1197261991Sdim SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch); 1198261991Sdim break; 1199261991Sdim case OMPC_threadprivate: 1200309124Sdim case OMPC_uniform: 1201276479Sdim Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind) 1202276479Sdim << getOpenMPDirectiveName(DKind); 1203261991Sdim SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch); 1204261991Sdim break; 1205261991Sdim } 1206276479Sdim return ErrorFound ? nullptr : Clause; 1207261991Sdim} 1208261991Sdim 1209309124Sdim/// Parses simple expression in parens for single-expression clauses of OpenMP 1210309124Sdim/// constructs. 1211309124Sdim/// \param RLoc Returned location of right paren. 1212309124SdimExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName, 1213309124Sdim SourceLocation &RLoc) { 1214309124Sdim BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); 1215309124Sdim if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data())) 1216309124Sdim return ExprError(); 1217309124Sdim 1218309124Sdim SourceLocation ELoc = Tok.getLocation(); 1219309124Sdim ExprResult LHS(ParseCastExpression( 1220309124Sdim /*isUnaryExpression=*/false, /*isAddressOfOperand=*/false, NotTypeCast)); 1221309124Sdim ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional)); 1222309124Sdim Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc); 1223309124Sdim 1224309124Sdim // Parse ')'. 1225309124Sdim T.consumeClose(); 1226309124Sdim 1227309124Sdim RLoc = T.getCloseLocation(); 1228309124Sdim return Val; 1229309124Sdim} 1230309124Sdim 1231296417Sdim/// \brief Parsing of OpenMP clauses with single expressions like 'final', 1232296417Sdim/// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams', 1233296417Sdim/// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks' or 'hint'. 1234261991Sdim/// 1235276479Sdim/// final-clause: 1236276479Sdim/// 'final' '(' expression ')' 1237276479Sdim/// 1238276479Sdim/// num_threads-clause: 1239276479Sdim/// 'num_threads' '(' expression ')' 1240276479Sdim/// 1241276479Sdim/// safelen-clause: 1242276479Sdim/// 'safelen' '(' expression ')' 1243276479Sdim/// 1244296417Sdim/// simdlen-clause: 1245296417Sdim/// 'simdlen' '(' expression ')' 1246296417Sdim/// 1247276479Sdim/// collapse-clause: 1248276479Sdim/// 'collapse' '(' expression ')' 1249276479Sdim/// 1250296417Sdim/// priority-clause: 1251296417Sdim/// 'priority' '(' expression ')' 1252296417Sdim/// 1253296417Sdim/// grainsize-clause: 1254296417Sdim/// 'grainsize' '(' expression ')' 1255296417Sdim/// 1256296417Sdim/// num_tasks-clause: 1257296417Sdim/// 'num_tasks' '(' expression ')' 1258296417Sdim/// 1259296417Sdim/// hint-clause: 1260296417Sdim/// 'hint' '(' expression ')' 1261296417Sdim/// 1262276479SdimOMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind) { 1263276479Sdim SourceLocation Loc = ConsumeToken(); 1264309124Sdim SourceLocation LLoc = Tok.getLocation(); 1265309124Sdim SourceLocation RLoc; 1266276479Sdim 1267309124Sdim ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc); 1268276479Sdim 1269276479Sdim if (Val.isInvalid()) 1270276479Sdim return nullptr; 1271276479Sdim 1272309124Sdim return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc); 1273276479Sdim} 1274276479Sdim 1275276479Sdim/// \brief Parsing of simple OpenMP clauses like 'default' or 'proc_bind'. 1276276479Sdim/// 1277261991Sdim/// default-clause: 1278261991Sdim/// 'default' '(' 'none' | 'shared' ') 1279261991Sdim/// 1280276479Sdim/// proc_bind-clause: 1281276479Sdim/// 'proc_bind' '(' 'master' | 'close' | 'spread' ') 1282276479Sdim/// 1283261991SdimOMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) { 1284261991Sdim SourceLocation Loc = Tok.getLocation(); 1285261991Sdim SourceLocation LOpen = ConsumeToken(); 1286261991Sdim // Parse '('. 1287261991Sdim BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); 1288261991Sdim if (T.expectAndConsume(diag::err_expected_lparen_after, 1289261991Sdim getOpenMPClauseName(Kind))) 1290276479Sdim return nullptr; 1291261991Sdim 1292276479Sdim unsigned Type = getOpenMPSimpleClauseType( 1293276479Sdim Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)); 1294261991Sdim SourceLocation TypeLoc = Tok.getLocation(); 1295261991Sdim if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && 1296261991Sdim Tok.isNot(tok::annot_pragma_openmp_end)) 1297261991Sdim ConsumeAnyToken(); 1298261991Sdim 1299261991Sdim // Parse ')'. 1300261991Sdim T.consumeClose(); 1301261991Sdim 1302261991Sdim return Actions.ActOnOpenMPSimpleClause(Kind, Type, TypeLoc, LOpen, Loc, 1303261991Sdim Tok.getLocation()); 1304261991Sdim} 1305261991Sdim 1306276479Sdim/// \brief Parsing of OpenMP clauses like 'ordered'. 1307261991Sdim/// 1308276479Sdim/// ordered-clause: 1309276479Sdim/// 'ordered' 1310276479Sdim/// 1311276479Sdim/// nowait-clause: 1312276479Sdim/// 'nowait' 1313276479Sdim/// 1314276479Sdim/// untied-clause: 1315276479Sdim/// 'untied' 1316276479Sdim/// 1317276479Sdim/// mergeable-clause: 1318276479Sdim/// 'mergeable' 1319276479Sdim/// 1320280031Sdim/// read-clause: 1321280031Sdim/// 'read' 1322280031Sdim/// 1323296417Sdim/// threads-clause: 1324296417Sdim/// 'threads' 1325296417Sdim/// 1326296417Sdim/// simd-clause: 1327296417Sdim/// 'simd' 1328296417Sdim/// 1329296417Sdim/// nogroup-clause: 1330296417Sdim/// 'nogroup' 1331296417Sdim/// 1332276479SdimOMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind) { 1333276479Sdim SourceLocation Loc = Tok.getLocation(); 1334276479Sdim ConsumeAnyToken(); 1335276479Sdim 1336276479Sdim return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation()); 1337276479Sdim} 1338276479Sdim 1339276479Sdim 1340276479Sdim/// \brief Parsing of OpenMP clauses with single expressions and some additional 1341276479Sdim/// argument like 'schedule' or 'dist_schedule'. 1342276479Sdim/// 1343276479Sdim/// schedule-clause: 1344296417Sdim/// 'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ] 1345296417Sdim/// ')' 1346276479Sdim/// 1347296417Sdim/// if-clause: 1348296417Sdim/// 'if' '(' [ directive-name-modifier ':' ] expression ')' 1349296417Sdim/// 1350309124Sdim/// defaultmap: 1351309124Sdim/// 'defaultmap' '(' modifier ':' kind ')' 1352309124Sdim/// 1353276479SdimOMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind) { 1354276479Sdim SourceLocation Loc = ConsumeToken(); 1355296417Sdim SourceLocation DelimLoc; 1356276479Sdim // Parse '('. 1357276479Sdim BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); 1358276479Sdim if (T.expectAndConsume(diag::err_expected_lparen_after, 1359276479Sdim getOpenMPClauseName(Kind))) 1360276479Sdim return nullptr; 1361276479Sdim 1362276479Sdim ExprResult Val; 1363296417Sdim SmallVector<unsigned, 4> Arg; 1364296417Sdim SmallVector<SourceLocation, 4> KLoc; 1365296417Sdim if (Kind == OMPC_schedule) { 1366296417Sdim enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 1367296417Sdim Arg.resize(NumberOfElements); 1368296417Sdim KLoc.resize(NumberOfElements); 1369296417Sdim Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown; 1370296417Sdim Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown; 1371296417Sdim Arg[ScheduleKind] = OMPC_SCHEDULE_unknown; 1372296417Sdim auto KindModifier = getOpenMPSimpleClauseType( 1373296417Sdim Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)); 1374296417Sdim if (KindModifier > OMPC_SCHEDULE_unknown) { 1375296417Sdim // Parse 'modifier' 1376296417Sdim Arg[Modifier1] = KindModifier; 1377296417Sdim KLoc[Modifier1] = Tok.getLocation(); 1378296417Sdim if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && 1379296417Sdim Tok.isNot(tok::annot_pragma_openmp_end)) 1380296417Sdim ConsumeAnyToken(); 1381296417Sdim if (Tok.is(tok::comma)) { 1382296417Sdim // Parse ',' 'modifier' 1383296417Sdim ConsumeAnyToken(); 1384296417Sdim KindModifier = getOpenMPSimpleClauseType( 1385296417Sdim Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)); 1386296417Sdim Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown 1387296417Sdim ? KindModifier 1388296417Sdim : (unsigned)OMPC_SCHEDULE_unknown; 1389296417Sdim KLoc[Modifier2] = Tok.getLocation(); 1390296417Sdim if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && 1391296417Sdim Tok.isNot(tok::annot_pragma_openmp_end)) 1392296417Sdim ConsumeAnyToken(); 1393296417Sdim } 1394296417Sdim // Parse ':' 1395296417Sdim if (Tok.is(tok::colon)) 1396296417Sdim ConsumeAnyToken(); 1397296417Sdim else 1398296417Sdim Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier"; 1399296417Sdim KindModifier = getOpenMPSimpleClauseType( 1400296417Sdim Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)); 1401296417Sdim } 1402296417Sdim Arg[ScheduleKind] = KindModifier; 1403296417Sdim KLoc[ScheduleKind] = Tok.getLocation(); 1404296417Sdim if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && 1405296417Sdim Tok.isNot(tok::annot_pragma_openmp_end)) 1406296417Sdim ConsumeAnyToken(); 1407296417Sdim if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static || 1408296417Sdim Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic || 1409296417Sdim Arg[ScheduleKind] == OMPC_SCHEDULE_guided) && 1410296417Sdim Tok.is(tok::comma)) 1411296417Sdim DelimLoc = ConsumeAnyToken(); 1412309124Sdim } else if (Kind == OMPC_dist_schedule) { 1413309124Sdim Arg.push_back(getOpenMPSimpleClauseType( 1414309124Sdim Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok))); 1415309124Sdim KLoc.push_back(Tok.getLocation()); 1416309124Sdim if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && 1417309124Sdim Tok.isNot(tok::annot_pragma_openmp_end)) 1418309124Sdim ConsumeAnyToken(); 1419309124Sdim if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma)) 1420309124Sdim DelimLoc = ConsumeAnyToken(); 1421309124Sdim } else if (Kind == OMPC_defaultmap) { 1422309124Sdim // Get a defaultmap modifier 1423309124Sdim Arg.push_back(getOpenMPSimpleClauseType( 1424309124Sdim Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok))); 1425309124Sdim KLoc.push_back(Tok.getLocation()); 1426309124Sdim if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && 1427309124Sdim Tok.isNot(tok::annot_pragma_openmp_end)) 1428309124Sdim ConsumeAnyToken(); 1429309124Sdim // Parse ':' 1430309124Sdim if (Tok.is(tok::colon)) 1431309124Sdim ConsumeAnyToken(); 1432309124Sdim else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown) 1433309124Sdim Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier"; 1434309124Sdim // Get a defaultmap kind 1435309124Sdim Arg.push_back(getOpenMPSimpleClauseType( 1436309124Sdim Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok))); 1437309124Sdim KLoc.push_back(Tok.getLocation()); 1438309124Sdim if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) && 1439309124Sdim Tok.isNot(tok::annot_pragma_openmp_end)) 1440309124Sdim ConsumeAnyToken(); 1441296417Sdim } else { 1442296417Sdim assert(Kind == OMPC_if); 1443296417Sdim KLoc.push_back(Tok.getLocation()); 1444296417Sdim Arg.push_back(ParseOpenMPDirectiveKind(*this)); 1445296417Sdim if (Arg.back() != OMPD_unknown) { 1446296417Sdim ConsumeToken(); 1447296417Sdim if (Tok.is(tok::colon)) 1448296417Sdim DelimLoc = ConsumeToken(); 1449296417Sdim else 1450296417Sdim Diag(Tok, diag::warn_pragma_expected_colon) 1451296417Sdim << "directive name modifier"; 1452296417Sdim } 1453296417Sdim } 1454276479Sdim 1455309124Sdim bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) || 1456309124Sdim (Kind == OMPC_dist_schedule && DelimLoc.isValid()) || 1457309124Sdim Kind == OMPC_if; 1458296417Sdim if (NeedAnExpression) { 1459296417Sdim SourceLocation ELoc = Tok.getLocation(); 1460276479Sdim ExprResult LHS(ParseCastExpression(false, false, NotTypeCast)); 1461276479Sdim Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional); 1462296417Sdim Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc); 1463276479Sdim } 1464276479Sdim 1465276479Sdim // Parse ')'. 1466276479Sdim T.consumeClose(); 1467276479Sdim 1468296417Sdim if (NeedAnExpression && Val.isInvalid()) 1469296417Sdim return nullptr; 1470296417Sdim 1471276479Sdim return Actions.ActOnOpenMPSingleExprWithArgClause( 1472296417Sdim Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, 1473276479Sdim T.getCloseLocation()); 1474276479Sdim} 1475276479Sdim 1476276479Sdimstatic bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec, 1477276479Sdim UnqualifiedId &ReductionId) { 1478276479Sdim SourceLocation TemplateKWLoc; 1479276479Sdim if (ReductionIdScopeSpec.isEmpty()) { 1480276479Sdim auto OOK = OO_None; 1481276479Sdim switch (P.getCurToken().getKind()) { 1482276479Sdim case tok::plus: 1483276479Sdim OOK = OO_Plus; 1484276479Sdim break; 1485276479Sdim case tok::minus: 1486276479Sdim OOK = OO_Minus; 1487276479Sdim break; 1488276479Sdim case tok::star: 1489276479Sdim OOK = OO_Star; 1490276479Sdim break; 1491276479Sdim case tok::amp: 1492276479Sdim OOK = OO_Amp; 1493276479Sdim break; 1494276479Sdim case tok::pipe: 1495276479Sdim OOK = OO_Pipe; 1496276479Sdim break; 1497276479Sdim case tok::caret: 1498276479Sdim OOK = OO_Caret; 1499276479Sdim break; 1500276479Sdim case tok::ampamp: 1501276479Sdim OOK = OO_AmpAmp; 1502276479Sdim break; 1503276479Sdim case tok::pipepipe: 1504276479Sdim OOK = OO_PipePipe; 1505276479Sdim break; 1506276479Sdim default: 1507276479Sdim break; 1508276479Sdim } 1509276479Sdim if (OOK != OO_None) { 1510276479Sdim SourceLocation OpLoc = P.ConsumeToken(); 1511276479Sdim SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()}; 1512276479Sdim ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations); 1513276479Sdim return false; 1514276479Sdim } 1515276479Sdim } 1516276479Sdim return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false, 1517276479Sdim /*AllowDestructorName*/ false, 1518309124Sdim /*AllowConstructorName*/ false, nullptr, 1519276479Sdim TemplateKWLoc, ReductionId); 1520276479Sdim} 1521276479Sdim 1522309124Sdim/// Parses clauses with list. 1523309124Sdimbool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, 1524309124Sdim OpenMPClauseKind Kind, 1525309124Sdim SmallVectorImpl<Expr *> &Vars, 1526309124Sdim OpenMPVarListDataTy &Data) { 1527309124Sdim UnqualifiedId UnqualifiedReductionId; 1528276479Sdim bool InvalidReductionId = false; 1529296417Sdim bool MapTypeModifierSpecified = false; 1530288943Sdim 1531261991Sdim // Parse '('. 1532261991Sdim BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end); 1533261991Sdim if (T.expectAndConsume(diag::err_expected_lparen_after, 1534261991Sdim getOpenMPClauseName(Kind))) 1535309124Sdim return true; 1536261991Sdim 1537296417Sdim bool NeedRParenForLinear = false; 1538296417Sdim BalancedDelimiterTracker LinearT(*this, tok::l_paren, 1539296417Sdim tok::annot_pragma_openmp_end); 1540276479Sdim // Handle reduction-identifier for reduction clause. 1541276479Sdim if (Kind == OMPC_reduction) { 1542276479Sdim ColonProtectionRAIIObject ColonRAII(*this); 1543309124Sdim if (getLangOpts().CPlusPlus) 1544309124Sdim ParseOptionalCXXScopeSpecifier(Data.ReductionIdScopeSpec, 1545309124Sdim /*ObjectType=*/nullptr, 1546309124Sdim /*EnteringContext=*/false); 1547309124Sdim InvalidReductionId = ParseReductionId(*this, Data.ReductionIdScopeSpec, 1548309124Sdim UnqualifiedReductionId); 1549276479Sdim if (InvalidReductionId) { 1550276479Sdim SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end, 1551276479Sdim StopBeforeMatch); 1552276479Sdim } 1553309124Sdim if (Tok.is(tok::colon)) 1554309124Sdim Data.ColonLoc = ConsumeToken(); 1555309124Sdim else 1556276479Sdim Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier"; 1557309124Sdim if (!InvalidReductionId) 1558309124Sdim Data.ReductionId = 1559309124Sdim Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId); 1560288943Sdim } else if (Kind == OMPC_depend) { 1561288943Sdim // Handle dependency type for depend clause. 1562288943Sdim ColonProtectionRAIIObject ColonRAII(*this); 1563309124Sdim Data.DepKind = 1564309124Sdim static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType( 1565309124Sdim Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : "")); 1566309124Sdim Data.DepLinMapLoc = Tok.getLocation(); 1567288943Sdim 1568309124Sdim if (Data.DepKind == OMPC_DEPEND_unknown) { 1569288943Sdim SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end, 1570288943Sdim StopBeforeMatch); 1571288943Sdim } else { 1572288943Sdim ConsumeToken(); 1573296417Sdim // Special processing for depend(source) clause. 1574309124Sdim if (DKind == OMPD_ordered && Data.DepKind == OMPC_DEPEND_source) { 1575296417Sdim // Parse ')'. 1576296417Sdim T.consumeClose(); 1577309124Sdim return false; 1578296417Sdim } 1579288943Sdim } 1580309124Sdim if (Tok.is(tok::colon)) 1581309124Sdim Data.ColonLoc = ConsumeToken(); 1582309124Sdim else { 1583296417Sdim Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren 1584296417Sdim : diag::warn_pragma_expected_colon) 1585296417Sdim << "dependency type"; 1586288943Sdim } 1587296417Sdim } else if (Kind == OMPC_linear) { 1588296417Sdim // Try to parse modifier if any. 1589296417Sdim if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) { 1590309124Sdim Data.LinKind = static_cast<OpenMPLinearClauseKind>( 1591296417Sdim getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))); 1592309124Sdim Data.DepLinMapLoc = ConsumeToken(); 1593296417Sdim LinearT.consumeOpen(); 1594296417Sdim NeedRParenForLinear = true; 1595296417Sdim } 1596296417Sdim } else if (Kind == OMPC_map) { 1597296417Sdim // Handle map type for map clause. 1598296417Sdim ColonProtectionRAIIObject ColonRAII(*this); 1599296417Sdim 1600309124Sdim /// The map clause modifier token can be either a identifier or the C++ 1601309124Sdim /// delete keyword. 1602309124Sdim auto &&IsMapClauseModifierToken = [](const Token &Tok) -> bool { 1603309124Sdim return Tok.isOneOf(tok::identifier, tok::kw_delete); 1604309124Sdim }; 1605309124Sdim 1606309124Sdim // The first identifier may be a list item, a map-type or a 1607309124Sdim // map-type-modifier. The map modifier can also be delete which has the same 1608309124Sdim // spelling of the C++ delete keyword. 1609309124Sdim Data.MapType = 1610309124Sdim IsMapClauseModifierToken(Tok) 1611309124Sdim ? static_cast<OpenMPMapClauseKind>( 1612309124Sdim getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))) 1613309124Sdim : OMPC_MAP_unknown; 1614309124Sdim Data.DepLinMapLoc = Tok.getLocation(); 1615296417Sdim bool ColonExpected = false; 1616296417Sdim 1617309124Sdim if (IsMapClauseModifierToken(Tok)) { 1618296417Sdim if (PP.LookAhead(0).is(tok::colon)) { 1619309124Sdim if (Data.MapType == OMPC_MAP_unknown) 1620296417Sdim Diag(Tok, diag::err_omp_unknown_map_type); 1621309124Sdim else if (Data.MapType == OMPC_MAP_always) 1622296417Sdim Diag(Tok, diag::err_omp_map_type_missing); 1623296417Sdim ConsumeToken(); 1624296417Sdim } else if (PP.LookAhead(0).is(tok::comma)) { 1625309124Sdim if (IsMapClauseModifierToken(PP.LookAhead(1)) && 1626296417Sdim PP.LookAhead(2).is(tok::colon)) { 1627309124Sdim Data.MapTypeModifier = Data.MapType; 1628309124Sdim if (Data.MapTypeModifier != OMPC_MAP_always) { 1629296417Sdim Diag(Tok, diag::err_omp_unknown_map_type_modifier); 1630309124Sdim Data.MapTypeModifier = OMPC_MAP_unknown; 1631309124Sdim } else 1632296417Sdim MapTypeModifierSpecified = true; 1633296417Sdim 1634296417Sdim ConsumeToken(); 1635296417Sdim ConsumeToken(); 1636296417Sdim 1637309124Sdim Data.MapType = 1638309124Sdim IsMapClauseModifierToken(Tok) 1639309124Sdim ? static_cast<OpenMPMapClauseKind>( 1640309124Sdim getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))) 1641309124Sdim : OMPC_MAP_unknown; 1642309124Sdim if (Data.MapType == OMPC_MAP_unknown || 1643309124Sdim Data.MapType == OMPC_MAP_always) 1644296417Sdim Diag(Tok, diag::err_omp_unknown_map_type); 1645296417Sdim ConsumeToken(); 1646296417Sdim } else { 1647309124Sdim Data.MapType = OMPC_MAP_tofrom; 1648309124Sdim Data.IsMapTypeImplicit = true; 1649296417Sdim } 1650296417Sdim } else { 1651309124Sdim Data.MapType = OMPC_MAP_tofrom; 1652309124Sdim Data.IsMapTypeImplicit = true; 1653296417Sdim } 1654296417Sdim } else { 1655309124Sdim Data.MapType = OMPC_MAP_tofrom; 1656309124Sdim Data.IsMapTypeImplicit = true; 1657296417Sdim } 1658296417Sdim 1659309124Sdim if (Tok.is(tok::colon)) 1660309124Sdim Data.ColonLoc = ConsumeToken(); 1661309124Sdim else if (ColonExpected) 1662296417Sdim Diag(Tok, diag::warn_pragma_expected_colon) << "map type"; 1663276479Sdim } 1664276479Sdim 1665296417Sdim bool IsComma = 1666309124Sdim (Kind != OMPC_reduction && Kind != OMPC_depend && Kind != OMPC_map) || 1667309124Sdim (Kind == OMPC_reduction && !InvalidReductionId) || 1668309124Sdim (Kind == OMPC_map && Data.MapType != OMPC_MAP_unknown && 1669296417Sdim (!MapTypeModifierSpecified || 1670309124Sdim Data.MapTypeModifier == OMPC_MAP_always)) || 1671309124Sdim (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown); 1672276479Sdim const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned); 1673276479Sdim while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) && 1674261991Sdim Tok.isNot(tok::annot_pragma_openmp_end))) { 1675276479Sdim ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail); 1676261991Sdim // Parse variable 1677280031Sdim ExprResult VarExpr = 1678280031Sdim Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression()); 1679309124Sdim if (VarExpr.isUsable()) 1680276479Sdim Vars.push_back(VarExpr.get()); 1681309124Sdim else { 1682261991Sdim SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, 1683261991Sdim StopBeforeMatch); 1684261991Sdim } 1685261991Sdim // Skip ',' if any 1686261991Sdim IsComma = Tok.is(tok::comma); 1687276479Sdim if (IsComma) 1688261991Sdim ConsumeToken(); 1689276479Sdim else if (Tok.isNot(tok::r_paren) && 1690276479Sdim Tok.isNot(tok::annot_pragma_openmp_end) && 1691276479Sdim (!MayHaveTail || Tok.isNot(tok::colon))) 1692261991Sdim Diag(Tok, diag::err_omp_expected_punc) 1693276479Sdim << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush) 1694276479Sdim : getOpenMPClauseName(Kind)) 1695276479Sdim << (Kind == OMPC_flush); 1696261991Sdim } 1697261991Sdim 1698296417Sdim // Parse ')' for linear clause with modifier. 1699296417Sdim if (NeedRParenForLinear) 1700296417Sdim LinearT.consumeClose(); 1701296417Sdim 1702276479Sdim // Parse ':' linear-step (or ':' alignment). 1703276479Sdim const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon); 1704276479Sdim if (MustHaveTail) { 1705309124Sdim Data.ColonLoc = Tok.getLocation(); 1706296417Sdim SourceLocation ELoc = ConsumeToken(); 1707296417Sdim ExprResult Tail = ParseAssignmentExpression(); 1708296417Sdim Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc); 1709276479Sdim if (Tail.isUsable()) 1710309124Sdim Data.TailExpr = Tail.get(); 1711276479Sdim else 1712276479Sdim SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end, 1713276479Sdim StopBeforeMatch); 1714276479Sdim } 1715276479Sdim 1716261991Sdim // Parse ')'. 1717261991Sdim T.consumeClose(); 1718309124Sdim if ((Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown && 1719309124Sdim Vars.empty()) || 1720309124Sdim (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) || 1721309124Sdim (MustHaveTail && !Data.TailExpr) || InvalidReductionId) 1722309124Sdim return true; 1723309124Sdim return false; 1724309124Sdim} 1725309124Sdim 1726309124Sdim/// \brief Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate', 1727309124Sdim/// 'shared', 'copyin', 'copyprivate', 'flush' or 'reduction'. 1728309124Sdim/// 1729309124Sdim/// private-clause: 1730309124Sdim/// 'private' '(' list ')' 1731309124Sdim/// firstprivate-clause: 1732309124Sdim/// 'firstprivate' '(' list ')' 1733309124Sdim/// lastprivate-clause: 1734309124Sdim/// 'lastprivate' '(' list ')' 1735309124Sdim/// shared-clause: 1736309124Sdim/// 'shared' '(' list ')' 1737309124Sdim/// linear-clause: 1738309124Sdim/// 'linear' '(' linear-list [ ':' linear-step ] ')' 1739309124Sdim/// aligned-clause: 1740309124Sdim/// 'aligned' '(' list [ ':' alignment ] ')' 1741309124Sdim/// reduction-clause: 1742309124Sdim/// 'reduction' '(' reduction-identifier ':' list ')' 1743309124Sdim/// copyprivate-clause: 1744309124Sdim/// 'copyprivate' '(' list ')' 1745309124Sdim/// flush-clause: 1746309124Sdim/// 'flush' '(' list ')' 1747309124Sdim/// depend-clause: 1748309124Sdim/// 'depend' '(' in | out | inout : list | source ')' 1749309124Sdim/// map-clause: 1750309124Sdim/// 'map' '(' [ [ always , ] 1751309124Sdim/// to | from | tofrom | alloc | release | delete ':' ] list ')'; 1752309124Sdim/// to-clause: 1753309124Sdim/// 'to' '(' list ')' 1754309124Sdim/// from-clause: 1755309124Sdim/// 'from' '(' list ')' 1756309124Sdim/// use_device_ptr-clause: 1757309124Sdim/// 'use_device_ptr' '(' list ')' 1758309124Sdim/// is_device_ptr-clause: 1759309124Sdim/// 'is_device_ptr' '(' list ')' 1760309124Sdim/// 1761309124Sdim/// For 'linear' clause linear-list may have the following forms: 1762309124Sdim/// list 1763309124Sdim/// modifier(list) 1764309124Sdim/// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++). 1765309124SdimOMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind, 1766309124Sdim OpenMPClauseKind Kind) { 1767309124Sdim SourceLocation Loc = Tok.getLocation(); 1768309124Sdim SourceLocation LOpen = ConsumeToken(); 1769309124Sdim SmallVector<Expr *, 4> Vars; 1770309124Sdim OpenMPVarListDataTy Data; 1771309124Sdim 1772309124Sdim if (ParseOpenMPVarList(DKind, Kind, Vars, Data)) 1773276479Sdim return nullptr; 1774261991Sdim 1775276479Sdim return Actions.ActOnOpenMPVarListClause( 1776309124Sdim Kind, Vars, Data.TailExpr, Loc, LOpen, Data.ColonLoc, Tok.getLocation(), 1777309124Sdim Data.ReductionIdScopeSpec, Data.ReductionId, Data.DepKind, Data.LinKind, 1778309124Sdim Data.MapTypeModifier, Data.MapType, Data.IsMapTypeImplicit, 1779309124Sdim Data.DepLinMapLoc); 1780261991Sdim} 1781261991Sdim 1782