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