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