1 //===--- ParseOpenMP.cpp - OpenMP directives parsing ----------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file implements parsing of all OpenMP directives and clauses.
10 ///
11 //===----------------------------------------------------------------------===//
12 
13 #include "clang/AST/ASTContext.h"
14 #include "clang/AST/OpenMPClause.h"
15 #include "clang/AST/StmtOpenMP.h"
16 #include "clang/Basic/OpenMPKinds.h"
17 #include "clang/Basic/TargetInfo.h"
18 #include "clang/Basic/TokenKinds.h"
19 #include "clang/Parse/ParseDiagnostic.h"
20 #include "clang/Parse/Parser.h"
21 #include "clang/Parse/RAIIObjectsForParser.h"
22 #include "clang/Sema/Scope.h"
23 #include "llvm/ADT/PointerIntPair.h"
24 #include "llvm/ADT/StringSwitch.h"
25 #include "llvm/ADT/UniqueVector.h"
26 #include "llvm/Frontend/OpenMP/OMPContext.h"
27 
28 using namespace clang;
29 using namespace llvm::omp;
30 
31 //===----------------------------------------------------------------------===//
32 // OpenMP declarative directives.
33 //===----------------------------------------------------------------------===//
34 
35 namespace {
36 enum OpenMPDirectiveKindEx {
37   OMPD_cancellation = llvm::omp::Directive_enumSize + 1,
38   OMPD_data,
39   OMPD_declare,
40   OMPD_end,
41   OMPD_end_declare,
42   OMPD_enter,
43   OMPD_exit,
44   OMPD_point,
45   OMPD_reduction,
46   OMPD_target_enter,
47   OMPD_target_exit,
48   OMPD_update,
49   OMPD_distribute_parallel,
50   OMPD_teams_distribute_parallel,
51   OMPD_target_teams_distribute_parallel,
52   OMPD_mapper,
53   OMPD_variant,
54   OMPD_begin,
55   OMPD_begin_declare,
56 };
57 
58 // Helper to unify the enum class OpenMPDirectiveKind with its extension
59 // the OpenMPDirectiveKindEx enum which allows to use them together as if they
60 // are unsigned values.
61 struct OpenMPDirectiveKindExWrapper {
62   OpenMPDirectiveKindExWrapper(unsigned Value) : Value(Value) {}
63   OpenMPDirectiveKindExWrapper(OpenMPDirectiveKind DK) : Value(unsigned(DK)) {}
64   bool operator==(OpenMPDirectiveKindExWrapper V) const {
65     return Value == V.Value;
66   }
67   bool operator!=(OpenMPDirectiveKindExWrapper V) const {
68     return Value != V.Value;
69   }
70   bool operator==(OpenMPDirectiveKind V) const { return Value == unsigned(V); }
71   bool operator!=(OpenMPDirectiveKind V) const { return Value != unsigned(V); }
72   bool operator<(OpenMPDirectiveKind V) const { return Value < unsigned(V); }
73   operator unsigned() const { return Value; }
74   operator OpenMPDirectiveKind() const { return OpenMPDirectiveKind(Value); }
75   unsigned Value;
76 };
77 
78 class DeclDirectiveListParserHelper final {
79   SmallVector<Expr *, 4> Identifiers;
80   Parser *P;
81   OpenMPDirectiveKind Kind;
82 
83 public:
84   DeclDirectiveListParserHelper(Parser *P, OpenMPDirectiveKind Kind)
85       : P(P), Kind(Kind) {}
86   void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
87     ExprResult Res = P->getActions().ActOnOpenMPIdExpression(
88         P->getCurScope(), SS, NameInfo, Kind);
89     if (Res.isUsable())
90       Identifiers.push_back(Res.get());
91   }
92   llvm::ArrayRef<Expr *> getIdentifiers() const { return Identifiers; }
93 };
94 } // namespace
95 
96 // Map token string to extended OMP token kind that are
97 // OpenMPDirectiveKind + OpenMPDirectiveKindEx.
98 static unsigned getOpenMPDirectiveKindEx(StringRef S) {
99   OpenMPDirectiveKindExWrapper DKind = getOpenMPDirectiveKind(S);
100   if (DKind != OMPD_unknown)
101     return DKind;
102 
103   return llvm::StringSwitch<OpenMPDirectiveKindExWrapper>(S)
104       .Case("cancellation", OMPD_cancellation)
105       .Case("data", OMPD_data)
106       .Case("declare", OMPD_declare)
107       .Case("end", OMPD_end)
108       .Case("enter", OMPD_enter)
109       .Case("exit", OMPD_exit)
110       .Case("point", OMPD_point)
111       .Case("reduction", OMPD_reduction)
112       .Case("update", OMPD_update)
113       .Case("mapper", OMPD_mapper)
114       .Case("variant", OMPD_variant)
115       .Case("begin", OMPD_begin)
116       .Default(OMPD_unknown);
117 }
118 
119 static OpenMPDirectiveKindExWrapper parseOpenMPDirectiveKind(Parser &P) {
120   // Array of foldings: F[i][0] F[i][1] ===> F[i][2].
121   // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd
122   // TODO: add other combined directives in topological order.
123   static const OpenMPDirectiveKindExWrapper F[][3] = {
124       {OMPD_begin, OMPD_declare, OMPD_begin_declare},
125       {OMPD_begin, OMPD_assumes, OMPD_begin_assumes},
126       {OMPD_end, OMPD_declare, OMPD_end_declare},
127       {OMPD_end, OMPD_assumes, OMPD_end_assumes},
128       {OMPD_cancellation, OMPD_point, OMPD_cancellation_point},
129       {OMPD_declare, OMPD_reduction, OMPD_declare_reduction},
130       {OMPD_declare, OMPD_mapper, OMPD_declare_mapper},
131       {OMPD_declare, OMPD_simd, OMPD_declare_simd},
132       {OMPD_declare, OMPD_target, OMPD_declare_target},
133       {OMPD_declare, OMPD_variant, OMPD_declare_variant},
134       {OMPD_begin_declare, OMPD_target, OMPD_begin_declare_target},
135       {OMPD_begin_declare, OMPD_variant, OMPD_begin_declare_variant},
136       {OMPD_end_declare, OMPD_variant, OMPD_end_declare_variant},
137       {OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel},
138       {OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for},
139       {OMPD_distribute_parallel_for, OMPD_simd,
140        OMPD_distribute_parallel_for_simd},
141       {OMPD_distribute, OMPD_simd, OMPD_distribute_simd},
142       {OMPD_end_declare, OMPD_target, OMPD_end_declare_target},
143       {OMPD_target, OMPD_data, OMPD_target_data},
144       {OMPD_target, OMPD_enter, OMPD_target_enter},
145       {OMPD_target, OMPD_exit, OMPD_target_exit},
146       {OMPD_target, OMPD_update, OMPD_target_update},
147       {OMPD_target_enter, OMPD_data, OMPD_target_enter_data},
148       {OMPD_target_exit, OMPD_data, OMPD_target_exit_data},
149       {OMPD_for, OMPD_simd, OMPD_for_simd},
150       {OMPD_parallel, OMPD_for, OMPD_parallel_for},
151       {OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},
152       {OMPD_parallel, OMPD_sections, OMPD_parallel_sections},
153       {OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd},
154       {OMPD_target, OMPD_parallel, OMPD_target_parallel},
155       {OMPD_target, OMPD_simd, OMPD_target_simd},
156       {OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for},
157       {OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd},
158       {OMPD_teams, OMPD_distribute, OMPD_teams_distribute},
159       {OMPD_teams_distribute, OMPD_simd, OMPD_teams_distribute_simd},
160       {OMPD_teams_distribute, OMPD_parallel, OMPD_teams_distribute_parallel},
161       {OMPD_teams_distribute_parallel, OMPD_for,
162        OMPD_teams_distribute_parallel_for},
163       {OMPD_teams_distribute_parallel_for, OMPD_simd,
164        OMPD_teams_distribute_parallel_for_simd},
165       {OMPD_target, OMPD_teams, OMPD_target_teams},
166       {OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute},
167       {OMPD_target_teams_distribute, OMPD_parallel,
168        OMPD_target_teams_distribute_parallel},
169       {OMPD_target_teams_distribute, OMPD_simd,
170        OMPD_target_teams_distribute_simd},
171       {OMPD_target_teams_distribute_parallel, OMPD_for,
172        OMPD_target_teams_distribute_parallel_for},
173       {OMPD_target_teams_distribute_parallel_for, OMPD_simd,
174        OMPD_target_teams_distribute_parallel_for_simd},
175       {OMPD_master, OMPD_taskloop, OMPD_master_taskloop},
176       {OMPD_master_taskloop, OMPD_simd, OMPD_master_taskloop_simd},
177       {OMPD_parallel, OMPD_master, OMPD_parallel_master},
178       {OMPD_parallel_master, OMPD_taskloop, OMPD_parallel_master_taskloop},
179       {OMPD_parallel_master_taskloop, OMPD_simd,
180        OMPD_parallel_master_taskloop_simd}};
181   enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };
182   Token Tok = P.getCurToken();
183   OpenMPDirectiveKindExWrapper DKind =
184       Tok.isAnnotation()
185           ? static_cast<unsigned>(OMPD_unknown)
186           : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
187   if (DKind == OMPD_unknown)
188     return OMPD_unknown;
189 
190   for (unsigned I = 0; I < llvm::array_lengthof(F); ++I) {
191     if (DKind != F[I][0])
192       continue;
193 
194     Tok = P.getPreprocessor().LookAhead(0);
195     OpenMPDirectiveKindExWrapper SDKind =
196         Tok.isAnnotation()
197             ? static_cast<unsigned>(OMPD_unknown)
198             : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
199     if (SDKind == OMPD_unknown)
200       continue;
201 
202     if (SDKind == F[I][1]) {
203       P.ConsumeToken();
204       DKind = F[I][2];
205     }
206   }
207   return unsigned(DKind) < llvm::omp::Directive_enumSize
208              ? static_cast<OpenMPDirectiveKind>(DKind)
209              : OMPD_unknown;
210 }
211 
212 static DeclarationName parseOpenMPReductionId(Parser &P) {
213   Token Tok = P.getCurToken();
214   Sema &Actions = P.getActions();
215   OverloadedOperatorKind OOK = OO_None;
216   // Allow to use 'operator' keyword for C++ operators
217   bool WithOperator = false;
218   if (Tok.is(tok::kw_operator)) {
219     P.ConsumeToken();
220     Tok = P.getCurToken();
221     WithOperator = true;
222   }
223   switch (Tok.getKind()) {
224   case tok::plus: // '+'
225     OOK = OO_Plus;
226     break;
227   case tok::minus: // '-'
228     OOK = OO_Minus;
229     break;
230   case tok::star: // '*'
231     OOK = OO_Star;
232     break;
233   case tok::amp: // '&'
234     OOK = OO_Amp;
235     break;
236   case tok::pipe: // '|'
237     OOK = OO_Pipe;
238     break;
239   case tok::caret: // '^'
240     OOK = OO_Caret;
241     break;
242   case tok::ampamp: // '&&'
243     OOK = OO_AmpAmp;
244     break;
245   case tok::pipepipe: // '||'
246     OOK = OO_PipePipe;
247     break;
248   case tok::identifier: // identifier
249     if (!WithOperator)
250       break;
251     LLVM_FALLTHROUGH;
252   default:
253     P.Diag(Tok.getLocation(), diag::err_omp_expected_reduction_identifier);
254     P.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
255                 Parser::StopBeforeMatch);
256     return DeclarationName();
257   }
258   P.ConsumeToken();
259   auto &DeclNames = Actions.getASTContext().DeclarationNames;
260   return OOK == OO_None ? DeclNames.getIdentifier(Tok.getIdentifierInfo())
261                         : DeclNames.getCXXOperatorName(OOK);
262 }
263 
264 /// Parse 'omp declare reduction' construct.
265 ///
266 ///       declare-reduction-directive:
267 ///        annot_pragma_openmp 'declare' 'reduction'
268 ///        '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')'
269 ///        ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')']
270 ///        annot_pragma_openmp_end
271 /// <reduction_id> is either a base language identifier or one of the following
272 /// operators: '+', '-', '*', '&', '|', '^', '&&' and '||'.
273 ///
274 Parser::DeclGroupPtrTy
275 Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
276   // Parse '('.
277   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
278   if (T.expectAndConsume(
279           diag::err_expected_lparen_after,
280           getOpenMPDirectiveName(OMPD_declare_reduction).data())) {
281     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
282     return DeclGroupPtrTy();
283   }
284 
285   DeclarationName Name = parseOpenMPReductionId(*this);
286   if (Name.isEmpty() && Tok.is(tok::annot_pragma_openmp_end))
287     return DeclGroupPtrTy();
288 
289   // Consume ':'.
290   bool IsCorrect = !ExpectAndConsume(tok::colon);
291 
292   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
293     return DeclGroupPtrTy();
294 
295   IsCorrect = IsCorrect && !Name.isEmpty();
296 
297   if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) {
298     Diag(Tok.getLocation(), diag::err_expected_type);
299     IsCorrect = false;
300   }
301 
302   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
303     return DeclGroupPtrTy();
304 
305   SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes;
306   // Parse list of types until ':' token.
307   do {
308     ColonProtectionRAIIObject ColonRAII(*this);
309     SourceRange Range;
310     TypeResult TR = ParseTypeName(&Range, DeclaratorContext::Prototype, AS);
311     if (TR.isUsable()) {
312       QualType ReductionType =
313           Actions.ActOnOpenMPDeclareReductionType(Range.getBegin(), TR);
314       if (!ReductionType.isNull()) {
315         ReductionTypes.push_back(
316             std::make_pair(ReductionType, Range.getBegin()));
317       }
318     } else {
319       SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
320                 StopBeforeMatch);
321     }
322 
323     if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end))
324       break;
325 
326     // Consume ','.
327     if (ExpectAndConsume(tok::comma)) {
328       IsCorrect = false;
329       if (Tok.is(tok::annot_pragma_openmp_end)) {
330         Diag(Tok.getLocation(), diag::err_expected_type);
331         return DeclGroupPtrTy();
332       }
333     }
334   } while (Tok.isNot(tok::annot_pragma_openmp_end));
335 
336   if (ReductionTypes.empty()) {
337     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
338     return DeclGroupPtrTy();
339   }
340 
341   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
342     return DeclGroupPtrTy();
343 
344   // Consume ':'.
345   if (ExpectAndConsume(tok::colon))
346     IsCorrect = false;
347 
348   if (Tok.is(tok::annot_pragma_openmp_end)) {
349     Diag(Tok.getLocation(), diag::err_expected_expression);
350     return DeclGroupPtrTy();
351   }
352 
353   DeclGroupPtrTy DRD = Actions.ActOnOpenMPDeclareReductionDirectiveStart(
354       getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes, AS);
355 
356   // Parse <combiner> expression and then parse initializer if any for each
357   // correct type.
358   unsigned I = 0, E = ReductionTypes.size();
359   for (Decl *D : DRD.get()) {
360     TentativeParsingAction TPA(*this);
361     ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
362                                     Scope::CompoundStmtScope |
363                                     Scope::OpenMPDirectiveScope);
364     // Parse <combiner> expression.
365     Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D);
366     ExprResult CombinerResult = Actions.ActOnFinishFullExpr(
367         ParseExpression().get(), D->getLocation(), /*DiscardedValue*/ false);
368     Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get());
369 
370     if (CombinerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
371         Tok.isNot(tok::annot_pragma_openmp_end)) {
372       TPA.Commit();
373       IsCorrect = false;
374       break;
375     }
376     IsCorrect = !T.consumeClose() && IsCorrect && CombinerResult.isUsable();
377     ExprResult InitializerResult;
378     if (Tok.isNot(tok::annot_pragma_openmp_end)) {
379       // Parse <initializer> expression.
380       if (Tok.is(tok::identifier) &&
381           Tok.getIdentifierInfo()->isStr("initializer")) {
382         ConsumeToken();
383       } else {
384         Diag(Tok.getLocation(), diag::err_expected) << "'initializer'";
385         TPA.Commit();
386         IsCorrect = false;
387         break;
388       }
389       // Parse '('.
390       BalancedDelimiterTracker T(*this, tok::l_paren,
391                                  tok::annot_pragma_openmp_end);
392       IsCorrect =
393           !T.expectAndConsume(diag::err_expected_lparen_after, "initializer") &&
394           IsCorrect;
395       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
396         ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
397                                         Scope::CompoundStmtScope |
398                                         Scope::OpenMPDirectiveScope);
399         // Parse expression.
400         VarDecl *OmpPrivParm =
401             Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(),
402                                                                 D);
403         // Check if initializer is omp_priv <init_expr> or something else.
404         if (Tok.is(tok::identifier) &&
405             Tok.getIdentifierInfo()->isStr("omp_priv")) {
406           ConsumeToken();
407           ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
408         } else {
409           InitializerResult = Actions.ActOnFinishFullExpr(
410               ParseAssignmentExpression().get(), D->getLocation(),
411               /*DiscardedValue*/ false);
412         }
413         Actions.ActOnOpenMPDeclareReductionInitializerEnd(
414             D, InitializerResult.get(), OmpPrivParm);
415         if (InitializerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
416             Tok.isNot(tok::annot_pragma_openmp_end)) {
417           TPA.Commit();
418           IsCorrect = false;
419           break;
420         }
421         IsCorrect =
422             !T.consumeClose() && IsCorrect && !InitializerResult.isInvalid();
423       }
424     }
425 
426     ++I;
427     // Revert parsing if not the last type, otherwise accept it, we're done with
428     // parsing.
429     if (I != E)
430       TPA.Revert();
431     else
432       TPA.Commit();
433   }
434   return Actions.ActOnOpenMPDeclareReductionDirectiveEnd(getCurScope(), DRD,
435                                                          IsCorrect);
436 }
437 
438 void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
439   // Parse declarator '=' initializer.
440   // If a '==' or '+=' is found, suggest a fixit to '='.
441   if (isTokenEqualOrEqualTypo()) {
442     ConsumeToken();
443 
444     if (Tok.is(tok::code_completion)) {
445       cutOffParsing();
446       Actions.CodeCompleteInitializer(getCurScope(), OmpPrivParm);
447       Actions.FinalizeDeclaration(OmpPrivParm);
448       return;
449     }
450 
451     PreferredType.enterVariableInit(Tok.getLocation(), OmpPrivParm);
452     ExprResult Init = ParseInitializer();
453 
454     if (Init.isInvalid()) {
455       SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
456       Actions.ActOnInitializerError(OmpPrivParm);
457     } else {
458       Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
459                                    /*DirectInit=*/false);
460     }
461   } else if (Tok.is(tok::l_paren)) {
462     // Parse C++ direct initializer: '(' expression-list ')'
463     BalancedDelimiterTracker T(*this, tok::l_paren);
464     T.consumeOpen();
465 
466     ExprVector Exprs;
467     CommaLocsTy CommaLocs;
468 
469     SourceLocation LParLoc = T.getOpenLocation();
470     auto RunSignatureHelp = [this, OmpPrivParm, LParLoc, &Exprs]() {
471       QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
472           getCurScope(), OmpPrivParm->getType()->getCanonicalTypeInternal(),
473           OmpPrivParm->getLocation(), Exprs, LParLoc);
474       CalledSignatureHelp = true;
475       return PreferredType;
476     };
477     if (ParseExpressionList(Exprs, CommaLocs, [&] {
478           PreferredType.enterFunctionArgument(Tok.getLocation(),
479                                               RunSignatureHelp);
480         })) {
481       if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
482         RunSignatureHelp();
483       Actions.ActOnInitializerError(OmpPrivParm);
484       SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
485     } else {
486       // Match the ')'.
487       SourceLocation RLoc = Tok.getLocation();
488       if (!T.consumeClose())
489         RLoc = T.getCloseLocation();
490 
491       assert(!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size() &&
492              "Unexpected number of commas!");
493 
494       ExprResult Initializer =
495           Actions.ActOnParenListExpr(T.getOpenLocation(), RLoc, Exprs);
496       Actions.AddInitializerToDecl(OmpPrivParm, Initializer.get(),
497                                    /*DirectInit=*/true);
498     }
499   } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
500     // Parse C++0x braced-init-list.
501     Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
502 
503     ExprResult Init(ParseBraceInitializer());
504 
505     if (Init.isInvalid()) {
506       Actions.ActOnInitializerError(OmpPrivParm);
507     } else {
508       Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
509                                    /*DirectInit=*/true);
510     }
511   } else {
512     Actions.ActOnUninitializedDecl(OmpPrivParm);
513   }
514 }
515 
516 /// Parses 'omp declare mapper' directive.
517 ///
518 ///       declare-mapper-directive:
519 ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifier> ':']
520 ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
521 ///         annot_pragma_openmp_end
522 /// <mapper-identifier> and <var> are base language identifiers.
523 ///
524 Parser::DeclGroupPtrTy
525 Parser::ParseOpenMPDeclareMapperDirective(AccessSpecifier AS) {
526   bool IsCorrect = true;
527   // Parse '('
528   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
529   if (T.expectAndConsume(diag::err_expected_lparen_after,
530                          getOpenMPDirectiveName(OMPD_declare_mapper).data())) {
531     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
532     return DeclGroupPtrTy();
533   }
534 
535   // Parse <mapper-identifier>
536   auto &DeclNames = Actions.getASTContext().DeclarationNames;
537   DeclarationName MapperId;
538   if (PP.LookAhead(0).is(tok::colon)) {
539     if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
540       Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
541       IsCorrect = false;
542     } else {
543       MapperId = DeclNames.getIdentifier(Tok.getIdentifierInfo());
544     }
545     ConsumeToken();
546     // Consume ':'.
547     ExpectAndConsume(tok::colon);
548   } else {
549     // If no mapper identifier is provided, its name is "default" by default
550     MapperId =
551         DeclNames.getIdentifier(&Actions.getASTContext().Idents.get("default"));
552   }
553 
554   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
555     return DeclGroupPtrTy();
556 
557   // Parse <type> <var>
558   DeclarationName VName;
559   QualType MapperType;
560   SourceRange Range;
561   TypeResult ParsedType = parseOpenMPDeclareMapperVarDecl(Range, VName, AS);
562   if (ParsedType.isUsable())
563     MapperType =
564         Actions.ActOnOpenMPDeclareMapperType(Range.getBegin(), ParsedType);
565   if (MapperType.isNull())
566     IsCorrect = false;
567   if (!IsCorrect) {
568     SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
569     return DeclGroupPtrTy();
570   }
571 
572   // Consume ')'.
573   IsCorrect &= !T.consumeClose();
574   if (!IsCorrect) {
575     SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
576     return DeclGroupPtrTy();
577   }
578 
579   // Enter scope.
580   DeclarationNameInfo DirName;
581   SourceLocation Loc = Tok.getLocation();
582   unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
583                         Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
584   ParseScope OMPDirectiveScope(this, ScopeFlags);
585   Actions.StartOpenMPDSABlock(OMPD_declare_mapper, DirName, getCurScope(), Loc);
586 
587   // Add the mapper variable declaration.
588   ExprResult MapperVarRef = Actions.ActOnOpenMPDeclareMapperDirectiveVarDecl(
589       getCurScope(), MapperType, Range.getBegin(), VName);
590 
591   // Parse map clauses.
592   SmallVector<OMPClause *, 6> Clauses;
593   while (Tok.isNot(tok::annot_pragma_openmp_end)) {
594     OpenMPClauseKind CKind = Tok.isAnnotation()
595                                  ? OMPC_unknown
596                                  : getOpenMPClauseKind(PP.getSpelling(Tok));
597     Actions.StartOpenMPClause(CKind);
598     OMPClause *Clause =
599         ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.empty());
600     if (Clause)
601       Clauses.push_back(Clause);
602     else
603       IsCorrect = false;
604     // Skip ',' if any.
605     if (Tok.is(tok::comma))
606       ConsumeToken();
607     Actions.EndOpenMPClause();
608   }
609   if (Clauses.empty()) {
610     Diag(Tok, diag::err_omp_expected_clause)
611         << getOpenMPDirectiveName(OMPD_declare_mapper);
612     IsCorrect = false;
613   }
614 
615   // Exit scope.
616   Actions.EndOpenMPDSABlock(nullptr);
617   OMPDirectiveScope.Exit();
618   DeclGroupPtrTy DG = Actions.ActOnOpenMPDeclareMapperDirective(
619       getCurScope(), Actions.getCurLexicalContext(), MapperId, MapperType,
620       Range.getBegin(), VName, AS, MapperVarRef.get(), Clauses);
621   if (!IsCorrect)
622     return DeclGroupPtrTy();
623 
624   return DG;
625 }
626 
627 TypeResult Parser::parseOpenMPDeclareMapperVarDecl(SourceRange &Range,
628                                                    DeclarationName &Name,
629                                                    AccessSpecifier AS) {
630   // Parse the common declaration-specifiers piece.
631   Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;
632   DeclSpec DS(AttrFactory);
633   ParseSpecifierQualifierList(DS, AS, DSC);
634 
635   // Parse the declarator.
636   DeclaratorContext Context = DeclaratorContext::Prototype;
637   Declarator DeclaratorInfo(DS, Context);
638   ParseDeclarator(DeclaratorInfo);
639   Range = DeclaratorInfo.getSourceRange();
640   if (DeclaratorInfo.getIdentifier() == nullptr) {
641     Diag(Tok.getLocation(), diag::err_omp_mapper_expected_declarator);
642     return true;
643   }
644   Name = Actions.GetNameForDeclarator(DeclaratorInfo).getName();
645 
646   return Actions.ActOnOpenMPDeclareMapperVarDecl(getCurScope(), DeclaratorInfo);
647 }
648 
649 namespace {
650 /// RAII that recreates function context for correct parsing of clauses of
651 /// 'declare simd' construct.
652 /// OpenMP, 2.8.2 declare simd Construct
653 /// The expressions appearing in the clauses of this directive are evaluated in
654 /// the scope of the arguments of the function declaration or definition.
655 class FNContextRAII final {
656   Parser &P;
657   Sema::CXXThisScopeRAII *ThisScope;
658   Parser::MultiParseScope Scopes;
659   bool HasFunScope = false;
660   FNContextRAII() = delete;
661   FNContextRAII(const FNContextRAII &) = delete;
662   FNContextRAII &operator=(const FNContextRAII &) = delete;
663 
664 public:
665   FNContextRAII(Parser &P, Parser::DeclGroupPtrTy Ptr) : P(P), Scopes(P) {
666     Decl *D = *Ptr.get().begin();
667     NamedDecl *ND = dyn_cast<NamedDecl>(D);
668     RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
669     Sema &Actions = P.getActions();
670 
671     // Allow 'this' within late-parsed attributes.
672     ThisScope = new Sema::CXXThisScopeRAII(Actions, RD, Qualifiers(),
673                                            ND && ND->isCXXInstanceMember());
674 
675     // If the Decl is templatized, add template parameters to scope.
676     // FIXME: Track CurTemplateDepth?
677     P.ReenterTemplateScopes(Scopes, D);
678 
679     // If the Decl is on a function, add function parameters to the scope.
680     if (D->isFunctionOrFunctionTemplate()) {
681       HasFunScope = true;
682       Scopes.Enter(Scope::FnScope | Scope::DeclScope |
683                    Scope::CompoundStmtScope);
684       Actions.ActOnReenterFunctionContext(Actions.getCurScope(), D);
685     }
686   }
687   ~FNContextRAII() {
688     if (HasFunScope)
689       P.getActions().ActOnExitFunctionContext();
690     delete ThisScope;
691   }
692 };
693 } // namespace
694 
695 /// Parses clauses for 'declare simd' directive.
696 ///    clause:
697 ///      'inbranch' | 'notinbranch'
698 ///      'simdlen' '(' <expr> ')'
699 ///      { 'uniform' '(' <argument_list> ')' }
700 ///      { 'aligned '(' <argument_list> [ ':' <alignment> ] ')' }
701 ///      { 'linear '(' <argument_list> [ ':' <step> ] ')' }
702 static bool parseDeclareSimdClauses(
703     Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, ExprResult &SimdLen,
704     SmallVectorImpl<Expr *> &Uniforms, SmallVectorImpl<Expr *> &Aligneds,
705     SmallVectorImpl<Expr *> &Alignments, SmallVectorImpl<Expr *> &Linears,
706     SmallVectorImpl<unsigned> &LinModifiers, SmallVectorImpl<Expr *> &Steps) {
707   SourceRange BSRange;
708   const Token &Tok = P.getCurToken();
709   bool IsError = false;
710   while (Tok.isNot(tok::annot_pragma_openmp_end)) {
711     if (Tok.isNot(tok::identifier))
712       break;
713     OMPDeclareSimdDeclAttr::BranchStateTy Out;
714     IdentifierInfo *II = Tok.getIdentifierInfo();
715     StringRef ClauseName = II->getName();
716     // Parse 'inranch|notinbranch' clauses.
717     if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
718       if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
719         P.Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
720             << ClauseName
721             << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
722         IsError = true;
723       }
724       BS = Out;
725       BSRange = SourceRange(Tok.getLocation(), Tok.getEndLoc());
726       P.ConsumeToken();
727     } else if (ClauseName.equals("simdlen")) {
728       if (SimdLen.isUsable()) {
729         P.Diag(Tok, diag::err_omp_more_one_clause)
730             << getOpenMPDirectiveName(OMPD_declare_simd) << ClauseName << 0;
731         IsError = true;
732       }
733       P.ConsumeToken();
734       SourceLocation RLoc;
735       SimdLen = P.ParseOpenMPParensExpr(ClauseName, RLoc);
736       if (SimdLen.isInvalid())
737         IsError = true;
738     } else {
739       OpenMPClauseKind CKind = getOpenMPClauseKind(ClauseName);
740       if (CKind == OMPC_uniform || CKind == OMPC_aligned ||
741           CKind == OMPC_linear) {
742         Parser::OpenMPVarListDataTy Data;
743         SmallVectorImpl<Expr *> *Vars = &Uniforms;
744         if (CKind == OMPC_aligned) {
745           Vars = &Aligneds;
746         } else if (CKind == OMPC_linear) {
747           Data.ExtraModifier = OMPC_LINEAR_val;
748           Vars = &Linears;
749         }
750 
751         P.ConsumeToken();
752         if (P.ParseOpenMPVarList(OMPD_declare_simd,
753                                  getOpenMPClauseKind(ClauseName), *Vars, Data))
754           IsError = true;
755         if (CKind == OMPC_aligned) {
756           Alignments.append(Aligneds.size() - Alignments.size(),
757                             Data.DepModOrTailExpr);
758         } else if (CKind == OMPC_linear) {
759           assert(0 <= Data.ExtraModifier &&
760                  Data.ExtraModifier <= OMPC_LINEAR_unknown &&
761                  "Unexpected linear modifier.");
762           if (P.getActions().CheckOpenMPLinearModifier(
763                   static_cast<OpenMPLinearClauseKind>(Data.ExtraModifier),
764                   Data.ExtraModifierLoc))
765             Data.ExtraModifier = OMPC_LINEAR_val;
766           LinModifiers.append(Linears.size() - LinModifiers.size(),
767                               Data.ExtraModifier);
768           Steps.append(Linears.size() - Steps.size(), Data.DepModOrTailExpr);
769         }
770       } else
771         // TODO: add parsing of other clauses.
772         break;
773     }
774     // Skip ',' if any.
775     if (Tok.is(tok::comma))
776       P.ConsumeToken();
777   }
778   return IsError;
779 }
780 
781 /// Parse clauses for '#pragma omp declare simd'.
782 Parser::DeclGroupPtrTy
783 Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
784                                    CachedTokens &Toks, SourceLocation Loc) {
785   PP.EnterToken(Tok, /*IsReinject*/ true);
786   PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
787                       /*IsReinject*/ true);
788   // Consume the previously pushed token.
789   ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
790   ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
791 
792   FNContextRAII FnContext(*this, Ptr);
793   OMPDeclareSimdDeclAttr::BranchStateTy BS =
794       OMPDeclareSimdDeclAttr::BS_Undefined;
795   ExprResult Simdlen;
796   SmallVector<Expr *, 4> Uniforms;
797   SmallVector<Expr *, 4> Aligneds;
798   SmallVector<Expr *, 4> Alignments;
799   SmallVector<Expr *, 4> Linears;
800   SmallVector<unsigned, 4> LinModifiers;
801   SmallVector<Expr *, 4> Steps;
802   bool IsError =
803       parseDeclareSimdClauses(*this, BS, Simdlen, Uniforms, Aligneds,
804                               Alignments, Linears, LinModifiers, Steps);
805   skipUntilPragmaOpenMPEnd(OMPD_declare_simd);
806   // Skip the last annot_pragma_openmp_end.
807   SourceLocation EndLoc = ConsumeAnnotationToken();
808   if (IsError)
809     return Ptr;
810   return Actions.ActOnOpenMPDeclareSimdDirective(
811       Ptr, BS, Simdlen.get(), Uniforms, Aligneds, Alignments, Linears,
812       LinModifiers, Steps, SourceRange(Loc, EndLoc));
813 }
814 
815 namespace {
816 /// Constant used in the diagnostics to distinguish the levels in an OpenMP
817 /// contexts: selector-set={selector(trait, ...), ...}, ....
818 enum OMPContextLvl {
819   CONTEXT_SELECTOR_SET_LVL = 0,
820   CONTEXT_SELECTOR_LVL = 1,
821   CONTEXT_TRAIT_LVL = 2,
822 };
823 
824 static StringRef stringLiteralParser(Parser &P) {
825   ExprResult Res = P.ParseStringLiteralExpression(true);
826   return Res.isUsable() ? Res.getAs<StringLiteral>()->getString() : "";
827 }
828 
829 static StringRef getNameFromIdOrString(Parser &P, Token &Tok,
830                                        OMPContextLvl Lvl) {
831   if (Tok.is(tok::identifier) || Tok.is(tok::kw_for)) {
832     llvm::SmallString<16> Buffer;
833     StringRef Name = P.getPreprocessor().getSpelling(Tok, Buffer);
834     (void)P.ConsumeToken();
835     return Name;
836   }
837 
838   if (tok::isStringLiteral(Tok.getKind()))
839     return stringLiteralParser(P);
840 
841   P.Diag(Tok.getLocation(),
842          diag::warn_omp_declare_variant_string_literal_or_identifier)
843       << Lvl;
844   return "";
845 }
846 
847 static bool checkForDuplicates(Parser &P, StringRef Name,
848                                SourceLocation NameLoc,
849                                llvm::StringMap<SourceLocation> &Seen,
850                                OMPContextLvl Lvl) {
851   auto Res = Seen.try_emplace(Name, NameLoc);
852   if (Res.second)
853     return false;
854 
855   // Each trait-set-selector-name, trait-selector-name and trait-name can
856   // only be specified once.
857   P.Diag(NameLoc, diag::warn_omp_declare_variant_ctx_mutiple_use)
858       << Lvl << Name;
859   P.Diag(Res.first->getValue(), diag::note_omp_declare_variant_ctx_used_here)
860       << Lvl << Name;
861   return true;
862 }
863 } // namespace
864 
865 void Parser::parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty,
866                                        llvm::omp::TraitSet Set,
867                                        llvm::omp::TraitSelector Selector,
868                                        llvm::StringMap<SourceLocation> &Seen) {
869   TIProperty.Kind = TraitProperty::invalid;
870 
871   SourceLocation NameLoc = Tok.getLocation();
872   StringRef Name = getNameFromIdOrString(*this, Tok, CONTEXT_TRAIT_LVL);
873   if (Name.empty()) {
874     Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
875         << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(Set, Selector);
876     return;
877   }
878 
879   TIProperty.RawString = Name;
880   TIProperty.Kind = getOpenMPContextTraitPropertyKind(Set, Selector, Name);
881   if (TIProperty.Kind != TraitProperty::invalid) {
882     if (checkForDuplicates(*this, Name, NameLoc, Seen, CONTEXT_TRAIT_LVL))
883       TIProperty.Kind = TraitProperty::invalid;
884     return;
885   }
886 
887   // It follows diagnosis and helping notes.
888   // FIXME: We should move the diagnosis string generation into libFrontend.
889   Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_property)
890       << Name << getOpenMPContextTraitSelectorName(Selector)
891       << getOpenMPContextTraitSetName(Set);
892 
893   TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
894   if (SetForName != TraitSet::invalid) {
895     Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
896         << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_TRAIT_LVL;
897     Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
898         << Name << "<selector-name>"
899         << "(<property-name>)";
900     return;
901   }
902   TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
903   if (SelectorForName != TraitSelector::invalid) {
904     Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
905         << Name << CONTEXT_SELECTOR_LVL << CONTEXT_TRAIT_LVL;
906     bool AllowsTraitScore = false;
907     bool RequiresProperty = false;
908     isValidTraitSelectorForTraitSet(
909         SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
910         AllowsTraitScore, RequiresProperty);
911     Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
912         << getOpenMPContextTraitSetName(
913                getOpenMPContextTraitSetForSelector(SelectorForName))
914         << Name << (RequiresProperty ? "(<property-name>)" : "");
915     return;
916   }
917   for (const auto &PotentialSet :
918        {TraitSet::construct, TraitSet::user, TraitSet::implementation,
919         TraitSet::device}) {
920     TraitProperty PropertyForName =
921         getOpenMPContextTraitPropertyKind(PotentialSet, Selector, Name);
922     if (PropertyForName == TraitProperty::invalid)
923       continue;
924     Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
925         << getOpenMPContextTraitSetName(
926                getOpenMPContextTraitSetForProperty(PropertyForName))
927         << getOpenMPContextTraitSelectorName(
928                getOpenMPContextTraitSelectorForProperty(PropertyForName))
929         << ("(" + Name + ")").str();
930     return;
931   }
932   Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
933       << CONTEXT_TRAIT_LVL << listOpenMPContextTraitProperties(Set, Selector);
934 }
935 
936 static bool checkExtensionProperty(Parser &P, SourceLocation Loc,
937                                    OMPTraitProperty &TIProperty,
938                                    OMPTraitSelector &TISelector,
939                                    llvm::StringMap<SourceLocation> &Seen) {
940   assert(TISelector.Kind ==
941              llvm::omp::TraitSelector::implementation_extension &&
942          "Only for extension properties, e.g., "
943          "`implementation={extension(PROPERTY)}`");
944   if (TIProperty.Kind == TraitProperty::invalid)
945     return false;
946 
947   if (TIProperty.Kind ==
948       TraitProperty::implementation_extension_disable_implicit_base)
949     return true;
950 
951   if (TIProperty.Kind ==
952       TraitProperty::implementation_extension_allow_templates)
953     return true;
954 
955   auto IsMatchExtension = [](OMPTraitProperty &TP) {
956     return (TP.Kind ==
957                 llvm::omp::TraitProperty::implementation_extension_match_all ||
958             TP.Kind ==
959                 llvm::omp::TraitProperty::implementation_extension_match_any ||
960             TP.Kind ==
961                 llvm::omp::TraitProperty::implementation_extension_match_none);
962   };
963 
964   if (IsMatchExtension(TIProperty)) {
965     for (OMPTraitProperty &SeenProp : TISelector.Properties)
966       if (IsMatchExtension(SeenProp)) {
967         P.Diag(Loc, diag::err_omp_variant_ctx_second_match_extension);
968         StringRef SeenName = llvm::omp::getOpenMPContextTraitPropertyName(
969             SeenProp.Kind, SeenProp.RawString);
970         SourceLocation SeenLoc = Seen[SeenName];
971         P.Diag(SeenLoc, diag::note_omp_declare_variant_ctx_used_here)
972             << CONTEXT_TRAIT_LVL << SeenName;
973         return false;
974       }
975     return true;
976   }
977 
978   llvm_unreachable("Unknown extension property!");
979 }
980 
981 void Parser::parseOMPContextProperty(OMPTraitSelector &TISelector,
982                                      llvm::omp::TraitSet Set,
983                                      llvm::StringMap<SourceLocation> &Seen) {
984   assert(TISelector.Kind != TraitSelector::user_condition &&
985          "User conditions are special properties not handled here!");
986 
987   SourceLocation PropertyLoc = Tok.getLocation();
988   OMPTraitProperty TIProperty;
989   parseOMPTraitPropertyKind(TIProperty, Set, TISelector.Kind, Seen);
990 
991   if (TISelector.Kind == llvm::omp::TraitSelector::implementation_extension)
992     if (!checkExtensionProperty(*this, Tok.getLocation(), TIProperty,
993                                 TISelector, Seen))
994       TIProperty.Kind = TraitProperty::invalid;
995 
996   // If we have an invalid property here we already issued a warning.
997   if (TIProperty.Kind == TraitProperty::invalid) {
998     if (PropertyLoc != Tok.getLocation())
999       Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1000           << CONTEXT_TRAIT_LVL;
1001     return;
1002   }
1003 
1004   if (isValidTraitPropertyForTraitSetAndSelector(TIProperty.Kind,
1005                                                  TISelector.Kind, Set)) {
1006 
1007     // If we make it here the property, selector, set, score, condition, ... are
1008     // all valid (or have been corrected). Thus we can record the property.
1009     TISelector.Properties.push_back(TIProperty);
1010     return;
1011   }
1012 
1013   Diag(PropertyLoc, diag::warn_omp_ctx_incompatible_property_for_selector)
1014       << getOpenMPContextTraitPropertyName(TIProperty.Kind,
1015                                            TIProperty.RawString)
1016       << getOpenMPContextTraitSelectorName(TISelector.Kind)
1017       << getOpenMPContextTraitSetName(Set);
1018   Diag(PropertyLoc, diag::note_omp_ctx_compatible_set_and_selector_for_property)
1019       << getOpenMPContextTraitPropertyName(TIProperty.Kind,
1020                                            TIProperty.RawString)
1021       << getOpenMPContextTraitSelectorName(
1022              getOpenMPContextTraitSelectorForProperty(TIProperty.Kind))
1023       << getOpenMPContextTraitSetName(
1024              getOpenMPContextTraitSetForProperty(TIProperty.Kind));
1025   Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1026       << CONTEXT_TRAIT_LVL;
1027 }
1028 
1029 void Parser::parseOMPTraitSelectorKind(OMPTraitSelector &TISelector,
1030                                        llvm::omp::TraitSet Set,
1031                                        llvm::StringMap<SourceLocation> &Seen) {
1032   TISelector.Kind = TraitSelector::invalid;
1033 
1034   SourceLocation NameLoc = Tok.getLocation();
1035   StringRef Name = getNameFromIdOrString(*this, Tok, CONTEXT_SELECTOR_LVL);
1036   if (Name.empty()) {
1037     Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1038         << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(Set);
1039     return;
1040   }
1041 
1042   TISelector.Kind = getOpenMPContextTraitSelectorKind(Name);
1043   if (TISelector.Kind != TraitSelector::invalid) {
1044     if (checkForDuplicates(*this, Name, NameLoc, Seen, CONTEXT_SELECTOR_LVL))
1045       TISelector.Kind = TraitSelector::invalid;
1046     return;
1047   }
1048 
1049   // It follows diagnosis and helping notes.
1050   Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_selector)
1051       << Name << getOpenMPContextTraitSetName(Set);
1052 
1053   TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
1054   if (SetForName != TraitSet::invalid) {
1055     Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1056         << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_SELECTOR_LVL;
1057     Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1058         << Name << "<selector-name>"
1059         << "<property-name>";
1060     return;
1061   }
1062   for (const auto &PotentialSet :
1063        {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1064         TraitSet::device}) {
1065     TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1066         PotentialSet, TraitSelector::invalid, Name);
1067     if (PropertyForName == TraitProperty::invalid)
1068       continue;
1069     Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1070         << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_LVL;
1071     Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1072         << getOpenMPContextTraitSetName(
1073                getOpenMPContextTraitSetForProperty(PropertyForName))
1074         << getOpenMPContextTraitSelectorName(
1075                getOpenMPContextTraitSelectorForProperty(PropertyForName))
1076         << ("(" + Name + ")").str();
1077     return;
1078   }
1079   Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1080       << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(Set);
1081 }
1082 
1083 /// Parse optional 'score' '(' <expr> ')' ':'.
1084 static ExprResult parseContextScore(Parser &P) {
1085   ExprResult ScoreExpr;
1086   llvm::SmallString<16> Buffer;
1087   StringRef SelectorName =
1088       P.getPreprocessor().getSpelling(P.getCurToken(), Buffer);
1089   if (!SelectorName.equals("score"))
1090     return ScoreExpr;
1091   (void)P.ConsumeToken();
1092   SourceLocation RLoc;
1093   ScoreExpr = P.ParseOpenMPParensExpr(SelectorName, RLoc);
1094   // Parse ':'
1095   if (P.getCurToken().is(tok::colon))
1096     (void)P.ConsumeAnyToken();
1097   else
1098     P.Diag(P.getCurToken(), diag::warn_omp_declare_variant_expected)
1099         << "':'"
1100         << "score expression";
1101   return ScoreExpr;
1102 }
1103 
1104 /// Parses an OpenMP context selector.
1105 ///
1106 /// <trait-selector-name> ['('[<trait-score>] <trait-property> [, <t-p>]* ')']
1107 void Parser::parseOMPContextSelector(
1108     OMPTraitSelector &TISelector, llvm::omp::TraitSet Set,
1109     llvm::StringMap<SourceLocation> &SeenSelectors) {
1110   unsigned short OuterPC = ParenCount;
1111 
1112   // If anything went wrong we issue an error or warning and then skip the rest
1113   // of the selector. However, commas are ambiguous so we look for the nesting
1114   // of parentheses here as well.
1115   auto FinishSelector = [OuterPC, this]() -> void {
1116     bool Done = false;
1117     while (!Done) {
1118       while (!SkipUntil({tok::r_brace, tok::r_paren, tok::comma,
1119                          tok::annot_pragma_openmp_end},
1120                         StopBeforeMatch))
1121         ;
1122       if (Tok.is(tok::r_paren) && OuterPC > ParenCount)
1123         (void)ConsumeParen();
1124       if (OuterPC <= ParenCount) {
1125         Done = true;
1126         break;
1127       }
1128       if (!Tok.is(tok::comma) && !Tok.is(tok::r_paren)) {
1129         Done = true;
1130         break;
1131       }
1132       (void)ConsumeAnyToken();
1133     }
1134     Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1135         << CONTEXT_SELECTOR_LVL;
1136   };
1137 
1138   SourceLocation SelectorLoc = Tok.getLocation();
1139   parseOMPTraitSelectorKind(TISelector, Set, SeenSelectors);
1140   if (TISelector.Kind == TraitSelector::invalid)
1141     return FinishSelector();
1142 
1143   bool AllowsTraitScore = false;
1144   bool RequiresProperty = false;
1145   if (!isValidTraitSelectorForTraitSet(TISelector.Kind, Set, AllowsTraitScore,
1146                                        RequiresProperty)) {
1147     Diag(SelectorLoc, diag::warn_omp_ctx_incompatible_selector_for_set)
1148         << getOpenMPContextTraitSelectorName(TISelector.Kind)
1149         << getOpenMPContextTraitSetName(Set);
1150     Diag(SelectorLoc, diag::note_omp_ctx_compatible_set_for_selector)
1151         << getOpenMPContextTraitSelectorName(TISelector.Kind)
1152         << getOpenMPContextTraitSetName(
1153                getOpenMPContextTraitSetForSelector(TISelector.Kind))
1154         << RequiresProperty;
1155     return FinishSelector();
1156   }
1157 
1158   if (!RequiresProperty) {
1159     TISelector.Properties.push_back(
1160         {getOpenMPContextTraitPropertyForSelector(TISelector.Kind),
1161          getOpenMPContextTraitSelectorName(TISelector.Kind)});
1162     return;
1163   }
1164 
1165   if (!Tok.is(tok::l_paren)) {
1166     Diag(SelectorLoc, diag::warn_omp_ctx_selector_without_properties)
1167         << getOpenMPContextTraitSelectorName(TISelector.Kind)
1168         << getOpenMPContextTraitSetName(Set);
1169     return FinishSelector();
1170   }
1171 
1172   if (TISelector.Kind == TraitSelector::user_condition) {
1173     SourceLocation RLoc;
1174     ExprResult Condition = ParseOpenMPParensExpr("user condition", RLoc);
1175     if (!Condition.isUsable())
1176       return FinishSelector();
1177     TISelector.ScoreOrCondition = Condition.get();
1178     TISelector.Properties.push_back(
1179         {TraitProperty::user_condition_unknown, "<condition>"});
1180     return;
1181   }
1182 
1183   BalancedDelimiterTracker BDT(*this, tok::l_paren,
1184                                tok::annot_pragma_openmp_end);
1185   // Parse '('.
1186   (void)BDT.consumeOpen();
1187 
1188   SourceLocation ScoreLoc = Tok.getLocation();
1189   ExprResult Score = parseContextScore(*this);
1190 
1191   if (!AllowsTraitScore && !Score.isUnset()) {
1192     if (Score.isUsable()) {
1193       Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1194           << getOpenMPContextTraitSelectorName(TISelector.Kind)
1195           << getOpenMPContextTraitSetName(Set) << Score.get();
1196     } else {
1197       Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1198           << getOpenMPContextTraitSelectorName(TISelector.Kind)
1199           << getOpenMPContextTraitSetName(Set) << "<invalid>";
1200     }
1201     Score = ExprResult();
1202   }
1203 
1204   if (Score.isUsable())
1205     TISelector.ScoreOrCondition = Score.get();
1206 
1207   llvm::StringMap<SourceLocation> SeenProperties;
1208   do {
1209     parseOMPContextProperty(TISelector, Set, SeenProperties);
1210   } while (TryConsumeToken(tok::comma));
1211 
1212   // Parse ')'.
1213   BDT.consumeClose();
1214 }
1215 
1216 void Parser::parseOMPTraitSetKind(OMPTraitSet &TISet,
1217                                   llvm::StringMap<SourceLocation> &Seen) {
1218   TISet.Kind = TraitSet::invalid;
1219 
1220   SourceLocation NameLoc = Tok.getLocation();
1221   StringRef Name = getNameFromIdOrString(*this, Tok, CONTEXT_SELECTOR_SET_LVL);
1222   if (Name.empty()) {
1223     Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1224         << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1225     return;
1226   }
1227 
1228   TISet.Kind = getOpenMPContextTraitSetKind(Name);
1229   if (TISet.Kind != TraitSet::invalid) {
1230     if (checkForDuplicates(*this, Name, NameLoc, Seen,
1231                            CONTEXT_SELECTOR_SET_LVL))
1232       TISet.Kind = TraitSet::invalid;
1233     return;
1234   }
1235 
1236   // It follows diagnosis and helping notes.
1237   Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_set) << Name;
1238 
1239   TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
1240   if (SelectorForName != TraitSelector::invalid) {
1241     Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1242         << Name << CONTEXT_SELECTOR_LVL << CONTEXT_SELECTOR_SET_LVL;
1243     bool AllowsTraitScore = false;
1244     bool RequiresProperty = false;
1245     isValidTraitSelectorForTraitSet(
1246         SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
1247         AllowsTraitScore, RequiresProperty);
1248     Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1249         << getOpenMPContextTraitSetName(
1250                getOpenMPContextTraitSetForSelector(SelectorForName))
1251         << Name << (RequiresProperty ? "(<property-name>)" : "");
1252     return;
1253   }
1254   for (const auto &PotentialSet :
1255        {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1256         TraitSet::device}) {
1257     TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1258         PotentialSet, TraitSelector::invalid, Name);
1259     if (PropertyForName == TraitProperty::invalid)
1260       continue;
1261     Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1262         << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_SET_LVL;
1263     Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1264         << getOpenMPContextTraitSetName(
1265                getOpenMPContextTraitSetForProperty(PropertyForName))
1266         << getOpenMPContextTraitSelectorName(
1267                getOpenMPContextTraitSelectorForProperty(PropertyForName))
1268         << ("(" + Name + ")").str();
1269     return;
1270   }
1271   Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1272       << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1273 }
1274 
1275 /// Parses an OpenMP context selector set.
1276 ///
1277 /// <trait-set-selector-name> '=' '{' <trait-selector> [, <trait-selector>]* '}'
1278 void Parser::parseOMPContextSelectorSet(
1279     OMPTraitSet &TISet, llvm::StringMap<SourceLocation> &SeenSets) {
1280   auto OuterBC = BraceCount;
1281 
1282   // If anything went wrong we issue an error or warning and then skip the rest
1283   // of the set. However, commas are ambiguous so we look for the nesting
1284   // of braces here as well.
1285   auto FinishSelectorSet = [this, OuterBC]() -> void {
1286     bool Done = false;
1287     while (!Done) {
1288       while (!SkipUntil({tok::comma, tok::r_brace, tok::r_paren,
1289                          tok::annot_pragma_openmp_end},
1290                         StopBeforeMatch))
1291         ;
1292       if (Tok.is(tok::r_brace) && OuterBC > BraceCount)
1293         (void)ConsumeBrace();
1294       if (OuterBC <= BraceCount) {
1295         Done = true;
1296         break;
1297       }
1298       if (!Tok.is(tok::comma) && !Tok.is(tok::r_brace)) {
1299         Done = true;
1300         break;
1301       }
1302       (void)ConsumeAnyToken();
1303     }
1304     Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1305         << CONTEXT_SELECTOR_SET_LVL;
1306   };
1307 
1308   parseOMPTraitSetKind(TISet, SeenSets);
1309   if (TISet.Kind == TraitSet::invalid)
1310     return FinishSelectorSet();
1311 
1312   // Parse '='.
1313   if (!TryConsumeToken(tok::equal))
1314     Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1315         << "="
1316         << ("context set name \"" + getOpenMPContextTraitSetName(TISet.Kind) +
1317             "\"")
1318                .str();
1319 
1320   // Parse '{'.
1321   if (Tok.is(tok::l_brace)) {
1322     (void)ConsumeBrace();
1323   } else {
1324     Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1325         << "{"
1326         << ("'=' that follows the context set name \"" +
1327             getOpenMPContextTraitSetName(TISet.Kind) + "\"")
1328                .str();
1329   }
1330 
1331   llvm::StringMap<SourceLocation> SeenSelectors;
1332   do {
1333     OMPTraitSelector TISelector;
1334     parseOMPContextSelector(TISelector, TISet.Kind, SeenSelectors);
1335     if (TISelector.Kind != TraitSelector::invalid &&
1336         !TISelector.Properties.empty())
1337       TISet.Selectors.push_back(TISelector);
1338   } while (TryConsumeToken(tok::comma));
1339 
1340   // Parse '}'.
1341   if (Tok.is(tok::r_brace)) {
1342     (void)ConsumeBrace();
1343   } else {
1344     Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1345         << "}"
1346         << ("context selectors for the context set \"" +
1347             getOpenMPContextTraitSetName(TISet.Kind) + "\"")
1348                .str();
1349   }
1350 }
1351 
1352 /// Parse OpenMP context selectors:
1353 ///
1354 /// <trait-set-selector> [, <trait-set-selector>]*
1355 bool Parser::parseOMPContextSelectors(SourceLocation Loc, OMPTraitInfo &TI) {
1356   llvm::StringMap<SourceLocation> SeenSets;
1357   do {
1358     OMPTraitSet TISet;
1359     parseOMPContextSelectorSet(TISet, SeenSets);
1360     if (TISet.Kind != TraitSet::invalid && !TISet.Selectors.empty())
1361       TI.Sets.push_back(TISet);
1362   } while (TryConsumeToken(tok::comma));
1363 
1364   return false;
1365 }
1366 
1367 /// Parse clauses for '#pragma omp declare variant ( variant-func-id ) clause'.
1368 void Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,
1369                                            CachedTokens &Toks,
1370                                            SourceLocation Loc) {
1371   PP.EnterToken(Tok, /*IsReinject*/ true);
1372   PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
1373                       /*IsReinject*/ true);
1374   // Consume the previously pushed token.
1375   ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
1376   ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
1377 
1378   FNContextRAII FnContext(*this, Ptr);
1379   // Parse function declaration id.
1380   SourceLocation RLoc;
1381   // Parse with IsAddressOfOperand set to true to parse methods as DeclRefExprs
1382   // instead of MemberExprs.
1383   ExprResult AssociatedFunction;
1384   {
1385     // Do not mark function as is used to prevent its emission if this is the
1386     // only place where it is used.
1387     EnterExpressionEvaluationContext Unevaluated(
1388         Actions, Sema::ExpressionEvaluationContext::Unevaluated);
1389     AssociatedFunction = ParseOpenMPParensExpr(
1390         getOpenMPDirectiveName(OMPD_declare_variant), RLoc,
1391         /*IsAddressOfOperand=*/true);
1392   }
1393   if (!AssociatedFunction.isUsable()) {
1394     if (!Tok.is(tok::annot_pragma_openmp_end))
1395       while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch))
1396         ;
1397     // Skip the last annot_pragma_openmp_end.
1398     (void)ConsumeAnnotationToken();
1399     return;
1400   }
1401 
1402   OMPTraitInfo *ParentTI = Actions.getOMPTraitInfoForSurroundingScope();
1403   ASTContext &ASTCtx = Actions.getASTContext();
1404   OMPTraitInfo &TI = ASTCtx.getNewOMPTraitInfo();
1405   SmallVector<Expr *, 6> AdjustNothing;
1406   SmallVector<Expr *, 6> AdjustNeedDevicePtr;
1407   SmallVector<OMPDeclareVariantAttr::InteropType, 3> AppendArgs;
1408   SourceLocation AdjustArgsLoc, AppendArgsLoc;
1409 
1410   // At least one clause is required.
1411   if (Tok.is(tok::annot_pragma_openmp_end)) {
1412     Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1413         << (getLangOpts().OpenMP < 51 ? 0 : 1);
1414   }
1415 
1416   bool IsError = false;
1417   while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1418     OpenMPClauseKind CKind = Tok.isAnnotation()
1419                                  ? OMPC_unknown
1420                                  : getOpenMPClauseKind(PP.getSpelling(Tok));
1421     if (!isAllowedClauseForDirective(OMPD_declare_variant, CKind,
1422                                      getLangOpts().OpenMP)) {
1423       Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1424           << (getLangOpts().OpenMP < 51 ? 0 : 1);
1425       IsError = true;
1426     }
1427     if (!IsError) {
1428       switch (CKind) {
1429       case OMPC_match:
1430         IsError = parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI);
1431         break;
1432       case OMPC_adjust_args: {
1433         AdjustArgsLoc = Tok.getLocation();
1434         ConsumeToken();
1435         Parser::OpenMPVarListDataTy Data;
1436         SmallVector<Expr *> Vars;
1437         IsError = ParseOpenMPVarList(OMPD_declare_variant, OMPC_adjust_args,
1438                                      Vars, Data);
1439         if (!IsError)
1440           llvm::append_range(Data.ExtraModifier == OMPC_ADJUST_ARGS_nothing
1441                                  ? AdjustNothing
1442                                  : AdjustNeedDevicePtr,
1443                              Vars);
1444         break;
1445       }
1446       case OMPC_append_args:
1447         if (!AppendArgs.empty()) {
1448           Diag(AppendArgsLoc, diag::err_omp_more_one_clause)
1449               << getOpenMPDirectiveName(OMPD_declare_variant)
1450               << getOpenMPClauseName(CKind) << 0;
1451           IsError = true;
1452         }
1453         if (!IsError) {
1454           AppendArgsLoc = Tok.getLocation();
1455           ConsumeToken();
1456           IsError = parseOpenMPAppendArgs(AppendArgs);
1457         }
1458         break;
1459       default:
1460         llvm_unreachable("Unexpected clause for declare variant.");
1461       }
1462     }
1463     if (IsError) {
1464       while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch))
1465         ;
1466       // Skip the last annot_pragma_openmp_end.
1467       (void)ConsumeAnnotationToken();
1468       return;
1469     }
1470     // Skip ',' if any.
1471     if (Tok.is(tok::comma))
1472       ConsumeToken();
1473   }
1474 
1475   Optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
1476       Actions.checkOpenMPDeclareVariantFunction(
1477           Ptr, AssociatedFunction.get(), TI, AppendArgs.size(),
1478           SourceRange(Loc, Tok.getLocation()));
1479 
1480   if (DeclVarData && !TI.Sets.empty())
1481     Actions.ActOnOpenMPDeclareVariantDirective(
1482         DeclVarData->first, DeclVarData->second, TI, AdjustNothing,
1483         AdjustNeedDevicePtr, AppendArgs, AdjustArgsLoc, AppendArgsLoc,
1484         SourceRange(Loc, Tok.getLocation()));
1485 
1486   // Skip the last annot_pragma_openmp_end.
1487   (void)ConsumeAnnotationToken();
1488 }
1489 
1490 /// Parse a list of interop-types. These are 'target' and 'targetsync'. Both
1491 /// are allowed but duplication of either is not meaningful.
1492 static Optional<OMPDeclareVariantAttr::InteropType>
1493 parseInteropTypeList(Parser &P) {
1494   const Token &Tok = P.getCurToken();
1495   bool HasError = false;
1496   bool IsTarget = false;
1497   bool IsTargetSync = false;
1498 
1499   while (Tok.is(tok::identifier)) {
1500     if (Tok.getIdentifierInfo()->isStr("target")) {
1501       // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
1502       // Each interop-type may be specified on an action-clause at most
1503       // once.
1504       if (IsTarget)
1505         P.Diag(Tok, diag::warn_omp_more_one_interop_type) << "target";
1506       IsTarget = true;
1507     } else if (Tok.getIdentifierInfo()->isStr("targetsync")) {
1508       if (IsTargetSync)
1509         P.Diag(Tok, diag::warn_omp_more_one_interop_type) << "targetsync";
1510       IsTargetSync = true;
1511     } else {
1512       HasError = true;
1513       P.Diag(Tok, diag::err_omp_expected_interop_type);
1514     }
1515     P.ConsumeToken();
1516 
1517     if (!Tok.is(tok::comma))
1518       break;
1519     P.ConsumeToken();
1520   }
1521   if (HasError)
1522     return None;
1523 
1524   if (!IsTarget && !IsTargetSync) {
1525     P.Diag(Tok, diag::err_omp_expected_interop_type);
1526     return None;
1527   }
1528 
1529   // As of OpenMP 5.1,there are two interop-types, "target" and
1530   // "targetsync". Either or both are allowed for a single interop.
1531   if (IsTarget && IsTargetSync)
1532     return OMPDeclareVariantAttr::Target_TargetSync;
1533   if (IsTarget)
1534     return OMPDeclareVariantAttr::Target;
1535   return OMPDeclareVariantAttr::TargetSync;
1536 }
1537 
1538 bool Parser::parseOpenMPAppendArgs(
1539     SmallVectorImpl<OMPDeclareVariantAttr::InteropType> &InterOpTypes) {
1540   bool HasError = false;
1541   // Parse '('.
1542   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1543   if (T.expectAndConsume(diag::err_expected_lparen_after,
1544                          getOpenMPClauseName(OMPC_append_args).data()))
1545     return true;
1546 
1547   // Parse the list of append-ops, each is;
1548   // interop(interop-type[,interop-type]...)
1549   while (Tok.is(tok::identifier) && Tok.getIdentifierInfo()->isStr("interop")) {
1550     ConsumeToken();
1551     BalancedDelimiterTracker IT(*this, tok::l_paren,
1552                                 tok::annot_pragma_openmp_end);
1553     if (IT.expectAndConsume(diag::err_expected_lparen_after, "interop"))
1554       return true;
1555 
1556     // Parse the interop-types.
1557     if (Optional<OMPDeclareVariantAttr::InteropType> IType =
1558             parseInteropTypeList(*this))
1559       InterOpTypes.push_back(IType.getValue());
1560     else
1561       HasError = true;
1562 
1563     IT.consumeClose();
1564     if (Tok.is(tok::comma))
1565       ConsumeToken();
1566   }
1567   if (!HasError && InterOpTypes.empty()) {
1568     HasError = true;
1569     Diag(Tok.getLocation(), diag::err_omp_unexpected_append_op);
1570     SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1571               StopBeforeMatch);
1572   }
1573   HasError = T.consumeClose() || HasError;
1574   return HasError;
1575 }
1576 
1577 bool Parser::parseOMPDeclareVariantMatchClause(SourceLocation Loc,
1578                                                OMPTraitInfo &TI,
1579                                                OMPTraitInfo *ParentTI) {
1580   // Parse 'match'.
1581   OpenMPClauseKind CKind = Tok.isAnnotation()
1582                                ? OMPC_unknown
1583                                : getOpenMPClauseKind(PP.getSpelling(Tok));
1584   if (CKind != OMPC_match) {
1585     Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1586         << (getLangOpts().OpenMP < 51 ? 0 : 1);
1587     return true;
1588   }
1589   (void)ConsumeToken();
1590   // Parse '('.
1591   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1592   if (T.expectAndConsume(diag::err_expected_lparen_after,
1593                          getOpenMPClauseName(OMPC_match).data()))
1594     return true;
1595 
1596   // Parse inner context selectors.
1597   parseOMPContextSelectors(Loc, TI);
1598 
1599   // Parse ')'
1600   (void)T.consumeClose();
1601 
1602   if (!ParentTI)
1603     return false;
1604 
1605   // Merge the parent/outer trait info into the one we just parsed and diagnose
1606   // problems.
1607   // TODO: Keep some source location in the TI to provide better diagnostics.
1608   // TODO: Perform some kind of equivalence check on the condition and score
1609   //       expressions.
1610   for (const OMPTraitSet &ParentSet : ParentTI->Sets) {
1611     bool MergedSet = false;
1612     for (OMPTraitSet &Set : TI.Sets) {
1613       if (Set.Kind != ParentSet.Kind)
1614         continue;
1615       MergedSet = true;
1616       for (const OMPTraitSelector &ParentSelector : ParentSet.Selectors) {
1617         bool MergedSelector = false;
1618         for (OMPTraitSelector &Selector : Set.Selectors) {
1619           if (Selector.Kind != ParentSelector.Kind)
1620             continue;
1621           MergedSelector = true;
1622           for (const OMPTraitProperty &ParentProperty :
1623                ParentSelector.Properties) {
1624             bool MergedProperty = false;
1625             for (OMPTraitProperty &Property : Selector.Properties) {
1626               // Ignore "equivalent" properties.
1627               if (Property.Kind != ParentProperty.Kind)
1628                 continue;
1629 
1630               // If the kind is the same but the raw string not, we don't want
1631               // to skip out on the property.
1632               MergedProperty |= Property.RawString == ParentProperty.RawString;
1633 
1634               if (Property.RawString == ParentProperty.RawString &&
1635                   Selector.ScoreOrCondition == ParentSelector.ScoreOrCondition)
1636                 continue;
1637 
1638               if (Selector.Kind == llvm::omp::TraitSelector::user_condition) {
1639                 Diag(Loc, diag::err_omp_declare_variant_nested_user_condition);
1640               } else if (Selector.ScoreOrCondition !=
1641                          ParentSelector.ScoreOrCondition) {
1642                 Diag(Loc, diag::err_omp_declare_variant_duplicate_nested_trait)
1643                     << getOpenMPContextTraitPropertyName(
1644                            ParentProperty.Kind, ParentProperty.RawString)
1645                     << getOpenMPContextTraitSelectorName(ParentSelector.Kind)
1646                     << getOpenMPContextTraitSetName(ParentSet.Kind);
1647               }
1648             }
1649             if (!MergedProperty)
1650               Selector.Properties.push_back(ParentProperty);
1651           }
1652         }
1653         if (!MergedSelector)
1654           Set.Selectors.push_back(ParentSelector);
1655       }
1656     }
1657     if (!MergedSet)
1658       TI.Sets.push_back(ParentSet);
1659   }
1660 
1661   return false;
1662 }
1663 
1664 /// `omp assumes` or `omp begin/end assumes` <clause> [[,]<clause>]...
1665 /// where
1666 ///
1667 ///   clause:
1668 ///     'ext_IMPL_DEFINED'
1669 ///     'absent' '(' directive-name [, directive-name]* ')'
1670 ///     'contains' '(' directive-name [, directive-name]* ')'
1671 ///     'holds' '(' scalar-expression ')'
1672 ///     'no_openmp'
1673 ///     'no_openmp_routines'
1674 ///     'no_parallelism'
1675 ///
1676 void Parser::ParseOpenMPAssumesDirective(OpenMPDirectiveKind DKind,
1677                                          SourceLocation Loc) {
1678   SmallVector<std::string, 4> Assumptions;
1679   bool SkippedClauses = false;
1680 
1681   auto SkipBraces = [&](llvm::StringRef Spelling, bool IssueNote) {
1682     BalancedDelimiterTracker T(*this, tok::l_paren,
1683                                tok::annot_pragma_openmp_end);
1684     if (T.expectAndConsume(diag::err_expected_lparen_after, Spelling.data()))
1685       return;
1686     T.skipToEnd();
1687     if (IssueNote && T.getCloseLocation().isValid())
1688       Diag(T.getCloseLocation(),
1689            diag::note_omp_assumption_clause_continue_here);
1690   };
1691 
1692   /// Helper to determine which AssumptionClauseMapping (ACM) in the
1693   /// AssumptionClauseMappings table matches \p RawString. The return value is
1694   /// the index of the matching ACM into the table or -1 if there was no match.
1695   auto MatchACMClause = [&](StringRef RawString) {
1696     llvm::StringSwitch<int> SS(RawString);
1697     unsigned ACMIdx = 0;
1698     for (const AssumptionClauseMappingInfo &ACMI : AssumptionClauseMappings) {
1699       if (ACMI.StartsWith)
1700         SS.StartsWith(ACMI.Identifier, ACMIdx++);
1701       else
1702         SS.Case(ACMI.Identifier, ACMIdx++);
1703     }
1704     return SS.Default(-1);
1705   };
1706 
1707   while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1708     IdentifierInfo *II = nullptr;
1709     SourceLocation StartLoc = Tok.getLocation();
1710     int Idx = -1;
1711     if (Tok.isAnyIdentifier()) {
1712       II = Tok.getIdentifierInfo();
1713       Idx = MatchACMClause(II->getName());
1714     }
1715     ConsumeAnyToken();
1716 
1717     bool NextIsLPar = Tok.is(tok::l_paren);
1718     // Handle unknown clauses by skipping them.
1719     if (Idx == -1) {
1720       Diag(StartLoc, diag::warn_omp_unknown_assumption_clause_missing_id)
1721           << llvm::omp::getOpenMPDirectiveName(DKind)
1722           << llvm::omp::getAllAssumeClauseOptions() << NextIsLPar;
1723       if (NextIsLPar)
1724         SkipBraces(II ? II->getName() : "", /* IssueNote */ true);
1725       SkippedClauses = true;
1726       continue;
1727     }
1728     const AssumptionClauseMappingInfo &ACMI = AssumptionClauseMappings[Idx];
1729     if (ACMI.HasDirectiveList || ACMI.HasExpression) {
1730       // TODO: We ignore absent, contains, and holds assumptions for now. We
1731       //       also do not verify the content in the parenthesis at all.
1732       SkippedClauses = true;
1733       SkipBraces(II->getName(), /* IssueNote */ false);
1734       continue;
1735     }
1736 
1737     if (NextIsLPar) {
1738       Diag(Tok.getLocation(),
1739            diag::warn_omp_unknown_assumption_clause_without_args)
1740           << II;
1741       SkipBraces(II->getName(), /* IssueNote */ true);
1742     }
1743 
1744     assert(II && "Expected an identifier clause!");
1745     std::string Assumption = II->getName().str();
1746     if (ACMI.StartsWith)
1747       Assumption = "ompx_" + Assumption.substr(ACMI.Identifier.size());
1748     else
1749       Assumption = "omp_" + Assumption;
1750     Assumptions.push_back(Assumption);
1751   }
1752 
1753   Actions.ActOnOpenMPAssumesDirective(Loc, DKind, Assumptions, SkippedClauses);
1754 }
1755 
1756 void Parser::ParseOpenMPEndAssumesDirective(SourceLocation Loc) {
1757   if (Actions.isInOpenMPAssumeScope())
1758     Actions.ActOnOpenMPEndAssumesDirective();
1759   else
1760     Diag(Loc, diag::err_expected_begin_assumes);
1761 }
1762 
1763 /// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
1764 ///
1765 ///    default-clause:
1766 ///         'default' '(' 'none' | 'shared'  | 'firstprivate' ')
1767 ///
1768 ///    proc_bind-clause:
1769 ///         'proc_bind' '(' 'master' | 'close' | 'spread' ')
1770 ///
1771 ///    device_type-clause:
1772 ///         'device_type' '(' 'host' | 'nohost' | 'any' )'
1773 namespace {
1774 struct SimpleClauseData {
1775   unsigned Type;
1776   SourceLocation Loc;
1777   SourceLocation LOpen;
1778   SourceLocation TypeLoc;
1779   SourceLocation RLoc;
1780   SimpleClauseData(unsigned Type, SourceLocation Loc, SourceLocation LOpen,
1781                    SourceLocation TypeLoc, SourceLocation RLoc)
1782       : Type(Type), Loc(Loc), LOpen(LOpen), TypeLoc(TypeLoc), RLoc(RLoc) {}
1783 };
1784 } // anonymous namespace
1785 
1786 static Optional<SimpleClauseData>
1787 parseOpenMPSimpleClause(Parser &P, OpenMPClauseKind Kind) {
1788   const Token &Tok = P.getCurToken();
1789   SourceLocation Loc = Tok.getLocation();
1790   SourceLocation LOpen = P.ConsumeToken();
1791   // Parse '('.
1792   BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openmp_end);
1793   if (T.expectAndConsume(diag::err_expected_lparen_after,
1794                          getOpenMPClauseName(Kind).data()))
1795     return llvm::None;
1796 
1797   unsigned Type = getOpenMPSimpleClauseType(
1798       Kind, Tok.isAnnotation() ? "" : P.getPreprocessor().getSpelling(Tok),
1799       P.getLangOpts());
1800   SourceLocation TypeLoc = Tok.getLocation();
1801   if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1802       Tok.isNot(tok::annot_pragma_openmp_end))
1803     P.ConsumeAnyToken();
1804 
1805   // Parse ')'.
1806   SourceLocation RLoc = Tok.getLocation();
1807   if (!T.consumeClose())
1808     RLoc = T.getCloseLocation();
1809 
1810   return SimpleClauseData(Type, Loc, LOpen, TypeLoc, RLoc);
1811 }
1812 
1813 void Parser::ParseOMPDeclareTargetClauses(
1814     Sema::DeclareTargetContextInfo &DTCI) {
1815   SourceLocation DeviceTypeLoc;
1816   bool RequiresToOrLinkClause = false;
1817   bool HasToOrLinkClause = false;
1818   while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1819     OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
1820     bool HasIdentifier = Tok.is(tok::identifier);
1821     if (HasIdentifier) {
1822       // If we see any clause we need a to or link clause.
1823       RequiresToOrLinkClause = true;
1824       IdentifierInfo *II = Tok.getIdentifierInfo();
1825       StringRef ClauseName = II->getName();
1826       bool IsDeviceTypeClause =
1827           getLangOpts().OpenMP >= 50 &&
1828           getOpenMPClauseKind(ClauseName) == OMPC_device_type;
1829 
1830       bool IsToOrLinkClause =
1831           OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT);
1832       assert((!IsDeviceTypeClause || !IsToOrLinkClause) && "Cannot be both!");
1833 
1834       if (!IsDeviceTypeClause && DTCI.Kind == OMPD_begin_declare_target) {
1835         Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
1836             << ClauseName << 0;
1837         break;
1838       }
1839       if (!IsDeviceTypeClause && !IsToOrLinkClause) {
1840         Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
1841             << ClauseName << (getLangOpts().OpenMP >= 50 ? 2 : 1);
1842         break;
1843       }
1844 
1845       if (IsToOrLinkClause)
1846         HasToOrLinkClause = true;
1847 
1848       // Parse 'device_type' clause and go to next clause if any.
1849       if (IsDeviceTypeClause) {
1850         Optional<SimpleClauseData> DevTypeData =
1851             parseOpenMPSimpleClause(*this, OMPC_device_type);
1852         if (DevTypeData.hasValue()) {
1853           if (DeviceTypeLoc.isValid()) {
1854             // We already saw another device_type clause, diagnose it.
1855             Diag(DevTypeData.getValue().Loc,
1856                  diag::warn_omp_more_one_device_type_clause);
1857             break;
1858           }
1859           switch (static_cast<OpenMPDeviceType>(DevTypeData.getValue().Type)) {
1860           case OMPC_DEVICE_TYPE_any:
1861             DTCI.DT = OMPDeclareTargetDeclAttr::DT_Any;
1862             break;
1863           case OMPC_DEVICE_TYPE_host:
1864             DTCI.DT = OMPDeclareTargetDeclAttr::DT_Host;
1865             break;
1866           case OMPC_DEVICE_TYPE_nohost:
1867             DTCI.DT = OMPDeclareTargetDeclAttr::DT_NoHost;
1868             break;
1869           case OMPC_DEVICE_TYPE_unknown:
1870             llvm_unreachable("Unexpected device_type");
1871           }
1872           DeviceTypeLoc = DevTypeData.getValue().Loc;
1873         }
1874         continue;
1875       }
1876       ConsumeToken();
1877     }
1878 
1879     if (DTCI.Kind == OMPD_declare_target || HasIdentifier) {
1880       auto &&Callback = [this, MT, &DTCI](CXXScopeSpec &SS,
1881                                           DeclarationNameInfo NameInfo) {
1882         NamedDecl *ND =
1883             Actions.lookupOpenMPDeclareTargetName(getCurScope(), SS, NameInfo);
1884         if (!ND)
1885           return;
1886         Sema::DeclareTargetContextInfo::MapInfo MI{MT, NameInfo.getLoc()};
1887         bool FirstMapping = DTCI.ExplicitlyMapped.try_emplace(ND, MI).second;
1888         if (!FirstMapping)
1889           Diag(NameInfo.getLoc(), diag::err_omp_declare_target_multiple)
1890               << NameInfo.getName();
1891       };
1892       if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
1893                                    /*AllowScopeSpecifier=*/true))
1894         break;
1895     }
1896 
1897     if (Tok.is(tok::l_paren)) {
1898       Diag(Tok,
1899            diag::err_omp_begin_declare_target_unexpected_implicit_to_clause);
1900       break;
1901     }
1902     if (!HasIdentifier && Tok.isNot(tok::annot_pragma_openmp_end)) {
1903       Diag(Tok,
1904            diag::err_omp_declare_target_unexpected_clause_after_implicit_to);
1905       break;
1906     }
1907 
1908     // Consume optional ','.
1909     if (Tok.is(tok::comma))
1910       ConsumeToken();
1911   }
1912 
1913   // For declare target require at least 'to' or 'link' to be present.
1914   if (DTCI.Kind == OMPD_declare_target && RequiresToOrLinkClause &&
1915       !HasToOrLinkClause)
1916     Diag(DTCI.Loc, diag::err_omp_declare_target_missing_to_or_link_clause);
1917 
1918   SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1919 }
1920 
1921 void Parser::skipUntilPragmaOpenMPEnd(OpenMPDirectiveKind DKind) {
1922   // The last seen token is annot_pragma_openmp_end - need to check for
1923   // extra tokens.
1924   if (Tok.is(tok::annot_pragma_openmp_end))
1925     return;
1926 
1927   Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1928       << getOpenMPDirectiveName(DKind);
1929   while (Tok.isNot(tok::annot_pragma_openmp_end))
1930     ConsumeAnyToken();
1931 }
1932 
1933 void Parser::parseOMPEndDirective(OpenMPDirectiveKind BeginKind,
1934                                   OpenMPDirectiveKind ExpectedKind,
1935                                   OpenMPDirectiveKind FoundKind,
1936                                   SourceLocation BeginLoc,
1937                                   SourceLocation FoundLoc,
1938                                   bool SkipUntilOpenMPEnd) {
1939   int DiagSelection = ExpectedKind == OMPD_end_declare_target ? 0 : 1;
1940 
1941   if (FoundKind == ExpectedKind) {
1942     ConsumeAnyToken();
1943     skipUntilPragmaOpenMPEnd(ExpectedKind);
1944     return;
1945   }
1946 
1947   Diag(FoundLoc, diag::err_expected_end_declare_target_or_variant)
1948       << DiagSelection;
1949   Diag(BeginLoc, diag::note_matching)
1950       << ("'#pragma omp " + getOpenMPDirectiveName(BeginKind) + "'").str();
1951   if (SkipUntilOpenMPEnd)
1952     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1953 }
1954 
1955 void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind BeginDKind,
1956                                                OpenMPDirectiveKind EndDKind,
1957                                                SourceLocation DKLoc) {
1958   parseOMPEndDirective(BeginDKind, OMPD_end_declare_target, EndDKind, DKLoc,
1959                        Tok.getLocation(),
1960                        /* SkipUntilOpenMPEnd */ false);
1961   // Skip the last annot_pragma_openmp_end.
1962   if (Tok.is(tok::annot_pragma_openmp_end))
1963     ConsumeAnnotationToken();
1964 }
1965 
1966 /// Parsing of declarative OpenMP directives.
1967 ///
1968 ///       threadprivate-directive:
1969 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
1970 ///         annot_pragma_openmp_end
1971 ///
1972 ///       allocate-directive:
1973 ///         annot_pragma_openmp 'allocate' simple-variable-list [<clause>]
1974 ///         annot_pragma_openmp_end
1975 ///
1976 ///       declare-reduction-directive:
1977 ///        annot_pragma_openmp 'declare' 'reduction' [...]
1978 ///        annot_pragma_openmp_end
1979 ///
1980 ///       declare-mapper-directive:
1981 ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
1982 ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
1983 ///         annot_pragma_openmp_end
1984 ///
1985 ///       declare-simd-directive:
1986 ///         annot_pragma_openmp 'declare simd' {<clause> [,]}
1987 ///         annot_pragma_openmp_end
1988 ///         <function declaration/definition>
1989 ///
1990 ///       requires directive:
1991 ///         annot_pragma_openmp 'requires' <clause> [[[,] <clause>] ... ]
1992 ///         annot_pragma_openmp_end
1993 ///
1994 ///       assumes directive:
1995 ///         annot_pragma_openmp 'assumes' <clause> [[[,] <clause>] ... ]
1996 ///         annot_pragma_openmp_end
1997 ///       or
1998 ///         annot_pragma_openmp 'begin assumes' <clause> [[[,] <clause>] ... ]
1999 ///         annot_pragma_openmp 'end assumes'
2000 ///         annot_pragma_openmp_end
2001 ///
2002 Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
2003     AccessSpecifier &AS, ParsedAttributesWithRange &Attrs, bool Delayed,
2004     DeclSpec::TST TagType, Decl *Tag) {
2005   assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
2006          "Not an OpenMP directive!");
2007   ParsingOpenMPDirectiveRAII DirScope(*this);
2008   ParenBraceBracketBalancer BalancerRAIIObj(*this);
2009 
2010   SourceLocation Loc;
2011   OpenMPDirectiveKind DKind;
2012   if (Delayed) {
2013     TentativeParsingAction TPA(*this);
2014     Loc = ConsumeAnnotationToken();
2015     DKind = parseOpenMPDirectiveKind(*this);
2016     if (DKind == OMPD_declare_reduction || DKind == OMPD_declare_mapper) {
2017       // Need to delay parsing until completion of the parent class.
2018       TPA.Revert();
2019       CachedTokens Toks;
2020       unsigned Cnt = 1;
2021       Toks.push_back(Tok);
2022       while (Cnt && Tok.isNot(tok::eof)) {
2023         (void)ConsumeAnyToken();
2024         if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp))
2025           ++Cnt;
2026         else if (Tok.is(tok::annot_pragma_openmp_end))
2027           --Cnt;
2028         Toks.push_back(Tok);
2029       }
2030       // Skip last annot_pragma_openmp_end.
2031       if (Cnt == 0)
2032         (void)ConsumeAnyToken();
2033       auto *LP = new LateParsedPragma(this, AS);
2034       LP->takeToks(Toks);
2035       getCurrentClass().LateParsedDeclarations.push_back(LP);
2036       return nullptr;
2037     }
2038     TPA.Commit();
2039   } else {
2040     Loc = ConsumeAnnotationToken();
2041     DKind = parseOpenMPDirectiveKind(*this);
2042   }
2043 
2044   switch (DKind) {
2045   case OMPD_threadprivate: {
2046     ConsumeToken();
2047     DeclDirectiveListParserHelper Helper(this, DKind);
2048     if (!ParseOpenMPSimpleVarList(DKind, Helper,
2049                                   /*AllowScopeSpecifier=*/true)) {
2050       skipUntilPragmaOpenMPEnd(DKind);
2051       // Skip the last annot_pragma_openmp_end.
2052       ConsumeAnnotationToken();
2053       return Actions.ActOnOpenMPThreadprivateDirective(Loc,
2054                                                        Helper.getIdentifiers());
2055     }
2056     break;
2057   }
2058   case OMPD_allocate: {
2059     ConsumeToken();
2060     DeclDirectiveListParserHelper Helper(this, DKind);
2061     if (!ParseOpenMPSimpleVarList(DKind, Helper,
2062                                   /*AllowScopeSpecifier=*/true)) {
2063       SmallVector<OMPClause *, 1> Clauses;
2064       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2065         SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
2066                     llvm::omp::Clause_enumSize + 1>
2067             FirstClauses(llvm::omp::Clause_enumSize + 1);
2068         while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2069           OpenMPClauseKind CKind =
2070               Tok.isAnnotation() ? OMPC_unknown
2071                                  : getOpenMPClauseKind(PP.getSpelling(Tok));
2072           Actions.StartOpenMPClause(CKind);
2073           OMPClause *Clause = ParseOpenMPClause(
2074               OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt());
2075           SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2076                     StopBeforeMatch);
2077           FirstClauses[unsigned(CKind)].setInt(true);
2078           if (Clause != nullptr)
2079             Clauses.push_back(Clause);
2080           if (Tok.is(tok::annot_pragma_openmp_end)) {
2081             Actions.EndOpenMPClause();
2082             break;
2083           }
2084           // Skip ',' if any.
2085           if (Tok.is(tok::comma))
2086             ConsumeToken();
2087           Actions.EndOpenMPClause();
2088         }
2089         skipUntilPragmaOpenMPEnd(DKind);
2090       }
2091       // Skip the last annot_pragma_openmp_end.
2092       ConsumeAnnotationToken();
2093       return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers(),
2094                                                   Clauses);
2095     }
2096     break;
2097   }
2098   case OMPD_requires: {
2099     SourceLocation StartLoc = ConsumeToken();
2100     SmallVector<OMPClause *, 5> Clauses;
2101     SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
2102                 llvm::omp::Clause_enumSize + 1>
2103         FirstClauses(llvm::omp::Clause_enumSize + 1);
2104     if (Tok.is(tok::annot_pragma_openmp_end)) {
2105       Diag(Tok, diag::err_omp_expected_clause)
2106           << getOpenMPDirectiveName(OMPD_requires);
2107       break;
2108     }
2109     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2110       OpenMPClauseKind CKind = Tok.isAnnotation()
2111                                    ? OMPC_unknown
2112                                    : getOpenMPClauseKind(PP.getSpelling(Tok));
2113       Actions.StartOpenMPClause(CKind);
2114       OMPClause *Clause = ParseOpenMPClause(
2115           OMPD_requires, CKind, !FirstClauses[unsigned(CKind)].getInt());
2116       SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2117                 StopBeforeMatch);
2118       FirstClauses[unsigned(CKind)].setInt(true);
2119       if (Clause != nullptr)
2120         Clauses.push_back(Clause);
2121       if (Tok.is(tok::annot_pragma_openmp_end)) {
2122         Actions.EndOpenMPClause();
2123         break;
2124       }
2125       // Skip ',' if any.
2126       if (Tok.is(tok::comma))
2127         ConsumeToken();
2128       Actions.EndOpenMPClause();
2129     }
2130     // Consume final annot_pragma_openmp_end
2131     if (Clauses.empty()) {
2132       Diag(Tok, diag::err_omp_expected_clause)
2133           << getOpenMPDirectiveName(OMPD_requires);
2134       ConsumeAnnotationToken();
2135       return nullptr;
2136     }
2137     ConsumeAnnotationToken();
2138     return Actions.ActOnOpenMPRequiresDirective(StartLoc, Clauses);
2139   }
2140   case OMPD_assumes:
2141   case OMPD_begin_assumes:
2142     ParseOpenMPAssumesDirective(DKind, ConsumeToken());
2143     break;
2144   case OMPD_end_assumes:
2145     ParseOpenMPEndAssumesDirective(ConsumeToken());
2146     break;
2147   case OMPD_declare_reduction:
2148     ConsumeToken();
2149     if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
2150       skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2151       // Skip the last annot_pragma_openmp_end.
2152       ConsumeAnnotationToken();
2153       return Res;
2154     }
2155     break;
2156   case OMPD_declare_mapper: {
2157     ConsumeToken();
2158     if (DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
2159       // Skip the last annot_pragma_openmp_end.
2160       ConsumeAnnotationToken();
2161       return Res;
2162     }
2163     break;
2164   }
2165   case OMPD_begin_declare_variant: {
2166     // The syntax is:
2167     // { #pragma omp begin declare variant clause }
2168     // <function-declaration-or-definition-sequence>
2169     // { #pragma omp end declare variant }
2170     //
2171     ConsumeToken();
2172     OMPTraitInfo *ParentTI = Actions.getOMPTraitInfoForSurroundingScope();
2173     ASTContext &ASTCtx = Actions.getASTContext();
2174     OMPTraitInfo &TI = ASTCtx.getNewOMPTraitInfo();
2175     if (parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI)) {
2176       while (!SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch))
2177         ;
2178       // Skip the last annot_pragma_openmp_end.
2179       (void)ConsumeAnnotationToken();
2180       break;
2181     }
2182 
2183     // Skip last tokens.
2184     skipUntilPragmaOpenMPEnd(OMPD_begin_declare_variant);
2185 
2186     ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false);
2187 
2188     VariantMatchInfo VMI;
2189     TI.getAsVariantMatchInfo(ASTCtx, VMI);
2190 
2191     std::function<void(StringRef)> DiagUnknownTrait = [this, Loc](
2192                                                           StringRef ISATrait) {
2193       // TODO Track the selector locations in a way that is accessible here to
2194       // improve the diagnostic location.
2195       Diag(Loc, diag::warn_unknown_begin_declare_variant_isa_trait) << ISATrait;
2196     };
2197     TargetOMPContext OMPCtx(
2198         ASTCtx, std::move(DiagUnknownTrait),
2199         /* CurrentFunctionDecl */ nullptr,
2200         /* ConstructTraits */ ArrayRef<llvm::omp::TraitProperty>());
2201 
2202     if (isVariantApplicableInContext(VMI, OMPCtx, /* DeviceSetOnly */ true)) {
2203       Actions.ActOnOpenMPBeginDeclareVariant(Loc, TI);
2204       break;
2205     }
2206 
2207     // Elide all the code till the matching end declare variant was found.
2208     unsigned Nesting = 1;
2209     SourceLocation DKLoc;
2210     OpenMPDirectiveKind DK = OMPD_unknown;
2211     do {
2212       DKLoc = Tok.getLocation();
2213       DK = parseOpenMPDirectiveKind(*this);
2214       if (DK == OMPD_end_declare_variant)
2215         --Nesting;
2216       else if (DK == OMPD_begin_declare_variant)
2217         ++Nesting;
2218       if (!Nesting || isEofOrEom())
2219         break;
2220       ConsumeAnyToken();
2221     } while (true);
2222 
2223     parseOMPEndDirective(OMPD_begin_declare_variant, OMPD_end_declare_variant,
2224                          DK, Loc, DKLoc, /* SkipUntilOpenMPEnd */ true);
2225     if (isEofOrEom())
2226       return nullptr;
2227     break;
2228   }
2229   case OMPD_end_declare_variant: {
2230     if (Actions.isInOpenMPDeclareVariantScope())
2231       Actions.ActOnOpenMPEndDeclareVariant();
2232     else
2233       Diag(Loc, diag::err_expected_begin_declare_variant);
2234     ConsumeToken();
2235     break;
2236   }
2237   case OMPD_declare_variant:
2238   case OMPD_declare_simd: {
2239     // The syntax is:
2240     // { #pragma omp declare {simd|variant} }
2241     // <function-declaration-or-definition>
2242     //
2243     CachedTokens Toks;
2244     Toks.push_back(Tok);
2245     ConsumeToken();
2246     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2247       Toks.push_back(Tok);
2248       ConsumeAnyToken();
2249     }
2250     Toks.push_back(Tok);
2251     ConsumeAnyToken();
2252 
2253     DeclGroupPtrTy Ptr;
2254     if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
2255       Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, Delayed,
2256                                                        TagType, Tag);
2257     } else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
2258       // Here we expect to see some function declaration.
2259       if (AS == AS_none) {
2260         assert(TagType == DeclSpec::TST_unspecified);
2261         MaybeParseCXX11Attributes(Attrs);
2262         ParsingDeclSpec PDS(*this);
2263         Ptr = ParseExternalDeclaration(Attrs, &PDS);
2264       } else {
2265         Ptr =
2266             ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
2267       }
2268     }
2269     if (!Ptr) {
2270       Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
2271           << (DKind == OMPD_declare_simd ? 0 : 1);
2272       return DeclGroupPtrTy();
2273     }
2274     if (DKind == OMPD_declare_simd)
2275       return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
2276     assert(DKind == OMPD_declare_variant &&
2277            "Expected declare variant directive only");
2278     ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
2279     return Ptr;
2280   }
2281   case OMPD_begin_declare_target:
2282   case OMPD_declare_target: {
2283     SourceLocation DTLoc = ConsumeAnyToken();
2284     bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2285     bool HasImplicitMappings =
2286         DKind == OMPD_begin_declare_target || !HasClauses;
2287     Sema::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2288     if (HasClauses)
2289       ParseOMPDeclareTargetClauses(DTCI);
2290 
2291     // Skip the last annot_pragma_openmp_end.
2292     ConsumeAnyToken();
2293 
2294     if (HasImplicitMappings) {
2295       Actions.ActOnStartOpenMPDeclareTargetContext(DTCI);
2296       return nullptr;
2297     }
2298 
2299     Actions.ActOnFinishedOpenMPDeclareTargetContext(DTCI);
2300     llvm::SmallVector<Decl *, 4> Decls;
2301     for (auto &It : DTCI.ExplicitlyMapped)
2302       Decls.push_back(It.first);
2303     return Actions.BuildDeclaratorGroup(Decls);
2304   }
2305   case OMPD_end_declare_target: {
2306     if (!Actions.isInOpenMPDeclareTargetContext()) {
2307       Diag(Tok, diag::err_omp_unexpected_directive)
2308           << 1 << getOpenMPDirectiveName(DKind);
2309       break;
2310     }
2311     const Sema::DeclareTargetContextInfo &DTCI =
2312         Actions.ActOnOpenMPEndDeclareTargetDirective();
2313     ParseOMPEndDeclareTargetDirective(DTCI.Kind, DKind, DTCI.Loc);
2314     return nullptr;
2315   }
2316   case OMPD_unknown:
2317     Diag(Tok, diag::err_omp_unknown_directive);
2318     break;
2319   case OMPD_parallel:
2320   case OMPD_simd:
2321   case OMPD_tile:
2322   case OMPD_unroll:
2323   case OMPD_task:
2324   case OMPD_taskyield:
2325   case OMPD_barrier:
2326   case OMPD_taskwait:
2327   case OMPD_taskgroup:
2328   case OMPD_flush:
2329   case OMPD_depobj:
2330   case OMPD_scan:
2331   case OMPD_for:
2332   case OMPD_for_simd:
2333   case OMPD_sections:
2334   case OMPD_section:
2335   case OMPD_single:
2336   case OMPD_master:
2337   case OMPD_ordered:
2338   case OMPD_critical:
2339   case OMPD_parallel_for:
2340   case OMPD_parallel_for_simd:
2341   case OMPD_parallel_sections:
2342   case OMPD_parallel_master:
2343   case OMPD_atomic:
2344   case OMPD_target:
2345   case OMPD_teams:
2346   case OMPD_cancellation_point:
2347   case OMPD_cancel:
2348   case OMPD_target_data:
2349   case OMPD_target_enter_data:
2350   case OMPD_target_exit_data:
2351   case OMPD_target_parallel:
2352   case OMPD_target_parallel_for:
2353   case OMPD_taskloop:
2354   case OMPD_taskloop_simd:
2355   case OMPD_master_taskloop:
2356   case OMPD_master_taskloop_simd:
2357   case OMPD_parallel_master_taskloop:
2358   case OMPD_parallel_master_taskloop_simd:
2359   case OMPD_distribute:
2360   case OMPD_target_update:
2361   case OMPD_distribute_parallel_for:
2362   case OMPD_distribute_parallel_for_simd:
2363   case OMPD_distribute_simd:
2364   case OMPD_target_parallel_for_simd:
2365   case OMPD_target_simd:
2366   case OMPD_teams_distribute:
2367   case OMPD_teams_distribute_simd:
2368   case OMPD_teams_distribute_parallel_for_simd:
2369   case OMPD_teams_distribute_parallel_for:
2370   case OMPD_target_teams:
2371   case OMPD_target_teams_distribute:
2372   case OMPD_target_teams_distribute_parallel_for:
2373   case OMPD_target_teams_distribute_parallel_for_simd:
2374   case OMPD_target_teams_distribute_simd:
2375   case OMPD_dispatch:
2376   case OMPD_masked:
2377   case OMPD_metadirective:
2378   case OMPD_loop:
2379     Diag(Tok, diag::err_omp_unexpected_directive)
2380         << 1 << getOpenMPDirectiveName(DKind);
2381     break;
2382   default:
2383     break;
2384   }
2385   while (Tok.isNot(tok::annot_pragma_openmp_end))
2386     ConsumeAnyToken();
2387   ConsumeAnyToken();
2388   return nullptr;
2389 }
2390 
2391 /// Parsing of declarative or executable OpenMP directives.
2392 ///
2393 ///       threadprivate-directive:
2394 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
2395 ///         annot_pragma_openmp_end
2396 ///
2397 ///       allocate-directive:
2398 ///         annot_pragma_openmp 'allocate' simple-variable-list
2399 ///         annot_pragma_openmp_end
2400 ///
2401 ///       declare-reduction-directive:
2402 ///         annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
2403 ///         <type> {',' <type>} ':' <expression> ')' ['initializer' '('
2404 ///         ('omp_priv' '=' <expression>|<function_call>) ')']
2405 ///         annot_pragma_openmp_end
2406 ///
2407 ///       declare-mapper-directive:
2408 ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
2409 ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
2410 ///         annot_pragma_openmp_end
2411 ///
2412 ///       executable-directive:
2413 ///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
2414 ///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
2415 ///         'parallel for' | 'parallel sections' | 'parallel master' | 'task' |
2416 ///         'taskyield' | 'barrier' | 'taskwait' | 'flush' | 'ordered' |
2417 ///         'atomic' | 'for simd' | 'parallel for simd' | 'target' | 'target
2418 ///         data' | 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
2419 ///         'master taskloop' | 'master taskloop simd' | 'parallel master
2420 ///         taskloop' | 'parallel master taskloop simd' | 'distribute' | 'target
2421 ///         enter data' | 'target exit data' | 'target parallel' | 'target
2422 ///         parallel for' | 'target update' | 'distribute parallel for' |
2423 ///         'distribute paralle for simd' | 'distribute simd' | 'target parallel
2424 ///         for simd' | 'target simd' | 'teams distribute' | 'teams distribute
2425 ///         simd' | 'teams distribute parallel for simd' | 'teams distribute
2426 ///         parallel for' | 'target teams' | 'target teams distribute' | 'target
2427 ///         teams distribute parallel for' | 'target teams distribute parallel
2428 ///         for simd' | 'target teams distribute simd' | 'masked' {clause}
2429 ///         annot_pragma_openmp_end
2430 ///
2431 StmtResult
2432 Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
2433   static bool ReadDirectiveWithinMetadirective = false;
2434   if (!ReadDirectiveWithinMetadirective)
2435     assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
2436            "Not an OpenMP directive!");
2437   ParsingOpenMPDirectiveRAII DirScope(*this);
2438   ParenBraceBracketBalancer BalancerRAIIObj(*this);
2439   SmallVector<OMPClause *, 5> Clauses;
2440   SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
2441               llvm::omp::Clause_enumSize + 1>
2442       FirstClauses(llvm::omp::Clause_enumSize + 1);
2443   unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
2444                         Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
2445   SourceLocation Loc = ReadDirectiveWithinMetadirective
2446                            ? Tok.getLocation()
2447                            : ConsumeAnnotationToken(),
2448                  EndLoc;
2449   OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
2450   if (ReadDirectiveWithinMetadirective && DKind == OMPD_unknown) {
2451     Diag(Tok, diag::err_omp_unknown_directive);
2452     return StmtError();
2453   }
2454   OpenMPDirectiveKind CancelRegion = OMPD_unknown;
2455   // Name of critical directive.
2456   DeclarationNameInfo DirName;
2457   StmtResult Directive = StmtError();
2458   bool HasAssociatedStatement = true;
2459 
2460   switch (DKind) {
2461   case OMPD_metadirective: {
2462     ConsumeToken();
2463     SmallVector<VariantMatchInfo, 4> VMIs;
2464 
2465     // First iteration of parsing all clauses of metadirective.
2466     // This iteration only parses and collects all context selector ignoring the
2467     // associated directives.
2468     TentativeParsingAction TPA(*this);
2469     ASTContext &ASTContext = Actions.getASTContext();
2470 
2471     BalancedDelimiterTracker T(*this, tok::l_paren,
2472                                tok::annot_pragma_openmp_end);
2473     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2474       OpenMPClauseKind CKind = Tok.isAnnotation()
2475                                    ? OMPC_unknown
2476                                    : getOpenMPClauseKind(PP.getSpelling(Tok));
2477       SourceLocation Loc = ConsumeToken();
2478 
2479       // Parse '('.
2480       if (T.expectAndConsume(diag::err_expected_lparen_after,
2481                              getOpenMPClauseName(CKind).data()))
2482         return Directive;
2483 
2484       OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2485       if (CKind == OMPC_when) {
2486         // parse and get OMPTraitInfo to pass to the When clause
2487         parseOMPContextSelectors(Loc, TI);
2488         if (TI.Sets.size() == 0) {
2489           Diag(Tok, diag::err_omp_expected_context_selector) << "when clause";
2490           TPA.Commit();
2491           return Directive;
2492         }
2493 
2494         // Parse ':'
2495         if (Tok.is(tok::colon))
2496           ConsumeAnyToken();
2497         else {
2498           Diag(Tok, diag::err_omp_expected_colon) << "when clause";
2499           TPA.Commit();
2500           return Directive;
2501         }
2502       }
2503       // Skip Directive for now. We will parse directive in the second iteration
2504       int paren = 0;
2505       while (Tok.isNot(tok::r_paren) || paren != 0) {
2506         if (Tok.is(tok::l_paren))
2507           paren++;
2508         if (Tok.is(tok::r_paren))
2509           paren--;
2510         if (Tok.is(tok::annot_pragma_openmp_end)) {
2511           Diag(Tok, diag::err_omp_expected_punc)
2512               << getOpenMPClauseName(CKind) << 0;
2513           TPA.Commit();
2514           return Directive;
2515         }
2516         ConsumeAnyToken();
2517       }
2518       // Parse ')'
2519       if (Tok.is(tok::r_paren))
2520         T.consumeClose();
2521 
2522       VariantMatchInfo VMI;
2523       TI.getAsVariantMatchInfo(ASTContext, VMI);
2524 
2525       VMIs.push_back(VMI);
2526     }
2527 
2528     TPA.Revert();
2529     // End of the first iteration. Parser is reset to the start of metadirective
2530 
2531     TargetOMPContext OMPCtx(ASTContext, /* DiagUnknownTrait */ nullptr,
2532                             /* CurrentFunctionDecl */ nullptr,
2533                             ArrayRef<llvm::omp::TraitProperty>());
2534 
2535     // A single match is returned for OpenMP 5.0
2536     int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
2537 
2538     int Idx = 0;
2539     // In OpenMP 5.0 metadirective is either replaced by another directive or
2540     // ignored.
2541     // TODO: In OpenMP 5.1 generate multiple directives based upon the matches
2542     // found by getBestWhenMatchForContext.
2543     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2544       // OpenMP 5.0 implementation - Skip to the best index found.
2545       if (Idx++ != BestIdx) {
2546         ConsumeToken();  // Consume clause name
2547         T.consumeOpen(); // Consume '('
2548         int paren = 0;
2549         // Skip everything inside the clause
2550         while (Tok.isNot(tok::r_paren) || paren != 0) {
2551           if (Tok.is(tok::l_paren))
2552             paren++;
2553           if (Tok.is(tok::r_paren))
2554             paren--;
2555           ConsumeAnyToken();
2556         }
2557         // Parse ')'
2558         if (Tok.is(tok::r_paren))
2559           T.consumeClose();
2560         continue;
2561       }
2562 
2563       OpenMPClauseKind CKind = Tok.isAnnotation()
2564                                    ? OMPC_unknown
2565                                    : getOpenMPClauseKind(PP.getSpelling(Tok));
2566       SourceLocation Loc = ConsumeToken();
2567 
2568       // Parse '('.
2569       T.consumeOpen();
2570 
2571       // Skip ContextSelectors for when clause
2572       if (CKind == OMPC_when) {
2573         OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2574         // parse and skip the ContextSelectors
2575         parseOMPContextSelectors(Loc, TI);
2576 
2577         // Parse ':'
2578         ConsumeAnyToken();
2579       }
2580 
2581       // If no directive is passed, skip in OpenMP 5.0.
2582       // TODO: Generate nothing directive from OpenMP 5.1.
2583       if (Tok.is(tok::r_paren)) {
2584         SkipUntil(tok::annot_pragma_openmp_end);
2585         break;
2586       }
2587 
2588       // Parse Directive
2589       ReadDirectiveWithinMetadirective = true;
2590       Directive = ParseOpenMPDeclarativeOrExecutableDirective(StmtCtx);
2591       ReadDirectiveWithinMetadirective = false;
2592       break;
2593     }
2594     break;
2595   }
2596   case OMPD_threadprivate: {
2597     // FIXME: Should this be permitted in C++?
2598     if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
2599         ParsedStmtContext()) {
2600       Diag(Tok, diag::err_omp_immediate_directive)
2601           << getOpenMPDirectiveName(DKind) << 0;
2602     }
2603     ConsumeToken();
2604     DeclDirectiveListParserHelper Helper(this, DKind);
2605     if (!ParseOpenMPSimpleVarList(DKind, Helper,
2606                                   /*AllowScopeSpecifier=*/false)) {
2607       skipUntilPragmaOpenMPEnd(DKind);
2608       DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
2609           Loc, Helper.getIdentifiers());
2610       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2611     }
2612     SkipUntil(tok::annot_pragma_openmp_end);
2613     break;
2614   }
2615   case OMPD_allocate: {
2616     // FIXME: Should this be permitted in C++?
2617     if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
2618         ParsedStmtContext()) {
2619       Diag(Tok, diag::err_omp_immediate_directive)
2620           << getOpenMPDirectiveName(DKind) << 0;
2621     }
2622     ConsumeToken();
2623     DeclDirectiveListParserHelper Helper(this, DKind);
2624     if (!ParseOpenMPSimpleVarList(DKind, Helper,
2625                                   /*AllowScopeSpecifier=*/false)) {
2626       SmallVector<OMPClause *, 1> Clauses;
2627       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2628         SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
2629                     llvm::omp::Clause_enumSize + 1>
2630             FirstClauses(llvm::omp::Clause_enumSize + 1);
2631         while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2632           OpenMPClauseKind CKind =
2633               Tok.isAnnotation() ? OMPC_unknown
2634                                  : getOpenMPClauseKind(PP.getSpelling(Tok));
2635           Actions.StartOpenMPClause(CKind);
2636           OMPClause *Clause = ParseOpenMPClause(
2637               OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt());
2638           SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2639                     StopBeforeMatch);
2640           FirstClauses[unsigned(CKind)].setInt(true);
2641           if (Clause != nullptr)
2642             Clauses.push_back(Clause);
2643           if (Tok.is(tok::annot_pragma_openmp_end)) {
2644             Actions.EndOpenMPClause();
2645             break;
2646           }
2647           // Skip ',' if any.
2648           if (Tok.is(tok::comma))
2649             ConsumeToken();
2650           Actions.EndOpenMPClause();
2651         }
2652         skipUntilPragmaOpenMPEnd(DKind);
2653       }
2654       DeclGroupPtrTy Res = Actions.ActOnOpenMPAllocateDirective(
2655           Loc, Helper.getIdentifiers(), Clauses);
2656       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2657     }
2658     SkipUntil(tok::annot_pragma_openmp_end);
2659     break;
2660   }
2661   case OMPD_declare_reduction:
2662     ConsumeToken();
2663     if (DeclGroupPtrTy Res =
2664             ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
2665       skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2666       ConsumeAnyToken();
2667       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2668     } else {
2669       SkipUntil(tok::annot_pragma_openmp_end);
2670     }
2671     break;
2672   case OMPD_declare_mapper: {
2673     ConsumeToken();
2674     if (DeclGroupPtrTy Res =
2675             ParseOpenMPDeclareMapperDirective(/*AS=*/AS_none)) {
2676       // Skip the last annot_pragma_openmp_end.
2677       ConsumeAnnotationToken();
2678       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2679     } else {
2680       SkipUntil(tok::annot_pragma_openmp_end);
2681     }
2682     break;
2683   }
2684   case OMPD_flush:
2685   case OMPD_depobj:
2686   case OMPD_scan:
2687   case OMPD_taskyield:
2688   case OMPD_barrier:
2689   case OMPD_taskwait:
2690   case OMPD_cancellation_point:
2691   case OMPD_cancel:
2692   case OMPD_target_enter_data:
2693   case OMPD_target_exit_data:
2694   case OMPD_target_update:
2695   case OMPD_interop:
2696     if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2697         ParsedStmtContext()) {
2698       Diag(Tok, diag::err_omp_immediate_directive)
2699           << getOpenMPDirectiveName(DKind) << 0;
2700     }
2701     HasAssociatedStatement = false;
2702     // Fall through for further analysis.
2703     LLVM_FALLTHROUGH;
2704   case OMPD_parallel:
2705   case OMPD_simd:
2706   case OMPD_tile:
2707   case OMPD_unroll:
2708   case OMPD_for:
2709   case OMPD_for_simd:
2710   case OMPD_sections:
2711   case OMPD_single:
2712   case OMPD_section:
2713   case OMPD_master:
2714   case OMPD_critical:
2715   case OMPD_parallel_for:
2716   case OMPD_parallel_for_simd:
2717   case OMPD_parallel_sections:
2718   case OMPD_parallel_master:
2719   case OMPD_task:
2720   case OMPD_ordered:
2721   case OMPD_atomic:
2722   case OMPD_target:
2723   case OMPD_teams:
2724   case OMPD_taskgroup:
2725   case OMPD_target_data:
2726   case OMPD_target_parallel:
2727   case OMPD_target_parallel_for:
2728   case OMPD_loop:
2729   case OMPD_taskloop:
2730   case OMPD_taskloop_simd:
2731   case OMPD_master_taskloop:
2732   case OMPD_master_taskloop_simd:
2733   case OMPD_parallel_master_taskloop:
2734   case OMPD_parallel_master_taskloop_simd:
2735   case OMPD_distribute:
2736   case OMPD_distribute_parallel_for:
2737   case OMPD_distribute_parallel_for_simd:
2738   case OMPD_distribute_simd:
2739   case OMPD_target_parallel_for_simd:
2740   case OMPD_target_simd:
2741   case OMPD_teams_distribute:
2742   case OMPD_teams_distribute_simd:
2743   case OMPD_teams_distribute_parallel_for_simd:
2744   case OMPD_teams_distribute_parallel_for:
2745   case OMPD_target_teams:
2746   case OMPD_target_teams_distribute:
2747   case OMPD_target_teams_distribute_parallel_for:
2748   case OMPD_target_teams_distribute_parallel_for_simd:
2749   case OMPD_target_teams_distribute_simd:
2750   case OMPD_dispatch:
2751   case OMPD_masked: {
2752     // Special processing for flush and depobj clauses.
2753     Token ImplicitTok;
2754     bool ImplicitClauseAllowed = false;
2755     if (DKind == OMPD_flush || DKind == OMPD_depobj) {
2756       ImplicitTok = Tok;
2757       ImplicitClauseAllowed = true;
2758     }
2759     ConsumeToken();
2760     // Parse directive name of the 'critical' directive if any.
2761     if (DKind == OMPD_critical) {
2762       BalancedDelimiterTracker T(*this, tok::l_paren,
2763                                  tok::annot_pragma_openmp_end);
2764       if (!T.consumeOpen()) {
2765         if (Tok.isAnyIdentifier()) {
2766           DirName =
2767               DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
2768           ConsumeAnyToken();
2769         } else {
2770           Diag(Tok, diag::err_omp_expected_identifier_for_critical);
2771         }
2772         T.consumeClose();
2773       }
2774     } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
2775       CancelRegion = parseOpenMPDirectiveKind(*this);
2776       if (Tok.isNot(tok::annot_pragma_openmp_end))
2777         ConsumeToken();
2778     }
2779 
2780     if (isOpenMPLoopDirective(DKind))
2781       ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
2782     if (isOpenMPSimdDirective(DKind))
2783       ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
2784     ParseScope OMPDirectiveScope(this, ScopeFlags);
2785     Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
2786 
2787     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2788       // If we are parsing for a directive within a metadirective, the directive
2789       // ends with a ')'.
2790       if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
2791         while (Tok.isNot(tok::annot_pragma_openmp_end))
2792           ConsumeAnyToken();
2793         break;
2794       }
2795       bool HasImplicitClause = false;
2796       if (ImplicitClauseAllowed && Tok.is(tok::l_paren)) {
2797         HasImplicitClause = true;
2798         // Push copy of the current token back to stream to properly parse
2799         // pseudo-clause OMPFlushClause or OMPDepobjClause.
2800         PP.EnterToken(Tok, /*IsReinject*/ true);
2801         PP.EnterToken(ImplicitTok, /*IsReinject*/ true);
2802         ConsumeAnyToken();
2803       }
2804       OpenMPClauseKind CKind = Tok.isAnnotation()
2805                                    ? OMPC_unknown
2806                                    : getOpenMPClauseKind(PP.getSpelling(Tok));
2807       if (HasImplicitClause) {
2808         assert(CKind == OMPC_unknown && "Must be unknown implicit clause.");
2809         if (DKind == OMPD_flush) {
2810           CKind = OMPC_flush;
2811         } else {
2812           assert(DKind == OMPD_depobj &&
2813                  "Expected flush or depobj directives.");
2814           CKind = OMPC_depobj;
2815         }
2816       }
2817       // No more implicit clauses allowed.
2818       ImplicitClauseAllowed = false;
2819       Actions.StartOpenMPClause(CKind);
2820       HasImplicitClause = false;
2821       OMPClause *Clause = ParseOpenMPClause(
2822           DKind, CKind, !FirstClauses[unsigned(CKind)].getInt());
2823       FirstClauses[unsigned(CKind)].setInt(true);
2824       if (Clause) {
2825         FirstClauses[unsigned(CKind)].setPointer(Clause);
2826         Clauses.push_back(Clause);
2827       }
2828 
2829       // Skip ',' if any.
2830       if (Tok.is(tok::comma))
2831         ConsumeToken();
2832       Actions.EndOpenMPClause();
2833     }
2834     // End location of the directive.
2835     EndLoc = Tok.getLocation();
2836     // Consume final annot_pragma_openmp_end.
2837     ConsumeAnnotationToken();
2838 
2839     // OpenMP [2.13.8, ordered Construct, Syntax]
2840     // If the depend clause is specified, the ordered construct is a stand-alone
2841     // directive.
2842     if (DKind == OMPD_ordered && FirstClauses[unsigned(OMPC_depend)].getInt()) {
2843       if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2844           ParsedStmtContext()) {
2845         Diag(Loc, diag::err_omp_immediate_directive)
2846             << getOpenMPDirectiveName(DKind) << 1
2847             << getOpenMPClauseName(OMPC_depend);
2848       }
2849       HasAssociatedStatement = false;
2850     }
2851 
2852     if (DKind == OMPD_tile && !FirstClauses[unsigned(OMPC_sizes)].getInt()) {
2853       Diag(Loc, diag::err_omp_required_clause)
2854           << getOpenMPDirectiveName(OMPD_tile) << "sizes";
2855     }
2856 
2857     StmtResult AssociatedStmt;
2858     if (HasAssociatedStatement) {
2859       // The body is a block scope like in Lambdas and Blocks.
2860       Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
2861       // FIXME: We create a bogus CompoundStmt scope to hold the contents of
2862       // the captured region. Code elsewhere assumes that any FunctionScopeInfo
2863       // should have at least one compound statement scope within it.
2864       ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false);
2865       {
2866         Sema::CompoundScopeRAII Scope(Actions);
2867         AssociatedStmt = ParseStatement();
2868 
2869         if (AssociatedStmt.isUsable() && isOpenMPLoopDirective(DKind) &&
2870             getLangOpts().OpenMPIRBuilder)
2871           AssociatedStmt = Actions.ActOnOpenMPLoopnest(AssociatedStmt.get());
2872       }
2873       AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2874     } else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
2875                DKind == OMPD_target_exit_data) {
2876       Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
2877       AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
2878                         Actions.ActOnCompoundStmt(Loc, Loc, llvm::None,
2879                                                   /*isStmtExpr=*/false));
2880       AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2881     }
2882     Directive = Actions.ActOnOpenMPExecutableDirective(
2883         DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
2884         EndLoc);
2885 
2886     // Exit scope.
2887     Actions.EndOpenMPDSABlock(Directive.get());
2888     OMPDirectiveScope.Exit();
2889     break;
2890   }
2891   case OMPD_declare_simd:
2892   case OMPD_declare_target:
2893   case OMPD_begin_declare_target:
2894   case OMPD_end_declare_target:
2895   case OMPD_requires:
2896   case OMPD_begin_declare_variant:
2897   case OMPD_end_declare_variant:
2898   case OMPD_declare_variant:
2899     Diag(Tok, diag::err_omp_unexpected_directive)
2900         << 1 << getOpenMPDirectiveName(DKind);
2901     SkipUntil(tok::annot_pragma_openmp_end);
2902     break;
2903   case OMPD_unknown:
2904   default:
2905     Diag(Tok, diag::err_omp_unknown_directive);
2906     SkipUntil(tok::annot_pragma_openmp_end);
2907     break;
2908   }
2909   return Directive;
2910 }
2911 
2912 // Parses simple list:
2913 //   simple-variable-list:
2914 //         '(' id-expression {, id-expression} ')'
2915 //
2916 bool Parser::ParseOpenMPSimpleVarList(
2917     OpenMPDirectiveKind Kind,
2918     const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)>
2919         &Callback,
2920     bool AllowScopeSpecifier) {
2921   // Parse '('.
2922   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2923   if (T.expectAndConsume(diag::err_expected_lparen_after,
2924                          getOpenMPDirectiveName(Kind).data()))
2925     return true;
2926   bool IsCorrect = true;
2927   bool NoIdentIsFound = true;
2928 
2929   // Read tokens while ')' or annot_pragma_openmp_end is not found.
2930   while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
2931     CXXScopeSpec SS;
2932     UnqualifiedId Name;
2933     // Read var name.
2934     Token PrevTok = Tok;
2935     NoIdentIsFound = false;
2936 
2937     if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
2938         ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
2939                                        /*ObjectHadErrors=*/false, false)) {
2940       IsCorrect = false;
2941       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2942                 StopBeforeMatch);
2943     } else if (ParseUnqualifiedId(SS, /*ObjectType=*/nullptr,
2944                                   /*ObjectHadErrors=*/false, false, false,
2945                                   false, false, nullptr, Name)) {
2946       IsCorrect = false;
2947       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2948                 StopBeforeMatch);
2949     } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
2950                Tok.isNot(tok::annot_pragma_openmp_end)) {
2951       IsCorrect = false;
2952       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2953                 StopBeforeMatch);
2954       Diag(PrevTok.getLocation(), diag::err_expected)
2955           << tok::identifier
2956           << SourceRange(PrevTok.getLocation(), PrevTokLocation);
2957     } else {
2958       Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
2959     }
2960     // Consume ','.
2961     if (Tok.is(tok::comma)) {
2962       ConsumeToken();
2963     }
2964   }
2965 
2966   if (NoIdentIsFound) {
2967     Diag(Tok, diag::err_expected) << tok::identifier;
2968     IsCorrect = false;
2969   }
2970 
2971   // Parse ')'.
2972   IsCorrect = !T.consumeClose() && IsCorrect;
2973 
2974   return !IsCorrect;
2975 }
2976 
2977 OMPClause *Parser::ParseOpenMPSizesClause() {
2978   SourceLocation ClauseNameLoc = ConsumeToken();
2979   SmallVector<Expr *, 4> ValExprs;
2980 
2981   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2982   if (T.consumeOpen()) {
2983     Diag(Tok, diag::err_expected) << tok::l_paren;
2984     return nullptr;
2985   }
2986 
2987   while (true) {
2988     ExprResult Val = ParseConstantExpression();
2989     if (!Val.isUsable()) {
2990       T.skipToEnd();
2991       return nullptr;
2992     }
2993 
2994     ValExprs.push_back(Val.get());
2995 
2996     if (Tok.is(tok::r_paren) || Tok.is(tok::annot_pragma_openmp_end))
2997       break;
2998 
2999     ExpectAndConsume(tok::comma);
3000   }
3001 
3002   T.consumeClose();
3003 
3004   return Actions.ActOnOpenMPSizesClause(
3005       ValExprs, ClauseNameLoc, T.getOpenLocation(), T.getCloseLocation());
3006 }
3007 
3008 OMPClause *Parser::ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind) {
3009   SourceLocation Loc = Tok.getLocation();
3010   ConsumeAnyToken();
3011 
3012   // Parse '('.
3013   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3014   if (T.expectAndConsume(diag::err_expected_lparen_after, "uses_allocator"))
3015     return nullptr;
3016   SmallVector<Sema::UsesAllocatorsData, 4> Data;
3017   do {
3018     ExprResult Allocator =
3019         getLangOpts().CPlusPlus ? ParseCXXIdExpression() : ParseExpression();
3020     if (Allocator.isInvalid()) {
3021       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3022                 StopBeforeMatch);
3023       break;
3024     }
3025     Sema::UsesAllocatorsData &D = Data.emplace_back();
3026     D.Allocator = Allocator.get();
3027     if (Tok.is(tok::l_paren)) {
3028       BalancedDelimiterTracker T(*this, tok::l_paren,
3029                                  tok::annot_pragma_openmp_end);
3030       T.consumeOpen();
3031       ExprResult AllocatorTraits =
3032           getLangOpts().CPlusPlus ? ParseCXXIdExpression() : ParseExpression();
3033       T.consumeClose();
3034       if (AllocatorTraits.isInvalid()) {
3035         SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3036                   StopBeforeMatch);
3037         break;
3038       }
3039       D.AllocatorTraits = AllocatorTraits.get();
3040       D.LParenLoc = T.getOpenLocation();
3041       D.RParenLoc = T.getCloseLocation();
3042     }
3043     if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
3044       Diag(Tok, diag::err_omp_expected_punc) << "uses_allocators" << 0;
3045     // Parse ','
3046     if (Tok.is(tok::comma))
3047       ConsumeAnyToken();
3048   } while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end));
3049   T.consumeClose();
3050   return Actions.ActOnOpenMPUsesAllocatorClause(Loc, T.getOpenLocation(),
3051                                                 T.getCloseLocation(), Data);
3052 }
3053 
3054 /// Parsing of OpenMP clauses.
3055 ///
3056 ///    clause:
3057 ///       if-clause | final-clause | num_threads-clause | safelen-clause |
3058 ///       default-clause | private-clause | firstprivate-clause | shared-clause
3059 ///       | linear-clause | aligned-clause | collapse-clause | bind-clause |
3060 ///       lastprivate-clause | reduction-clause | proc_bind-clause |
3061 ///       schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
3062 ///       mergeable-clause | flush-clause | read-clause | write-clause |
3063 ///       update-clause | capture-clause | seq_cst-clause | device-clause |
3064 ///       simdlen-clause | threads-clause | simd-clause | num_teams-clause |
3065 ///       thread_limit-clause | priority-clause | grainsize-clause |
3066 ///       nogroup-clause | num_tasks-clause | hint-clause | to-clause |
3067 ///       from-clause | is_device_ptr-clause | task_reduction-clause |
3068 ///       in_reduction-clause | allocator-clause | allocate-clause |
3069 ///       acq_rel-clause | acquire-clause | release-clause | relaxed-clause |
3070 ///       depobj-clause | destroy-clause | detach-clause | inclusive-clause |
3071 ///       exclusive-clause | uses_allocators-clause | use_device_addr-clause
3072 ///
3073 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
3074                                      OpenMPClauseKind CKind, bool FirstClause) {
3075   OMPClauseKind = CKind;
3076   OMPClause *Clause = nullptr;
3077   bool ErrorFound = false;
3078   bool WrongDirective = false;
3079   // Check if clause is allowed for the given directive.
3080   if (CKind != OMPC_unknown &&
3081       !isAllowedClauseForDirective(DKind, CKind, getLangOpts().OpenMP)) {
3082     Diag(Tok, diag::err_omp_unexpected_clause)
3083         << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
3084     ErrorFound = true;
3085     WrongDirective = true;
3086   }
3087 
3088   switch (CKind) {
3089   case OMPC_final:
3090   case OMPC_num_threads:
3091   case OMPC_safelen:
3092   case OMPC_simdlen:
3093   case OMPC_collapse:
3094   case OMPC_ordered:
3095   case OMPC_num_teams:
3096   case OMPC_thread_limit:
3097   case OMPC_priority:
3098   case OMPC_grainsize:
3099   case OMPC_num_tasks:
3100   case OMPC_hint:
3101   case OMPC_allocator:
3102   case OMPC_depobj:
3103   case OMPC_detach:
3104   case OMPC_novariants:
3105   case OMPC_nocontext:
3106   case OMPC_filter:
3107   case OMPC_partial:
3108     // OpenMP [2.5, Restrictions]
3109     //  At most one num_threads clause can appear on the directive.
3110     // OpenMP [2.8.1, simd construct, Restrictions]
3111     //  Only one safelen  clause can appear on a simd directive.
3112     //  Only one simdlen  clause can appear on a simd directive.
3113     //  Only one collapse clause can appear on a simd directive.
3114     // OpenMP [2.11.1, task Construct, Restrictions]
3115     //  At most one if clause can appear on the directive.
3116     //  At most one final clause can appear on the directive.
3117     // OpenMP [teams Construct, Restrictions]
3118     //  At most one num_teams clause can appear on the directive.
3119     //  At most one thread_limit clause can appear on the directive.
3120     // OpenMP [2.9.1, task Construct, Restrictions]
3121     // At most one priority clause can appear on the directive.
3122     // OpenMP [2.9.2, taskloop Construct, Restrictions]
3123     // At most one grainsize clause can appear on the directive.
3124     // OpenMP [2.9.2, taskloop Construct, Restrictions]
3125     // At most one num_tasks clause can appear on the directive.
3126     // OpenMP [2.11.3, allocate Directive, Restrictions]
3127     // At most one allocator clause can appear on the directive.
3128     // OpenMP 5.0, 2.10.1 task Construct, Restrictions.
3129     // At most one detach clause can appear on the directive.
3130     // OpenMP 5.1, 2.3.6 dispatch Construct, Restrictions.
3131     // At most one novariants clause can appear on a dispatch directive.
3132     // At most one nocontext clause can appear on a dispatch directive.
3133     if (!FirstClause) {
3134       Diag(Tok, diag::err_omp_more_one_clause)
3135           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3136       ErrorFound = true;
3137     }
3138 
3139     if ((CKind == OMPC_ordered || CKind == OMPC_partial) &&
3140         PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
3141       Clause = ParseOpenMPClause(CKind, WrongDirective);
3142     else
3143       Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3144     break;
3145   case OMPC_default:
3146   case OMPC_proc_bind:
3147   case OMPC_atomic_default_mem_order:
3148   case OMPC_order:
3149   case OMPC_bind:
3150     // OpenMP [2.14.3.1, Restrictions]
3151     //  Only a single default clause may be specified on a parallel, task or
3152     //  teams directive.
3153     // OpenMP [2.5, parallel Construct, Restrictions]
3154     //  At most one proc_bind clause can appear on the directive.
3155     // OpenMP [5.0, Requires directive, Restrictions]
3156     //  At most one atomic_default_mem_order clause can appear
3157     //  on the directive
3158     // OpenMP 5.1, 2.11.7 loop Construct, Restrictions.
3159     // At most one bind clause can appear on a loop directive.
3160     if (!FirstClause && CKind != OMPC_order) {
3161       Diag(Tok, diag::err_omp_more_one_clause)
3162           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3163       ErrorFound = true;
3164     }
3165 
3166     Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
3167     break;
3168   case OMPC_device:
3169   case OMPC_schedule:
3170   case OMPC_dist_schedule:
3171   case OMPC_defaultmap:
3172     // OpenMP [2.7.1, Restrictions, p. 3]
3173     //  Only one schedule clause can appear on a loop directive.
3174     // OpenMP 4.5 [2.10.4, Restrictions, p. 106]
3175     //  At most one defaultmap clause can appear on the directive.
3176     // OpenMP 5.0 [2.12.5, target construct, Restrictions]
3177     //  At most one device clause can appear on the directive.
3178     if ((getLangOpts().OpenMP < 50 || CKind != OMPC_defaultmap) &&
3179         !FirstClause) {
3180       Diag(Tok, diag::err_omp_more_one_clause)
3181           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3182       ErrorFound = true;
3183     }
3184     LLVM_FALLTHROUGH;
3185   case OMPC_if:
3186     Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3187     break;
3188   case OMPC_nowait:
3189   case OMPC_untied:
3190   case OMPC_mergeable:
3191   case OMPC_read:
3192   case OMPC_write:
3193   case OMPC_capture:
3194   case OMPC_seq_cst:
3195   case OMPC_acq_rel:
3196   case OMPC_acquire:
3197   case OMPC_release:
3198   case OMPC_relaxed:
3199   case OMPC_threads:
3200   case OMPC_simd:
3201   case OMPC_nogroup:
3202   case OMPC_unified_address:
3203   case OMPC_unified_shared_memory:
3204   case OMPC_reverse_offload:
3205   case OMPC_dynamic_allocators:
3206   case OMPC_full:
3207     // OpenMP [2.7.1, Restrictions, p. 9]
3208     //  Only one ordered clause can appear on a loop directive.
3209     // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
3210     //  Only one nowait clause can appear on a for directive.
3211     // OpenMP [5.0, Requires directive, Restrictions]
3212     //   Each of the requires clauses can appear at most once on the directive.
3213     if (!FirstClause) {
3214       Diag(Tok, diag::err_omp_more_one_clause)
3215           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3216       ErrorFound = true;
3217     }
3218 
3219     Clause = ParseOpenMPClause(CKind, WrongDirective);
3220     break;
3221   case OMPC_update:
3222     if (!FirstClause) {
3223       Diag(Tok, diag::err_omp_more_one_clause)
3224           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3225       ErrorFound = true;
3226     }
3227 
3228     Clause = (DKind == OMPD_depobj)
3229                  ? ParseOpenMPSimpleClause(CKind, WrongDirective)
3230                  : ParseOpenMPClause(CKind, WrongDirective);
3231     break;
3232   case OMPC_private:
3233   case OMPC_firstprivate:
3234   case OMPC_lastprivate:
3235   case OMPC_shared:
3236   case OMPC_reduction:
3237   case OMPC_task_reduction:
3238   case OMPC_in_reduction:
3239   case OMPC_linear:
3240   case OMPC_aligned:
3241   case OMPC_copyin:
3242   case OMPC_copyprivate:
3243   case OMPC_flush:
3244   case OMPC_depend:
3245   case OMPC_map:
3246   case OMPC_to:
3247   case OMPC_from:
3248   case OMPC_use_device_ptr:
3249   case OMPC_use_device_addr:
3250   case OMPC_is_device_ptr:
3251   case OMPC_allocate:
3252   case OMPC_nontemporal:
3253   case OMPC_inclusive:
3254   case OMPC_exclusive:
3255   case OMPC_affinity:
3256     Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
3257     break;
3258   case OMPC_sizes:
3259     if (!FirstClause) {
3260       Diag(Tok, diag::err_omp_more_one_clause)
3261           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3262       ErrorFound = true;
3263     }
3264 
3265     Clause = ParseOpenMPSizesClause();
3266     break;
3267   case OMPC_uses_allocators:
3268     Clause = ParseOpenMPUsesAllocatorClause(DKind);
3269     break;
3270   case OMPC_destroy:
3271     if (DKind != OMPD_interop) {
3272       if (!FirstClause) {
3273         Diag(Tok, diag::err_omp_more_one_clause)
3274             << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3275         ErrorFound = true;
3276       }
3277       Clause = ParseOpenMPClause(CKind, WrongDirective);
3278       break;
3279     }
3280     LLVM_FALLTHROUGH;
3281   case OMPC_init:
3282   case OMPC_use:
3283     Clause = ParseOpenMPInteropClause(CKind, WrongDirective);
3284     break;
3285   case OMPC_device_type:
3286   case OMPC_unknown:
3287     skipUntilPragmaOpenMPEnd(DKind);
3288     break;
3289   case OMPC_threadprivate:
3290   case OMPC_uniform:
3291   case OMPC_match:
3292     if (!WrongDirective)
3293       Diag(Tok, diag::err_omp_unexpected_clause)
3294           << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
3295     SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
3296     break;
3297   default:
3298     break;
3299   }
3300   return ErrorFound ? nullptr : Clause;
3301 }
3302 
3303 /// Parses simple expression in parens for single-expression clauses of OpenMP
3304 /// constructs.
3305 /// \param RLoc Returned location of right paren.
3306 ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
3307                                          SourceLocation &RLoc,
3308                                          bool IsAddressOfOperand) {
3309   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3310   if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
3311     return ExprError();
3312 
3313   SourceLocation ELoc = Tok.getLocation();
3314   ExprResult LHS(
3315       ParseCastExpression(AnyCastExpr, IsAddressOfOperand, NotTypeCast));
3316   ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3317   Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
3318 
3319   // Parse ')'.
3320   RLoc = Tok.getLocation();
3321   if (!T.consumeClose())
3322     RLoc = T.getCloseLocation();
3323 
3324   return Val;
3325 }
3326 
3327 /// Parsing of OpenMP clauses with single expressions like 'final',
3328 /// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
3329 /// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks', 'hint' or
3330 /// 'detach'.
3331 ///
3332 ///    final-clause:
3333 ///      'final' '(' expression ')'
3334 ///
3335 ///    num_threads-clause:
3336 ///      'num_threads' '(' expression ')'
3337 ///
3338 ///    safelen-clause:
3339 ///      'safelen' '(' expression ')'
3340 ///
3341 ///    simdlen-clause:
3342 ///      'simdlen' '(' expression ')'
3343 ///
3344 ///    collapse-clause:
3345 ///      'collapse' '(' expression ')'
3346 ///
3347 ///    priority-clause:
3348 ///      'priority' '(' expression ')'
3349 ///
3350 ///    grainsize-clause:
3351 ///      'grainsize' '(' expression ')'
3352 ///
3353 ///    num_tasks-clause:
3354 ///      'num_tasks' '(' expression ')'
3355 ///
3356 ///    hint-clause:
3357 ///      'hint' '(' expression ')'
3358 ///
3359 ///    allocator-clause:
3360 ///      'allocator' '(' expression ')'
3361 ///
3362 ///    detach-clause:
3363 ///      'detach' '(' event-handler-expression ')'
3364 ///
3365 OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
3366                                                bool ParseOnly) {
3367   SourceLocation Loc = ConsumeToken();
3368   SourceLocation LLoc = Tok.getLocation();
3369   SourceLocation RLoc;
3370 
3371   ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc);
3372 
3373   if (Val.isInvalid())
3374     return nullptr;
3375 
3376   if (ParseOnly)
3377     return nullptr;
3378   return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc);
3379 }
3380 
3381 /// Parsing of OpenMP clauses that use an interop-var.
3382 ///
3383 /// init-clause:
3384 ///   init([interop-modifier, ]interop-type[[, interop-type] ... ]:interop-var)
3385 ///
3386 /// destroy-clause:
3387 ///   destroy(interop-var)
3388 ///
3389 /// use-clause:
3390 ///   use(interop-var)
3391 ///
3392 /// interop-modifier:
3393 ///   prefer_type(preference-list)
3394 ///
3395 /// preference-list:
3396 ///   foreign-runtime-id [, foreign-runtime-id]...
3397 ///
3398 /// foreign-runtime-id:
3399 ///   <string-literal> | <constant-integral-expression>
3400 ///
3401 /// interop-type:
3402 ///   target | targetsync
3403 ///
3404 OMPClause *Parser::ParseOpenMPInteropClause(OpenMPClauseKind Kind,
3405                                             bool ParseOnly) {
3406   SourceLocation Loc = ConsumeToken();
3407   // Parse '('.
3408   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3409   if (T.expectAndConsume(diag::err_expected_lparen_after,
3410                          getOpenMPClauseName(Kind).data()))
3411     return nullptr;
3412 
3413   bool IsTarget = false;
3414   bool IsTargetSync = false;
3415   SmallVector<Expr *, 4> Prefs;
3416 
3417   if (Kind == OMPC_init) {
3418 
3419     // Parse optional interop-modifier.
3420     if (Tok.is(tok::identifier) && PP.getSpelling(Tok) == "prefer_type") {
3421       ConsumeToken();
3422       BalancedDelimiterTracker PT(*this, tok::l_paren,
3423                                   tok::annot_pragma_openmp_end);
3424       if (PT.expectAndConsume(diag::err_expected_lparen_after, "prefer_type"))
3425         return nullptr;
3426 
3427       while (Tok.isNot(tok::r_paren)) {
3428         SourceLocation Loc = Tok.getLocation();
3429         ExprResult LHS = ParseCastExpression(AnyCastExpr);
3430         ExprResult PTExpr = Actions.CorrectDelayedTyposInExpr(
3431             ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3432         PTExpr = Actions.ActOnFinishFullExpr(PTExpr.get(), Loc,
3433                                              /*DiscardedValue=*/false);
3434         if (PTExpr.isUsable())
3435           Prefs.push_back(PTExpr.get());
3436         else
3437           SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3438                     StopBeforeMatch);
3439 
3440         if (Tok.is(tok::comma))
3441           ConsumeToken();
3442       }
3443       PT.consumeClose();
3444     }
3445 
3446     if (!Prefs.empty()) {
3447       if (Tok.is(tok::comma))
3448         ConsumeToken();
3449       else
3450         Diag(Tok, diag::err_omp_expected_punc_after_interop_mod);
3451     }
3452 
3453     // Parse the interop-types.
3454     if (Optional<OMPDeclareVariantAttr::InteropType> IType =
3455             parseInteropTypeList(*this)) {
3456       IsTarget = IType != OMPDeclareVariantAttr::TargetSync;
3457       IsTargetSync = IType != OMPDeclareVariantAttr::Target;
3458       if (Tok.isNot(tok::colon))
3459         Diag(Tok, diag::warn_pragma_expected_colon) << "interop types";
3460     }
3461     if (Tok.is(tok::colon))
3462       ConsumeToken();
3463   }
3464 
3465   // Parse the variable.
3466   SourceLocation VarLoc = Tok.getLocation();
3467   ExprResult InteropVarExpr =
3468       Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
3469   if (!InteropVarExpr.isUsable()) {
3470     SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3471               StopBeforeMatch);
3472   }
3473 
3474   // Parse ')'.
3475   SourceLocation RLoc = Tok.getLocation();
3476   if (!T.consumeClose())
3477     RLoc = T.getCloseLocation();
3478 
3479   if (ParseOnly || !InteropVarExpr.isUsable() ||
3480       (Kind == OMPC_init && !IsTarget && !IsTargetSync))
3481     return nullptr;
3482 
3483   if (Kind == OMPC_init)
3484     return Actions.ActOnOpenMPInitClause(InteropVarExpr.get(), Prefs, IsTarget,
3485                                          IsTargetSync, Loc, T.getOpenLocation(),
3486                                          VarLoc, RLoc);
3487   if (Kind == OMPC_use)
3488     return Actions.ActOnOpenMPUseClause(InteropVarExpr.get(), Loc,
3489                                         T.getOpenLocation(), VarLoc, RLoc);
3490 
3491   if (Kind == OMPC_destroy)
3492     return Actions.ActOnOpenMPDestroyClause(InteropVarExpr.get(), Loc,
3493                                             T.getOpenLocation(), VarLoc, RLoc);
3494 
3495   llvm_unreachable("Unexpected interop variable clause.");
3496 }
3497 
3498 /// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
3499 ///
3500 ///    default-clause:
3501 ///         'default' '(' 'none' | 'shared' | 'firstprivate' ')'
3502 ///
3503 ///    proc_bind-clause:
3504 ///         'proc_bind' '(' 'master' | 'close' | 'spread' ')'
3505 ///
3506 ///    bind-clause:
3507 ///         'bind' '(' 'teams' | 'parallel' | 'thread' ')'
3508 ///
3509 ///    update-clause:
3510 ///         'update' '(' 'in' | 'out' | 'inout' | 'mutexinoutset' ')'
3511 ///
3512 OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind,
3513                                            bool ParseOnly) {
3514   llvm::Optional<SimpleClauseData> Val = parseOpenMPSimpleClause(*this, Kind);
3515   if (!Val || ParseOnly)
3516     return nullptr;
3517   if (getLangOpts().OpenMP < 51 && Kind == OMPC_default &&
3518       static_cast<DefaultKind>(Val.getValue().Type) ==
3519           OMP_DEFAULT_firstprivate) {
3520     Diag(Val.getValue().LOpen, diag::err_omp_invalid_dsa)
3521         << getOpenMPClauseName(OMPC_firstprivate)
3522         << getOpenMPClauseName(OMPC_default) << "5.1";
3523     return nullptr;
3524   }
3525   return Actions.ActOnOpenMPSimpleClause(
3526       Kind, Val.getValue().Type, Val.getValue().TypeLoc, Val.getValue().LOpen,
3527       Val.getValue().Loc, Val.getValue().RLoc);
3528 }
3529 
3530 /// Parsing of OpenMP clauses like 'ordered'.
3531 ///
3532 ///    ordered-clause:
3533 ///         'ordered'
3534 ///
3535 ///    nowait-clause:
3536 ///         'nowait'
3537 ///
3538 ///    untied-clause:
3539 ///         'untied'
3540 ///
3541 ///    mergeable-clause:
3542 ///         'mergeable'
3543 ///
3544 ///    read-clause:
3545 ///         'read'
3546 ///
3547 ///    threads-clause:
3548 ///         'threads'
3549 ///
3550 ///    simd-clause:
3551 ///         'simd'
3552 ///
3553 ///    nogroup-clause:
3554 ///         'nogroup'
3555 ///
3556 OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly) {
3557   SourceLocation Loc = Tok.getLocation();
3558   ConsumeAnyToken();
3559 
3560   if (ParseOnly)
3561     return nullptr;
3562   return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
3563 }
3564 
3565 /// Parsing of OpenMP clauses with single expressions and some additional
3566 /// argument like 'schedule' or 'dist_schedule'.
3567 ///
3568 ///    schedule-clause:
3569 ///      'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
3570 ///      ')'
3571 ///
3572 ///    if-clause:
3573 ///      'if' '(' [ directive-name-modifier ':' ] expression ')'
3574 ///
3575 ///    defaultmap:
3576 ///      'defaultmap' '(' modifier [ ':' kind ] ')'
3577 ///
3578 ///    device-clause:
3579 ///      'device' '(' [ device-modifier ':' ] expression ')'
3580 ///
3581 OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind,
3582                                                       OpenMPClauseKind Kind,
3583                                                       bool ParseOnly) {
3584   SourceLocation Loc = ConsumeToken();
3585   SourceLocation DelimLoc;
3586   // Parse '('.
3587   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3588   if (T.expectAndConsume(diag::err_expected_lparen_after,
3589                          getOpenMPClauseName(Kind).data()))
3590     return nullptr;
3591 
3592   ExprResult Val;
3593   SmallVector<unsigned, 4> Arg;
3594   SmallVector<SourceLocation, 4> KLoc;
3595   if (Kind == OMPC_schedule) {
3596     enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
3597     Arg.resize(NumberOfElements);
3598     KLoc.resize(NumberOfElements);
3599     Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
3600     Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
3601     Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
3602     unsigned KindModifier = getOpenMPSimpleClauseType(
3603         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok), getLangOpts());
3604     if (KindModifier > OMPC_SCHEDULE_unknown) {
3605       // Parse 'modifier'
3606       Arg[Modifier1] = KindModifier;
3607       KLoc[Modifier1] = Tok.getLocation();
3608       if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3609           Tok.isNot(tok::annot_pragma_openmp_end))
3610         ConsumeAnyToken();
3611       if (Tok.is(tok::comma)) {
3612         // Parse ',' 'modifier'
3613         ConsumeAnyToken();
3614         KindModifier = getOpenMPSimpleClauseType(
3615             Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok), getLangOpts());
3616         Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown
3617                              ? KindModifier
3618                              : (unsigned)OMPC_SCHEDULE_unknown;
3619         KLoc[Modifier2] = Tok.getLocation();
3620         if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3621             Tok.isNot(tok::annot_pragma_openmp_end))
3622           ConsumeAnyToken();
3623       }
3624       // Parse ':'
3625       if (Tok.is(tok::colon))
3626         ConsumeAnyToken();
3627       else
3628         Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier";
3629       KindModifier = getOpenMPSimpleClauseType(
3630           Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok), getLangOpts());
3631     }
3632     Arg[ScheduleKind] = KindModifier;
3633     KLoc[ScheduleKind] = Tok.getLocation();
3634     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3635         Tok.isNot(tok::annot_pragma_openmp_end))
3636       ConsumeAnyToken();
3637     if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
3638          Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
3639          Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
3640         Tok.is(tok::comma))
3641       DelimLoc = ConsumeAnyToken();
3642   } else if (Kind == OMPC_dist_schedule) {
3643     Arg.push_back(getOpenMPSimpleClauseType(
3644         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok), getLangOpts()));
3645     KLoc.push_back(Tok.getLocation());
3646     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3647         Tok.isNot(tok::annot_pragma_openmp_end))
3648       ConsumeAnyToken();
3649     if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
3650       DelimLoc = ConsumeAnyToken();
3651   } else if (Kind == OMPC_defaultmap) {
3652     // Get a defaultmap modifier
3653     unsigned Modifier = getOpenMPSimpleClauseType(
3654         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok), getLangOpts());
3655     // Set defaultmap modifier to unknown if it is either scalar, aggregate, or
3656     // pointer
3657     if (Modifier < OMPC_DEFAULTMAP_MODIFIER_unknown)
3658       Modifier = OMPC_DEFAULTMAP_MODIFIER_unknown;
3659     Arg.push_back(Modifier);
3660     KLoc.push_back(Tok.getLocation());
3661     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3662         Tok.isNot(tok::annot_pragma_openmp_end))
3663       ConsumeAnyToken();
3664     // Parse ':'
3665     if (Tok.is(tok::colon) || getLangOpts().OpenMP < 50) {
3666       if (Tok.is(tok::colon))
3667         ConsumeAnyToken();
3668       else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown)
3669         Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier";
3670       // Get a defaultmap kind
3671       Arg.push_back(getOpenMPSimpleClauseType(
3672           Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok), getLangOpts()));
3673       KLoc.push_back(Tok.getLocation());
3674       if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3675           Tok.isNot(tok::annot_pragma_openmp_end))
3676         ConsumeAnyToken();
3677     } else {
3678       Arg.push_back(OMPC_DEFAULTMAP_unknown);
3679       KLoc.push_back(SourceLocation());
3680     }
3681   } else if (Kind == OMPC_device) {
3682     // Only target executable directives support extended device construct.
3683     if (isOpenMPTargetExecutionDirective(DKind) && getLangOpts().OpenMP >= 50 &&
3684         NextToken().is(tok::colon)) {
3685       // Parse optional <device modifier> ':'
3686       Arg.push_back(getOpenMPSimpleClauseType(
3687           Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok), getLangOpts()));
3688       KLoc.push_back(Tok.getLocation());
3689       ConsumeAnyToken();
3690       // Parse ':'
3691       ConsumeAnyToken();
3692     } else {
3693       Arg.push_back(OMPC_DEVICE_unknown);
3694       KLoc.emplace_back();
3695     }
3696   } else {
3697     assert(Kind == OMPC_if);
3698     KLoc.push_back(Tok.getLocation());
3699     TentativeParsingAction TPA(*this);
3700     auto DK = parseOpenMPDirectiveKind(*this);
3701     Arg.push_back(DK);
3702     if (DK != OMPD_unknown) {
3703       ConsumeToken();
3704       if (Tok.is(tok::colon) && getLangOpts().OpenMP > 40) {
3705         TPA.Commit();
3706         DelimLoc = ConsumeToken();
3707       } else {
3708         TPA.Revert();
3709         Arg.back() = unsigned(OMPD_unknown);
3710       }
3711     } else {
3712       TPA.Revert();
3713     }
3714   }
3715 
3716   bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) ||
3717                           (Kind == OMPC_dist_schedule && DelimLoc.isValid()) ||
3718                           Kind == OMPC_if || Kind == OMPC_device;
3719   if (NeedAnExpression) {
3720     SourceLocation ELoc = Tok.getLocation();
3721     ExprResult LHS(ParseCastExpression(AnyCastExpr, false, NotTypeCast));
3722     Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
3723     Val =
3724         Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
3725   }
3726 
3727   // Parse ')'.
3728   SourceLocation RLoc = Tok.getLocation();
3729   if (!T.consumeClose())
3730     RLoc = T.getCloseLocation();
3731 
3732   if (NeedAnExpression && Val.isInvalid())
3733     return nullptr;
3734 
3735   if (ParseOnly)
3736     return nullptr;
3737   return Actions.ActOnOpenMPSingleExprWithArgClause(
3738       Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
3739 }
3740 
3741 static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
3742                              UnqualifiedId &ReductionId) {
3743   if (ReductionIdScopeSpec.isEmpty()) {
3744     auto OOK = OO_None;
3745     switch (P.getCurToken().getKind()) {
3746     case tok::plus:
3747       OOK = OO_Plus;
3748       break;
3749     case tok::minus:
3750       OOK = OO_Minus;
3751       break;
3752     case tok::star:
3753       OOK = OO_Star;
3754       break;
3755     case tok::amp:
3756       OOK = OO_Amp;
3757       break;
3758     case tok::pipe:
3759       OOK = OO_Pipe;
3760       break;
3761     case tok::caret:
3762       OOK = OO_Caret;
3763       break;
3764     case tok::ampamp:
3765       OOK = OO_AmpAmp;
3766       break;
3767     case tok::pipepipe:
3768       OOK = OO_PipePipe;
3769       break;
3770     default:
3771       break;
3772     }
3773     if (OOK != OO_None) {
3774       SourceLocation OpLoc = P.ConsumeToken();
3775       SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
3776       ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
3777       return false;
3778     }
3779   }
3780   return P.ParseUnqualifiedId(
3781       ReductionIdScopeSpec, /*ObjectType=*/nullptr,
3782       /*ObjectHadErrors=*/false, /*EnteringContext*/ false,
3783       /*AllowDestructorName*/ false,
3784       /*AllowConstructorName*/ false,
3785       /*AllowDeductionGuide*/ false, nullptr, ReductionId);
3786 }
3787 
3788 /// Checks if the token is a valid map-type-modifier.
3789 /// FIXME: It will return an OpenMPMapClauseKind if that's what it parses.
3790 static OpenMPMapModifierKind isMapModifier(Parser &P) {
3791   Token Tok = P.getCurToken();
3792   if (!Tok.is(tok::identifier))
3793     return OMPC_MAP_MODIFIER_unknown;
3794 
3795   Preprocessor &PP = P.getPreprocessor();
3796   OpenMPMapModifierKind TypeModifier =
3797       static_cast<OpenMPMapModifierKind>(getOpenMPSimpleClauseType(
3798           OMPC_map, PP.getSpelling(Tok), P.getLangOpts()));
3799   return TypeModifier;
3800 }
3801 
3802 /// Parse the mapper modifier in map, to, and from clauses.
3803 bool Parser::parseMapperModifier(OpenMPVarListDataTy &Data) {
3804   // Parse '('.
3805   BalancedDelimiterTracker T(*this, tok::l_paren, tok::colon);
3806   if (T.expectAndConsume(diag::err_expected_lparen_after, "mapper")) {
3807     SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3808               StopBeforeMatch);
3809     return true;
3810   }
3811   // Parse mapper-identifier
3812   if (getLangOpts().CPlusPlus)
3813     ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
3814                                    /*ObjectType=*/nullptr,
3815                                    /*ObjectHadErrors=*/false,
3816                                    /*EnteringContext=*/false);
3817   if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
3818     Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
3819     SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3820               StopBeforeMatch);
3821     return true;
3822   }
3823   auto &DeclNames = Actions.getASTContext().DeclarationNames;
3824   Data.ReductionOrMapperId = DeclarationNameInfo(
3825       DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
3826   ConsumeToken();
3827   // Parse ')'.
3828   return T.consumeClose();
3829 }
3830 
3831 /// Parse map-type-modifiers in map clause.
3832 /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
3833 /// where, map-type-modifier ::= always | close | mapper(mapper-identifier) |
3834 /// present
3835 bool Parser::parseMapTypeModifiers(OpenMPVarListDataTy &Data) {
3836   while (getCurToken().isNot(tok::colon)) {
3837     OpenMPMapModifierKind TypeModifier = isMapModifier(*this);
3838     if (TypeModifier == OMPC_MAP_MODIFIER_always ||
3839         TypeModifier == OMPC_MAP_MODIFIER_close ||
3840         TypeModifier == OMPC_MAP_MODIFIER_present ||
3841         TypeModifier == OMPC_MAP_MODIFIER_ompx_hold) {
3842       Data.MapTypeModifiers.push_back(TypeModifier);
3843       Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
3844       ConsumeToken();
3845     } else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
3846       Data.MapTypeModifiers.push_back(TypeModifier);
3847       Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
3848       ConsumeToken();
3849       if (parseMapperModifier(Data))
3850         return true;
3851     } else {
3852       // For the case of unknown map-type-modifier or a map-type.
3853       // Map-type is followed by a colon; the function returns when it
3854       // encounters a token followed by a colon.
3855       if (Tok.is(tok::comma)) {
3856         Diag(Tok, diag::err_omp_map_type_modifier_missing);
3857         ConsumeToken();
3858         continue;
3859       }
3860       // Potential map-type token as it is followed by a colon.
3861       if (PP.LookAhead(0).is(tok::colon))
3862         return false;
3863       Diag(Tok, diag::err_omp_unknown_map_type_modifier)
3864           << (getLangOpts().OpenMP >= 51 ? 1 : 0)
3865           << getLangOpts().OpenMPExtensions;
3866       ConsumeToken();
3867     }
3868     if (getCurToken().is(tok::comma))
3869       ConsumeToken();
3870   }
3871   return false;
3872 }
3873 
3874 /// Checks if the token is a valid map-type.
3875 /// FIXME: It will return an OpenMPMapModifierKind if that's what it parses.
3876 static OpenMPMapClauseKind isMapType(Parser &P) {
3877   Token Tok = P.getCurToken();
3878   // The map-type token can be either an identifier or the C++ delete keyword.
3879   if (!Tok.isOneOf(tok::identifier, tok::kw_delete))
3880     return OMPC_MAP_unknown;
3881   Preprocessor &PP = P.getPreprocessor();
3882   OpenMPMapClauseKind MapType =
3883       static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType(
3884           OMPC_map, PP.getSpelling(Tok), P.getLangOpts()));
3885   return MapType;
3886 }
3887 
3888 /// Parse map-type in map clause.
3889 /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
3890 /// where, map-type ::= to | from | tofrom | alloc | release | delete
3891 static void parseMapType(Parser &P, Parser::OpenMPVarListDataTy &Data) {
3892   Token Tok = P.getCurToken();
3893   if (Tok.is(tok::colon)) {
3894     P.Diag(Tok, diag::err_omp_map_type_missing);
3895     return;
3896   }
3897   Data.ExtraModifier = isMapType(P);
3898   if (Data.ExtraModifier == OMPC_MAP_unknown)
3899     P.Diag(Tok, diag::err_omp_unknown_map_type);
3900   P.ConsumeToken();
3901 }
3902 
3903 /// Parses simple expression in parens for single-expression clauses of OpenMP
3904 /// constructs.
3905 ExprResult Parser::ParseOpenMPIteratorsExpr() {
3906   assert(Tok.is(tok::identifier) && PP.getSpelling(Tok) == "iterator" &&
3907          "Expected 'iterator' token.");
3908   SourceLocation IteratorKwLoc = ConsumeToken();
3909 
3910   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3911   if (T.expectAndConsume(diag::err_expected_lparen_after, "iterator"))
3912     return ExprError();
3913 
3914   SourceLocation LLoc = T.getOpenLocation();
3915   SmallVector<Sema::OMPIteratorData, 4> Data;
3916   while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
3917     // Check if the type parsing is required.
3918     ParsedType IteratorType;
3919     if (Tok.isNot(tok::identifier) || NextToken().isNot(tok::equal)) {
3920       // identifier '=' is not found - parse type.
3921       TypeResult TR = ParseTypeName();
3922       if (TR.isInvalid()) {
3923         T.skipToEnd();
3924         return ExprError();
3925       }
3926       IteratorType = TR.get();
3927     }
3928 
3929     // Parse identifier.
3930     IdentifierInfo *II = nullptr;
3931     SourceLocation IdLoc;
3932     if (Tok.is(tok::identifier)) {
3933       II = Tok.getIdentifierInfo();
3934       IdLoc = ConsumeToken();
3935     } else {
3936       Diag(Tok, diag::err_expected_unqualified_id) << 0;
3937     }
3938 
3939     // Parse '='.
3940     SourceLocation AssignLoc;
3941     if (Tok.is(tok::equal))
3942       AssignLoc = ConsumeToken();
3943     else
3944       Diag(Tok, diag::err_omp_expected_equal_in_iterator);
3945 
3946     // Parse range-specification - <begin> ':' <end> [ ':' <step> ]
3947     ColonProtectionRAIIObject ColonRAII(*this);
3948     // Parse <begin>
3949     SourceLocation Loc = Tok.getLocation();
3950     ExprResult LHS = ParseCastExpression(AnyCastExpr);
3951     ExprResult Begin = Actions.CorrectDelayedTyposInExpr(
3952         ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3953     Begin = Actions.ActOnFinishFullExpr(Begin.get(), Loc,
3954                                         /*DiscardedValue=*/false);
3955     // Parse ':'.
3956     SourceLocation ColonLoc;
3957     if (Tok.is(tok::colon))
3958       ColonLoc = ConsumeToken();
3959 
3960     // Parse <end>
3961     Loc = Tok.getLocation();
3962     LHS = ParseCastExpression(AnyCastExpr);
3963     ExprResult End = Actions.CorrectDelayedTyposInExpr(
3964         ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3965     End = Actions.ActOnFinishFullExpr(End.get(), Loc,
3966                                       /*DiscardedValue=*/false);
3967 
3968     SourceLocation SecColonLoc;
3969     ExprResult Step;
3970     // Parse optional step.
3971     if (Tok.is(tok::colon)) {
3972       // Parse ':'
3973       SecColonLoc = ConsumeToken();
3974       // Parse <step>
3975       Loc = Tok.getLocation();
3976       LHS = ParseCastExpression(AnyCastExpr);
3977       Step = Actions.CorrectDelayedTyposInExpr(
3978           ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3979       Step = Actions.ActOnFinishFullExpr(Step.get(), Loc,
3980                                          /*DiscardedValue=*/false);
3981     }
3982 
3983     // Parse ',' or ')'
3984     if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
3985       Diag(Tok, diag::err_omp_expected_punc_after_iterator);
3986     if (Tok.is(tok::comma))
3987       ConsumeToken();
3988 
3989     Sema::OMPIteratorData &D = Data.emplace_back();
3990     D.DeclIdent = II;
3991     D.DeclIdentLoc = IdLoc;
3992     D.Type = IteratorType;
3993     D.AssignLoc = AssignLoc;
3994     D.ColonLoc = ColonLoc;
3995     D.SecColonLoc = SecColonLoc;
3996     D.Range.Begin = Begin.get();
3997     D.Range.End = End.get();
3998     D.Range.Step = Step.get();
3999   }
4000 
4001   // Parse ')'.
4002   SourceLocation RLoc = Tok.getLocation();
4003   if (!T.consumeClose())
4004     RLoc = T.getCloseLocation();
4005 
4006   return Actions.ActOnOMPIteratorExpr(getCurScope(), IteratorKwLoc, LLoc, RLoc,
4007                                       Data);
4008 }
4009 
4010 /// Parses clauses with list.
4011 bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
4012                                 OpenMPClauseKind Kind,
4013                                 SmallVectorImpl<Expr *> &Vars,
4014                                 OpenMPVarListDataTy &Data) {
4015   UnqualifiedId UnqualifiedReductionId;
4016   bool InvalidReductionId = false;
4017   bool IsInvalidMapperModifier = false;
4018 
4019   // Parse '('.
4020   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
4021   if (T.expectAndConsume(diag::err_expected_lparen_after,
4022                          getOpenMPClauseName(Kind).data()))
4023     return true;
4024 
4025   bool HasIterator = false;
4026   bool NeedRParenForLinear = false;
4027   BalancedDelimiterTracker LinearT(*this, tok::l_paren,
4028                                    tok::annot_pragma_openmp_end);
4029   // Handle reduction-identifier for reduction clause.
4030   if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
4031       Kind == OMPC_in_reduction) {
4032     Data.ExtraModifier = OMPC_REDUCTION_unknown;
4033     if (Kind == OMPC_reduction && getLangOpts().OpenMP >= 50 &&
4034         (Tok.is(tok::identifier) || Tok.is(tok::kw_default)) &&
4035         NextToken().is(tok::comma)) {
4036       // Parse optional reduction modifier.
4037       Data.ExtraModifier =
4038           getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok), getLangOpts());
4039       Data.ExtraModifierLoc = Tok.getLocation();
4040       ConsumeToken();
4041       assert(Tok.is(tok::comma) && "Expected comma.");
4042       (void)ConsumeToken();
4043     }
4044     ColonProtectionRAIIObject ColonRAII(*this);
4045     if (getLangOpts().CPlusPlus)
4046       ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
4047                                      /*ObjectType=*/nullptr,
4048                                      /*ObjectHadErrors=*/false,
4049                                      /*EnteringContext=*/false);
4050     InvalidReductionId = ParseReductionId(
4051         *this, Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
4052     if (InvalidReductionId) {
4053       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4054                 StopBeforeMatch);
4055     }
4056     if (Tok.is(tok::colon))
4057       Data.ColonLoc = ConsumeToken();
4058     else
4059       Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
4060     if (!InvalidReductionId)
4061       Data.ReductionOrMapperId =
4062           Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
4063   } else if (Kind == OMPC_depend) {
4064     if (getLangOpts().OpenMP >= 50) {
4065       if (Tok.is(tok::identifier) && PP.getSpelling(Tok) == "iterator") {
4066         // Handle optional dependence modifier.
4067         // iterator(iterators-definition)
4068         // where iterators-definition is iterator-specifier [,
4069         // iterators-definition ]
4070         // where iterator-specifier is [ iterator-type ] identifier =
4071         // range-specification
4072         HasIterator = true;
4073         EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope);
4074         ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4075         Data.DepModOrTailExpr = IteratorRes.get();
4076         // Parse ','
4077         ExpectAndConsume(tok::comma);
4078       }
4079     }
4080     // Handle dependency type for depend clause.
4081     ColonProtectionRAIIObject ColonRAII(*this);
4082     Data.ExtraModifier = getOpenMPSimpleClauseType(
4083         Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : "",
4084         getLangOpts());
4085     Data.ExtraModifierLoc = Tok.getLocation();
4086     if (Data.ExtraModifier == OMPC_DEPEND_unknown) {
4087       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4088                 StopBeforeMatch);
4089     } else {
4090       ConsumeToken();
4091       // Special processing for depend(source) clause.
4092       if (DKind == OMPD_ordered && Data.ExtraModifier == OMPC_DEPEND_source) {
4093         // Parse ')'.
4094         T.consumeClose();
4095         return false;
4096       }
4097     }
4098     if (Tok.is(tok::colon)) {
4099       Data.ColonLoc = ConsumeToken();
4100     } else {
4101       Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
4102                                       : diag::warn_pragma_expected_colon)
4103           << "dependency type";
4104     }
4105   } else if (Kind == OMPC_linear) {
4106     // Try to parse modifier if any.
4107     Data.ExtraModifier = OMPC_LINEAR_val;
4108     if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
4109       Data.ExtraModifier =
4110           getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok), getLangOpts());
4111       Data.ExtraModifierLoc = ConsumeToken();
4112       LinearT.consumeOpen();
4113       NeedRParenForLinear = true;
4114     }
4115   } else if (Kind == OMPC_lastprivate) {
4116     // Try to parse modifier if any.
4117     Data.ExtraModifier = OMPC_LASTPRIVATE_unknown;
4118     // Conditional modifier allowed only in OpenMP 5.0 and not supported in
4119     // distribute and taskloop based directives.
4120     if ((getLangOpts().OpenMP >= 50 && !isOpenMPDistributeDirective(DKind) &&
4121          !isOpenMPTaskLoopDirective(DKind)) &&
4122         Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::colon)) {
4123       Data.ExtraModifier =
4124           getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok), getLangOpts());
4125       Data.ExtraModifierLoc = Tok.getLocation();
4126       ConsumeToken();
4127       assert(Tok.is(tok::colon) && "Expected colon.");
4128       Data.ColonLoc = ConsumeToken();
4129     }
4130   } else if (Kind == OMPC_map) {
4131     // Handle map type for map clause.
4132     ColonProtectionRAIIObject ColonRAII(*this);
4133 
4134     // The first identifier may be a list item, a map-type or a
4135     // map-type-modifier. The map-type can also be delete which has the same
4136     // spelling of the C++ delete keyword.
4137     Data.ExtraModifier = OMPC_MAP_unknown;
4138     Data.ExtraModifierLoc = Tok.getLocation();
4139 
4140     // Check for presence of a colon in the map clause.
4141     TentativeParsingAction TPA(*this);
4142     bool ColonPresent = false;
4143     if (SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4144                   StopBeforeMatch)) {
4145       if (Tok.is(tok::colon))
4146         ColonPresent = true;
4147     }
4148     TPA.Revert();
4149     // Only parse map-type-modifier[s] and map-type if a colon is present in
4150     // the map clause.
4151     if (ColonPresent) {
4152       IsInvalidMapperModifier = parseMapTypeModifiers(Data);
4153       if (!IsInvalidMapperModifier)
4154         parseMapType(*this, Data);
4155       else
4156         SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch);
4157     }
4158     if (Data.ExtraModifier == OMPC_MAP_unknown) {
4159       Data.ExtraModifier = OMPC_MAP_tofrom;
4160       Data.IsMapTypeImplicit = true;
4161     }
4162 
4163     if (Tok.is(tok::colon))
4164       Data.ColonLoc = ConsumeToken();
4165   } else if (Kind == OMPC_to || Kind == OMPC_from) {
4166     while (Tok.is(tok::identifier)) {
4167       auto Modifier = static_cast<OpenMPMotionModifierKind>(
4168           getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok), getLangOpts()));
4169       if (Modifier == OMPC_MOTION_MODIFIER_unknown)
4170         break;
4171       Data.MotionModifiers.push_back(Modifier);
4172       Data.MotionModifiersLoc.push_back(Tok.getLocation());
4173       ConsumeToken();
4174       if (Modifier == OMPC_MOTION_MODIFIER_mapper) {
4175         IsInvalidMapperModifier = parseMapperModifier(Data);
4176         if (IsInvalidMapperModifier)
4177           break;
4178       }
4179       // OpenMP < 5.1 doesn't permit a ',' or additional modifiers.
4180       if (getLangOpts().OpenMP < 51)
4181         break;
4182       // OpenMP 5.1 accepts an optional ',' even if the next character is ':'.
4183       // TODO: Is that intentional?
4184       if (Tok.is(tok::comma))
4185         ConsumeToken();
4186     }
4187     if (!Data.MotionModifiers.empty() && Tok.isNot(tok::colon)) {
4188       if (!IsInvalidMapperModifier) {
4189         if (getLangOpts().OpenMP < 51)
4190           Diag(Tok, diag::warn_pragma_expected_colon) << ")";
4191         else
4192           Diag(Tok, diag::warn_pragma_expected_colon) << "motion modifier";
4193       }
4194       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4195                 StopBeforeMatch);
4196     }
4197     // OpenMP 5.1 permits a ':' even without a preceding modifier.  TODO: Is
4198     // that intentional?
4199     if ((!Data.MotionModifiers.empty() || getLangOpts().OpenMP >= 51) &&
4200         Tok.is(tok::colon))
4201       Data.ColonLoc = ConsumeToken();
4202   } else if (Kind == OMPC_allocate ||
4203              (Kind == OMPC_affinity && Tok.is(tok::identifier) &&
4204               PP.getSpelling(Tok) == "iterator")) {
4205     // Handle optional allocator expression followed by colon delimiter.
4206     ColonProtectionRAIIObject ColonRAII(*this);
4207     TentativeParsingAction TPA(*this);
4208     // OpenMP 5.0, 2.10.1, task Construct.
4209     // where aff-modifier is one of the following:
4210     // iterator(iterators-definition)
4211     ExprResult Tail;
4212     if (Kind == OMPC_allocate) {
4213       Tail = ParseAssignmentExpression();
4214     } else {
4215       HasIterator = true;
4216       EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope);
4217       Tail = ParseOpenMPIteratorsExpr();
4218     }
4219     Tail = Actions.CorrectDelayedTyposInExpr(Tail);
4220     Tail = Actions.ActOnFinishFullExpr(Tail.get(), T.getOpenLocation(),
4221                                        /*DiscardedValue=*/false);
4222     if (Tail.isUsable()) {
4223       if (Tok.is(tok::colon)) {
4224         Data.DepModOrTailExpr = Tail.get();
4225         Data.ColonLoc = ConsumeToken();
4226         TPA.Commit();
4227       } else {
4228         // Colon not found, parse only list of variables.
4229         TPA.Revert();
4230       }
4231     } else {
4232       // Parsing was unsuccessfull, revert and skip to the end of clause or
4233       // directive.
4234       TPA.Revert();
4235       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4236                 StopBeforeMatch);
4237     }
4238   } else if (Kind == OMPC_adjust_args) {
4239     // Handle adjust-op for adjust_args clause.
4240     ColonProtectionRAIIObject ColonRAII(*this);
4241     Data.ExtraModifier = getOpenMPSimpleClauseType(
4242         Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : "",
4243         getLangOpts());
4244     Data.ExtraModifierLoc = Tok.getLocation();
4245     if (Data.ExtraModifier == OMPC_ADJUST_ARGS_unknown) {
4246       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4247                 StopBeforeMatch);
4248     } else {
4249       ConsumeToken();
4250       if (Tok.is(tok::colon))
4251         Data.ColonLoc = Tok.getLocation();
4252       ExpectAndConsume(tok::colon, diag::warn_pragma_expected_colon,
4253                        "adjust-op");
4254     }
4255   }
4256 
4257   bool IsComma =
4258       (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
4259        Kind != OMPC_in_reduction && Kind != OMPC_depend && Kind != OMPC_map) ||
4260       (Kind == OMPC_reduction && !InvalidReductionId) ||
4261       (Kind == OMPC_map && Data.ExtraModifier != OMPC_MAP_unknown) ||
4262       (Kind == OMPC_depend && Data.ExtraModifier != OMPC_DEPEND_unknown) ||
4263       (Kind == OMPC_adjust_args &&
4264        Data.ExtraModifier != OMPC_ADJUST_ARGS_unknown);
4265   const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
4266   while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
4267                      Tok.isNot(tok::annot_pragma_openmp_end))) {
4268     ParseScope OMPListScope(this, Scope::OpenMPDirectiveScope);
4269     ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
4270     // Parse variable
4271     ExprResult VarExpr =
4272         Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
4273     if (VarExpr.isUsable()) {
4274       Vars.push_back(VarExpr.get());
4275     } else {
4276       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4277                 StopBeforeMatch);
4278     }
4279     // Skip ',' if any
4280     IsComma = Tok.is(tok::comma);
4281     if (IsComma)
4282       ConsumeToken();
4283     else if (Tok.isNot(tok::r_paren) &&
4284              Tok.isNot(tok::annot_pragma_openmp_end) &&
4285              (!MayHaveTail || Tok.isNot(tok::colon)))
4286       Diag(Tok, diag::err_omp_expected_punc)
4287           << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
4288                                    : getOpenMPClauseName(Kind))
4289           << (Kind == OMPC_flush);
4290   }
4291 
4292   // Parse ')' for linear clause with modifier.
4293   if (NeedRParenForLinear)
4294     LinearT.consumeClose();
4295 
4296   // Parse ':' linear-step (or ':' alignment).
4297   const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
4298   if (MustHaveTail) {
4299     Data.ColonLoc = Tok.getLocation();
4300     SourceLocation ELoc = ConsumeToken();
4301     ExprResult Tail = ParseAssignmentExpression();
4302     Tail =
4303         Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false);
4304     if (Tail.isUsable())
4305       Data.DepModOrTailExpr = Tail.get();
4306     else
4307       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4308                 StopBeforeMatch);
4309   }
4310 
4311   // Parse ')'.
4312   Data.RLoc = Tok.getLocation();
4313   if (!T.consumeClose())
4314     Data.RLoc = T.getCloseLocation();
4315   // Exit from scope when the iterator is used in depend clause.
4316   if (HasIterator)
4317     ExitScope();
4318   return (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
4319          (MustHaveTail && !Data.DepModOrTailExpr) || InvalidReductionId ||
4320          IsInvalidMapperModifier;
4321 }
4322 
4323 /// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
4324 /// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction',
4325 /// 'in_reduction', 'nontemporal', 'exclusive' or 'inclusive'.
4326 ///
4327 ///    private-clause:
4328 ///       'private' '(' list ')'
4329 ///    firstprivate-clause:
4330 ///       'firstprivate' '(' list ')'
4331 ///    lastprivate-clause:
4332 ///       'lastprivate' '(' list ')'
4333 ///    shared-clause:
4334 ///       'shared' '(' list ')'
4335 ///    linear-clause:
4336 ///       'linear' '(' linear-list [ ':' linear-step ] ')'
4337 ///    aligned-clause:
4338 ///       'aligned' '(' list [ ':' alignment ] ')'
4339 ///    reduction-clause:
4340 ///       'reduction' '(' [ modifier ',' ] reduction-identifier ':' list ')'
4341 ///    task_reduction-clause:
4342 ///       'task_reduction' '(' reduction-identifier ':' list ')'
4343 ///    in_reduction-clause:
4344 ///       'in_reduction' '(' reduction-identifier ':' list ')'
4345 ///    copyprivate-clause:
4346 ///       'copyprivate' '(' list ')'
4347 ///    flush-clause:
4348 ///       'flush' '(' list ')'
4349 ///    depend-clause:
4350 ///       'depend' '(' in | out | inout : list | source ')'
4351 ///    map-clause:
4352 ///       'map' '(' [ [ always [,] ] [ close [,] ]
4353 ///          [ mapper '(' mapper-identifier ')' [,] ]
4354 ///          to | from | tofrom | alloc | release | delete ':' ] list ')';
4355 ///    to-clause:
4356 ///       'to' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
4357 ///    from-clause:
4358 ///       'from' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
4359 ///    use_device_ptr-clause:
4360 ///       'use_device_ptr' '(' list ')'
4361 ///    use_device_addr-clause:
4362 ///       'use_device_addr' '(' list ')'
4363 ///    is_device_ptr-clause:
4364 ///       'is_device_ptr' '(' list ')'
4365 ///    allocate-clause:
4366 ///       'allocate' '(' [ allocator ':' ] list ')'
4367 ///    nontemporal-clause:
4368 ///       'nontemporal' '(' list ')'
4369 ///    inclusive-clause:
4370 ///       'inclusive' '(' list ')'
4371 ///    exclusive-clause:
4372 ///       'exclusive' '(' list ')'
4373 ///
4374 /// For 'linear' clause linear-list may have the following forms:
4375 ///  list
4376 ///  modifier(list)
4377 /// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
4378 OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
4379                                             OpenMPClauseKind Kind,
4380                                             bool ParseOnly) {
4381   SourceLocation Loc = Tok.getLocation();
4382   SourceLocation LOpen = ConsumeToken();
4383   SmallVector<Expr *, 4> Vars;
4384   OpenMPVarListDataTy Data;
4385 
4386   if (ParseOpenMPVarList(DKind, Kind, Vars, Data))
4387     return nullptr;
4388 
4389   if (ParseOnly)
4390     return nullptr;
4391   OMPVarListLocTy Locs(Loc, LOpen, Data.RLoc);
4392   return Actions.ActOnOpenMPVarListClause(
4393       Kind, Vars, Data.DepModOrTailExpr, Locs, Data.ColonLoc,
4394       Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId,
4395       Data.ExtraModifier, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
4396       Data.IsMapTypeImplicit, Data.ExtraModifierLoc, Data.MotionModifiers,
4397       Data.MotionModifiersLoc);
4398 }
4399