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