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