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