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