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/StmtOpenMP.h"
15 #include "clang/Parse/ParseDiagnostic.h"
16 #include "clang/Parse/Parser.h"
17 #include "clang/Parse/RAIIObjectsForParser.h"
18 #include "clang/Sema/Scope.h"
19 #include "llvm/ADT/PointerIntPair.h"
20 
21 using namespace clang;
22 
23 //===----------------------------------------------------------------------===//
24 // OpenMP declarative directives.
25 //===----------------------------------------------------------------------===//
26 
27 namespace {
28 enum OpenMPDirectiveKindEx {
29   OMPD_cancellation = OMPD_unknown + 1,
30   OMPD_data,
31   OMPD_declare,
32   OMPD_end,
33   OMPD_end_declare,
34   OMPD_enter,
35   OMPD_exit,
36   OMPD_point,
37   OMPD_reduction,
38   OMPD_target_enter,
39   OMPD_target_exit,
40   OMPD_update,
41   OMPD_distribute_parallel,
42   OMPD_teams_distribute_parallel,
43   OMPD_target_teams_distribute_parallel,
44   OMPD_mapper,
45 };
46 
47 class DeclDirectiveListParserHelper final {
48   SmallVector<Expr *, 4> Identifiers;
49   Parser *P;
50   OpenMPDirectiveKind Kind;
51 
52 public:
53   DeclDirectiveListParserHelper(Parser *P, OpenMPDirectiveKind Kind)
54       : P(P), Kind(Kind) {}
55   void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
56     ExprResult Res = P->getActions().ActOnOpenMPIdExpression(
57         P->getCurScope(), SS, NameInfo, Kind);
58     if (Res.isUsable())
59       Identifiers.push_back(Res.get());
60   }
61   llvm::ArrayRef<Expr *> getIdentifiers() const { return Identifiers; }
62 };
63 } // namespace
64 
65 // Map token string to extended OMP token kind that are
66 // OpenMPDirectiveKind + OpenMPDirectiveKindEx.
67 static unsigned getOpenMPDirectiveKindEx(StringRef S) {
68   auto DKind = getOpenMPDirectiveKind(S);
69   if (DKind != OMPD_unknown)
70     return DKind;
71 
72   return llvm::StringSwitch<unsigned>(S)
73       .Case("cancellation", OMPD_cancellation)
74       .Case("data", OMPD_data)
75       .Case("declare", OMPD_declare)
76       .Case("end", OMPD_end)
77       .Case("enter", OMPD_enter)
78       .Case("exit", OMPD_exit)
79       .Case("point", OMPD_point)
80       .Case("reduction", OMPD_reduction)
81       .Case("update", OMPD_update)
82       .Case("mapper", OMPD_mapper)
83       .Default(OMPD_unknown);
84 }
85 
86 static OpenMPDirectiveKind parseOpenMPDirectiveKind(Parser &P) {
87   // Array of foldings: F[i][0] F[i][1] ===> F[i][2].
88   // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd
89   // TODO: add other combined directives in topological order.
90   static const unsigned F[][3] = {
91       {OMPD_cancellation, OMPD_point, OMPD_cancellation_point},
92       {OMPD_declare, OMPD_reduction, OMPD_declare_reduction},
93       {OMPD_declare, OMPD_mapper, OMPD_declare_mapper},
94       {OMPD_declare, OMPD_simd, OMPD_declare_simd},
95       {OMPD_declare, OMPD_target, OMPD_declare_target},
96       {OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel},
97       {OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for},
98       {OMPD_distribute_parallel_for, OMPD_simd,
99        OMPD_distribute_parallel_for_simd},
100       {OMPD_distribute, OMPD_simd, OMPD_distribute_simd},
101       {OMPD_end, OMPD_declare, OMPD_end_declare},
102       {OMPD_end_declare, OMPD_target, OMPD_end_declare_target},
103       {OMPD_target, OMPD_data, OMPD_target_data},
104       {OMPD_target, OMPD_enter, OMPD_target_enter},
105       {OMPD_target, OMPD_exit, OMPD_target_exit},
106       {OMPD_target, OMPD_update, OMPD_target_update},
107       {OMPD_target_enter, OMPD_data, OMPD_target_enter_data},
108       {OMPD_target_exit, OMPD_data, OMPD_target_exit_data},
109       {OMPD_for, OMPD_simd, OMPD_for_simd},
110       {OMPD_parallel, OMPD_for, OMPD_parallel_for},
111       {OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},
112       {OMPD_parallel, OMPD_sections, OMPD_parallel_sections},
113       {OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd},
114       {OMPD_target, OMPD_parallel, OMPD_target_parallel},
115       {OMPD_target, OMPD_simd, OMPD_target_simd},
116       {OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for},
117       {OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd},
118       {OMPD_teams, OMPD_distribute, OMPD_teams_distribute},
119       {OMPD_teams_distribute, OMPD_simd, OMPD_teams_distribute_simd},
120       {OMPD_teams_distribute, OMPD_parallel, OMPD_teams_distribute_parallel},
121       {OMPD_teams_distribute_parallel, OMPD_for,
122        OMPD_teams_distribute_parallel_for},
123       {OMPD_teams_distribute_parallel_for, OMPD_simd,
124        OMPD_teams_distribute_parallel_for_simd},
125       {OMPD_target, OMPD_teams, OMPD_target_teams},
126       {OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute},
127       {OMPD_target_teams_distribute, OMPD_parallel,
128        OMPD_target_teams_distribute_parallel},
129       {OMPD_target_teams_distribute, OMPD_simd,
130        OMPD_target_teams_distribute_simd},
131       {OMPD_target_teams_distribute_parallel, OMPD_for,
132        OMPD_target_teams_distribute_parallel_for},
133       {OMPD_target_teams_distribute_parallel_for, OMPD_simd,
134        OMPD_target_teams_distribute_parallel_for_simd}};
135   enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };
136   Token Tok = P.getCurToken();
137   unsigned DKind =
138       Tok.isAnnotation()
139           ? static_cast<unsigned>(OMPD_unknown)
140           : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
141   if (DKind == OMPD_unknown)
142     return OMPD_unknown;
143 
144   for (unsigned I = 0; I < llvm::array_lengthof(F); ++I) {
145     if (DKind != F[I][0])
146       continue;
147 
148     Tok = P.getPreprocessor().LookAhead(0);
149     unsigned SDKind =
150         Tok.isAnnotation()
151             ? static_cast<unsigned>(OMPD_unknown)
152             : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
153     if (SDKind == OMPD_unknown)
154       continue;
155 
156     if (SDKind == F[I][1]) {
157       P.ConsumeToken();
158       DKind = F[I][2];
159     }
160   }
161   return DKind < OMPD_unknown ? static_cast<OpenMPDirectiveKind>(DKind)
162                               : OMPD_unknown;
163 }
164 
165 static DeclarationName parseOpenMPReductionId(Parser &P) {
166   Token Tok = P.getCurToken();
167   Sema &Actions = P.getActions();
168   OverloadedOperatorKind OOK = OO_None;
169   // Allow to use 'operator' keyword for C++ operators
170   bool WithOperator = false;
171   if (Tok.is(tok::kw_operator)) {
172     P.ConsumeToken();
173     Tok = P.getCurToken();
174     WithOperator = true;
175   }
176   switch (Tok.getKind()) {
177   case tok::plus: // '+'
178     OOK = OO_Plus;
179     break;
180   case tok::minus: // '-'
181     OOK = OO_Minus;
182     break;
183   case tok::star: // '*'
184     OOK = OO_Star;
185     break;
186   case tok::amp: // '&'
187     OOK = OO_Amp;
188     break;
189   case tok::pipe: // '|'
190     OOK = OO_Pipe;
191     break;
192   case tok::caret: // '^'
193     OOK = OO_Caret;
194     break;
195   case tok::ampamp: // '&&'
196     OOK = OO_AmpAmp;
197     break;
198   case tok::pipepipe: // '||'
199     OOK = OO_PipePipe;
200     break;
201   case tok::identifier: // identifier
202     if (!WithOperator)
203       break;
204     LLVM_FALLTHROUGH;
205   default:
206     P.Diag(Tok.getLocation(), diag::err_omp_expected_reduction_identifier);
207     P.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
208                 Parser::StopBeforeMatch);
209     return DeclarationName();
210   }
211   P.ConsumeToken();
212   auto &DeclNames = Actions.getASTContext().DeclarationNames;
213   return OOK == OO_None ? DeclNames.getIdentifier(Tok.getIdentifierInfo())
214                         : DeclNames.getCXXOperatorName(OOK);
215 }
216 
217 /// Parse 'omp declare reduction' construct.
218 ///
219 ///       declare-reduction-directive:
220 ///        annot_pragma_openmp 'declare' 'reduction'
221 ///        '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')'
222 ///        ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')']
223 ///        annot_pragma_openmp_end
224 /// <reduction_id> is either a base language identifier or one of the following
225 /// operators: '+', '-', '*', '&', '|', '^', '&&' and '||'.
226 ///
227 Parser::DeclGroupPtrTy
228 Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
229   // Parse '('.
230   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
231   if (T.expectAndConsume(diag::err_expected_lparen_after,
232                          getOpenMPDirectiveName(OMPD_declare_reduction))) {
233     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
234     return DeclGroupPtrTy();
235   }
236 
237   DeclarationName Name = parseOpenMPReductionId(*this);
238   if (Name.isEmpty() && Tok.is(tok::annot_pragma_openmp_end))
239     return DeclGroupPtrTy();
240 
241   // Consume ':'.
242   bool IsCorrect = !ExpectAndConsume(tok::colon);
243 
244   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
245     return DeclGroupPtrTy();
246 
247   IsCorrect = IsCorrect && !Name.isEmpty();
248 
249   if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) {
250     Diag(Tok.getLocation(), diag::err_expected_type);
251     IsCorrect = false;
252   }
253 
254   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
255     return DeclGroupPtrTy();
256 
257   SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes;
258   // Parse list of types until ':' token.
259   do {
260     ColonProtectionRAIIObject ColonRAII(*this);
261     SourceRange Range;
262     TypeResult TR =
263         ParseTypeName(&Range, DeclaratorContext::PrototypeContext, AS);
264     if (TR.isUsable()) {
265       QualType ReductionType =
266           Actions.ActOnOpenMPDeclareReductionType(Range.getBegin(), TR);
267       if (!ReductionType.isNull()) {
268         ReductionTypes.push_back(
269             std::make_pair(ReductionType, Range.getBegin()));
270       }
271     } else {
272       SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
273                 StopBeforeMatch);
274     }
275 
276     if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end))
277       break;
278 
279     // Consume ','.
280     if (ExpectAndConsume(tok::comma)) {
281       IsCorrect = false;
282       if (Tok.is(tok::annot_pragma_openmp_end)) {
283         Diag(Tok.getLocation(), diag::err_expected_type);
284         return DeclGroupPtrTy();
285       }
286     }
287   } while (Tok.isNot(tok::annot_pragma_openmp_end));
288 
289   if (ReductionTypes.empty()) {
290     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
291     return DeclGroupPtrTy();
292   }
293 
294   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
295     return DeclGroupPtrTy();
296 
297   // Consume ':'.
298   if (ExpectAndConsume(tok::colon))
299     IsCorrect = false;
300 
301   if (Tok.is(tok::annot_pragma_openmp_end)) {
302     Diag(Tok.getLocation(), diag::err_expected_expression);
303     return DeclGroupPtrTy();
304   }
305 
306   DeclGroupPtrTy DRD = Actions.ActOnOpenMPDeclareReductionDirectiveStart(
307       getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes, AS);
308 
309   // Parse <combiner> expression and then parse initializer if any for each
310   // correct type.
311   unsigned I = 0, E = ReductionTypes.size();
312   for (Decl *D : DRD.get()) {
313     TentativeParsingAction TPA(*this);
314     ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
315                                     Scope::CompoundStmtScope |
316                                     Scope::OpenMPDirectiveScope);
317     // Parse <combiner> expression.
318     Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D);
319     ExprResult CombinerResult =
320         Actions.ActOnFinishFullExpr(ParseAssignmentExpression().get(),
321                                     D->getLocation(), /*DiscardedValue*/ false);
322     Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get());
323 
324     if (CombinerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
325         Tok.isNot(tok::annot_pragma_openmp_end)) {
326       TPA.Commit();
327       IsCorrect = false;
328       break;
329     }
330     IsCorrect = !T.consumeClose() && IsCorrect && CombinerResult.isUsable();
331     ExprResult InitializerResult;
332     if (Tok.isNot(tok::annot_pragma_openmp_end)) {
333       // Parse <initializer> expression.
334       if (Tok.is(tok::identifier) &&
335           Tok.getIdentifierInfo()->isStr("initializer")) {
336         ConsumeToken();
337       } else {
338         Diag(Tok.getLocation(), diag::err_expected) << "'initializer'";
339         TPA.Commit();
340         IsCorrect = false;
341         break;
342       }
343       // Parse '('.
344       BalancedDelimiterTracker T(*this, tok::l_paren,
345                                  tok::annot_pragma_openmp_end);
346       IsCorrect =
347           !T.expectAndConsume(diag::err_expected_lparen_after, "initializer") &&
348           IsCorrect;
349       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
350         ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
351                                         Scope::CompoundStmtScope |
352                                         Scope::OpenMPDirectiveScope);
353         // Parse expression.
354         VarDecl *OmpPrivParm =
355             Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(),
356                                                                 D);
357         // Check if initializer is omp_priv <init_expr> or something else.
358         if (Tok.is(tok::identifier) &&
359             Tok.getIdentifierInfo()->isStr("omp_priv")) {
360           if (Actions.getLangOpts().CPlusPlus) {
361             InitializerResult = Actions.ActOnFinishFullExpr(
362                 ParseAssignmentExpression().get(), D->getLocation(),
363                 /*DiscardedValue*/ false);
364           } else {
365             ConsumeToken();
366             ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
367           }
368         } else {
369           InitializerResult = Actions.ActOnFinishFullExpr(
370               ParseAssignmentExpression().get(), D->getLocation(),
371               /*DiscardedValue*/ false);
372         }
373         Actions.ActOnOpenMPDeclareReductionInitializerEnd(
374             D, InitializerResult.get(), OmpPrivParm);
375         if (InitializerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
376             Tok.isNot(tok::annot_pragma_openmp_end)) {
377           TPA.Commit();
378           IsCorrect = false;
379           break;
380         }
381         IsCorrect =
382             !T.consumeClose() && IsCorrect && !InitializerResult.isInvalid();
383       }
384     }
385 
386     ++I;
387     // Revert parsing if not the last type, otherwise accept it, we're done with
388     // parsing.
389     if (I != E)
390       TPA.Revert();
391     else
392       TPA.Commit();
393   }
394   return Actions.ActOnOpenMPDeclareReductionDirectiveEnd(getCurScope(), DRD,
395                                                          IsCorrect);
396 }
397 
398 void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
399   // Parse declarator '=' initializer.
400   // If a '==' or '+=' is found, suggest a fixit to '='.
401   if (isTokenEqualOrEqualTypo()) {
402     ConsumeToken();
403 
404     if (Tok.is(tok::code_completion)) {
405       Actions.CodeCompleteInitializer(getCurScope(), OmpPrivParm);
406       Actions.FinalizeDeclaration(OmpPrivParm);
407       cutOffParsing();
408       return;
409     }
410 
411     ExprResult Init(ParseInitializer());
412 
413     if (Init.isInvalid()) {
414       SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
415       Actions.ActOnInitializerError(OmpPrivParm);
416     } else {
417       Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
418                                    /*DirectInit=*/false);
419     }
420   } else if (Tok.is(tok::l_paren)) {
421     // Parse C++ direct initializer: '(' expression-list ')'
422     BalancedDelimiterTracker T(*this, tok::l_paren);
423     T.consumeOpen();
424 
425     ExprVector Exprs;
426     CommaLocsTy CommaLocs;
427 
428     SourceLocation LParLoc = T.getOpenLocation();
429     auto RunSignatureHelp = [this, OmpPrivParm, LParLoc, &Exprs]() {
430       QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
431           getCurScope(), OmpPrivParm->getType()->getCanonicalTypeInternal(),
432           OmpPrivParm->getLocation(), Exprs, LParLoc);
433       CalledSignatureHelp = true;
434       return PreferredType;
435     };
436     if (ParseExpressionList(Exprs, CommaLocs, [&] {
437           PreferredType.enterFunctionArgument(Tok.getLocation(),
438                                               RunSignatureHelp);
439         })) {
440       if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
441         RunSignatureHelp();
442       Actions.ActOnInitializerError(OmpPrivParm);
443       SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
444     } else {
445       // Match the ')'.
446       SourceLocation RLoc = Tok.getLocation();
447       if (!T.consumeClose())
448         RLoc = T.getCloseLocation();
449 
450       assert(!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size() &&
451              "Unexpected number of commas!");
452 
453       ExprResult Initializer =
454           Actions.ActOnParenListExpr(T.getOpenLocation(), RLoc, Exprs);
455       Actions.AddInitializerToDecl(OmpPrivParm, Initializer.get(),
456                                    /*DirectInit=*/true);
457     }
458   } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
459     // Parse C++0x braced-init-list.
460     Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
461 
462     ExprResult Init(ParseBraceInitializer());
463 
464     if (Init.isInvalid()) {
465       Actions.ActOnInitializerError(OmpPrivParm);
466     } else {
467       Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
468                                    /*DirectInit=*/true);
469     }
470   } else {
471     Actions.ActOnUninitializedDecl(OmpPrivParm);
472   }
473 }
474 
475 /// Parses 'omp declare mapper' directive.
476 ///
477 ///       declare-mapper-directive:
478 ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifier> ':']
479 ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
480 ///         annot_pragma_openmp_end
481 /// <mapper-identifier> and <var> are base language identifiers.
482 ///
483 Parser::DeclGroupPtrTy
484 Parser::ParseOpenMPDeclareMapperDirective(AccessSpecifier AS) {
485   bool IsCorrect = true;
486   // Parse '('
487   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
488   if (T.expectAndConsume(diag::err_expected_lparen_after,
489                          getOpenMPDirectiveName(OMPD_declare_mapper))) {
490     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
491     return DeclGroupPtrTy();
492   }
493 
494   // Parse <mapper-identifier>
495   auto &DeclNames = Actions.getASTContext().DeclarationNames;
496   DeclarationName MapperId;
497   if (PP.LookAhead(0).is(tok::colon)) {
498     if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
499       Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
500       IsCorrect = false;
501     } else {
502       MapperId = DeclNames.getIdentifier(Tok.getIdentifierInfo());
503     }
504     ConsumeToken();
505     // Consume ':'.
506     ExpectAndConsume(tok::colon);
507   } else {
508     // If no mapper identifier is provided, its name is "default" by default
509     MapperId =
510         DeclNames.getIdentifier(&Actions.getASTContext().Idents.get("default"));
511   }
512 
513   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
514     return DeclGroupPtrTy();
515 
516   // Parse <type> <var>
517   DeclarationName VName;
518   QualType MapperType;
519   SourceRange Range;
520   TypeResult ParsedType = parseOpenMPDeclareMapperVarDecl(Range, VName, AS);
521   if (ParsedType.isUsable())
522     MapperType =
523         Actions.ActOnOpenMPDeclareMapperType(Range.getBegin(), ParsedType);
524   if (MapperType.isNull())
525     IsCorrect = false;
526   if (!IsCorrect) {
527     SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
528     return DeclGroupPtrTy();
529   }
530 
531   // Consume ')'.
532   IsCorrect &= !T.consumeClose();
533   if (!IsCorrect) {
534     SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
535     return DeclGroupPtrTy();
536   }
537 
538   // Enter scope.
539   OMPDeclareMapperDecl *DMD = Actions.ActOnOpenMPDeclareMapperDirectiveStart(
540       getCurScope(), Actions.getCurLexicalContext(), MapperId, MapperType,
541       Range.getBegin(), VName, AS);
542   DeclarationNameInfo DirName;
543   SourceLocation Loc = Tok.getLocation();
544   unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
545                         Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
546   ParseScope OMPDirectiveScope(this, ScopeFlags);
547   Actions.StartOpenMPDSABlock(OMPD_declare_mapper, DirName, getCurScope(), Loc);
548 
549   // Add the mapper variable declaration.
550   Actions.ActOnOpenMPDeclareMapperDirectiveVarDecl(
551       DMD, getCurScope(), MapperType, Range.getBegin(), VName);
552 
553   // Parse map clauses.
554   SmallVector<OMPClause *, 6> Clauses;
555   while (Tok.isNot(tok::annot_pragma_openmp_end)) {
556     OpenMPClauseKind CKind = Tok.isAnnotation()
557                                  ? OMPC_unknown
558                                  : getOpenMPClauseKind(PP.getSpelling(Tok));
559     Actions.StartOpenMPClause(CKind);
560     OMPClause *Clause =
561         ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.size() == 0);
562     if (Clause)
563       Clauses.push_back(Clause);
564     else
565       IsCorrect = false;
566     // Skip ',' if any.
567     if (Tok.is(tok::comma))
568       ConsumeToken();
569     Actions.EndOpenMPClause();
570   }
571   if (Clauses.empty()) {
572     Diag(Tok, diag::err_omp_expected_clause)
573         << getOpenMPDirectiveName(OMPD_declare_mapper);
574     IsCorrect = false;
575   }
576 
577   // Exit scope.
578   Actions.EndOpenMPDSABlock(nullptr);
579   OMPDirectiveScope.Exit();
580 
581   DeclGroupPtrTy DGP =
582       Actions.ActOnOpenMPDeclareMapperDirectiveEnd(DMD, getCurScope(), Clauses);
583   if (!IsCorrect)
584     return DeclGroupPtrTy();
585   return DGP;
586 }
587 
588 TypeResult Parser::parseOpenMPDeclareMapperVarDecl(SourceRange &Range,
589                                                    DeclarationName &Name,
590                                                    AccessSpecifier AS) {
591   // Parse the common declaration-specifiers piece.
592   Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;
593   DeclSpec DS(AttrFactory);
594   ParseSpecifierQualifierList(DS, AS, DSC);
595 
596   // Parse the declarator.
597   DeclaratorContext Context = DeclaratorContext::PrototypeContext;
598   Declarator DeclaratorInfo(DS, Context);
599   ParseDeclarator(DeclaratorInfo);
600   Range = DeclaratorInfo.getSourceRange();
601   if (DeclaratorInfo.getIdentifier() == nullptr) {
602     Diag(Tok.getLocation(), diag::err_omp_mapper_expected_declarator);
603     return true;
604   }
605   Name = Actions.GetNameForDeclarator(DeclaratorInfo).getName();
606 
607   return Actions.ActOnOpenMPDeclareMapperVarDecl(getCurScope(), DeclaratorInfo);
608 }
609 
610 namespace {
611 /// RAII that recreates function context for correct parsing of clauses of
612 /// 'declare simd' construct.
613 /// OpenMP, 2.8.2 declare simd Construct
614 /// The expressions appearing in the clauses of this directive are evaluated in
615 /// the scope of the arguments of the function declaration or definition.
616 class FNContextRAII final {
617   Parser &P;
618   Sema::CXXThisScopeRAII *ThisScope;
619   Parser::ParseScope *TempScope;
620   Parser::ParseScope *FnScope;
621   bool HasTemplateScope = false;
622   bool HasFunScope = false;
623   FNContextRAII() = delete;
624   FNContextRAII(const FNContextRAII &) = delete;
625   FNContextRAII &operator=(const FNContextRAII &) = delete;
626 
627 public:
628   FNContextRAII(Parser &P, Parser::DeclGroupPtrTy Ptr) : P(P) {
629     Decl *D = *Ptr.get().begin();
630     NamedDecl *ND = dyn_cast<NamedDecl>(D);
631     RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
632     Sema &Actions = P.getActions();
633 
634     // Allow 'this' within late-parsed attributes.
635     ThisScope = new Sema::CXXThisScopeRAII(Actions, RD, Qualifiers(),
636                                            ND && ND->isCXXInstanceMember());
637 
638     // If the Decl is templatized, add template parameters to scope.
639     HasTemplateScope = D->isTemplateDecl();
640     TempScope =
641         new Parser::ParseScope(&P, Scope::TemplateParamScope, HasTemplateScope);
642     if (HasTemplateScope)
643       Actions.ActOnReenterTemplateScope(Actions.getCurScope(), D);
644 
645     // If the Decl is on a function, add function parameters to the scope.
646     HasFunScope = D->isFunctionOrFunctionTemplate();
647     FnScope = new Parser::ParseScope(
648         &P, Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope,
649         HasFunScope);
650     if (HasFunScope)
651       Actions.ActOnReenterFunctionContext(Actions.getCurScope(), D);
652   }
653   ~FNContextRAII() {
654     if (HasFunScope) {
655       P.getActions().ActOnExitFunctionContext();
656       FnScope->Exit(); // Pop scope, and remove Decls from IdResolver
657     }
658     if (HasTemplateScope)
659       TempScope->Exit();
660     delete FnScope;
661     delete TempScope;
662     delete ThisScope;
663   }
664 };
665 } // namespace
666 
667 /// Parses clauses for 'declare simd' directive.
668 ///    clause:
669 ///      'inbranch' | 'notinbranch'
670 ///      'simdlen' '(' <expr> ')'
671 ///      { 'uniform' '(' <argument_list> ')' }
672 ///      { 'aligned '(' <argument_list> [ ':' <alignment> ] ')' }
673 ///      { 'linear '(' <argument_list> [ ':' <step> ] ')' }
674 static bool parseDeclareSimdClauses(
675     Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, ExprResult &SimdLen,
676     SmallVectorImpl<Expr *> &Uniforms, SmallVectorImpl<Expr *> &Aligneds,
677     SmallVectorImpl<Expr *> &Alignments, SmallVectorImpl<Expr *> &Linears,
678     SmallVectorImpl<unsigned> &LinModifiers, SmallVectorImpl<Expr *> &Steps) {
679   SourceRange BSRange;
680   const Token &Tok = P.getCurToken();
681   bool IsError = false;
682   while (Tok.isNot(tok::annot_pragma_openmp_end)) {
683     if (Tok.isNot(tok::identifier))
684       break;
685     OMPDeclareSimdDeclAttr::BranchStateTy Out;
686     IdentifierInfo *II = Tok.getIdentifierInfo();
687     StringRef ClauseName = II->getName();
688     // Parse 'inranch|notinbranch' clauses.
689     if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
690       if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
691         P.Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
692             << ClauseName
693             << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
694         IsError = true;
695       }
696       BS = Out;
697       BSRange = SourceRange(Tok.getLocation(), Tok.getEndLoc());
698       P.ConsumeToken();
699     } else if (ClauseName.equals("simdlen")) {
700       if (SimdLen.isUsable()) {
701         P.Diag(Tok, diag::err_omp_more_one_clause)
702             << getOpenMPDirectiveName(OMPD_declare_simd) << ClauseName << 0;
703         IsError = true;
704       }
705       P.ConsumeToken();
706       SourceLocation RLoc;
707       SimdLen = P.ParseOpenMPParensExpr(ClauseName, RLoc);
708       if (SimdLen.isInvalid())
709         IsError = true;
710     } else {
711       OpenMPClauseKind CKind = getOpenMPClauseKind(ClauseName);
712       if (CKind == OMPC_uniform || CKind == OMPC_aligned ||
713           CKind == OMPC_linear) {
714         Parser::OpenMPVarListDataTy Data;
715         SmallVectorImpl<Expr *> *Vars = &Uniforms;
716         if (CKind == OMPC_aligned)
717           Vars = &Aligneds;
718         else if (CKind == OMPC_linear)
719           Vars = &Linears;
720 
721         P.ConsumeToken();
722         if (P.ParseOpenMPVarList(OMPD_declare_simd,
723                                  getOpenMPClauseKind(ClauseName), *Vars, Data))
724           IsError = true;
725         if (CKind == OMPC_aligned) {
726           Alignments.append(Aligneds.size() - Alignments.size(), Data.TailExpr);
727         } else if (CKind == OMPC_linear) {
728           if (P.getActions().CheckOpenMPLinearModifier(Data.LinKind,
729                                                        Data.DepLinMapLoc))
730             Data.LinKind = OMPC_LINEAR_val;
731           LinModifiers.append(Linears.size() - LinModifiers.size(),
732                               Data.LinKind);
733           Steps.append(Linears.size() - Steps.size(), Data.TailExpr);
734         }
735       } else
736         // TODO: add parsing of other clauses.
737         break;
738     }
739     // Skip ',' if any.
740     if (Tok.is(tok::comma))
741       P.ConsumeToken();
742   }
743   return IsError;
744 }
745 
746 /// Parse clauses for '#pragma omp declare simd'.
747 Parser::DeclGroupPtrTy
748 Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
749                                    CachedTokens &Toks, SourceLocation Loc) {
750   PP.EnterToken(Tok);
751   PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
752   // Consume the previously pushed token.
753   ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
754 
755   FNContextRAII FnContext(*this, Ptr);
756   OMPDeclareSimdDeclAttr::BranchStateTy BS =
757       OMPDeclareSimdDeclAttr::BS_Undefined;
758   ExprResult Simdlen;
759   SmallVector<Expr *, 4> Uniforms;
760   SmallVector<Expr *, 4> Aligneds;
761   SmallVector<Expr *, 4> Alignments;
762   SmallVector<Expr *, 4> Linears;
763   SmallVector<unsigned, 4> LinModifiers;
764   SmallVector<Expr *, 4> Steps;
765   bool IsError =
766       parseDeclareSimdClauses(*this, BS, Simdlen, Uniforms, Aligneds,
767                               Alignments, Linears, LinModifiers, Steps);
768   // Need to check for extra tokens.
769   if (Tok.isNot(tok::annot_pragma_openmp_end)) {
770     Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
771         << getOpenMPDirectiveName(OMPD_declare_simd);
772     while (Tok.isNot(tok::annot_pragma_openmp_end))
773       ConsumeAnyToken();
774   }
775   // Skip the last annot_pragma_openmp_end.
776   SourceLocation EndLoc = ConsumeAnnotationToken();
777   if (IsError)
778     return Ptr;
779   return Actions.ActOnOpenMPDeclareSimdDirective(
780       Ptr, BS, Simdlen.get(), Uniforms, Aligneds, Alignments, Linears,
781       LinModifiers, Steps, SourceRange(Loc, EndLoc));
782 }
783 
784 Parser::DeclGroupPtrTy Parser::ParseOMPDeclareTargetClauses() {
785   // OpenMP 4.5 syntax with list of entities.
786   Sema::NamedDeclSetType SameDirectiveDecls;
787   while (Tok.isNot(tok::annot_pragma_openmp_end)) {
788     OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
789     if (Tok.is(tok::identifier)) {
790       IdentifierInfo *II = Tok.getIdentifierInfo();
791       StringRef ClauseName = II->getName();
792       // Parse 'to|link' clauses.
793       if (!OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT)) {
794         Diag(Tok, diag::err_omp_declare_target_unexpected_clause) << ClauseName;
795         break;
796       }
797       ConsumeToken();
798     }
799     auto &&Callback = [this, MT, &SameDirectiveDecls](
800         CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
801       Actions.ActOnOpenMPDeclareTargetName(getCurScope(), SS, NameInfo, MT,
802                                            SameDirectiveDecls);
803     };
804     if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
805                                  /*AllowScopeSpecifier=*/true))
806       break;
807 
808     // Consume optional ','.
809     if (Tok.is(tok::comma))
810       ConsumeToken();
811   }
812   SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
813   ConsumeAnyToken();
814   SmallVector<Decl *, 4> Decls(SameDirectiveDecls.begin(),
815                                SameDirectiveDecls.end());
816   if (Decls.empty())
817     return DeclGroupPtrTy();
818   return Actions.BuildDeclaratorGroup(Decls);
819 }
820 
821 void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind DKind,
822                                                SourceLocation DTLoc) {
823   if (DKind != OMPD_end_declare_target) {
824     Diag(Tok, diag::err_expected_end_declare_target);
825     Diag(DTLoc, diag::note_matching) << "'#pragma omp declare target'";
826     return;
827   }
828   ConsumeAnyToken();
829   if (Tok.isNot(tok::annot_pragma_openmp_end)) {
830     Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
831         << getOpenMPDirectiveName(OMPD_end_declare_target);
832     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
833   }
834   // Skip the last annot_pragma_openmp_end.
835   ConsumeAnyToken();
836 }
837 
838 /// Parsing of declarative OpenMP directives.
839 ///
840 ///       threadprivate-directive:
841 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
842 ///         annot_pragma_openmp_end
843 ///
844 ///       allocate-directive:
845 ///         annot_pragma_openmp 'allocate' simple-variable-list
846 ///         annot_pragma_openmp_end
847 ///
848 ///       declare-reduction-directive:
849 ///        annot_pragma_openmp 'declare' 'reduction' [...]
850 ///        annot_pragma_openmp_end
851 ///
852 ///       declare-mapper-directive:
853 ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
854 ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
855 ///         annot_pragma_openmp_end
856 ///
857 ///       declare-simd-directive:
858 ///         annot_pragma_openmp 'declare simd' {<clause> [,]}
859 ///         annot_pragma_openmp_end
860 ///         <function declaration/definition>
861 ///
862 ///       requires directive:
863 ///         annot_pragma_openmp 'requires' <clause> [[[,] <clause>] ... ]
864 ///         annot_pragma_openmp_end
865 ///
866 Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
867     AccessSpecifier &AS, ParsedAttributesWithRange &Attrs,
868     DeclSpec::TST TagType, Decl *Tag) {
869   assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
870   ParenBraceBracketBalancer BalancerRAIIObj(*this);
871 
872   SourceLocation Loc = ConsumeAnnotationToken();
873   OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
874 
875   switch (DKind) {
876   case OMPD_threadprivate: {
877     ConsumeToken();
878     DeclDirectiveListParserHelper Helper(this, DKind);
879     if (!ParseOpenMPSimpleVarList(DKind, Helper,
880                                   /*AllowScopeSpecifier=*/true)) {
881       // The last seen token is annot_pragma_openmp_end - need to check for
882       // extra tokens.
883       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
884         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
885             << getOpenMPDirectiveName(DKind);
886         SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
887       }
888       // Skip the last annot_pragma_openmp_end.
889       ConsumeAnnotationToken();
890       return Actions.ActOnOpenMPThreadprivateDirective(Loc,
891                                                        Helper.getIdentifiers());
892     }
893     break;
894   }
895   case OMPD_allocate: {
896     ConsumeToken();
897     DeclDirectiveListParserHelper Helper(this, DKind);
898     if (!ParseOpenMPSimpleVarList(DKind, Helper,
899                                   /*AllowScopeSpecifier=*/true)) {
900       // The last seen token is annot_pragma_openmp_end - need to check for
901       // extra tokens.
902       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
903         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
904             << getOpenMPDirectiveName(DKind);
905         SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
906       }
907       // Skip the last annot_pragma_openmp_end.
908       ConsumeAnnotationToken();
909       return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers());
910     }
911     break;
912   }
913   case OMPD_requires: {
914     SourceLocation StartLoc = ConsumeToken();
915     SmallVector<OMPClause *, 5> Clauses;
916     SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
917     FirstClauses(OMPC_unknown + 1);
918     if (Tok.is(tok::annot_pragma_openmp_end)) {
919       Diag(Tok, diag::err_omp_expected_clause)
920           << getOpenMPDirectiveName(OMPD_requires);
921       break;
922     }
923     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
924       OpenMPClauseKind CKind = Tok.isAnnotation()
925                                    ? OMPC_unknown
926                                    : getOpenMPClauseKind(PP.getSpelling(Tok));
927       Actions.StartOpenMPClause(CKind);
928       OMPClause *Clause =
929           ParseOpenMPClause(OMPD_requires, CKind, !FirstClauses[CKind].getInt());
930       SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end, StopBeforeMatch);
931       FirstClauses[CKind].setInt(true);
932       if (Clause != nullptr)
933         Clauses.push_back(Clause);
934       if (Tok.is(tok::annot_pragma_openmp_end)) {
935         Actions.EndOpenMPClause();
936         break;
937       }
938       // Skip ',' if any.
939       if (Tok.is(tok::comma))
940         ConsumeToken();
941       Actions.EndOpenMPClause();
942     }
943     // Consume final annot_pragma_openmp_end
944     if (Clauses.size() == 0) {
945       Diag(Tok, diag::err_omp_expected_clause)
946           << getOpenMPDirectiveName(OMPD_requires);
947       ConsumeAnnotationToken();
948       return nullptr;
949     }
950     ConsumeAnnotationToken();
951     return Actions.ActOnOpenMPRequiresDirective(StartLoc, Clauses);
952   }
953   case OMPD_declare_reduction:
954     ConsumeToken();
955     if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
956       // The last seen token is annot_pragma_openmp_end - need to check for
957       // extra tokens.
958       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
959         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
960             << getOpenMPDirectiveName(OMPD_declare_reduction);
961         while (Tok.isNot(tok::annot_pragma_openmp_end))
962           ConsumeAnyToken();
963       }
964       // Skip the last annot_pragma_openmp_end.
965       ConsumeAnnotationToken();
966       return Res;
967     }
968     break;
969   case OMPD_declare_mapper: {
970     ConsumeToken();
971     if (DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
972       // Skip the last annot_pragma_openmp_end.
973       ConsumeAnnotationToken();
974       return Res;
975     }
976     break;
977   }
978   case OMPD_declare_simd: {
979     // The syntax is:
980     // { #pragma omp declare simd }
981     // <function-declaration-or-definition>
982     //
983     ConsumeToken();
984     CachedTokens Toks;
985     while(Tok.isNot(tok::annot_pragma_openmp_end)) {
986       Toks.push_back(Tok);
987       ConsumeAnyToken();
988     }
989     Toks.push_back(Tok);
990     ConsumeAnyToken();
991 
992     DeclGroupPtrTy Ptr;
993     if (Tok.is(tok::annot_pragma_openmp)) {
994       Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, TagType, Tag);
995     } else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
996       // Here we expect to see some function declaration.
997       if (AS == AS_none) {
998         assert(TagType == DeclSpec::TST_unspecified);
999         MaybeParseCXX11Attributes(Attrs);
1000         ParsingDeclSpec PDS(*this);
1001         Ptr = ParseExternalDeclaration(Attrs, &PDS);
1002       } else {
1003         Ptr =
1004             ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
1005       }
1006     }
1007     if (!Ptr) {
1008       Diag(Loc, diag::err_omp_decl_in_declare_simd);
1009       return DeclGroupPtrTy();
1010     }
1011     return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
1012   }
1013   case OMPD_declare_target: {
1014     SourceLocation DTLoc = ConsumeAnyToken();
1015     if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1016       return ParseOMPDeclareTargetClauses();
1017     }
1018 
1019     // Skip the last annot_pragma_openmp_end.
1020     ConsumeAnyToken();
1021 
1022     if (!Actions.ActOnStartOpenMPDeclareTargetDirective(DTLoc))
1023       return DeclGroupPtrTy();
1024 
1025     llvm::SmallVector<Decl *, 4>  Decls;
1026     DKind = parseOpenMPDirectiveKind(*this);
1027     while (DKind != OMPD_end_declare_target && Tok.isNot(tok::eof) &&
1028            Tok.isNot(tok::r_brace)) {
1029       DeclGroupPtrTy Ptr;
1030       // Here we expect to see some function declaration.
1031       if (AS == AS_none) {
1032         assert(TagType == DeclSpec::TST_unspecified);
1033         MaybeParseCXX11Attributes(Attrs);
1034         ParsingDeclSpec PDS(*this);
1035         Ptr = ParseExternalDeclaration(Attrs, &PDS);
1036       } else {
1037         Ptr =
1038             ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
1039       }
1040       if (Ptr) {
1041         DeclGroupRef Ref = Ptr.get();
1042         Decls.append(Ref.begin(), Ref.end());
1043       }
1044       if (Tok.isAnnotation() && Tok.is(tok::annot_pragma_openmp)) {
1045         TentativeParsingAction TPA(*this);
1046         ConsumeAnnotationToken();
1047         DKind = parseOpenMPDirectiveKind(*this);
1048         if (DKind != OMPD_end_declare_target)
1049           TPA.Revert();
1050         else
1051           TPA.Commit();
1052       }
1053     }
1054 
1055     ParseOMPEndDeclareTargetDirective(DKind, DTLoc);
1056     Actions.ActOnFinishOpenMPDeclareTargetDirective();
1057     return Actions.BuildDeclaratorGroup(Decls);
1058   }
1059   case OMPD_unknown:
1060     Diag(Tok, diag::err_omp_unknown_directive);
1061     break;
1062   case OMPD_parallel:
1063   case OMPD_simd:
1064   case OMPD_task:
1065   case OMPD_taskyield:
1066   case OMPD_barrier:
1067   case OMPD_taskwait:
1068   case OMPD_taskgroup:
1069   case OMPD_flush:
1070   case OMPD_for:
1071   case OMPD_for_simd:
1072   case OMPD_sections:
1073   case OMPD_section:
1074   case OMPD_single:
1075   case OMPD_master:
1076   case OMPD_ordered:
1077   case OMPD_critical:
1078   case OMPD_parallel_for:
1079   case OMPD_parallel_for_simd:
1080   case OMPD_parallel_sections:
1081   case OMPD_atomic:
1082   case OMPD_target:
1083   case OMPD_teams:
1084   case OMPD_cancellation_point:
1085   case OMPD_cancel:
1086   case OMPD_target_data:
1087   case OMPD_target_enter_data:
1088   case OMPD_target_exit_data:
1089   case OMPD_target_parallel:
1090   case OMPD_target_parallel_for:
1091   case OMPD_taskloop:
1092   case OMPD_taskloop_simd:
1093   case OMPD_distribute:
1094   case OMPD_end_declare_target:
1095   case OMPD_target_update:
1096   case OMPD_distribute_parallel_for:
1097   case OMPD_distribute_parallel_for_simd:
1098   case OMPD_distribute_simd:
1099   case OMPD_target_parallel_for_simd:
1100   case OMPD_target_simd:
1101   case OMPD_teams_distribute:
1102   case OMPD_teams_distribute_simd:
1103   case OMPD_teams_distribute_parallel_for_simd:
1104   case OMPD_teams_distribute_parallel_for:
1105   case OMPD_target_teams:
1106   case OMPD_target_teams_distribute:
1107   case OMPD_target_teams_distribute_parallel_for:
1108   case OMPD_target_teams_distribute_parallel_for_simd:
1109   case OMPD_target_teams_distribute_simd:
1110     Diag(Tok, diag::err_omp_unexpected_directive)
1111         << 1 << getOpenMPDirectiveName(DKind);
1112     break;
1113   }
1114   while (Tok.isNot(tok::annot_pragma_openmp_end))
1115     ConsumeAnyToken();
1116   ConsumeAnyToken();
1117   return nullptr;
1118 }
1119 
1120 /// Parsing of declarative or executable OpenMP directives.
1121 ///
1122 ///       threadprivate-directive:
1123 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
1124 ///         annot_pragma_openmp_end
1125 ///
1126 ///       allocate-directive:
1127 ///         annot_pragma_openmp 'allocate' simple-variable-list
1128 ///         annot_pragma_openmp_end
1129 ///
1130 ///       declare-reduction-directive:
1131 ///         annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
1132 ///         <type> {',' <type>} ':' <expression> ')' ['initializer' '('
1133 ///         ('omp_priv' '=' <expression>|<function_call>) ')']
1134 ///         annot_pragma_openmp_end
1135 ///
1136 ///       declare-mapper-directive:
1137 ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
1138 ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
1139 ///         annot_pragma_openmp_end
1140 ///
1141 ///       executable-directive:
1142 ///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
1143 ///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
1144 ///         'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
1145 ///         'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' |
1146 ///         'for simd' | 'parallel for simd' | 'target' | 'target data' |
1147 ///         'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
1148 ///         'distribute' | 'target enter data' | 'target exit data' |
1149 ///         'target parallel' | 'target parallel for' |
1150 ///         'target update' | 'distribute parallel for' |
1151 ///         'distribute paralle for simd' | 'distribute simd' |
1152 ///         'target parallel for simd' | 'target simd' |
1153 ///         'teams distribute' | 'teams distribute simd' |
1154 ///         'teams distribute parallel for simd' |
1155 ///         'teams distribute parallel for' | 'target teams' |
1156 ///         'target teams distribute' |
1157 ///         'target teams distribute parallel for' |
1158 ///         'target teams distribute parallel for simd' |
1159 ///         'target teams distribute simd' {clause}
1160 ///         annot_pragma_openmp_end
1161 ///
1162 StmtResult
1163 Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
1164   assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
1165   ParenBraceBracketBalancer BalancerRAIIObj(*this);
1166   SmallVector<OMPClause *, 5> Clauses;
1167   SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
1168   FirstClauses(OMPC_unknown + 1);
1169   unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
1170                         Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
1171   SourceLocation Loc = ConsumeAnnotationToken(), EndLoc;
1172   OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
1173   OpenMPDirectiveKind CancelRegion = OMPD_unknown;
1174   // Name of critical directive.
1175   DeclarationNameInfo DirName;
1176   StmtResult Directive = StmtError();
1177   bool HasAssociatedStatement = true;
1178   bool FlushHasClause = false;
1179 
1180   switch (DKind) {
1181   case OMPD_threadprivate: {
1182     // FIXME: Should this be permitted in C++?
1183     if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
1184         ParsedStmtContext()) {
1185       Diag(Tok, diag::err_omp_immediate_directive)
1186           << getOpenMPDirectiveName(DKind) << 0;
1187     }
1188     ConsumeToken();
1189     DeclDirectiveListParserHelper Helper(this, DKind);
1190     if (!ParseOpenMPSimpleVarList(DKind, Helper,
1191                                   /*AllowScopeSpecifier=*/false)) {
1192       // The last seen token is annot_pragma_openmp_end - need to check for
1193       // extra tokens.
1194       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1195         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1196             << getOpenMPDirectiveName(DKind);
1197         SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1198       }
1199       DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
1200           Loc, Helper.getIdentifiers());
1201       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
1202     }
1203     SkipUntil(tok::annot_pragma_openmp_end);
1204     break;
1205   }
1206   case OMPD_allocate: {
1207     // FIXME: Should this be permitted in C++?
1208     if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
1209         ParsedStmtContext()) {
1210       Diag(Tok, diag::err_omp_immediate_directive)
1211           << getOpenMPDirectiveName(DKind) << 0;
1212     }
1213     ConsumeToken();
1214     DeclDirectiveListParserHelper Helper(this, DKind);
1215     if (!ParseOpenMPSimpleVarList(DKind, Helper,
1216                                   /*AllowScopeSpecifier=*/false)) {
1217       // The last seen token is annot_pragma_openmp_end - need to check for
1218       // extra tokens.
1219       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1220         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1221             << getOpenMPDirectiveName(DKind);
1222         SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1223       }
1224       DeclGroupPtrTy Res =
1225           Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers());
1226       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
1227     }
1228     SkipUntil(tok::annot_pragma_openmp_end);
1229     break;
1230   }
1231   case OMPD_declare_reduction:
1232     ConsumeToken();
1233     if (DeclGroupPtrTy Res =
1234             ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
1235       // The last seen token is annot_pragma_openmp_end - need to check for
1236       // extra tokens.
1237       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1238         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1239             << getOpenMPDirectiveName(OMPD_declare_reduction);
1240         while (Tok.isNot(tok::annot_pragma_openmp_end))
1241           ConsumeAnyToken();
1242       }
1243       ConsumeAnyToken();
1244       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
1245     } else {
1246       SkipUntil(tok::annot_pragma_openmp_end);
1247     }
1248     break;
1249   case OMPD_declare_mapper: {
1250     ConsumeToken();
1251     if (DeclGroupPtrTy Res =
1252             ParseOpenMPDeclareMapperDirective(/*AS=*/AS_none)) {
1253       // Skip the last annot_pragma_openmp_end.
1254       ConsumeAnnotationToken();
1255       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
1256     } else {
1257       SkipUntil(tok::annot_pragma_openmp_end);
1258     }
1259     break;
1260   }
1261   case OMPD_flush:
1262     if (PP.LookAhead(0).is(tok::l_paren)) {
1263       FlushHasClause = true;
1264       // Push copy of the current token back to stream to properly parse
1265       // pseudo-clause OMPFlushClause.
1266       PP.EnterToken(Tok);
1267     }
1268     LLVM_FALLTHROUGH;
1269   case OMPD_taskyield:
1270   case OMPD_barrier:
1271   case OMPD_taskwait:
1272   case OMPD_cancellation_point:
1273   case OMPD_cancel:
1274   case OMPD_target_enter_data:
1275   case OMPD_target_exit_data:
1276   case OMPD_target_update:
1277     if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
1278         ParsedStmtContext()) {
1279       Diag(Tok, diag::err_omp_immediate_directive)
1280           << getOpenMPDirectiveName(DKind) << 0;
1281     }
1282     HasAssociatedStatement = false;
1283     // Fall through for further analysis.
1284     LLVM_FALLTHROUGH;
1285   case OMPD_parallel:
1286   case OMPD_simd:
1287   case OMPD_for:
1288   case OMPD_for_simd:
1289   case OMPD_sections:
1290   case OMPD_single:
1291   case OMPD_section:
1292   case OMPD_master:
1293   case OMPD_critical:
1294   case OMPD_parallel_for:
1295   case OMPD_parallel_for_simd:
1296   case OMPD_parallel_sections:
1297   case OMPD_task:
1298   case OMPD_ordered:
1299   case OMPD_atomic:
1300   case OMPD_target:
1301   case OMPD_teams:
1302   case OMPD_taskgroup:
1303   case OMPD_target_data:
1304   case OMPD_target_parallel:
1305   case OMPD_target_parallel_for:
1306   case OMPD_taskloop:
1307   case OMPD_taskloop_simd:
1308   case OMPD_distribute:
1309   case OMPD_distribute_parallel_for:
1310   case OMPD_distribute_parallel_for_simd:
1311   case OMPD_distribute_simd:
1312   case OMPD_target_parallel_for_simd:
1313   case OMPD_target_simd:
1314   case OMPD_teams_distribute:
1315   case OMPD_teams_distribute_simd:
1316   case OMPD_teams_distribute_parallel_for_simd:
1317   case OMPD_teams_distribute_parallel_for:
1318   case OMPD_target_teams:
1319   case OMPD_target_teams_distribute:
1320   case OMPD_target_teams_distribute_parallel_for:
1321   case OMPD_target_teams_distribute_parallel_for_simd:
1322   case OMPD_target_teams_distribute_simd: {
1323     ConsumeToken();
1324     // Parse directive name of the 'critical' directive if any.
1325     if (DKind == OMPD_critical) {
1326       BalancedDelimiterTracker T(*this, tok::l_paren,
1327                                  tok::annot_pragma_openmp_end);
1328       if (!T.consumeOpen()) {
1329         if (Tok.isAnyIdentifier()) {
1330           DirName =
1331               DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
1332           ConsumeAnyToken();
1333         } else {
1334           Diag(Tok, diag::err_omp_expected_identifier_for_critical);
1335         }
1336         T.consumeClose();
1337       }
1338     } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
1339       CancelRegion = parseOpenMPDirectiveKind(*this);
1340       if (Tok.isNot(tok::annot_pragma_openmp_end))
1341         ConsumeToken();
1342     }
1343 
1344     if (isOpenMPLoopDirective(DKind))
1345       ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
1346     if (isOpenMPSimdDirective(DKind))
1347       ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
1348     ParseScope OMPDirectiveScope(this, ScopeFlags);
1349     Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
1350 
1351     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1352       OpenMPClauseKind CKind =
1353           Tok.isAnnotation()
1354               ? OMPC_unknown
1355               : FlushHasClause ? OMPC_flush
1356                                : getOpenMPClauseKind(PP.getSpelling(Tok));
1357       Actions.StartOpenMPClause(CKind);
1358       FlushHasClause = false;
1359       OMPClause *Clause =
1360           ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
1361       FirstClauses[CKind].setInt(true);
1362       if (Clause) {
1363         FirstClauses[CKind].setPointer(Clause);
1364         Clauses.push_back(Clause);
1365       }
1366 
1367       // Skip ',' if any.
1368       if (Tok.is(tok::comma))
1369         ConsumeToken();
1370       Actions.EndOpenMPClause();
1371     }
1372     // End location of the directive.
1373     EndLoc = Tok.getLocation();
1374     // Consume final annot_pragma_openmp_end.
1375     ConsumeAnnotationToken();
1376 
1377     // OpenMP [2.13.8, ordered Construct, Syntax]
1378     // If the depend clause is specified, the ordered construct is a stand-alone
1379     // directive.
1380     if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) {
1381       if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
1382           ParsedStmtContext()) {
1383         Diag(Loc, diag::err_omp_immediate_directive)
1384             << getOpenMPDirectiveName(DKind) << 1
1385             << getOpenMPClauseName(OMPC_depend);
1386       }
1387       HasAssociatedStatement = false;
1388     }
1389 
1390     StmtResult AssociatedStmt;
1391     if (HasAssociatedStatement) {
1392       // The body is a block scope like in Lambdas and Blocks.
1393       Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
1394       // FIXME: We create a bogus CompoundStmt scope to hold the contents of
1395       // the captured region. Code elsewhere assumes that any FunctionScopeInfo
1396       // should have at least one compound statement scope within it.
1397       AssociatedStmt = (Sema::CompoundScopeRAII(Actions), ParseStatement());
1398       AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
1399     } else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
1400                DKind == OMPD_target_exit_data) {
1401       Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
1402       AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
1403                         Actions.ActOnCompoundStmt(Loc, Loc, llvm::None,
1404                                                   /*isStmtExpr=*/false));
1405       AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
1406     }
1407     Directive = Actions.ActOnOpenMPExecutableDirective(
1408         DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
1409         EndLoc);
1410 
1411     // Exit scope.
1412     Actions.EndOpenMPDSABlock(Directive.get());
1413     OMPDirectiveScope.Exit();
1414     break;
1415   }
1416   case OMPD_declare_simd:
1417   case OMPD_declare_target:
1418   case OMPD_end_declare_target:
1419   case OMPD_requires:
1420     Diag(Tok, diag::err_omp_unexpected_directive)
1421         << 1 << getOpenMPDirectiveName(DKind);
1422     SkipUntil(tok::annot_pragma_openmp_end);
1423     break;
1424   case OMPD_unknown:
1425     Diag(Tok, diag::err_omp_unknown_directive);
1426     SkipUntil(tok::annot_pragma_openmp_end);
1427     break;
1428   }
1429   return Directive;
1430 }
1431 
1432 // Parses simple list:
1433 //   simple-variable-list:
1434 //         '(' id-expression {, id-expression} ')'
1435 //
1436 bool Parser::ParseOpenMPSimpleVarList(
1437     OpenMPDirectiveKind Kind,
1438     const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> &
1439         Callback,
1440     bool AllowScopeSpecifier) {
1441   // Parse '('.
1442   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1443   if (T.expectAndConsume(diag::err_expected_lparen_after,
1444                          getOpenMPDirectiveName(Kind)))
1445     return true;
1446   bool IsCorrect = true;
1447   bool NoIdentIsFound = true;
1448 
1449   // Read tokens while ')' or annot_pragma_openmp_end is not found.
1450   while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
1451     CXXScopeSpec SS;
1452     UnqualifiedId Name;
1453     // Read var name.
1454     Token PrevTok = Tok;
1455     NoIdentIsFound = false;
1456 
1457     if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
1458         ParseOptionalCXXScopeSpecifier(SS, nullptr, false)) {
1459       IsCorrect = false;
1460       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1461                 StopBeforeMatch);
1462     } else if (ParseUnqualifiedId(SS, false, false, false, false, nullptr,
1463                                   nullptr, Name)) {
1464       IsCorrect = false;
1465       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1466                 StopBeforeMatch);
1467     } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
1468                Tok.isNot(tok::annot_pragma_openmp_end)) {
1469       IsCorrect = false;
1470       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1471                 StopBeforeMatch);
1472       Diag(PrevTok.getLocation(), diag::err_expected)
1473           << tok::identifier
1474           << SourceRange(PrevTok.getLocation(), PrevTokLocation);
1475     } else {
1476       Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
1477     }
1478     // Consume ','.
1479     if (Tok.is(tok::comma)) {
1480       ConsumeToken();
1481     }
1482   }
1483 
1484   if (NoIdentIsFound) {
1485     Diag(Tok, diag::err_expected) << tok::identifier;
1486     IsCorrect = false;
1487   }
1488 
1489   // Parse ')'.
1490   IsCorrect = !T.consumeClose() && IsCorrect;
1491 
1492   return !IsCorrect;
1493 }
1494 
1495 /// Parsing of OpenMP clauses.
1496 ///
1497 ///    clause:
1498 ///       if-clause | final-clause | num_threads-clause | safelen-clause |
1499 ///       default-clause | private-clause | firstprivate-clause | shared-clause
1500 ///       | linear-clause | aligned-clause | collapse-clause |
1501 ///       lastprivate-clause | reduction-clause | proc_bind-clause |
1502 ///       schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
1503 ///       mergeable-clause | flush-clause | read-clause | write-clause |
1504 ///       update-clause | capture-clause | seq_cst-clause | device-clause |
1505 ///       simdlen-clause | threads-clause | simd-clause | num_teams-clause |
1506 ///       thread_limit-clause | priority-clause | grainsize-clause |
1507 ///       nogroup-clause | num_tasks-clause | hint-clause | to-clause |
1508 ///       from-clause | is_device_ptr-clause | task_reduction-clause |
1509 ///       in_reduction-clause
1510 ///
1511 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
1512                                      OpenMPClauseKind CKind, bool FirstClause) {
1513   OMPClause *Clause = nullptr;
1514   bool ErrorFound = false;
1515   bool WrongDirective = false;
1516   // Check if clause is allowed for the given directive.
1517   if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) {
1518     Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
1519                                                << getOpenMPDirectiveName(DKind);
1520     ErrorFound = true;
1521     WrongDirective = true;
1522   }
1523 
1524   switch (CKind) {
1525   case OMPC_final:
1526   case OMPC_num_threads:
1527   case OMPC_safelen:
1528   case OMPC_simdlen:
1529   case OMPC_collapse:
1530   case OMPC_ordered:
1531   case OMPC_device:
1532   case OMPC_num_teams:
1533   case OMPC_thread_limit:
1534   case OMPC_priority:
1535   case OMPC_grainsize:
1536   case OMPC_num_tasks:
1537   case OMPC_hint:
1538     // OpenMP [2.5, Restrictions]
1539     //  At most one num_threads clause can appear on the directive.
1540     // OpenMP [2.8.1, simd construct, Restrictions]
1541     //  Only one safelen  clause can appear on a simd directive.
1542     //  Only one simdlen  clause can appear on a simd directive.
1543     //  Only one collapse clause can appear on a simd directive.
1544     // OpenMP [2.9.1, target data construct, Restrictions]
1545     //  At most one device clause can appear on the directive.
1546     // OpenMP [2.11.1, task Construct, Restrictions]
1547     //  At most one if clause can appear on the directive.
1548     //  At most one final clause can appear on the directive.
1549     // OpenMP [teams Construct, Restrictions]
1550     //  At most one num_teams clause can appear on the directive.
1551     //  At most one thread_limit clause can appear on the directive.
1552     // OpenMP [2.9.1, task Construct, Restrictions]
1553     // At most one priority clause can appear on the directive.
1554     // OpenMP [2.9.2, taskloop Construct, Restrictions]
1555     // At most one grainsize clause can appear on the directive.
1556     // OpenMP [2.9.2, taskloop Construct, Restrictions]
1557     // At most one num_tasks clause can appear on the directive.
1558     if (!FirstClause) {
1559       Diag(Tok, diag::err_omp_more_one_clause)
1560           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1561       ErrorFound = true;
1562     }
1563 
1564     if (CKind == OMPC_ordered && PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
1565       Clause = ParseOpenMPClause(CKind, WrongDirective);
1566     else
1567       Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
1568     break;
1569   case OMPC_default:
1570   case OMPC_proc_bind:
1571   case OMPC_atomic_default_mem_order:
1572     // OpenMP [2.14.3.1, Restrictions]
1573     //  Only a single default clause may be specified on a parallel, task or
1574     //  teams directive.
1575     // OpenMP [2.5, parallel Construct, Restrictions]
1576     //  At most one proc_bind clause can appear on the directive.
1577     // OpenMP [5.0, Requires directive, Restrictions]
1578     //  At most one atomic_default_mem_order clause can appear
1579     //  on the directive
1580     if (!FirstClause) {
1581       Diag(Tok, diag::err_omp_more_one_clause)
1582           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1583       ErrorFound = true;
1584     }
1585 
1586     Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
1587     break;
1588   case OMPC_schedule:
1589   case OMPC_dist_schedule:
1590   case OMPC_defaultmap:
1591     // OpenMP [2.7.1, Restrictions, p. 3]
1592     //  Only one schedule clause can appear on a loop directive.
1593     // OpenMP [2.10.4, Restrictions, p. 106]
1594     //  At most one defaultmap clause can appear on the directive.
1595     if (!FirstClause) {
1596       Diag(Tok, diag::err_omp_more_one_clause)
1597           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1598       ErrorFound = true;
1599     }
1600     LLVM_FALLTHROUGH;
1601 
1602   case OMPC_if:
1603     Clause = ParseOpenMPSingleExprWithArgClause(CKind, WrongDirective);
1604     break;
1605   case OMPC_nowait:
1606   case OMPC_untied:
1607   case OMPC_mergeable:
1608   case OMPC_read:
1609   case OMPC_write:
1610   case OMPC_update:
1611   case OMPC_capture:
1612   case OMPC_seq_cst:
1613   case OMPC_threads:
1614   case OMPC_simd:
1615   case OMPC_nogroup:
1616   case OMPC_unified_address:
1617   case OMPC_unified_shared_memory:
1618   case OMPC_reverse_offload:
1619   case OMPC_dynamic_allocators:
1620     // OpenMP [2.7.1, Restrictions, p. 9]
1621     //  Only one ordered clause can appear on a loop directive.
1622     // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
1623     //  Only one nowait clause can appear on a for directive.
1624     // OpenMP [5.0, Requires directive, Restrictions]
1625     //   Each of the requires clauses can appear at most once on the directive.
1626     if (!FirstClause) {
1627       Diag(Tok, diag::err_omp_more_one_clause)
1628           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1629       ErrorFound = true;
1630     }
1631 
1632     Clause = ParseOpenMPClause(CKind, WrongDirective);
1633     break;
1634   case OMPC_private:
1635   case OMPC_firstprivate:
1636   case OMPC_lastprivate:
1637   case OMPC_shared:
1638   case OMPC_reduction:
1639   case OMPC_task_reduction:
1640   case OMPC_in_reduction:
1641   case OMPC_linear:
1642   case OMPC_aligned:
1643   case OMPC_copyin:
1644   case OMPC_copyprivate:
1645   case OMPC_flush:
1646   case OMPC_depend:
1647   case OMPC_map:
1648   case OMPC_to:
1649   case OMPC_from:
1650   case OMPC_use_device_ptr:
1651   case OMPC_is_device_ptr:
1652     Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
1653     break;
1654   case OMPC_unknown:
1655     Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1656         << getOpenMPDirectiveName(DKind);
1657     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1658     break;
1659   case OMPC_threadprivate:
1660   case OMPC_allocate:
1661   case OMPC_uniform:
1662     if (!WrongDirective)
1663       Diag(Tok, diag::err_omp_unexpected_clause)
1664           << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
1665     SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
1666     break;
1667   }
1668   return ErrorFound ? nullptr : Clause;
1669 }
1670 
1671 /// Parses simple expression in parens for single-expression clauses of OpenMP
1672 /// constructs.
1673 /// \param RLoc Returned location of right paren.
1674 ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
1675                                          SourceLocation &RLoc) {
1676   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1677   if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
1678     return ExprError();
1679 
1680   SourceLocation ELoc = Tok.getLocation();
1681   ExprResult LHS(ParseCastExpression(
1682       /*isUnaryExpression=*/false, /*isAddressOfOperand=*/false, NotTypeCast));
1683   ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
1684   Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
1685 
1686   // Parse ')'.
1687   RLoc = Tok.getLocation();
1688   if (!T.consumeClose())
1689     RLoc = T.getCloseLocation();
1690 
1691   return Val;
1692 }
1693 
1694 /// Parsing of OpenMP clauses with single expressions like 'final',
1695 /// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
1696 /// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks' or 'hint'.
1697 ///
1698 ///    final-clause:
1699 ///      'final' '(' expression ')'
1700 ///
1701 ///    num_threads-clause:
1702 ///      'num_threads' '(' expression ')'
1703 ///
1704 ///    safelen-clause:
1705 ///      'safelen' '(' expression ')'
1706 ///
1707 ///    simdlen-clause:
1708 ///      'simdlen' '(' expression ')'
1709 ///
1710 ///    collapse-clause:
1711 ///      'collapse' '(' expression ')'
1712 ///
1713 ///    priority-clause:
1714 ///      'priority' '(' expression ')'
1715 ///
1716 ///    grainsize-clause:
1717 ///      'grainsize' '(' expression ')'
1718 ///
1719 ///    num_tasks-clause:
1720 ///      'num_tasks' '(' expression ')'
1721 ///
1722 ///    hint-clause:
1723 ///      'hint' '(' expression ')'
1724 ///
1725 OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
1726                                                bool ParseOnly) {
1727   SourceLocation Loc = ConsumeToken();
1728   SourceLocation LLoc = Tok.getLocation();
1729   SourceLocation RLoc;
1730 
1731   ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc);
1732 
1733   if (Val.isInvalid())
1734     return nullptr;
1735 
1736   if (ParseOnly)
1737     return nullptr;
1738   return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc);
1739 }
1740 
1741 /// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
1742 ///
1743 ///    default-clause:
1744 ///         'default' '(' 'none' | 'shared' ')
1745 ///
1746 ///    proc_bind-clause:
1747 ///         'proc_bind' '(' 'master' | 'close' | 'spread' ')
1748 ///
1749 OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind,
1750                                            bool ParseOnly) {
1751   SourceLocation Loc = Tok.getLocation();
1752   SourceLocation LOpen = ConsumeToken();
1753   // Parse '('.
1754   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1755   if (T.expectAndConsume(diag::err_expected_lparen_after,
1756                          getOpenMPClauseName(Kind)))
1757     return nullptr;
1758 
1759   unsigned Type = getOpenMPSimpleClauseType(
1760       Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1761   SourceLocation TypeLoc = Tok.getLocation();
1762   if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1763       Tok.isNot(tok::annot_pragma_openmp_end))
1764     ConsumeAnyToken();
1765 
1766   // Parse ')'.
1767   SourceLocation RLoc = Tok.getLocation();
1768   if (!T.consumeClose())
1769     RLoc = T.getCloseLocation();
1770 
1771   if (ParseOnly)
1772     return nullptr;
1773   return Actions.ActOnOpenMPSimpleClause(Kind, Type, TypeLoc, LOpen, Loc, RLoc);
1774 }
1775 
1776 /// Parsing of OpenMP clauses like 'ordered'.
1777 ///
1778 ///    ordered-clause:
1779 ///         'ordered'
1780 ///
1781 ///    nowait-clause:
1782 ///         'nowait'
1783 ///
1784 ///    untied-clause:
1785 ///         'untied'
1786 ///
1787 ///    mergeable-clause:
1788 ///         'mergeable'
1789 ///
1790 ///    read-clause:
1791 ///         'read'
1792 ///
1793 ///    threads-clause:
1794 ///         'threads'
1795 ///
1796 ///    simd-clause:
1797 ///         'simd'
1798 ///
1799 ///    nogroup-clause:
1800 ///         'nogroup'
1801 ///
1802 OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly) {
1803   SourceLocation Loc = Tok.getLocation();
1804   ConsumeAnyToken();
1805 
1806   if (ParseOnly)
1807     return nullptr;
1808   return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
1809 }
1810 
1811 
1812 /// Parsing of OpenMP clauses with single expressions and some additional
1813 /// argument like 'schedule' or 'dist_schedule'.
1814 ///
1815 ///    schedule-clause:
1816 ///      'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
1817 ///      ')'
1818 ///
1819 ///    if-clause:
1820 ///      'if' '(' [ directive-name-modifier ':' ] expression ')'
1821 ///
1822 ///    defaultmap:
1823 ///      'defaultmap' '(' modifier ':' kind ')'
1824 ///
1825 OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,
1826                                                       bool ParseOnly) {
1827   SourceLocation Loc = ConsumeToken();
1828   SourceLocation DelimLoc;
1829   // Parse '('.
1830   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1831   if (T.expectAndConsume(diag::err_expected_lparen_after,
1832                          getOpenMPClauseName(Kind)))
1833     return nullptr;
1834 
1835   ExprResult Val;
1836   SmallVector<unsigned, 4> Arg;
1837   SmallVector<SourceLocation, 4> KLoc;
1838   if (Kind == OMPC_schedule) {
1839     enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
1840     Arg.resize(NumberOfElements);
1841     KLoc.resize(NumberOfElements);
1842     Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
1843     Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
1844     Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
1845     unsigned KindModifier = getOpenMPSimpleClauseType(
1846         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1847     if (KindModifier > OMPC_SCHEDULE_unknown) {
1848       // Parse 'modifier'
1849       Arg[Modifier1] = KindModifier;
1850       KLoc[Modifier1] = Tok.getLocation();
1851       if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1852           Tok.isNot(tok::annot_pragma_openmp_end))
1853         ConsumeAnyToken();
1854       if (Tok.is(tok::comma)) {
1855         // Parse ',' 'modifier'
1856         ConsumeAnyToken();
1857         KindModifier = getOpenMPSimpleClauseType(
1858             Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1859         Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown
1860                              ? KindModifier
1861                              : (unsigned)OMPC_SCHEDULE_unknown;
1862         KLoc[Modifier2] = Tok.getLocation();
1863         if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1864             Tok.isNot(tok::annot_pragma_openmp_end))
1865           ConsumeAnyToken();
1866       }
1867       // Parse ':'
1868       if (Tok.is(tok::colon))
1869         ConsumeAnyToken();
1870       else
1871         Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier";
1872       KindModifier = getOpenMPSimpleClauseType(
1873           Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1874     }
1875     Arg[ScheduleKind] = KindModifier;
1876     KLoc[ScheduleKind] = Tok.getLocation();
1877     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1878         Tok.isNot(tok::annot_pragma_openmp_end))
1879       ConsumeAnyToken();
1880     if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
1881          Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
1882          Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
1883         Tok.is(tok::comma))
1884       DelimLoc = ConsumeAnyToken();
1885   } else if (Kind == OMPC_dist_schedule) {
1886     Arg.push_back(getOpenMPSimpleClauseType(
1887         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1888     KLoc.push_back(Tok.getLocation());
1889     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1890         Tok.isNot(tok::annot_pragma_openmp_end))
1891       ConsumeAnyToken();
1892     if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
1893       DelimLoc = ConsumeAnyToken();
1894   } else if (Kind == OMPC_defaultmap) {
1895     // Get a defaultmap modifier
1896     Arg.push_back(getOpenMPSimpleClauseType(
1897         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1898     KLoc.push_back(Tok.getLocation());
1899     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1900         Tok.isNot(tok::annot_pragma_openmp_end))
1901       ConsumeAnyToken();
1902     // Parse ':'
1903     if (Tok.is(tok::colon))
1904       ConsumeAnyToken();
1905     else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown)
1906       Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier";
1907     // Get a defaultmap kind
1908     Arg.push_back(getOpenMPSimpleClauseType(
1909         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1910     KLoc.push_back(Tok.getLocation());
1911     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1912         Tok.isNot(tok::annot_pragma_openmp_end))
1913       ConsumeAnyToken();
1914   } else {
1915     assert(Kind == OMPC_if);
1916     KLoc.push_back(Tok.getLocation());
1917     TentativeParsingAction TPA(*this);
1918     Arg.push_back(parseOpenMPDirectiveKind(*this));
1919     if (Arg.back() != OMPD_unknown) {
1920       ConsumeToken();
1921       if (Tok.is(tok::colon) && getLangOpts().OpenMP > 40) {
1922         TPA.Commit();
1923         DelimLoc = ConsumeToken();
1924       } else {
1925         TPA.Revert();
1926         Arg.back() = OMPD_unknown;
1927       }
1928     } else {
1929       TPA.Revert();
1930     }
1931   }
1932 
1933   bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) ||
1934                           (Kind == OMPC_dist_schedule && DelimLoc.isValid()) ||
1935                           Kind == OMPC_if;
1936   if (NeedAnExpression) {
1937     SourceLocation ELoc = Tok.getLocation();
1938     ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
1939     Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
1940     Val =
1941         Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
1942   }
1943 
1944   // Parse ')'.
1945   SourceLocation RLoc = Tok.getLocation();
1946   if (!T.consumeClose())
1947     RLoc = T.getCloseLocation();
1948 
1949   if (NeedAnExpression && Val.isInvalid())
1950     return nullptr;
1951 
1952   if (ParseOnly)
1953     return nullptr;
1954   return Actions.ActOnOpenMPSingleExprWithArgClause(
1955       Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
1956 }
1957 
1958 static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
1959                              UnqualifiedId &ReductionId) {
1960   if (ReductionIdScopeSpec.isEmpty()) {
1961     auto OOK = OO_None;
1962     switch (P.getCurToken().getKind()) {
1963     case tok::plus:
1964       OOK = OO_Plus;
1965       break;
1966     case tok::minus:
1967       OOK = OO_Minus;
1968       break;
1969     case tok::star:
1970       OOK = OO_Star;
1971       break;
1972     case tok::amp:
1973       OOK = OO_Amp;
1974       break;
1975     case tok::pipe:
1976       OOK = OO_Pipe;
1977       break;
1978     case tok::caret:
1979       OOK = OO_Caret;
1980       break;
1981     case tok::ampamp:
1982       OOK = OO_AmpAmp;
1983       break;
1984     case tok::pipepipe:
1985       OOK = OO_PipePipe;
1986       break;
1987     default:
1988       break;
1989     }
1990     if (OOK != OO_None) {
1991       SourceLocation OpLoc = P.ConsumeToken();
1992       SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
1993       ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
1994       return false;
1995     }
1996   }
1997   return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false,
1998                               /*AllowDestructorName*/ false,
1999                               /*AllowConstructorName*/ false,
2000                               /*AllowDeductionGuide*/ false,
2001                               nullptr, nullptr, ReductionId);
2002 }
2003 
2004 /// Checks if the token is a valid map-type-modifier.
2005 static OpenMPMapModifierKind isMapModifier(Parser &P) {
2006   Token Tok = P.getCurToken();
2007   if (!Tok.is(tok::identifier))
2008     return OMPC_MAP_MODIFIER_unknown;
2009 
2010   Preprocessor &PP = P.getPreprocessor();
2011   OpenMPMapModifierKind TypeModifier = static_cast<OpenMPMapModifierKind>(
2012       getOpenMPSimpleClauseType(OMPC_map, PP.getSpelling(Tok)));
2013   return TypeModifier;
2014 }
2015 
2016 /// Parse the mapper modifier in map, to, and from clauses.
2017 bool Parser::parseMapperModifier(OpenMPVarListDataTy &Data) {
2018   // Parse '('.
2019   BalancedDelimiterTracker T(*this, tok::l_paren, tok::colon);
2020   if (T.expectAndConsume(diag::err_expected_lparen_after, "mapper")) {
2021     SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2022               StopBeforeMatch);
2023     return true;
2024   }
2025   // Parse mapper-identifier
2026   if (getLangOpts().CPlusPlus)
2027     ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
2028                                    /*ObjectType=*/nullptr,
2029                                    /*EnteringContext=*/false);
2030   if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
2031     Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
2032     SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2033               StopBeforeMatch);
2034     return true;
2035   }
2036   auto &DeclNames = Actions.getASTContext().DeclarationNames;
2037   Data.ReductionOrMapperId = DeclarationNameInfo(
2038       DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
2039   ConsumeToken();
2040   // Parse ')'.
2041   return T.consumeClose();
2042 }
2043 
2044 /// Parse map-type-modifiers in map clause.
2045 /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
2046 /// where, map-type-modifier ::= always | close | mapper(mapper-identifier)
2047 bool Parser::parseMapTypeModifiers(OpenMPVarListDataTy &Data) {
2048   while (getCurToken().isNot(tok::colon)) {
2049     OpenMPMapModifierKind TypeModifier = isMapModifier(*this);
2050     if (TypeModifier == OMPC_MAP_MODIFIER_always ||
2051         TypeModifier == OMPC_MAP_MODIFIER_close) {
2052       Data.MapTypeModifiers.push_back(TypeModifier);
2053       Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
2054       ConsumeToken();
2055     } else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
2056       Data.MapTypeModifiers.push_back(TypeModifier);
2057       Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
2058       ConsumeToken();
2059       if (parseMapperModifier(Data))
2060         return true;
2061     } else {
2062       // For the case of unknown map-type-modifier or a map-type.
2063       // Map-type is followed by a colon; the function returns when it
2064       // encounters a token followed by a colon.
2065       if (Tok.is(tok::comma)) {
2066         Diag(Tok, diag::err_omp_map_type_modifier_missing);
2067         ConsumeToken();
2068         continue;
2069       }
2070       // Potential map-type token as it is followed by a colon.
2071       if (PP.LookAhead(0).is(tok::colon))
2072         return false;
2073       Diag(Tok, diag::err_omp_unknown_map_type_modifier);
2074       ConsumeToken();
2075     }
2076     if (getCurToken().is(tok::comma))
2077       ConsumeToken();
2078   }
2079   return false;
2080 }
2081 
2082 /// Checks if the token is a valid map-type.
2083 static OpenMPMapClauseKind isMapType(Parser &P) {
2084   Token Tok = P.getCurToken();
2085   // The map-type token can be either an identifier or the C++ delete keyword.
2086   if (!Tok.isOneOf(tok::identifier, tok::kw_delete))
2087     return OMPC_MAP_unknown;
2088   Preprocessor &PP = P.getPreprocessor();
2089   OpenMPMapClauseKind MapType = static_cast<OpenMPMapClauseKind>(
2090       getOpenMPSimpleClauseType(OMPC_map, PP.getSpelling(Tok)));
2091   return MapType;
2092 }
2093 
2094 /// Parse map-type in map clause.
2095 /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
2096 /// where, map-type ::= to | from | tofrom | alloc | release | delete
2097 static void parseMapType(Parser &P, Parser::OpenMPVarListDataTy &Data) {
2098   Token Tok = P.getCurToken();
2099   if (Tok.is(tok::colon)) {
2100     P.Diag(Tok, diag::err_omp_map_type_missing);
2101     return;
2102   }
2103   Data.MapType = isMapType(P);
2104   if (Data.MapType == OMPC_MAP_unknown)
2105     P.Diag(Tok, diag::err_omp_unknown_map_type);
2106   P.ConsumeToken();
2107 }
2108 
2109 /// Parses clauses with list.
2110 bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
2111                                 OpenMPClauseKind Kind,
2112                                 SmallVectorImpl<Expr *> &Vars,
2113                                 OpenMPVarListDataTy &Data) {
2114   UnqualifiedId UnqualifiedReductionId;
2115   bool InvalidReductionId = false;
2116   bool IsInvalidMapperModifier = false;
2117 
2118   // Parse '('.
2119   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2120   if (T.expectAndConsume(diag::err_expected_lparen_after,
2121                          getOpenMPClauseName(Kind)))
2122     return true;
2123 
2124   bool NeedRParenForLinear = false;
2125   BalancedDelimiterTracker LinearT(*this, tok::l_paren,
2126                                   tok::annot_pragma_openmp_end);
2127   // Handle reduction-identifier for reduction clause.
2128   if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
2129       Kind == OMPC_in_reduction) {
2130     ColonProtectionRAIIObject ColonRAII(*this);
2131     if (getLangOpts().CPlusPlus)
2132       ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
2133                                      /*ObjectType=*/nullptr,
2134                                      /*EnteringContext=*/false);
2135     InvalidReductionId = ParseReductionId(
2136         *this, Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
2137     if (InvalidReductionId) {
2138       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2139                 StopBeforeMatch);
2140     }
2141     if (Tok.is(tok::colon))
2142       Data.ColonLoc = ConsumeToken();
2143     else
2144       Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
2145     if (!InvalidReductionId)
2146       Data.ReductionOrMapperId =
2147           Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
2148   } else if (Kind == OMPC_depend) {
2149   // Handle dependency type for depend clause.
2150     ColonProtectionRAIIObject ColonRAII(*this);
2151     Data.DepKind =
2152         static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType(
2153             Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
2154     Data.DepLinMapLoc = Tok.getLocation();
2155 
2156     if (Data.DepKind == OMPC_DEPEND_unknown) {
2157       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2158                 StopBeforeMatch);
2159     } else {
2160       ConsumeToken();
2161       // Special processing for depend(source) clause.
2162       if (DKind == OMPD_ordered && Data.DepKind == OMPC_DEPEND_source) {
2163         // Parse ')'.
2164         T.consumeClose();
2165         return false;
2166       }
2167     }
2168     if (Tok.is(tok::colon)) {
2169       Data.ColonLoc = ConsumeToken();
2170     } else {
2171       Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
2172                                       : diag::warn_pragma_expected_colon)
2173           << "dependency type";
2174     }
2175   } else if (Kind == OMPC_linear) {
2176     // Try to parse modifier if any.
2177     if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
2178       Data.LinKind = static_cast<OpenMPLinearClauseKind>(
2179           getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
2180       Data.DepLinMapLoc = ConsumeToken();
2181       LinearT.consumeOpen();
2182       NeedRParenForLinear = true;
2183     }
2184   } else if (Kind == OMPC_map) {
2185     // Handle map type for map clause.
2186     ColonProtectionRAIIObject ColonRAII(*this);
2187 
2188     // The first identifier may be a list item, a map-type or a
2189     // map-type-modifier. The map-type can also be delete which has the same
2190     // spelling of the C++ delete keyword.
2191     Data.DepLinMapLoc = Tok.getLocation();
2192 
2193     // Check for presence of a colon in the map clause.
2194     TentativeParsingAction TPA(*this);
2195     bool ColonPresent = false;
2196     if (SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2197         StopBeforeMatch)) {
2198       if (Tok.is(tok::colon))
2199         ColonPresent = true;
2200     }
2201     TPA.Revert();
2202     // Only parse map-type-modifier[s] and map-type if a colon is present in
2203     // the map clause.
2204     if (ColonPresent) {
2205       IsInvalidMapperModifier = parseMapTypeModifiers(Data);
2206       if (!IsInvalidMapperModifier)
2207         parseMapType(*this, Data);
2208       else
2209         SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch);
2210     }
2211     if (Data.MapType == OMPC_MAP_unknown) {
2212       Data.MapType = OMPC_MAP_tofrom;
2213       Data.IsMapTypeImplicit = true;
2214     }
2215 
2216     if (Tok.is(tok::colon))
2217       Data.ColonLoc = ConsumeToken();
2218   } else if (Kind == OMPC_to || Kind == OMPC_from) {
2219     if (Tok.is(tok::identifier)) {
2220       bool IsMapperModifier = false;
2221       if (Kind == OMPC_to) {
2222         auto Modifier = static_cast<OpenMPToModifierKind>(
2223             getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
2224         if (Modifier == OMPC_TO_MODIFIER_mapper)
2225           IsMapperModifier = true;
2226       } else {
2227         auto Modifier = static_cast<OpenMPFromModifierKind>(
2228             getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
2229         if (Modifier == OMPC_FROM_MODIFIER_mapper)
2230           IsMapperModifier = true;
2231       }
2232       if (IsMapperModifier) {
2233         // Parse the mapper modifier.
2234         ConsumeToken();
2235         IsInvalidMapperModifier = parseMapperModifier(Data);
2236         if (Tok.isNot(tok::colon)) {
2237           if (!IsInvalidMapperModifier)
2238             Diag(Tok, diag::warn_pragma_expected_colon) << ")";
2239           SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2240                     StopBeforeMatch);
2241         }
2242         // Consume ':'.
2243         if (Tok.is(tok::colon))
2244           ConsumeToken();
2245       }
2246     }
2247   }
2248 
2249   bool IsComma =
2250       (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
2251        Kind != OMPC_in_reduction && Kind != OMPC_depend && Kind != OMPC_map) ||
2252       (Kind == OMPC_reduction && !InvalidReductionId) ||
2253       (Kind == OMPC_map && Data.MapType != OMPC_MAP_unknown) ||
2254       (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown);
2255   const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
2256   while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
2257                      Tok.isNot(tok::annot_pragma_openmp_end))) {
2258     ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
2259     // Parse variable
2260     ExprResult VarExpr =
2261         Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
2262     if (VarExpr.isUsable()) {
2263       Vars.push_back(VarExpr.get());
2264     } else {
2265       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2266                 StopBeforeMatch);
2267     }
2268     // Skip ',' if any
2269     IsComma = Tok.is(tok::comma);
2270     if (IsComma)
2271       ConsumeToken();
2272     else if (Tok.isNot(tok::r_paren) &&
2273              Tok.isNot(tok::annot_pragma_openmp_end) &&
2274              (!MayHaveTail || Tok.isNot(tok::colon)))
2275       Diag(Tok, diag::err_omp_expected_punc)
2276           << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
2277                                    : getOpenMPClauseName(Kind))
2278           << (Kind == OMPC_flush);
2279   }
2280 
2281   // Parse ')' for linear clause with modifier.
2282   if (NeedRParenForLinear)
2283     LinearT.consumeClose();
2284 
2285   // Parse ':' linear-step (or ':' alignment).
2286   const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
2287   if (MustHaveTail) {
2288     Data.ColonLoc = Tok.getLocation();
2289     SourceLocation ELoc = ConsumeToken();
2290     ExprResult Tail = ParseAssignmentExpression();
2291     Tail =
2292         Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false);
2293     if (Tail.isUsable())
2294       Data.TailExpr = Tail.get();
2295     else
2296       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2297                 StopBeforeMatch);
2298   }
2299 
2300   // Parse ')'.
2301   Data.RLoc = Tok.getLocation();
2302   if (!T.consumeClose())
2303     Data.RLoc = T.getCloseLocation();
2304   return (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown &&
2305           Vars.empty()) ||
2306          (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
2307          (MustHaveTail && !Data.TailExpr) || InvalidReductionId ||
2308          IsInvalidMapperModifier;
2309 }
2310 
2311 /// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
2312 /// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction' or
2313 /// 'in_reduction'.
2314 ///
2315 ///    private-clause:
2316 ///       'private' '(' list ')'
2317 ///    firstprivate-clause:
2318 ///       'firstprivate' '(' list ')'
2319 ///    lastprivate-clause:
2320 ///       'lastprivate' '(' list ')'
2321 ///    shared-clause:
2322 ///       'shared' '(' list ')'
2323 ///    linear-clause:
2324 ///       'linear' '(' linear-list [ ':' linear-step ] ')'
2325 ///    aligned-clause:
2326 ///       'aligned' '(' list [ ':' alignment ] ')'
2327 ///    reduction-clause:
2328 ///       'reduction' '(' reduction-identifier ':' list ')'
2329 ///    task_reduction-clause:
2330 ///       'task_reduction' '(' reduction-identifier ':' list ')'
2331 ///    in_reduction-clause:
2332 ///       'in_reduction' '(' reduction-identifier ':' list ')'
2333 ///    copyprivate-clause:
2334 ///       'copyprivate' '(' list ')'
2335 ///    flush-clause:
2336 ///       'flush' '(' list ')'
2337 ///    depend-clause:
2338 ///       'depend' '(' in | out | inout : list | source ')'
2339 ///    map-clause:
2340 ///       'map' '(' [ [ always [,] ] [ close [,] ]
2341 ///          [ mapper '(' mapper-identifier ')' [,] ]
2342 ///          to | from | tofrom | alloc | release | delete ':' ] list ')';
2343 ///    to-clause:
2344 ///       'to' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
2345 ///    from-clause:
2346 ///       'from' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
2347 ///    use_device_ptr-clause:
2348 ///       'use_device_ptr' '(' list ')'
2349 ///    is_device_ptr-clause:
2350 ///       'is_device_ptr' '(' list ')'
2351 ///
2352 /// For 'linear' clause linear-list may have the following forms:
2353 ///  list
2354 ///  modifier(list)
2355 /// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
2356 OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
2357                                             OpenMPClauseKind Kind,
2358                                             bool ParseOnly) {
2359   SourceLocation Loc = Tok.getLocation();
2360   SourceLocation LOpen = ConsumeToken();
2361   SmallVector<Expr *, 4> Vars;
2362   OpenMPVarListDataTy Data;
2363 
2364   if (ParseOpenMPVarList(DKind, Kind, Vars, Data))
2365     return nullptr;
2366 
2367   if (ParseOnly)
2368     return nullptr;
2369   OMPVarListLocTy Locs(Loc, LOpen, Data.RLoc);
2370   return Actions.ActOnOpenMPVarListClause(
2371       Kind, Vars, Data.TailExpr, Locs, Data.ColonLoc,
2372       Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId, Data.DepKind,
2373       Data.LinKind, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
2374       Data.MapType, Data.IsMapTypeImplicit, Data.DepLinMapLoc);
2375 }
2376 
2377