1 //===--- ParseOpenMP.cpp - OpenMP directives parsing ----------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 /// \brief This file implements parsing of all OpenMP directives and clauses.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #include "RAIIObjectsForParser.h"
15 #include "clang/AST/ASTConsumer.h"
16 #include "clang/AST/ASTContext.h"
17 #include "clang/AST/StmtOpenMP.h"
18 #include "clang/Parse/ParseDiagnostic.h"
19 #include "clang/Parse/Parser.h"
20 #include "clang/Sema/Scope.h"
21 #include "llvm/ADT/PointerIntPair.h"
22 
23 using namespace clang;
24 
25 //===----------------------------------------------------------------------===//
26 // OpenMP declarative directives.
27 //===----------------------------------------------------------------------===//
28 
29 namespace {
30 enum OpenMPDirectiveKindEx {
31   OMPD_cancellation = OMPD_unknown + 1,
32   OMPD_data,
33   OMPD_declare,
34   OMPD_enter,
35   OMPD_exit,
36   OMPD_point,
37   OMPD_reduction,
38   OMPD_target_enter,
39   OMPD_target_exit
40 };
41 } // namespace
42 
43 // Map token string to extended OMP token kind that are
44 // OpenMPDirectiveKind + OpenMPDirectiveKindEx.
45 static unsigned getOpenMPDirectiveKindEx(StringRef S) {
46   auto DKind = getOpenMPDirectiveKind(S);
47   if (DKind != OMPD_unknown)
48     return DKind;
49 
50   return llvm::StringSwitch<unsigned>(S)
51       .Case("cancellation", OMPD_cancellation)
52       .Case("data", OMPD_data)
53       .Case("declare", OMPD_declare)
54       .Case("enter", OMPD_enter)
55       .Case("exit", OMPD_exit)
56       .Case("point", OMPD_point)
57       .Case("reduction", OMPD_reduction)
58       .Default(OMPD_unknown);
59 }
60 
61 static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P) {
62   // Array of foldings: F[i][0] F[i][1] ===> F[i][2].
63   // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd
64   // TODO: add other combined directives in topological order.
65   static const unsigned F[][3] = {
66     { OMPD_cancellation, OMPD_point, OMPD_cancellation_point },
67     { OMPD_declare, OMPD_reduction, OMPD_declare_reduction },
68     { OMPD_target, OMPD_data, OMPD_target_data },
69     { OMPD_target, OMPD_enter, OMPD_target_enter },
70     { OMPD_target, OMPD_exit, OMPD_target_exit },
71     { OMPD_target_enter, OMPD_data, OMPD_target_enter_data },
72     { OMPD_target_exit, OMPD_data, OMPD_target_exit_data },
73     { OMPD_for, OMPD_simd, OMPD_for_simd },
74     { OMPD_parallel, OMPD_for, OMPD_parallel_for },
75     { OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd },
76     { OMPD_parallel, OMPD_sections, OMPD_parallel_sections },
77     { OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd },
78     { OMPD_target, OMPD_parallel, OMPD_target_parallel },
79     { OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for }
80   };
81   enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };
82   auto Tok = P.getCurToken();
83   unsigned DKind =
84       Tok.isAnnotation()
85           ? static_cast<unsigned>(OMPD_unknown)
86           : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
87   if (DKind == OMPD_unknown)
88     return OMPD_unknown;
89 
90   for (unsigned i = 0; i < llvm::array_lengthof(F); ++i) {
91     if (DKind != F[i][0])
92       continue;
93 
94     Tok = P.getPreprocessor().LookAhead(0);
95     unsigned SDKind =
96         Tok.isAnnotation()
97             ? static_cast<unsigned>(OMPD_unknown)
98             : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
99     if (SDKind == OMPD_unknown)
100       continue;
101 
102     if (SDKind == F[i][1]) {
103       P.ConsumeToken();
104       DKind = F[i][2];
105     }
106   }
107   return DKind < OMPD_unknown ? static_cast<OpenMPDirectiveKind>(DKind)
108                               : OMPD_unknown;
109 }
110 
111 static DeclarationName parseOpenMPReductionId(Parser &P) {
112   Token Tok = P.getCurToken();
113   Sema &Actions = P.getActions();
114   OverloadedOperatorKind OOK = OO_None;
115   // Allow to use 'operator' keyword for C++ operators
116   bool WithOperator = false;
117   if (Tok.is(tok::kw_operator)) {
118     P.ConsumeToken();
119     Tok = P.getCurToken();
120     WithOperator = true;
121   }
122   switch (Tok.getKind()) {
123   case tok::plus: // '+'
124     OOK = OO_Plus;
125     break;
126   case tok::minus: // '-'
127     OOK = OO_Minus;
128     break;
129   case tok::star: // '*'
130     OOK = OO_Star;
131     break;
132   case tok::amp: // '&'
133     OOK = OO_Amp;
134     break;
135   case tok::pipe: // '|'
136     OOK = OO_Pipe;
137     break;
138   case tok::caret: // '^'
139     OOK = OO_Caret;
140     break;
141   case tok::ampamp: // '&&'
142     OOK = OO_AmpAmp;
143     break;
144   case tok::pipepipe: // '||'
145     OOK = OO_PipePipe;
146     break;
147   case tok::identifier: // identifier
148     if (!WithOperator)
149       break;
150   default:
151     P.Diag(Tok.getLocation(), diag::err_omp_expected_reduction_identifier);
152     P.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
153                 Parser::StopBeforeMatch);
154     return DeclarationName();
155   }
156   P.ConsumeToken();
157   auto &DeclNames = Actions.getASTContext().DeclarationNames;
158   return OOK == OO_None ? DeclNames.getIdentifier(Tok.getIdentifierInfo())
159                         : DeclNames.getCXXOperatorName(OOK);
160 }
161 
162 /// \brief Parse 'omp declare reduction' construct.
163 ///
164 ///       declare-reduction-directive:
165 ///        annot_pragma_openmp 'declare' 'reduction'
166 ///        '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')'
167 ///        ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')']
168 ///        annot_pragma_openmp_end
169 /// <reduction_id> is either a base language identifier or one of the following
170 /// operators: '+', '-', '*', '&', '|', '^', '&&' and '||'.
171 ///
172 Parser::DeclGroupPtrTy
173 Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
174   // Parse '('.
175   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
176   if (T.expectAndConsume(diag::err_expected_lparen_after,
177                          getOpenMPDirectiveName(OMPD_declare_reduction))) {
178     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
179     return DeclGroupPtrTy();
180   }
181 
182   DeclarationName Name = parseOpenMPReductionId(*this);
183   if (Name.isEmpty() && Tok.is(tok::annot_pragma_openmp_end))
184     return DeclGroupPtrTy();
185 
186   // Consume ':'.
187   bool IsCorrect = !ExpectAndConsume(tok::colon);
188 
189   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
190     return DeclGroupPtrTy();
191 
192   IsCorrect = IsCorrect && !Name.isEmpty();
193 
194   if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) {
195     Diag(Tok.getLocation(), diag::err_expected_type);
196     IsCorrect = false;
197   }
198 
199   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
200     return DeclGroupPtrTy();
201 
202   SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes;
203   // Parse list of types until ':' token.
204   do {
205     ColonProtectionRAIIObject ColonRAII(*this);
206     SourceRange Range;
207     TypeResult TR = ParseTypeName(&Range, Declarator::PrototypeContext, AS);
208     if (TR.isUsable()) {
209       auto ReductionType =
210           Actions.ActOnOpenMPDeclareReductionType(Range.getBegin(), TR);
211       if (!ReductionType.isNull()) {
212         ReductionTypes.push_back(
213             std::make_pair(ReductionType, Range.getBegin()));
214       }
215     } else {
216       SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
217                 StopBeforeMatch);
218     }
219 
220     if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end))
221       break;
222 
223     // Consume ','.
224     if (ExpectAndConsume(tok::comma)) {
225       IsCorrect = false;
226       if (Tok.is(tok::annot_pragma_openmp_end)) {
227         Diag(Tok.getLocation(), diag::err_expected_type);
228         return DeclGroupPtrTy();
229       }
230     }
231   } while (Tok.isNot(tok::annot_pragma_openmp_end));
232 
233   if (ReductionTypes.empty()) {
234     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
235     return DeclGroupPtrTy();
236   }
237 
238   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
239     return DeclGroupPtrTy();
240 
241   // Consume ':'.
242   if (ExpectAndConsume(tok::colon))
243     IsCorrect = false;
244 
245   if (Tok.is(tok::annot_pragma_openmp_end)) {
246     Diag(Tok.getLocation(), diag::err_expected_expression);
247     return DeclGroupPtrTy();
248   }
249 
250   DeclGroupPtrTy DRD = Actions.ActOnOpenMPDeclareReductionDirectiveStart(
251       getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes, AS);
252 
253   // Parse <combiner> expression and then parse initializer if any for each
254   // correct type.
255   unsigned I = 0, E = ReductionTypes.size();
256   for (auto *D : DRD.get()) {
257     TentativeParsingAction TPA(*this);
258     ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
259                                     Scope::OpenMPDirectiveScope);
260     // Parse <combiner> expression.
261     Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D);
262     ExprResult CombinerResult =
263         Actions.ActOnFinishFullExpr(ParseAssignmentExpression().get(),
264                                     D->getLocation(), /*DiscardedValue=*/true);
265     Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get());
266 
267     if (CombinerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
268         Tok.isNot(tok::annot_pragma_openmp_end)) {
269       TPA.Commit();
270       IsCorrect = false;
271       break;
272     }
273     IsCorrect = !T.consumeClose() && IsCorrect && CombinerResult.isUsable();
274     ExprResult InitializerResult;
275     if (Tok.isNot(tok::annot_pragma_openmp_end)) {
276       // Parse <initializer> expression.
277       if (Tok.is(tok::identifier) &&
278           Tok.getIdentifierInfo()->isStr("initializer"))
279         ConsumeToken();
280       else {
281         Diag(Tok.getLocation(), diag::err_expected) << "'initializer'";
282         TPA.Commit();
283         IsCorrect = false;
284         break;
285       }
286       // Parse '('.
287       BalancedDelimiterTracker T(*this, tok::l_paren,
288                                  tok::annot_pragma_openmp_end);
289       IsCorrect =
290           !T.expectAndConsume(diag::err_expected_lparen_after, "initializer") &&
291           IsCorrect;
292       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
293         ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
294                                         Scope::OpenMPDirectiveScope);
295         // Parse expression.
296         Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(), D);
297         InitializerResult = Actions.ActOnFinishFullExpr(
298             ParseAssignmentExpression().get(), D->getLocation(),
299             /*DiscardedValue=*/true);
300         Actions.ActOnOpenMPDeclareReductionInitializerEnd(
301             D, InitializerResult.get());
302         if (InitializerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
303             Tok.isNot(tok::annot_pragma_openmp_end)) {
304           TPA.Commit();
305           IsCorrect = false;
306           break;
307         }
308         IsCorrect =
309             !T.consumeClose() && IsCorrect && !InitializerResult.isInvalid();
310       }
311     }
312 
313     ++I;
314     // Revert parsing if not the last type, otherwise accept it, we're done with
315     // parsing.
316     if (I != E)
317       TPA.Revert();
318     else
319       TPA.Commit();
320   }
321   return Actions.ActOnOpenMPDeclareReductionDirectiveEnd(getCurScope(), DRD,
322                                                          IsCorrect);
323 }
324 
325 /// \brief Parsing of declarative OpenMP directives.
326 ///
327 ///       threadprivate-directive:
328 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
329 ///         annot_pragma_openmp_end
330 ///
331 ///       declare-reduction-directive:
332 ///        annot_pragma_openmp 'declare' 'reduction' [...]
333 ///        annot_pragma_openmp_end
334 ///
335 Parser::DeclGroupPtrTy
336 Parser::ParseOpenMPDeclarativeDirective(AccessSpecifier AS) {
337   assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
338   ParenBraceBracketBalancer BalancerRAIIObj(*this);
339 
340   SourceLocation Loc = ConsumeToken();
341   SmallVector<Expr *, 5> Identifiers;
342   auto DKind = ParseOpenMPDirectiveKind(*this);
343 
344   switch (DKind) {
345   case OMPD_threadprivate:
346     ConsumeToken();
347     if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Identifiers, true)) {
348       // The last seen token is annot_pragma_openmp_end - need to check for
349       // extra tokens.
350       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
351         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
352             << getOpenMPDirectiveName(OMPD_threadprivate);
353         SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
354       }
355       // Skip the last annot_pragma_openmp_end.
356       ConsumeToken();
357       return Actions.ActOnOpenMPThreadprivateDirective(Loc, Identifiers);
358     }
359     break;
360   case OMPD_declare_reduction:
361     ConsumeToken();
362     if (auto Res = ParseOpenMPDeclareReductionDirective(AS)) {
363       // The last seen token is annot_pragma_openmp_end - need to check for
364       // extra tokens.
365       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
366         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
367             << getOpenMPDirectiveName(OMPD_declare_reduction);
368         while (Tok.isNot(tok::annot_pragma_openmp_end))
369           ConsumeAnyToken();
370       }
371       // Skip the last annot_pragma_openmp_end.
372       ConsumeToken();
373       return Res;
374     }
375     break;
376   case OMPD_unknown:
377     Diag(Tok, diag::err_omp_unknown_directive);
378     break;
379   case OMPD_parallel:
380   case OMPD_simd:
381   case OMPD_task:
382   case OMPD_taskyield:
383   case OMPD_barrier:
384   case OMPD_taskwait:
385   case OMPD_taskgroup:
386   case OMPD_flush:
387   case OMPD_for:
388   case OMPD_for_simd:
389   case OMPD_sections:
390   case OMPD_section:
391   case OMPD_single:
392   case OMPD_master:
393   case OMPD_ordered:
394   case OMPD_critical:
395   case OMPD_parallel_for:
396   case OMPD_parallel_for_simd:
397   case OMPD_parallel_sections:
398   case OMPD_atomic:
399   case OMPD_target:
400   case OMPD_teams:
401   case OMPD_cancellation_point:
402   case OMPD_cancel:
403   case OMPD_target_data:
404   case OMPD_target_enter_data:
405   case OMPD_target_exit_data:
406   case OMPD_target_parallel:
407   case OMPD_target_parallel_for:
408   case OMPD_taskloop:
409   case OMPD_taskloop_simd:
410   case OMPD_distribute:
411     Diag(Tok, diag::err_omp_unexpected_directive)
412         << getOpenMPDirectiveName(DKind);
413     break;
414   }
415   while (Tok.isNot(tok::annot_pragma_openmp_end))
416     ConsumeAnyToken();
417   ConsumeAnyToken();
418   return nullptr;
419 }
420 
421 /// \brief Parsing of declarative or executable OpenMP directives.
422 ///
423 ///       threadprivate-directive:
424 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
425 ///         annot_pragma_openmp_end
426 ///
427 ///       declare-reduction-directive:
428 ///         annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
429 ///         <type> {',' <type>} ':' <expression> ')' ['initializer' '('
430 ///         ('omp_priv' '=' <expression>|<function_call>) ')']
431 ///         annot_pragma_openmp_end
432 ///
433 ///       executable-directive:
434 ///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
435 ///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
436 ///         'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
437 ///         'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' |
438 ///         'for simd' | 'parallel for simd' | 'target' | 'target data' |
439 ///         'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
440 ///         'distribute' | 'target enter data' | 'target exit data' |
441 ///         'target parallel' | 'target parallel for' {clause}
442 ///         annot_pragma_openmp_end
443 ///
444 StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
445     AllowedContsructsKind Allowed) {
446   assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
447   ParenBraceBracketBalancer BalancerRAIIObj(*this);
448   SmallVector<Expr *, 5> Identifiers;
449   SmallVector<OMPClause *, 5> Clauses;
450   SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
451   FirstClauses(OMPC_unknown + 1);
452   unsigned ScopeFlags =
453       Scope::FnScope | Scope::DeclScope | Scope::OpenMPDirectiveScope;
454   SourceLocation Loc = ConsumeToken(), EndLoc;
455   auto DKind = ParseOpenMPDirectiveKind(*this);
456   OpenMPDirectiveKind CancelRegion = OMPD_unknown;
457   // Name of critical directive.
458   DeclarationNameInfo DirName;
459   StmtResult Directive = StmtError();
460   bool HasAssociatedStatement = true;
461   bool FlushHasClause = false;
462 
463   switch (DKind) {
464   case OMPD_threadprivate:
465     if (Allowed != ACK_Any) {
466       Diag(Tok, diag::err_omp_immediate_directive)
467           << getOpenMPDirectiveName(DKind) << 0;
468     }
469     ConsumeToken();
470     if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Identifiers, false)) {
471       // The last seen token is annot_pragma_openmp_end - need to check for
472       // extra tokens.
473       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
474         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
475             << getOpenMPDirectiveName(OMPD_threadprivate);
476         SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
477       }
478       DeclGroupPtrTy Res =
479           Actions.ActOnOpenMPThreadprivateDirective(Loc, Identifiers);
480       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
481     }
482     SkipUntil(tok::annot_pragma_openmp_end);
483     break;
484   case OMPD_declare_reduction:
485     ConsumeToken();
486     if (auto Res = ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
487       // The last seen token is annot_pragma_openmp_end - need to check for
488       // extra tokens.
489       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
490         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
491             << getOpenMPDirectiveName(OMPD_declare_reduction);
492         while (Tok.isNot(tok::annot_pragma_openmp_end))
493           ConsumeAnyToken();
494       }
495       ConsumeAnyToken();
496       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
497     } else
498       SkipUntil(tok::annot_pragma_openmp_end);
499     break;
500   case OMPD_flush:
501     if (PP.LookAhead(0).is(tok::l_paren)) {
502       FlushHasClause = true;
503       // Push copy of the current token back to stream to properly parse
504       // pseudo-clause OMPFlushClause.
505       PP.EnterToken(Tok);
506     }
507   case OMPD_taskyield:
508   case OMPD_barrier:
509   case OMPD_taskwait:
510   case OMPD_cancellation_point:
511   case OMPD_cancel:
512   case OMPD_target_enter_data:
513   case OMPD_target_exit_data:
514     if (Allowed == ACK_StatementsOpenMPNonStandalone) {
515       Diag(Tok, diag::err_omp_immediate_directive)
516           << getOpenMPDirectiveName(DKind) << 0;
517     }
518     HasAssociatedStatement = false;
519     // Fall through for further analysis.
520   case OMPD_parallel:
521   case OMPD_simd:
522   case OMPD_for:
523   case OMPD_for_simd:
524   case OMPD_sections:
525   case OMPD_single:
526   case OMPD_section:
527   case OMPD_master:
528   case OMPD_critical:
529   case OMPD_parallel_for:
530   case OMPD_parallel_for_simd:
531   case OMPD_parallel_sections:
532   case OMPD_task:
533   case OMPD_ordered:
534   case OMPD_atomic:
535   case OMPD_target:
536   case OMPD_teams:
537   case OMPD_taskgroup:
538   case OMPD_target_data:
539   case OMPD_target_parallel:
540   case OMPD_target_parallel_for:
541   case OMPD_taskloop:
542   case OMPD_taskloop_simd:
543   case OMPD_distribute: {
544     ConsumeToken();
545     // Parse directive name of the 'critical' directive if any.
546     if (DKind == OMPD_critical) {
547       BalancedDelimiterTracker T(*this, tok::l_paren,
548                                  tok::annot_pragma_openmp_end);
549       if (!T.consumeOpen()) {
550         if (Tok.isAnyIdentifier()) {
551           DirName =
552               DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
553           ConsumeAnyToken();
554         } else {
555           Diag(Tok, diag::err_omp_expected_identifier_for_critical);
556         }
557         T.consumeClose();
558       }
559     } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
560       CancelRegion = ParseOpenMPDirectiveKind(*this);
561       if (Tok.isNot(tok::annot_pragma_openmp_end))
562         ConsumeToken();
563     }
564 
565     if (isOpenMPLoopDirective(DKind))
566       ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
567     if (isOpenMPSimdDirective(DKind))
568       ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
569     ParseScope OMPDirectiveScope(this, ScopeFlags);
570     Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
571 
572     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
573       OpenMPClauseKind CKind =
574           Tok.isAnnotation()
575               ? OMPC_unknown
576               : FlushHasClause ? OMPC_flush
577                                : getOpenMPClauseKind(PP.getSpelling(Tok));
578       Actions.StartOpenMPClause(CKind);
579       FlushHasClause = false;
580       OMPClause *Clause =
581           ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
582       FirstClauses[CKind].setInt(true);
583       if (Clause) {
584         FirstClauses[CKind].setPointer(Clause);
585         Clauses.push_back(Clause);
586       }
587 
588       // Skip ',' if any.
589       if (Tok.is(tok::comma))
590         ConsumeToken();
591       Actions.EndOpenMPClause();
592     }
593     // End location of the directive.
594     EndLoc = Tok.getLocation();
595     // Consume final annot_pragma_openmp_end.
596     ConsumeToken();
597 
598     // OpenMP [2.13.8, ordered Construct, Syntax]
599     // If the depend clause is specified, the ordered construct is a stand-alone
600     // directive.
601     if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) {
602       if (Allowed == ACK_StatementsOpenMPNonStandalone) {
603         Diag(Loc, diag::err_omp_immediate_directive)
604             << getOpenMPDirectiveName(DKind) << 1
605             << getOpenMPClauseName(OMPC_depend);
606       }
607       HasAssociatedStatement = false;
608     }
609 
610     StmtResult AssociatedStmt;
611     if (HasAssociatedStatement) {
612       // The body is a block scope like in Lambdas and Blocks.
613       Sema::CompoundScopeRAII CompoundScope(Actions);
614       Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
615       Actions.ActOnStartOfCompoundStmt();
616       // Parse statement
617       AssociatedStmt = ParseStatement();
618       Actions.ActOnFinishOfCompoundStmt();
619       AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
620     }
621     Directive = Actions.ActOnOpenMPExecutableDirective(
622         DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
623         EndLoc);
624 
625     // Exit scope.
626     Actions.EndOpenMPDSABlock(Directive.get());
627     OMPDirectiveScope.Exit();
628     break;
629   }
630   case OMPD_unknown:
631     Diag(Tok, diag::err_omp_unknown_directive);
632     SkipUntil(tok::annot_pragma_openmp_end);
633     break;
634   }
635   return Directive;
636 }
637 
638 /// \brief Parses list of simple variables for '#pragma omp threadprivate'
639 /// directive.
640 ///
641 ///   simple-variable-list:
642 ///         '(' id-expression {, id-expression} ')'
643 ///
644 bool Parser::ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind,
645                                       SmallVectorImpl<Expr *> &VarList,
646                                       bool AllowScopeSpecifier) {
647   VarList.clear();
648   // Parse '('.
649   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
650   if (T.expectAndConsume(diag::err_expected_lparen_after,
651                          getOpenMPDirectiveName(Kind)))
652     return true;
653   bool IsCorrect = true;
654   bool NoIdentIsFound = true;
655 
656   // Read tokens while ')' or annot_pragma_openmp_end is not found.
657   while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
658     CXXScopeSpec SS;
659     SourceLocation TemplateKWLoc;
660     UnqualifiedId Name;
661     // Read var name.
662     Token PrevTok = Tok;
663     NoIdentIsFound = false;
664 
665     if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
666         ParseOptionalCXXScopeSpecifier(SS, nullptr, false)) {
667       IsCorrect = false;
668       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
669                 StopBeforeMatch);
670     } else if (ParseUnqualifiedId(SS, false, false, false, nullptr,
671                                   TemplateKWLoc, Name)) {
672       IsCorrect = false;
673       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
674                 StopBeforeMatch);
675     } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
676                Tok.isNot(tok::annot_pragma_openmp_end)) {
677       IsCorrect = false;
678       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
679                 StopBeforeMatch);
680       Diag(PrevTok.getLocation(), diag::err_expected)
681           << tok::identifier
682           << SourceRange(PrevTok.getLocation(), PrevTokLocation);
683     } else {
684       DeclarationNameInfo NameInfo = Actions.GetNameFromUnqualifiedId(Name);
685       ExprResult Res =
686           Actions.ActOnOpenMPIdExpression(getCurScope(), SS, NameInfo);
687       if (Res.isUsable())
688         VarList.push_back(Res.get());
689     }
690     // Consume ','.
691     if (Tok.is(tok::comma)) {
692       ConsumeToken();
693     }
694   }
695 
696   if (NoIdentIsFound) {
697     Diag(Tok, diag::err_expected) << tok::identifier;
698     IsCorrect = false;
699   }
700 
701   // Parse ')'.
702   IsCorrect = !T.consumeClose() && IsCorrect;
703 
704   return !IsCorrect && VarList.empty();
705 }
706 
707 /// \brief Parsing of OpenMP clauses.
708 ///
709 ///    clause:
710 ///       if-clause | final-clause | num_threads-clause | safelen-clause |
711 ///       default-clause | private-clause | firstprivate-clause | shared-clause
712 ///       | linear-clause | aligned-clause | collapse-clause |
713 ///       lastprivate-clause | reduction-clause | proc_bind-clause |
714 ///       schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
715 ///       mergeable-clause | flush-clause | read-clause | write-clause |
716 ///       update-clause | capture-clause | seq_cst-clause | device-clause |
717 ///       simdlen-clause | threads-clause | simd-clause | num_teams-clause |
718 ///       thread_limit-clause | priority-clause | grainsize-clause |
719 ///       nogroup-clause | num_tasks-clause | hint-clause
720 ///
721 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
722                                      OpenMPClauseKind CKind, bool FirstClause) {
723   OMPClause *Clause = nullptr;
724   bool ErrorFound = false;
725   // Check if clause is allowed for the given directive.
726   if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) {
727     Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
728                                                << getOpenMPDirectiveName(DKind);
729     ErrorFound = true;
730   }
731 
732   switch (CKind) {
733   case OMPC_final:
734   case OMPC_num_threads:
735   case OMPC_safelen:
736   case OMPC_simdlen:
737   case OMPC_collapse:
738   case OMPC_ordered:
739   case OMPC_device:
740   case OMPC_num_teams:
741   case OMPC_thread_limit:
742   case OMPC_priority:
743   case OMPC_grainsize:
744   case OMPC_num_tasks:
745   case OMPC_hint:
746     // OpenMP [2.5, Restrictions]
747     //  At most one num_threads clause can appear on the directive.
748     // OpenMP [2.8.1, simd construct, Restrictions]
749     //  Only one safelen  clause can appear on a simd directive.
750     //  Only one simdlen  clause can appear on a simd directive.
751     //  Only one collapse clause can appear on a simd directive.
752     // OpenMP [2.9.1, target data construct, Restrictions]
753     //  At most one device clause can appear on the directive.
754     // OpenMP [2.11.1, task Construct, Restrictions]
755     //  At most one if clause can appear on the directive.
756     //  At most one final clause can appear on the directive.
757     // OpenMP [teams Construct, Restrictions]
758     //  At most one num_teams clause can appear on the directive.
759     //  At most one thread_limit clause can appear on the directive.
760     // OpenMP [2.9.1, task Construct, Restrictions]
761     // At most one priority clause can appear on the directive.
762     // OpenMP [2.9.2, taskloop Construct, Restrictions]
763     // At most one grainsize clause can appear on the directive.
764     // OpenMP [2.9.2, taskloop Construct, Restrictions]
765     // At most one num_tasks clause can appear on the directive.
766     if (!FirstClause) {
767       Diag(Tok, diag::err_omp_more_one_clause)
768           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
769       ErrorFound = true;
770     }
771 
772     if (CKind == OMPC_ordered && PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
773       Clause = ParseOpenMPClause(CKind);
774     else
775       Clause = ParseOpenMPSingleExprClause(CKind);
776     break;
777   case OMPC_default:
778   case OMPC_proc_bind:
779     // OpenMP [2.14.3.1, Restrictions]
780     //  Only a single default clause may be specified on a parallel, task or
781     //  teams directive.
782     // OpenMP [2.5, parallel Construct, Restrictions]
783     //  At most one proc_bind clause can appear on the directive.
784     if (!FirstClause) {
785       Diag(Tok, diag::err_omp_more_one_clause)
786           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
787       ErrorFound = true;
788     }
789 
790     Clause = ParseOpenMPSimpleClause(CKind);
791     break;
792   case OMPC_schedule:
793   case OMPC_dist_schedule:
794   case OMPC_defaultmap:
795     // OpenMP [2.7.1, Restrictions, p. 3]
796     //  Only one schedule clause can appear on a loop directive.
797     // OpenMP [2.10.4, Restrictions, p. 106]
798     //  At most one defaultmap clause can appear on the directive.
799     if (!FirstClause) {
800       Diag(Tok, diag::err_omp_more_one_clause)
801           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
802       ErrorFound = true;
803     }
804 
805   case OMPC_if:
806     Clause = ParseOpenMPSingleExprWithArgClause(CKind);
807     break;
808   case OMPC_nowait:
809   case OMPC_untied:
810   case OMPC_mergeable:
811   case OMPC_read:
812   case OMPC_write:
813   case OMPC_update:
814   case OMPC_capture:
815   case OMPC_seq_cst:
816   case OMPC_threads:
817   case OMPC_simd:
818   case OMPC_nogroup:
819     // OpenMP [2.7.1, Restrictions, p. 9]
820     //  Only one ordered clause can appear on a loop directive.
821     // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
822     //  Only one nowait clause can appear on a for directive.
823     if (!FirstClause) {
824       Diag(Tok, diag::err_omp_more_one_clause)
825           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
826       ErrorFound = true;
827     }
828 
829     Clause = ParseOpenMPClause(CKind);
830     break;
831   case OMPC_private:
832   case OMPC_firstprivate:
833   case OMPC_lastprivate:
834   case OMPC_shared:
835   case OMPC_reduction:
836   case OMPC_linear:
837   case OMPC_aligned:
838   case OMPC_copyin:
839   case OMPC_copyprivate:
840   case OMPC_flush:
841   case OMPC_depend:
842   case OMPC_map:
843     Clause = ParseOpenMPVarListClause(DKind, CKind);
844     break;
845   case OMPC_unknown:
846     Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
847         << getOpenMPDirectiveName(DKind);
848     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
849     break;
850   case OMPC_threadprivate:
851     Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
852                                                << getOpenMPDirectiveName(DKind);
853     SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
854     break;
855   }
856   return ErrorFound ? nullptr : Clause;
857 }
858 
859 /// \brief Parsing of OpenMP clauses with single expressions like 'final',
860 /// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
861 /// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks' or 'hint'.
862 ///
863 ///    final-clause:
864 ///      'final' '(' expression ')'
865 ///
866 ///    num_threads-clause:
867 ///      'num_threads' '(' expression ')'
868 ///
869 ///    safelen-clause:
870 ///      'safelen' '(' expression ')'
871 ///
872 ///    simdlen-clause:
873 ///      'simdlen' '(' expression ')'
874 ///
875 ///    collapse-clause:
876 ///      'collapse' '(' expression ')'
877 ///
878 ///    priority-clause:
879 ///      'priority' '(' expression ')'
880 ///
881 ///    grainsize-clause:
882 ///      'grainsize' '(' expression ')'
883 ///
884 ///    num_tasks-clause:
885 ///      'num_tasks' '(' expression ')'
886 ///
887 ///    hint-clause:
888 ///      'hint' '(' expression ')'
889 ///
890 OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind) {
891   SourceLocation Loc = ConsumeToken();
892 
893   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
894   if (T.expectAndConsume(diag::err_expected_lparen_after,
895                          getOpenMPClauseName(Kind)))
896     return nullptr;
897 
898   SourceLocation ELoc = Tok.getLocation();
899   ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
900   ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
901   Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
902 
903   // Parse ')'.
904   T.consumeClose();
905 
906   if (Val.isInvalid())
907     return nullptr;
908 
909   return Actions.ActOnOpenMPSingleExprClause(
910       Kind, Val.get(), Loc, T.getOpenLocation(), T.getCloseLocation());
911 }
912 
913 /// \brief Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
914 ///
915 ///    default-clause:
916 ///         'default' '(' 'none' | 'shared' ')
917 ///
918 ///    proc_bind-clause:
919 ///         'proc_bind' '(' 'master' | 'close' | 'spread' ')
920 ///
921 OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) {
922   SourceLocation Loc = Tok.getLocation();
923   SourceLocation LOpen = ConsumeToken();
924   // Parse '('.
925   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
926   if (T.expectAndConsume(diag::err_expected_lparen_after,
927                          getOpenMPClauseName(Kind)))
928     return nullptr;
929 
930   unsigned Type = getOpenMPSimpleClauseType(
931       Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
932   SourceLocation TypeLoc = Tok.getLocation();
933   if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
934       Tok.isNot(tok::annot_pragma_openmp_end))
935     ConsumeAnyToken();
936 
937   // Parse ')'.
938   T.consumeClose();
939 
940   return Actions.ActOnOpenMPSimpleClause(Kind, Type, TypeLoc, LOpen, Loc,
941                                          Tok.getLocation());
942 }
943 
944 /// \brief Parsing of OpenMP clauses like 'ordered'.
945 ///
946 ///    ordered-clause:
947 ///         'ordered'
948 ///
949 ///    nowait-clause:
950 ///         'nowait'
951 ///
952 ///    untied-clause:
953 ///         'untied'
954 ///
955 ///    mergeable-clause:
956 ///         'mergeable'
957 ///
958 ///    read-clause:
959 ///         'read'
960 ///
961 ///    threads-clause:
962 ///         'threads'
963 ///
964 ///    simd-clause:
965 ///         'simd'
966 ///
967 ///    nogroup-clause:
968 ///         'nogroup'
969 ///
970 OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind) {
971   SourceLocation Loc = Tok.getLocation();
972   ConsumeAnyToken();
973 
974   return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
975 }
976 
977 
978 /// \brief Parsing of OpenMP clauses with single expressions and some additional
979 /// argument like 'schedule' or 'dist_schedule'.
980 ///
981 ///    schedule-clause:
982 ///      'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
983 ///      ')'
984 ///
985 ///    if-clause:
986 ///      'if' '(' [ directive-name-modifier ':' ] expression ')'
987 ///
988 ///    defaultmap:
989 ///      'defaultmap' '(' modifier ':' kind ')'
990 ///
991 OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind) {
992   SourceLocation Loc = ConsumeToken();
993   SourceLocation DelimLoc;
994   // Parse '('.
995   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
996   if (T.expectAndConsume(diag::err_expected_lparen_after,
997                          getOpenMPClauseName(Kind)))
998     return nullptr;
999 
1000   ExprResult Val;
1001   SmallVector<unsigned, 4> Arg;
1002   SmallVector<SourceLocation, 4> KLoc;
1003   if (Kind == OMPC_schedule) {
1004     enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
1005     Arg.resize(NumberOfElements);
1006     KLoc.resize(NumberOfElements);
1007     Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
1008     Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
1009     Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
1010     auto KindModifier = getOpenMPSimpleClauseType(
1011         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1012     if (KindModifier > OMPC_SCHEDULE_unknown) {
1013       // Parse 'modifier'
1014       Arg[Modifier1] = KindModifier;
1015       KLoc[Modifier1] = Tok.getLocation();
1016       if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1017           Tok.isNot(tok::annot_pragma_openmp_end))
1018         ConsumeAnyToken();
1019       if (Tok.is(tok::comma)) {
1020         // Parse ',' 'modifier'
1021         ConsumeAnyToken();
1022         KindModifier = getOpenMPSimpleClauseType(
1023             Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1024         Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown
1025                              ? KindModifier
1026                              : (unsigned)OMPC_SCHEDULE_unknown;
1027         KLoc[Modifier2] = Tok.getLocation();
1028         if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1029             Tok.isNot(tok::annot_pragma_openmp_end))
1030           ConsumeAnyToken();
1031       }
1032       // Parse ':'
1033       if (Tok.is(tok::colon))
1034         ConsumeAnyToken();
1035       else
1036         Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier";
1037       KindModifier = getOpenMPSimpleClauseType(
1038           Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1039     }
1040     Arg[ScheduleKind] = KindModifier;
1041     KLoc[ScheduleKind] = Tok.getLocation();
1042     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1043         Tok.isNot(tok::annot_pragma_openmp_end))
1044       ConsumeAnyToken();
1045     if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
1046          Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
1047          Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
1048         Tok.is(tok::comma))
1049       DelimLoc = ConsumeAnyToken();
1050   } else if (Kind == OMPC_dist_schedule) {
1051     Arg.push_back(getOpenMPSimpleClauseType(
1052         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1053     KLoc.push_back(Tok.getLocation());
1054     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1055         Tok.isNot(tok::annot_pragma_openmp_end))
1056       ConsumeAnyToken();
1057     if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
1058       DelimLoc = ConsumeAnyToken();
1059   } else if (Kind == OMPC_defaultmap) {
1060     // Get a defaultmap modifier
1061     Arg.push_back(getOpenMPSimpleClauseType(
1062         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1063     KLoc.push_back(Tok.getLocation());
1064     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1065         Tok.isNot(tok::annot_pragma_openmp_end))
1066       ConsumeAnyToken();
1067     // Parse ':'
1068     if (Tok.is(tok::colon))
1069       ConsumeAnyToken();
1070     else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown)
1071       Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier";
1072     // Get a defaultmap kind
1073     Arg.push_back(getOpenMPSimpleClauseType(
1074         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1075     KLoc.push_back(Tok.getLocation());
1076     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1077         Tok.isNot(tok::annot_pragma_openmp_end))
1078       ConsumeAnyToken();
1079   } else {
1080     assert(Kind == OMPC_if);
1081     KLoc.push_back(Tok.getLocation());
1082     Arg.push_back(ParseOpenMPDirectiveKind(*this));
1083     if (Arg.back() != OMPD_unknown) {
1084       ConsumeToken();
1085       if (Tok.is(tok::colon))
1086         DelimLoc = ConsumeToken();
1087       else
1088         Diag(Tok, diag::warn_pragma_expected_colon)
1089             << "directive name modifier";
1090     }
1091   }
1092 
1093   bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) ||
1094                           (Kind == OMPC_dist_schedule && DelimLoc.isValid()) ||
1095                           Kind == OMPC_if;
1096   if (NeedAnExpression) {
1097     SourceLocation ELoc = Tok.getLocation();
1098     ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
1099     Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
1100     Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
1101   }
1102 
1103   // Parse ')'.
1104   T.consumeClose();
1105 
1106   if (NeedAnExpression && Val.isInvalid())
1107     return nullptr;
1108 
1109   return Actions.ActOnOpenMPSingleExprWithArgClause(
1110       Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc,
1111       T.getCloseLocation());
1112 }
1113 
1114 static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
1115                              UnqualifiedId &ReductionId) {
1116   SourceLocation TemplateKWLoc;
1117   if (ReductionIdScopeSpec.isEmpty()) {
1118     auto OOK = OO_None;
1119     switch (P.getCurToken().getKind()) {
1120     case tok::plus:
1121       OOK = OO_Plus;
1122       break;
1123     case tok::minus:
1124       OOK = OO_Minus;
1125       break;
1126     case tok::star:
1127       OOK = OO_Star;
1128       break;
1129     case tok::amp:
1130       OOK = OO_Amp;
1131       break;
1132     case tok::pipe:
1133       OOK = OO_Pipe;
1134       break;
1135     case tok::caret:
1136       OOK = OO_Caret;
1137       break;
1138     case tok::ampamp:
1139       OOK = OO_AmpAmp;
1140       break;
1141     case tok::pipepipe:
1142       OOK = OO_PipePipe;
1143       break;
1144     default:
1145       break;
1146     }
1147     if (OOK != OO_None) {
1148       SourceLocation OpLoc = P.ConsumeToken();
1149       SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
1150       ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
1151       return false;
1152     }
1153   }
1154   return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false,
1155                               /*AllowDestructorName*/ false,
1156                               /*AllowConstructorName*/ false, nullptr,
1157                               TemplateKWLoc, ReductionId);
1158 }
1159 
1160 /// \brief Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
1161 /// 'shared', 'copyin', 'copyprivate', 'flush' or 'reduction'.
1162 ///
1163 ///    private-clause:
1164 ///       'private' '(' list ')'
1165 ///    firstprivate-clause:
1166 ///       'firstprivate' '(' list ')'
1167 ///    lastprivate-clause:
1168 ///       'lastprivate' '(' list ')'
1169 ///    shared-clause:
1170 ///       'shared' '(' list ')'
1171 ///    linear-clause:
1172 ///       'linear' '(' linear-list [ ':' linear-step ] ')'
1173 ///    aligned-clause:
1174 ///       'aligned' '(' list [ ':' alignment ] ')'
1175 ///    reduction-clause:
1176 ///       'reduction' '(' reduction-identifier ':' list ')'
1177 ///    copyprivate-clause:
1178 ///       'copyprivate' '(' list ')'
1179 ///    flush-clause:
1180 ///       'flush' '(' list ')'
1181 ///    depend-clause:
1182 ///       'depend' '(' in | out | inout : list | source ')'
1183 ///    map-clause:
1184 ///       'map' '(' [ [ always , ]
1185 ///          to | from | tofrom | alloc | release | delete ':' ] list ')';
1186 ///
1187 /// For 'linear' clause linear-list may have the following forms:
1188 ///  list
1189 ///  modifier(list)
1190 /// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
1191 OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
1192                                             OpenMPClauseKind Kind) {
1193   SourceLocation Loc = Tok.getLocation();
1194   SourceLocation LOpen = ConsumeToken();
1195   SourceLocation ColonLoc = SourceLocation();
1196   // Optional scope specifier and unqualified id for reduction identifier.
1197   CXXScopeSpec ReductionIdScopeSpec;
1198   UnqualifiedId ReductionId;
1199   bool InvalidReductionId = false;
1200   OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown;
1201   // OpenMP 4.1 [2.15.3.7, linear Clause]
1202   //  If no modifier is specified it is assumed to be val.
1203   OpenMPLinearClauseKind LinearModifier = OMPC_LINEAR_val;
1204   OpenMPMapClauseKind MapType = OMPC_MAP_unknown;
1205   OpenMPMapClauseKind MapTypeModifier = OMPC_MAP_unknown;
1206   bool MapTypeIsImplicit = false;
1207   bool MapTypeModifierSpecified = false;
1208   SourceLocation DepLinMapLoc;
1209 
1210   // Parse '('.
1211   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1212   if (T.expectAndConsume(diag::err_expected_lparen_after,
1213                          getOpenMPClauseName(Kind)))
1214     return nullptr;
1215 
1216   bool NeedRParenForLinear = false;
1217   BalancedDelimiterTracker LinearT(*this, tok::l_paren,
1218                                   tok::annot_pragma_openmp_end);
1219   // Handle reduction-identifier for reduction clause.
1220   if (Kind == OMPC_reduction) {
1221     ColonProtectionRAIIObject ColonRAII(*this);
1222     if (getLangOpts().CPlusPlus)
1223       ParseOptionalCXXScopeSpecifier(ReductionIdScopeSpec,
1224                                      /*ObjectType=*/nullptr,
1225                                      /*EnteringContext=*/false);
1226     InvalidReductionId =
1227         ParseReductionId(*this, ReductionIdScopeSpec, ReductionId);
1228     if (InvalidReductionId) {
1229       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
1230                 StopBeforeMatch);
1231     }
1232     if (Tok.is(tok::colon)) {
1233       ColonLoc = ConsumeToken();
1234     } else {
1235       Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
1236     }
1237   } else if (Kind == OMPC_depend) {
1238   // Handle dependency type for depend clause.
1239     ColonProtectionRAIIObject ColonRAII(*this);
1240     DepKind = static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType(
1241         Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
1242     DepLinMapLoc = Tok.getLocation();
1243 
1244     if (DepKind == OMPC_DEPEND_unknown) {
1245       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
1246                 StopBeforeMatch);
1247     } else {
1248       ConsumeToken();
1249       // Special processing for depend(source) clause.
1250       if (DKind == OMPD_ordered && DepKind == OMPC_DEPEND_source) {
1251         // Parse ')'.
1252         T.consumeClose();
1253         return Actions.ActOnOpenMPVarListClause(
1254             Kind, llvm::None, /*TailExpr=*/nullptr, Loc, LOpen,
1255             /*ColonLoc=*/SourceLocation(), Tok.getLocation(),
1256             ReductionIdScopeSpec, DeclarationNameInfo(), DepKind,
1257             LinearModifier, MapTypeModifier, MapType, MapTypeIsImplicit,
1258             DepLinMapLoc);
1259       }
1260     }
1261     if (Tok.is(tok::colon)) {
1262       ColonLoc = ConsumeToken();
1263     } else {
1264       Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
1265                                       : diag::warn_pragma_expected_colon)
1266           << "dependency type";
1267     }
1268   } else if (Kind == OMPC_linear) {
1269     // Try to parse modifier if any.
1270     if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
1271       LinearModifier = static_cast<OpenMPLinearClauseKind>(
1272           getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
1273       DepLinMapLoc = ConsumeToken();
1274       LinearT.consumeOpen();
1275       NeedRParenForLinear = true;
1276     }
1277   } else if (Kind == OMPC_map) {
1278     // Handle map type for map clause.
1279     ColonProtectionRAIIObject ColonRAII(*this);
1280 
1281     /// The map clause modifier token can be either a identifier or the C++
1282     /// delete keyword.
1283     auto IsMapClauseModifierToken = [](const Token &Tok) {
1284       return Tok.isOneOf(tok::identifier, tok::kw_delete);
1285     };
1286 
1287     // The first identifier may be a list item, a map-type or a
1288     // map-type-modifier. The map modifier can also be delete which has the same
1289     // spelling of the C++ delete keyword.
1290     MapType = static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType(
1291         Kind, IsMapClauseModifierToken(Tok) ? PP.getSpelling(Tok) : ""));
1292     DepLinMapLoc = Tok.getLocation();
1293     bool ColonExpected = false;
1294 
1295     if (IsMapClauseModifierToken(Tok)) {
1296       if (PP.LookAhead(0).is(tok::colon)) {
1297         MapType = static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType(
1298             Kind, IsMapClauseModifierToken(Tok) ? PP.getSpelling(Tok) : ""));
1299         if (MapType == OMPC_MAP_unknown) {
1300           Diag(Tok, diag::err_omp_unknown_map_type);
1301         } else if (MapType == OMPC_MAP_always) {
1302           Diag(Tok, diag::err_omp_map_type_missing);
1303         }
1304         ConsumeToken();
1305       } else if (PP.LookAhead(0).is(tok::comma)) {
1306         if (IsMapClauseModifierToken(PP.LookAhead(1)) &&
1307             PP.LookAhead(2).is(tok::colon)) {
1308           MapTypeModifier =
1309               static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType(
1310                   Kind,
1311                   IsMapClauseModifierToken(Tok) ? PP.getSpelling(Tok) : ""));
1312           if (MapTypeModifier != OMPC_MAP_always) {
1313             Diag(Tok, diag::err_omp_unknown_map_type_modifier);
1314             MapTypeModifier = OMPC_MAP_unknown;
1315           } else {
1316             MapTypeModifierSpecified = true;
1317           }
1318 
1319           ConsumeToken();
1320           ConsumeToken();
1321 
1322           MapType = static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType(
1323               Kind, IsMapClauseModifierToken(Tok) ? PP.getSpelling(Tok) : ""));
1324           if (MapType == OMPC_MAP_unknown || MapType == OMPC_MAP_always) {
1325             Diag(Tok, diag::err_omp_unknown_map_type);
1326           }
1327           ConsumeToken();
1328         } else {
1329           MapType = OMPC_MAP_tofrom;
1330           MapTypeIsImplicit = true;
1331         }
1332       } else {
1333         MapType = OMPC_MAP_tofrom;
1334         MapTypeIsImplicit = true;
1335       }
1336     } else {
1337       MapType = OMPC_MAP_tofrom;
1338       MapTypeIsImplicit = true;
1339     }
1340 
1341     if (Tok.is(tok::colon)) {
1342       ColonLoc = ConsumeToken();
1343     } else if (ColonExpected) {
1344       Diag(Tok, diag::warn_pragma_expected_colon) << "map type";
1345     }
1346   }
1347 
1348   SmallVector<Expr *, 5> Vars;
1349   bool IsComma =
1350       ((Kind != OMPC_reduction) && (Kind != OMPC_depend) &&
1351        (Kind != OMPC_map)) ||
1352       ((Kind == OMPC_reduction) && !InvalidReductionId) ||
1353       ((Kind == OMPC_map) && (MapType != OMPC_MAP_unknown) &&
1354        (!MapTypeModifierSpecified ||
1355         (MapTypeModifierSpecified && MapTypeModifier == OMPC_MAP_always))) ||
1356       ((Kind == OMPC_depend) && DepKind != OMPC_DEPEND_unknown);
1357   const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
1358   while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
1359                      Tok.isNot(tok::annot_pragma_openmp_end))) {
1360     ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
1361     // Parse variable
1362     ExprResult VarExpr =
1363         Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
1364     if (VarExpr.isUsable()) {
1365       Vars.push_back(VarExpr.get());
1366     } else {
1367       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1368                 StopBeforeMatch);
1369     }
1370     // Skip ',' if any
1371     IsComma = Tok.is(tok::comma);
1372     if (IsComma)
1373       ConsumeToken();
1374     else if (Tok.isNot(tok::r_paren) &&
1375              Tok.isNot(tok::annot_pragma_openmp_end) &&
1376              (!MayHaveTail || Tok.isNot(tok::colon)))
1377       Diag(Tok, diag::err_omp_expected_punc)
1378           << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
1379                                    : getOpenMPClauseName(Kind))
1380           << (Kind == OMPC_flush);
1381   }
1382 
1383   // Parse ')' for linear clause with modifier.
1384   if (NeedRParenForLinear)
1385     LinearT.consumeClose();
1386 
1387   // Parse ':' linear-step (or ':' alignment).
1388   Expr *TailExpr = nullptr;
1389   const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
1390   if (MustHaveTail) {
1391     ColonLoc = Tok.getLocation();
1392     SourceLocation ELoc = ConsumeToken();
1393     ExprResult Tail = ParseAssignmentExpression();
1394     Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc);
1395     if (Tail.isUsable())
1396       TailExpr = Tail.get();
1397     else
1398       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1399                 StopBeforeMatch);
1400   }
1401 
1402   // Parse ')'.
1403   T.consumeClose();
1404   if ((Kind == OMPC_depend && DepKind != OMPC_DEPEND_unknown && Vars.empty()) ||
1405       (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
1406       (MustHaveTail && !TailExpr) || InvalidReductionId) {
1407     return nullptr;
1408   }
1409 
1410   return Actions.ActOnOpenMPVarListClause(
1411       Kind, Vars, TailExpr, Loc, LOpen, ColonLoc, Tok.getLocation(),
1412       ReductionIdScopeSpec,
1413       ReductionId.isValid() ? Actions.GetNameFromUnqualifiedId(ReductionId)
1414                             : DeclarationNameInfo(),
1415       DepKind, LinearModifier, MapTypeModifier, MapType, MapTypeIsImplicit,
1416       DepLinMapLoc);
1417 }
1418 
1419