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 [<clause>]
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       SmallVector<OMPClause *, 1> Clauses;
901       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
902         SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
903                     OMPC_unknown + 1>
904             FirstClauses(OMPC_unknown + 1);
905         while (Tok.isNot(tok::annot_pragma_openmp_end)) {
906           OpenMPClauseKind CKind =
907               Tok.isAnnotation() ? OMPC_unknown
908                                  : getOpenMPClauseKind(PP.getSpelling(Tok));
909           Actions.StartOpenMPClause(CKind);
910           OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
911                                                 !FirstClauses[CKind].getInt());
912           SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
913                     StopBeforeMatch);
914           FirstClauses[CKind].setInt(true);
915           if (Clause != nullptr)
916             Clauses.push_back(Clause);
917           if (Tok.is(tok::annot_pragma_openmp_end)) {
918             Actions.EndOpenMPClause();
919             break;
920           }
921           // Skip ',' if any.
922           if (Tok.is(tok::comma))
923             ConsumeToken();
924           Actions.EndOpenMPClause();
925         }
926         // The last seen token is annot_pragma_openmp_end - need to check for
927         // extra tokens.
928         if (Tok.isNot(tok::annot_pragma_openmp_end)) {
929           Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
930               << getOpenMPDirectiveName(DKind);
931           SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
932         }
933       }
934       // Skip the last annot_pragma_openmp_end.
935       ConsumeAnnotationToken();
936       return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers(),
937                                                   Clauses);
938     }
939     break;
940   }
941   case OMPD_requires: {
942     SourceLocation StartLoc = ConsumeToken();
943     SmallVector<OMPClause *, 5> Clauses;
944     SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
945     FirstClauses(OMPC_unknown + 1);
946     if (Tok.is(tok::annot_pragma_openmp_end)) {
947       Diag(Tok, diag::err_omp_expected_clause)
948           << getOpenMPDirectiveName(OMPD_requires);
949       break;
950     }
951     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
952       OpenMPClauseKind CKind = Tok.isAnnotation()
953                                    ? OMPC_unknown
954                                    : getOpenMPClauseKind(PP.getSpelling(Tok));
955       Actions.StartOpenMPClause(CKind);
956       OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind,
957                                             !FirstClauses[CKind].getInt());
958       SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
959                 StopBeforeMatch);
960       FirstClauses[CKind].setInt(true);
961       if (Clause != nullptr)
962         Clauses.push_back(Clause);
963       if (Tok.is(tok::annot_pragma_openmp_end)) {
964         Actions.EndOpenMPClause();
965         break;
966       }
967       // Skip ',' if any.
968       if (Tok.is(tok::comma))
969         ConsumeToken();
970       Actions.EndOpenMPClause();
971     }
972     // Consume final annot_pragma_openmp_end
973     if (Clauses.size() == 0) {
974       Diag(Tok, diag::err_omp_expected_clause)
975           << getOpenMPDirectiveName(OMPD_requires);
976       ConsumeAnnotationToken();
977       return nullptr;
978     }
979     ConsumeAnnotationToken();
980     return Actions.ActOnOpenMPRequiresDirective(StartLoc, Clauses);
981   }
982   case OMPD_declare_reduction:
983     ConsumeToken();
984     if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
985       // The last seen token is annot_pragma_openmp_end - need to check for
986       // extra tokens.
987       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
988         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
989             << getOpenMPDirectiveName(OMPD_declare_reduction);
990         while (Tok.isNot(tok::annot_pragma_openmp_end))
991           ConsumeAnyToken();
992       }
993       // Skip the last annot_pragma_openmp_end.
994       ConsumeAnnotationToken();
995       return Res;
996     }
997     break;
998   case OMPD_declare_mapper: {
999     ConsumeToken();
1000     if (DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
1001       // Skip the last annot_pragma_openmp_end.
1002       ConsumeAnnotationToken();
1003       return Res;
1004     }
1005     break;
1006   }
1007   case OMPD_declare_simd: {
1008     // The syntax is:
1009     // { #pragma omp declare simd }
1010     // <function-declaration-or-definition>
1011     //
1012     ConsumeToken();
1013     CachedTokens Toks;
1014     while(Tok.isNot(tok::annot_pragma_openmp_end)) {
1015       Toks.push_back(Tok);
1016       ConsumeAnyToken();
1017     }
1018     Toks.push_back(Tok);
1019     ConsumeAnyToken();
1020 
1021     DeclGroupPtrTy Ptr;
1022     if (Tok.is(tok::annot_pragma_openmp)) {
1023       Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, TagType, Tag);
1024     } else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
1025       // Here we expect to see some function declaration.
1026       if (AS == AS_none) {
1027         assert(TagType == DeclSpec::TST_unspecified);
1028         MaybeParseCXX11Attributes(Attrs);
1029         ParsingDeclSpec PDS(*this);
1030         Ptr = ParseExternalDeclaration(Attrs, &PDS);
1031       } else {
1032         Ptr =
1033             ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
1034       }
1035     }
1036     if (!Ptr) {
1037       Diag(Loc, diag::err_omp_decl_in_declare_simd);
1038       return DeclGroupPtrTy();
1039     }
1040     return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
1041   }
1042   case OMPD_declare_target: {
1043     SourceLocation DTLoc = ConsumeAnyToken();
1044     if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1045       return ParseOMPDeclareTargetClauses();
1046     }
1047 
1048     // Skip the last annot_pragma_openmp_end.
1049     ConsumeAnyToken();
1050 
1051     if (!Actions.ActOnStartOpenMPDeclareTargetDirective(DTLoc))
1052       return DeclGroupPtrTy();
1053 
1054     llvm::SmallVector<Decl *, 4>  Decls;
1055     DKind = parseOpenMPDirectiveKind(*this);
1056     while (DKind != OMPD_end_declare_target && Tok.isNot(tok::eof) &&
1057            Tok.isNot(tok::r_brace)) {
1058       DeclGroupPtrTy Ptr;
1059       // Here we expect to see some function declaration.
1060       if (AS == AS_none) {
1061         assert(TagType == DeclSpec::TST_unspecified);
1062         MaybeParseCXX11Attributes(Attrs);
1063         ParsingDeclSpec PDS(*this);
1064         Ptr = ParseExternalDeclaration(Attrs, &PDS);
1065       } else {
1066         Ptr =
1067             ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
1068       }
1069       if (Ptr) {
1070         DeclGroupRef Ref = Ptr.get();
1071         Decls.append(Ref.begin(), Ref.end());
1072       }
1073       if (Tok.isAnnotation() && Tok.is(tok::annot_pragma_openmp)) {
1074         TentativeParsingAction TPA(*this);
1075         ConsumeAnnotationToken();
1076         DKind = parseOpenMPDirectiveKind(*this);
1077         if (DKind != OMPD_end_declare_target)
1078           TPA.Revert();
1079         else
1080           TPA.Commit();
1081       }
1082     }
1083 
1084     ParseOMPEndDeclareTargetDirective(DKind, DTLoc);
1085     Actions.ActOnFinishOpenMPDeclareTargetDirective();
1086     return Actions.BuildDeclaratorGroup(Decls);
1087   }
1088   case OMPD_unknown:
1089     Diag(Tok, diag::err_omp_unknown_directive);
1090     break;
1091   case OMPD_parallel:
1092   case OMPD_simd:
1093   case OMPD_task:
1094   case OMPD_taskyield:
1095   case OMPD_barrier:
1096   case OMPD_taskwait:
1097   case OMPD_taskgroup:
1098   case OMPD_flush:
1099   case OMPD_for:
1100   case OMPD_for_simd:
1101   case OMPD_sections:
1102   case OMPD_section:
1103   case OMPD_single:
1104   case OMPD_master:
1105   case OMPD_ordered:
1106   case OMPD_critical:
1107   case OMPD_parallel_for:
1108   case OMPD_parallel_for_simd:
1109   case OMPD_parallel_sections:
1110   case OMPD_atomic:
1111   case OMPD_target:
1112   case OMPD_teams:
1113   case OMPD_cancellation_point:
1114   case OMPD_cancel:
1115   case OMPD_target_data:
1116   case OMPD_target_enter_data:
1117   case OMPD_target_exit_data:
1118   case OMPD_target_parallel:
1119   case OMPD_target_parallel_for:
1120   case OMPD_taskloop:
1121   case OMPD_taskloop_simd:
1122   case OMPD_distribute:
1123   case OMPD_end_declare_target:
1124   case OMPD_target_update:
1125   case OMPD_distribute_parallel_for:
1126   case OMPD_distribute_parallel_for_simd:
1127   case OMPD_distribute_simd:
1128   case OMPD_target_parallel_for_simd:
1129   case OMPD_target_simd:
1130   case OMPD_teams_distribute:
1131   case OMPD_teams_distribute_simd:
1132   case OMPD_teams_distribute_parallel_for_simd:
1133   case OMPD_teams_distribute_parallel_for:
1134   case OMPD_target_teams:
1135   case OMPD_target_teams_distribute:
1136   case OMPD_target_teams_distribute_parallel_for:
1137   case OMPD_target_teams_distribute_parallel_for_simd:
1138   case OMPD_target_teams_distribute_simd:
1139     Diag(Tok, diag::err_omp_unexpected_directive)
1140         << 1 << getOpenMPDirectiveName(DKind);
1141     break;
1142   }
1143   while (Tok.isNot(tok::annot_pragma_openmp_end))
1144     ConsumeAnyToken();
1145   ConsumeAnyToken();
1146   return nullptr;
1147 }
1148 
1149 /// Parsing of declarative or executable OpenMP directives.
1150 ///
1151 ///       threadprivate-directive:
1152 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
1153 ///         annot_pragma_openmp_end
1154 ///
1155 ///       allocate-directive:
1156 ///         annot_pragma_openmp 'allocate' simple-variable-list
1157 ///         annot_pragma_openmp_end
1158 ///
1159 ///       declare-reduction-directive:
1160 ///         annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
1161 ///         <type> {',' <type>} ':' <expression> ')' ['initializer' '('
1162 ///         ('omp_priv' '=' <expression>|<function_call>) ')']
1163 ///         annot_pragma_openmp_end
1164 ///
1165 ///       declare-mapper-directive:
1166 ///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
1167 ///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
1168 ///         annot_pragma_openmp_end
1169 ///
1170 ///       executable-directive:
1171 ///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
1172 ///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
1173 ///         'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
1174 ///         'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' |
1175 ///         'for simd' | 'parallel for simd' | 'target' | 'target data' |
1176 ///         'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
1177 ///         'distribute' | 'target enter data' | 'target exit data' |
1178 ///         'target parallel' | 'target parallel for' |
1179 ///         'target update' | 'distribute parallel for' |
1180 ///         'distribute paralle for simd' | 'distribute simd' |
1181 ///         'target parallel for simd' | 'target simd' |
1182 ///         'teams distribute' | 'teams distribute simd' |
1183 ///         'teams distribute parallel for simd' |
1184 ///         'teams distribute parallel for' | 'target teams' |
1185 ///         'target teams distribute' |
1186 ///         'target teams distribute parallel for' |
1187 ///         'target teams distribute parallel for simd' |
1188 ///         'target teams distribute simd' {clause}
1189 ///         annot_pragma_openmp_end
1190 ///
1191 StmtResult
1192 Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
1193   assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
1194   ParenBraceBracketBalancer BalancerRAIIObj(*this);
1195   SmallVector<OMPClause *, 5> Clauses;
1196   SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
1197   FirstClauses(OMPC_unknown + 1);
1198   unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
1199                         Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
1200   SourceLocation Loc = ConsumeAnnotationToken(), EndLoc;
1201   OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
1202   OpenMPDirectiveKind CancelRegion = OMPD_unknown;
1203   // Name of critical directive.
1204   DeclarationNameInfo DirName;
1205   StmtResult Directive = StmtError();
1206   bool HasAssociatedStatement = true;
1207   bool FlushHasClause = false;
1208 
1209   switch (DKind) {
1210   case OMPD_threadprivate: {
1211     // FIXME: Should this be permitted in C++?
1212     if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
1213         ParsedStmtContext()) {
1214       Diag(Tok, diag::err_omp_immediate_directive)
1215           << getOpenMPDirectiveName(DKind) << 0;
1216     }
1217     ConsumeToken();
1218     DeclDirectiveListParserHelper Helper(this, DKind);
1219     if (!ParseOpenMPSimpleVarList(DKind, Helper,
1220                                   /*AllowScopeSpecifier=*/false)) {
1221       // The last seen token is annot_pragma_openmp_end - need to check for
1222       // extra tokens.
1223       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1224         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1225             << getOpenMPDirectiveName(DKind);
1226         SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1227       }
1228       DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
1229           Loc, Helper.getIdentifiers());
1230       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
1231     }
1232     SkipUntil(tok::annot_pragma_openmp_end);
1233     break;
1234   }
1235   case OMPD_allocate: {
1236     // FIXME: Should this be permitted in C++?
1237     if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
1238         ParsedStmtContext()) {
1239       Diag(Tok, diag::err_omp_immediate_directive)
1240           << getOpenMPDirectiveName(DKind) << 0;
1241     }
1242     ConsumeToken();
1243     DeclDirectiveListParserHelper Helper(this, DKind);
1244     if (!ParseOpenMPSimpleVarList(DKind, Helper,
1245                                   /*AllowScopeSpecifier=*/false)) {
1246       SmallVector<OMPClause *, 1> Clauses;
1247       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1248         SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
1249                     OMPC_unknown + 1>
1250             FirstClauses(OMPC_unknown + 1);
1251         while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1252           OpenMPClauseKind CKind =
1253               Tok.isAnnotation() ? OMPC_unknown
1254                                  : getOpenMPClauseKind(PP.getSpelling(Tok));
1255           Actions.StartOpenMPClause(CKind);
1256           OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
1257                                                 !FirstClauses[CKind].getInt());
1258           SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1259                     StopBeforeMatch);
1260           FirstClauses[CKind].setInt(true);
1261           if (Clause != nullptr)
1262             Clauses.push_back(Clause);
1263           if (Tok.is(tok::annot_pragma_openmp_end)) {
1264             Actions.EndOpenMPClause();
1265             break;
1266           }
1267           // Skip ',' if any.
1268           if (Tok.is(tok::comma))
1269             ConsumeToken();
1270           Actions.EndOpenMPClause();
1271         }
1272         // The last seen token is annot_pragma_openmp_end - need to check for
1273         // extra tokens.
1274         if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1275           Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1276               << getOpenMPDirectiveName(DKind);
1277           SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1278         }
1279       }
1280       DeclGroupPtrTy Res = Actions.ActOnOpenMPAllocateDirective(
1281           Loc, Helper.getIdentifiers(), Clauses);
1282       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
1283     }
1284     SkipUntil(tok::annot_pragma_openmp_end);
1285     break;
1286   }
1287   case OMPD_declare_reduction:
1288     ConsumeToken();
1289     if (DeclGroupPtrTy Res =
1290             ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
1291       // The last seen token is annot_pragma_openmp_end - need to check for
1292       // extra tokens.
1293       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1294         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1295             << getOpenMPDirectiveName(OMPD_declare_reduction);
1296         while (Tok.isNot(tok::annot_pragma_openmp_end))
1297           ConsumeAnyToken();
1298       }
1299       ConsumeAnyToken();
1300       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
1301     } else {
1302       SkipUntil(tok::annot_pragma_openmp_end);
1303     }
1304     break;
1305   case OMPD_declare_mapper: {
1306     ConsumeToken();
1307     if (DeclGroupPtrTy Res =
1308             ParseOpenMPDeclareMapperDirective(/*AS=*/AS_none)) {
1309       // Skip the last annot_pragma_openmp_end.
1310       ConsumeAnnotationToken();
1311       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
1312     } else {
1313       SkipUntil(tok::annot_pragma_openmp_end);
1314     }
1315     break;
1316   }
1317   case OMPD_flush:
1318     if (PP.LookAhead(0).is(tok::l_paren)) {
1319       FlushHasClause = true;
1320       // Push copy of the current token back to stream to properly parse
1321       // pseudo-clause OMPFlushClause.
1322       PP.EnterToken(Tok);
1323     }
1324     LLVM_FALLTHROUGH;
1325   case OMPD_taskyield:
1326   case OMPD_barrier:
1327   case OMPD_taskwait:
1328   case OMPD_cancellation_point:
1329   case OMPD_cancel:
1330   case OMPD_target_enter_data:
1331   case OMPD_target_exit_data:
1332   case OMPD_target_update:
1333     if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
1334         ParsedStmtContext()) {
1335       Diag(Tok, diag::err_omp_immediate_directive)
1336           << getOpenMPDirectiveName(DKind) << 0;
1337     }
1338     HasAssociatedStatement = false;
1339     // Fall through for further analysis.
1340     LLVM_FALLTHROUGH;
1341   case OMPD_parallel:
1342   case OMPD_simd:
1343   case OMPD_for:
1344   case OMPD_for_simd:
1345   case OMPD_sections:
1346   case OMPD_single:
1347   case OMPD_section:
1348   case OMPD_master:
1349   case OMPD_critical:
1350   case OMPD_parallel_for:
1351   case OMPD_parallel_for_simd:
1352   case OMPD_parallel_sections:
1353   case OMPD_task:
1354   case OMPD_ordered:
1355   case OMPD_atomic:
1356   case OMPD_target:
1357   case OMPD_teams:
1358   case OMPD_taskgroup:
1359   case OMPD_target_data:
1360   case OMPD_target_parallel:
1361   case OMPD_target_parallel_for:
1362   case OMPD_taskloop:
1363   case OMPD_taskloop_simd:
1364   case OMPD_distribute:
1365   case OMPD_distribute_parallel_for:
1366   case OMPD_distribute_parallel_for_simd:
1367   case OMPD_distribute_simd:
1368   case OMPD_target_parallel_for_simd:
1369   case OMPD_target_simd:
1370   case OMPD_teams_distribute:
1371   case OMPD_teams_distribute_simd:
1372   case OMPD_teams_distribute_parallel_for_simd:
1373   case OMPD_teams_distribute_parallel_for:
1374   case OMPD_target_teams:
1375   case OMPD_target_teams_distribute:
1376   case OMPD_target_teams_distribute_parallel_for:
1377   case OMPD_target_teams_distribute_parallel_for_simd:
1378   case OMPD_target_teams_distribute_simd: {
1379     ConsumeToken();
1380     // Parse directive name of the 'critical' directive if any.
1381     if (DKind == OMPD_critical) {
1382       BalancedDelimiterTracker T(*this, tok::l_paren,
1383                                  tok::annot_pragma_openmp_end);
1384       if (!T.consumeOpen()) {
1385         if (Tok.isAnyIdentifier()) {
1386           DirName =
1387               DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
1388           ConsumeAnyToken();
1389         } else {
1390           Diag(Tok, diag::err_omp_expected_identifier_for_critical);
1391         }
1392         T.consumeClose();
1393       }
1394     } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
1395       CancelRegion = parseOpenMPDirectiveKind(*this);
1396       if (Tok.isNot(tok::annot_pragma_openmp_end))
1397         ConsumeToken();
1398     }
1399 
1400     if (isOpenMPLoopDirective(DKind))
1401       ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
1402     if (isOpenMPSimdDirective(DKind))
1403       ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
1404     ParseScope OMPDirectiveScope(this, ScopeFlags);
1405     Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
1406 
1407     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1408       OpenMPClauseKind CKind =
1409           Tok.isAnnotation()
1410               ? OMPC_unknown
1411               : FlushHasClause ? OMPC_flush
1412                                : getOpenMPClauseKind(PP.getSpelling(Tok));
1413       Actions.StartOpenMPClause(CKind);
1414       FlushHasClause = false;
1415       OMPClause *Clause =
1416           ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
1417       FirstClauses[CKind].setInt(true);
1418       if (Clause) {
1419         FirstClauses[CKind].setPointer(Clause);
1420         Clauses.push_back(Clause);
1421       }
1422 
1423       // Skip ',' if any.
1424       if (Tok.is(tok::comma))
1425         ConsumeToken();
1426       Actions.EndOpenMPClause();
1427     }
1428     // End location of the directive.
1429     EndLoc = Tok.getLocation();
1430     // Consume final annot_pragma_openmp_end.
1431     ConsumeAnnotationToken();
1432 
1433     // OpenMP [2.13.8, ordered Construct, Syntax]
1434     // If the depend clause is specified, the ordered construct is a stand-alone
1435     // directive.
1436     if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) {
1437       if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
1438           ParsedStmtContext()) {
1439         Diag(Loc, diag::err_omp_immediate_directive)
1440             << getOpenMPDirectiveName(DKind) << 1
1441             << getOpenMPClauseName(OMPC_depend);
1442       }
1443       HasAssociatedStatement = false;
1444     }
1445 
1446     StmtResult AssociatedStmt;
1447     if (HasAssociatedStatement) {
1448       // The body is a block scope like in Lambdas and Blocks.
1449       Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
1450       // FIXME: We create a bogus CompoundStmt scope to hold the contents of
1451       // the captured region. Code elsewhere assumes that any FunctionScopeInfo
1452       // should have at least one compound statement scope within it.
1453       AssociatedStmt = (Sema::CompoundScopeRAII(Actions), ParseStatement());
1454       AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
1455     } else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
1456                DKind == OMPD_target_exit_data) {
1457       Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
1458       AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
1459                         Actions.ActOnCompoundStmt(Loc, Loc, llvm::None,
1460                                                   /*isStmtExpr=*/false));
1461       AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
1462     }
1463     Directive = Actions.ActOnOpenMPExecutableDirective(
1464         DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
1465         EndLoc);
1466 
1467     // Exit scope.
1468     Actions.EndOpenMPDSABlock(Directive.get());
1469     OMPDirectiveScope.Exit();
1470     break;
1471   }
1472   case OMPD_declare_simd:
1473   case OMPD_declare_target:
1474   case OMPD_end_declare_target:
1475   case OMPD_requires:
1476     Diag(Tok, diag::err_omp_unexpected_directive)
1477         << 1 << getOpenMPDirectiveName(DKind);
1478     SkipUntil(tok::annot_pragma_openmp_end);
1479     break;
1480   case OMPD_unknown:
1481     Diag(Tok, diag::err_omp_unknown_directive);
1482     SkipUntil(tok::annot_pragma_openmp_end);
1483     break;
1484   }
1485   return Directive;
1486 }
1487 
1488 // Parses simple list:
1489 //   simple-variable-list:
1490 //         '(' id-expression {, id-expression} ')'
1491 //
1492 bool Parser::ParseOpenMPSimpleVarList(
1493     OpenMPDirectiveKind Kind,
1494     const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> &
1495         Callback,
1496     bool AllowScopeSpecifier) {
1497   // Parse '('.
1498   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1499   if (T.expectAndConsume(diag::err_expected_lparen_after,
1500                          getOpenMPDirectiveName(Kind)))
1501     return true;
1502   bool IsCorrect = true;
1503   bool NoIdentIsFound = true;
1504 
1505   // Read tokens while ')' or annot_pragma_openmp_end is not found.
1506   while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
1507     CXXScopeSpec SS;
1508     UnqualifiedId Name;
1509     // Read var name.
1510     Token PrevTok = Tok;
1511     NoIdentIsFound = false;
1512 
1513     if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
1514         ParseOptionalCXXScopeSpecifier(SS, nullptr, false)) {
1515       IsCorrect = false;
1516       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1517                 StopBeforeMatch);
1518     } else if (ParseUnqualifiedId(SS, false, false, false, false, nullptr,
1519                                   nullptr, Name)) {
1520       IsCorrect = false;
1521       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1522                 StopBeforeMatch);
1523     } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
1524                Tok.isNot(tok::annot_pragma_openmp_end)) {
1525       IsCorrect = false;
1526       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1527                 StopBeforeMatch);
1528       Diag(PrevTok.getLocation(), diag::err_expected)
1529           << tok::identifier
1530           << SourceRange(PrevTok.getLocation(), PrevTokLocation);
1531     } else {
1532       Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
1533     }
1534     // Consume ','.
1535     if (Tok.is(tok::comma)) {
1536       ConsumeToken();
1537     }
1538   }
1539 
1540   if (NoIdentIsFound) {
1541     Diag(Tok, diag::err_expected) << tok::identifier;
1542     IsCorrect = false;
1543   }
1544 
1545   // Parse ')'.
1546   IsCorrect = !T.consumeClose() && IsCorrect;
1547 
1548   return !IsCorrect;
1549 }
1550 
1551 /// Parsing of OpenMP clauses.
1552 ///
1553 ///    clause:
1554 ///       if-clause | final-clause | num_threads-clause | safelen-clause |
1555 ///       default-clause | private-clause | firstprivate-clause | shared-clause
1556 ///       | linear-clause | aligned-clause | collapse-clause |
1557 ///       lastprivate-clause | reduction-clause | proc_bind-clause |
1558 ///       schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
1559 ///       mergeable-clause | flush-clause | read-clause | write-clause |
1560 ///       update-clause | capture-clause | seq_cst-clause | device-clause |
1561 ///       simdlen-clause | threads-clause | simd-clause | num_teams-clause |
1562 ///       thread_limit-clause | priority-clause | grainsize-clause |
1563 ///       nogroup-clause | num_tasks-clause | hint-clause | to-clause |
1564 ///       from-clause | is_device_ptr-clause | task_reduction-clause |
1565 ///       in_reduction-clause | allocator-clause | allocate-clause
1566 ///
1567 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
1568                                      OpenMPClauseKind CKind, bool FirstClause) {
1569   OMPClause *Clause = nullptr;
1570   bool ErrorFound = false;
1571   bool WrongDirective = false;
1572   // Check if clause is allowed for the given directive.
1573   if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) {
1574     Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
1575                                                << getOpenMPDirectiveName(DKind);
1576     ErrorFound = true;
1577     WrongDirective = true;
1578   }
1579 
1580   switch (CKind) {
1581   case OMPC_final:
1582   case OMPC_num_threads:
1583   case OMPC_safelen:
1584   case OMPC_simdlen:
1585   case OMPC_collapse:
1586   case OMPC_ordered:
1587   case OMPC_device:
1588   case OMPC_num_teams:
1589   case OMPC_thread_limit:
1590   case OMPC_priority:
1591   case OMPC_grainsize:
1592   case OMPC_num_tasks:
1593   case OMPC_hint:
1594   case OMPC_allocator:
1595     // OpenMP [2.5, Restrictions]
1596     //  At most one num_threads clause can appear on the directive.
1597     // OpenMP [2.8.1, simd construct, Restrictions]
1598     //  Only one safelen  clause can appear on a simd directive.
1599     //  Only one simdlen  clause can appear on a simd directive.
1600     //  Only one collapse clause can appear on a simd directive.
1601     // OpenMP [2.9.1, target data construct, Restrictions]
1602     //  At most one device clause can appear on the directive.
1603     // OpenMP [2.11.1, task Construct, Restrictions]
1604     //  At most one if clause can appear on the directive.
1605     //  At most one final clause can appear on the directive.
1606     // OpenMP [teams Construct, Restrictions]
1607     //  At most one num_teams clause can appear on the directive.
1608     //  At most one thread_limit clause can appear on the directive.
1609     // OpenMP [2.9.1, task Construct, Restrictions]
1610     // At most one priority clause can appear on the directive.
1611     // OpenMP [2.9.2, taskloop Construct, Restrictions]
1612     // At most one grainsize clause can appear on the directive.
1613     // OpenMP [2.9.2, taskloop Construct, Restrictions]
1614     // At most one num_tasks clause can appear on the directive.
1615     // OpenMP [2.11.3, allocate Directive, Restrictions]
1616     // At most one allocator clause can appear on the directive.
1617     if (!FirstClause) {
1618       Diag(Tok, diag::err_omp_more_one_clause)
1619           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1620       ErrorFound = true;
1621     }
1622 
1623     if (CKind == OMPC_ordered && PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
1624       Clause = ParseOpenMPClause(CKind, WrongDirective);
1625     else
1626       Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
1627     break;
1628   case OMPC_default:
1629   case OMPC_proc_bind:
1630   case OMPC_atomic_default_mem_order:
1631     // OpenMP [2.14.3.1, Restrictions]
1632     //  Only a single default clause may be specified on a parallel, task or
1633     //  teams directive.
1634     // OpenMP [2.5, parallel Construct, Restrictions]
1635     //  At most one proc_bind clause can appear on the directive.
1636     // OpenMP [5.0, Requires directive, Restrictions]
1637     //  At most one atomic_default_mem_order clause can appear
1638     //  on the directive
1639     if (!FirstClause) {
1640       Diag(Tok, diag::err_omp_more_one_clause)
1641           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1642       ErrorFound = true;
1643     }
1644 
1645     Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
1646     break;
1647   case OMPC_schedule:
1648   case OMPC_dist_schedule:
1649   case OMPC_defaultmap:
1650     // OpenMP [2.7.1, Restrictions, p. 3]
1651     //  Only one schedule clause can appear on a loop directive.
1652     // OpenMP [2.10.4, Restrictions, p. 106]
1653     //  At most one defaultmap clause can appear on the directive.
1654     if (!FirstClause) {
1655       Diag(Tok, diag::err_omp_more_one_clause)
1656           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1657       ErrorFound = true;
1658     }
1659     LLVM_FALLTHROUGH;
1660 
1661   case OMPC_if:
1662     Clause = ParseOpenMPSingleExprWithArgClause(CKind, WrongDirective);
1663     break;
1664   case OMPC_nowait:
1665   case OMPC_untied:
1666   case OMPC_mergeable:
1667   case OMPC_read:
1668   case OMPC_write:
1669   case OMPC_update:
1670   case OMPC_capture:
1671   case OMPC_seq_cst:
1672   case OMPC_threads:
1673   case OMPC_simd:
1674   case OMPC_nogroup:
1675   case OMPC_unified_address:
1676   case OMPC_unified_shared_memory:
1677   case OMPC_reverse_offload:
1678   case OMPC_dynamic_allocators:
1679     // OpenMP [2.7.1, Restrictions, p. 9]
1680     //  Only one ordered clause can appear on a loop directive.
1681     // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
1682     //  Only one nowait clause can appear on a for directive.
1683     // OpenMP [5.0, Requires directive, Restrictions]
1684     //   Each of the requires clauses can appear at most once on the directive.
1685     if (!FirstClause) {
1686       Diag(Tok, diag::err_omp_more_one_clause)
1687           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1688       ErrorFound = true;
1689     }
1690 
1691     Clause = ParseOpenMPClause(CKind, WrongDirective);
1692     break;
1693   case OMPC_private:
1694   case OMPC_firstprivate:
1695   case OMPC_lastprivate:
1696   case OMPC_shared:
1697   case OMPC_reduction:
1698   case OMPC_task_reduction:
1699   case OMPC_in_reduction:
1700   case OMPC_linear:
1701   case OMPC_aligned:
1702   case OMPC_copyin:
1703   case OMPC_copyprivate:
1704   case OMPC_flush:
1705   case OMPC_depend:
1706   case OMPC_map:
1707   case OMPC_to:
1708   case OMPC_from:
1709   case OMPC_use_device_ptr:
1710   case OMPC_is_device_ptr:
1711   case OMPC_allocate:
1712     Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
1713     break;
1714   case OMPC_unknown:
1715     Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1716         << getOpenMPDirectiveName(DKind);
1717     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1718     break;
1719   case OMPC_threadprivate:
1720   case OMPC_uniform:
1721     if (!WrongDirective)
1722       Diag(Tok, diag::err_omp_unexpected_clause)
1723           << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
1724     SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
1725     break;
1726   }
1727   return ErrorFound ? nullptr : Clause;
1728 }
1729 
1730 /// Parses simple expression in parens for single-expression clauses of OpenMP
1731 /// constructs.
1732 /// \param RLoc Returned location of right paren.
1733 ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
1734                                          SourceLocation &RLoc) {
1735   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1736   if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
1737     return ExprError();
1738 
1739   SourceLocation ELoc = Tok.getLocation();
1740   ExprResult LHS(ParseCastExpression(
1741       /*isUnaryExpression=*/false, /*isAddressOfOperand=*/false, NotTypeCast));
1742   ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
1743   Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
1744 
1745   // Parse ')'.
1746   RLoc = Tok.getLocation();
1747   if (!T.consumeClose())
1748     RLoc = T.getCloseLocation();
1749 
1750   return Val;
1751 }
1752 
1753 /// Parsing of OpenMP clauses with single expressions like 'final',
1754 /// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
1755 /// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks' or 'hint'.
1756 ///
1757 ///    final-clause:
1758 ///      'final' '(' expression ')'
1759 ///
1760 ///    num_threads-clause:
1761 ///      'num_threads' '(' expression ')'
1762 ///
1763 ///    safelen-clause:
1764 ///      'safelen' '(' expression ')'
1765 ///
1766 ///    simdlen-clause:
1767 ///      'simdlen' '(' expression ')'
1768 ///
1769 ///    collapse-clause:
1770 ///      'collapse' '(' expression ')'
1771 ///
1772 ///    priority-clause:
1773 ///      'priority' '(' expression ')'
1774 ///
1775 ///    grainsize-clause:
1776 ///      'grainsize' '(' expression ')'
1777 ///
1778 ///    num_tasks-clause:
1779 ///      'num_tasks' '(' expression ')'
1780 ///
1781 ///    hint-clause:
1782 ///      'hint' '(' expression ')'
1783 ///
1784 ///    allocator-clause:
1785 ///      'allocator' '(' expression ')'
1786 ///
1787 OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
1788                                                bool ParseOnly) {
1789   SourceLocation Loc = ConsumeToken();
1790   SourceLocation LLoc = Tok.getLocation();
1791   SourceLocation RLoc;
1792 
1793   ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc);
1794 
1795   if (Val.isInvalid())
1796     return nullptr;
1797 
1798   if (ParseOnly)
1799     return nullptr;
1800   return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc);
1801 }
1802 
1803 /// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
1804 ///
1805 ///    default-clause:
1806 ///         'default' '(' 'none' | 'shared' ')
1807 ///
1808 ///    proc_bind-clause:
1809 ///         'proc_bind' '(' 'master' | 'close' | 'spread' ')
1810 ///
1811 OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind,
1812                                            bool ParseOnly) {
1813   SourceLocation Loc = Tok.getLocation();
1814   SourceLocation LOpen = ConsumeToken();
1815   // Parse '('.
1816   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1817   if (T.expectAndConsume(diag::err_expected_lparen_after,
1818                          getOpenMPClauseName(Kind)))
1819     return nullptr;
1820 
1821   unsigned Type = getOpenMPSimpleClauseType(
1822       Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1823   SourceLocation TypeLoc = Tok.getLocation();
1824   if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1825       Tok.isNot(tok::annot_pragma_openmp_end))
1826     ConsumeAnyToken();
1827 
1828   // Parse ')'.
1829   SourceLocation RLoc = Tok.getLocation();
1830   if (!T.consumeClose())
1831     RLoc = T.getCloseLocation();
1832 
1833   if (ParseOnly)
1834     return nullptr;
1835   return Actions.ActOnOpenMPSimpleClause(Kind, Type, TypeLoc, LOpen, Loc, RLoc);
1836 }
1837 
1838 /// Parsing of OpenMP clauses like 'ordered'.
1839 ///
1840 ///    ordered-clause:
1841 ///         'ordered'
1842 ///
1843 ///    nowait-clause:
1844 ///         'nowait'
1845 ///
1846 ///    untied-clause:
1847 ///         'untied'
1848 ///
1849 ///    mergeable-clause:
1850 ///         'mergeable'
1851 ///
1852 ///    read-clause:
1853 ///         'read'
1854 ///
1855 ///    threads-clause:
1856 ///         'threads'
1857 ///
1858 ///    simd-clause:
1859 ///         'simd'
1860 ///
1861 ///    nogroup-clause:
1862 ///         'nogroup'
1863 ///
1864 OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly) {
1865   SourceLocation Loc = Tok.getLocation();
1866   ConsumeAnyToken();
1867 
1868   if (ParseOnly)
1869     return nullptr;
1870   return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
1871 }
1872 
1873 
1874 /// Parsing of OpenMP clauses with single expressions and some additional
1875 /// argument like 'schedule' or 'dist_schedule'.
1876 ///
1877 ///    schedule-clause:
1878 ///      'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
1879 ///      ')'
1880 ///
1881 ///    if-clause:
1882 ///      'if' '(' [ directive-name-modifier ':' ] expression ')'
1883 ///
1884 ///    defaultmap:
1885 ///      'defaultmap' '(' modifier ':' kind ')'
1886 ///
1887 OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,
1888                                                       bool ParseOnly) {
1889   SourceLocation Loc = ConsumeToken();
1890   SourceLocation DelimLoc;
1891   // Parse '('.
1892   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1893   if (T.expectAndConsume(diag::err_expected_lparen_after,
1894                          getOpenMPClauseName(Kind)))
1895     return nullptr;
1896 
1897   ExprResult Val;
1898   SmallVector<unsigned, 4> Arg;
1899   SmallVector<SourceLocation, 4> KLoc;
1900   if (Kind == OMPC_schedule) {
1901     enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
1902     Arg.resize(NumberOfElements);
1903     KLoc.resize(NumberOfElements);
1904     Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
1905     Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
1906     Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
1907     unsigned KindModifier = getOpenMPSimpleClauseType(
1908         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1909     if (KindModifier > OMPC_SCHEDULE_unknown) {
1910       // Parse 'modifier'
1911       Arg[Modifier1] = KindModifier;
1912       KLoc[Modifier1] = Tok.getLocation();
1913       if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1914           Tok.isNot(tok::annot_pragma_openmp_end))
1915         ConsumeAnyToken();
1916       if (Tok.is(tok::comma)) {
1917         // Parse ',' 'modifier'
1918         ConsumeAnyToken();
1919         KindModifier = getOpenMPSimpleClauseType(
1920             Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1921         Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown
1922                              ? KindModifier
1923                              : (unsigned)OMPC_SCHEDULE_unknown;
1924         KLoc[Modifier2] = Tok.getLocation();
1925         if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1926             Tok.isNot(tok::annot_pragma_openmp_end))
1927           ConsumeAnyToken();
1928       }
1929       // Parse ':'
1930       if (Tok.is(tok::colon))
1931         ConsumeAnyToken();
1932       else
1933         Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier";
1934       KindModifier = getOpenMPSimpleClauseType(
1935           Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1936     }
1937     Arg[ScheduleKind] = KindModifier;
1938     KLoc[ScheduleKind] = Tok.getLocation();
1939     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1940         Tok.isNot(tok::annot_pragma_openmp_end))
1941       ConsumeAnyToken();
1942     if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
1943          Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
1944          Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
1945         Tok.is(tok::comma))
1946       DelimLoc = ConsumeAnyToken();
1947   } else if (Kind == OMPC_dist_schedule) {
1948     Arg.push_back(getOpenMPSimpleClauseType(
1949         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1950     KLoc.push_back(Tok.getLocation());
1951     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1952         Tok.isNot(tok::annot_pragma_openmp_end))
1953       ConsumeAnyToken();
1954     if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
1955       DelimLoc = ConsumeAnyToken();
1956   } else if (Kind == OMPC_defaultmap) {
1957     // Get a defaultmap modifier
1958     Arg.push_back(getOpenMPSimpleClauseType(
1959         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1960     KLoc.push_back(Tok.getLocation());
1961     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1962         Tok.isNot(tok::annot_pragma_openmp_end))
1963       ConsumeAnyToken();
1964     // Parse ':'
1965     if (Tok.is(tok::colon))
1966       ConsumeAnyToken();
1967     else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown)
1968       Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier";
1969     // Get a defaultmap kind
1970     Arg.push_back(getOpenMPSimpleClauseType(
1971         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1972     KLoc.push_back(Tok.getLocation());
1973     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1974         Tok.isNot(tok::annot_pragma_openmp_end))
1975       ConsumeAnyToken();
1976   } else {
1977     assert(Kind == OMPC_if);
1978     KLoc.push_back(Tok.getLocation());
1979     TentativeParsingAction TPA(*this);
1980     Arg.push_back(parseOpenMPDirectiveKind(*this));
1981     if (Arg.back() != OMPD_unknown) {
1982       ConsumeToken();
1983       if (Tok.is(tok::colon) && getLangOpts().OpenMP > 40) {
1984         TPA.Commit();
1985         DelimLoc = ConsumeToken();
1986       } else {
1987         TPA.Revert();
1988         Arg.back() = OMPD_unknown;
1989       }
1990     } else {
1991       TPA.Revert();
1992     }
1993   }
1994 
1995   bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) ||
1996                           (Kind == OMPC_dist_schedule && DelimLoc.isValid()) ||
1997                           Kind == OMPC_if;
1998   if (NeedAnExpression) {
1999     SourceLocation ELoc = Tok.getLocation();
2000     ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
2001     Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
2002     Val =
2003         Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
2004   }
2005 
2006   // Parse ')'.
2007   SourceLocation RLoc = Tok.getLocation();
2008   if (!T.consumeClose())
2009     RLoc = T.getCloseLocation();
2010 
2011   if (NeedAnExpression && Val.isInvalid())
2012     return nullptr;
2013 
2014   if (ParseOnly)
2015     return nullptr;
2016   return Actions.ActOnOpenMPSingleExprWithArgClause(
2017       Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
2018 }
2019 
2020 static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
2021                              UnqualifiedId &ReductionId) {
2022   if (ReductionIdScopeSpec.isEmpty()) {
2023     auto OOK = OO_None;
2024     switch (P.getCurToken().getKind()) {
2025     case tok::plus:
2026       OOK = OO_Plus;
2027       break;
2028     case tok::minus:
2029       OOK = OO_Minus;
2030       break;
2031     case tok::star:
2032       OOK = OO_Star;
2033       break;
2034     case tok::amp:
2035       OOK = OO_Amp;
2036       break;
2037     case tok::pipe:
2038       OOK = OO_Pipe;
2039       break;
2040     case tok::caret:
2041       OOK = OO_Caret;
2042       break;
2043     case tok::ampamp:
2044       OOK = OO_AmpAmp;
2045       break;
2046     case tok::pipepipe:
2047       OOK = OO_PipePipe;
2048       break;
2049     default:
2050       break;
2051     }
2052     if (OOK != OO_None) {
2053       SourceLocation OpLoc = P.ConsumeToken();
2054       SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
2055       ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
2056       return false;
2057     }
2058   }
2059   return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false,
2060                               /*AllowDestructorName*/ false,
2061                               /*AllowConstructorName*/ false,
2062                               /*AllowDeductionGuide*/ false,
2063                               nullptr, nullptr, ReductionId);
2064 }
2065 
2066 /// Checks if the token is a valid map-type-modifier.
2067 static OpenMPMapModifierKind isMapModifier(Parser &P) {
2068   Token Tok = P.getCurToken();
2069   if (!Tok.is(tok::identifier))
2070     return OMPC_MAP_MODIFIER_unknown;
2071 
2072   Preprocessor &PP = P.getPreprocessor();
2073   OpenMPMapModifierKind TypeModifier = static_cast<OpenMPMapModifierKind>(
2074       getOpenMPSimpleClauseType(OMPC_map, PP.getSpelling(Tok)));
2075   return TypeModifier;
2076 }
2077 
2078 /// Parse the mapper modifier in map, to, and from clauses.
2079 bool Parser::parseMapperModifier(OpenMPVarListDataTy &Data) {
2080   // Parse '('.
2081   BalancedDelimiterTracker T(*this, tok::l_paren, tok::colon);
2082   if (T.expectAndConsume(diag::err_expected_lparen_after, "mapper")) {
2083     SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2084               StopBeforeMatch);
2085     return true;
2086   }
2087   // Parse mapper-identifier
2088   if (getLangOpts().CPlusPlus)
2089     ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
2090                                    /*ObjectType=*/nullptr,
2091                                    /*EnteringContext=*/false);
2092   if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
2093     Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
2094     SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2095               StopBeforeMatch);
2096     return true;
2097   }
2098   auto &DeclNames = Actions.getASTContext().DeclarationNames;
2099   Data.ReductionOrMapperId = DeclarationNameInfo(
2100       DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
2101   ConsumeToken();
2102   // Parse ')'.
2103   return T.consumeClose();
2104 }
2105 
2106 /// Parse map-type-modifiers in map clause.
2107 /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
2108 /// where, map-type-modifier ::= always | close | mapper(mapper-identifier)
2109 bool Parser::parseMapTypeModifiers(OpenMPVarListDataTy &Data) {
2110   while (getCurToken().isNot(tok::colon)) {
2111     OpenMPMapModifierKind TypeModifier = isMapModifier(*this);
2112     if (TypeModifier == OMPC_MAP_MODIFIER_always ||
2113         TypeModifier == OMPC_MAP_MODIFIER_close) {
2114       Data.MapTypeModifiers.push_back(TypeModifier);
2115       Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
2116       ConsumeToken();
2117     } else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
2118       Data.MapTypeModifiers.push_back(TypeModifier);
2119       Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
2120       ConsumeToken();
2121       if (parseMapperModifier(Data))
2122         return true;
2123     } else {
2124       // For the case of unknown map-type-modifier or a map-type.
2125       // Map-type is followed by a colon; the function returns when it
2126       // encounters a token followed by a colon.
2127       if (Tok.is(tok::comma)) {
2128         Diag(Tok, diag::err_omp_map_type_modifier_missing);
2129         ConsumeToken();
2130         continue;
2131       }
2132       // Potential map-type token as it is followed by a colon.
2133       if (PP.LookAhead(0).is(tok::colon))
2134         return false;
2135       Diag(Tok, diag::err_omp_unknown_map_type_modifier);
2136       ConsumeToken();
2137     }
2138     if (getCurToken().is(tok::comma))
2139       ConsumeToken();
2140   }
2141   return false;
2142 }
2143 
2144 /// Checks if the token is a valid map-type.
2145 static OpenMPMapClauseKind isMapType(Parser &P) {
2146   Token Tok = P.getCurToken();
2147   // The map-type token can be either an identifier or the C++ delete keyword.
2148   if (!Tok.isOneOf(tok::identifier, tok::kw_delete))
2149     return OMPC_MAP_unknown;
2150   Preprocessor &PP = P.getPreprocessor();
2151   OpenMPMapClauseKind MapType = static_cast<OpenMPMapClauseKind>(
2152       getOpenMPSimpleClauseType(OMPC_map, PP.getSpelling(Tok)));
2153   return MapType;
2154 }
2155 
2156 /// Parse map-type in map clause.
2157 /// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
2158 /// where, map-type ::= to | from | tofrom | alloc | release | delete
2159 static void parseMapType(Parser &P, Parser::OpenMPVarListDataTy &Data) {
2160   Token Tok = P.getCurToken();
2161   if (Tok.is(tok::colon)) {
2162     P.Diag(Tok, diag::err_omp_map_type_missing);
2163     return;
2164   }
2165   Data.MapType = isMapType(P);
2166   if (Data.MapType == OMPC_MAP_unknown)
2167     P.Diag(Tok, diag::err_omp_unknown_map_type);
2168   P.ConsumeToken();
2169 }
2170 
2171 /// Parses clauses with list.
2172 bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
2173                                 OpenMPClauseKind Kind,
2174                                 SmallVectorImpl<Expr *> &Vars,
2175                                 OpenMPVarListDataTy &Data) {
2176   UnqualifiedId UnqualifiedReductionId;
2177   bool InvalidReductionId = false;
2178   bool IsInvalidMapperModifier = false;
2179 
2180   // Parse '('.
2181   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2182   if (T.expectAndConsume(diag::err_expected_lparen_after,
2183                          getOpenMPClauseName(Kind)))
2184     return true;
2185 
2186   bool NeedRParenForLinear = false;
2187   BalancedDelimiterTracker LinearT(*this, tok::l_paren,
2188                                   tok::annot_pragma_openmp_end);
2189   // Handle reduction-identifier for reduction clause.
2190   if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
2191       Kind == OMPC_in_reduction) {
2192     ColonProtectionRAIIObject ColonRAII(*this);
2193     if (getLangOpts().CPlusPlus)
2194       ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
2195                                      /*ObjectType=*/nullptr,
2196                                      /*EnteringContext=*/false);
2197     InvalidReductionId = ParseReductionId(
2198         *this, Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
2199     if (InvalidReductionId) {
2200       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2201                 StopBeforeMatch);
2202     }
2203     if (Tok.is(tok::colon))
2204       Data.ColonLoc = ConsumeToken();
2205     else
2206       Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
2207     if (!InvalidReductionId)
2208       Data.ReductionOrMapperId =
2209           Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
2210   } else if (Kind == OMPC_depend) {
2211   // Handle dependency type for depend clause.
2212     ColonProtectionRAIIObject ColonRAII(*this);
2213     Data.DepKind =
2214         static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType(
2215             Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
2216     Data.DepLinMapLoc = Tok.getLocation();
2217 
2218     if (Data.DepKind == OMPC_DEPEND_unknown) {
2219       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2220                 StopBeforeMatch);
2221     } else {
2222       ConsumeToken();
2223       // Special processing for depend(source) clause.
2224       if (DKind == OMPD_ordered && Data.DepKind == OMPC_DEPEND_source) {
2225         // Parse ')'.
2226         T.consumeClose();
2227         return false;
2228       }
2229     }
2230     if (Tok.is(tok::colon)) {
2231       Data.ColonLoc = ConsumeToken();
2232     } else {
2233       Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
2234                                       : diag::warn_pragma_expected_colon)
2235           << "dependency type";
2236     }
2237   } else if (Kind == OMPC_linear) {
2238     // Try to parse modifier if any.
2239     if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
2240       Data.LinKind = static_cast<OpenMPLinearClauseKind>(
2241           getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
2242       Data.DepLinMapLoc = ConsumeToken();
2243       LinearT.consumeOpen();
2244       NeedRParenForLinear = true;
2245     }
2246   } else if (Kind == OMPC_map) {
2247     // Handle map type for map clause.
2248     ColonProtectionRAIIObject ColonRAII(*this);
2249 
2250     // The first identifier may be a list item, a map-type or a
2251     // map-type-modifier. The map-type can also be delete which has the same
2252     // spelling of the C++ delete keyword.
2253     Data.DepLinMapLoc = Tok.getLocation();
2254 
2255     // Check for presence of a colon in the map clause.
2256     TentativeParsingAction TPA(*this);
2257     bool ColonPresent = false;
2258     if (SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2259         StopBeforeMatch)) {
2260       if (Tok.is(tok::colon))
2261         ColonPresent = true;
2262     }
2263     TPA.Revert();
2264     // Only parse map-type-modifier[s] and map-type if a colon is present in
2265     // the map clause.
2266     if (ColonPresent) {
2267       IsInvalidMapperModifier = parseMapTypeModifiers(Data);
2268       if (!IsInvalidMapperModifier)
2269         parseMapType(*this, Data);
2270       else
2271         SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch);
2272     }
2273     if (Data.MapType == OMPC_MAP_unknown) {
2274       Data.MapType = OMPC_MAP_tofrom;
2275       Data.IsMapTypeImplicit = true;
2276     }
2277 
2278     if (Tok.is(tok::colon))
2279       Data.ColonLoc = ConsumeToken();
2280   } else if (Kind == OMPC_to || Kind == OMPC_from) {
2281     if (Tok.is(tok::identifier)) {
2282       bool IsMapperModifier = false;
2283       if (Kind == OMPC_to) {
2284         auto Modifier = static_cast<OpenMPToModifierKind>(
2285             getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
2286         if (Modifier == OMPC_TO_MODIFIER_mapper)
2287           IsMapperModifier = true;
2288       } else {
2289         auto Modifier = static_cast<OpenMPFromModifierKind>(
2290             getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
2291         if (Modifier == OMPC_FROM_MODIFIER_mapper)
2292           IsMapperModifier = true;
2293       }
2294       if (IsMapperModifier) {
2295         // Parse the mapper modifier.
2296         ConsumeToken();
2297         IsInvalidMapperModifier = parseMapperModifier(Data);
2298         if (Tok.isNot(tok::colon)) {
2299           if (!IsInvalidMapperModifier)
2300             Diag(Tok, diag::warn_pragma_expected_colon) << ")";
2301           SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2302                     StopBeforeMatch);
2303         }
2304         // Consume ':'.
2305         if (Tok.is(tok::colon))
2306           ConsumeToken();
2307       }
2308     }
2309   } else if (Kind == OMPC_allocate) {
2310     // Handle optional allocator expression followed by colon delimiter.
2311     ColonProtectionRAIIObject ColonRAII(*this);
2312     TentativeParsingAction TPA(*this);
2313     ExprResult Tail =
2314         Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
2315     Tail = Actions.ActOnFinishFullExpr(Tail.get(), T.getOpenLocation(),
2316                                        /*DiscardedValue=*/false);
2317     if (Tail.isUsable()) {
2318       if (Tok.is(tok::colon)) {
2319         Data.TailExpr = Tail.get();
2320         Data.ColonLoc = ConsumeToken();
2321         TPA.Commit();
2322       } else {
2323         // colon not found, no allocator specified, parse only list of
2324         // variables.
2325         TPA.Revert();
2326       }
2327     } else {
2328       // Parsing was unsuccessfull, revert and skip to the end of clause or
2329       // directive.
2330       TPA.Revert();
2331       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2332                 StopBeforeMatch);
2333     }
2334   }
2335 
2336   bool IsComma =
2337       (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
2338        Kind != OMPC_in_reduction && Kind != OMPC_depend && Kind != OMPC_map) ||
2339       (Kind == OMPC_reduction && !InvalidReductionId) ||
2340       (Kind == OMPC_map && Data.MapType != OMPC_MAP_unknown) ||
2341       (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown);
2342   const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
2343   while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
2344                      Tok.isNot(tok::annot_pragma_openmp_end))) {
2345     ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
2346     // Parse variable
2347     ExprResult VarExpr =
2348         Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
2349     if (VarExpr.isUsable()) {
2350       Vars.push_back(VarExpr.get());
2351     } else {
2352       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2353                 StopBeforeMatch);
2354     }
2355     // Skip ',' if any
2356     IsComma = Tok.is(tok::comma);
2357     if (IsComma)
2358       ConsumeToken();
2359     else if (Tok.isNot(tok::r_paren) &&
2360              Tok.isNot(tok::annot_pragma_openmp_end) &&
2361              (!MayHaveTail || Tok.isNot(tok::colon)))
2362       Diag(Tok, diag::err_omp_expected_punc)
2363           << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
2364                                    : getOpenMPClauseName(Kind))
2365           << (Kind == OMPC_flush);
2366   }
2367 
2368   // Parse ')' for linear clause with modifier.
2369   if (NeedRParenForLinear)
2370     LinearT.consumeClose();
2371 
2372   // Parse ':' linear-step (or ':' alignment).
2373   const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
2374   if (MustHaveTail) {
2375     Data.ColonLoc = Tok.getLocation();
2376     SourceLocation ELoc = ConsumeToken();
2377     ExprResult Tail = ParseAssignmentExpression();
2378     Tail =
2379         Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false);
2380     if (Tail.isUsable())
2381       Data.TailExpr = Tail.get();
2382     else
2383       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2384                 StopBeforeMatch);
2385   }
2386 
2387   // Parse ')'.
2388   Data.RLoc = Tok.getLocation();
2389   if (!T.consumeClose())
2390     Data.RLoc = T.getCloseLocation();
2391   return (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown &&
2392           Vars.empty()) ||
2393          (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
2394          (MustHaveTail && !Data.TailExpr) || InvalidReductionId ||
2395          IsInvalidMapperModifier;
2396 }
2397 
2398 /// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
2399 /// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction' or
2400 /// 'in_reduction'.
2401 ///
2402 ///    private-clause:
2403 ///       'private' '(' list ')'
2404 ///    firstprivate-clause:
2405 ///       'firstprivate' '(' list ')'
2406 ///    lastprivate-clause:
2407 ///       'lastprivate' '(' list ')'
2408 ///    shared-clause:
2409 ///       'shared' '(' list ')'
2410 ///    linear-clause:
2411 ///       'linear' '(' linear-list [ ':' linear-step ] ')'
2412 ///    aligned-clause:
2413 ///       'aligned' '(' list [ ':' alignment ] ')'
2414 ///    reduction-clause:
2415 ///       'reduction' '(' reduction-identifier ':' list ')'
2416 ///    task_reduction-clause:
2417 ///       'task_reduction' '(' reduction-identifier ':' list ')'
2418 ///    in_reduction-clause:
2419 ///       'in_reduction' '(' reduction-identifier ':' list ')'
2420 ///    copyprivate-clause:
2421 ///       'copyprivate' '(' list ')'
2422 ///    flush-clause:
2423 ///       'flush' '(' list ')'
2424 ///    depend-clause:
2425 ///       'depend' '(' in | out | inout : list | source ')'
2426 ///    map-clause:
2427 ///       'map' '(' [ [ always [,] ] [ close [,] ]
2428 ///          [ mapper '(' mapper-identifier ')' [,] ]
2429 ///          to | from | tofrom | alloc | release | delete ':' ] list ')';
2430 ///    to-clause:
2431 ///       'to' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
2432 ///    from-clause:
2433 ///       'from' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
2434 ///    use_device_ptr-clause:
2435 ///       'use_device_ptr' '(' list ')'
2436 ///    is_device_ptr-clause:
2437 ///       'is_device_ptr' '(' list ')'
2438 ///    allocate-clause:
2439 ///       'allocate' '(' [ allocator ':' ] list ')'
2440 ///
2441 /// For 'linear' clause linear-list may have the following forms:
2442 ///  list
2443 ///  modifier(list)
2444 /// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
2445 OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
2446                                             OpenMPClauseKind Kind,
2447                                             bool ParseOnly) {
2448   SourceLocation Loc = Tok.getLocation();
2449   SourceLocation LOpen = ConsumeToken();
2450   SmallVector<Expr *, 4> Vars;
2451   OpenMPVarListDataTy Data;
2452 
2453   if (ParseOpenMPVarList(DKind, Kind, Vars, Data))
2454     return nullptr;
2455 
2456   if (ParseOnly)
2457     return nullptr;
2458   OMPVarListLocTy Locs(Loc, LOpen, Data.RLoc);
2459   return Actions.ActOnOpenMPVarListClause(
2460       Kind, Vars, Data.TailExpr, Locs, Data.ColonLoc,
2461       Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId, Data.DepKind,
2462       Data.LinKind, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
2463       Data.MapType, Data.IsMapTypeImplicit, Data.DepLinMapLoc);
2464 }
2465 
2466