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   if (TIProperty.Kind ==
939       TraitProperty::implementation_extension_disable_implicit_base)
940     return true;
941 
942   if (TIProperty.Kind ==
943       TraitProperty::implementation_extension_allow_templates)
944     return true;
945 
946   auto IsMatchExtension = [](OMPTraitProperty &TP) {
947     return (TP.Kind ==
948                 llvm::omp::TraitProperty::implementation_extension_match_all ||
949             TP.Kind ==
950                 llvm::omp::TraitProperty::implementation_extension_match_any ||
951             TP.Kind ==
952                 llvm::omp::TraitProperty::implementation_extension_match_none);
953   };
954 
955   if (IsMatchExtension(TIProperty)) {
956     for (OMPTraitProperty &SeenProp : TISelector.Properties)
957       if (IsMatchExtension(SeenProp)) {
958         P.Diag(Loc, diag::err_omp_variant_ctx_second_match_extension);
959         StringRef SeenName = llvm::omp::getOpenMPContextTraitPropertyName(
960             SeenProp.Kind, SeenProp.RawString);
961         SourceLocation SeenLoc = Seen[SeenName];
962         P.Diag(SeenLoc, diag::note_omp_declare_variant_ctx_used_here)
963             << CONTEXT_TRAIT_LVL << SeenName;
964         return false;
965       }
966     return true;
967   }
968 
969   llvm_unreachable("Unknown extension property!");
970 }
971 
972 void Parser::parseOMPContextProperty(OMPTraitSelector &TISelector,
973                                      llvm::omp::TraitSet Set,
974                                      llvm::StringMap<SourceLocation> &Seen) {
975   assert(TISelector.Kind != TraitSelector::user_condition &&
976          "User conditions are special properties not handled here!");
977 
978   SourceLocation PropertyLoc = Tok.getLocation();
979   OMPTraitProperty TIProperty;
980   parseOMPTraitPropertyKind(TIProperty, Set, TISelector.Kind, Seen);
981 
982   if (TISelector.Kind == llvm::omp::TraitSelector::implementation_extension)
983     if (!checkExtensionProperty(*this, Tok.getLocation(), TIProperty,
984                                 TISelector, Seen))
985       TIProperty.Kind = TraitProperty::invalid;
986 
987   // If we have an invalid property here we already issued a warning.
988   if (TIProperty.Kind == TraitProperty::invalid) {
989     if (PropertyLoc != Tok.getLocation())
990       Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
991           << CONTEXT_TRAIT_LVL;
992     return;
993   }
994 
995   if (isValidTraitPropertyForTraitSetAndSelector(TIProperty.Kind,
996                                                  TISelector.Kind, Set)) {
997 
998     // If we make it here the property, selector, set, score, condition, ... are
999     // all valid (or have been corrected). Thus we can record the property.
1000     TISelector.Properties.push_back(TIProperty);
1001     return;
1002   }
1003 
1004   Diag(PropertyLoc, diag::warn_omp_ctx_incompatible_property_for_selector)
1005       << getOpenMPContextTraitPropertyName(TIProperty.Kind,
1006                                            TIProperty.RawString)
1007       << getOpenMPContextTraitSelectorName(TISelector.Kind)
1008       << getOpenMPContextTraitSetName(Set);
1009   Diag(PropertyLoc, diag::note_omp_ctx_compatible_set_and_selector_for_property)
1010       << getOpenMPContextTraitPropertyName(TIProperty.Kind,
1011                                            TIProperty.RawString)
1012       << getOpenMPContextTraitSelectorName(
1013              getOpenMPContextTraitSelectorForProperty(TIProperty.Kind))
1014       << getOpenMPContextTraitSetName(
1015              getOpenMPContextTraitSetForProperty(TIProperty.Kind));
1016   Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1017       << CONTEXT_TRAIT_LVL;
1018 }
1019 
1020 void Parser::parseOMPTraitSelectorKind(
1021     OMPTraitSelector &TISelector, llvm::omp::TraitSet Set,
1022     llvm::StringMap<SourceLocation> &Seen) {
1023   TISelector.Kind = TraitSelector::invalid;
1024 
1025   SourceLocation NameLoc = Tok.getLocation();
1026   StringRef Name = getNameFromIdOrString(*this, Tok, CONTEXT_SELECTOR_LVL
1027                     );
1028   if (Name.empty()) {
1029     Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1030         << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(Set);
1031     return;
1032   }
1033 
1034   TISelector.Kind = getOpenMPContextTraitSelectorKind(Name);
1035   if (TISelector.Kind != TraitSelector::invalid) {
1036     if (checkForDuplicates(*this, Name, NameLoc, Seen, CONTEXT_SELECTOR_LVL))
1037       TISelector.Kind = TraitSelector::invalid;
1038     return;
1039   }
1040 
1041   // It follows diagnosis and helping notes.
1042   Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_selector)
1043       << Name << getOpenMPContextTraitSetName(Set);
1044 
1045   TraitSet SetForName = getOpenMPContextTraitSetKind(Name);
1046   if (SetForName != TraitSet::invalid) {
1047     Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1048         << Name << CONTEXT_SELECTOR_SET_LVL << CONTEXT_SELECTOR_LVL;
1049     Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1050         << Name << "<selector-name>"
1051         << "<property-name>";
1052     return;
1053   }
1054   for (const auto &PotentialSet :
1055        {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1056         TraitSet::device}) {
1057     TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1058         PotentialSet, TraitSelector::invalid, Name);
1059     if (PropertyForName == TraitProperty::invalid)
1060       continue;
1061     Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1062         << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_LVL;
1063     Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1064         << getOpenMPContextTraitSetName(
1065                getOpenMPContextTraitSetForProperty(PropertyForName))
1066         << getOpenMPContextTraitSelectorName(
1067                getOpenMPContextTraitSelectorForProperty(PropertyForName))
1068         << ("(" + Name + ")").str();
1069     return;
1070   }
1071   Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1072       << CONTEXT_SELECTOR_LVL << listOpenMPContextTraitSelectors(Set);
1073 }
1074 
1075 /// Parse optional 'score' '(' <expr> ')' ':'.
1076 static ExprResult parseContextScore(Parser &P) {
1077   ExprResult ScoreExpr;
1078   llvm::SmallString<16> Buffer;
1079   StringRef SelectorName =
1080       P.getPreprocessor().getSpelling(P.getCurToken(), Buffer);
1081   if (!SelectorName.equals("score"))
1082     return ScoreExpr;
1083   (void)P.ConsumeToken();
1084   SourceLocation RLoc;
1085   ScoreExpr = P.ParseOpenMPParensExpr(SelectorName, RLoc);
1086   // Parse ':'
1087   if (P.getCurToken().is(tok::colon))
1088     (void)P.ConsumeAnyToken();
1089   else
1090     P.Diag(P.getCurToken(), diag::warn_omp_declare_variant_expected)
1091         << "':'"
1092         << "score expression";
1093   return ScoreExpr;
1094 }
1095 
1096 /// Parses an OpenMP context selector.
1097 ///
1098 /// <trait-selector-name> ['('[<trait-score>] <trait-property> [, <t-p>]* ')']
1099 void Parser::parseOMPContextSelector(
1100     OMPTraitSelector &TISelector, llvm::omp::TraitSet Set,
1101     llvm::StringMap<SourceLocation> &SeenSelectors) {
1102   unsigned short OuterPC = ParenCount;
1103 
1104   // If anything went wrong we issue an error or warning and then skip the rest
1105   // of the selector. However, commas are ambiguous so we look for the nesting
1106   // of parentheses here as well.
1107   auto FinishSelector = [OuterPC, this]() -> void {
1108     bool Done = false;
1109     while (!Done) {
1110       while (!SkipUntil({tok::r_brace, tok::r_paren, tok::comma,
1111                          tok::annot_pragma_openmp_end},
1112                         StopBeforeMatch))
1113         ;
1114       if (Tok.is(tok::r_paren) && OuterPC > ParenCount)
1115         (void)ConsumeParen();
1116       if (OuterPC <= ParenCount) {
1117         Done = true;
1118         break;
1119       }
1120       if (!Tok.is(tok::comma) && !Tok.is(tok::r_paren)) {
1121         Done = true;
1122         break;
1123       }
1124       (void)ConsumeAnyToken();
1125     }
1126     Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1127         << CONTEXT_SELECTOR_LVL;
1128   };
1129 
1130   SourceLocation SelectorLoc = Tok.getLocation();
1131   parseOMPTraitSelectorKind(TISelector, Set, SeenSelectors);
1132   if (TISelector.Kind == TraitSelector::invalid)
1133     return FinishSelector();
1134 
1135   bool AllowsTraitScore = false;
1136   bool RequiresProperty = false;
1137   if (!isValidTraitSelectorForTraitSet(TISelector.Kind, Set, AllowsTraitScore,
1138                                        RequiresProperty)) {
1139     Diag(SelectorLoc, diag::warn_omp_ctx_incompatible_selector_for_set)
1140         << getOpenMPContextTraitSelectorName(TISelector.Kind)
1141         << getOpenMPContextTraitSetName(Set);
1142     Diag(SelectorLoc, diag::note_omp_ctx_compatible_set_for_selector)
1143         << getOpenMPContextTraitSelectorName(TISelector.Kind)
1144         << getOpenMPContextTraitSetName(
1145                getOpenMPContextTraitSetForSelector(TISelector.Kind))
1146         << RequiresProperty;
1147     return FinishSelector();
1148   }
1149 
1150   if (!RequiresProperty) {
1151     TISelector.Properties.push_back(
1152         {getOpenMPContextTraitPropertyForSelector(TISelector.Kind),
1153          getOpenMPContextTraitSelectorName(TISelector.Kind)});
1154     return;
1155   }
1156 
1157   if (!Tok.is(tok::l_paren)) {
1158     Diag(SelectorLoc, diag::warn_omp_ctx_selector_without_properties)
1159         << getOpenMPContextTraitSelectorName(TISelector.Kind)
1160         << getOpenMPContextTraitSetName(Set);
1161     return FinishSelector();
1162   }
1163 
1164   if (TISelector.Kind == TraitSelector::user_condition) {
1165     SourceLocation RLoc;
1166     ExprResult Condition = ParseOpenMPParensExpr("user condition", RLoc);
1167     if (!Condition.isUsable())
1168       return FinishSelector();
1169     TISelector.ScoreOrCondition = Condition.get();
1170     TISelector.Properties.push_back(
1171         {TraitProperty::user_condition_unknown, "<condition>"});
1172     return;
1173   }
1174 
1175   BalancedDelimiterTracker BDT(*this, tok::l_paren,
1176                                tok::annot_pragma_openmp_end);
1177   // Parse '('.
1178   (void)BDT.consumeOpen();
1179 
1180   SourceLocation ScoreLoc = Tok.getLocation();
1181   ExprResult Score = parseContextScore(*this);
1182 
1183   if (!AllowsTraitScore && !Score.isUnset()) {
1184     if (Score.isUsable()) {
1185       Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1186           << getOpenMPContextTraitSelectorName(TISelector.Kind)
1187           << getOpenMPContextTraitSetName(Set) << Score.get();
1188     } else {
1189       Diag(ScoreLoc, diag::warn_omp_ctx_incompatible_score_for_property)
1190           << getOpenMPContextTraitSelectorName(TISelector.Kind)
1191           << getOpenMPContextTraitSetName(Set) << "<invalid>";
1192     }
1193     Score = ExprResult();
1194   }
1195 
1196   if (Score.isUsable())
1197     TISelector.ScoreOrCondition = Score.get();
1198 
1199   llvm::StringMap<SourceLocation> SeenProperties;
1200   do {
1201     parseOMPContextProperty(TISelector, Set, SeenProperties);
1202   } while (TryConsumeToken(tok::comma));
1203 
1204   // Parse ')'.
1205   BDT.consumeClose();
1206 }
1207 
1208 void Parser::parseOMPTraitSetKind(OMPTraitSet &TISet,
1209                                   llvm::StringMap<SourceLocation> &Seen) {
1210   TISet.Kind = TraitSet::invalid;
1211 
1212   SourceLocation NameLoc = Tok.getLocation();
1213   StringRef Name = getNameFromIdOrString(*this, Tok, CONTEXT_SELECTOR_SET_LVL
1214                    );
1215   if (Name.empty()) {
1216     Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_options)
1217         << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1218     return;
1219   }
1220 
1221   TISet.Kind = getOpenMPContextTraitSetKind(Name);
1222   if (TISet.Kind != TraitSet::invalid) {
1223     if (checkForDuplicates(*this, Name, NameLoc, Seen,
1224                            CONTEXT_SELECTOR_SET_LVL))
1225       TISet.Kind = TraitSet::invalid;
1226     return;
1227   }
1228 
1229   // It follows diagnosis and helping notes.
1230   Diag(NameLoc, diag::warn_omp_declare_variant_ctx_not_a_set) << Name;
1231 
1232   TraitSelector SelectorForName = getOpenMPContextTraitSelectorKind(Name);
1233   if (SelectorForName != TraitSelector::invalid) {
1234     Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1235         << Name << CONTEXT_SELECTOR_LVL << CONTEXT_SELECTOR_SET_LVL;
1236     bool AllowsTraitScore = false;
1237     bool RequiresProperty = false;
1238     isValidTraitSelectorForTraitSet(
1239         SelectorForName, getOpenMPContextTraitSetForSelector(SelectorForName),
1240         AllowsTraitScore, RequiresProperty);
1241     Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1242         << getOpenMPContextTraitSetName(
1243                getOpenMPContextTraitSetForSelector(SelectorForName))
1244         << Name << (RequiresProperty ? "(<property-name>)" : "");
1245     return;
1246   }
1247   for (const auto &PotentialSet :
1248        {TraitSet::construct, TraitSet::user, TraitSet::implementation,
1249         TraitSet::device}) {
1250     TraitProperty PropertyForName = getOpenMPContextTraitPropertyKind(
1251         PotentialSet, TraitSelector::invalid, Name);
1252     if (PropertyForName == TraitProperty::invalid)
1253       continue;
1254     Diag(NameLoc, diag::note_omp_declare_variant_ctx_is_a)
1255         << Name << CONTEXT_TRAIT_LVL << CONTEXT_SELECTOR_SET_LVL;
1256     Diag(NameLoc, diag::note_omp_declare_variant_ctx_try)
1257         << getOpenMPContextTraitSetName(
1258                getOpenMPContextTraitSetForProperty(PropertyForName))
1259         << getOpenMPContextTraitSelectorName(
1260                getOpenMPContextTraitSelectorForProperty(PropertyForName))
1261         << ("(" + Name + ")").str();
1262     return;
1263   }
1264   Diag(NameLoc, diag::note_omp_declare_variant_ctx_options)
1265       << CONTEXT_SELECTOR_SET_LVL << listOpenMPContextTraitSets();
1266 }
1267 
1268 /// Parses an OpenMP context selector set.
1269 ///
1270 /// <trait-set-selector-name> '=' '{' <trait-selector> [, <trait-selector>]* '}'
1271 void Parser::parseOMPContextSelectorSet(
1272     OMPTraitSet &TISet,
1273     llvm::StringMap<SourceLocation> &SeenSets) {
1274   auto OuterBC = BraceCount;
1275 
1276   // If anything went wrong we issue an error or warning and then skip the rest
1277   // of the set. However, commas are ambiguous so we look for the nesting
1278   // of braces here as well.
1279   auto FinishSelectorSet = [this, OuterBC]() -> void {
1280     bool Done = false;
1281     while (!Done) {
1282       while (!SkipUntil({tok::comma, tok::r_brace, tok::r_paren,
1283                          tok::annot_pragma_openmp_end},
1284                         StopBeforeMatch))
1285         ;
1286       if (Tok.is(tok::r_brace) && OuterBC > BraceCount)
1287         (void)ConsumeBrace();
1288       if (OuterBC <= BraceCount) {
1289         Done = true;
1290         break;
1291       }
1292       if (!Tok.is(tok::comma) && !Tok.is(tok::r_brace)) {
1293         Done = true;
1294         break;
1295       }
1296       (void)ConsumeAnyToken();
1297     }
1298     Diag(Tok.getLocation(), diag::note_omp_declare_variant_ctx_continue_here)
1299         << CONTEXT_SELECTOR_SET_LVL;
1300   };
1301 
1302   parseOMPTraitSetKind(TISet, SeenSets);
1303   if (TISet.Kind == TraitSet::invalid)
1304     return FinishSelectorSet();
1305 
1306   // Parse '='.
1307   if (!TryConsumeToken(tok::equal))
1308     Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1309         << "="
1310         << ("context set name \"" + getOpenMPContextTraitSetName(TISet.Kind) +
1311             "\"")
1312                .str();
1313 
1314   // Parse '{'.
1315   if (Tok.is(tok::l_brace)) {
1316     (void)ConsumeBrace();
1317   } else {
1318     Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1319         << "{"
1320         << ("'=' that follows the context set name \"" +
1321             getOpenMPContextTraitSetName(TISet.Kind) + "\"")
1322                .str();
1323   }
1324 
1325   llvm::StringMap<SourceLocation> SeenSelectors;
1326   do {
1327     OMPTraitSelector TISelector;
1328     parseOMPContextSelector(TISelector, TISet.Kind, SeenSelectors);
1329     if (TISelector.Kind != TraitSelector::invalid &&
1330         !TISelector.Properties.empty())
1331       TISet.Selectors.push_back(TISelector);
1332   } while (TryConsumeToken(tok::comma));
1333 
1334   // Parse '}'.
1335   if (Tok.is(tok::r_brace)) {
1336     (void)ConsumeBrace();
1337   } else {
1338     Diag(Tok.getLocation(), diag::warn_omp_declare_variant_expected)
1339         << "}"
1340         << ("context selectors for the context set \"" +
1341             getOpenMPContextTraitSetName(TISet.Kind) + "\"")
1342                .str();
1343   }
1344 }
1345 
1346 /// Parse OpenMP context selectors:
1347 ///
1348 /// <trait-set-selector> [, <trait-set-selector>]*
1349 bool Parser::parseOMPContextSelectors(SourceLocation Loc, OMPTraitInfo& TI) {
1350   llvm::StringMap<SourceLocation> SeenSets;
1351   do {
1352     OMPTraitSet TISet;
1353     parseOMPContextSelectorSet(TISet, SeenSets);
1354     if (TISet.Kind != TraitSet::invalid && !TISet.Selectors.empty())
1355       TI.Sets.push_back(TISet);
1356   } while (TryConsumeToken(tok::comma));
1357 
1358   return false;
1359 }
1360 
1361 /// Parse clauses for '#pragma omp declare variant ( variant-func-id ) clause'.
1362 void Parser::ParseOMPDeclareVariantClauses(Parser::DeclGroupPtrTy Ptr,
1363                                            CachedTokens &Toks,
1364                                            SourceLocation Loc) {
1365   PP.EnterToken(Tok, /*IsReinject*/ true);
1366   PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
1367                       /*IsReinject*/ true);
1368   // Consume the previously pushed token.
1369   ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
1370   ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
1371 
1372   FNContextRAII FnContext(*this, Ptr);
1373   // Parse function declaration id.
1374   SourceLocation RLoc;
1375   // Parse with IsAddressOfOperand set to true to parse methods as DeclRefExprs
1376   // instead of MemberExprs.
1377   ExprResult AssociatedFunction;
1378   {
1379     // Do not mark function as is used to prevent its emission if this is the
1380     // only place where it is used.
1381     EnterExpressionEvaluationContext Unevaluated(
1382         Actions, Sema::ExpressionEvaluationContext::Unevaluated);
1383     AssociatedFunction = ParseOpenMPParensExpr(
1384         getOpenMPDirectiveName(OMPD_declare_variant), RLoc,
1385         /*IsAddressOfOperand=*/true);
1386   }
1387   if (!AssociatedFunction.isUsable()) {
1388     if (!Tok.is(tok::annot_pragma_openmp_end))
1389       while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch))
1390         ;
1391     // Skip the last annot_pragma_openmp_end.
1392     (void)ConsumeAnnotationToken();
1393     return;
1394   }
1395 
1396   OMPTraitInfo *ParentTI = Actions.getOMPTraitInfoForSurroundingScope();
1397   ASTContext &ASTCtx = Actions.getASTContext();
1398   OMPTraitInfo &TI = ASTCtx.getNewOMPTraitInfo();
1399   if (parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI))
1400     return;
1401 
1402   Optional<std::pair<FunctionDecl *, Expr *>> DeclVarData =
1403       Actions.checkOpenMPDeclareVariantFunction(
1404           Ptr, AssociatedFunction.get(), TI,
1405           SourceRange(Loc, Tok.getLocation()));
1406 
1407   // Skip last tokens.
1408   while (Tok.isNot(tok::annot_pragma_openmp_end))
1409     ConsumeAnyToken();
1410   if (DeclVarData && !TI.Sets.empty())
1411     Actions.ActOnOpenMPDeclareVariantDirective(
1412         DeclVarData->first, DeclVarData->second, TI,
1413         SourceRange(Loc, Tok.getLocation()));
1414 
1415   // Skip the last annot_pragma_openmp_end.
1416   (void)ConsumeAnnotationToken();
1417 }
1418 
1419 bool Parser::parseOMPDeclareVariantMatchClause(SourceLocation Loc,
1420                                                OMPTraitInfo &TI,
1421                                                OMPTraitInfo *ParentTI) {
1422   // Parse 'match'.
1423   OpenMPClauseKind CKind = Tok.isAnnotation()
1424                                ? OMPC_unknown
1425                                : getOpenMPClauseKind(PP.getSpelling(Tok));
1426   if (CKind != OMPC_match) {
1427     Diag(Tok.getLocation(), diag::err_omp_declare_variant_wrong_clause)
1428         << getOpenMPClauseName(OMPC_match);
1429     while (!SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch))
1430       ;
1431     // Skip the last annot_pragma_openmp_end.
1432     (void)ConsumeAnnotationToken();
1433     return true;
1434   }
1435   (void)ConsumeToken();
1436   // Parse '('.
1437   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1438   if (T.expectAndConsume(diag::err_expected_lparen_after,
1439                          getOpenMPClauseName(OMPC_match).data())) {
1440     while (!SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch))
1441       ;
1442     // Skip the last annot_pragma_openmp_end.
1443     (void)ConsumeAnnotationToken();
1444     return true;
1445   }
1446 
1447   // Parse inner context selectors.
1448   parseOMPContextSelectors(Loc, TI);
1449 
1450   // Parse ')'
1451   (void)T.consumeClose();
1452 
1453   if (!ParentTI)
1454     return false;
1455 
1456   // Merge the parent/outer trait info into the one we just parsed and diagnose
1457   // problems.
1458   // TODO: Keep some source location in the TI to provide better diagnostics.
1459   // TODO: Perform some kind of equivalence check on the condition and score
1460   //       expressions.
1461   for (const OMPTraitSet &ParentSet : ParentTI->Sets) {
1462     bool MergedSet = false;
1463     for (OMPTraitSet &Set : TI.Sets) {
1464       if (Set.Kind != ParentSet.Kind)
1465         continue;
1466       MergedSet = true;
1467       for (const OMPTraitSelector &ParentSelector : ParentSet.Selectors) {
1468         bool MergedSelector = false;
1469         for (OMPTraitSelector &Selector : Set.Selectors) {
1470           if (Selector.Kind != ParentSelector.Kind)
1471             continue;
1472           MergedSelector = true;
1473           for (const OMPTraitProperty &ParentProperty :
1474                ParentSelector.Properties) {
1475             bool MergedProperty = false;
1476             for (OMPTraitProperty &Property : Selector.Properties) {
1477               // Ignore "equivalent" properties.
1478               if (Property.Kind != ParentProperty.Kind)
1479                 continue;
1480 
1481               // If the kind is the same but the raw string not, we don't want
1482               // to skip out on the property.
1483               MergedProperty |= Property.RawString == ParentProperty.RawString;
1484 
1485               if (Property.RawString == ParentProperty.RawString &&
1486                   Selector.ScoreOrCondition == ParentSelector.ScoreOrCondition)
1487                 continue;
1488 
1489               if (Selector.Kind == llvm::omp::TraitSelector::user_condition) {
1490                 Diag(Loc, diag::err_omp_declare_variant_nested_user_condition);
1491               } else if (Selector.ScoreOrCondition !=
1492                          ParentSelector.ScoreOrCondition) {
1493                 Diag(Loc, diag::err_omp_declare_variant_duplicate_nested_trait)
1494                     << getOpenMPContextTraitPropertyName(
1495                            ParentProperty.Kind, ParentProperty.RawString)
1496                     << getOpenMPContextTraitSelectorName(ParentSelector.Kind)
1497                     << getOpenMPContextTraitSetName(ParentSet.Kind);
1498               }
1499             }
1500             if (!MergedProperty)
1501               Selector.Properties.push_back(ParentProperty);
1502           }
1503         }
1504         if (!MergedSelector)
1505           Set.Selectors.push_back(ParentSelector);
1506       }
1507     }
1508     if (!MergedSet)
1509       TI.Sets.push_back(ParentSet);
1510   }
1511 
1512   return false;
1513 }
1514 
1515 /// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
1516 ///
1517 ///    default-clause:
1518 ///         'default' '(' 'none' | 'shared'  | 'firstprivate' ')
1519 ///
1520 ///    proc_bind-clause:
1521 ///         'proc_bind' '(' 'master' | 'close' | 'spread' ')
1522 ///
1523 ///    device_type-clause:
1524 ///         'device_type' '(' 'host' | 'nohost' | 'any' )'
1525 namespace {
1526   struct SimpleClauseData {
1527     unsigned Type;
1528     SourceLocation Loc;
1529     SourceLocation LOpen;
1530     SourceLocation TypeLoc;
1531     SourceLocation RLoc;
1532     SimpleClauseData(unsigned Type, SourceLocation Loc, SourceLocation LOpen,
1533                      SourceLocation TypeLoc, SourceLocation RLoc)
1534         : Type(Type), Loc(Loc), LOpen(LOpen), TypeLoc(TypeLoc), RLoc(RLoc) {}
1535   };
1536 } // anonymous namespace
1537 
1538 static Optional<SimpleClauseData>
1539 parseOpenMPSimpleClause(Parser &P, OpenMPClauseKind Kind) {
1540   const Token &Tok = P.getCurToken();
1541   SourceLocation Loc = Tok.getLocation();
1542   SourceLocation LOpen = P.ConsumeToken();
1543   // Parse '('.
1544   BalancedDelimiterTracker T(P, tok::l_paren, tok::annot_pragma_openmp_end);
1545   if (T.expectAndConsume(diag::err_expected_lparen_after,
1546                          getOpenMPClauseName(Kind).data()))
1547     return llvm::None;
1548 
1549   unsigned Type = getOpenMPSimpleClauseType(
1550       Kind, Tok.isAnnotation() ? "" : P.getPreprocessor().getSpelling(Tok),
1551       P.getLangOpts().OpenMP);
1552   SourceLocation TypeLoc = Tok.getLocation();
1553   if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1554       Tok.isNot(tok::annot_pragma_openmp_end))
1555     P.ConsumeAnyToken();
1556 
1557   // Parse ')'.
1558   SourceLocation RLoc = Tok.getLocation();
1559   if (!T.consumeClose())
1560     RLoc = T.getCloseLocation();
1561 
1562   return SimpleClauseData(Type, Loc, LOpen, TypeLoc, RLoc);
1563 }
1564 
1565 Parser::DeclGroupPtrTy Parser::ParseOMPDeclareTargetClauses() {
1566   // OpenMP 4.5 syntax with list of entities.
1567   Sema::NamedDeclSetType SameDirectiveDecls;
1568   SmallVector<std::tuple<OMPDeclareTargetDeclAttr::MapTypeTy, SourceLocation,
1569                          NamedDecl *>,
1570               4>
1571       DeclareTargetDecls;
1572   OMPDeclareTargetDeclAttr::DevTypeTy DT = OMPDeclareTargetDeclAttr::DT_Any;
1573   SourceLocation DeviceTypeLoc;
1574   while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1575     OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
1576     if (Tok.is(tok::identifier)) {
1577       IdentifierInfo *II = Tok.getIdentifierInfo();
1578       StringRef ClauseName = II->getName();
1579       bool IsDeviceTypeClause =
1580           getLangOpts().OpenMP >= 50 &&
1581           getOpenMPClauseKind(ClauseName) == OMPC_device_type;
1582       // Parse 'to|link|device_type' clauses.
1583       if (!OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT) &&
1584           !IsDeviceTypeClause) {
1585         Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
1586             << ClauseName << (getLangOpts().OpenMP >= 50 ? 1 : 0);
1587         break;
1588       }
1589       // Parse 'device_type' clause and go to next clause if any.
1590       if (IsDeviceTypeClause) {
1591         Optional<SimpleClauseData> DevTypeData =
1592             parseOpenMPSimpleClause(*this, OMPC_device_type);
1593         if (DevTypeData.hasValue()) {
1594           if (DeviceTypeLoc.isValid()) {
1595             // We already saw another device_type clause, diagnose it.
1596             Diag(DevTypeData.getValue().Loc,
1597                  diag::warn_omp_more_one_device_type_clause);
1598           }
1599           switch(static_cast<OpenMPDeviceType>(DevTypeData.getValue().Type)) {
1600           case OMPC_DEVICE_TYPE_any:
1601             DT = OMPDeclareTargetDeclAttr::DT_Any;
1602             break;
1603           case OMPC_DEVICE_TYPE_host:
1604             DT = OMPDeclareTargetDeclAttr::DT_Host;
1605             break;
1606           case OMPC_DEVICE_TYPE_nohost:
1607             DT = OMPDeclareTargetDeclAttr::DT_NoHost;
1608             break;
1609           case OMPC_DEVICE_TYPE_unknown:
1610             llvm_unreachable("Unexpected device_type");
1611           }
1612           DeviceTypeLoc = DevTypeData.getValue().Loc;
1613         }
1614         continue;
1615       }
1616       ConsumeToken();
1617     }
1618     auto &&Callback = [this, MT, &DeclareTargetDecls, &SameDirectiveDecls](
1619                           CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
1620       NamedDecl *ND = Actions.lookupOpenMPDeclareTargetName(
1621           getCurScope(), SS, NameInfo, SameDirectiveDecls);
1622       if (ND)
1623         DeclareTargetDecls.emplace_back(MT, NameInfo.getLoc(), ND);
1624     };
1625     if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
1626                                  /*AllowScopeSpecifier=*/true))
1627       break;
1628 
1629     // Consume optional ','.
1630     if (Tok.is(tok::comma))
1631       ConsumeToken();
1632   }
1633   SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1634   ConsumeAnyToken();
1635   for (auto &MTLocDecl : DeclareTargetDecls) {
1636     OMPDeclareTargetDeclAttr::MapTypeTy MT;
1637     SourceLocation Loc;
1638     NamedDecl *ND;
1639     std::tie(MT, Loc, ND) = MTLocDecl;
1640     // device_type clause is applied only to functions.
1641     Actions.ActOnOpenMPDeclareTargetName(
1642         ND, Loc, MT, isa<VarDecl>(ND) ? OMPDeclareTargetDeclAttr::DT_Any : DT);
1643   }
1644   SmallVector<Decl *, 4> Decls(SameDirectiveDecls.begin(),
1645                                SameDirectiveDecls.end());
1646   if (Decls.empty())
1647     return DeclGroupPtrTy();
1648   return Actions.BuildDeclaratorGroup(Decls);
1649 }
1650 
1651 void Parser::skipUntilPragmaOpenMPEnd(OpenMPDirectiveKind DKind) {
1652   // The last seen token is annot_pragma_openmp_end - need to check for
1653   // extra tokens.
1654   if (Tok.is(tok::annot_pragma_openmp_end))
1655     return;
1656 
1657   Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1658       << getOpenMPDirectiveName(DKind);
1659   while (Tok.isNot(tok::annot_pragma_openmp_end))
1660     ConsumeAnyToken();
1661 }
1662 
1663 void Parser::parseOMPEndDirective(OpenMPDirectiveKind BeginKind,
1664                                   OpenMPDirectiveKind ExpectedKind,
1665                                   OpenMPDirectiveKind FoundKind,
1666                                   SourceLocation BeginLoc,
1667                                   SourceLocation FoundLoc,
1668                                   bool SkipUntilOpenMPEnd) {
1669   int DiagSelection = ExpectedKind == OMPD_end_declare_target ? 0 : 1;
1670 
1671   if (FoundKind == ExpectedKind) {
1672     ConsumeAnyToken();
1673     skipUntilPragmaOpenMPEnd(ExpectedKind);
1674     return;
1675   }
1676 
1677   Diag(FoundLoc, diag::err_expected_end_declare_target_or_variant)
1678       << DiagSelection;
1679   Diag(BeginLoc, diag::note_matching)
1680       << ("'#pragma omp " + getOpenMPDirectiveName(BeginKind) + "'").str();
1681   if (SkipUntilOpenMPEnd)
1682     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1683 }
1684 
1685 void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind DKind,
1686                                                SourceLocation DKLoc) {
1687   parseOMPEndDirective(OMPD_declare_target, OMPD_end_declare_target, DKind,
1688                        DKLoc, Tok.getLocation(),
1689                        /* SkipUntilOpenMPEnd */ false);
1690   // Skip the last annot_pragma_openmp_end.
1691   if (Tok.is(tok::annot_pragma_openmp_end))
1692     ConsumeAnnotationToken();
1693 }
1694 
1695 /// Parsing of declarative OpenMP directives.
1696 ///
1697 ///       threadprivate-directive:
1698 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
1699 ///         annot_pragma_openmp_end
1700 ///
1701 ///       allocate-directive:
1702 ///         annot_pragma_openmp 'allocate' simple-variable-list [<clause>]
1703 ///         annot_pragma_openmp_end
1704 ///
1705 ///       declare-reduction-directive:
1706 ///        annot_pragma_openmp 'declare' 'reduction' [...]
1707 ///        annot_pragma_openmp_end
1708 ///
1709 ///       declare-mapper-directive:
1710 ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
1711 ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
1712 ///         annot_pragma_openmp_end
1713 ///
1714 ///       declare-simd-directive:
1715 ///         annot_pragma_openmp 'declare simd' {<clause> [,]}
1716 ///         annot_pragma_openmp_end
1717 ///         <function declaration/definition>
1718 ///
1719 ///       requires directive:
1720 ///         annot_pragma_openmp 'requires' <clause> [[[,] <clause>] ... ]
1721 ///         annot_pragma_openmp_end
1722 ///
1723 Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
1724     AccessSpecifier &AS, ParsedAttributesWithRange &Attrs, bool Delayed,
1725     DeclSpec::TST TagType, Decl *Tag) {
1726   assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
1727   ParsingOpenMPDirectiveRAII DirScope(*this);
1728   ParenBraceBracketBalancer BalancerRAIIObj(*this);
1729 
1730   SourceLocation Loc;
1731   OpenMPDirectiveKind DKind;
1732   if (Delayed) {
1733     TentativeParsingAction TPA(*this);
1734     Loc = ConsumeAnnotationToken();
1735     DKind = parseOpenMPDirectiveKind(*this);
1736     if (DKind == OMPD_declare_reduction || DKind == OMPD_declare_mapper) {
1737       // Need to delay parsing until completion of the parent class.
1738       TPA.Revert();
1739       CachedTokens Toks;
1740       unsigned Cnt = 1;
1741       Toks.push_back(Tok);
1742       while (Cnt && Tok.isNot(tok::eof)) {
1743         (void)ConsumeAnyToken();
1744         if (Tok.is(tok::annot_pragma_openmp))
1745           ++Cnt;
1746         else if (Tok.is(tok::annot_pragma_openmp_end))
1747           --Cnt;
1748         Toks.push_back(Tok);
1749       }
1750       // Skip last annot_pragma_openmp_end.
1751       if (Cnt == 0)
1752         (void)ConsumeAnyToken();
1753       auto *LP = new LateParsedPragma(this, AS);
1754       LP->takeToks(Toks);
1755       getCurrentClass().LateParsedDeclarations.push_back(LP);
1756       return nullptr;
1757     }
1758     TPA.Commit();
1759   } else {
1760     Loc = ConsumeAnnotationToken();
1761     DKind = parseOpenMPDirectiveKind(*this);
1762   }
1763 
1764   switch (DKind) {
1765   case OMPD_threadprivate: {
1766     ConsumeToken();
1767     DeclDirectiveListParserHelper Helper(this, DKind);
1768     if (!ParseOpenMPSimpleVarList(DKind, Helper,
1769                                   /*AllowScopeSpecifier=*/true)) {
1770       skipUntilPragmaOpenMPEnd(DKind);
1771       // Skip the last annot_pragma_openmp_end.
1772       ConsumeAnnotationToken();
1773       return Actions.ActOnOpenMPThreadprivateDirective(Loc,
1774                                                        Helper.getIdentifiers());
1775     }
1776     break;
1777   }
1778   case OMPD_allocate: {
1779     ConsumeToken();
1780     DeclDirectiveListParserHelper Helper(this, DKind);
1781     if (!ParseOpenMPSimpleVarList(DKind, Helper,
1782                                   /*AllowScopeSpecifier=*/true)) {
1783       SmallVector<OMPClause *, 1> Clauses;
1784       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1785         SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
1786                     llvm::omp::Clause_enumSize + 1>
1787             FirstClauses(llvm::omp::Clause_enumSize + 1);
1788         while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1789           OpenMPClauseKind CKind =
1790               Tok.isAnnotation() ? OMPC_unknown
1791                                  : getOpenMPClauseKind(PP.getSpelling(Tok));
1792           Actions.StartOpenMPClause(CKind);
1793           OMPClause *Clause = ParseOpenMPClause(
1794               OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt());
1795           SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1796                     StopBeforeMatch);
1797           FirstClauses[unsigned(CKind)].setInt(true);
1798           if (Clause != nullptr)
1799             Clauses.push_back(Clause);
1800           if (Tok.is(tok::annot_pragma_openmp_end)) {
1801             Actions.EndOpenMPClause();
1802             break;
1803           }
1804           // Skip ',' if any.
1805           if (Tok.is(tok::comma))
1806             ConsumeToken();
1807           Actions.EndOpenMPClause();
1808         }
1809         skipUntilPragmaOpenMPEnd(DKind);
1810       }
1811       // Skip the last annot_pragma_openmp_end.
1812       ConsumeAnnotationToken();
1813       return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers(),
1814                                                   Clauses);
1815     }
1816     break;
1817   }
1818   case OMPD_requires: {
1819     SourceLocation StartLoc = ConsumeToken();
1820     SmallVector<OMPClause *, 5> Clauses;
1821     SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
1822                 llvm::omp::Clause_enumSize + 1>
1823         FirstClauses(llvm::omp::Clause_enumSize + 1);
1824     if (Tok.is(tok::annot_pragma_openmp_end)) {
1825       Diag(Tok, diag::err_omp_expected_clause)
1826           << getOpenMPDirectiveName(OMPD_requires);
1827       break;
1828     }
1829     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1830       OpenMPClauseKind CKind = Tok.isAnnotation()
1831                                    ? OMPC_unknown
1832                                    : getOpenMPClauseKind(PP.getSpelling(Tok));
1833       Actions.StartOpenMPClause(CKind);
1834       OMPClause *Clause = ParseOpenMPClause(
1835           OMPD_requires, CKind, !FirstClauses[unsigned(CKind)].getInt());
1836       SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1837                 StopBeforeMatch);
1838       FirstClauses[unsigned(CKind)].setInt(true);
1839       if (Clause != nullptr)
1840         Clauses.push_back(Clause);
1841       if (Tok.is(tok::annot_pragma_openmp_end)) {
1842         Actions.EndOpenMPClause();
1843         break;
1844       }
1845       // Skip ',' if any.
1846       if (Tok.is(tok::comma))
1847         ConsumeToken();
1848       Actions.EndOpenMPClause();
1849     }
1850     // Consume final annot_pragma_openmp_end
1851     if (Clauses.empty()) {
1852       Diag(Tok, diag::err_omp_expected_clause)
1853           << getOpenMPDirectiveName(OMPD_requires);
1854       ConsumeAnnotationToken();
1855       return nullptr;
1856     }
1857     ConsumeAnnotationToken();
1858     return Actions.ActOnOpenMPRequiresDirective(StartLoc, Clauses);
1859   }
1860   case OMPD_declare_reduction:
1861     ConsumeToken();
1862     if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
1863       skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
1864       // Skip the last annot_pragma_openmp_end.
1865       ConsumeAnnotationToken();
1866       return Res;
1867     }
1868     break;
1869   case OMPD_declare_mapper: {
1870     ConsumeToken();
1871     if (DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
1872       // Skip the last annot_pragma_openmp_end.
1873       ConsumeAnnotationToken();
1874       return Res;
1875     }
1876     break;
1877   }
1878   case OMPD_begin_declare_variant: {
1879     // The syntax is:
1880     // { #pragma omp begin declare variant clause }
1881     // <function-declaration-or-definition-sequence>
1882     // { #pragma omp end declare variant }
1883     //
1884     ConsumeToken();
1885     OMPTraitInfo *ParentTI = Actions.getOMPTraitInfoForSurroundingScope();
1886     ASTContext &ASTCtx = Actions.getASTContext();
1887     OMPTraitInfo &TI = ASTCtx.getNewOMPTraitInfo();
1888     if (parseOMPDeclareVariantMatchClause(Loc, TI, ParentTI))
1889       break;
1890 
1891     // Skip last tokens.
1892     skipUntilPragmaOpenMPEnd(OMPD_begin_declare_variant);
1893 
1894     ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false);
1895 
1896     VariantMatchInfo VMI;
1897     TI.getAsVariantMatchInfo(ASTCtx, VMI);
1898 
1899     std::function<void(StringRef)> DiagUnknownTrait = [this, Loc](
1900                                                           StringRef ISATrait) {
1901       // TODO Track the selector locations in a way that is accessible here to
1902       // improve the diagnostic location.
1903       Diag(Loc, diag::warn_unknown_begin_declare_variant_isa_trait) << ISATrait;
1904     };
1905     TargetOMPContext OMPCtx(ASTCtx, std::move(DiagUnknownTrait),
1906                             /* CurrentFunctionDecl */ nullptr);
1907 
1908     if (isVariantApplicableInContext(VMI, OMPCtx, /* DeviceSetOnly */ true)) {
1909       Actions.ActOnOpenMPBeginDeclareVariant(Loc, TI);
1910       break;
1911     }
1912 
1913     // Elide all the code till the matching end declare variant was found.
1914     unsigned Nesting = 1;
1915     SourceLocation DKLoc;
1916     OpenMPDirectiveKind DK = OMPD_unknown;
1917     do {
1918       DKLoc = Tok.getLocation();
1919       DK = parseOpenMPDirectiveKind(*this);
1920       if (DK == OMPD_end_declare_variant)
1921         --Nesting;
1922       else if (DK == OMPD_begin_declare_variant)
1923         ++Nesting;
1924       if (!Nesting || isEofOrEom())
1925         break;
1926       ConsumeAnyToken();
1927     } while (true);
1928 
1929     parseOMPEndDirective(OMPD_begin_declare_variant, OMPD_end_declare_variant,
1930                          DK, Loc, DKLoc, /* SkipUntilOpenMPEnd */ true);
1931     if (isEofOrEom())
1932       return nullptr;
1933     break;
1934   }
1935   case OMPD_end_declare_variant: {
1936     if (Actions.isInOpenMPDeclareVariantScope())
1937       Actions.ActOnOpenMPEndDeclareVariant();
1938     else
1939       Diag(Loc, diag::err_expected_begin_declare_variant);
1940     ConsumeToken();
1941     break;
1942   }
1943   case OMPD_declare_variant:
1944   case OMPD_declare_simd: {
1945     // The syntax is:
1946     // { #pragma omp declare {simd|variant} }
1947     // <function-declaration-or-definition>
1948     //
1949     CachedTokens Toks;
1950     Toks.push_back(Tok);
1951     ConsumeToken();
1952     while(Tok.isNot(tok::annot_pragma_openmp_end)) {
1953       Toks.push_back(Tok);
1954       ConsumeAnyToken();
1955     }
1956     Toks.push_back(Tok);
1957     ConsumeAnyToken();
1958 
1959     DeclGroupPtrTy Ptr;
1960     if (Tok.is(tok::annot_pragma_openmp)) {
1961       Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, Delayed,
1962                                                        TagType, Tag);
1963     } else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
1964       // Here we expect to see some function declaration.
1965       if (AS == AS_none) {
1966         assert(TagType == DeclSpec::TST_unspecified);
1967         MaybeParseCXX11Attributes(Attrs);
1968         ParsingDeclSpec PDS(*this);
1969         Ptr = ParseExternalDeclaration(Attrs, &PDS);
1970       } else {
1971         Ptr =
1972             ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
1973       }
1974     }
1975     if (!Ptr) {
1976       Diag(Loc, diag::err_omp_decl_in_declare_simd_variant)
1977           << (DKind == OMPD_declare_simd ? 0 : 1);
1978       return DeclGroupPtrTy();
1979     }
1980     if (DKind == OMPD_declare_simd)
1981       return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
1982     assert(DKind == OMPD_declare_variant &&
1983            "Expected declare variant directive only");
1984     ParseOMPDeclareVariantClauses(Ptr, Toks, Loc);
1985     return Ptr;
1986   }
1987   case OMPD_declare_target: {
1988     SourceLocation DTLoc = ConsumeAnyToken();
1989     if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1990       return ParseOMPDeclareTargetClauses();
1991     }
1992 
1993     // Skip the last annot_pragma_openmp_end.
1994     ConsumeAnyToken();
1995 
1996     if (!Actions.ActOnStartOpenMPDeclareTargetDirective(DTLoc))
1997       return DeclGroupPtrTy();
1998 
1999     ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false);
2000     llvm::SmallVector<Decl *, 4>  Decls;
2001     DKind = parseOpenMPDirectiveKind(*this);
2002     while (DKind != OMPD_end_declare_target && Tok.isNot(tok::eof) &&
2003            Tok.isNot(tok::r_brace)) {
2004       DeclGroupPtrTy Ptr;
2005       // Here we expect to see some function declaration.
2006       if (AS == AS_none) {
2007         assert(TagType == DeclSpec::TST_unspecified);
2008         MaybeParseCXX11Attributes(Attrs);
2009         ParsingDeclSpec PDS(*this);
2010         Ptr = ParseExternalDeclaration(Attrs, &PDS);
2011       } else {
2012         Ptr =
2013             ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
2014       }
2015       if (Ptr) {
2016         DeclGroupRef Ref = Ptr.get();
2017         Decls.append(Ref.begin(), Ref.end());
2018       }
2019       if (Tok.isAnnotation() && Tok.is(tok::annot_pragma_openmp)) {
2020         TentativeParsingAction TPA(*this);
2021         ConsumeAnnotationToken();
2022         DKind = parseOpenMPDirectiveKind(*this);
2023         if (DKind != OMPD_end_declare_target)
2024           TPA.Revert();
2025         else
2026           TPA.Commit();
2027       }
2028     }
2029 
2030     ParseOMPEndDeclareTargetDirective(DKind, DTLoc);
2031     Actions.ActOnFinishOpenMPDeclareTargetDirective();
2032     return Actions.BuildDeclaratorGroup(Decls);
2033   }
2034   case OMPD_unknown:
2035     Diag(Tok, diag::err_omp_unknown_directive);
2036     break;
2037   case OMPD_parallel:
2038   case OMPD_simd:
2039   case OMPD_task:
2040   case OMPD_taskyield:
2041   case OMPD_barrier:
2042   case OMPD_taskwait:
2043   case OMPD_taskgroup:
2044   case OMPD_flush:
2045   case OMPD_depobj:
2046   case OMPD_scan:
2047   case OMPD_for:
2048   case OMPD_for_simd:
2049   case OMPD_sections:
2050   case OMPD_section:
2051   case OMPD_single:
2052   case OMPD_master:
2053   case OMPD_ordered:
2054   case OMPD_critical:
2055   case OMPD_parallel_for:
2056   case OMPD_parallel_for_simd:
2057   case OMPD_parallel_sections:
2058   case OMPD_parallel_master:
2059   case OMPD_atomic:
2060   case OMPD_target:
2061   case OMPD_teams:
2062   case OMPD_cancellation_point:
2063   case OMPD_cancel:
2064   case OMPD_target_data:
2065   case OMPD_target_enter_data:
2066   case OMPD_target_exit_data:
2067   case OMPD_target_parallel:
2068   case OMPD_target_parallel_for:
2069   case OMPD_taskloop:
2070   case OMPD_taskloop_simd:
2071   case OMPD_master_taskloop:
2072   case OMPD_master_taskloop_simd:
2073   case OMPD_parallel_master_taskloop:
2074   case OMPD_parallel_master_taskloop_simd:
2075   case OMPD_distribute:
2076   case OMPD_end_declare_target:
2077   case OMPD_target_update:
2078   case OMPD_distribute_parallel_for:
2079   case OMPD_distribute_parallel_for_simd:
2080   case OMPD_distribute_simd:
2081   case OMPD_target_parallel_for_simd:
2082   case OMPD_target_simd:
2083   case OMPD_teams_distribute:
2084   case OMPD_teams_distribute_simd:
2085   case OMPD_teams_distribute_parallel_for_simd:
2086   case OMPD_teams_distribute_parallel_for:
2087   case OMPD_target_teams:
2088   case OMPD_target_teams_distribute:
2089   case OMPD_target_teams_distribute_parallel_for:
2090   case OMPD_target_teams_distribute_parallel_for_simd:
2091   case OMPD_target_teams_distribute_simd:
2092     Diag(Tok, diag::err_omp_unexpected_directive)
2093         << 1 << getOpenMPDirectiveName(DKind);
2094     break;
2095   default:
2096     break;
2097   }
2098   while (Tok.isNot(tok::annot_pragma_openmp_end))
2099     ConsumeAnyToken();
2100   ConsumeAnyToken();
2101   return nullptr;
2102 }
2103 
2104 /// Parsing of declarative or executable OpenMP directives.
2105 ///
2106 ///       threadprivate-directive:
2107 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
2108 ///         annot_pragma_openmp_end
2109 ///
2110 ///       allocate-directive:
2111 ///         annot_pragma_openmp 'allocate' simple-variable-list
2112 ///         annot_pragma_openmp_end
2113 ///
2114 ///       declare-reduction-directive:
2115 ///         annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
2116 ///         <type> {',' <type>} ':' <expression> ')' ['initializer' '('
2117 ///         ('omp_priv' '=' <expression>|<function_call>) ')']
2118 ///         annot_pragma_openmp_end
2119 ///
2120 ///       declare-mapper-directive:
2121 ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
2122 ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
2123 ///         annot_pragma_openmp_end
2124 ///
2125 ///       executable-directive:
2126 ///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
2127 ///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
2128 ///         'parallel for' | 'parallel sections' | 'parallel master' | 'task' |
2129 ///         'taskyield' | 'barrier' | 'taskwait' | 'flush' | 'ordered' |
2130 ///         'atomic' | 'for simd' | 'parallel for simd' | 'target' | 'target
2131 ///         data' | 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
2132 ///         'master taskloop' | 'master taskloop simd' | 'parallel master
2133 ///         taskloop' | 'parallel master taskloop simd' | 'distribute' | 'target
2134 ///         enter data' | 'target exit data' | 'target parallel' | 'target
2135 ///         parallel for' | 'target update' | 'distribute parallel for' |
2136 ///         'distribute paralle for simd' | 'distribute simd' | 'target parallel
2137 ///         for simd' | 'target simd' | 'teams distribute' | 'teams distribute
2138 ///         simd' | 'teams distribute parallel for simd' | 'teams distribute
2139 ///         parallel for' | 'target teams' | 'target teams distribute' | 'target
2140 ///         teams distribute parallel for' | 'target teams distribute parallel
2141 ///         for simd' | 'target teams distribute simd' {clause}
2142 ///         annot_pragma_openmp_end
2143 ///
2144 StmtResult
2145 Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
2146   assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
2147   ParsingOpenMPDirectiveRAII DirScope(*this);
2148   ParenBraceBracketBalancer BalancerRAIIObj(*this);
2149   SmallVector<OMPClause *, 5> Clauses;
2150   SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
2151               llvm::omp::Clause_enumSize + 1>
2152       FirstClauses(llvm::omp::Clause_enumSize + 1);
2153   unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
2154                         Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
2155   SourceLocation Loc = ConsumeAnnotationToken(), EndLoc;
2156   OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
2157   OpenMPDirectiveKind CancelRegion = OMPD_unknown;
2158   // Name of critical directive.
2159   DeclarationNameInfo DirName;
2160   StmtResult Directive = StmtError();
2161   bool HasAssociatedStatement = true;
2162 
2163   switch (DKind) {
2164   case OMPD_threadprivate: {
2165     // FIXME: Should this be permitted in C++?
2166     if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
2167         ParsedStmtContext()) {
2168       Diag(Tok, diag::err_omp_immediate_directive)
2169           << getOpenMPDirectiveName(DKind) << 0;
2170     }
2171     ConsumeToken();
2172     DeclDirectiveListParserHelper Helper(this, DKind);
2173     if (!ParseOpenMPSimpleVarList(DKind, Helper,
2174                                   /*AllowScopeSpecifier=*/false)) {
2175       skipUntilPragmaOpenMPEnd(DKind);
2176       DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
2177           Loc, Helper.getIdentifiers());
2178       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2179     }
2180     SkipUntil(tok::annot_pragma_openmp_end);
2181     break;
2182   }
2183   case OMPD_allocate: {
2184     // FIXME: Should this be permitted in C++?
2185     if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
2186         ParsedStmtContext()) {
2187       Diag(Tok, diag::err_omp_immediate_directive)
2188           << getOpenMPDirectiveName(DKind) << 0;
2189     }
2190     ConsumeToken();
2191     DeclDirectiveListParserHelper Helper(this, DKind);
2192     if (!ParseOpenMPSimpleVarList(DKind, Helper,
2193                                   /*AllowScopeSpecifier=*/false)) {
2194       SmallVector<OMPClause *, 1> Clauses;
2195       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
2196         SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
2197                     llvm::omp::Clause_enumSize + 1>
2198             FirstClauses(llvm::omp::Clause_enumSize + 1);
2199         while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2200           OpenMPClauseKind CKind =
2201               Tok.isAnnotation() ? OMPC_unknown
2202                                  : getOpenMPClauseKind(PP.getSpelling(Tok));
2203           Actions.StartOpenMPClause(CKind);
2204           OMPClause *Clause = ParseOpenMPClause(
2205               OMPD_allocate, CKind, !FirstClauses[unsigned(CKind)].getInt());
2206           SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
2207                     StopBeforeMatch);
2208           FirstClauses[unsigned(CKind)].setInt(true);
2209           if (Clause != nullptr)
2210             Clauses.push_back(Clause);
2211           if (Tok.is(tok::annot_pragma_openmp_end)) {
2212             Actions.EndOpenMPClause();
2213             break;
2214           }
2215           // Skip ',' if any.
2216           if (Tok.is(tok::comma))
2217             ConsumeToken();
2218           Actions.EndOpenMPClause();
2219         }
2220         skipUntilPragmaOpenMPEnd(DKind);
2221       }
2222       DeclGroupPtrTy Res = Actions.ActOnOpenMPAllocateDirective(
2223           Loc, Helper.getIdentifiers(), Clauses);
2224       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2225     }
2226     SkipUntil(tok::annot_pragma_openmp_end);
2227     break;
2228   }
2229   case OMPD_declare_reduction:
2230     ConsumeToken();
2231     if (DeclGroupPtrTy Res =
2232             ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
2233       skipUntilPragmaOpenMPEnd(OMPD_declare_reduction);
2234       ConsumeAnyToken();
2235       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2236     } else {
2237       SkipUntil(tok::annot_pragma_openmp_end);
2238     }
2239     break;
2240   case OMPD_declare_mapper: {
2241     ConsumeToken();
2242     if (DeclGroupPtrTy Res =
2243             ParseOpenMPDeclareMapperDirective(/*AS=*/AS_none)) {
2244       // Skip the last annot_pragma_openmp_end.
2245       ConsumeAnnotationToken();
2246       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
2247     } else {
2248       SkipUntil(tok::annot_pragma_openmp_end);
2249     }
2250     break;
2251   }
2252   case OMPD_flush:
2253   case OMPD_depobj:
2254   case OMPD_scan:
2255   case OMPD_taskyield:
2256   case OMPD_barrier:
2257   case OMPD_taskwait:
2258   case OMPD_cancellation_point:
2259   case OMPD_cancel:
2260   case OMPD_target_enter_data:
2261   case OMPD_target_exit_data:
2262   case OMPD_target_update:
2263     if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2264         ParsedStmtContext()) {
2265       Diag(Tok, diag::err_omp_immediate_directive)
2266           << getOpenMPDirectiveName(DKind) << 0;
2267     }
2268     HasAssociatedStatement = false;
2269     // Fall through for further analysis.
2270     LLVM_FALLTHROUGH;
2271   case OMPD_parallel:
2272   case OMPD_simd:
2273   case OMPD_for:
2274   case OMPD_for_simd:
2275   case OMPD_sections:
2276   case OMPD_single:
2277   case OMPD_section:
2278   case OMPD_master:
2279   case OMPD_critical:
2280   case OMPD_parallel_for:
2281   case OMPD_parallel_for_simd:
2282   case OMPD_parallel_sections:
2283   case OMPD_parallel_master:
2284   case OMPD_task:
2285   case OMPD_ordered:
2286   case OMPD_atomic:
2287   case OMPD_target:
2288   case OMPD_teams:
2289   case OMPD_taskgroup:
2290   case OMPD_target_data:
2291   case OMPD_target_parallel:
2292   case OMPD_target_parallel_for:
2293   case OMPD_taskloop:
2294   case OMPD_taskloop_simd:
2295   case OMPD_master_taskloop:
2296   case OMPD_master_taskloop_simd:
2297   case OMPD_parallel_master_taskloop:
2298   case OMPD_parallel_master_taskloop_simd:
2299   case OMPD_distribute:
2300   case OMPD_distribute_parallel_for:
2301   case OMPD_distribute_parallel_for_simd:
2302   case OMPD_distribute_simd:
2303   case OMPD_target_parallel_for_simd:
2304   case OMPD_target_simd:
2305   case OMPD_teams_distribute:
2306   case OMPD_teams_distribute_simd:
2307   case OMPD_teams_distribute_parallel_for_simd:
2308   case OMPD_teams_distribute_parallel_for:
2309   case OMPD_target_teams:
2310   case OMPD_target_teams_distribute:
2311   case OMPD_target_teams_distribute_parallel_for:
2312   case OMPD_target_teams_distribute_parallel_for_simd:
2313   case OMPD_target_teams_distribute_simd: {
2314     // Special processing for flush and depobj clauses.
2315     Token ImplicitTok;
2316     bool ImplicitClauseAllowed = false;
2317     if (DKind == OMPD_flush || DKind == OMPD_depobj) {
2318       ImplicitTok = Tok;
2319       ImplicitClauseAllowed = true;
2320     }
2321     ConsumeToken();
2322     // Parse directive name of the 'critical' directive if any.
2323     if (DKind == OMPD_critical) {
2324       BalancedDelimiterTracker T(*this, tok::l_paren,
2325                                  tok::annot_pragma_openmp_end);
2326       if (!T.consumeOpen()) {
2327         if (Tok.isAnyIdentifier()) {
2328           DirName =
2329               DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
2330           ConsumeAnyToken();
2331         } else {
2332           Diag(Tok, diag::err_omp_expected_identifier_for_critical);
2333         }
2334         T.consumeClose();
2335       }
2336     } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
2337       CancelRegion = parseOpenMPDirectiveKind(*this);
2338       if (Tok.isNot(tok::annot_pragma_openmp_end))
2339         ConsumeToken();
2340     }
2341 
2342     if (isOpenMPLoopDirective(DKind))
2343       ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
2344     if (isOpenMPSimdDirective(DKind))
2345       ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
2346     ParseScope OMPDirectiveScope(this, ScopeFlags);
2347     Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
2348 
2349     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
2350       bool HasImplicitClause = false;
2351       if (ImplicitClauseAllowed && Tok.is(tok::l_paren)) {
2352         HasImplicitClause = true;
2353         // Push copy of the current token back to stream to properly parse
2354         // pseudo-clause OMPFlushClause or OMPDepobjClause.
2355         PP.EnterToken(Tok, /*IsReinject*/ true);
2356         PP.EnterToken(ImplicitTok, /*IsReinject*/ true);
2357         ConsumeAnyToken();
2358       }
2359       OpenMPClauseKind CKind = Tok.isAnnotation()
2360                                    ? OMPC_unknown
2361                                    : getOpenMPClauseKind(PP.getSpelling(Tok));
2362       if (HasImplicitClause) {
2363         assert(CKind == OMPC_unknown && "Must be unknown implicit clause.");
2364         if (DKind == OMPD_flush) {
2365           CKind = OMPC_flush;
2366         } else {
2367           assert(DKind == OMPD_depobj &&
2368                  "Expected flush or depobj directives.");
2369           CKind = OMPC_depobj;
2370         }
2371       }
2372       // No more implicit clauses allowed.
2373       ImplicitClauseAllowed = false;
2374       Actions.StartOpenMPClause(CKind);
2375       HasImplicitClause = false;
2376       OMPClause *Clause = ParseOpenMPClause(
2377           DKind, CKind, !FirstClauses[unsigned(CKind)].getInt());
2378       FirstClauses[unsigned(CKind)].setInt(true);
2379       if (Clause) {
2380         FirstClauses[unsigned(CKind)].setPointer(Clause);
2381         Clauses.push_back(Clause);
2382       }
2383 
2384       // Skip ',' if any.
2385       if (Tok.is(tok::comma))
2386         ConsumeToken();
2387       Actions.EndOpenMPClause();
2388     }
2389     // End location of the directive.
2390     EndLoc = Tok.getLocation();
2391     // Consume final annot_pragma_openmp_end.
2392     ConsumeAnnotationToken();
2393 
2394     // OpenMP [2.13.8, ordered Construct, Syntax]
2395     // If the depend clause is specified, the ordered construct is a stand-alone
2396     // directive.
2397     if (DKind == OMPD_ordered && FirstClauses[unsigned(OMPC_depend)].getInt()) {
2398       if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
2399           ParsedStmtContext()) {
2400         Diag(Loc, diag::err_omp_immediate_directive)
2401             << getOpenMPDirectiveName(DKind) << 1
2402             << getOpenMPClauseName(OMPC_depend);
2403       }
2404       HasAssociatedStatement = false;
2405     }
2406 
2407     StmtResult AssociatedStmt;
2408     if (HasAssociatedStatement) {
2409       // The body is a block scope like in Lambdas and Blocks.
2410       Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
2411       // FIXME: We create a bogus CompoundStmt scope to hold the contents of
2412       // the captured region. Code elsewhere assumes that any FunctionScopeInfo
2413       // should have at least one compound statement scope within it.
2414       ParsingOpenMPDirectiveRAII NormalScope(*this, /*Value=*/false);
2415       AssociatedStmt = (Sema::CompoundScopeRAII(Actions), ParseStatement());
2416       AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2417     } else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
2418                DKind == OMPD_target_exit_data) {
2419       Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
2420       AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
2421                         Actions.ActOnCompoundStmt(Loc, Loc, llvm::None,
2422                                                   /*isStmtExpr=*/false));
2423       AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
2424     }
2425     Directive = Actions.ActOnOpenMPExecutableDirective(
2426         DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
2427         EndLoc);
2428 
2429     // Exit scope.
2430     Actions.EndOpenMPDSABlock(Directive.get());
2431     OMPDirectiveScope.Exit();
2432     break;
2433   }
2434   case OMPD_declare_simd:
2435   case OMPD_declare_target:
2436   case OMPD_end_declare_target:
2437   case OMPD_requires:
2438   case OMPD_begin_declare_variant:
2439   case OMPD_end_declare_variant:
2440   case OMPD_declare_variant:
2441     Diag(Tok, diag::err_omp_unexpected_directive)
2442         << 1 << getOpenMPDirectiveName(DKind);
2443     SkipUntil(tok::annot_pragma_openmp_end);
2444     break;
2445   case OMPD_unknown:
2446   default:
2447     Diag(Tok, diag::err_omp_unknown_directive);
2448     SkipUntil(tok::annot_pragma_openmp_end);
2449     break;
2450   }
2451   return Directive;
2452 }
2453 
2454 // Parses simple list:
2455 //   simple-variable-list:
2456 //         '(' id-expression {, id-expression} ')'
2457 //
2458 bool Parser::ParseOpenMPSimpleVarList(
2459     OpenMPDirectiveKind Kind,
2460     const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> &
2461         Callback,
2462     bool AllowScopeSpecifier) {
2463   // Parse '('.
2464   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2465   if (T.expectAndConsume(diag::err_expected_lparen_after,
2466                          getOpenMPDirectiveName(Kind).data()))
2467     return true;
2468   bool IsCorrect = true;
2469   bool NoIdentIsFound = true;
2470 
2471   // Read tokens while ')' or annot_pragma_openmp_end is not found.
2472   while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
2473     CXXScopeSpec SS;
2474     UnqualifiedId Name;
2475     // Read var name.
2476     Token PrevTok = Tok;
2477     NoIdentIsFound = false;
2478 
2479     if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
2480         ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
2481                                        /*ObjectHadErrors=*/false, false)) {
2482       IsCorrect = false;
2483       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2484                 StopBeforeMatch);
2485     } else if (ParseUnqualifiedId(SS, /*ObjectType=*/nullptr,
2486                                   /*ObjectHadErrors=*/false, false, false,
2487                                   false, false, nullptr, Name)) {
2488       IsCorrect = false;
2489       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2490                 StopBeforeMatch);
2491     } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
2492                Tok.isNot(tok::annot_pragma_openmp_end)) {
2493       IsCorrect = false;
2494       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2495                 StopBeforeMatch);
2496       Diag(PrevTok.getLocation(), diag::err_expected)
2497           << tok::identifier
2498           << SourceRange(PrevTok.getLocation(), PrevTokLocation);
2499     } else {
2500       Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
2501     }
2502     // Consume ','.
2503     if (Tok.is(tok::comma)) {
2504       ConsumeToken();
2505     }
2506   }
2507 
2508   if (NoIdentIsFound) {
2509     Diag(Tok, diag::err_expected) << tok::identifier;
2510     IsCorrect = false;
2511   }
2512 
2513   // Parse ')'.
2514   IsCorrect = !T.consumeClose() && IsCorrect;
2515 
2516   return !IsCorrect;
2517 }
2518 
2519 OMPClause *Parser::ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind) {
2520   SourceLocation Loc = Tok.getLocation();
2521   ConsumeAnyToken();
2522 
2523   // Parse '('.
2524   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2525   if (T.expectAndConsume(diag::err_expected_lparen_after, "uses_allocator"))
2526     return nullptr;
2527   SmallVector<Sema::UsesAllocatorsData, 4> Data;
2528   do {
2529     ExprResult Allocator = ParseCXXIdExpression();
2530     if (Allocator.isInvalid()) {
2531       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2532                 StopBeforeMatch);
2533       break;
2534     }
2535     Sema::UsesAllocatorsData &D = Data.emplace_back();
2536     D.Allocator = Allocator.get();
2537     if (Tok.is(tok::l_paren)) {
2538       BalancedDelimiterTracker T(*this, tok::l_paren,
2539                                  tok::annot_pragma_openmp_end);
2540       T.consumeOpen();
2541       ExprResult AllocatorTraits = ParseCXXIdExpression();
2542       T.consumeClose();
2543       if (AllocatorTraits.isInvalid()) {
2544         SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2545                   StopBeforeMatch);
2546         break;
2547       }
2548       D.AllocatorTraits = AllocatorTraits.get();
2549       D.LParenLoc = T.getOpenLocation();
2550       D.RParenLoc = T.getCloseLocation();
2551     }
2552     if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
2553       Diag(Tok, diag::err_omp_expected_punc) << "uses_allocators" << 0;
2554     // Parse ','
2555     if (Tok.is(tok::comma))
2556       ConsumeAnyToken();
2557   } while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end));
2558   T.consumeClose();
2559   return Actions.ActOnOpenMPUsesAllocatorClause(Loc, T.getOpenLocation(),
2560                                                 T.getCloseLocation(), Data);
2561 }
2562 
2563 /// Parsing of OpenMP clauses.
2564 ///
2565 ///    clause:
2566 ///       if-clause | final-clause | num_threads-clause | safelen-clause |
2567 ///       default-clause | private-clause | firstprivate-clause | shared-clause
2568 ///       | linear-clause | aligned-clause | collapse-clause |
2569 ///       lastprivate-clause | reduction-clause | proc_bind-clause |
2570 ///       schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
2571 ///       mergeable-clause | flush-clause | read-clause | write-clause |
2572 ///       update-clause | capture-clause | seq_cst-clause | device-clause |
2573 ///       simdlen-clause | threads-clause | simd-clause | num_teams-clause |
2574 ///       thread_limit-clause | priority-clause | grainsize-clause |
2575 ///       nogroup-clause | num_tasks-clause | hint-clause | to-clause |
2576 ///       from-clause | is_device_ptr-clause | task_reduction-clause |
2577 ///       in_reduction-clause | allocator-clause | allocate-clause |
2578 ///       acq_rel-clause | acquire-clause | release-clause | relaxed-clause |
2579 ///       depobj-clause | destroy-clause | detach-clause | inclusive-clause |
2580 ///       exclusive-clause | uses_allocators-clause | use_device_addr-clause
2581 ///
2582 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
2583                                      OpenMPClauseKind CKind, bool FirstClause) {
2584   OMPClauseKind = CKind;
2585   OMPClause *Clause = nullptr;
2586   bool ErrorFound = false;
2587   bool WrongDirective = false;
2588   // Check if clause is allowed for the given directive.
2589   if (CKind != OMPC_unknown &&
2590       !isAllowedClauseForDirective(DKind, CKind, getLangOpts().OpenMP)) {
2591     Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
2592                                                << getOpenMPDirectiveName(DKind);
2593     ErrorFound = true;
2594     WrongDirective = true;
2595   }
2596 
2597   switch (CKind) {
2598   case OMPC_final:
2599   case OMPC_num_threads:
2600   case OMPC_safelen:
2601   case OMPC_simdlen:
2602   case OMPC_collapse:
2603   case OMPC_ordered:
2604   case OMPC_num_teams:
2605   case OMPC_thread_limit:
2606   case OMPC_priority:
2607   case OMPC_grainsize:
2608   case OMPC_num_tasks:
2609   case OMPC_hint:
2610   case OMPC_allocator:
2611   case OMPC_depobj:
2612   case OMPC_detach:
2613     // OpenMP [2.5, Restrictions]
2614     //  At most one num_threads clause can appear on the directive.
2615     // OpenMP [2.8.1, simd construct, Restrictions]
2616     //  Only one safelen  clause can appear on a simd directive.
2617     //  Only one simdlen  clause can appear on a simd directive.
2618     //  Only one collapse clause can appear on a simd directive.
2619     // OpenMP [2.11.1, task Construct, Restrictions]
2620     //  At most one if clause can appear on the directive.
2621     //  At most one final clause can appear on the directive.
2622     // OpenMP [teams Construct, Restrictions]
2623     //  At most one num_teams clause can appear on the directive.
2624     //  At most one thread_limit clause can appear on the directive.
2625     // OpenMP [2.9.1, task Construct, Restrictions]
2626     // At most one priority clause can appear on the directive.
2627     // OpenMP [2.9.2, taskloop Construct, Restrictions]
2628     // At most one grainsize clause can appear on the directive.
2629     // OpenMP [2.9.2, taskloop Construct, Restrictions]
2630     // At most one num_tasks clause can appear on the directive.
2631     // OpenMP [2.11.3, allocate Directive, Restrictions]
2632     // At most one allocator clause can appear on the directive.
2633     // OpenMP 5.0, 2.10.1 task Construct, Restrictions.
2634     // At most one detach clause can appear on the directive.
2635     if (!FirstClause) {
2636       Diag(Tok, diag::err_omp_more_one_clause)
2637           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2638       ErrorFound = true;
2639     }
2640 
2641     if (CKind == OMPC_ordered && PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
2642       Clause = ParseOpenMPClause(CKind, WrongDirective);
2643     else
2644       Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
2645     break;
2646   case OMPC_default:
2647   case OMPC_proc_bind:
2648   case OMPC_atomic_default_mem_order:
2649   case OMPC_order:
2650     // OpenMP [2.14.3.1, Restrictions]
2651     //  Only a single default clause may be specified on a parallel, task or
2652     //  teams directive.
2653     // OpenMP [2.5, parallel Construct, Restrictions]
2654     //  At most one proc_bind clause can appear on the directive.
2655     // OpenMP [5.0, Requires directive, Restrictions]
2656     //  At most one atomic_default_mem_order clause can appear
2657     //  on the directive
2658     if (!FirstClause && CKind != OMPC_order) {
2659       Diag(Tok, diag::err_omp_more_one_clause)
2660           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2661       ErrorFound = true;
2662     }
2663 
2664     Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
2665     break;
2666   case OMPC_device:
2667   case OMPC_schedule:
2668   case OMPC_dist_schedule:
2669   case OMPC_defaultmap:
2670     // OpenMP [2.7.1, Restrictions, p. 3]
2671     //  Only one schedule clause can appear on a loop directive.
2672     // OpenMP 4.5 [2.10.4, Restrictions, p. 106]
2673     //  At most one defaultmap clause can appear on the directive.
2674     // OpenMP 5.0 [2.12.5, target construct, Restrictions]
2675     //  At most one device clause can appear on the directive.
2676     if ((getLangOpts().OpenMP < 50 || CKind != OMPC_defaultmap) &&
2677         !FirstClause) {
2678       Diag(Tok, diag::err_omp_more_one_clause)
2679           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2680       ErrorFound = true;
2681     }
2682     LLVM_FALLTHROUGH;
2683   case OMPC_if:
2684     Clause = ParseOpenMPSingleExprWithArgClause(DKind, CKind, WrongDirective);
2685     break;
2686   case OMPC_nowait:
2687   case OMPC_untied:
2688   case OMPC_mergeable:
2689   case OMPC_read:
2690   case OMPC_write:
2691   case OMPC_capture:
2692   case OMPC_seq_cst:
2693   case OMPC_acq_rel:
2694   case OMPC_acquire:
2695   case OMPC_release:
2696   case OMPC_relaxed:
2697   case OMPC_threads:
2698   case OMPC_simd:
2699   case OMPC_nogroup:
2700   case OMPC_unified_address:
2701   case OMPC_unified_shared_memory:
2702   case OMPC_reverse_offload:
2703   case OMPC_dynamic_allocators:
2704   case OMPC_destroy:
2705     // OpenMP [2.7.1, Restrictions, p. 9]
2706     //  Only one ordered clause can appear on a loop directive.
2707     // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
2708     //  Only one nowait clause can appear on a for directive.
2709     // OpenMP [5.0, Requires directive, Restrictions]
2710     //   Each of the requires clauses can appear at most once on the directive.
2711     if (!FirstClause) {
2712       Diag(Tok, diag::err_omp_more_one_clause)
2713           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2714       ErrorFound = true;
2715     }
2716 
2717     Clause = ParseOpenMPClause(CKind, WrongDirective);
2718     break;
2719   case OMPC_update:
2720     if (!FirstClause) {
2721       Diag(Tok, diag::err_omp_more_one_clause)
2722           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
2723       ErrorFound = true;
2724     }
2725 
2726     Clause = (DKind == OMPD_depobj)
2727                  ? ParseOpenMPSimpleClause(CKind, WrongDirective)
2728                  : ParseOpenMPClause(CKind, WrongDirective);
2729     break;
2730   case OMPC_private:
2731   case OMPC_firstprivate:
2732   case OMPC_lastprivate:
2733   case OMPC_shared:
2734   case OMPC_reduction:
2735   case OMPC_task_reduction:
2736   case OMPC_in_reduction:
2737   case OMPC_linear:
2738   case OMPC_aligned:
2739   case OMPC_copyin:
2740   case OMPC_copyprivate:
2741   case OMPC_flush:
2742   case OMPC_depend:
2743   case OMPC_map:
2744   case OMPC_to:
2745   case OMPC_from:
2746   case OMPC_use_device_ptr:
2747   case OMPC_use_device_addr:
2748   case OMPC_is_device_ptr:
2749   case OMPC_allocate:
2750   case OMPC_nontemporal:
2751   case OMPC_inclusive:
2752   case OMPC_exclusive:
2753   case OMPC_affinity:
2754     Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
2755     break;
2756   case OMPC_uses_allocators:
2757     Clause = ParseOpenMPUsesAllocatorClause(DKind);
2758     break;
2759   case OMPC_device_type:
2760   case OMPC_unknown:
2761     skipUntilPragmaOpenMPEnd(DKind);
2762     break;
2763   case OMPC_threadprivate:
2764   case OMPC_uniform:
2765   case OMPC_match:
2766     if (!WrongDirective)
2767       Diag(Tok, diag::err_omp_unexpected_clause)
2768           << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
2769     SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
2770     break;
2771   default:
2772     break;
2773   }
2774   return ErrorFound ? nullptr : Clause;
2775 }
2776 
2777 /// Parses simple expression in parens for single-expression clauses of OpenMP
2778 /// constructs.
2779 /// \param RLoc Returned location of right paren.
2780 ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
2781                                          SourceLocation &RLoc,
2782                                          bool IsAddressOfOperand) {
2783   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2784   if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
2785     return ExprError();
2786 
2787   SourceLocation ELoc = Tok.getLocation();
2788   ExprResult LHS(ParseCastExpression(AnyCastExpr, IsAddressOfOperand,
2789                                      NotTypeCast));
2790   ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
2791   Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
2792 
2793   // Parse ')'.
2794   RLoc = Tok.getLocation();
2795   if (!T.consumeClose())
2796     RLoc = T.getCloseLocation();
2797 
2798   return Val;
2799 }
2800 
2801 /// Parsing of OpenMP clauses with single expressions like 'final',
2802 /// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
2803 /// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks', 'hint' or
2804 /// 'detach'.
2805 ///
2806 ///    final-clause:
2807 ///      'final' '(' expression ')'
2808 ///
2809 ///    num_threads-clause:
2810 ///      'num_threads' '(' expression ')'
2811 ///
2812 ///    safelen-clause:
2813 ///      'safelen' '(' expression ')'
2814 ///
2815 ///    simdlen-clause:
2816 ///      'simdlen' '(' expression ')'
2817 ///
2818 ///    collapse-clause:
2819 ///      'collapse' '(' expression ')'
2820 ///
2821 ///    priority-clause:
2822 ///      'priority' '(' expression ')'
2823 ///
2824 ///    grainsize-clause:
2825 ///      'grainsize' '(' expression ')'
2826 ///
2827 ///    num_tasks-clause:
2828 ///      'num_tasks' '(' expression ')'
2829 ///
2830 ///    hint-clause:
2831 ///      'hint' '(' expression ')'
2832 ///
2833 ///    allocator-clause:
2834 ///      'allocator' '(' expression ')'
2835 ///
2836 ///    detach-clause:
2837 ///      'detach' '(' event-handler-expression ')'
2838 ///
2839 OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
2840                                                bool ParseOnly) {
2841   SourceLocation Loc = ConsumeToken();
2842   SourceLocation LLoc = Tok.getLocation();
2843   SourceLocation RLoc;
2844 
2845   ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc);
2846 
2847   if (Val.isInvalid())
2848     return nullptr;
2849 
2850   if (ParseOnly)
2851     return nullptr;
2852   return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc);
2853 }
2854 
2855 /// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
2856 ///
2857 ///    default-clause:
2858 ///         'default' '(' 'none' | 'shared' | 'firstprivate' ')'
2859 ///
2860 ///    proc_bind-clause:
2861 ///         'proc_bind' '(' 'master' | 'close' | 'spread' ')'
2862 ///
2863 ///    update-clause:
2864 ///         'update' '(' 'in' | 'out' | 'inout' | 'mutexinoutset' ')'
2865 ///
2866 OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind,
2867                                            bool ParseOnly) {
2868   llvm::Optional<SimpleClauseData> Val = parseOpenMPSimpleClause(*this, Kind);
2869   if (!Val || ParseOnly)
2870     return nullptr;
2871   if (getLangOpts().OpenMP < 51 && Kind == OMPC_default &&
2872       static_cast<DefaultKind>(Val.getValue().Type) ==
2873           OMP_DEFAULT_firstprivate) {
2874     Diag(Val.getValue().LOpen, diag::err_omp_invalid_dsa)
2875         << getOpenMPClauseName(OMPC_firstprivate)
2876         << getOpenMPClauseName(OMPC_default) << "5.1";
2877     return nullptr;
2878   }
2879   return Actions.ActOnOpenMPSimpleClause(
2880       Kind, Val.getValue().Type, Val.getValue().TypeLoc, Val.getValue().LOpen,
2881       Val.getValue().Loc, Val.getValue().RLoc);
2882 }
2883 
2884 /// Parsing of OpenMP clauses like 'ordered'.
2885 ///
2886 ///    ordered-clause:
2887 ///         'ordered'
2888 ///
2889 ///    nowait-clause:
2890 ///         'nowait'
2891 ///
2892 ///    untied-clause:
2893 ///         'untied'
2894 ///
2895 ///    mergeable-clause:
2896 ///         'mergeable'
2897 ///
2898 ///    read-clause:
2899 ///         'read'
2900 ///
2901 ///    threads-clause:
2902 ///         'threads'
2903 ///
2904 ///    simd-clause:
2905 ///         'simd'
2906 ///
2907 ///    nogroup-clause:
2908 ///         'nogroup'
2909 ///
2910 OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly) {
2911   SourceLocation Loc = Tok.getLocation();
2912   ConsumeAnyToken();
2913 
2914   if (ParseOnly)
2915     return nullptr;
2916   return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
2917 }
2918 
2919 /// Parsing of OpenMP clauses with single expressions and some additional
2920 /// argument like 'schedule' or 'dist_schedule'.
2921 ///
2922 ///    schedule-clause:
2923 ///      'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
2924 ///      ')'
2925 ///
2926 ///    if-clause:
2927 ///      'if' '(' [ directive-name-modifier ':' ] expression ')'
2928 ///
2929 ///    defaultmap:
2930 ///      'defaultmap' '(' modifier [ ':' kind ] ')'
2931 ///
2932 ///    device-clause:
2933 ///      'device' '(' [ device-modifier ':' ] expression ')'
2934 ///
2935 OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind,
2936                                                       OpenMPClauseKind Kind,
2937                                                       bool ParseOnly) {
2938   SourceLocation Loc = ConsumeToken();
2939   SourceLocation DelimLoc;
2940   // Parse '('.
2941   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2942   if (T.expectAndConsume(diag::err_expected_lparen_after,
2943                          getOpenMPClauseName(Kind).data()))
2944     return nullptr;
2945 
2946   ExprResult Val;
2947   SmallVector<unsigned, 4> Arg;
2948   SmallVector<SourceLocation, 4> KLoc;
2949   if (Kind == OMPC_schedule) {
2950     enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
2951     Arg.resize(NumberOfElements);
2952     KLoc.resize(NumberOfElements);
2953     Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
2954     Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
2955     Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
2956     unsigned KindModifier = getOpenMPSimpleClauseType(
2957         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok),
2958         getLangOpts().OpenMP);
2959     if (KindModifier > OMPC_SCHEDULE_unknown) {
2960       // Parse 'modifier'
2961       Arg[Modifier1] = KindModifier;
2962       KLoc[Modifier1] = Tok.getLocation();
2963       if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
2964           Tok.isNot(tok::annot_pragma_openmp_end))
2965         ConsumeAnyToken();
2966       if (Tok.is(tok::comma)) {
2967         // Parse ',' 'modifier'
2968         ConsumeAnyToken();
2969         KindModifier = getOpenMPSimpleClauseType(
2970             Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok),
2971             getLangOpts().OpenMP);
2972         Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown
2973                              ? KindModifier
2974                              : (unsigned)OMPC_SCHEDULE_unknown;
2975         KLoc[Modifier2] = Tok.getLocation();
2976         if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
2977             Tok.isNot(tok::annot_pragma_openmp_end))
2978           ConsumeAnyToken();
2979       }
2980       // Parse ':'
2981       if (Tok.is(tok::colon))
2982         ConsumeAnyToken();
2983       else
2984         Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier";
2985       KindModifier = getOpenMPSimpleClauseType(
2986           Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok),
2987           getLangOpts().OpenMP);
2988     }
2989     Arg[ScheduleKind] = KindModifier;
2990     KLoc[ScheduleKind] = Tok.getLocation();
2991     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
2992         Tok.isNot(tok::annot_pragma_openmp_end))
2993       ConsumeAnyToken();
2994     if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
2995          Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
2996          Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
2997         Tok.is(tok::comma))
2998       DelimLoc = ConsumeAnyToken();
2999   } else if (Kind == OMPC_dist_schedule) {
3000     Arg.push_back(getOpenMPSimpleClauseType(
3001         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok),
3002         getLangOpts().OpenMP));
3003     KLoc.push_back(Tok.getLocation());
3004     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3005         Tok.isNot(tok::annot_pragma_openmp_end))
3006       ConsumeAnyToken();
3007     if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
3008       DelimLoc = ConsumeAnyToken();
3009   } else if (Kind == OMPC_defaultmap) {
3010     // Get a defaultmap modifier
3011     unsigned Modifier = getOpenMPSimpleClauseType(
3012         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok),
3013         getLangOpts().OpenMP);
3014     // Set defaultmap modifier to unknown if it is either scalar, aggregate, or
3015     // pointer
3016     if (Modifier < OMPC_DEFAULTMAP_MODIFIER_unknown)
3017       Modifier = OMPC_DEFAULTMAP_MODIFIER_unknown;
3018     Arg.push_back(Modifier);
3019     KLoc.push_back(Tok.getLocation());
3020     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3021         Tok.isNot(tok::annot_pragma_openmp_end))
3022       ConsumeAnyToken();
3023     // Parse ':'
3024     if (Tok.is(tok::colon) || getLangOpts().OpenMP < 50) {
3025       if (Tok.is(tok::colon))
3026         ConsumeAnyToken();
3027       else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown)
3028         Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier";
3029       // Get a defaultmap kind
3030       Arg.push_back(getOpenMPSimpleClauseType(
3031           Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok),
3032           getLangOpts().OpenMP));
3033       KLoc.push_back(Tok.getLocation());
3034       if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
3035           Tok.isNot(tok::annot_pragma_openmp_end))
3036         ConsumeAnyToken();
3037     } else {
3038       Arg.push_back(OMPC_DEFAULTMAP_unknown);
3039       KLoc.push_back(SourceLocation());
3040     }
3041   } else if (Kind == OMPC_device) {
3042     // Only target executable directives support extended device construct.
3043     if (isOpenMPTargetExecutionDirective(DKind) && getLangOpts().OpenMP >= 50 &&
3044         NextToken().is(tok::colon)) {
3045       // Parse optional <device modifier> ':'
3046       Arg.push_back(getOpenMPSimpleClauseType(
3047           Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok),
3048           getLangOpts().OpenMP));
3049       KLoc.push_back(Tok.getLocation());
3050       ConsumeAnyToken();
3051       // Parse ':'
3052       ConsumeAnyToken();
3053     } else {
3054       Arg.push_back(OMPC_DEVICE_unknown);
3055       KLoc.emplace_back();
3056     }
3057   } else {
3058     assert(Kind == OMPC_if);
3059     KLoc.push_back(Tok.getLocation());
3060     TentativeParsingAction TPA(*this);
3061     auto DK = parseOpenMPDirectiveKind(*this);
3062     Arg.push_back(DK);
3063     if (DK != OMPD_unknown) {
3064       ConsumeToken();
3065       if (Tok.is(tok::colon) && getLangOpts().OpenMP > 40) {
3066         TPA.Commit();
3067         DelimLoc = ConsumeToken();
3068       } else {
3069         TPA.Revert();
3070         Arg.back() = unsigned(OMPD_unknown);
3071       }
3072     } else {
3073       TPA.Revert();
3074     }
3075   }
3076 
3077   bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) ||
3078                           (Kind == OMPC_dist_schedule && DelimLoc.isValid()) ||
3079                           Kind == OMPC_if || Kind == OMPC_device;
3080   if (NeedAnExpression) {
3081     SourceLocation ELoc = Tok.getLocation();
3082     ExprResult LHS(ParseCastExpression(AnyCastExpr, false, NotTypeCast));
3083     Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
3084     Val =
3085         Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
3086   }
3087 
3088   // Parse ')'.
3089   SourceLocation RLoc = Tok.getLocation();
3090   if (!T.consumeClose())
3091     RLoc = T.getCloseLocation();
3092 
3093   if (NeedAnExpression && Val.isInvalid())
3094     return nullptr;
3095 
3096   if (ParseOnly)
3097     return nullptr;
3098   return Actions.ActOnOpenMPSingleExprWithArgClause(
3099       Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
3100 }
3101 
3102 static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
3103                              UnqualifiedId &ReductionId) {
3104   if (ReductionIdScopeSpec.isEmpty()) {
3105     auto OOK = OO_None;
3106     switch (P.getCurToken().getKind()) {
3107     case tok::plus:
3108       OOK = OO_Plus;
3109       break;
3110     case tok::minus:
3111       OOK = OO_Minus;
3112       break;
3113     case tok::star:
3114       OOK = OO_Star;
3115       break;
3116     case tok::amp:
3117       OOK = OO_Amp;
3118       break;
3119     case tok::pipe:
3120       OOK = OO_Pipe;
3121       break;
3122     case tok::caret:
3123       OOK = OO_Caret;
3124       break;
3125     case tok::ampamp:
3126       OOK = OO_AmpAmp;
3127       break;
3128     case tok::pipepipe:
3129       OOK = OO_PipePipe;
3130       break;
3131     default:
3132       break;
3133     }
3134     if (OOK != OO_None) {
3135       SourceLocation OpLoc = P.ConsumeToken();
3136       SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
3137       ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
3138       return false;
3139     }
3140   }
3141   return P.ParseUnqualifiedId(
3142       ReductionIdScopeSpec, /*ObjectType=*/nullptr,
3143       /*ObjectHadErrors=*/false, /*EnteringContext*/ false,
3144       /*AllowDestructorName*/ false,
3145       /*AllowConstructorName*/ false,
3146       /*AllowDeductionGuide*/ false, nullptr, ReductionId);
3147 }
3148 
3149 /// Checks if the token is a valid map-type-modifier.
3150 /// FIXME: It will return an OpenMPMapClauseKind if that's what it parses.
3151 static OpenMPMapModifierKind isMapModifier(Parser &P) {
3152   Token Tok = P.getCurToken();
3153   if (!Tok.is(tok::identifier))
3154     return OMPC_MAP_MODIFIER_unknown;
3155 
3156   Preprocessor &PP = P.getPreprocessor();
3157   OpenMPMapModifierKind TypeModifier =
3158       static_cast<OpenMPMapModifierKind>(getOpenMPSimpleClauseType(
3159           OMPC_map, PP.getSpelling(Tok), P.getLangOpts().OpenMP));
3160   return TypeModifier;
3161 }
3162 
3163 /// Parse the mapper modifier in map, to, and from clauses.
3164 bool Parser::parseMapperModifier(OpenMPVarListDataTy &Data) {
3165   // Parse '('.
3166   BalancedDelimiterTracker T(*this, tok::l_paren, tok::colon);
3167   if (T.expectAndConsume(diag::err_expected_lparen_after, "mapper")) {
3168     SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3169               StopBeforeMatch);
3170     return true;
3171   }
3172   // Parse mapper-identifier
3173   if (getLangOpts().CPlusPlus)
3174     ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
3175                                    /*ObjectType=*/nullptr,
3176                                    /*ObjectHadErrors=*/false,
3177                                    /*EnteringContext=*/false);
3178   if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
3179     Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
3180     SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3181               StopBeforeMatch);
3182     return true;
3183   }
3184   auto &DeclNames = Actions.getASTContext().DeclarationNames;
3185   Data.ReductionOrMapperId = DeclarationNameInfo(
3186       DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
3187   ConsumeToken();
3188   // Parse ')'.
3189   return T.consumeClose();
3190 }
3191 
3192 /// Parse map-type-modifiers in map clause.
3193 /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
3194 /// where, map-type-modifier ::= always | close | mapper(mapper-identifier) |
3195 /// present
3196 bool Parser::parseMapTypeModifiers(OpenMPVarListDataTy &Data) {
3197   while (getCurToken().isNot(tok::colon)) {
3198     OpenMPMapModifierKind TypeModifier = isMapModifier(*this);
3199     if (TypeModifier == OMPC_MAP_MODIFIER_always ||
3200         TypeModifier == OMPC_MAP_MODIFIER_close ||
3201         TypeModifier == OMPC_MAP_MODIFIER_present) {
3202       Data.MapTypeModifiers.push_back(TypeModifier);
3203       Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
3204       ConsumeToken();
3205     } else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
3206       Data.MapTypeModifiers.push_back(TypeModifier);
3207       Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
3208       ConsumeToken();
3209       if (parseMapperModifier(Data))
3210         return true;
3211     } else {
3212       // For the case of unknown map-type-modifier or a map-type.
3213       // Map-type is followed by a colon; the function returns when it
3214       // encounters a token followed by a colon.
3215       if (Tok.is(tok::comma)) {
3216         Diag(Tok, diag::err_omp_map_type_modifier_missing);
3217         ConsumeToken();
3218         continue;
3219       }
3220       // Potential map-type token as it is followed by a colon.
3221       if (PP.LookAhead(0).is(tok::colon))
3222         return false;
3223       Diag(Tok, diag::err_omp_unknown_map_type_modifier)
3224           << (getLangOpts().OpenMP >= 51 ? 1 : 0);
3225       ConsumeToken();
3226     }
3227     if (getCurToken().is(tok::comma))
3228       ConsumeToken();
3229   }
3230   return false;
3231 }
3232 
3233 /// Checks if the token is a valid map-type.
3234 /// FIXME: It will return an OpenMPMapModifierKind if that's what it parses.
3235 static OpenMPMapClauseKind isMapType(Parser &P) {
3236   Token Tok = P.getCurToken();
3237   // The map-type token can be either an identifier or the C++ delete keyword.
3238   if (!Tok.isOneOf(tok::identifier, tok::kw_delete))
3239     return OMPC_MAP_unknown;
3240   Preprocessor &PP = P.getPreprocessor();
3241   OpenMPMapClauseKind MapType =
3242       static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType(
3243           OMPC_map, PP.getSpelling(Tok), P.getLangOpts().OpenMP));
3244   return MapType;
3245 }
3246 
3247 /// Parse map-type in map clause.
3248 /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
3249 /// where, map-type ::= to | from | tofrom | alloc | release | delete
3250 static void parseMapType(Parser &P, Parser::OpenMPVarListDataTy &Data) {
3251   Token Tok = P.getCurToken();
3252   if (Tok.is(tok::colon)) {
3253     P.Diag(Tok, diag::err_omp_map_type_missing);
3254     return;
3255   }
3256   Data.ExtraModifier = isMapType(P);
3257   if (Data.ExtraModifier == OMPC_MAP_unknown)
3258     P.Diag(Tok, diag::err_omp_unknown_map_type);
3259   P.ConsumeToken();
3260 }
3261 
3262 /// Parses simple expression in parens for single-expression clauses of OpenMP
3263 /// constructs.
3264 ExprResult Parser::ParseOpenMPIteratorsExpr() {
3265   assert(Tok.is(tok::identifier) && PP.getSpelling(Tok) == "iterator" &&
3266          "Expected 'iterator' token.");
3267   SourceLocation IteratorKwLoc = ConsumeToken();
3268 
3269   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3270   if (T.expectAndConsume(diag::err_expected_lparen_after, "iterator"))
3271     return ExprError();
3272 
3273   SourceLocation LLoc = T.getOpenLocation();
3274   SmallVector<Sema::OMPIteratorData, 4> Data;
3275   while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
3276     // Check if the type parsing is required.
3277     ParsedType IteratorType;
3278     if (Tok.isNot(tok::identifier) || NextToken().isNot(tok::equal)) {
3279       // identifier '=' is not found - parse type.
3280       TypeResult TR = ParseTypeName();
3281       if (TR.isInvalid()) {
3282         T.skipToEnd();
3283         return ExprError();
3284       }
3285       IteratorType = TR.get();
3286     }
3287 
3288     // Parse identifier.
3289     IdentifierInfo *II = nullptr;
3290     SourceLocation IdLoc;
3291     if (Tok.is(tok::identifier)) {
3292       II = Tok.getIdentifierInfo();
3293       IdLoc = ConsumeToken();
3294     } else {
3295       Diag(Tok, diag::err_expected_unqualified_id) << 0;
3296     }
3297 
3298     // Parse '='.
3299     SourceLocation AssignLoc;
3300     if (Tok.is(tok::equal))
3301       AssignLoc = ConsumeToken();
3302     else
3303       Diag(Tok, diag::err_omp_expected_equal_in_iterator);
3304 
3305     // Parse range-specification - <begin> ':' <end> [ ':' <step> ]
3306     ColonProtectionRAIIObject ColonRAII(*this);
3307     // Parse <begin>
3308     SourceLocation Loc = Tok.getLocation();
3309     ExprResult LHS = ParseCastExpression(AnyCastExpr);
3310     ExprResult Begin = Actions.CorrectDelayedTyposInExpr(
3311         ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3312     Begin = Actions.ActOnFinishFullExpr(Begin.get(), Loc,
3313                                         /*DiscardedValue=*/false);
3314     // Parse ':'.
3315     SourceLocation ColonLoc;
3316     if (Tok.is(tok::colon))
3317       ColonLoc = ConsumeToken();
3318 
3319     // Parse <end>
3320     Loc = Tok.getLocation();
3321     LHS = ParseCastExpression(AnyCastExpr);
3322     ExprResult End = Actions.CorrectDelayedTyposInExpr(
3323         ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3324     End = Actions.ActOnFinishFullExpr(End.get(), Loc,
3325                                       /*DiscardedValue=*/false);
3326 
3327     SourceLocation SecColonLoc;
3328     ExprResult Step;
3329     // Parse optional step.
3330     if (Tok.is(tok::colon)) {
3331       // Parse ':'
3332       SecColonLoc = ConsumeToken();
3333       // Parse <step>
3334       Loc = Tok.getLocation();
3335       LHS = ParseCastExpression(AnyCastExpr);
3336       Step = Actions.CorrectDelayedTyposInExpr(
3337           ParseRHSOfBinaryExpression(LHS, prec::Conditional));
3338       Step = Actions.ActOnFinishFullExpr(Step.get(), Loc,
3339                                          /*DiscardedValue=*/false);
3340     }
3341 
3342     // Parse ',' or ')'
3343     if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
3344       Diag(Tok, diag::err_omp_expected_punc_after_iterator);
3345     if (Tok.is(tok::comma))
3346       ConsumeToken();
3347 
3348     Sema::OMPIteratorData &D = Data.emplace_back();
3349     D.DeclIdent = II;
3350     D.DeclIdentLoc = IdLoc;
3351     D.Type = IteratorType;
3352     D.AssignLoc = AssignLoc;
3353     D.ColonLoc = ColonLoc;
3354     D.SecColonLoc = SecColonLoc;
3355     D.Range.Begin = Begin.get();
3356     D.Range.End = End.get();
3357     D.Range.Step = Step.get();
3358   }
3359 
3360   // Parse ')'.
3361   SourceLocation RLoc = Tok.getLocation();
3362   if (!T.consumeClose())
3363     RLoc = T.getCloseLocation();
3364 
3365   return Actions.ActOnOMPIteratorExpr(getCurScope(), IteratorKwLoc, LLoc, RLoc,
3366                                       Data);
3367 }
3368 
3369 /// Parses clauses with list.
3370 bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
3371                                 OpenMPClauseKind Kind,
3372                                 SmallVectorImpl<Expr *> &Vars,
3373                                 OpenMPVarListDataTy &Data) {
3374   UnqualifiedId UnqualifiedReductionId;
3375   bool InvalidReductionId = false;
3376   bool IsInvalidMapperModifier = false;
3377 
3378   // Parse '('.
3379   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
3380   if (T.expectAndConsume(diag::err_expected_lparen_after,
3381                          getOpenMPClauseName(Kind).data()))
3382     return true;
3383 
3384   bool HasIterator = false;
3385   bool NeedRParenForLinear = false;
3386   BalancedDelimiterTracker LinearT(*this, tok::l_paren,
3387                                   tok::annot_pragma_openmp_end);
3388   // Handle reduction-identifier for reduction clause.
3389   if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
3390       Kind == OMPC_in_reduction) {
3391     Data.ExtraModifier = OMPC_REDUCTION_unknown;
3392     if (Kind == OMPC_reduction && getLangOpts().OpenMP >= 50 &&
3393         (Tok.is(tok::identifier) || Tok.is(tok::kw_default)) &&
3394         NextToken().is(tok::comma)) {
3395       // Parse optional reduction modifier.
3396       Data.ExtraModifier = getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok),
3397                                                      getLangOpts().OpenMP);
3398       Data.ExtraModifierLoc = Tok.getLocation();
3399       ConsumeToken();
3400       assert(Tok.is(tok::comma) && "Expected comma.");
3401       (void)ConsumeToken();
3402     }
3403     ColonProtectionRAIIObject ColonRAII(*this);
3404     if (getLangOpts().CPlusPlus)
3405       ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
3406                                      /*ObjectType=*/nullptr,
3407                                      /*ObjectHadErrors=*/false,
3408                                      /*EnteringContext=*/false);
3409     InvalidReductionId = ParseReductionId(
3410         *this, Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
3411     if (InvalidReductionId) {
3412       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3413                 StopBeforeMatch);
3414     }
3415     if (Tok.is(tok::colon))
3416       Data.ColonLoc = ConsumeToken();
3417     else
3418       Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
3419     if (!InvalidReductionId)
3420       Data.ReductionOrMapperId =
3421           Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
3422   } else if (Kind == OMPC_depend) {
3423     if (getLangOpts().OpenMP >= 50) {
3424       if (Tok.is(tok::identifier) && PP.getSpelling(Tok) == "iterator") {
3425         // Handle optional dependence modifier.
3426         // iterator(iterators-definition)
3427         // where iterators-definition is iterator-specifier [,
3428         // iterators-definition ]
3429         // where iterator-specifier is [ iterator-type ] identifier =
3430         // range-specification
3431         HasIterator = true;
3432         EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope);
3433         ExprResult IteratorRes = ParseOpenMPIteratorsExpr();
3434         Data.DepModOrTailExpr = IteratorRes.get();
3435         // Parse ','
3436         ExpectAndConsume(tok::comma);
3437       }
3438     }
3439     // Handle dependency type for depend clause.
3440     ColonProtectionRAIIObject ColonRAII(*this);
3441     Data.ExtraModifier = getOpenMPSimpleClauseType(
3442         Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : "",
3443         getLangOpts().OpenMP);
3444     Data.ExtraModifierLoc = Tok.getLocation();
3445     if (Data.ExtraModifier == OMPC_DEPEND_unknown) {
3446       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3447                 StopBeforeMatch);
3448     } else {
3449       ConsumeToken();
3450       // Special processing for depend(source) clause.
3451       if (DKind == OMPD_ordered && Data.ExtraModifier == OMPC_DEPEND_source) {
3452         // Parse ')'.
3453         T.consumeClose();
3454         return false;
3455       }
3456     }
3457     if (Tok.is(tok::colon)) {
3458       Data.ColonLoc = ConsumeToken();
3459     } else {
3460       Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
3461                                       : diag::warn_pragma_expected_colon)
3462           << "dependency type";
3463     }
3464   } else if (Kind == OMPC_linear) {
3465     // Try to parse modifier if any.
3466     Data.ExtraModifier = OMPC_LINEAR_val;
3467     if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
3468       Data.ExtraModifier = getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok),
3469                                                      getLangOpts().OpenMP);
3470       Data.ExtraModifierLoc = ConsumeToken();
3471       LinearT.consumeOpen();
3472       NeedRParenForLinear = true;
3473     }
3474   } else if (Kind == OMPC_lastprivate) {
3475     // Try to parse modifier if any.
3476     Data.ExtraModifier = OMPC_LASTPRIVATE_unknown;
3477     // Conditional modifier allowed only in OpenMP 5.0 and not supported in
3478     // distribute and taskloop based directives.
3479     if ((getLangOpts().OpenMP >= 50 && !isOpenMPDistributeDirective(DKind) &&
3480          !isOpenMPTaskLoopDirective(DKind)) &&
3481         Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::colon)) {
3482       Data.ExtraModifier = getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok),
3483                                                      getLangOpts().OpenMP);
3484       Data.ExtraModifierLoc = Tok.getLocation();
3485       ConsumeToken();
3486       assert(Tok.is(tok::colon) && "Expected colon.");
3487       Data.ColonLoc = ConsumeToken();
3488     }
3489   } else if (Kind == OMPC_map) {
3490     // Handle map type for map clause.
3491     ColonProtectionRAIIObject ColonRAII(*this);
3492 
3493     // The first identifier may be a list item, a map-type or a
3494     // map-type-modifier. The map-type can also be delete which has the same
3495     // spelling of the C++ delete keyword.
3496     Data.ExtraModifier = OMPC_MAP_unknown;
3497     Data.ExtraModifierLoc = Tok.getLocation();
3498 
3499     // Check for presence of a colon in the map clause.
3500     TentativeParsingAction TPA(*this);
3501     bool ColonPresent = false;
3502     if (SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3503         StopBeforeMatch)) {
3504       if (Tok.is(tok::colon))
3505         ColonPresent = true;
3506     }
3507     TPA.Revert();
3508     // Only parse map-type-modifier[s] and map-type if a colon is present in
3509     // the map clause.
3510     if (ColonPresent) {
3511       IsInvalidMapperModifier = parseMapTypeModifiers(Data);
3512       if (!IsInvalidMapperModifier)
3513         parseMapType(*this, Data);
3514       else
3515         SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch);
3516     }
3517     if (Data.ExtraModifier == OMPC_MAP_unknown) {
3518       Data.ExtraModifier = OMPC_MAP_tofrom;
3519       Data.IsMapTypeImplicit = true;
3520     }
3521 
3522     if (Tok.is(tok::colon))
3523       Data.ColonLoc = ConsumeToken();
3524   } else if (Kind == OMPC_to || Kind == OMPC_from) {
3525     while (Tok.is(tok::identifier)) {
3526       auto Modifier =
3527           static_cast<OpenMPMotionModifierKind>(getOpenMPSimpleClauseType(
3528               Kind, PP.getSpelling(Tok), getLangOpts().OpenMP));
3529       if (Modifier == OMPC_MOTION_MODIFIER_unknown)
3530         break;
3531       Data.MotionModifiers.push_back(Modifier);
3532       Data.MotionModifiersLoc.push_back(Tok.getLocation());
3533       ConsumeToken();
3534       if (Modifier == OMPC_MOTION_MODIFIER_mapper) {
3535         IsInvalidMapperModifier = parseMapperModifier(Data);
3536         if (IsInvalidMapperModifier)
3537           break;
3538       }
3539       // OpenMP < 5.1 doesn't permit a ',' or additional modifiers.
3540       if (getLangOpts().OpenMP < 51)
3541         break;
3542       // OpenMP 5.1 accepts an optional ',' even if the next character is ':'.
3543       // TODO: Is that intentional?
3544       if (Tok.is(tok::comma))
3545         ConsumeToken();
3546     }
3547     if (!Data.MotionModifiers.empty() && Tok.isNot(tok::colon)) {
3548       if (!IsInvalidMapperModifier) {
3549         if (getLangOpts().OpenMP < 51)
3550           Diag(Tok, diag::warn_pragma_expected_colon) << ")";
3551         else
3552           Diag(Tok, diag::warn_pragma_expected_colon) << "motion modifier";
3553       }
3554       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
3555                 StopBeforeMatch);
3556     }
3557     // OpenMP 5.1 permits a ':' even without a preceding modifier.  TODO: Is
3558     // that intentional?
3559     if ((!Data.MotionModifiers.empty() || getLangOpts().OpenMP >= 51) &&
3560         Tok.is(tok::colon))
3561       Data.ColonLoc = ConsumeToken();
3562   } else if (Kind == OMPC_allocate ||
3563              (Kind == OMPC_affinity && Tok.is(tok::identifier) &&
3564               PP.getSpelling(Tok) == "iterator")) {
3565     // Handle optional allocator expression followed by colon delimiter.
3566     ColonProtectionRAIIObject ColonRAII(*this);
3567     TentativeParsingAction TPA(*this);
3568     // OpenMP 5.0, 2.10.1, task Construct.
3569     // where aff-modifier is one of the following:
3570     // iterator(iterators-definition)
3571     ExprResult Tail;
3572     if (Kind == OMPC_allocate) {
3573       Tail = ParseAssignmentExpression();
3574     } else {
3575       HasIterator = true;
3576       EnterScope(Scope::OpenMPDirectiveScope | Scope::DeclScope);
3577       Tail = ParseOpenMPIteratorsExpr();
3578     }
3579     Tail = Actions.CorrectDelayedTyposInExpr(Tail);
3580     Tail = Actions.ActOnFinishFullExpr(Tail.get(), T.getOpenLocation(),
3581                                        /*DiscardedValue=*/false);
3582     if (Tail.isUsable()) {
3583       if (Tok.is(tok::colon)) {
3584         Data.DepModOrTailExpr = Tail.get();
3585         Data.ColonLoc = ConsumeToken();
3586         TPA.Commit();
3587       } else {
3588         // Colon not found, parse only list of variables.
3589         TPA.Revert();
3590       }
3591     } else {
3592       // Parsing was unsuccessfull, revert and skip to the end of clause or
3593       // directive.
3594       TPA.Revert();
3595       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3596                 StopBeforeMatch);
3597     }
3598   }
3599 
3600   bool IsComma =
3601       (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
3602        Kind != OMPC_in_reduction && Kind != OMPC_depend && Kind != OMPC_map) ||
3603       (Kind == OMPC_reduction && !InvalidReductionId) ||
3604       (Kind == OMPC_map && Data.ExtraModifier != OMPC_MAP_unknown) ||
3605       (Kind == OMPC_depend && Data.ExtraModifier != OMPC_DEPEND_unknown);
3606   const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
3607   while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
3608                      Tok.isNot(tok::annot_pragma_openmp_end))) {
3609     ParseScope OMPListScope(this, Scope::OpenMPDirectiveScope);
3610     ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
3611     // Parse variable
3612     ExprResult VarExpr =
3613         Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
3614     if (VarExpr.isUsable()) {
3615       Vars.push_back(VarExpr.get());
3616     } else {
3617       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3618                 StopBeforeMatch);
3619     }
3620     // Skip ',' if any
3621     IsComma = Tok.is(tok::comma);
3622     if (IsComma)
3623       ConsumeToken();
3624     else if (Tok.isNot(tok::r_paren) &&
3625              Tok.isNot(tok::annot_pragma_openmp_end) &&
3626              (!MayHaveTail || Tok.isNot(tok::colon)))
3627       Diag(Tok, diag::err_omp_expected_punc)
3628           << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
3629                                    : getOpenMPClauseName(Kind))
3630           << (Kind == OMPC_flush);
3631   }
3632 
3633   // Parse ')' for linear clause with modifier.
3634   if (NeedRParenForLinear)
3635     LinearT.consumeClose();
3636 
3637   // Parse ':' linear-step (or ':' alignment).
3638   const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
3639   if (MustHaveTail) {
3640     Data.ColonLoc = Tok.getLocation();
3641     SourceLocation ELoc = ConsumeToken();
3642     ExprResult Tail = ParseAssignmentExpression();
3643     Tail =
3644         Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false);
3645     if (Tail.isUsable())
3646       Data.DepModOrTailExpr = Tail.get();
3647     else
3648       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
3649                 StopBeforeMatch);
3650   }
3651 
3652   // Parse ')'.
3653   Data.RLoc = Tok.getLocation();
3654   if (!T.consumeClose())
3655     Data.RLoc = T.getCloseLocation();
3656   // Exit from scope when the iterator is used in depend clause.
3657   if (HasIterator)
3658     ExitScope();
3659   return (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
3660          (MustHaveTail && !Data.DepModOrTailExpr) || InvalidReductionId ||
3661          IsInvalidMapperModifier;
3662 }
3663 
3664 /// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
3665 /// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction',
3666 /// 'in_reduction', 'nontemporal', 'exclusive' or 'inclusive'.
3667 ///
3668 ///    private-clause:
3669 ///       'private' '(' list ')'
3670 ///    firstprivate-clause:
3671 ///       'firstprivate' '(' list ')'
3672 ///    lastprivate-clause:
3673 ///       'lastprivate' '(' list ')'
3674 ///    shared-clause:
3675 ///       'shared' '(' list ')'
3676 ///    linear-clause:
3677 ///       'linear' '(' linear-list [ ':' linear-step ] ')'
3678 ///    aligned-clause:
3679 ///       'aligned' '(' list [ ':' alignment ] ')'
3680 ///    reduction-clause:
3681 ///       'reduction' '(' [ modifier ',' ] reduction-identifier ':' list ')'
3682 ///    task_reduction-clause:
3683 ///       'task_reduction' '(' reduction-identifier ':' list ')'
3684 ///    in_reduction-clause:
3685 ///       'in_reduction' '(' reduction-identifier ':' list ')'
3686 ///    copyprivate-clause:
3687 ///       'copyprivate' '(' list ')'
3688 ///    flush-clause:
3689 ///       'flush' '(' list ')'
3690 ///    depend-clause:
3691 ///       'depend' '(' in | out | inout : list | source ')'
3692 ///    map-clause:
3693 ///       'map' '(' [ [ always [,] ] [ close [,] ]
3694 ///          [ mapper '(' mapper-identifier ')' [,] ]
3695 ///          to | from | tofrom | alloc | release | delete ':' ] list ')';
3696 ///    to-clause:
3697 ///       'to' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
3698 ///    from-clause:
3699 ///       'from' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
3700 ///    use_device_ptr-clause:
3701 ///       'use_device_ptr' '(' list ')'
3702 ///    use_device_addr-clause:
3703 ///       'use_device_addr' '(' list ')'
3704 ///    is_device_ptr-clause:
3705 ///       'is_device_ptr' '(' list ')'
3706 ///    allocate-clause:
3707 ///       'allocate' '(' [ allocator ':' ] list ')'
3708 ///    nontemporal-clause:
3709 ///       'nontemporal' '(' list ')'
3710 ///    inclusive-clause:
3711 ///       'inclusive' '(' list ')'
3712 ///    exclusive-clause:
3713 ///       'exclusive' '(' list ')'
3714 ///
3715 /// For 'linear' clause linear-list may have the following forms:
3716 ///  list
3717 ///  modifier(list)
3718 /// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
3719 OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
3720                                             OpenMPClauseKind Kind,
3721                                             bool ParseOnly) {
3722   SourceLocation Loc = Tok.getLocation();
3723   SourceLocation LOpen = ConsumeToken();
3724   SmallVector<Expr *, 4> Vars;
3725   OpenMPVarListDataTy Data;
3726 
3727   if (ParseOpenMPVarList(DKind, Kind, Vars, Data))
3728     return nullptr;
3729 
3730   if (ParseOnly)
3731     return nullptr;
3732   OMPVarListLocTy Locs(Loc, LOpen, Data.RLoc);
3733   return Actions.ActOnOpenMPVarListClause(
3734       Kind, Vars, Data.DepModOrTailExpr, Locs, Data.ColonLoc,
3735       Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId,
3736       Data.ExtraModifier, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
3737       Data.IsMapTypeImplicit, Data.ExtraModifierLoc, Data.MotionModifiers,
3738       Data.MotionModifiersLoc);
3739 }
3740 
3741