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