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