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 RequiresToOrLinkOrIndirectClause = false;
1818   bool HasToOrLinkOrIndirectClause = 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       RequiresToOrLinkOrIndirectClause = 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 IsIndirectClause = getLangOpts().OpenMP >= 51 &&
1832                               getOpenMPClauseKind(ClauseName) == OMPC_indirect;
1833       if (DTCI.Indirect.hasValue() && IsIndirectClause) {
1834         Diag(Tok, diag::err_omp_more_one_clause)
1835             << getOpenMPDirectiveName(OMPD_declare_target)
1836             << getOpenMPClauseName(OMPC_indirect) << 0;
1837         break;
1838       }
1839       bool IsToOrLinkClause =
1840           OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT);
1841       assert((!IsDeviceTypeClause || !IsToOrLinkClause) && "Cannot be both!");
1842 
1843       if (!IsDeviceTypeClause && !IsIndirectClause &&
1844           DTCI.Kind == OMPD_begin_declare_target) {
1845         Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
1846             << ClauseName << (getLangOpts().OpenMP >= 51 ? 3 : 0);
1847         break;
1848       }
1849       if (!IsDeviceTypeClause && !IsToOrLinkClause && !IsIndirectClause) {
1850         Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
1851             << ClauseName
1852             << (getLangOpts().OpenMP >= 51   ? 4
1853                 : getLangOpts().OpenMP >= 50 ? 2
1854                                              : 1);
1855         break;
1856       }
1857 
1858       if (IsToOrLinkClause || IsIndirectClause)
1859         HasToOrLinkOrIndirectClause = true;
1860 
1861       if (IsIndirectClause) {
1862         if (!ParseOpenMPIndirectClause(DTCI, /*ParseOnly*/ false))
1863           break;
1864         continue;
1865       }
1866       // Parse 'device_type' clause and go to next clause if any.
1867       if (IsDeviceTypeClause) {
1868         Optional<SimpleClauseData> DevTypeData =
1869             parseOpenMPSimpleClause(*this, OMPC_device_type);
1870         if (DevTypeData.hasValue()) {
1871           if (DeviceTypeLoc.isValid()) {
1872             // We already saw another device_type clause, diagnose it.
1873             Diag(DevTypeData.getValue().Loc,
1874                  diag::warn_omp_more_one_device_type_clause);
1875             break;
1876           }
1877           switch (static_cast<OpenMPDeviceType>(DevTypeData.getValue().Type)) {
1878           case OMPC_DEVICE_TYPE_any:
1879             DTCI.DT = OMPDeclareTargetDeclAttr::DT_Any;
1880             break;
1881           case OMPC_DEVICE_TYPE_host:
1882             DTCI.DT = OMPDeclareTargetDeclAttr::DT_Host;
1883             break;
1884           case OMPC_DEVICE_TYPE_nohost:
1885             DTCI.DT = OMPDeclareTargetDeclAttr::DT_NoHost;
1886             break;
1887           case OMPC_DEVICE_TYPE_unknown:
1888             llvm_unreachable("Unexpected device_type");
1889           }
1890           DeviceTypeLoc = DevTypeData.getValue().Loc;
1891         }
1892         continue;
1893       }
1894       ConsumeToken();
1895     }
1896 
1897     if (DTCI.Kind == OMPD_declare_target || HasIdentifier) {
1898       auto &&Callback = [this, MT, &DTCI](CXXScopeSpec &SS,
1899                                           DeclarationNameInfo NameInfo) {
1900         NamedDecl *ND =
1901             Actions.lookupOpenMPDeclareTargetName(getCurScope(), SS, NameInfo);
1902         if (!ND)
1903           return;
1904         Sema::DeclareTargetContextInfo::MapInfo MI{MT, NameInfo.getLoc()};
1905         bool FirstMapping = DTCI.ExplicitlyMapped.try_emplace(ND, MI).second;
1906         if (!FirstMapping)
1907           Diag(NameInfo.getLoc(), diag::err_omp_declare_target_multiple)
1908               << NameInfo.getName();
1909       };
1910       if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
1911                                    /*AllowScopeSpecifier=*/true))
1912         break;
1913     }
1914 
1915     if (Tok.is(tok::l_paren)) {
1916       Diag(Tok,
1917            diag::err_omp_begin_declare_target_unexpected_implicit_to_clause);
1918       break;
1919     }
1920     if (!HasIdentifier && Tok.isNot(tok::annot_pragma_openmp_end)) {
1921       Diag(Tok,
1922            diag::err_omp_declare_target_unexpected_clause_after_implicit_to);
1923       break;
1924     }
1925 
1926     // Consume optional ','.
1927     if (Tok.is(tok::comma))
1928       ConsumeToken();
1929   }
1930 
1931   if (DTCI.Indirect.hasValue() && DTCI.DT != OMPDeclareTargetDeclAttr::DT_Any)
1932     Diag(DeviceTypeLoc, diag::err_omp_declare_target_indirect_device_type);
1933 
1934   // For declare target require at least 'to' or 'link' to be present.
1935   if (DTCI.Kind == OMPD_declare_target && RequiresToOrLinkOrIndirectClause &&
1936       !HasToOrLinkOrIndirectClause)
1937     Diag(DTCI.Loc, diag::err_omp_declare_target_missing_to_or_link_clause)
1938         << (getLangOpts().OpenMP >= 51 ? 1 : 0);
1939 
1940   SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1941 }
1942 
1943 void Parser::skipUntilPragmaOpenMPEnd(OpenMPDirectiveKind DKind) {
1944   // The last seen token is annot_pragma_openmp_end - need to check for
1945   // extra tokens.
1946   if (Tok.is(tok::annot_pragma_openmp_end))
1947     return;
1948 
1949   Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1950       << getOpenMPDirectiveName(DKind);
1951   while (Tok.isNot(tok::annot_pragma_openmp_end))
1952     ConsumeAnyToken();
1953 }
1954 
1955 void Parser::parseOMPEndDirective(OpenMPDirectiveKind BeginKind,
1956                                   OpenMPDirectiveKind ExpectedKind,
1957                                   OpenMPDirectiveKind FoundKind,
1958                                   SourceLocation BeginLoc,
1959                                   SourceLocation FoundLoc,
1960                                   bool SkipUntilOpenMPEnd) {
1961   int DiagSelection = ExpectedKind == OMPD_end_declare_target ? 0 : 1;
1962 
1963   if (FoundKind == ExpectedKind) {
1964     ConsumeAnyToken();
1965     skipUntilPragmaOpenMPEnd(ExpectedKind);
1966     return;
1967   }
1968 
1969   Diag(FoundLoc, diag::err_expected_end_declare_target_or_variant)
1970       << DiagSelection;
1971   Diag(BeginLoc, diag::note_matching)
1972       << ("'#pragma omp " + getOpenMPDirectiveName(BeginKind) + "'").str();
1973   if (SkipUntilOpenMPEnd)
1974     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1975 }
1976 
1977 void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind BeginDKind,
1978                                                OpenMPDirectiveKind EndDKind,
1979                                                SourceLocation DKLoc) {
1980   parseOMPEndDirective(BeginDKind, OMPD_end_declare_target, EndDKind, DKLoc,
1981                        Tok.getLocation(),
1982                        /* SkipUntilOpenMPEnd */ false);
1983   // Skip the last annot_pragma_openmp_end.
1984   if (Tok.is(tok::annot_pragma_openmp_end))
1985     ConsumeAnnotationToken();
1986 }
1987 
1988 /// Parsing of declarative OpenMP directives.
1989 ///
1990 ///       threadprivate-directive:
1991 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
1992 ///         annot_pragma_openmp_end
1993 ///
1994 ///       allocate-directive:
1995 ///         annot_pragma_openmp 'allocate' simple-variable-list [<clause>]
1996 ///         annot_pragma_openmp_end
1997 ///
1998 ///       declare-reduction-directive:
1999 ///        annot_pragma_openmp 'declare' 'reduction' [...]
2000 ///        annot_pragma_openmp_end
2001 ///
2002 ///       declare-mapper-directive:
2003 ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
2004 ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
2005 ///         annot_pragma_openmp_end
2006 ///
2007 ///       declare-simd-directive:
2008 ///         annot_pragma_openmp 'declare simd' {<clause> [,]}
2009 ///         annot_pragma_openmp_end
2010 ///         <function declaration/definition>
2011 ///
2012 ///       requires directive:
2013 ///         annot_pragma_openmp 'requires' <clause> [[[,] <clause>] ... ]
2014 ///         annot_pragma_openmp_end
2015 ///
2016 ///       assumes directive:
2017 ///         annot_pragma_openmp 'assumes' <clause> [[[,] <clause>] ... ]
2018 ///         annot_pragma_openmp_end
2019 ///       or
2020 ///         annot_pragma_openmp 'begin assumes' <clause> [[[,] <clause>] ... ]
2021 ///         annot_pragma_openmp 'end assumes'
2022 ///         annot_pragma_openmp_end
2023 ///
2024 Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
2025     AccessSpecifier &AS, ParsedAttributesWithRange &Attrs, bool Delayed,
2026     DeclSpec::TST TagType, Decl *Tag) {
2027   assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
2028          "Not an OpenMP directive!");
2029   ParsingOpenMPDirectiveRAII DirScope(*this);
2030   ParenBraceBracketBalancer BalancerRAIIObj(*this);
2031 
2032   SourceLocation Loc;
2033   OpenMPDirectiveKind DKind;
2034   if (Delayed) {
2035     TentativeParsingAction TPA(*this);
2036     Loc = ConsumeAnnotationToken();
2037     DKind = parseOpenMPDirectiveKind(*this);
2038     if (DKind == OMPD_declare_reduction || DKind == OMPD_declare_mapper) {
2039       // Need to delay parsing until completion of the parent class.
2040       TPA.Revert();
2041       CachedTokens Toks;
2042       unsigned Cnt = 1;
2043       Toks.push_back(Tok);
2044       while (Cnt && Tok.isNot(tok::eof)) {
2045         (void)ConsumeAnyToken();
2046         if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp))
2047           ++Cnt;
2048         else if (Tok.is(tok::annot_pragma_openmp_end))
2049           --Cnt;
2050         Toks.push_back(Tok);
2051       }
2052       // Skip last annot_pragma_openmp_end.
2053       if (Cnt == 0)
2054         (void)ConsumeAnyToken();
2055       auto *LP = new LateParsedPragma(this, AS);
2056       LP->takeToks(Toks);
2057       getCurrentClass().LateParsedDeclarations.push_back(LP);
2058       return nullptr;
2059     }
2060     TPA.Commit();
2061   } else {
2062     Loc = ConsumeAnnotationToken();
2063     DKind = parseOpenMPDirectiveKind(*this);
2064   }
2065 
2066   switch (DKind) {
2067   case OMPD_threadprivate: {
2068     ConsumeToken();
2069     DeclDirectiveListParserHelper Helper(this, DKind);
2070     if (!ParseOpenMPSimpleVarList(DKind, Helper,
2071                                   /*AllowScopeSpecifier=*/true)) {
2072       skipUntilPragmaOpenMPEnd(DKind);
2073       // Skip the last annot_pragma_openmp_end.
2074       ConsumeAnnotationToken();
2075       return Actions.ActOnOpenMPThreadprivateDirective(Loc,
2076                                                        Helper.getIdentifiers());
2077     }
2078     break;
2079   }
2080   case OMPD_allocate: {
2081     ConsumeToken();
2082     DeclDirectiveListParserHelper Helper(this, DKind);
2083     if (!ParseOpenMPSimpleVarList(DKind, Helper,
2084                                   /*AllowScopeSpecifier=*/true)) {
2085       SmallVector<OMPClause *, 1> Clauses;
2086       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2087         SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
2088                     llvm::omp::Clause_enumSize + 1>
2089             FirstClauses(llvm::omp::Clause_enumSize + 1);
2090         while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2091           OpenMPClauseKind CKind =
2092               Tok.isAnnotation() ? OMPC_unknown
2093                                  : getOpenMPClauseKind(PP.getSpelling(Tok));
2094           Actions.StartOpenMPClause(CKind);
2095           OMPClause *Clause = ParseOpenMPClause(
2096               OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt());
2097           SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2098                     StopBeforeMatch);
2099           FirstClauses[unsigned(CKind)].setInt(true);
2100           if (Clause != nullptr)
2101             Clauses.push_back(Clause);
2102           if (Tok.is(tok::annot_pragma_openmp_end)) {
2103             Actions.EndOpenMPClause();
2104             break;
2105           }
2106           // Skip ',' if any.
2107           if (Tok.is(tok::comma))
2108             ConsumeToken();
2109           Actions.EndOpenMPClause();
2110         }
2111         skipUntilPragmaOpenMPEnd(DKind);
2112       }
2113       // Skip the last annot_pragma_openmp_end.
2114       ConsumeAnnotationToken();
2115       return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers(),
2116                                                   Clauses);
2117     }
2118     break;
2119   }
2120   case OMPD_requires: {
2121     SourceLocation StartLoc = ConsumeToken();
2122     SmallVector<OMPClause *, 5> Clauses;
2123     SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
2124                 llvm::omp::Clause_enumSize + 1>
2125         FirstClauses(llvm::omp::Clause_enumSize + 1);
2126     if (Tok.is(tok::annot_pragma_openmp_end)) {
2127       Diag(Tok, diag::err_omp_expected_clause)
2128           << getOpenMPDirectiveName(OMPD_requires);
2129       break;
2130     }
2131     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2132       OpenMPClauseKind CKind = Tok.isAnnotation()
2133                                    ? OMPC_unknown
2134                                    : getOpenMPClauseKind(PP.getSpelling(Tok));
2135       Actions.StartOpenMPClause(CKind);
2136       OMPClause *Clause = ParseOpenMPClause(
2137           OMPD_requires, CKind, !FirstClauses[unsigned(CKind)].getInt());
2138       SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2139                 StopBeforeMatch);
2140       FirstClauses[unsigned(CKind)].setInt(true);
2141       if (Clause != nullptr)
2142         Clauses.push_back(Clause);
2143       if (Tok.is(tok::annot_pragma_openmp_end)) {
2144         Actions.EndOpenMPClause();
2145         break;
2146       }
2147       // Skip ',' if any.
2148       if (Tok.is(tok::comma))
2149         ConsumeToken();
2150       Actions.EndOpenMPClause();
2151     }
2152     // Consume final annot_pragma_openmp_end
2153     if (Clauses.empty()) {
2154       Diag(Tok, diag::err_omp_expected_clause)
2155           << getOpenMPDirectiveName(OMPD_requires);
2156       ConsumeAnnotationToken();
2157       return nullptr;
2158     }
2159     ConsumeAnnotationToken();
2160     return Actions.ActOnOpenMPRequiresDirective(StartLoc, Clauses);
2161   }
2162   case OMPD_assumes:
2163   case OMPD_begin_assumes:
2164     ParseOpenMPAssumesDirective(DKind, ConsumeToken());
2165     break;
2166   case OMPD_end_assumes:
2167     ParseOpenMPEndAssumesDirective(ConsumeToken());
2168     break;
2169   case OMPD_declare_reduction:
2170     ConsumeToken();
2171     if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
2172       skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2173       // Skip the last annot_pragma_openmp_end.
2174       ConsumeAnnotationToken();
2175       return Res;
2176     }
2177     break;
2178   case OMPD_declare_mapper: {
2179     ConsumeToken();
2180     if (DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
2181       // Skip the last annot_pragma_openmp_end.
2182       ConsumeAnnotationToken();
2183       return Res;
2184     }
2185     break;
2186   }
2187   case OMPD_begin_declare_variant: {
2188     // The syntax is:
2189     // { #pragma omp begin declare variant clause }
2190     // <function-declaration-or-definition-sequence>
2191     // { #pragma omp end declare variant }
2192     //
2193     ConsumeToken();
2194     OMPTraitInfo *ParentTI = Actions.getOMPTraitInfoForSurroundingScope();
2195     ASTContext &ASTCtx = Actions.getASTContext();
2196     OMPTraitInfo &TI = ASTCtx.getNewOMPTraitInfo();
2197     if (parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI)) {
2198       while (!SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch))
2199         ;
2200       // Skip the last annot_pragma_openmp_end.
2201       (void)ConsumeAnnotationToken();
2202       break;
2203     }
2204 
2205     // Skip last tokens.
2206     skipUntilPragmaOpenMPEnd(OMPD_begin_declare_variant);
2207 
2208     ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false);
2209 
2210     VariantMatchInfo VMI;
2211     TI.getAsVariantMatchInfo(ASTCtx, VMI);
2212 
2213     std::function<void(StringRef)> DiagUnknownTrait =
2214         [this, Loc](StringRef ISATrait) {
2215           // TODO Track the selector locations in a way that is accessible here
2216           // to improve the diagnostic location.
2217           Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
2218         };
2219     TargetOMPContext OMPCtx(
2220         ASTCtx, std::move(DiagUnknownTrait),
2221         /* CurrentFunctionDecl */ nullptr,
2222         /* ConstructTraits */ ArrayRef<llvm::omp::TraitProperty>());
2223 
2224     if (isVariantApplicableInContext(VMI, OMPCtx, /* DeviceSetOnly */ true)) {
2225       Actions.ActOnOpenMPBeginDeclareVariant(Loc, TI);
2226       break;
2227     }
2228 
2229     // Elide all the code till the matching end declare variant was found.
2230     unsigned Nesting = 1;
2231     SourceLocation DKLoc;
2232     OpenMPDirectiveKind DK = OMPD_unknown;
2233     do {
2234       DKLoc = Tok.getLocation();
2235       DK = parseOpenMPDirectiveKind(*this);
2236       if (DK == OMPD_end_declare_variant)
2237         --Nesting;
2238       else if (DK == OMPD_begin_declare_variant)
2239         ++Nesting;
2240       if (!Nesting || isEofOrEom())
2241         break;
2242       ConsumeAnyToken();
2243     } while (true);
2244 
2245     parseOMPEndDirective(OMPD_begin_declare_variant, OMPD_end_declare_variant,
2246                          DK, Loc, DKLoc, /* SkipUntilOpenMPEnd */ true);
2247     if (isEofOrEom())
2248       return nullptr;
2249     break;
2250   }
2251   case OMPD_end_declare_variant: {
2252     if (Actions.isInOpenMPDeclareVariantScope())
2253       Actions.ActOnOpenMPEndDeclareVariant();
2254     else
2255       Diag(Loc, diag::err_expected_begin_declare_variant);
2256     ConsumeToken();
2257     break;
2258   }
2259   case OMPD_declare_variant:
2260   case OMPD_declare_simd: {
2261     // The syntax is:
2262     // { #pragma omp declare {simd|variant} }
2263     // <function-declaration-or-definition>
2264     //
2265     CachedTokens Toks;
2266     Toks.push_back(Tok);
2267     ConsumeToken();
2268     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2269       Toks.push_back(Tok);
2270       ConsumeAnyToken();
2271     }
2272     Toks.push_back(Tok);
2273     ConsumeAnyToken();
2274 
2275     DeclGroupPtrTy Ptr;
2276     if (Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp)) {
2277       Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, Delayed,
2278                                                        TagType, Tag);
2279     } else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
2280       // Here we expect to see some function declaration.
2281       if (AS == AS_none) {
2282         assert(TagType == DeclSpec::TST_unspecified);
2283         MaybeParseCXX11Attributes(Attrs);
2284         ParsingDeclSpec PDS(*this);
2285         Ptr = ParseExternalDeclaration(Attrs, &PDS);
2286       } else {
2287         Ptr =
2288             ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
2289       }
2290     }
2291     if (!Ptr) {
2292       Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
2293           << (DKind == OMPD_declare_simd ? 0 : 1);
2294       return DeclGroupPtrTy();
2295     }
2296     if (DKind == OMPD_declare_simd)
2297       return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
2298     assert(DKind == OMPD_declare_variant &&
2299            "Expected declare variant directive only");
2300     ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
2301     return Ptr;
2302   }
2303   case OMPD_begin_declare_target:
2304   case OMPD_declare_target: {
2305     SourceLocation DTLoc = ConsumeAnyToken();
2306     bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2307     Sema::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2308     if (HasClauses)
2309       ParseOMPDeclareTargetClauses(DTCI);
2310     bool HasImplicitMappings =
2311         DKind == OMPD_begin_declare_target || !HasClauses ||
2312         (DTCI.ExplicitlyMapped.empty() && DTCI.Indirect.hasValue());
2313 
2314     // Skip the last annot_pragma_openmp_end.
2315     ConsumeAnyToken();
2316 
2317     if (HasImplicitMappings) {
2318       Actions.ActOnStartOpenMPDeclareTargetContext(DTCI);
2319       return nullptr;
2320     }
2321 
2322     Actions.ActOnFinishedOpenMPDeclareTargetContext(DTCI);
2323     llvm::SmallVector<Decl *, 4> Decls;
2324     for (auto &It : DTCI.ExplicitlyMapped)
2325       Decls.push_back(It.first);
2326     return Actions.BuildDeclaratorGroup(Decls);
2327   }
2328   case OMPD_end_declare_target: {
2329     if (!Actions.isInOpenMPDeclareTargetContext()) {
2330       Diag(Tok, diag::err_omp_unexpected_directive)
2331           << 1 << getOpenMPDirectiveName(DKind);
2332       break;
2333     }
2334     const Sema::DeclareTargetContextInfo &DTCI =
2335         Actions.ActOnOpenMPEndDeclareTargetDirective();
2336     ParseOMPEndDeclareTargetDirective(DTCI.Kind, DKind, DTCI.Loc);
2337     return nullptr;
2338   }
2339   case OMPD_unknown:
2340     Diag(Tok, diag::err_omp_unknown_directive);
2341     break;
2342   case OMPD_parallel:
2343   case OMPD_simd:
2344   case OMPD_tile:
2345   case OMPD_unroll:
2346   case OMPD_task:
2347   case OMPD_taskyield:
2348   case OMPD_barrier:
2349   case OMPD_taskwait:
2350   case OMPD_taskgroup:
2351   case OMPD_flush:
2352   case OMPD_depobj:
2353   case OMPD_scan:
2354   case OMPD_for:
2355   case OMPD_for_simd:
2356   case OMPD_sections:
2357   case OMPD_section:
2358   case OMPD_single:
2359   case OMPD_master:
2360   case OMPD_ordered:
2361   case OMPD_critical:
2362   case OMPD_parallel_for:
2363   case OMPD_parallel_for_simd:
2364   case OMPD_parallel_sections:
2365   case OMPD_parallel_master:
2366   case OMPD_atomic:
2367   case OMPD_target:
2368   case OMPD_teams:
2369   case OMPD_cancellation_point:
2370   case OMPD_cancel:
2371   case OMPD_target_data:
2372   case OMPD_target_enter_data:
2373   case OMPD_target_exit_data:
2374   case OMPD_target_parallel:
2375   case OMPD_target_parallel_for:
2376   case OMPD_taskloop:
2377   case OMPD_taskloop_simd:
2378   case OMPD_master_taskloop:
2379   case OMPD_master_taskloop_simd:
2380   case OMPD_parallel_master_taskloop:
2381   case OMPD_parallel_master_taskloop_simd:
2382   case OMPD_distribute:
2383   case OMPD_target_update:
2384   case OMPD_distribute_parallel_for:
2385   case OMPD_distribute_parallel_for_simd:
2386   case OMPD_distribute_simd:
2387   case OMPD_target_parallel_for_simd:
2388   case OMPD_target_simd:
2389   case OMPD_teams_distribute:
2390   case OMPD_teams_distribute_simd:
2391   case OMPD_teams_distribute_parallel_for_simd:
2392   case OMPD_teams_distribute_parallel_for:
2393   case OMPD_target_teams:
2394   case OMPD_target_teams_distribute:
2395   case OMPD_target_teams_distribute_parallel_for:
2396   case OMPD_target_teams_distribute_parallel_for_simd:
2397   case OMPD_target_teams_distribute_simd:
2398   case OMPD_dispatch:
2399   case OMPD_masked:
2400   case OMPD_metadirective:
2401   case OMPD_loop:
2402     Diag(Tok, diag::err_omp_unexpected_directive)
2403         << 1 << getOpenMPDirectiveName(DKind);
2404     break;
2405   default:
2406     break;
2407   }
2408   while (Tok.isNot(tok::annot_pragma_openmp_end))
2409     ConsumeAnyToken();
2410   ConsumeAnyToken();
2411   return nullptr;
2412 }
2413 
2414 /// Parsing of declarative or executable OpenMP directives.
2415 ///
2416 ///       threadprivate-directive:
2417 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
2418 ///         annot_pragma_openmp_end
2419 ///
2420 ///       allocate-directive:
2421 ///         annot_pragma_openmp 'allocate' simple-variable-list
2422 ///         annot_pragma_openmp_end
2423 ///
2424 ///       declare-reduction-directive:
2425 ///         annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
2426 ///         <type> {',' <type>} ':' <expression> ')' ['initializer' '('
2427 ///         ('omp_priv' '=' <expression>|<function_call>) ')']
2428 ///         annot_pragma_openmp_end
2429 ///
2430 ///       declare-mapper-directive:
2431 ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
2432 ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
2433 ///         annot_pragma_openmp_end
2434 ///
2435 ///       executable-directive:
2436 ///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
2437 ///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
2438 ///         'parallel for' | 'parallel sections' | 'parallel master' | 'task' |
2439 ///         'taskyield' | 'barrier' | 'taskwait' | 'flush' | 'ordered' |
2440 ///         'atomic' | 'for simd' | 'parallel for simd' | 'target' | 'target
2441 ///         data' | 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
2442 ///         'master taskloop' | 'master taskloop simd' | 'parallel master
2443 ///         taskloop' | 'parallel master taskloop simd' | 'distribute' | 'target
2444 ///         enter data' | 'target exit data' | 'target parallel' | 'target
2445 ///         parallel for' | 'target update' | 'distribute parallel for' |
2446 ///         'distribute paralle for simd' | 'distribute simd' | 'target parallel
2447 ///         for simd' | 'target simd' | 'teams distribute' | 'teams distribute
2448 ///         simd' | 'teams distribute parallel for simd' | 'teams distribute
2449 ///         parallel for' | 'target teams' | 'target teams distribute' | 'target
2450 ///         teams distribute parallel for' | 'target teams distribute parallel
2451 ///         for simd' | 'target teams distribute simd' | 'masked' {clause}
2452 ///         annot_pragma_openmp_end
2453 ///
2454 StmtResult
2455 Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
2456   static bool ReadDirectiveWithinMetadirective = false;
2457   if (!ReadDirectiveWithinMetadirective)
2458     assert(Tok.isOneOf(tok::annot_pragma_openmp, tok::annot_attr_openmp) &&
2459            "Not an OpenMP directive!");
2460   ParsingOpenMPDirectiveRAII DirScope(*this);
2461   ParenBraceBracketBalancer BalancerRAIIObj(*this);
2462   SmallVector<OMPClause *, 5> Clauses;
2463   SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
2464               llvm::omp::Clause_enumSize + 1>
2465       FirstClauses(llvm::omp::Clause_enumSize + 1);
2466   unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
2467                         Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
2468   SourceLocation Loc = ReadDirectiveWithinMetadirective
2469                            ? Tok.getLocation()
2470                            : ConsumeAnnotationToken(),
2471                  EndLoc;
2472   OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
2473   if (ReadDirectiveWithinMetadirective && DKind == OMPD_unknown) {
2474     Diag(Tok, diag::err_omp_unknown_directive);
2475     return StmtError();
2476   }
2477   OpenMPDirectiveKind CancelRegion = OMPD_unknown;
2478   // Name of critical directive.
2479   DeclarationNameInfo DirName;
2480   StmtResult Directive = StmtError();
2481   bool HasAssociatedStatement = true;
2482 
2483   switch (DKind) {
2484   case OMPD_metadirective: {
2485     ConsumeToken();
2486     SmallVector<VariantMatchInfo, 4> VMIs;
2487 
2488     // First iteration of parsing all clauses of metadirective.
2489     // This iteration only parses and collects all context selector ignoring the
2490     // associated directives.
2491     TentativeParsingAction TPA(*this);
2492     ASTContext &ASTContext = Actions.getASTContext();
2493 
2494     BalancedDelimiterTracker T(*this, tok::l_paren,
2495                                tok::annot_pragma_openmp_end);
2496     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2497       OpenMPClauseKind CKind = Tok.isAnnotation()
2498                                    ? OMPC_unknown
2499                                    : getOpenMPClauseKind(PP.getSpelling(Tok));
2500       SourceLocation Loc = ConsumeToken();
2501 
2502       // Parse '('.
2503       if (T.expectAndConsume(diag::err_expected_lparen_after,
2504                              getOpenMPClauseName(CKind).data()))
2505         return Directive;
2506 
2507       OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2508       if (CKind == OMPC_when) {
2509         // parse and get OMPTraitInfo to pass to the When clause
2510         parseOMPContextSelectors(Loc, TI);
2511         if (TI.Sets.size() == 0) {
2512           Diag(Tok, diag::err_omp_expected_context_selector) << "when clause";
2513           TPA.Commit();
2514           return Directive;
2515         }
2516 
2517         // Parse ':'
2518         if (Tok.is(tok::colon))
2519           ConsumeAnyToken();
2520         else {
2521           Diag(Tok, diag::err_omp_expected_colon) << "when clause";
2522           TPA.Commit();
2523           return Directive;
2524         }
2525       }
2526       // Skip Directive for now. We will parse directive in the second iteration
2527       int paren = 0;
2528       while (Tok.isNot(tok::r_paren) || paren != 0) {
2529         if (Tok.is(tok::l_paren))
2530           paren++;
2531         if (Tok.is(tok::r_paren))
2532           paren--;
2533         if (Tok.is(tok::annot_pragma_openmp_end)) {
2534           Diag(Tok, diag::err_omp_expected_punc)
2535               << getOpenMPClauseName(CKind) << 0;
2536           TPA.Commit();
2537           return Directive;
2538         }
2539         ConsumeAnyToken();
2540       }
2541       // Parse ')'
2542       if (Tok.is(tok::r_paren))
2543         T.consumeClose();
2544 
2545       VariantMatchInfo VMI;
2546       TI.getAsVariantMatchInfo(ASTContext, VMI);
2547 
2548       VMIs.push_back(VMI);
2549     }
2550 
2551     TPA.Revert();
2552     // End of the first iteration. Parser is reset to the start of metadirective
2553 
2554     std::function<void(StringRef)> DiagUnknownTrait =
2555         [this, Loc](StringRef ISATrait) {
2556           // TODO Track the selector locations in a way that is accessible here
2557           // to improve the diagnostic location.
2558           Diag(Loc, diag::warn_unknown_declare_variant_isa_trait) << ISATrait;
2559         };
2560     TargetOMPContext OMPCtx(ASTContext, std::move(DiagUnknownTrait),
2561                             /* CurrentFunctionDecl */ nullptr,
2562                             ArrayRef<llvm::omp::TraitProperty>());
2563 
2564     // A single match is returned for OpenMP 5.0
2565     int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
2566 
2567     int Idx = 0;
2568     // In OpenMP 5.0 metadirective is either replaced by another directive or
2569     // ignored.
2570     // TODO: In OpenMP 5.1 generate multiple directives based upon the matches
2571     // found by getBestWhenMatchForContext.
2572     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2573       // OpenMP 5.0 implementation - Skip to the best index found.
2574       if (Idx++ != BestIdx) {
2575         ConsumeToken();  // Consume clause name
2576         T.consumeOpen(); // Consume '('
2577         int paren = 0;
2578         // Skip everything inside the clause
2579         while (Tok.isNot(tok::r_paren) || paren != 0) {
2580           if (Tok.is(tok::l_paren))
2581             paren++;
2582           if (Tok.is(tok::r_paren))
2583             paren--;
2584           ConsumeAnyToken();
2585         }
2586         // Parse ')'
2587         if (Tok.is(tok::r_paren))
2588           T.consumeClose();
2589         continue;
2590       }
2591 
2592       OpenMPClauseKind CKind = Tok.isAnnotation()
2593                                    ? OMPC_unknown
2594                                    : getOpenMPClauseKind(PP.getSpelling(Tok));
2595       SourceLocation Loc = ConsumeToken();
2596 
2597       // Parse '('.
2598       T.consumeOpen();
2599 
2600       // Skip ContextSelectors for when clause
2601       if (CKind == OMPC_when) {
2602         OMPTraitInfo &TI = Actions.getASTContext().getNewOMPTraitInfo();
2603         // parse and skip the ContextSelectors
2604         parseOMPContextSelectors(Loc, TI);
2605 
2606         // Parse ':'
2607         ConsumeAnyToken();
2608       }
2609 
2610       // If no directive is passed, skip in OpenMP 5.0.
2611       // TODO: Generate nothing directive from OpenMP 5.1.
2612       if (Tok.is(tok::r_paren)) {
2613         SkipUntil(tok::annot_pragma_openmp_end);
2614         break;
2615       }
2616 
2617       // Parse Directive
2618       ReadDirectiveWithinMetadirective = true;
2619       Directive = ParseOpenMPDeclarativeOrExecutableDirective(StmtCtx);
2620       ReadDirectiveWithinMetadirective = false;
2621       break;
2622     }
2623     break;
2624   }
2625   case OMPD_threadprivate: {
2626     // FIXME: Should this be permitted in C++?
2627     if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
2628         ParsedStmtContext()) {
2629       Diag(Tok, diag::err_omp_immediate_directive)
2630           << getOpenMPDirectiveName(DKind) << 0;
2631     }
2632     ConsumeToken();
2633     DeclDirectiveListParserHelper Helper(this, DKind);
2634     if (!ParseOpenMPSimpleVarList(DKind, Helper,
2635                                   /*AllowScopeSpecifier=*/false)) {
2636       skipUntilPragmaOpenMPEnd(DKind);
2637       DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
2638           Loc, Helper.getIdentifiers());
2639       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2640     }
2641     SkipUntil(tok::annot_pragma_openmp_end);
2642     break;
2643   }
2644   case OMPD_allocate: {
2645     // FIXME: Should this be permitted in C++?
2646     if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
2647         ParsedStmtContext()) {
2648       Diag(Tok, diag::err_omp_immediate_directive)
2649           << getOpenMPDirectiveName(DKind) << 0;
2650     }
2651     ConsumeToken();
2652     DeclDirectiveListParserHelper Helper(this, DKind);
2653     if (!ParseOpenMPSimpleVarList(DKind, Helper,
2654                                   /*AllowScopeSpecifier=*/false)) {
2655       SmallVector<OMPClause *, 1> Clauses;
2656       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2657         SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
2658                     llvm::omp::Clause_enumSize + 1>
2659             FirstClauses(llvm::omp::Clause_enumSize + 1);
2660         while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2661           OpenMPClauseKind CKind =
2662               Tok.isAnnotation() ? OMPC_unknown
2663                                  : getOpenMPClauseKind(PP.getSpelling(Tok));
2664           Actions.StartOpenMPClause(CKind);
2665           OMPClause *Clause = ParseOpenMPClause(
2666               OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt());
2667           SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2668                     StopBeforeMatch);
2669           FirstClauses[unsigned(CKind)].setInt(true);
2670           if (Clause != nullptr)
2671             Clauses.push_back(Clause);
2672           if (Tok.is(tok::annot_pragma_openmp_end)) {
2673             Actions.EndOpenMPClause();
2674             break;
2675           }
2676           // Skip ',' if any.
2677           if (Tok.is(tok::comma))
2678             ConsumeToken();
2679           Actions.EndOpenMPClause();
2680         }
2681         skipUntilPragmaOpenMPEnd(DKind);
2682       }
2683       DeclGroupPtrTy Res = Actions.ActOnOpenMPAllocateDirective(
2684           Loc, Helper.getIdentifiers(), Clauses);
2685       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2686     }
2687     SkipUntil(tok::annot_pragma_openmp_end);
2688     break;
2689   }
2690   case OMPD_declare_reduction:
2691     ConsumeToken();
2692     if (DeclGroupPtrTy Res =
2693             ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
2694       skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2695       ConsumeAnyToken();
2696       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2697     } else {
2698       SkipUntil(tok::annot_pragma_openmp_end);
2699     }
2700     break;
2701   case OMPD_declare_mapper: {
2702     ConsumeToken();
2703     if (DeclGroupPtrTy Res =
2704             ParseOpenMPDeclareMapperDirective(/*AS=*/AS_none)) {
2705       // Skip the last annot_pragma_openmp_end.
2706       ConsumeAnnotationToken();
2707       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2708     } else {
2709       SkipUntil(tok::annot_pragma_openmp_end);
2710     }
2711     break;
2712   }
2713   case OMPD_flush:
2714   case OMPD_depobj:
2715   case OMPD_scan:
2716   case OMPD_taskyield:
2717   case OMPD_barrier:
2718   case OMPD_taskwait:
2719   case OMPD_cancellation_point:
2720   case OMPD_cancel:
2721   case OMPD_target_enter_data:
2722   case OMPD_target_exit_data:
2723   case OMPD_target_update:
2724   case OMPD_interop:
2725     if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2726         ParsedStmtContext()) {
2727       Diag(Tok, diag::err_omp_immediate_directive)
2728           << getOpenMPDirectiveName(DKind) << 0;
2729     }
2730     HasAssociatedStatement = false;
2731     // Fall through for further analysis.
2732     LLVM_FALLTHROUGH;
2733   case OMPD_parallel:
2734   case OMPD_simd:
2735   case OMPD_tile:
2736   case OMPD_unroll:
2737   case OMPD_for:
2738   case OMPD_for_simd:
2739   case OMPD_sections:
2740   case OMPD_single:
2741   case OMPD_section:
2742   case OMPD_master:
2743   case OMPD_critical:
2744   case OMPD_parallel_for:
2745   case OMPD_parallel_for_simd:
2746   case OMPD_parallel_sections:
2747   case OMPD_parallel_master:
2748   case OMPD_task:
2749   case OMPD_ordered:
2750   case OMPD_atomic:
2751   case OMPD_target:
2752   case OMPD_teams:
2753   case OMPD_taskgroup:
2754   case OMPD_target_data:
2755   case OMPD_target_parallel:
2756   case OMPD_target_parallel_for:
2757   case OMPD_loop:
2758   case OMPD_taskloop:
2759   case OMPD_taskloop_simd:
2760   case OMPD_master_taskloop:
2761   case OMPD_master_taskloop_simd:
2762   case OMPD_parallel_master_taskloop:
2763   case OMPD_parallel_master_taskloop_simd:
2764   case OMPD_distribute:
2765   case OMPD_distribute_parallel_for:
2766   case OMPD_distribute_parallel_for_simd:
2767   case OMPD_distribute_simd:
2768   case OMPD_target_parallel_for_simd:
2769   case OMPD_target_simd:
2770   case OMPD_teams_distribute:
2771   case OMPD_teams_distribute_simd:
2772   case OMPD_teams_distribute_parallel_for_simd:
2773   case OMPD_teams_distribute_parallel_for:
2774   case OMPD_target_teams:
2775   case OMPD_target_teams_distribute:
2776   case OMPD_target_teams_distribute_parallel_for:
2777   case OMPD_target_teams_distribute_parallel_for_simd:
2778   case OMPD_target_teams_distribute_simd:
2779   case OMPD_dispatch:
2780   case OMPD_masked: {
2781     // Special processing for flush and depobj clauses.
2782     Token ImplicitTok;
2783     bool ImplicitClauseAllowed = false;
2784     if (DKind == OMPD_flush || DKind == OMPD_depobj) {
2785       ImplicitTok = Tok;
2786       ImplicitClauseAllowed = true;
2787     }
2788     ConsumeToken();
2789     // Parse directive name of the 'critical' directive if any.
2790     if (DKind == OMPD_critical) {
2791       BalancedDelimiterTracker T(*this, tok::l_paren,
2792                                  tok::annot_pragma_openmp_end);
2793       if (!T.consumeOpen()) {
2794         if (Tok.isAnyIdentifier()) {
2795           DirName =
2796               DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
2797           ConsumeAnyToken();
2798         } else {
2799           Diag(Tok, diag::err_omp_expected_identifier_for_critical);
2800         }
2801         T.consumeClose();
2802       }
2803     } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
2804       CancelRegion = parseOpenMPDirectiveKind(*this);
2805       if (Tok.isNot(tok::annot_pragma_openmp_end))
2806         ConsumeToken();
2807     }
2808 
2809     if (isOpenMPLoopDirective(DKind))
2810       ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
2811     if (isOpenMPSimdDirective(DKind))
2812       ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
2813     ParseScope OMPDirectiveScope(this, ScopeFlags);
2814     Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
2815 
2816     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2817       // If we are parsing for a directive within a metadirective, the directive
2818       // ends with a ')'.
2819       if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
2820         while (Tok.isNot(tok::annot_pragma_openmp_end))
2821           ConsumeAnyToken();
2822         break;
2823       }
2824       bool HasImplicitClause = false;
2825       if (ImplicitClauseAllowed && Tok.is(tok::l_paren)) {
2826         HasImplicitClause = true;
2827         // Push copy of the current token back to stream to properly parse
2828         // pseudo-clause OMPFlushClause or OMPDepobjClause.
2829         PP.EnterToken(Tok, /*IsReinject*/ true);
2830         PP.EnterToken(ImplicitTok, /*IsReinject*/ true);
2831         ConsumeAnyToken();
2832       }
2833       OpenMPClauseKind CKind = Tok.isAnnotation()
2834                                    ? OMPC_unknown
2835                                    : getOpenMPClauseKind(PP.getSpelling(Tok));
2836       if (HasImplicitClause) {
2837         assert(CKind == OMPC_unknown && "Must be unknown implicit clause.");
2838         if (DKind == OMPD_flush) {
2839           CKind = OMPC_flush;
2840         } else {
2841           assert(DKind == OMPD_depobj &&
2842                  "Expected flush or depobj directives.");
2843           CKind = OMPC_depobj;
2844         }
2845       }
2846       // No more implicit clauses allowed.
2847       ImplicitClauseAllowed = false;
2848       Actions.StartOpenMPClause(CKind);
2849       HasImplicitClause = false;
2850       OMPClause *Clause = ParseOpenMPClause(
2851           DKind, CKind, !FirstClauses[unsigned(CKind)].getInt());
2852       FirstClauses[unsigned(CKind)].setInt(true);
2853       if (Clause) {
2854         FirstClauses[unsigned(CKind)].setPointer(Clause);
2855         Clauses.push_back(Clause);
2856       }
2857 
2858       // Skip ',' if any.
2859       if (Tok.is(tok::comma))
2860         ConsumeToken();
2861       Actions.EndOpenMPClause();
2862     }
2863     // End location of the directive.
2864     EndLoc = Tok.getLocation();
2865     // Consume final annot_pragma_openmp_end.
2866     ConsumeAnnotationToken();
2867 
2868     // OpenMP [2.13.8, ordered Construct, Syntax]
2869     // If the depend clause is specified, the ordered construct is a stand-alone
2870     // directive.
2871     if (DKind == OMPD_ordered && FirstClauses[unsigned(OMPC_depend)].getInt()) {
2872       if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2873           ParsedStmtContext()) {
2874         Diag(Loc, diag::err_omp_immediate_directive)
2875             << getOpenMPDirectiveName(DKind) << 1
2876             << getOpenMPClauseName(OMPC_depend);
2877       }
2878       HasAssociatedStatement = false;
2879     }
2880 
2881     if (DKind == OMPD_tile && !FirstClauses[unsigned(OMPC_sizes)].getInt()) {
2882       Diag(Loc, diag::err_omp_required_clause)
2883           << getOpenMPDirectiveName(OMPD_tile) << "sizes";
2884     }
2885 
2886     StmtResult AssociatedStmt;
2887     if (HasAssociatedStatement) {
2888       // The body is a block scope like in Lambdas and Blocks.
2889       Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
2890       // FIXME: We create a bogus CompoundStmt scope to hold the contents of
2891       // the captured region. Code elsewhere assumes that any FunctionScopeInfo
2892       // should have at least one compound statement scope within it.
2893       ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false);
2894       {
2895         Sema::CompoundScopeRAII Scope(Actions);
2896         AssociatedStmt = ParseStatement();
2897 
2898         if (AssociatedStmt.isUsable() && isOpenMPLoopDirective(DKind) &&
2899             getLangOpts().OpenMPIRBuilder)
2900           AssociatedStmt = Actions.ActOnOpenMPLoopnest(AssociatedStmt.get());
2901       }
2902       AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2903     } else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
2904                DKind == OMPD_target_exit_data) {
2905       Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
2906       AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
2907                         Actions.ActOnCompoundStmt(Loc, Loc, llvm::None,
2908                                                   /*isStmtExpr=*/false));
2909       AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2910     }
2911     Directive = Actions.ActOnOpenMPExecutableDirective(
2912         DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
2913         EndLoc);
2914 
2915     // Exit scope.
2916     Actions.EndOpenMPDSABlock(Directive.get());
2917     OMPDirectiveScope.Exit();
2918     break;
2919   }
2920   case OMPD_declare_simd:
2921   case OMPD_declare_target:
2922   case OMPD_begin_declare_target:
2923   case OMPD_end_declare_target:
2924   case OMPD_requires:
2925   case OMPD_begin_declare_variant:
2926   case OMPD_end_declare_variant:
2927   case OMPD_declare_variant:
2928     Diag(Tok, diag::err_omp_unexpected_directive)
2929         << 1 << getOpenMPDirectiveName(DKind);
2930     SkipUntil(tok::annot_pragma_openmp_end);
2931     break;
2932   case OMPD_unknown:
2933   default:
2934     Diag(Tok, diag::err_omp_unknown_directive);
2935     SkipUntil(tok::annot_pragma_openmp_end);
2936     break;
2937   }
2938   return Directive;
2939 }
2940 
2941 // Parses simple list:
2942 //   simple-variable-list:
2943 //         '(' id-expression {, id-expression} ')'
2944 //
2945 bool Parser::ParseOpenMPSimpleVarList(
2946     OpenMPDirectiveKind Kind,
2947     const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)>
2948         &Callback,
2949     bool AllowScopeSpecifier) {
2950   // Parse '('.
2951   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2952   if (T.expectAndConsume(diag::err_expected_lparen_after,
2953                          getOpenMPDirectiveName(Kind).data()))
2954     return true;
2955   bool IsCorrect = true;
2956   bool NoIdentIsFound = true;
2957 
2958   // Read tokens while ')' or annot_pragma_openmp_end is not found.
2959   while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
2960     CXXScopeSpec SS;
2961     UnqualifiedId Name;
2962     // Read var name.
2963     Token PrevTok = Tok;
2964     NoIdentIsFound = false;
2965 
2966     if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
2967         ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
2968                                        /*ObjectHasErrors=*/false, false)) {
2969       IsCorrect = false;
2970       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2971                 StopBeforeMatch);
2972     } else if (ParseUnqualifiedId(SS, /*ObjectType=*/nullptr,
2973                                   /*ObjectHadErrors=*/false, false, false,
2974                                   false, false, nullptr, Name)) {
2975       IsCorrect = false;
2976       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2977                 StopBeforeMatch);
2978     } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
2979                Tok.isNot(tok::annot_pragma_openmp_end)) {
2980       IsCorrect = false;
2981       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2982                 StopBeforeMatch);
2983       Diag(PrevTok.getLocation(), diag::err_expected)
2984           << tok::identifier
2985           << SourceRange(PrevTok.getLocation(), PrevTokLocation);
2986     } else {
2987       Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
2988     }
2989     // Consume ','.
2990     if (Tok.is(tok::comma)) {
2991       ConsumeToken();
2992     }
2993   }
2994 
2995   if (NoIdentIsFound) {
2996     Diag(Tok, diag::err_expected) << tok::identifier;
2997     IsCorrect = false;
2998   }
2999 
3000   // Parse ')'.
3001   IsCorrect = !T.consumeClose() && IsCorrect;
3002 
3003   return !IsCorrect;
3004 }
3005 
3006 OMPClause *Parser::ParseOpenMPSizesClause() {
3007   SourceLocation ClauseNameLoc = ConsumeToken();
3008   SmallVector<Expr *, 4> ValExprs;
3009 
3010   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3011   if (T.consumeOpen()) {
3012     Diag(Tok, diag::err_expected) << tok::l_paren;
3013     return nullptr;
3014   }
3015 
3016   while (true) {
3017     ExprResult Val = ParseConstantExpression();
3018     if (!Val.isUsable()) {
3019       T.skipToEnd();
3020       return nullptr;
3021     }
3022 
3023     ValExprs.push_back(Val.get());
3024 
3025     if (Tok.is(tok::r_paren) || Tok.is(tok::annot_pragma_openmp_end))
3026       break;
3027 
3028     ExpectAndConsume(tok::comma);
3029   }
3030 
3031   T.consumeClose();
3032 
3033   return Actions.ActOnOpenMPSizesClause(
3034       ValExprs, ClauseNameLoc, T.getOpenLocation(), T.getCloseLocation());
3035 }
3036 
3037 OMPClause *Parser::ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind) {
3038   SourceLocation Loc = Tok.getLocation();
3039   ConsumeAnyToken();
3040 
3041   // Parse '('.
3042   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3043   if (T.expectAndConsume(diag::err_expected_lparen_after, "uses_allocator"))
3044     return nullptr;
3045   SmallVector<Sema::UsesAllocatorsData, 4> Data;
3046   do {
3047     ExprResult Allocator =
3048         getLangOpts().CPlusPlus ? ParseCXXIdExpression() : ParseExpression();
3049     if (Allocator.isInvalid()) {
3050       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3051                 StopBeforeMatch);
3052       break;
3053     }
3054     Sema::UsesAllocatorsData &D = Data.emplace_back();
3055     D.Allocator = Allocator.get();
3056     if (Tok.is(tok::l_paren)) {
3057       BalancedDelimiterTracker T(*this, tok::l_paren,
3058                                  tok::annot_pragma_openmp_end);
3059       T.consumeOpen();
3060       ExprResult AllocatorTraits =
3061           getLangOpts().CPlusPlus ? ParseCXXIdExpression() : ParseExpression();
3062       T.consumeClose();
3063       if (AllocatorTraits.isInvalid()) {
3064         SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3065                   StopBeforeMatch);
3066         break;
3067       }
3068       D.AllocatorTraits = AllocatorTraits.get();
3069       D.LParenLoc = T.getOpenLocation();
3070       D.RParenLoc = T.getCloseLocation();
3071     }
3072     if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
3073       Diag(Tok, diag::err_omp_expected_punc) << "uses_allocators" << 0;
3074     // Parse ','
3075     if (Tok.is(tok::comma))
3076       ConsumeAnyToken();
3077   } while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end));
3078   T.consumeClose();
3079   return Actions.ActOnOpenMPUsesAllocatorClause(Loc, T.getOpenLocation(),
3080                                                 T.getCloseLocation(), Data);
3081 }
3082 
3083 /// Parsing of OpenMP clauses.
3084 ///
3085 ///    clause:
3086 ///       if-clause | final-clause | num_threads-clause | safelen-clause |
3087 ///       default-clause | private-clause | firstprivate-clause | shared-clause
3088 ///       | linear-clause | aligned-clause | collapse-clause | bind-clause |
3089 ///       lastprivate-clause | reduction-clause | proc_bind-clause |
3090 ///       schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
3091 ///       mergeable-clause | flush-clause | read-clause | write-clause |
3092 ///       update-clause | capture-clause | seq_cst-clause | device-clause |
3093 ///       simdlen-clause | threads-clause | simd-clause | num_teams-clause |
3094 ///       thread_limit-clause | priority-clause | grainsize-clause |
3095 ///       nogroup-clause | num_tasks-clause | hint-clause | to-clause |
3096 ///       from-clause | is_device_ptr-clause | task_reduction-clause |
3097 ///       in_reduction-clause | allocator-clause | allocate-clause |
3098 ///       acq_rel-clause | acquire-clause | release-clause | relaxed-clause |
3099 ///       depobj-clause | destroy-clause | detach-clause | inclusive-clause |
3100 ///       exclusive-clause | uses_allocators-clause | use_device_addr-clause
3101 ///
3102 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
3103                                      OpenMPClauseKind CKind, bool FirstClause) {
3104   OMPClauseKind = CKind;
3105   OMPClause *Clause = nullptr;
3106   bool ErrorFound = false;
3107   bool WrongDirective = false;
3108   // Check if clause is allowed for the given directive.
3109   if (CKind != OMPC_unknown &&
3110       !isAllowedClauseForDirective(DKind, CKind, getLangOpts().OpenMP)) {
3111     Diag(Tok, diag::err_omp_unexpected_clause)
3112         << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
3113     ErrorFound = true;
3114     WrongDirective = true;
3115   }
3116 
3117   switch (CKind) {
3118   case OMPC_final:
3119   case OMPC_num_threads:
3120   case OMPC_safelen:
3121   case OMPC_simdlen:
3122   case OMPC_collapse:
3123   case OMPC_ordered:
3124   case OMPC_num_teams:
3125   case OMPC_thread_limit:
3126   case OMPC_priority:
3127   case OMPC_grainsize:
3128   case OMPC_num_tasks:
3129   case OMPC_hint:
3130   case OMPC_allocator:
3131   case OMPC_depobj:
3132   case OMPC_detach:
3133   case OMPC_novariants:
3134   case OMPC_nocontext:
3135   case OMPC_filter:
3136   case OMPC_partial:
3137   case OMPC_align:
3138     // OpenMP [2.5, Restrictions]
3139     //  At most one num_threads clause can appear on the directive.
3140     // OpenMP [2.8.1, simd construct, Restrictions]
3141     //  Only one safelen  clause can appear on a simd directive.
3142     //  Only one simdlen  clause can appear on a simd directive.
3143     //  Only one collapse clause can appear on a simd directive.
3144     // OpenMP [2.11.1, task Construct, Restrictions]
3145     //  At most one if clause can appear on the directive.
3146     //  At most one final clause can appear on the directive.
3147     // OpenMP [teams Construct, Restrictions]
3148     //  At most one num_teams clause can appear on the directive.
3149     //  At most one thread_limit clause can appear on the directive.
3150     // OpenMP [2.9.1, task Construct, Restrictions]
3151     // At most one priority clause can appear on the directive.
3152     // OpenMP [2.9.2, taskloop Construct, Restrictions]
3153     // At most one grainsize clause can appear on the directive.
3154     // OpenMP [2.9.2, taskloop Construct, Restrictions]
3155     // At most one num_tasks clause can appear on the directive.
3156     // OpenMP [2.11.3, allocate Directive, Restrictions]
3157     // At most one allocator clause can appear on the directive.
3158     // OpenMP 5.0, 2.10.1 task Construct, Restrictions.
3159     // At most one detach clause can appear on the directive.
3160     // OpenMP 5.1, 2.3.6 dispatch Construct, Restrictions.
3161     // At most one novariants clause can appear on a dispatch directive.
3162     // At most one nocontext clause can appear on a dispatch directive.
3163     if (!FirstClause) {
3164       Diag(Tok, diag::err_omp_more_one_clause)
3165           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3166       ErrorFound = true;
3167     }
3168 
3169     if ((CKind == OMPC_ordered || CKind == OMPC_partial) &&
3170         PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
3171       Clause = ParseOpenMPClause(CKind, WrongDirective);
3172     else
3173       Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
3174     break;
3175   case OMPC_default:
3176   case OMPC_proc_bind:
3177   case OMPC_atomic_default_mem_order:
3178   case OMPC_order:
3179   case OMPC_bind:
3180     // OpenMP [2.14.3.1, Restrictions]
3181     //  Only a single default clause may be specified on a parallel, task or
3182     //  teams directive.
3183     // OpenMP [2.5, parallel Construct, Restrictions]
3184     //  At most one proc_bind clause can appear on the directive.
3185     // OpenMP [5.0, Requires directive, Restrictions]
3186     //  At most one atomic_default_mem_order clause can appear
3187     //  on the directive
3188     // OpenMP 5.1, 2.11.7 loop Construct, Restrictions.
3189     // At most one bind clause can appear on a loop directive.
3190     if (!FirstClause && CKind != OMPC_order) {
3191       Diag(Tok, diag::err_omp_more_one_clause)
3192           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3193       ErrorFound = true;
3194     }
3195 
3196     Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
3197     break;
3198   case OMPC_device:
3199   case OMPC_schedule:
3200   case OMPC_dist_schedule:
3201   case OMPC_defaultmap:
3202     // OpenMP [2.7.1, Restrictions, p. 3]
3203     //  Only one schedule clause can appear on a loop directive.
3204     // OpenMP 4.5 [2.10.4, Restrictions, p. 106]
3205     //  At most one defaultmap clause can appear on the directive.
3206     // OpenMP 5.0 [2.12.5, target construct, Restrictions]
3207     //  At most one device clause can appear on the directive.
3208     if ((getLangOpts().OpenMP < 50 || CKind != OMPC_defaultmap) &&
3209         !FirstClause) {
3210       Diag(Tok, diag::err_omp_more_one_clause)
3211           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3212       ErrorFound = true;
3213     }
3214     LLVM_FALLTHROUGH;
3215   case OMPC_if:
3216     Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
3217     break;
3218   case OMPC_nowait:
3219   case OMPC_untied:
3220   case OMPC_mergeable:
3221   case OMPC_read:
3222   case OMPC_write:
3223   case OMPC_capture:
3224   case OMPC_compare:
3225   case OMPC_seq_cst:
3226   case OMPC_acq_rel:
3227   case OMPC_acquire:
3228   case OMPC_release:
3229   case OMPC_relaxed:
3230   case OMPC_threads:
3231   case OMPC_simd:
3232   case OMPC_nogroup:
3233   case OMPC_unified_address:
3234   case OMPC_unified_shared_memory:
3235   case OMPC_reverse_offload:
3236   case OMPC_dynamic_allocators:
3237   case OMPC_full:
3238     // OpenMP [2.7.1, Restrictions, p. 9]
3239     //  Only one ordered clause can appear on a loop directive.
3240     // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
3241     //  Only one nowait clause can appear on a for directive.
3242     // OpenMP [5.0, Requires directive, Restrictions]
3243     //   Each of the requires clauses can appear at most once on the directive.
3244     if (!FirstClause) {
3245       Diag(Tok, diag::err_omp_more_one_clause)
3246           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3247       ErrorFound = true;
3248     }
3249 
3250     Clause = ParseOpenMPClause(CKind, WrongDirective);
3251     break;
3252   case OMPC_update:
3253     if (!FirstClause) {
3254       Diag(Tok, diag::err_omp_more_one_clause)
3255           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3256       ErrorFound = true;
3257     }
3258 
3259     Clause = (DKind == OMPD_depobj)
3260                  ? ParseOpenMPSimpleClause(CKind, WrongDirective)
3261                  : ParseOpenMPClause(CKind, WrongDirective);
3262     break;
3263   case OMPC_private:
3264   case OMPC_firstprivate:
3265   case OMPC_lastprivate:
3266   case OMPC_shared:
3267   case OMPC_reduction:
3268   case OMPC_task_reduction:
3269   case OMPC_in_reduction:
3270   case OMPC_linear:
3271   case OMPC_aligned:
3272   case OMPC_copyin:
3273   case OMPC_copyprivate:
3274   case OMPC_flush:
3275   case OMPC_depend:
3276   case OMPC_map:
3277   case OMPC_to:
3278   case OMPC_from:
3279   case OMPC_use_device_ptr:
3280   case OMPC_use_device_addr:
3281   case OMPC_is_device_ptr:
3282   case OMPC_allocate:
3283   case OMPC_nontemporal:
3284   case OMPC_inclusive:
3285   case OMPC_exclusive:
3286   case OMPC_affinity:
3287     Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
3288     break;
3289   case OMPC_sizes:
3290     if (!FirstClause) {
3291       Diag(Tok, diag::err_omp_more_one_clause)
3292           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3293       ErrorFound = true;
3294     }
3295 
3296     Clause = ParseOpenMPSizesClause();
3297     break;
3298   case OMPC_uses_allocators:
3299     Clause = ParseOpenMPUsesAllocatorClause(DKind);
3300     break;
3301   case OMPC_destroy:
3302     if (DKind != OMPD_interop) {
3303       if (!FirstClause) {
3304         Diag(Tok, diag::err_omp_more_one_clause)
3305             << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
3306         ErrorFound = true;
3307       }
3308       Clause = ParseOpenMPClause(CKind, WrongDirective);
3309       break;
3310     }
3311     LLVM_FALLTHROUGH;
3312   case OMPC_init:
3313   case OMPC_use:
3314     Clause = ParseOpenMPInteropClause(CKind, WrongDirective);
3315     break;
3316   case OMPC_device_type:
3317   case OMPC_unknown:
3318     skipUntilPragmaOpenMPEnd(DKind);
3319     break;
3320   case OMPC_threadprivate:
3321   case OMPC_uniform:
3322   case OMPC_match:
3323     if (!WrongDirective)
3324       Diag(Tok, diag::err_omp_unexpected_clause)
3325           << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
3326     SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
3327     break;
3328   default:
3329     break;
3330   }
3331   return ErrorFound ? nullptr : Clause;
3332 }
3333 
3334 /// Parses simple expression in parens for single-expression clauses of OpenMP
3335 /// constructs.
3336 /// \param RLoc Returned location of right paren.
3337 ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
3338                                          SourceLocation &RLoc,
3339                                          bool IsAddressOfOperand) {
3340   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3341   if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
3342     return ExprError();
3343 
3344   SourceLocation ELoc = Tok.getLocation();
3345   ExprResult LHS(
3346       ParseCastExpression(AnyCastExpr, IsAddressOfOperand, NotTypeCast));
3347   ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3348   Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
3349 
3350   // Parse ')'.
3351   RLoc = Tok.getLocation();
3352   if (!T.consumeClose())
3353     RLoc = T.getCloseLocation();
3354 
3355   return Val;
3356 }
3357 
3358 /// Parsing of OpenMP clauses with single expressions like 'final',
3359 /// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
3360 /// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks', 'hint' or
3361 /// 'detach'.
3362 ///
3363 ///    final-clause:
3364 ///      'final' '(' expression ')'
3365 ///
3366 ///    num_threads-clause:
3367 ///      'num_threads' '(' expression ')'
3368 ///
3369 ///    safelen-clause:
3370 ///      'safelen' '(' expression ')'
3371 ///
3372 ///    simdlen-clause:
3373 ///      'simdlen' '(' expression ')'
3374 ///
3375 ///    collapse-clause:
3376 ///      'collapse' '(' expression ')'
3377 ///
3378 ///    priority-clause:
3379 ///      'priority' '(' expression ')'
3380 ///
3381 ///    grainsize-clause:
3382 ///      'grainsize' '(' expression ')'
3383 ///
3384 ///    num_tasks-clause:
3385 ///      'num_tasks' '(' expression ')'
3386 ///
3387 ///    hint-clause:
3388 ///      'hint' '(' expression ')'
3389 ///
3390 ///    allocator-clause:
3391 ///      'allocator' '(' expression ')'
3392 ///
3393 ///    detach-clause:
3394 ///      'detach' '(' event-handler-expression ')'
3395 ///
3396 ///    align-clause
3397 ///      'align' '(' positive-integer-constant ')'
3398 ///
3399 OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
3400                                                bool ParseOnly) {
3401   SourceLocation Loc = ConsumeToken();
3402   SourceLocation LLoc = Tok.getLocation();
3403   SourceLocation RLoc;
3404 
3405   ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc);
3406 
3407   if (Val.isInvalid())
3408     return nullptr;
3409 
3410   if (ParseOnly)
3411     return nullptr;
3412   return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc);
3413 }
3414 
3415 /// Parse indirect clause for '#pragma omp declare target' directive.
3416 ///  'indirect' '[' '(' invoked-by-fptr ')' ']'
3417 /// where invoked-by-fptr is a constant boolean expression that evaluates to
3418 /// true or false at compile time.
3419 bool Parser::ParseOpenMPIndirectClause(Sema::DeclareTargetContextInfo &DTCI,
3420                                        bool ParseOnly) {
3421   SourceLocation Loc = ConsumeToken();
3422   SourceLocation RLoc;
3423 
3424   if (Tok.isNot(tok::l_paren)) {
3425     if (ParseOnly)
3426       return false;
3427     DTCI.Indirect = nullptr;
3428     return true;
3429   }
3430 
3431   ExprResult Val =
3432       ParseOpenMPParensExpr(getOpenMPClauseName(OMPC_indirect), RLoc);
3433   if (Val.isInvalid())
3434     return false;
3435 
3436   if (ParseOnly)
3437     return false;
3438 
3439   if (!Val.get()->isValueDependent() && !Val.get()->isTypeDependent() &&
3440       !Val.get()->isInstantiationDependent() &&
3441       !Val.get()->containsUnexpandedParameterPack()) {
3442     ExprResult Ret = Actions.CheckBooleanCondition(Loc, Val.get());
3443     if (Ret.isInvalid())
3444       return false;
3445     llvm::APSInt Result;
3446     Ret = Actions.VerifyIntegerConstantExpression(Val.get(), &Result,
3447                                                   Sema::AllowFold);
3448     if (Ret.isInvalid())
3449       return false;
3450     DTCI.Indirect = Val.get();
3451     return true;
3452   }
3453   return false;
3454 }
3455 
3456 /// Parsing of OpenMP clauses that use an interop-var.
3457 ///
3458 /// init-clause:
3459 ///   init([interop-modifier, ]interop-type[[, interop-type] ... ]:interop-var)
3460 ///
3461 /// destroy-clause:
3462 ///   destroy(interop-var)
3463 ///
3464 /// use-clause:
3465 ///   use(interop-var)
3466 ///
3467 /// interop-modifier:
3468 ///   prefer_type(preference-list)
3469 ///
3470 /// preference-list:
3471 ///   foreign-runtime-id [, foreign-runtime-id]...
3472 ///
3473 /// foreign-runtime-id:
3474 ///   <string-literal> | <constant-integral-expression>
3475 ///
3476 /// interop-type:
3477 ///   target | targetsync
3478 ///
3479 OMPClause *Parser::ParseOpenMPInteropClause(OpenMPClauseKind Kind,
3480                                             bool ParseOnly) {
3481   SourceLocation Loc = ConsumeToken();
3482   // Parse '('.
3483   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3484   if (T.expectAndConsume(diag::err_expected_lparen_after,
3485                          getOpenMPClauseName(Kind).data()))
3486     return nullptr;
3487 
3488   bool IsTarget = false;
3489   bool IsTargetSync = false;
3490   SmallVector<Expr *, 4> Prefs;
3491 
3492   if (Kind == OMPC_init) {
3493 
3494     // Parse optional interop-modifier.
3495     if (Tok.is(tok::identifier) && PP.getSpelling(Tok) == "prefer_type") {
3496       ConsumeToken();
3497       BalancedDelimiterTracker PT(*this, tok::l_paren,
3498                                   tok::annot_pragma_openmp_end);
3499       if (PT.expectAndConsume(diag::err_expected_lparen_after, "prefer_type"))
3500         return nullptr;
3501 
3502       while (Tok.isNot(tok::r_paren)) {
3503         SourceLocation Loc = Tok.getLocation();
3504         ExprResult LHS = ParseCastExpression(AnyCastExpr);
3505         ExprResult PTExpr = Actions.CorrectDelayedTyposInExpr(
3506             ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3507         PTExpr = Actions.ActOnFinishFullExpr(PTExpr.get(), Loc,
3508                                              /*DiscardedValue=*/false);
3509         if (PTExpr.isUsable())
3510           Prefs.push_back(PTExpr.get());
3511         else
3512           SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3513                     StopBeforeMatch);
3514 
3515         if (Tok.is(tok::comma))
3516           ConsumeToken();
3517       }
3518       PT.consumeClose();
3519     }
3520 
3521     if (!Prefs.empty()) {
3522       if (Tok.is(tok::comma))
3523         ConsumeToken();
3524       else
3525         Diag(Tok, diag::err_omp_expected_punc_after_interop_mod);
3526     }
3527 
3528     // Parse the interop-types.
3529     if (Optional<OMPDeclareVariantAttr::InteropType> IType =
3530             parseInteropTypeList(*this)) {
3531       IsTarget = IType != OMPDeclareVariantAttr::TargetSync;
3532       IsTargetSync = IType != OMPDeclareVariantAttr::Target;
3533       if (Tok.isNot(tok::colon))
3534         Diag(Tok, diag::warn_pragma_expected_colon) << "interop types";
3535     }
3536     if (Tok.is(tok::colon))
3537       ConsumeToken();
3538   }
3539 
3540   // Parse the variable.
3541   SourceLocation VarLoc = Tok.getLocation();
3542   ExprResult InteropVarExpr =
3543       Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
3544   if (!InteropVarExpr.isUsable()) {
3545     SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3546               StopBeforeMatch);
3547   }
3548 
3549   // Parse ')'.
3550   SourceLocation RLoc = Tok.getLocation();
3551   if (!T.consumeClose())
3552     RLoc = T.getCloseLocation();
3553 
3554   if (ParseOnly || !InteropVarExpr.isUsable() ||
3555       (Kind == OMPC_init && !IsTarget && !IsTargetSync))
3556     return nullptr;
3557 
3558   if (Kind == OMPC_init)
3559     return Actions.ActOnOpenMPInitClause(InteropVarExpr.get(), Prefs, IsTarget,
3560                                          IsTargetSync, Loc, T.getOpenLocation(),
3561                                          VarLoc, RLoc);
3562   if (Kind == OMPC_use)
3563     return Actions.ActOnOpenMPUseClause(InteropVarExpr.get(), Loc,
3564                                         T.getOpenLocation(), VarLoc, RLoc);
3565 
3566   if (Kind == OMPC_destroy)
3567     return Actions.ActOnOpenMPDestroyClause(InteropVarExpr.get(), Loc,
3568                                             T.getOpenLocation(), VarLoc, RLoc);
3569 
3570   llvm_unreachable("Unexpected interop variable clause.");
3571 }
3572 
3573 /// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
3574 ///
3575 ///    default-clause:
3576 ///         'default' '(' 'none' | 'shared' | 'firstprivate' ')'
3577 ///
3578 ///    proc_bind-clause:
3579 ///         'proc_bind' '(' 'master' | 'close' | 'spread' ')'
3580 ///
3581 ///    bind-clause:
3582 ///         'bind' '(' 'teams' | 'parallel' | 'thread' ')'
3583 ///
3584 ///    update-clause:
3585 ///         'update' '(' 'in' | 'out' | 'inout' | 'mutexinoutset' ')'
3586 ///
3587 OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind,
3588                                            bool ParseOnly) {
3589   llvm::Optional<SimpleClauseData> Val = parseOpenMPSimpleClause(*this, Kind);
3590   if (!Val || ParseOnly)
3591     return nullptr;
3592   if (getLangOpts().OpenMP < 51 && Kind == OMPC_default &&
3593       static_cast<DefaultKind>(Val.getValue().Type) ==
3594           OMP_DEFAULT_firstprivate) {
3595     Diag(Val.getValue().LOpen, diag::err_omp_invalid_dsa)
3596         << getOpenMPClauseName(OMPC_firstprivate)
3597         << getOpenMPClauseName(OMPC_default) << "5.1";
3598     return nullptr;
3599   }
3600   return Actions.ActOnOpenMPSimpleClause(
3601       Kind, Val.getValue().Type, Val.getValue().TypeLoc, Val.getValue().LOpen,
3602       Val.getValue().Loc, Val.getValue().RLoc);
3603 }
3604 
3605 /// Parsing of OpenMP clauses like 'ordered'.
3606 ///
3607 ///    ordered-clause:
3608 ///         'ordered'
3609 ///
3610 ///    nowait-clause:
3611 ///         'nowait'
3612 ///
3613 ///    untied-clause:
3614 ///         'untied'
3615 ///
3616 ///    mergeable-clause:
3617 ///         'mergeable'
3618 ///
3619 ///    read-clause:
3620 ///         'read'
3621 ///
3622 ///    threads-clause:
3623 ///         'threads'
3624 ///
3625 ///    simd-clause:
3626 ///         'simd'
3627 ///
3628 ///    nogroup-clause:
3629 ///         'nogroup'
3630 ///
3631 OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly) {
3632   SourceLocation Loc = Tok.getLocation();
3633   ConsumeAnyToken();
3634 
3635   if (ParseOnly)
3636     return nullptr;
3637   return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
3638 }
3639 
3640 /// Parsing of OpenMP clauses with single expressions and some additional
3641 /// argument like 'schedule' or 'dist_schedule'.
3642 ///
3643 ///    schedule-clause:
3644 ///      'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
3645 ///      ')'
3646 ///
3647 ///    if-clause:
3648 ///      'if' '(' [ directive-name-modifier ':' ] expression ')'
3649 ///
3650 ///    defaultmap:
3651 ///      'defaultmap' '(' modifier [ ':' kind ] ')'
3652 ///
3653 ///    device-clause:
3654 ///      'device' '(' [ device-modifier ':' ] expression ')'
3655 ///
3656 OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind,
3657                                                       OpenMPClauseKind Kind,
3658                                                       bool ParseOnly) {
3659   SourceLocation Loc = ConsumeToken();
3660   SourceLocation DelimLoc;
3661   // Parse '('.
3662   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3663   if (T.expectAndConsume(diag::err_expected_lparen_after,
3664                          getOpenMPClauseName(Kind).data()))
3665     return nullptr;
3666 
3667   ExprResult Val;
3668   SmallVector<unsigned, 4> Arg;
3669   SmallVector<SourceLocation, 4> KLoc;
3670   if (Kind == OMPC_schedule) {
3671     enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
3672     Arg.resize(NumberOfElements);
3673     KLoc.resize(NumberOfElements);
3674     Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
3675     Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
3676     Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
3677     unsigned KindModifier = getOpenMPSimpleClauseType(
3678         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok), getLangOpts());
3679     if (KindModifier > OMPC_SCHEDULE_unknown) {
3680       // Parse 'modifier'
3681       Arg[Modifier1] = KindModifier;
3682       KLoc[Modifier1] = Tok.getLocation();
3683       if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3684           Tok.isNot(tok::annot_pragma_openmp_end))
3685         ConsumeAnyToken();
3686       if (Tok.is(tok::comma)) {
3687         // Parse ',' 'modifier'
3688         ConsumeAnyToken();
3689         KindModifier = getOpenMPSimpleClauseType(
3690             Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok), getLangOpts());
3691         Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown
3692                              ? KindModifier
3693                              : (unsigned)OMPC_SCHEDULE_unknown;
3694         KLoc[Modifier2] = Tok.getLocation();
3695         if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3696             Tok.isNot(tok::annot_pragma_openmp_end))
3697           ConsumeAnyToken();
3698       }
3699       // Parse ':'
3700       if (Tok.is(tok::colon))
3701         ConsumeAnyToken();
3702       else
3703         Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier";
3704       KindModifier = getOpenMPSimpleClauseType(
3705           Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok), getLangOpts());
3706     }
3707     Arg[ScheduleKind] = KindModifier;
3708     KLoc[ScheduleKind] = Tok.getLocation();
3709     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3710         Tok.isNot(tok::annot_pragma_openmp_end))
3711       ConsumeAnyToken();
3712     if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
3713          Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
3714          Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
3715         Tok.is(tok::comma))
3716       DelimLoc = ConsumeAnyToken();
3717   } else if (Kind == OMPC_dist_schedule) {
3718     Arg.push_back(getOpenMPSimpleClauseType(
3719         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok), getLangOpts()));
3720     KLoc.push_back(Tok.getLocation());
3721     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3722         Tok.isNot(tok::annot_pragma_openmp_end))
3723       ConsumeAnyToken();
3724     if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
3725       DelimLoc = ConsumeAnyToken();
3726   } else if (Kind == OMPC_defaultmap) {
3727     // Get a defaultmap modifier
3728     unsigned Modifier = getOpenMPSimpleClauseType(
3729         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok), getLangOpts());
3730     // Set defaultmap modifier to unknown if it is either scalar, aggregate, or
3731     // pointer
3732     if (Modifier < OMPC_DEFAULTMAP_MODIFIER_unknown)
3733       Modifier = OMPC_DEFAULTMAP_MODIFIER_unknown;
3734     Arg.push_back(Modifier);
3735     KLoc.push_back(Tok.getLocation());
3736     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3737         Tok.isNot(tok::annot_pragma_openmp_end))
3738       ConsumeAnyToken();
3739     // Parse ':'
3740     if (Tok.is(tok::colon) || getLangOpts().OpenMP < 50) {
3741       if (Tok.is(tok::colon))
3742         ConsumeAnyToken();
3743       else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown)
3744         Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier";
3745       // Get a defaultmap kind
3746       Arg.push_back(getOpenMPSimpleClauseType(
3747           Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok), getLangOpts()));
3748       KLoc.push_back(Tok.getLocation());
3749       if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3750           Tok.isNot(tok::annot_pragma_openmp_end))
3751         ConsumeAnyToken();
3752     } else {
3753       Arg.push_back(OMPC_DEFAULTMAP_unknown);
3754       KLoc.push_back(SourceLocation());
3755     }
3756   } else if (Kind == OMPC_device) {
3757     // Only target executable directives support extended device construct.
3758     if (isOpenMPTargetExecutionDirective(DKind) && getLangOpts().OpenMP >= 50 &&
3759         NextToken().is(tok::colon)) {
3760       // Parse optional <device modifier> ':'
3761       Arg.push_back(getOpenMPSimpleClauseType(
3762           Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok), getLangOpts()));
3763       KLoc.push_back(Tok.getLocation());
3764       ConsumeAnyToken();
3765       // Parse ':'
3766       ConsumeAnyToken();
3767     } else {
3768       Arg.push_back(OMPC_DEVICE_unknown);
3769       KLoc.emplace_back();
3770     }
3771   } else {
3772     assert(Kind == OMPC_if);
3773     KLoc.push_back(Tok.getLocation());
3774     TentativeParsingAction TPA(*this);
3775     auto DK = parseOpenMPDirectiveKind(*this);
3776     Arg.push_back(DK);
3777     if (DK != OMPD_unknown) {
3778       ConsumeToken();
3779       if (Tok.is(tok::colon) && getLangOpts().OpenMP > 40) {
3780         TPA.Commit();
3781         DelimLoc = ConsumeToken();
3782       } else {
3783         TPA.Revert();
3784         Arg.back() = unsigned(OMPD_unknown);
3785       }
3786     } else {
3787       TPA.Revert();
3788     }
3789   }
3790 
3791   bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) ||
3792                           (Kind == OMPC_dist_schedule && DelimLoc.isValid()) ||
3793                           Kind == OMPC_if || Kind == OMPC_device;
3794   if (NeedAnExpression) {
3795     SourceLocation ELoc = Tok.getLocation();
3796     ExprResult LHS(ParseCastExpression(AnyCastExpr, false, NotTypeCast));
3797     Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
3798     Val =
3799         Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
3800   }
3801 
3802   // Parse ')'.
3803   SourceLocation RLoc = Tok.getLocation();
3804   if (!T.consumeClose())
3805     RLoc = T.getCloseLocation();
3806 
3807   if (NeedAnExpression && Val.isInvalid())
3808     return nullptr;
3809 
3810   if (ParseOnly)
3811     return nullptr;
3812   return Actions.ActOnOpenMPSingleExprWithArgClause(
3813       Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
3814 }
3815 
3816 static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
3817                              UnqualifiedId &ReductionId) {
3818   if (ReductionIdScopeSpec.isEmpty()) {
3819     auto OOK = OO_None;
3820     switch (P.getCurToken().getKind()) {
3821     case tok::plus:
3822       OOK = OO_Plus;
3823       break;
3824     case tok::minus:
3825       OOK = OO_Minus;
3826       break;
3827     case tok::star:
3828       OOK = OO_Star;
3829       break;
3830     case tok::amp:
3831       OOK = OO_Amp;
3832       break;
3833     case tok::pipe:
3834       OOK = OO_Pipe;
3835       break;
3836     case tok::caret:
3837       OOK = OO_Caret;
3838       break;
3839     case tok::ampamp:
3840       OOK = OO_AmpAmp;
3841       break;
3842     case tok::pipepipe:
3843       OOK = OO_PipePipe;
3844       break;
3845     default:
3846       break;
3847     }
3848     if (OOK != OO_None) {
3849       SourceLocation OpLoc = P.ConsumeToken();
3850       SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
3851       ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
3852       return false;
3853     }
3854   }
3855   return P.ParseUnqualifiedId(
3856       ReductionIdScopeSpec, /*ObjectType=*/nullptr,
3857       /*ObjectHadErrors=*/false, /*EnteringContext*/ false,
3858       /*AllowDestructorName*/ false,
3859       /*AllowConstructorName*/ false,
3860       /*AllowDeductionGuide*/ false, nullptr, ReductionId);
3861 }
3862 
3863 /// Checks if the token is a valid map-type-modifier.
3864 /// FIXME: It will return an OpenMPMapClauseKind if that's what it parses.
3865 static OpenMPMapModifierKind isMapModifier(Parser &P) {
3866   Token Tok = P.getCurToken();
3867   if (!Tok.is(tok::identifier))
3868     return OMPC_MAP_MODIFIER_unknown;
3869 
3870   Preprocessor &PP = P.getPreprocessor();
3871   OpenMPMapModifierKind TypeModifier =
3872       static_cast<OpenMPMapModifierKind>(getOpenMPSimpleClauseType(
3873           OMPC_map, PP.getSpelling(Tok), P.getLangOpts()));
3874   return TypeModifier;
3875 }
3876 
3877 /// Parse the mapper modifier in map, to, and from clauses.
3878 bool Parser::parseMapperModifier(OpenMPVarListDataTy &Data) {
3879   // Parse '('.
3880   BalancedDelimiterTracker T(*this, tok::l_paren, tok::colon);
3881   if (T.expectAndConsume(diag::err_expected_lparen_after, "mapper")) {
3882     SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3883               StopBeforeMatch);
3884     return true;
3885   }
3886   // Parse mapper-identifier
3887   if (getLangOpts().CPlusPlus)
3888     ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
3889                                    /*ObjectType=*/nullptr,
3890                                    /*ObjectHasErrors=*/false,
3891                                    /*EnteringContext=*/false);
3892   if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
3893     Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
3894     SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3895               StopBeforeMatch);
3896     return true;
3897   }
3898   auto &DeclNames = Actions.getASTContext().DeclarationNames;
3899   Data.ReductionOrMapperId = DeclarationNameInfo(
3900       DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
3901   ConsumeToken();
3902   // Parse ')'.
3903   return T.consumeClose();
3904 }
3905 
3906 /// Parse map-type-modifiers in map clause.
3907 /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
3908 /// where, map-type-modifier ::= always | close | mapper(mapper-identifier) |
3909 /// present
3910 bool Parser::parseMapTypeModifiers(OpenMPVarListDataTy &Data) {
3911   while (getCurToken().isNot(tok::colon)) {
3912     OpenMPMapModifierKind TypeModifier = isMapModifier(*this);
3913     if (TypeModifier == OMPC_MAP_MODIFIER_always ||
3914         TypeModifier == OMPC_MAP_MODIFIER_close ||
3915         TypeModifier == OMPC_MAP_MODIFIER_present ||
3916         TypeModifier == OMPC_MAP_MODIFIER_ompx_hold) {
3917       Data.MapTypeModifiers.push_back(TypeModifier);
3918       Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
3919       ConsumeToken();
3920     } else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
3921       Data.MapTypeModifiers.push_back(TypeModifier);
3922       Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
3923       ConsumeToken();
3924       if (parseMapperModifier(Data))
3925         return true;
3926     } else {
3927       // For the case of unknown map-type-modifier or a map-type.
3928       // Map-type is followed by a colon; the function returns when it
3929       // encounters a token followed by a colon.
3930       if (Tok.is(tok::comma)) {
3931         Diag(Tok, diag::err_omp_map_type_modifier_missing);
3932         ConsumeToken();
3933         continue;
3934       }
3935       // Potential map-type token as it is followed by a colon.
3936       if (PP.LookAhead(0).is(tok::colon))
3937         return false;
3938       Diag(Tok, diag::err_omp_unknown_map_type_modifier)
3939           << (getLangOpts().OpenMP >= 51 ? 1 : 0)
3940           << getLangOpts().OpenMPExtensions;
3941       ConsumeToken();
3942     }
3943     if (getCurToken().is(tok::comma))
3944       ConsumeToken();
3945   }
3946   return false;
3947 }
3948 
3949 /// Checks if the token is a valid map-type.
3950 /// FIXME: It will return an OpenMPMapModifierKind if that's what it parses.
3951 static OpenMPMapClauseKind isMapType(Parser &P) {
3952   Token Tok = P.getCurToken();
3953   // The map-type token can be either an identifier or the C++ delete keyword.
3954   if (!Tok.isOneOf(tok::identifier, tok::kw_delete))
3955     return OMPC_MAP_unknown;
3956   Preprocessor &PP = P.getPreprocessor();
3957   OpenMPMapClauseKind MapType =
3958       static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType(
3959           OMPC_map, PP.getSpelling(Tok), P.getLangOpts()));
3960   return MapType;
3961 }
3962 
3963 /// Parse map-type in map clause.
3964 /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
3965 /// where, map-type ::= to | from | tofrom | alloc | release | delete
3966 static void parseMapType(Parser &P, Parser::OpenMPVarListDataTy &Data) {
3967   Token Tok = P.getCurToken();
3968   if (Tok.is(tok::colon)) {
3969     P.Diag(Tok, diag::err_omp_map_type_missing);
3970     return;
3971   }
3972   Data.ExtraModifier = isMapType(P);
3973   if (Data.ExtraModifier == OMPC_MAP_unknown)
3974     P.Diag(Tok, diag::err_omp_unknown_map_type);
3975   P.ConsumeToken();
3976 }
3977 
3978 /// Parses simple expression in parens for single-expression clauses of OpenMP
3979 /// constructs.
3980 ExprResult Parser::ParseOpenMPIteratorsExpr() {
3981   assert(Tok.is(tok::identifier) && PP.getSpelling(Tok) == "iterator" &&
3982          "Expected 'iterator' token.");
3983   SourceLocation IteratorKwLoc = ConsumeToken();
3984 
3985   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3986   if (T.expectAndConsume(diag::err_expected_lparen_after, "iterator"))
3987     return ExprError();
3988 
3989   SourceLocation LLoc = T.getOpenLocation();
3990   SmallVector<Sema::OMPIteratorData, 4> Data;
3991   while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
3992     // Check if the type parsing is required.
3993     ParsedType IteratorType;
3994     if (Tok.isNot(tok::identifier) || NextToken().isNot(tok::equal)) {
3995       // identifier '=' is not found - parse type.
3996       TypeResult TR = ParseTypeName();
3997       if (TR.isInvalid()) {
3998         T.skipToEnd();
3999         return ExprError();
4000       }
4001       IteratorType = TR.get();
4002     }
4003 
4004     // Parse identifier.
4005     IdentifierInfo *II = nullptr;
4006     SourceLocation IdLoc;
4007     if (Tok.is(tok::identifier)) {
4008       II = Tok.getIdentifierInfo();
4009       IdLoc = ConsumeToken();
4010     } else {
4011       Diag(Tok, diag::err_expected_unqualified_id) << 0;
4012     }
4013 
4014     // Parse '='.
4015     SourceLocation AssignLoc;
4016     if (Tok.is(tok::equal))
4017       AssignLoc = ConsumeToken();
4018     else
4019       Diag(Tok, diag::err_omp_expected_equal_in_iterator);
4020 
4021     // Parse range-specification - <begin> ':' <end> [ ':' <step> ]
4022     ColonProtectionRAIIObject ColonRAII(*this);
4023     // Parse <begin>
4024     SourceLocation Loc = Tok.getLocation();
4025     ExprResult LHS = ParseCastExpression(AnyCastExpr);
4026     ExprResult Begin = Actions.CorrectDelayedTyposInExpr(
4027         ParseRHSOfBinaryExpression(LHS, prec::Conditional));
4028     Begin = Actions.ActOnFinishFullExpr(Begin.get(), Loc,
4029                                         /*DiscardedValue=*/false);
4030     // Parse ':'.
4031     SourceLocation ColonLoc;
4032     if (Tok.is(tok::colon))
4033       ColonLoc = ConsumeToken();
4034 
4035     // Parse <end>
4036     Loc = Tok.getLocation();
4037     LHS = ParseCastExpression(AnyCastExpr);
4038     ExprResult End = Actions.CorrectDelayedTyposInExpr(
4039         ParseRHSOfBinaryExpression(LHS, prec::Conditional));
4040     End = Actions.ActOnFinishFullExpr(End.get(), Loc,
4041                                       /*DiscardedValue=*/false);
4042 
4043     SourceLocation SecColonLoc;
4044     ExprResult Step;
4045     // Parse optional step.
4046     if (Tok.is(tok::colon)) {
4047       // Parse ':'
4048       SecColonLoc = ConsumeToken();
4049       // Parse <step>
4050       Loc = Tok.getLocation();
4051       LHS = ParseCastExpression(AnyCastExpr);
4052       Step = Actions.CorrectDelayedTyposInExpr(
4053           ParseRHSOfBinaryExpression(LHS, prec::Conditional));
4054       Step = Actions.ActOnFinishFullExpr(Step.get(), Loc,
4055                                          /*DiscardedValue=*/false);
4056     }
4057 
4058     // Parse ',' or ')'
4059     if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
4060       Diag(Tok, diag::err_omp_expected_punc_after_iterator);
4061     if (Tok.is(tok::comma))
4062       ConsumeToken();
4063 
4064     Sema::OMPIteratorData &D = Data.emplace_back();
4065     D.DeclIdent = II;
4066     D.DeclIdentLoc = IdLoc;
4067     D.Type = IteratorType;
4068     D.AssignLoc = AssignLoc;
4069     D.ColonLoc = ColonLoc;
4070     D.SecColonLoc = SecColonLoc;
4071     D.Range.Begin = Begin.get();
4072     D.Range.End = End.get();
4073     D.Range.Step = Step.get();
4074   }
4075 
4076   // Parse ')'.
4077   SourceLocation RLoc = Tok.getLocation();
4078   if (!T.consumeClose())
4079     RLoc = T.getCloseLocation();
4080 
4081   return Actions.ActOnOMPIteratorExpr(getCurScope(), IteratorKwLoc, LLoc, RLoc,
4082                                       Data);
4083 }
4084 
4085 /// Parses clauses with list.
4086 bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
4087                                 OpenMPClauseKind Kind,
4088                                 SmallVectorImpl<Expr *> &Vars,
4089                                 OpenMPVarListDataTy &Data) {
4090   UnqualifiedId UnqualifiedReductionId;
4091   bool InvalidReductionId = false;
4092   bool IsInvalidMapperModifier = false;
4093 
4094   // Parse '('.
4095   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
4096   if (T.expectAndConsume(diag::err_expected_lparen_after,
4097                          getOpenMPClauseName(Kind).data()))
4098     return true;
4099 
4100   bool HasIterator = false;
4101   bool NeedRParenForLinear = false;
4102   BalancedDelimiterTracker LinearT(*this, tok::l_paren,
4103                                    tok::annot_pragma_openmp_end);
4104   // Handle reduction-identifier for reduction clause.
4105   if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
4106       Kind == OMPC_in_reduction) {
4107     Data.ExtraModifier = OMPC_REDUCTION_unknown;
4108     if (Kind == OMPC_reduction && getLangOpts().OpenMP >= 50 &&
4109         (Tok.is(tok::identifier) || Tok.is(tok::kw_default)) &&
4110         NextToken().is(tok::comma)) {
4111       // Parse optional reduction modifier.
4112       Data.ExtraModifier =
4113           getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok), getLangOpts());
4114       Data.ExtraModifierLoc = Tok.getLocation();
4115       ConsumeToken();
4116       assert(Tok.is(tok::comma) && "Expected comma.");
4117       (void)ConsumeToken();
4118     }
4119     ColonProtectionRAIIObject ColonRAII(*this);
4120     if (getLangOpts().CPlusPlus)
4121       ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
4122                                      /*ObjectType=*/nullptr,
4123                                      /*ObjectHasErrors=*/false,
4124                                      /*EnteringContext=*/false);
4125     InvalidReductionId = ParseReductionId(
4126         *this, Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
4127     if (InvalidReductionId) {
4128       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4129                 StopBeforeMatch);
4130     }
4131     if (Tok.is(tok::colon))
4132       Data.ColonLoc = ConsumeToken();
4133     else
4134       Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
4135     if (!InvalidReductionId)
4136       Data.ReductionOrMapperId =
4137           Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
4138   } else if (Kind == OMPC_depend) {
4139     if (getLangOpts().OpenMP >= 50) {
4140       if (Tok.is(tok::identifier) && PP.getSpelling(Tok) == "iterator") {
4141         // Handle optional dependence modifier.
4142         // iterator(iterators-definition)
4143         // where iterators-definition is iterator-specifier [,
4144         // iterators-definition ]
4145         // where iterator-specifier is [ iterator-type ] identifier =
4146         // range-specification
4147         HasIterator = true;
4148         EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope);
4149         ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
4150         Data.DepModOrTailExpr = IteratorRes.get();
4151         // Parse ','
4152         ExpectAndConsume(tok::comma);
4153       }
4154     }
4155     // Handle dependency type for depend clause.
4156     ColonProtectionRAIIObject ColonRAII(*this);
4157     Data.ExtraModifier = getOpenMPSimpleClauseType(
4158         Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : "",
4159         getLangOpts());
4160     Data.ExtraModifierLoc = Tok.getLocation();
4161     if (Data.ExtraModifier == OMPC_DEPEND_unknown) {
4162       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4163                 StopBeforeMatch);
4164     } else {
4165       ConsumeToken();
4166       // Special processing for depend(source) clause.
4167       if (DKind == OMPD_ordered && Data.ExtraModifier == OMPC_DEPEND_source) {
4168         // Parse ')'.
4169         T.consumeClose();
4170         return false;
4171       }
4172     }
4173     if (Tok.is(tok::colon)) {
4174       Data.ColonLoc = ConsumeToken();
4175     } else {
4176       Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
4177                                       : diag::warn_pragma_expected_colon)
4178           << "dependency type";
4179     }
4180   } else if (Kind == OMPC_linear) {
4181     // Try to parse modifier if any.
4182     Data.ExtraModifier = OMPC_LINEAR_val;
4183     if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
4184       Data.ExtraModifier =
4185           getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok), getLangOpts());
4186       Data.ExtraModifierLoc = ConsumeToken();
4187       LinearT.consumeOpen();
4188       NeedRParenForLinear = true;
4189     }
4190   } else if (Kind == OMPC_lastprivate) {
4191     // Try to parse modifier if any.
4192     Data.ExtraModifier = OMPC_LASTPRIVATE_unknown;
4193     // Conditional modifier allowed only in OpenMP 5.0 and not supported in
4194     // distribute and taskloop based directives.
4195     if ((getLangOpts().OpenMP >= 50 && !isOpenMPDistributeDirective(DKind) &&
4196          !isOpenMPTaskLoopDirective(DKind)) &&
4197         Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::colon)) {
4198       Data.ExtraModifier =
4199           getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok), getLangOpts());
4200       Data.ExtraModifierLoc = Tok.getLocation();
4201       ConsumeToken();
4202       assert(Tok.is(tok::colon) && "Expected colon.");
4203       Data.ColonLoc = ConsumeToken();
4204     }
4205   } else if (Kind == OMPC_map) {
4206     // Handle map type for map clause.
4207     ColonProtectionRAIIObject ColonRAII(*this);
4208 
4209     // The first identifier may be a list item, a map-type or a
4210     // map-type-modifier. The map-type can also be delete which has the same
4211     // spelling of the C++ delete keyword.
4212     Data.ExtraModifier = OMPC_MAP_unknown;
4213     Data.ExtraModifierLoc = Tok.getLocation();
4214 
4215     // Check for presence of a colon in the map clause.
4216     TentativeParsingAction TPA(*this);
4217     bool ColonPresent = false;
4218     if (SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4219                   StopBeforeMatch)) {
4220       if (Tok.is(tok::colon))
4221         ColonPresent = true;
4222     }
4223     TPA.Revert();
4224     // Only parse map-type-modifier[s] and map-type if a colon is present in
4225     // the map clause.
4226     if (ColonPresent) {
4227       IsInvalidMapperModifier = parseMapTypeModifiers(Data);
4228       if (!IsInvalidMapperModifier)
4229         parseMapType(*this, Data);
4230       else
4231         SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch);
4232     }
4233     if (Data.ExtraModifier == OMPC_MAP_unknown) {
4234       Data.ExtraModifier = OMPC_MAP_tofrom;
4235       Data.IsMapTypeImplicit = true;
4236     }
4237 
4238     if (Tok.is(tok::colon))
4239       Data.ColonLoc = ConsumeToken();
4240   } else if (Kind == OMPC_to || Kind == OMPC_from) {
4241     while (Tok.is(tok::identifier)) {
4242       auto Modifier = static_cast<OpenMPMotionModifierKind>(
4243           getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok), getLangOpts()));
4244       if (Modifier == OMPC_MOTION_MODIFIER_unknown)
4245         break;
4246       Data.MotionModifiers.push_back(Modifier);
4247       Data.MotionModifiersLoc.push_back(Tok.getLocation());
4248       ConsumeToken();
4249       if (Modifier == OMPC_MOTION_MODIFIER_mapper) {
4250         IsInvalidMapperModifier = parseMapperModifier(Data);
4251         if (IsInvalidMapperModifier)
4252           break;
4253       }
4254       // OpenMP < 5.1 doesn't permit a ',' or additional modifiers.
4255       if (getLangOpts().OpenMP < 51)
4256         break;
4257       // OpenMP 5.1 accepts an optional ',' even if the next character is ':'.
4258       // TODO: Is that intentional?
4259       if (Tok.is(tok::comma))
4260         ConsumeToken();
4261     }
4262     if (!Data.MotionModifiers.empty() && Tok.isNot(tok::colon)) {
4263       if (!IsInvalidMapperModifier) {
4264         if (getLangOpts().OpenMP < 51)
4265           Diag(Tok, diag::warn_pragma_expected_colon) << ")";
4266         else
4267           Diag(Tok, diag::warn_pragma_expected_colon) << "motion modifier";
4268       }
4269       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4270                 StopBeforeMatch);
4271     }
4272     // OpenMP 5.1 permits a ':' even without a preceding modifier.  TODO: Is
4273     // that intentional?
4274     if ((!Data.MotionModifiers.empty() || getLangOpts().OpenMP >= 51) &&
4275         Tok.is(tok::colon))
4276       Data.ColonLoc = ConsumeToken();
4277   } else if (Kind == OMPC_allocate ||
4278              (Kind == OMPC_affinity && Tok.is(tok::identifier) &&
4279               PP.getSpelling(Tok) == "iterator")) {
4280     // Handle optional allocator expression followed by colon delimiter.
4281     ColonProtectionRAIIObject ColonRAII(*this);
4282     TentativeParsingAction TPA(*this);
4283     // OpenMP 5.0, 2.10.1, task Construct.
4284     // where aff-modifier is one of the following:
4285     // iterator(iterators-definition)
4286     ExprResult Tail;
4287     if (Kind == OMPC_allocate) {
4288       Tail = ParseAssignmentExpression();
4289     } else {
4290       HasIterator = true;
4291       EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope);
4292       Tail = ParseOpenMPIteratorsExpr();
4293     }
4294     Tail = Actions.CorrectDelayedTyposInExpr(Tail);
4295     Tail = Actions.ActOnFinishFullExpr(Tail.get(), T.getOpenLocation(),
4296                                        /*DiscardedValue=*/false);
4297     if (Tail.isUsable()) {
4298       if (Tok.is(tok::colon)) {
4299         Data.DepModOrTailExpr = Tail.get();
4300         Data.ColonLoc = ConsumeToken();
4301         TPA.Commit();
4302       } else {
4303         // Colon not found, parse only list of variables.
4304         TPA.Revert();
4305       }
4306     } else {
4307       // Parsing was unsuccessfull, revert and skip to the end of clause or
4308       // directive.
4309       TPA.Revert();
4310       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4311                 StopBeforeMatch);
4312     }
4313   } else if (Kind == OMPC_adjust_args) {
4314     // Handle adjust-op for adjust_args clause.
4315     ColonProtectionRAIIObject ColonRAII(*this);
4316     Data.ExtraModifier = getOpenMPSimpleClauseType(
4317         Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : "",
4318         getLangOpts());
4319     Data.ExtraModifierLoc = Tok.getLocation();
4320     if (Data.ExtraModifier == OMPC_ADJUST_ARGS_unknown) {
4321       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
4322                 StopBeforeMatch);
4323     } else {
4324       ConsumeToken();
4325       if (Tok.is(tok::colon))
4326         Data.ColonLoc = Tok.getLocation();
4327       ExpectAndConsume(tok::colon, diag::warn_pragma_expected_colon,
4328                        "adjust-op");
4329     }
4330   }
4331 
4332   bool IsComma =
4333       (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
4334        Kind != OMPC_in_reduction && Kind != OMPC_depend && Kind != OMPC_map) ||
4335       (Kind == OMPC_reduction && !InvalidReductionId) ||
4336       (Kind == OMPC_map && Data.ExtraModifier != OMPC_MAP_unknown) ||
4337       (Kind == OMPC_depend && Data.ExtraModifier != OMPC_DEPEND_unknown) ||
4338       (Kind == OMPC_adjust_args &&
4339        Data.ExtraModifier != OMPC_ADJUST_ARGS_unknown);
4340   const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
4341   while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
4342                      Tok.isNot(tok::annot_pragma_openmp_end))) {
4343     ParseScope OMPListScope(this, Scope::OpenMPDirectiveScope);
4344     ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
4345     // Parse variable
4346     ExprResult VarExpr =
4347         Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
4348     if (VarExpr.isUsable()) {
4349       Vars.push_back(VarExpr.get());
4350     } else {
4351       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4352                 StopBeforeMatch);
4353     }
4354     // Skip ',' if any
4355     IsComma = Tok.is(tok::comma);
4356     if (IsComma)
4357       ConsumeToken();
4358     else if (Tok.isNot(tok::r_paren) &&
4359              Tok.isNot(tok::annot_pragma_openmp_end) &&
4360              (!MayHaveTail || Tok.isNot(tok::colon)))
4361       Diag(Tok, diag::err_omp_expected_punc)
4362           << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
4363                                    : getOpenMPClauseName(Kind))
4364           << (Kind == OMPC_flush);
4365   }
4366 
4367   // Parse ')' for linear clause with modifier.
4368   if (NeedRParenForLinear)
4369     LinearT.consumeClose();
4370 
4371   // Parse ':' linear-step (or ':' alignment).
4372   const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
4373   if (MustHaveTail) {
4374     Data.ColonLoc = Tok.getLocation();
4375     SourceLocation ELoc = ConsumeToken();
4376     ExprResult Tail = ParseAssignmentExpression();
4377     Tail =
4378         Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false);
4379     if (Tail.isUsable())
4380       Data.DepModOrTailExpr = Tail.get();
4381     else
4382       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
4383                 StopBeforeMatch);
4384   }
4385 
4386   // Parse ')'.
4387   Data.RLoc = Tok.getLocation();
4388   if (!T.consumeClose())
4389     Data.RLoc = T.getCloseLocation();
4390   // Exit from scope when the iterator is used in depend clause.
4391   if (HasIterator)
4392     ExitScope();
4393   return (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
4394          (MustHaveTail && !Data.DepModOrTailExpr) || InvalidReductionId ||
4395          IsInvalidMapperModifier;
4396 }
4397 
4398 /// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
4399 /// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction',
4400 /// 'in_reduction', 'nontemporal', 'exclusive' or 'inclusive'.
4401 ///
4402 ///    private-clause:
4403 ///       'private' '(' list ')'
4404 ///    firstprivate-clause:
4405 ///       'firstprivate' '(' list ')'
4406 ///    lastprivate-clause:
4407 ///       'lastprivate' '(' list ')'
4408 ///    shared-clause:
4409 ///       'shared' '(' list ')'
4410 ///    linear-clause:
4411 ///       'linear' '(' linear-list [ ':' linear-step ] ')'
4412 ///    aligned-clause:
4413 ///       'aligned' '(' list [ ':' alignment ] ')'
4414 ///    reduction-clause:
4415 ///       'reduction' '(' [ modifier ',' ] reduction-identifier ':' list ')'
4416 ///    task_reduction-clause:
4417 ///       'task_reduction' '(' reduction-identifier ':' list ')'
4418 ///    in_reduction-clause:
4419 ///       'in_reduction' '(' reduction-identifier ':' list ')'
4420 ///    copyprivate-clause:
4421 ///       'copyprivate' '(' list ')'
4422 ///    flush-clause:
4423 ///       'flush' '(' list ')'
4424 ///    depend-clause:
4425 ///       'depend' '(' in | out | inout : list | source ')'
4426 ///    map-clause:
4427 ///       'map' '(' [ [ always [,] ] [ close [,] ]
4428 ///          [ mapper '(' mapper-identifier ')' [,] ]
4429 ///          to | from | tofrom | alloc | release | delete ':' ] list ')';
4430 ///    to-clause:
4431 ///       'to' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
4432 ///    from-clause:
4433 ///       'from' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
4434 ///    use_device_ptr-clause:
4435 ///       'use_device_ptr' '(' list ')'
4436 ///    use_device_addr-clause:
4437 ///       'use_device_addr' '(' list ')'
4438 ///    is_device_ptr-clause:
4439 ///       'is_device_ptr' '(' list ')'
4440 ///    allocate-clause:
4441 ///       'allocate' '(' [ allocator ':' ] list ')'
4442 ///    nontemporal-clause:
4443 ///       'nontemporal' '(' list ')'
4444 ///    inclusive-clause:
4445 ///       'inclusive' '(' list ')'
4446 ///    exclusive-clause:
4447 ///       'exclusive' '(' list ')'
4448 ///
4449 /// For 'linear' clause linear-list may have the following forms:
4450 ///  list
4451 ///  modifier(list)
4452 /// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
4453 OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
4454                                             OpenMPClauseKind Kind,
4455                                             bool ParseOnly) {
4456   SourceLocation Loc = Tok.getLocation();
4457   SourceLocation LOpen = ConsumeToken();
4458   SmallVector<Expr *, 4> Vars;
4459   OpenMPVarListDataTy Data;
4460 
4461   if (ParseOpenMPVarList(DKind, Kind, Vars, Data))
4462     return nullptr;
4463 
4464   if (ParseOnly)
4465     return nullptr;
4466   OMPVarListLocTy Locs(Loc, LOpen, Data.RLoc);
4467   return Actions.ActOnOpenMPVarListClause(
4468       Kind, Vars, Data.DepModOrTailExpr, Locs, Data.ColonLoc,
4469       Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId,
4470       Data.ExtraModifier, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
4471       Data.IsMapTypeImplicit, Data.ExtraModifierLoc, Data.MotionModifiers,
4472       Data.MotionModifiersLoc);
4473 }
4474