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