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
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     // OpenMP [2.7.1, Restrictions, p. 9]
476     //  Only one ordered clause can appear on a loop directive.
477     // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
478     //  Only one nowait clause can appear on a for directive.
479     if (!FirstClause) {
480       Diag(Tok, diag::err_omp_more_one_clause)
481           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
482       ErrorFound = true;
483     }
484 
485     Clause = ParseOpenMPClause(CKind);
486     break;
487   case OMPC_private:
488   case OMPC_firstprivate:
489   case OMPC_lastprivate:
490   case OMPC_shared:
491   case OMPC_reduction:
492   case OMPC_linear:
493   case OMPC_aligned:
494   case OMPC_copyin:
495   case OMPC_copyprivate:
496   case OMPC_flush:
497   case OMPC_depend:
498     Clause = ParseOpenMPVarListClause(CKind);
499     break;
500   case OMPC_unknown:
501     Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
502         << getOpenMPDirectiveName(DKind);
503     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
504     break;
505   case OMPC_threadprivate:
506     Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
507                                                << getOpenMPDirectiveName(DKind);
508     SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
509     break;
510   }
511   return ErrorFound ? nullptr : Clause;
512 }
513 
514 /// \brief Parsing of OpenMP clauses with single expressions like 'final',
515 /// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams', 'thread_limit'
516 /// or 'simdlen'.
517 ///
518 ///    final-clause:
519 ///      'final' '(' expression ')'
520 ///
521 ///    num_threads-clause:
522 ///      'num_threads' '(' expression ')'
523 ///
524 ///    safelen-clause:
525 ///      'safelen' '(' expression ')'
526 ///
527 ///    simdlen-clause:
528 ///      'simdlen' '(' expression ')'
529 ///
530 ///    collapse-clause:
531 ///      'collapse' '(' expression ')'
532 ///
533 OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind) {
534   SourceLocation Loc = ConsumeToken();
535 
536   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
537   if (T.expectAndConsume(diag::err_expected_lparen_after,
538                          getOpenMPClauseName(Kind)))
539     return nullptr;
540 
541   SourceLocation ELoc = Tok.getLocation();
542   ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
543   ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
544   Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
545 
546   // Parse ')'.
547   T.consumeClose();
548 
549   if (Val.isInvalid())
550     return nullptr;
551 
552   return Actions.ActOnOpenMPSingleExprClause(
553       Kind, Val.get(), Loc, T.getOpenLocation(), T.getCloseLocation());
554 }
555 
556 /// \brief Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
557 ///
558 ///    default-clause:
559 ///         'default' '(' 'none' | 'shared' ')
560 ///
561 ///    proc_bind-clause:
562 ///         'proc_bind' '(' 'master' | 'close' | 'spread' ')
563 ///
564 OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) {
565   SourceLocation Loc = Tok.getLocation();
566   SourceLocation LOpen = ConsumeToken();
567   // Parse '('.
568   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
569   if (T.expectAndConsume(diag::err_expected_lparen_after,
570                          getOpenMPClauseName(Kind)))
571     return nullptr;
572 
573   unsigned Type = getOpenMPSimpleClauseType(
574       Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
575   SourceLocation TypeLoc = Tok.getLocation();
576   if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
577       Tok.isNot(tok::annot_pragma_openmp_end))
578     ConsumeAnyToken();
579 
580   // Parse ')'.
581   T.consumeClose();
582 
583   return Actions.ActOnOpenMPSimpleClause(Kind, Type, TypeLoc, LOpen, Loc,
584                                          Tok.getLocation());
585 }
586 
587 /// \brief Parsing of OpenMP clauses like 'ordered'.
588 ///
589 ///    ordered-clause:
590 ///         'ordered'
591 ///
592 ///    nowait-clause:
593 ///         'nowait'
594 ///
595 ///    untied-clause:
596 ///         'untied'
597 ///
598 ///    mergeable-clause:
599 ///         'mergeable'
600 ///
601 ///    read-clause:
602 ///         'read'
603 ///
604 OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind) {
605   SourceLocation Loc = Tok.getLocation();
606   ConsumeAnyToken();
607 
608   return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
609 }
610 
611 
612 /// \brief Parsing of OpenMP clauses with single expressions and some additional
613 /// argument like 'schedule' or 'dist_schedule'.
614 ///
615 ///    schedule-clause:
616 ///      'schedule' '(' kind [',' expression ] ')'
617 ///
618 ///    if-clause:
619 ///      'if' '(' [ directive-name-modifier ':' ] expression ')'
620 ///
621 OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind) {
622   SourceLocation Loc = ConsumeToken();
623   SourceLocation DelimLoc;
624   // Parse '('.
625   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
626   if (T.expectAndConsume(diag::err_expected_lparen_after,
627                          getOpenMPClauseName(Kind)))
628     return nullptr;
629 
630   ExprResult Val;
631   unsigned Arg;
632   SourceLocation KLoc;
633   if (Kind == OMPC_schedule) {
634     Arg = getOpenMPSimpleClauseType(
635         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
636     KLoc = Tok.getLocation();
637     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
638         Tok.isNot(tok::annot_pragma_openmp_end))
639       ConsumeAnyToken();
640     if ((Arg == OMPC_SCHEDULE_static || Arg == OMPC_SCHEDULE_dynamic ||
641          Arg == OMPC_SCHEDULE_guided) &&
642         Tok.is(tok::comma))
643       DelimLoc = ConsumeAnyToken();
644   } else {
645     assert(Kind == OMPC_if);
646     KLoc = Tok.getLocation();
647     Arg = ParseOpenMPDirectiveKind(*this);
648     if (Arg != OMPD_unknown) {
649       ConsumeToken();
650       if (Tok.is(tok::colon))
651         DelimLoc = ConsumeToken();
652       else
653         Diag(Tok, diag::warn_pragma_expected_colon)
654             << "directive name modifier";
655     }
656   }
657 
658   bool NeedAnExpression =
659       (Kind == OMPC_schedule && DelimLoc.isValid()) || Kind == OMPC_if;
660   if (NeedAnExpression) {
661     SourceLocation ELoc = Tok.getLocation();
662     ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
663     Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
664     Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
665   }
666 
667   // Parse ')'.
668   T.consumeClose();
669 
670   if (NeedAnExpression && Val.isInvalid())
671     return nullptr;
672 
673   return Actions.ActOnOpenMPSingleExprWithArgClause(
674       Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc,
675       T.getCloseLocation());
676 }
677 
678 static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
679                              UnqualifiedId &ReductionId) {
680   SourceLocation TemplateKWLoc;
681   if (ReductionIdScopeSpec.isEmpty()) {
682     auto OOK = OO_None;
683     switch (P.getCurToken().getKind()) {
684     case tok::plus:
685       OOK = OO_Plus;
686       break;
687     case tok::minus:
688       OOK = OO_Minus;
689       break;
690     case tok::star:
691       OOK = OO_Star;
692       break;
693     case tok::amp:
694       OOK = OO_Amp;
695       break;
696     case tok::pipe:
697       OOK = OO_Pipe;
698       break;
699     case tok::caret:
700       OOK = OO_Caret;
701       break;
702     case tok::ampamp:
703       OOK = OO_AmpAmp;
704       break;
705     case tok::pipepipe:
706       OOK = OO_PipePipe;
707       break;
708     default:
709       break;
710     }
711     if (OOK != OO_None) {
712       SourceLocation OpLoc = P.ConsumeToken();
713       SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
714       ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
715       return false;
716     }
717   }
718   return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false,
719                               /*AllowDestructorName*/ false,
720                               /*AllowConstructorName*/ false, ParsedType(),
721                               TemplateKWLoc, ReductionId);
722 }
723 
724 /// \brief Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
725 /// 'shared', 'copyin', 'copyprivate', 'flush' or 'reduction'.
726 ///
727 ///    private-clause:
728 ///       'private' '(' list ')'
729 ///    firstprivate-clause:
730 ///       'firstprivate' '(' list ')'
731 ///    lastprivate-clause:
732 ///       'lastprivate' '(' list ')'
733 ///    shared-clause:
734 ///       'shared' '(' list ')'
735 ///    linear-clause:
736 ///       'linear' '(' linear-list [ ':' linear-step ] ')'
737 ///    aligned-clause:
738 ///       'aligned' '(' list [ ':' alignment ] ')'
739 ///    reduction-clause:
740 ///       'reduction' '(' reduction-identifier ':' list ')'
741 ///    copyprivate-clause:
742 ///       'copyprivate' '(' list ')'
743 ///    flush-clause:
744 ///       'flush' '(' list ')'
745 ///    depend-clause:
746 ///       'depend' '(' in | out | inout : list ')'
747 ///
748 /// For 'linear' clause linear-list may have the following forms:
749 ///  list
750 ///  modifier(list)
751 /// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
752 OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) {
753   SourceLocation Loc = Tok.getLocation();
754   SourceLocation LOpen = ConsumeToken();
755   SourceLocation ColonLoc = SourceLocation();
756   // Optional scope specifier and unqualified id for reduction identifier.
757   CXXScopeSpec ReductionIdScopeSpec;
758   UnqualifiedId ReductionId;
759   bool InvalidReductionId = false;
760   OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown;
761   // OpenMP 4.1 [2.15.3.7, linear Clause]
762   //  If no modifier is specified it is assumed to be val.
763   OpenMPLinearClauseKind LinearModifier = OMPC_LINEAR_val;
764   SourceLocation DepLinLoc;
765 
766   // Parse '('.
767   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
768   if (T.expectAndConsume(diag::err_expected_lparen_after,
769                          getOpenMPClauseName(Kind)))
770     return nullptr;
771 
772   bool NeedRParenForLinear = false;
773   BalancedDelimiterTracker LinearT(*this, tok::l_paren,
774                                   tok::annot_pragma_openmp_end);
775   // Handle reduction-identifier for reduction clause.
776   if (Kind == OMPC_reduction) {
777     ColonProtectionRAIIObject ColonRAII(*this);
778     if (getLangOpts().CPlusPlus) {
779       ParseOptionalCXXScopeSpecifier(ReductionIdScopeSpec, ParsedType(), false);
780     }
781     InvalidReductionId =
782         ParseReductionId(*this, ReductionIdScopeSpec, ReductionId);
783     if (InvalidReductionId) {
784       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
785                 StopBeforeMatch);
786     }
787     if (Tok.is(tok::colon)) {
788       ColonLoc = ConsumeToken();
789     } else {
790       Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
791     }
792   } else if (Kind == OMPC_depend) {
793   // Handle dependency type for depend clause.
794     ColonProtectionRAIIObject ColonRAII(*this);
795     DepKind = static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType(
796         Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
797     DepLinLoc = Tok.getLocation();
798 
799     if (DepKind == OMPC_DEPEND_unknown) {
800       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
801                 StopBeforeMatch);
802     } else {
803       ConsumeToken();
804     }
805     if (Tok.is(tok::colon)) {
806       ColonLoc = ConsumeToken();
807     } else {
808       Diag(Tok, diag::warn_pragma_expected_colon) << "dependency type";
809     }
810   } else if (Kind == OMPC_linear) {
811     // Try to parse modifier if any.
812     if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
813       LinearModifier = static_cast<OpenMPLinearClauseKind>(
814           getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
815       DepLinLoc = ConsumeToken();
816       LinearT.consumeOpen();
817       NeedRParenForLinear = true;
818     }
819   }
820 
821   SmallVector<Expr *, 5> Vars;
822   bool IsComma = ((Kind != OMPC_reduction) && (Kind != OMPC_depend)) ||
823                  ((Kind == OMPC_reduction) && !InvalidReductionId) ||
824                  ((Kind == OMPC_depend) && DepKind != OMPC_DEPEND_unknown);
825   const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
826   while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
827                      Tok.isNot(tok::annot_pragma_openmp_end))) {
828     ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
829     // Parse variable
830     ExprResult VarExpr =
831         Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
832     if (VarExpr.isUsable()) {
833       Vars.push_back(VarExpr.get());
834     } else {
835       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
836                 StopBeforeMatch);
837     }
838     // Skip ',' if any
839     IsComma = Tok.is(tok::comma);
840     if (IsComma)
841       ConsumeToken();
842     else if (Tok.isNot(tok::r_paren) &&
843              Tok.isNot(tok::annot_pragma_openmp_end) &&
844              (!MayHaveTail || Tok.isNot(tok::colon)))
845       Diag(Tok, diag::err_omp_expected_punc)
846           << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
847                                    : getOpenMPClauseName(Kind))
848           << (Kind == OMPC_flush);
849   }
850 
851   // Parse ')' for linear clause with modifier.
852   if (NeedRParenForLinear)
853     LinearT.consumeClose();
854 
855   // Parse ':' linear-step (or ':' alignment).
856   Expr *TailExpr = nullptr;
857   const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
858   if (MustHaveTail) {
859     ColonLoc = Tok.getLocation();
860     SourceLocation ELoc = ConsumeToken();
861     ExprResult Tail = ParseAssignmentExpression();
862     Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc);
863     if (Tail.isUsable())
864       TailExpr = Tail.get();
865     else
866       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
867                 StopBeforeMatch);
868   }
869 
870   // Parse ')'.
871   T.consumeClose();
872   if ((Kind == OMPC_depend && DepKind != OMPC_DEPEND_unknown && Vars.empty()) ||
873       (Kind != OMPC_depend && Vars.empty()) || (MustHaveTail && !TailExpr) ||
874       InvalidReductionId)
875     return nullptr;
876 
877   return Actions.ActOnOpenMPVarListClause(
878       Kind, Vars, TailExpr, Loc, LOpen, ColonLoc, Tok.getLocation(),
879       ReductionIdScopeSpec,
880       ReductionId.isValid() ? Actions.GetNameFromUnqualifiedId(ReductionId)
881                             : DeclarationNameInfo(),
882       DepKind, LinearModifier, DepLinLoc);
883 }
884 
885