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