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