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 static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P) {
30   // Array of foldings: F[i][0] F[i][1] ===> F[i][2].
31   // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd
32   // TODO: add other combined directives in topological order.
33   const OpenMPDirectiveKind F[][3] = {
34       {OMPD_unknown /*cancellation*/, OMPD_unknown /*point*/,
35        OMPD_cancellation_point},
36       {OMPD_target, OMPD_unknown /*data*/, OMPD_target_data},
37       {OMPD_for, OMPD_simd, OMPD_for_simd},
38       {OMPD_parallel, OMPD_for, OMPD_parallel_for},
39       {OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},
40       {OMPD_parallel, OMPD_sections, OMPD_parallel_sections}};
41   auto Tok = P.getCurToken();
42   auto DKind =
43       Tok.isAnnotation()
44           ? OMPD_unknown
45           : getOpenMPDirectiveKind(P.getPreprocessor().getSpelling(Tok));
46 
47   bool TokenMatched = false;
48   for (unsigned i = 0; i < llvm::array_lengthof(F); ++i) {
49     if (!Tok.isAnnotation() && DKind == OMPD_unknown) {
50       TokenMatched =
51           (i == 0) &&
52           !P.getPreprocessor().getSpelling(Tok).compare("cancellation");
53     } else {
54       TokenMatched = DKind == F[i][0] && DKind != OMPD_unknown;
55     }
56 
57     if (TokenMatched) {
58       Tok = P.getPreprocessor().LookAhead(0);
59       auto TokenIsAnnotation = Tok.isAnnotation();
60       auto SDKind =
61           TokenIsAnnotation
62               ? OMPD_unknown
63               : getOpenMPDirectiveKind(P.getPreprocessor().getSpelling(Tok));
64 
65       if (!TokenIsAnnotation && SDKind == OMPD_unknown) {
66         TokenMatched =
67             ((i == 0) &&
68              !P.getPreprocessor().getSpelling(Tok).compare("point")) ||
69             ((i == 1) && !P.getPreprocessor().getSpelling(Tok).compare("data"));
70       } else {
71         TokenMatched = SDKind == F[i][1] && SDKind != OMPD_unknown;
72       }
73 
74       if (TokenMatched) {
75         P.ConsumeToken();
76         DKind = F[i][2];
77       }
78     }
79   }
80   return DKind;
81 }
82 
83 /// \brief Parsing of declarative OpenMP directives.
84 ///
85 ///       threadprivate-directive:
86 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
87 ///
88 Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() {
89   assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
90   ParenBraceBracketBalancer BalancerRAIIObj(*this);
91 
92   SourceLocation Loc = ConsumeToken();
93   SmallVector<Expr *, 5> Identifiers;
94   auto DKind = ParseOpenMPDirectiveKind(*this);
95 
96   switch (DKind) {
97   case OMPD_threadprivate:
98     ConsumeToken();
99     if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Identifiers, true)) {
100       // The last seen token is annot_pragma_openmp_end - need to check for
101       // extra tokens.
102       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
103         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
104             << getOpenMPDirectiveName(OMPD_threadprivate);
105         SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
106       }
107       // Skip the last annot_pragma_openmp_end.
108       ConsumeToken();
109       return Actions.ActOnOpenMPThreadprivateDirective(Loc, Identifiers);
110     }
111     break;
112   case OMPD_unknown:
113     Diag(Tok, diag::err_omp_unknown_directive);
114     break;
115   case OMPD_parallel:
116   case OMPD_simd:
117   case OMPD_task:
118   case OMPD_taskyield:
119   case OMPD_barrier:
120   case OMPD_taskwait:
121   case OMPD_taskgroup:
122   case OMPD_flush:
123   case OMPD_for:
124   case OMPD_for_simd:
125   case OMPD_sections:
126   case OMPD_section:
127   case OMPD_single:
128   case OMPD_master:
129   case OMPD_ordered:
130   case OMPD_critical:
131   case OMPD_parallel_for:
132   case OMPD_parallel_for_simd:
133   case OMPD_parallel_sections:
134   case OMPD_atomic:
135   case OMPD_target:
136   case OMPD_teams:
137   case OMPD_cancellation_point:
138   case OMPD_cancel:
139   case OMPD_target_data:
140     Diag(Tok, diag::err_omp_unexpected_directive)
141         << getOpenMPDirectiveName(DKind);
142     break;
143   }
144   SkipUntil(tok::annot_pragma_openmp_end);
145   return DeclGroupPtrTy();
146 }
147 
148 /// \brief Parsing of declarative or executable OpenMP directives.
149 ///
150 ///       threadprivate-directive:
151 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
152 ///         annot_pragma_openmp_end
153 ///
154 ///       executable-directive:
155 ///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
156 ///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
157 ///         'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
158 ///         'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' |
159 ///         'for simd' | 'parallel for simd' | 'target' | 'target data' |
160 ///         'taskgroup' | 'teams' {clause}
161 ///         annot_pragma_openmp_end
162 ///
163 StmtResult
164 Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) {
165   assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
166   ParenBraceBracketBalancer BalancerRAIIObj(*this);
167   SmallVector<Expr *, 5> Identifiers;
168   SmallVector<OMPClause *, 5> Clauses;
169   SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
170   FirstClauses(OMPC_unknown + 1);
171   unsigned ScopeFlags =
172       Scope::FnScope | Scope::DeclScope | Scope::OpenMPDirectiveScope;
173   SourceLocation Loc = ConsumeToken(), EndLoc;
174   auto DKind = ParseOpenMPDirectiveKind(*this);
175   OpenMPDirectiveKind CancelRegion = OMPD_unknown;
176   // Name of critical directive.
177   DeclarationNameInfo DirName;
178   StmtResult Directive = StmtError();
179   bool HasAssociatedStatement = true;
180   bool FlushHasClause = false;
181 
182   switch (DKind) {
183   case OMPD_threadprivate:
184     ConsumeToken();
185     if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Identifiers, false)) {
186       // The last seen token is annot_pragma_openmp_end - need to check for
187       // extra tokens.
188       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
189         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
190             << getOpenMPDirectiveName(OMPD_threadprivate);
191         SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
192       }
193       DeclGroupPtrTy Res =
194           Actions.ActOnOpenMPThreadprivateDirective(Loc, Identifiers);
195       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
196     }
197     SkipUntil(tok::annot_pragma_openmp_end);
198     break;
199   case OMPD_flush:
200     if (PP.LookAhead(0).is(tok::l_paren)) {
201       FlushHasClause = true;
202       // Push copy of the current token back to stream to properly parse
203       // pseudo-clause OMPFlushClause.
204       PP.EnterToken(Tok);
205     }
206   case OMPD_taskyield:
207   case OMPD_barrier:
208   case OMPD_taskwait:
209   case OMPD_cancellation_point:
210   case OMPD_cancel:
211     if (!StandAloneAllowed) {
212       Diag(Tok, diag::err_omp_immediate_directive)
213           << getOpenMPDirectiveName(DKind);
214     }
215     HasAssociatedStatement = false;
216     // Fall through for further analysis.
217   case OMPD_parallel:
218   case OMPD_simd:
219   case OMPD_for:
220   case OMPD_for_simd:
221   case OMPD_sections:
222   case OMPD_single:
223   case OMPD_section:
224   case OMPD_master:
225   case OMPD_critical:
226   case OMPD_parallel_for:
227   case OMPD_parallel_for_simd:
228   case OMPD_parallel_sections:
229   case OMPD_task:
230   case OMPD_ordered:
231   case OMPD_atomic:
232   case OMPD_target:
233   case OMPD_teams:
234   case OMPD_taskgroup:
235   case OMPD_target_data: {
236     ConsumeToken();
237     // Parse directive name of the 'critical' directive if any.
238     if (DKind == OMPD_critical) {
239       BalancedDelimiterTracker T(*this, tok::l_paren,
240                                  tok::annot_pragma_openmp_end);
241       if (!T.consumeOpen()) {
242         if (Tok.isAnyIdentifier()) {
243           DirName =
244               DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
245           ConsumeAnyToken();
246         } else {
247           Diag(Tok, diag::err_omp_expected_identifier_for_critical);
248         }
249         T.consumeClose();
250       }
251     } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
252       CancelRegion = ParseOpenMPDirectiveKind(*this);
253       if (Tok.isNot(tok::annot_pragma_openmp_end))
254         ConsumeToken();
255     }
256 
257     if (isOpenMPLoopDirective(DKind))
258       ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
259     if (isOpenMPSimdDirective(DKind))
260       ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
261     ParseScope OMPDirectiveScope(this, ScopeFlags);
262     Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
263 
264     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
265       OpenMPClauseKind CKind =
266           Tok.isAnnotation()
267               ? OMPC_unknown
268               : FlushHasClause ? OMPC_flush
269                                : getOpenMPClauseKind(PP.getSpelling(Tok));
270       Actions.StartOpenMPClause(CKind);
271       FlushHasClause = false;
272       OMPClause *Clause =
273           ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
274       FirstClauses[CKind].setInt(true);
275       if (Clause) {
276         FirstClauses[CKind].setPointer(Clause);
277         Clauses.push_back(Clause);
278       }
279 
280       // Skip ',' if any.
281       if (Tok.is(tok::comma))
282         ConsumeToken();
283       Actions.EndOpenMPClause();
284     }
285     // End location of the directive.
286     EndLoc = Tok.getLocation();
287     // Consume final annot_pragma_openmp_end.
288     ConsumeToken();
289 
290     StmtResult AssociatedStmt;
291     if (HasAssociatedStatement) {
292       // The body is a block scope like in Lambdas and Blocks.
293       Sema::CompoundScopeRAII CompoundScope(Actions);
294       Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
295       Actions.ActOnStartOfCompoundStmt();
296       // Parse statement
297       AssociatedStmt = ParseStatement();
298       Actions.ActOnFinishOfCompoundStmt();
299       AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
300     }
301     Directive = Actions.ActOnOpenMPExecutableDirective(
302         DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
303         EndLoc);
304 
305     // Exit scope.
306     Actions.EndOpenMPDSABlock(Directive.get());
307     OMPDirectiveScope.Exit();
308     break;
309   }
310   case OMPD_unknown:
311     Diag(Tok, diag::err_omp_unknown_directive);
312     SkipUntil(tok::annot_pragma_openmp_end);
313     break;
314   }
315   return Directive;
316 }
317 
318 /// \brief Parses list of simple variables for '#pragma omp threadprivate'
319 /// directive.
320 ///
321 ///   simple-variable-list:
322 ///         '(' id-expression {, id-expression} ')'
323 ///
324 bool Parser::ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind,
325                                       SmallVectorImpl<Expr *> &VarList,
326                                       bool AllowScopeSpecifier) {
327   VarList.clear();
328   // Parse '('.
329   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
330   if (T.expectAndConsume(diag::err_expected_lparen_after,
331                          getOpenMPDirectiveName(Kind)))
332     return true;
333   bool IsCorrect = true;
334   bool NoIdentIsFound = true;
335 
336   // Read tokens while ')' or annot_pragma_openmp_end is not found.
337   while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
338     CXXScopeSpec SS;
339     SourceLocation TemplateKWLoc;
340     UnqualifiedId Name;
341     // Read var name.
342     Token PrevTok = Tok;
343     NoIdentIsFound = false;
344 
345     if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
346         ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false)) {
347       IsCorrect = false;
348       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
349                 StopBeforeMatch);
350     } else if (ParseUnqualifiedId(SS, false, false, false, ParsedType(),
351                                   TemplateKWLoc, Name)) {
352       IsCorrect = false;
353       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
354                 StopBeforeMatch);
355     } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
356                Tok.isNot(tok::annot_pragma_openmp_end)) {
357       IsCorrect = false;
358       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
359                 StopBeforeMatch);
360       Diag(PrevTok.getLocation(), diag::err_expected)
361           << tok::identifier
362           << SourceRange(PrevTok.getLocation(), PrevTokLocation);
363     } else {
364       DeclarationNameInfo NameInfo = Actions.GetNameFromUnqualifiedId(Name);
365       ExprResult Res =
366           Actions.ActOnOpenMPIdExpression(getCurScope(), SS, NameInfo);
367       if (Res.isUsable())
368         VarList.push_back(Res.get());
369     }
370     // Consume ','.
371     if (Tok.is(tok::comma)) {
372       ConsumeToken();
373     }
374   }
375 
376   if (NoIdentIsFound) {
377     Diag(Tok, diag::err_expected) << tok::identifier;
378     IsCorrect = false;
379   }
380 
381   // Parse ')'.
382   IsCorrect = !T.consumeClose() && IsCorrect;
383 
384   return !IsCorrect && VarList.empty();
385 }
386 
387 /// \brief Parsing of OpenMP clauses.
388 ///
389 ///    clause:
390 ///       if-clause | final-clause | num_threads-clause | safelen-clause |
391 ///       default-clause | private-clause | firstprivate-clause | shared-clause
392 ///       | linear-clause | aligned-clause | collapse-clause |
393 ///       lastprivate-clause | reduction-clause | proc_bind-clause |
394 ///       schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
395 ///       mergeable-clause | flush-clause | read-clause | write-clause |
396 ///       update-clause | capture-clause | seq_cst-clause | device-clause |
397 ///       simdlen-clause | threads-clause | simd-clause
398 ///
399 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
400                                      OpenMPClauseKind CKind, bool FirstClause) {
401   OMPClause *Clause = nullptr;
402   bool ErrorFound = false;
403   // Check if clause is allowed for the given directive.
404   if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) {
405     Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
406                                                << getOpenMPDirectiveName(DKind);
407     ErrorFound = true;
408   }
409 
410   switch (CKind) {
411   case OMPC_final:
412   case OMPC_num_threads:
413   case OMPC_safelen:
414   case OMPC_simdlen:
415   case OMPC_collapse:
416   case OMPC_ordered:
417   case OMPC_device:
418     // OpenMP [2.5, Restrictions]
419     //  At most one num_threads clause can appear on the directive.
420     // OpenMP [2.8.1, simd construct, Restrictions]
421     //  Only one safelen  clause can appear on a simd directive.
422     //  Only one simdlen  clause can appear on a simd directive.
423     //  Only one collapse clause can appear on a simd directive.
424     // OpenMP [2.9.1, target data construct, Restrictions]
425     //  At most one device clause can appear on the directive.
426     // OpenMP [2.11.1, task Construct, Restrictions]
427     //  At most one if clause can appear on the directive.
428     //  At most one final clause can appear on the directive.
429     if (!FirstClause) {
430       Diag(Tok, diag::err_omp_more_one_clause)
431           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
432       ErrorFound = true;
433     }
434 
435     if (CKind == OMPC_ordered && PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
436       Clause = ParseOpenMPClause(CKind);
437     else
438       Clause = ParseOpenMPSingleExprClause(CKind);
439     break;
440   case OMPC_default:
441   case OMPC_proc_bind:
442     // OpenMP [2.14.3.1, Restrictions]
443     //  Only a single default clause may be specified on a parallel, task or
444     //  teams directive.
445     // OpenMP [2.5, parallel Construct, Restrictions]
446     //  At most one proc_bind clause can appear on the directive.
447     if (!FirstClause) {
448       Diag(Tok, diag::err_omp_more_one_clause)
449           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
450       ErrorFound = true;
451     }
452 
453     Clause = ParseOpenMPSimpleClause(CKind);
454     break;
455   case OMPC_schedule:
456     // OpenMP [2.7.1, Restrictions, p. 3]
457     //  Only one schedule clause can appear on a loop directive.
458     if (!FirstClause) {
459       Diag(Tok, diag::err_omp_more_one_clause)
460           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
461       ErrorFound = true;
462     }
463 
464   case OMPC_if:
465     Clause = ParseOpenMPSingleExprWithArgClause(CKind);
466     break;
467   case OMPC_nowait:
468   case OMPC_untied:
469   case OMPC_mergeable:
470   case OMPC_read:
471   case OMPC_write:
472   case OMPC_update:
473   case OMPC_capture:
474   case OMPC_seq_cst:
475   case OMPC_threads:
476   case OMPC_simd:
477     // OpenMP [2.7.1, Restrictions, p. 9]
478     //  Only one ordered clause can appear on a loop directive.
479     // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
480     //  Only one nowait clause can appear on a for directive.
481     if (!FirstClause) {
482       Diag(Tok, diag::err_omp_more_one_clause)
483           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
484       ErrorFound = true;
485     }
486 
487     Clause = ParseOpenMPClause(CKind);
488     break;
489   case OMPC_private:
490   case OMPC_firstprivate:
491   case OMPC_lastprivate:
492   case OMPC_shared:
493   case OMPC_reduction:
494   case OMPC_linear:
495   case OMPC_aligned:
496   case OMPC_copyin:
497   case OMPC_copyprivate:
498   case OMPC_flush:
499   case OMPC_depend:
500     Clause = ParseOpenMPVarListClause(CKind);
501     break;
502   case OMPC_unknown:
503     Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
504         << getOpenMPDirectiveName(DKind);
505     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
506     break;
507   case OMPC_threadprivate:
508     Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
509                                                << getOpenMPDirectiveName(DKind);
510     SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
511     break;
512   }
513   return ErrorFound ? nullptr : Clause;
514 }
515 
516 /// \brief Parsing of OpenMP clauses with single expressions like 'final',
517 /// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams', 'thread_limit'
518 /// or 'simdlen'.
519 ///
520 ///    final-clause:
521 ///      'final' '(' expression ')'
522 ///
523 ///    num_threads-clause:
524 ///      'num_threads' '(' expression ')'
525 ///
526 ///    safelen-clause:
527 ///      'safelen' '(' expression ')'
528 ///
529 ///    simdlen-clause:
530 ///      'simdlen' '(' expression ')'
531 ///
532 ///    collapse-clause:
533 ///      'collapse' '(' expression ')'
534 ///
535 OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind) {
536   SourceLocation Loc = ConsumeToken();
537 
538   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
539   if (T.expectAndConsume(diag::err_expected_lparen_after,
540                          getOpenMPClauseName(Kind)))
541     return nullptr;
542 
543   SourceLocation ELoc = Tok.getLocation();
544   ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
545   ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
546   Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
547 
548   // Parse ')'.
549   T.consumeClose();
550 
551   if (Val.isInvalid())
552     return nullptr;
553 
554   return Actions.ActOnOpenMPSingleExprClause(
555       Kind, Val.get(), Loc, T.getOpenLocation(), T.getCloseLocation());
556 }
557 
558 /// \brief Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
559 ///
560 ///    default-clause:
561 ///         'default' '(' 'none' | 'shared' ')
562 ///
563 ///    proc_bind-clause:
564 ///         'proc_bind' '(' 'master' | 'close' | 'spread' ')
565 ///
566 OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) {
567   SourceLocation Loc = Tok.getLocation();
568   SourceLocation LOpen = ConsumeToken();
569   // Parse '('.
570   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
571   if (T.expectAndConsume(diag::err_expected_lparen_after,
572                          getOpenMPClauseName(Kind)))
573     return nullptr;
574 
575   unsigned Type = getOpenMPSimpleClauseType(
576       Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
577   SourceLocation TypeLoc = Tok.getLocation();
578   if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
579       Tok.isNot(tok::annot_pragma_openmp_end))
580     ConsumeAnyToken();
581 
582   // Parse ')'.
583   T.consumeClose();
584 
585   return Actions.ActOnOpenMPSimpleClause(Kind, Type, TypeLoc, LOpen, Loc,
586                                          Tok.getLocation());
587 }
588 
589 /// \brief Parsing of OpenMP clauses like 'ordered'.
590 ///
591 ///    ordered-clause:
592 ///         'ordered'
593 ///
594 ///    nowait-clause:
595 ///         'nowait'
596 ///
597 ///    untied-clause:
598 ///         'untied'
599 ///
600 ///    mergeable-clause:
601 ///         'mergeable'
602 ///
603 ///    read-clause:
604 ///         'read'
605 ///
606 ///    threads-clause:
607 ///         'threads'
608 ///
609 ///    simd-clause:
610 ///         'simd'
611 ///
612 OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind) {
613   SourceLocation Loc = Tok.getLocation();
614   ConsumeAnyToken();
615 
616   return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
617 }
618 
619 
620 /// \brief Parsing of OpenMP clauses with single expressions and some additional
621 /// argument like 'schedule' or 'dist_schedule'.
622 ///
623 ///    schedule-clause:
624 ///      'schedule' '(' kind [',' expression ] ')'
625 ///
626 ///    if-clause:
627 ///      'if' '(' [ directive-name-modifier ':' ] expression ')'
628 ///
629 OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind) {
630   SourceLocation Loc = ConsumeToken();
631   SourceLocation DelimLoc;
632   // Parse '('.
633   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
634   if (T.expectAndConsume(diag::err_expected_lparen_after,
635                          getOpenMPClauseName(Kind)))
636     return nullptr;
637 
638   ExprResult Val;
639   unsigned Arg;
640   SourceLocation KLoc;
641   if (Kind == OMPC_schedule) {
642     Arg = getOpenMPSimpleClauseType(
643         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
644     KLoc = Tok.getLocation();
645     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
646         Tok.isNot(tok::annot_pragma_openmp_end))
647       ConsumeAnyToken();
648     if ((Arg == OMPC_SCHEDULE_static || Arg == OMPC_SCHEDULE_dynamic ||
649          Arg == OMPC_SCHEDULE_guided) &&
650         Tok.is(tok::comma))
651       DelimLoc = ConsumeAnyToken();
652   } else {
653     assert(Kind == OMPC_if);
654     KLoc = Tok.getLocation();
655     Arg = ParseOpenMPDirectiveKind(*this);
656     if (Arg != OMPD_unknown) {
657       ConsumeToken();
658       if (Tok.is(tok::colon))
659         DelimLoc = ConsumeToken();
660       else
661         Diag(Tok, diag::warn_pragma_expected_colon)
662             << "directive name modifier";
663     }
664   }
665 
666   bool NeedAnExpression =
667       (Kind == OMPC_schedule && DelimLoc.isValid()) || Kind == OMPC_if;
668   if (NeedAnExpression) {
669     SourceLocation ELoc = Tok.getLocation();
670     ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
671     Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
672     Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
673   }
674 
675   // Parse ')'.
676   T.consumeClose();
677 
678   if (NeedAnExpression && Val.isInvalid())
679     return nullptr;
680 
681   return Actions.ActOnOpenMPSingleExprWithArgClause(
682       Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc,
683       T.getCloseLocation());
684 }
685 
686 static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
687                              UnqualifiedId &ReductionId) {
688   SourceLocation TemplateKWLoc;
689   if (ReductionIdScopeSpec.isEmpty()) {
690     auto OOK = OO_None;
691     switch (P.getCurToken().getKind()) {
692     case tok::plus:
693       OOK = OO_Plus;
694       break;
695     case tok::minus:
696       OOK = OO_Minus;
697       break;
698     case tok::star:
699       OOK = OO_Star;
700       break;
701     case tok::amp:
702       OOK = OO_Amp;
703       break;
704     case tok::pipe:
705       OOK = OO_Pipe;
706       break;
707     case tok::caret:
708       OOK = OO_Caret;
709       break;
710     case tok::ampamp:
711       OOK = OO_AmpAmp;
712       break;
713     case tok::pipepipe:
714       OOK = OO_PipePipe;
715       break;
716     default:
717       break;
718     }
719     if (OOK != OO_None) {
720       SourceLocation OpLoc = P.ConsumeToken();
721       SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
722       ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
723       return false;
724     }
725   }
726   return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false,
727                               /*AllowDestructorName*/ false,
728                               /*AllowConstructorName*/ false, ParsedType(),
729                               TemplateKWLoc, ReductionId);
730 }
731 
732 /// \brief Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
733 /// 'shared', 'copyin', 'copyprivate', 'flush' or 'reduction'.
734 ///
735 ///    private-clause:
736 ///       'private' '(' list ')'
737 ///    firstprivate-clause:
738 ///       'firstprivate' '(' list ')'
739 ///    lastprivate-clause:
740 ///       'lastprivate' '(' list ')'
741 ///    shared-clause:
742 ///       'shared' '(' list ')'
743 ///    linear-clause:
744 ///       'linear' '(' linear-list [ ':' linear-step ] ')'
745 ///    aligned-clause:
746 ///       'aligned' '(' list [ ':' alignment ] ')'
747 ///    reduction-clause:
748 ///       'reduction' '(' reduction-identifier ':' list ')'
749 ///    copyprivate-clause:
750 ///       'copyprivate' '(' list ')'
751 ///    flush-clause:
752 ///       'flush' '(' list ')'
753 ///    depend-clause:
754 ///       'depend' '(' in | out | inout : list ')'
755 ///
756 /// For 'linear' clause linear-list may have the following forms:
757 ///  list
758 ///  modifier(list)
759 /// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
760 OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
761   SourceLocation Loc = Tok.getLocation();
762   SourceLocation LOpen = ConsumeToken();
763   SourceLocation ColonLoc = SourceLocation();
764   // Optional scope specifier and unqualified id for reduction identifier.
765   CXXScopeSpec ReductionIdScopeSpec;
766   UnqualifiedId ReductionId;
767   bool InvalidReductionId = false;
768   OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown;
769   // OpenMP 4.1 [2.15.3.7, linear Clause]
770   //  If no modifier is specified it is assumed to be val.
771   OpenMPLinearClauseKind LinearModifier = OMPC_LINEAR_val;
772   SourceLocation DepLinLoc;
773 
774   // Parse '('.
775   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
776   if (T.expectAndConsume(diag::err_expected_lparen_after,
777                          getOpenMPClauseName(Kind)))
778     return nullptr;
779 
780   bool NeedRParenForLinear = false;
781   BalancedDelimiterTracker LinearT(*this, tok::l_paren,
782                                   tok::annot_pragma_openmp_end);
783   // Handle reduction-identifier for reduction clause.
784   if (Kind == OMPC_reduction) {
785     ColonProtectionRAIIObject ColonRAII(*this);
786     if (getLangOpts().CPlusPlus) {
787       ParseOptionalCXXScopeSpecifier(ReductionIdScopeSpec, ParsedType(), false);
788     }
789     InvalidReductionId =
790         ParseReductionId(*this, ReductionIdScopeSpec, ReductionId);
791     if (InvalidReductionId) {
792       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
793                 StopBeforeMatch);
794     }
795     if (Tok.is(tok::colon)) {
796       ColonLoc = ConsumeToken();
797     } else {
798       Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
799     }
800   } else if (Kind == OMPC_depend) {
801   // Handle dependency type for depend clause.
802     ColonProtectionRAIIObject ColonRAII(*this);
803     DepKind = static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType(
804         Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
805     DepLinLoc = Tok.getLocation();
806 
807     if (DepKind == OMPC_DEPEND_unknown) {
808       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
809                 StopBeforeMatch);
810     } else {
811       ConsumeToken();
812     }
813     if (Tok.is(tok::colon)) {
814       ColonLoc = ConsumeToken();
815     } else {
816       Diag(Tok, diag::warn_pragma_expected_colon) << "dependency type";
817     }
818   } else if (Kind == OMPC_linear) {
819     // Try to parse modifier if any.
820     if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
821       LinearModifier = static_cast<OpenMPLinearClauseKind>(
822           getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
823       DepLinLoc = ConsumeToken();
824       LinearT.consumeOpen();
825       NeedRParenForLinear = true;
826     }
827   }
828 
829   SmallVector<Expr *, 5> Vars;
830   bool IsComma = ((Kind != OMPC_reduction) && (Kind != OMPC_depend)) ||
831                  ((Kind == OMPC_reduction) && !InvalidReductionId) ||
832                  ((Kind == OMPC_depend) && DepKind != OMPC_DEPEND_unknown);
833   const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
834   while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
835                      Tok.isNot(tok::annot_pragma_openmp_end))) {
836     ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
837     // Parse variable
838     ExprResult VarExpr =
839         Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
840     if (VarExpr.isUsable()) {
841       Vars.push_back(VarExpr.get());
842     } else {
843       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
844                 StopBeforeMatch);
845     }
846     // Skip ',' if any
847     IsComma = Tok.is(tok::comma);
848     if (IsComma)
849       ConsumeToken();
850     else if (Tok.isNot(tok::r_paren) &&
851              Tok.isNot(tok::annot_pragma_openmp_end) &&
852              (!MayHaveTail || Tok.isNot(tok::colon)))
853       Diag(Tok, diag::err_omp_expected_punc)
854           << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
855                                    : getOpenMPClauseName(Kind))
856           << (Kind == OMPC_flush);
857   }
858 
859   // Parse ')' for linear clause with modifier.
860   if (NeedRParenForLinear)
861     LinearT.consumeClose();
862 
863   // Parse ':' linear-step (or ':' alignment).
864   Expr *TailExpr = nullptr;
865   const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
866   if (MustHaveTail) {
867     ColonLoc = Tok.getLocation();
868     SourceLocation ELoc = ConsumeToken();
869     ExprResult Tail = ParseAssignmentExpression();
870     Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc);
871     if (Tail.isUsable())
872       TailExpr = Tail.get();
873     else
874       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
875                 StopBeforeMatch);
876   }
877 
878   // Parse ')'.
879   T.consumeClose();
880   if ((Kind == OMPC_depend && DepKind != OMPC_DEPEND_unknown && Vars.empty()) ||
881       (Kind != OMPC_depend && Vars.empty()) || (MustHaveTail && !TailExpr) ||
882       InvalidReductionId)
883     return nullptr;
884 
885   return Actions.ActOnOpenMPVarListClause(
886       Kind, Vars, TailExpr, Loc, LOpen, ColonLoc, Tok.getLocation(),
887       ReductionIdScopeSpec,
888       ReductionId.isValid() ? Actions.GetNameFromUnqualifiedId(ReductionId)
889                             : DeclarationNameInfo(),
890       DepKind, LinearModifier, DepLinLoc);
891 }
892 
893