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