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