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 namespace {
30 enum OpenMPDirectiveKindEx {
31   OMPD_cancellation = OMPD_unknown + 1,
32   OMPD_data,
33   OMPD_declare,
34   OMPD_end,
35   OMPD_end_declare,
36   OMPD_enter,
37   OMPD_exit,
38   OMPD_point,
39   OMPD_reduction,
40   OMPD_target_enter,
41   OMPD_target_exit
42 };
43 
44 class ThreadprivateListParserHelper final {
45   SmallVector<Expr *, 4> Identifiers;
46   Parser *P;
47 
48 public:
49   ThreadprivateListParserHelper(Parser *P) : P(P) {}
50   void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
51     ExprResult Res =
52         P->getActions().ActOnOpenMPIdExpression(P->getCurScope(), SS, NameInfo);
53     if (Res.isUsable())
54       Identifiers.push_back(Res.get());
55   }
56   llvm::ArrayRef<Expr *> getIdentifiers() const { return Identifiers; }
57 };
58 } // namespace
59 
60 // Map token string to extended OMP token kind that are
61 // OpenMPDirectiveKind + OpenMPDirectiveKindEx.
62 static unsigned getOpenMPDirectiveKindEx(StringRef S) {
63   auto DKind = getOpenMPDirectiveKind(S);
64   if (DKind != OMPD_unknown)
65     return DKind;
66 
67   return llvm::StringSwitch<unsigned>(S)
68       .Case("cancellation", OMPD_cancellation)
69       .Case("data", OMPD_data)
70       .Case("declare", OMPD_declare)
71       .Case("end", OMPD_end)
72       .Case("enter", OMPD_enter)
73       .Case("exit", OMPD_exit)
74       .Case("point", OMPD_point)
75       .Case("reduction", OMPD_reduction)
76       .Default(OMPD_unknown);
77 }
78 
79 static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P) {
80   // Array of foldings: F[i][0] F[i][1] ===> F[i][2].
81   // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd
82   // TODO: add other combined directives in topological order.
83   static const unsigned F[][3] = {
84     { OMPD_cancellation, OMPD_point, OMPD_cancellation_point },
85     { OMPD_declare, OMPD_reduction, OMPD_declare_reduction },
86     { OMPD_declare, OMPD_simd, OMPD_declare_simd },
87     { OMPD_declare, OMPD_target, OMPD_declare_target },
88     { OMPD_end, OMPD_declare, OMPD_end_declare },
89     { OMPD_end_declare, OMPD_target, OMPD_end_declare_target },
90     { OMPD_target, OMPD_data, OMPD_target_data },
91     { OMPD_target, OMPD_enter, OMPD_target_enter },
92     { OMPD_target, OMPD_exit, OMPD_target_exit },
93     { OMPD_target_enter, OMPD_data, OMPD_target_enter_data },
94     { OMPD_target_exit, OMPD_data, OMPD_target_exit_data },
95     { OMPD_for, OMPD_simd, OMPD_for_simd },
96     { OMPD_parallel, OMPD_for, OMPD_parallel_for },
97     { OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd },
98     { OMPD_parallel, OMPD_sections, OMPD_parallel_sections },
99     { OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd },
100     { OMPD_target, OMPD_parallel, OMPD_target_parallel },
101     { OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for }
102   };
103   enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };
104   auto Tok = P.getCurToken();
105   unsigned DKind =
106       Tok.isAnnotation()
107           ? static_cast<unsigned>(OMPD_unknown)
108           : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
109   if (DKind == OMPD_unknown)
110     return OMPD_unknown;
111 
112   for (unsigned i = 0; i < llvm::array_lengthof(F); ++i) {
113     if (DKind != F[i][0])
114       continue;
115 
116     Tok = P.getPreprocessor().LookAhead(0);
117     unsigned SDKind =
118         Tok.isAnnotation()
119             ? static_cast<unsigned>(OMPD_unknown)
120             : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
121     if (SDKind == OMPD_unknown)
122       continue;
123 
124     if (SDKind == F[i][1]) {
125       P.ConsumeToken();
126       DKind = F[i][2];
127     }
128   }
129   return DKind < OMPD_unknown ? static_cast<OpenMPDirectiveKind>(DKind)
130                               : OMPD_unknown;
131 }
132 
133 static DeclarationName parseOpenMPReductionId(Parser &P) {
134   Token Tok = P.getCurToken();
135   Sema &Actions = P.getActions();
136   OverloadedOperatorKind OOK = OO_None;
137   // Allow to use 'operator' keyword for C++ operators
138   bool WithOperator = false;
139   if (Tok.is(tok::kw_operator)) {
140     P.ConsumeToken();
141     Tok = P.getCurToken();
142     WithOperator = true;
143   }
144   switch (Tok.getKind()) {
145   case tok::plus: // '+'
146     OOK = OO_Plus;
147     break;
148   case tok::minus: // '-'
149     OOK = OO_Minus;
150     break;
151   case tok::star: // '*'
152     OOK = OO_Star;
153     break;
154   case tok::amp: // '&'
155     OOK = OO_Amp;
156     break;
157   case tok::pipe: // '|'
158     OOK = OO_Pipe;
159     break;
160   case tok::caret: // '^'
161     OOK = OO_Caret;
162     break;
163   case tok::ampamp: // '&&'
164     OOK = OO_AmpAmp;
165     break;
166   case tok::pipepipe: // '||'
167     OOK = OO_PipePipe;
168     break;
169   case tok::identifier: // identifier
170     if (!WithOperator)
171       break;
172   default:
173     P.Diag(Tok.getLocation(), diag::err_omp_expected_reduction_identifier);
174     P.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
175                 Parser::StopBeforeMatch);
176     return DeclarationName();
177   }
178   P.ConsumeToken();
179   auto &DeclNames = Actions.getASTContext().DeclarationNames;
180   return OOK == OO_None ? DeclNames.getIdentifier(Tok.getIdentifierInfo())
181                         : DeclNames.getCXXOperatorName(OOK);
182 }
183 
184 /// \brief Parse 'omp declare reduction' construct.
185 ///
186 ///       declare-reduction-directive:
187 ///        annot_pragma_openmp 'declare' 'reduction'
188 ///        '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')'
189 ///        ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')']
190 ///        annot_pragma_openmp_end
191 /// <reduction_id> is either a base language identifier or one of the following
192 /// operators: '+', '-', '*', '&', '|', '^', '&&' and '||'.
193 ///
194 Parser::DeclGroupPtrTy
195 Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
196   // Parse '('.
197   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
198   if (T.expectAndConsume(diag::err_expected_lparen_after,
199                          getOpenMPDirectiveName(OMPD_declare_reduction))) {
200     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
201     return DeclGroupPtrTy();
202   }
203 
204   DeclarationName Name = parseOpenMPReductionId(*this);
205   if (Name.isEmpty() && Tok.is(tok::annot_pragma_openmp_end))
206     return DeclGroupPtrTy();
207 
208   // Consume ':'.
209   bool IsCorrect = !ExpectAndConsume(tok::colon);
210 
211   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
212     return DeclGroupPtrTy();
213 
214   IsCorrect = IsCorrect && !Name.isEmpty();
215 
216   if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) {
217     Diag(Tok.getLocation(), diag::err_expected_type);
218     IsCorrect = false;
219   }
220 
221   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
222     return DeclGroupPtrTy();
223 
224   SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes;
225   // Parse list of types until ':' token.
226   do {
227     ColonProtectionRAIIObject ColonRAII(*this);
228     SourceRange Range;
229     TypeResult TR = ParseTypeName(&Range, Declarator::PrototypeContext, AS);
230     if (TR.isUsable()) {
231       auto ReductionType =
232           Actions.ActOnOpenMPDeclareReductionType(Range.getBegin(), TR);
233       if (!ReductionType.isNull()) {
234         ReductionTypes.push_back(
235             std::make_pair(ReductionType, Range.getBegin()));
236       }
237     } else {
238       SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
239                 StopBeforeMatch);
240     }
241 
242     if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end))
243       break;
244 
245     // Consume ','.
246     if (ExpectAndConsume(tok::comma)) {
247       IsCorrect = false;
248       if (Tok.is(tok::annot_pragma_openmp_end)) {
249         Diag(Tok.getLocation(), diag::err_expected_type);
250         return DeclGroupPtrTy();
251       }
252     }
253   } while (Tok.isNot(tok::annot_pragma_openmp_end));
254 
255   if (ReductionTypes.empty()) {
256     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
257     return DeclGroupPtrTy();
258   }
259 
260   if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
261     return DeclGroupPtrTy();
262 
263   // Consume ':'.
264   if (ExpectAndConsume(tok::colon))
265     IsCorrect = false;
266 
267   if (Tok.is(tok::annot_pragma_openmp_end)) {
268     Diag(Tok.getLocation(), diag::err_expected_expression);
269     return DeclGroupPtrTy();
270   }
271 
272   DeclGroupPtrTy DRD = Actions.ActOnOpenMPDeclareReductionDirectiveStart(
273       getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes, AS);
274 
275   // Parse <combiner> expression and then parse initializer if any for each
276   // correct type.
277   unsigned I = 0, E = ReductionTypes.size();
278   for (auto *D : DRD.get()) {
279     TentativeParsingAction TPA(*this);
280     ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
281                                     Scope::OpenMPDirectiveScope);
282     // Parse <combiner> expression.
283     Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D);
284     ExprResult CombinerResult =
285         Actions.ActOnFinishFullExpr(ParseAssignmentExpression().get(),
286                                     D->getLocation(), /*DiscardedValue=*/true);
287     Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get());
288 
289     if (CombinerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
290         Tok.isNot(tok::annot_pragma_openmp_end)) {
291       TPA.Commit();
292       IsCorrect = false;
293       break;
294     }
295     IsCorrect = !T.consumeClose() && IsCorrect && CombinerResult.isUsable();
296     ExprResult InitializerResult;
297     if (Tok.isNot(tok::annot_pragma_openmp_end)) {
298       // Parse <initializer> expression.
299       if (Tok.is(tok::identifier) &&
300           Tok.getIdentifierInfo()->isStr("initializer"))
301         ConsumeToken();
302       else {
303         Diag(Tok.getLocation(), diag::err_expected) << "'initializer'";
304         TPA.Commit();
305         IsCorrect = false;
306         break;
307       }
308       // Parse '('.
309       BalancedDelimiterTracker T(*this, tok::l_paren,
310                                  tok::annot_pragma_openmp_end);
311       IsCorrect =
312           !T.expectAndConsume(diag::err_expected_lparen_after, "initializer") &&
313           IsCorrect;
314       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
315         ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
316                                         Scope::OpenMPDirectiveScope);
317         // Parse expression.
318         Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(), D);
319         InitializerResult = Actions.ActOnFinishFullExpr(
320             ParseAssignmentExpression().get(), D->getLocation(),
321             /*DiscardedValue=*/true);
322         Actions.ActOnOpenMPDeclareReductionInitializerEnd(
323             D, InitializerResult.get());
324         if (InitializerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
325             Tok.isNot(tok::annot_pragma_openmp_end)) {
326           TPA.Commit();
327           IsCorrect = false;
328           break;
329         }
330         IsCorrect =
331             !T.consumeClose() && IsCorrect && !InitializerResult.isInvalid();
332       }
333     }
334 
335     ++I;
336     // Revert parsing if not the last type, otherwise accept it, we're done with
337     // parsing.
338     if (I != E)
339       TPA.Revert();
340     else
341       TPA.Commit();
342   }
343   return Actions.ActOnOpenMPDeclareReductionDirectiveEnd(getCurScope(), DRD,
344                                                          IsCorrect);
345 }
346 
347 namespace {
348 /// RAII that recreates function context for correct parsing of clauses of
349 /// 'declare simd' construct.
350 /// OpenMP, 2.8.2 declare simd Construct
351 /// The expressions appearing in the clauses of this directive are evaluated in
352 /// the scope of the arguments of the function declaration or definition.
353 class FNContextRAII final {
354   Parser &P;
355   Sema::CXXThisScopeRAII *ThisScope;
356   Parser::ParseScope *TempScope;
357   Parser::ParseScope *FnScope;
358   bool HasTemplateScope = false;
359   bool HasFunScope = false;
360   FNContextRAII() = delete;
361   FNContextRAII(const FNContextRAII &) = delete;
362   FNContextRAII &operator=(const FNContextRAII &) = delete;
363 
364 public:
365   FNContextRAII(Parser &P, Parser::DeclGroupPtrTy Ptr) : P(P) {
366     Decl *D = *Ptr.get().begin();
367     NamedDecl *ND = dyn_cast<NamedDecl>(D);
368     RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
369     Sema &Actions = P.getActions();
370 
371     // Allow 'this' within late-parsed attributes.
372     ThisScope = new Sema::CXXThisScopeRAII(Actions, RD, /*TypeQuals=*/0,
373                                            ND && ND->isCXXInstanceMember());
374 
375     // If the Decl is templatized, add template parameters to scope.
376     HasTemplateScope = D->isTemplateDecl();
377     TempScope =
378         new Parser::ParseScope(&P, Scope::TemplateParamScope, HasTemplateScope);
379     if (HasTemplateScope)
380       Actions.ActOnReenterTemplateScope(Actions.getCurScope(), D);
381 
382     // If the Decl is on a function, add function parameters to the scope.
383     HasFunScope = D->isFunctionOrFunctionTemplate();
384     FnScope = new Parser::ParseScope(&P, Scope::FnScope | Scope::DeclScope,
385                                      HasFunScope);
386     if (HasFunScope)
387       Actions.ActOnReenterFunctionContext(Actions.getCurScope(), D);
388   }
389   ~FNContextRAII() {
390     if (HasFunScope) {
391       P.getActions().ActOnExitFunctionContext();
392       FnScope->Exit(); // Pop scope, and remove Decls from IdResolver
393     }
394     if (HasTemplateScope)
395       TempScope->Exit();
396     delete FnScope;
397     delete TempScope;
398     delete ThisScope;
399   }
400 };
401 } // namespace
402 
403 /// Parses clauses for 'declare simd' directive.
404 ///    clause:
405 ///      'inbranch' | 'notinbranch'
406 ///      'simdlen' '(' <expr> ')'
407 ///      { 'uniform' '(' <argument_list> ')' }
408 ///      { 'aligned '(' <argument_list> [ ':' <alignment> ] ')' }
409 ///      { 'linear '(' <argument_list> [ ':' <step> ] ')' }
410 static bool parseDeclareSimdClauses(
411     Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, ExprResult &SimdLen,
412     SmallVectorImpl<Expr *> &Uniforms, SmallVectorImpl<Expr *> &Aligneds,
413     SmallVectorImpl<Expr *> &Alignments, SmallVectorImpl<Expr *> &Linears,
414     SmallVectorImpl<unsigned> &LinModifiers, SmallVectorImpl<Expr *> &Steps) {
415   SourceRange BSRange;
416   const Token &Tok = P.getCurToken();
417   bool IsError = false;
418   while (Tok.isNot(tok::annot_pragma_openmp_end)) {
419     if (Tok.isNot(tok::identifier))
420       break;
421     OMPDeclareSimdDeclAttr::BranchStateTy Out;
422     IdentifierInfo *II = Tok.getIdentifierInfo();
423     StringRef ClauseName = II->getName();
424     // Parse 'inranch|notinbranch' clauses.
425     if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
426       if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
427         P.Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
428             << ClauseName
429             << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
430         IsError = true;
431       }
432       BS = Out;
433       BSRange = SourceRange(Tok.getLocation(), Tok.getEndLoc());
434       P.ConsumeToken();
435     } else if (ClauseName.equals("simdlen")) {
436       if (SimdLen.isUsable()) {
437         P.Diag(Tok, diag::err_omp_more_one_clause)
438             << getOpenMPDirectiveName(OMPD_declare_simd) << ClauseName << 0;
439         IsError = true;
440       }
441       P.ConsumeToken();
442       SourceLocation RLoc;
443       SimdLen = P.ParseOpenMPParensExpr(ClauseName, RLoc);
444       if (SimdLen.isInvalid())
445         IsError = true;
446     } else {
447       OpenMPClauseKind CKind = getOpenMPClauseKind(ClauseName);
448       if (CKind == OMPC_uniform || CKind == OMPC_aligned ||
449           CKind == OMPC_linear) {
450         Parser::OpenMPVarListDataTy Data;
451         auto *Vars = &Uniforms;
452         if (CKind == OMPC_aligned)
453           Vars = &Aligneds;
454         else if (CKind == OMPC_linear)
455           Vars = &Linears;
456 
457         P.ConsumeToken();
458         if (P.ParseOpenMPVarList(OMPD_declare_simd,
459                                  getOpenMPClauseKind(ClauseName), *Vars, Data))
460           IsError = true;
461         if (CKind == OMPC_aligned)
462           Alignments.append(Aligneds.size() - Alignments.size(), Data.TailExpr);
463         else if (CKind == OMPC_linear) {
464           if (P.getActions().CheckOpenMPLinearModifier(Data.LinKind,
465                                                        Data.DepLinMapLoc))
466             Data.LinKind = OMPC_LINEAR_val;
467           LinModifiers.append(Linears.size() - LinModifiers.size(),
468                               Data.LinKind);
469           Steps.append(Linears.size() - Steps.size(), Data.TailExpr);
470         }
471       } else
472         // TODO: add parsing of other clauses.
473         break;
474     }
475     // Skip ',' if any.
476     if (Tok.is(tok::comma))
477       P.ConsumeToken();
478   }
479   return IsError;
480 }
481 
482 /// Parse clauses for '#pragma omp declare simd'.
483 Parser::DeclGroupPtrTy
484 Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
485                                    CachedTokens &Toks, SourceLocation Loc) {
486   PP.EnterToken(Tok);
487   PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
488   // Consume the previously pushed token.
489   ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
490 
491   FNContextRAII FnContext(*this, Ptr);
492   OMPDeclareSimdDeclAttr::BranchStateTy BS =
493       OMPDeclareSimdDeclAttr::BS_Undefined;
494   ExprResult Simdlen;
495   SmallVector<Expr *, 4> Uniforms;
496   SmallVector<Expr *, 4> Aligneds;
497   SmallVector<Expr *, 4> Alignments;
498   SmallVector<Expr *, 4> Linears;
499   SmallVector<unsigned, 4> LinModifiers;
500   SmallVector<Expr *, 4> Steps;
501   bool IsError =
502       parseDeclareSimdClauses(*this, BS, Simdlen, Uniforms, Aligneds,
503                               Alignments, Linears, LinModifiers, Steps);
504   // Need to check for extra tokens.
505   if (Tok.isNot(tok::annot_pragma_openmp_end)) {
506     Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
507         << getOpenMPDirectiveName(OMPD_declare_simd);
508     while (Tok.isNot(tok::annot_pragma_openmp_end))
509       ConsumeAnyToken();
510   }
511   // Skip the last annot_pragma_openmp_end.
512   SourceLocation EndLoc = ConsumeToken();
513   if (!IsError) {
514     return Actions.ActOnOpenMPDeclareSimdDirective(
515         Ptr, BS, Simdlen.get(), Uniforms, Aligneds, Alignments, Linears,
516         LinModifiers, Steps, SourceRange(Loc, EndLoc));
517   }
518   return Ptr;
519 }
520 
521 /// \brief Parsing of declarative OpenMP directives.
522 ///
523 ///       threadprivate-directive:
524 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
525 ///         annot_pragma_openmp_end
526 ///
527 ///       declare-reduction-directive:
528 ///        annot_pragma_openmp 'declare' 'reduction' [...]
529 ///        annot_pragma_openmp_end
530 ///
531 ///       declare-simd-directive:
532 ///         annot_pragma_openmp 'declare simd' {<clause> [,]}
533 ///         annot_pragma_openmp_end
534 ///         <function declaration/definition>
535 ///
536 Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
537     AccessSpecifier &AS, ParsedAttributesWithRange &Attrs,
538     DeclSpec::TST TagType, Decl *Tag) {
539   assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
540   ParenBraceBracketBalancer BalancerRAIIObj(*this);
541 
542   SourceLocation Loc = ConsumeToken();
543   auto DKind = ParseOpenMPDirectiveKind(*this);
544 
545   switch (DKind) {
546   case OMPD_threadprivate: {
547     ConsumeToken();
548     ThreadprivateListParserHelper Helper(this);
549     if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Helper, true)) {
550       // The last seen token is annot_pragma_openmp_end - need to check for
551       // extra tokens.
552       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
553         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
554             << getOpenMPDirectiveName(OMPD_threadprivate);
555         SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
556       }
557       // Skip the last annot_pragma_openmp_end.
558       ConsumeToken();
559       return Actions.ActOnOpenMPThreadprivateDirective(Loc,
560                                                        Helper.getIdentifiers());
561     }
562     break;
563   }
564   case OMPD_declare_reduction:
565     ConsumeToken();
566     if (auto Res = ParseOpenMPDeclareReductionDirective(AS)) {
567       // The last seen token is annot_pragma_openmp_end - need to check for
568       // extra tokens.
569       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
570         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
571             << getOpenMPDirectiveName(OMPD_declare_reduction);
572         while (Tok.isNot(tok::annot_pragma_openmp_end))
573           ConsumeAnyToken();
574       }
575       // Skip the last annot_pragma_openmp_end.
576       ConsumeToken();
577       return Res;
578     }
579     break;
580   case OMPD_declare_simd: {
581     // The syntax is:
582     // { #pragma omp declare simd }
583     // <function-declaration-or-definition>
584     //
585     ConsumeToken();
586     CachedTokens Toks;
587     while(Tok.isNot(tok::annot_pragma_openmp_end)) {
588       Toks.push_back(Tok);
589       ConsumeAnyToken();
590     }
591     Toks.push_back(Tok);
592     ConsumeAnyToken();
593 
594     DeclGroupPtrTy Ptr;
595     if (Tok.is(tok::annot_pragma_openmp))
596       Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, TagType, Tag);
597     else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
598       // Here we expect to see some function declaration.
599       if (AS == AS_none) {
600         assert(TagType == DeclSpec::TST_unspecified);
601         MaybeParseCXX11Attributes(Attrs);
602         MaybeParseMicrosoftAttributes(Attrs);
603         ParsingDeclSpec PDS(*this);
604         Ptr = ParseExternalDeclaration(Attrs, &PDS);
605       } else {
606         Ptr =
607             ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
608       }
609     }
610     if (!Ptr) {
611       Diag(Loc, diag::err_omp_decl_in_declare_simd);
612       return DeclGroupPtrTy();
613     }
614     return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
615   }
616   case OMPD_declare_target: {
617     SourceLocation DTLoc = ConsumeAnyToken();
618     if (Tok.isNot(tok::annot_pragma_openmp_end)) {
619       // OpenMP 4.5 syntax with list of entities.
620       llvm::SmallSetVector<const NamedDecl*, 16> SameDirectiveDecls;
621       while (Tok.isNot(tok::annot_pragma_openmp_end)) {
622         OMPDeclareTargetDeclAttr::MapTypeTy MT =
623             OMPDeclareTargetDeclAttr::MT_To;
624         if (Tok.is(tok::identifier)) {
625           IdentifierInfo *II = Tok.getIdentifierInfo();
626           StringRef ClauseName = II->getName();
627           // Parse 'to|link' clauses.
628           if (!OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName,
629                                                                MT)) {
630             Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
631                 << ClauseName;
632             break;
633           }
634           ConsumeToken();
635         }
636         auto Callback = [this, MT, &SameDirectiveDecls](
637             CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
638           Actions.ActOnOpenMPDeclareTargetName(getCurScope(), SS, NameInfo, MT,
639                                                SameDirectiveDecls);
640         };
641         if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback, true))
642           break;
643 
644         // Consume optional ','.
645         if (Tok.is(tok::comma))
646           ConsumeToken();
647       }
648       SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
649       ConsumeAnyToken();
650       return DeclGroupPtrTy();
651     }
652 
653     // Skip the last annot_pragma_openmp_end.
654     ConsumeAnyToken();
655 
656     if (!Actions.ActOnStartOpenMPDeclareTargetDirective(DTLoc))
657       return DeclGroupPtrTy();
658 
659     DKind = ParseOpenMPDirectiveKind(*this);
660     while (DKind != OMPD_end_declare_target && DKind != OMPD_declare_target &&
661            Tok.isNot(tok::eof) && Tok.isNot(tok::r_brace)) {
662       ParsedAttributesWithRange attrs(AttrFactory);
663       MaybeParseCXX11Attributes(attrs);
664       MaybeParseMicrosoftAttributes(attrs);
665       ParseExternalDeclaration(attrs);
666       if (Tok.isAnnotation() && Tok.is(tok::annot_pragma_openmp)) {
667         TentativeParsingAction TPA(*this);
668         ConsumeToken();
669         DKind = ParseOpenMPDirectiveKind(*this);
670         if (DKind != OMPD_end_declare_target)
671           TPA.Revert();
672         else
673           TPA.Commit();
674       }
675     }
676 
677     if (DKind == OMPD_end_declare_target) {
678       ConsumeAnyToken();
679       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
680         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
681             << getOpenMPDirectiveName(OMPD_end_declare_target);
682         SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
683       }
684       // Skip the last annot_pragma_openmp_end.
685       ConsumeAnyToken();
686     } else {
687       Diag(Tok, diag::err_expected_end_declare_target);
688       Diag(DTLoc, diag::note_matching) << "'#pragma omp declare target'";
689     }
690     Actions.ActOnFinishOpenMPDeclareTargetDirective();
691     return DeclGroupPtrTy();
692   }
693   case OMPD_unknown:
694     Diag(Tok, diag::err_omp_unknown_directive);
695     break;
696   case OMPD_parallel:
697   case OMPD_simd:
698   case OMPD_task:
699   case OMPD_taskyield:
700   case OMPD_barrier:
701   case OMPD_taskwait:
702   case OMPD_taskgroup:
703   case OMPD_flush:
704   case OMPD_for:
705   case OMPD_for_simd:
706   case OMPD_sections:
707   case OMPD_section:
708   case OMPD_single:
709   case OMPD_master:
710   case OMPD_ordered:
711   case OMPD_critical:
712   case OMPD_parallel_for:
713   case OMPD_parallel_for_simd:
714   case OMPD_parallel_sections:
715   case OMPD_atomic:
716   case OMPD_target:
717   case OMPD_teams:
718   case OMPD_cancellation_point:
719   case OMPD_cancel:
720   case OMPD_target_data:
721   case OMPD_target_enter_data:
722   case OMPD_target_exit_data:
723   case OMPD_target_parallel:
724   case OMPD_target_parallel_for:
725   case OMPD_taskloop:
726   case OMPD_taskloop_simd:
727   case OMPD_distribute:
728   case OMPD_end_declare_target:
729     Diag(Tok, diag::err_omp_unexpected_directive)
730         << getOpenMPDirectiveName(DKind);
731     break;
732   }
733   while (Tok.isNot(tok::annot_pragma_openmp_end))
734     ConsumeAnyToken();
735   ConsumeAnyToken();
736   return nullptr;
737 }
738 
739 /// \brief Parsing of declarative or executable OpenMP directives.
740 ///
741 ///       threadprivate-directive:
742 ///         annot_pragma_openmp 'threadprivate' simple-variable-list
743 ///         annot_pragma_openmp_end
744 ///
745 ///       declare-reduction-directive:
746 ///         annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
747 ///         <type> {',' <type>} ':' <expression> ')' ['initializer' '('
748 ///         ('omp_priv' '=' <expression>|<function_call>) ')']
749 ///         annot_pragma_openmp_end
750 ///
751 ///       executable-directive:
752 ///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
753 ///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
754 ///         'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
755 ///         'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' |
756 ///         'for simd' | 'parallel for simd' | 'target' | 'target data' |
757 ///         'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
758 ///         'distribute' | 'target enter data' | 'target exit data' |
759 ///         'target parallel' | 'target parallel for' {clause}
760 ///         annot_pragma_openmp_end
761 ///
762 StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
763     AllowedContsructsKind Allowed) {
764   assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
765   ParenBraceBracketBalancer BalancerRAIIObj(*this);
766   SmallVector<OMPClause *, 5> Clauses;
767   SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
768   FirstClauses(OMPC_unknown + 1);
769   unsigned ScopeFlags =
770       Scope::FnScope | Scope::DeclScope | Scope::OpenMPDirectiveScope;
771   SourceLocation Loc = ConsumeToken(), EndLoc;
772   auto DKind = ParseOpenMPDirectiveKind(*this);
773   OpenMPDirectiveKind CancelRegion = OMPD_unknown;
774   // Name of critical directive.
775   DeclarationNameInfo DirName;
776   StmtResult Directive = StmtError();
777   bool HasAssociatedStatement = true;
778   bool FlushHasClause = false;
779 
780   switch (DKind) {
781   case OMPD_threadprivate: {
782     if (Allowed != ACK_Any) {
783       Diag(Tok, diag::err_omp_immediate_directive)
784           << getOpenMPDirectiveName(DKind) << 0;
785     }
786     ConsumeToken();
787     ThreadprivateListParserHelper Helper(this);
788     if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Helper, false)) {
789       // The last seen token is annot_pragma_openmp_end - need to check for
790       // extra tokens.
791       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
792         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
793             << getOpenMPDirectiveName(OMPD_threadprivate);
794         SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
795       }
796       DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
797           Loc, Helper.getIdentifiers());
798       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
799     }
800     SkipUntil(tok::annot_pragma_openmp_end);
801     break;
802   }
803   case OMPD_declare_reduction:
804     ConsumeToken();
805     if (auto Res = ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
806       // The last seen token is annot_pragma_openmp_end - need to check for
807       // extra tokens.
808       if (Tok.isNot(tok::annot_pragma_openmp_end)) {
809         Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
810             << getOpenMPDirectiveName(OMPD_declare_reduction);
811         while (Tok.isNot(tok::annot_pragma_openmp_end))
812           ConsumeAnyToken();
813       }
814       ConsumeAnyToken();
815       Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
816     } else
817       SkipUntil(tok::annot_pragma_openmp_end);
818     break;
819   case OMPD_flush:
820     if (PP.LookAhead(0).is(tok::l_paren)) {
821       FlushHasClause = true;
822       // Push copy of the current token back to stream to properly parse
823       // pseudo-clause OMPFlushClause.
824       PP.EnterToken(Tok);
825     }
826   case OMPD_taskyield:
827   case OMPD_barrier:
828   case OMPD_taskwait:
829   case OMPD_cancellation_point:
830   case OMPD_cancel:
831   case OMPD_target_enter_data:
832   case OMPD_target_exit_data:
833     if (Allowed == ACK_StatementsOpenMPNonStandalone) {
834       Diag(Tok, diag::err_omp_immediate_directive)
835           << getOpenMPDirectiveName(DKind) << 0;
836     }
837     HasAssociatedStatement = false;
838     // Fall through for further analysis.
839   case OMPD_parallel:
840   case OMPD_simd:
841   case OMPD_for:
842   case OMPD_for_simd:
843   case OMPD_sections:
844   case OMPD_single:
845   case OMPD_section:
846   case OMPD_master:
847   case OMPD_critical:
848   case OMPD_parallel_for:
849   case OMPD_parallel_for_simd:
850   case OMPD_parallel_sections:
851   case OMPD_task:
852   case OMPD_ordered:
853   case OMPD_atomic:
854   case OMPD_target:
855   case OMPD_teams:
856   case OMPD_taskgroup:
857   case OMPD_target_data:
858   case OMPD_target_parallel:
859   case OMPD_target_parallel_for:
860   case OMPD_taskloop:
861   case OMPD_taskloop_simd:
862   case OMPD_distribute: {
863     ConsumeToken();
864     // Parse directive name of the 'critical' directive if any.
865     if (DKind == OMPD_critical) {
866       BalancedDelimiterTracker T(*this, tok::l_paren,
867                                  tok::annot_pragma_openmp_end);
868       if (!T.consumeOpen()) {
869         if (Tok.isAnyIdentifier()) {
870           DirName =
871               DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
872           ConsumeAnyToken();
873         } else {
874           Diag(Tok, diag::err_omp_expected_identifier_for_critical);
875         }
876         T.consumeClose();
877       }
878     } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
879       CancelRegion = ParseOpenMPDirectiveKind(*this);
880       if (Tok.isNot(tok::annot_pragma_openmp_end))
881         ConsumeToken();
882     }
883 
884     if (isOpenMPLoopDirective(DKind))
885       ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
886     if (isOpenMPSimdDirective(DKind))
887       ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
888     ParseScope OMPDirectiveScope(this, ScopeFlags);
889     Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
890 
891     while (Tok.isNot(tok::annot_pragma_openmp_end)) {
892       OpenMPClauseKind CKind =
893           Tok.isAnnotation()
894               ? OMPC_unknown
895               : FlushHasClause ? OMPC_flush
896                                : getOpenMPClauseKind(PP.getSpelling(Tok));
897       Actions.StartOpenMPClause(CKind);
898       FlushHasClause = false;
899       OMPClause *Clause =
900           ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
901       FirstClauses[CKind].setInt(true);
902       if (Clause) {
903         FirstClauses[CKind].setPointer(Clause);
904         Clauses.push_back(Clause);
905       }
906 
907       // Skip ',' if any.
908       if (Tok.is(tok::comma))
909         ConsumeToken();
910       Actions.EndOpenMPClause();
911     }
912     // End location of the directive.
913     EndLoc = Tok.getLocation();
914     // Consume final annot_pragma_openmp_end.
915     ConsumeToken();
916 
917     // OpenMP [2.13.8, ordered Construct, Syntax]
918     // If the depend clause is specified, the ordered construct is a stand-alone
919     // directive.
920     if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) {
921       if (Allowed == ACK_StatementsOpenMPNonStandalone) {
922         Diag(Loc, diag::err_omp_immediate_directive)
923             << getOpenMPDirectiveName(DKind) << 1
924             << getOpenMPClauseName(OMPC_depend);
925       }
926       HasAssociatedStatement = false;
927     }
928 
929     StmtResult AssociatedStmt;
930     if (HasAssociatedStatement) {
931       // The body is a block scope like in Lambdas and Blocks.
932       Sema::CompoundScopeRAII CompoundScope(Actions);
933       Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
934       Actions.ActOnStartOfCompoundStmt();
935       // Parse statement
936       AssociatedStmt = ParseStatement();
937       Actions.ActOnFinishOfCompoundStmt();
938       AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
939     }
940     Directive = Actions.ActOnOpenMPExecutableDirective(
941         DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
942         EndLoc);
943 
944     // Exit scope.
945     Actions.EndOpenMPDSABlock(Directive.get());
946     OMPDirectiveScope.Exit();
947     break;
948   }
949   case OMPD_declare_simd:
950   case OMPD_declare_target:
951   case OMPD_end_declare_target:
952     Diag(Tok, diag::err_omp_unexpected_directive)
953         << getOpenMPDirectiveName(DKind);
954     SkipUntil(tok::annot_pragma_openmp_end);
955     break;
956   case OMPD_unknown:
957     Diag(Tok, diag::err_omp_unknown_directive);
958     SkipUntil(tok::annot_pragma_openmp_end);
959     break;
960   }
961   return Directive;
962 }
963 
964 // Parses simple list:
965 //   simple-variable-list:
966 //         '(' id-expression {, id-expression} ')'
967 //
968 bool Parser::ParseOpenMPSimpleVarList(
969     OpenMPDirectiveKind Kind,
970     const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> &
971         Callback,
972     bool AllowScopeSpecifier) {
973   // Parse '('.
974   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
975   if (T.expectAndConsume(diag::err_expected_lparen_after,
976                          getOpenMPDirectiveName(Kind)))
977     return true;
978   bool IsCorrect = true;
979   bool NoIdentIsFound = true;
980 
981   // Read tokens while ')' or annot_pragma_openmp_end is not found.
982   while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
983     CXXScopeSpec SS;
984     SourceLocation TemplateKWLoc;
985     UnqualifiedId Name;
986     // Read var name.
987     Token PrevTok = Tok;
988     NoIdentIsFound = false;
989 
990     if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
991         ParseOptionalCXXScopeSpecifier(SS, nullptr, false)) {
992       IsCorrect = false;
993       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
994                 StopBeforeMatch);
995     } else if (ParseUnqualifiedId(SS, false, false, false, nullptr,
996                                   TemplateKWLoc, Name)) {
997       IsCorrect = false;
998       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
999                 StopBeforeMatch);
1000     } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
1001                Tok.isNot(tok::annot_pragma_openmp_end)) {
1002       IsCorrect = false;
1003       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1004                 StopBeforeMatch);
1005       Diag(PrevTok.getLocation(), diag::err_expected)
1006           << tok::identifier
1007           << SourceRange(PrevTok.getLocation(), PrevTokLocation);
1008     } else {
1009       Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
1010     }
1011     // Consume ','.
1012     if (Tok.is(tok::comma)) {
1013       ConsumeToken();
1014     }
1015   }
1016 
1017   if (NoIdentIsFound) {
1018     Diag(Tok, diag::err_expected) << tok::identifier;
1019     IsCorrect = false;
1020   }
1021 
1022   // Parse ')'.
1023   IsCorrect = !T.consumeClose() && IsCorrect;
1024 
1025   return !IsCorrect;
1026 }
1027 
1028 /// \brief Parsing of OpenMP clauses.
1029 ///
1030 ///    clause:
1031 ///       if-clause | final-clause | num_threads-clause | safelen-clause |
1032 ///       default-clause | private-clause | firstprivate-clause | shared-clause
1033 ///       | linear-clause | aligned-clause | collapse-clause |
1034 ///       lastprivate-clause | reduction-clause | proc_bind-clause |
1035 ///       schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
1036 ///       mergeable-clause | flush-clause | read-clause | write-clause |
1037 ///       update-clause | capture-clause | seq_cst-clause | device-clause |
1038 ///       simdlen-clause | threads-clause | simd-clause | num_teams-clause |
1039 ///       thread_limit-clause | priority-clause | grainsize-clause |
1040 ///       nogroup-clause | num_tasks-clause | hint-clause
1041 ///
1042 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
1043                                      OpenMPClauseKind CKind, bool FirstClause) {
1044   OMPClause *Clause = nullptr;
1045   bool ErrorFound = false;
1046   // Check if clause is allowed for the given directive.
1047   if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) {
1048     Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
1049                                                << getOpenMPDirectiveName(DKind);
1050     ErrorFound = true;
1051   }
1052 
1053   switch (CKind) {
1054   case OMPC_final:
1055   case OMPC_num_threads:
1056   case OMPC_safelen:
1057   case OMPC_simdlen:
1058   case OMPC_collapse:
1059   case OMPC_ordered:
1060   case OMPC_device:
1061   case OMPC_num_teams:
1062   case OMPC_thread_limit:
1063   case OMPC_priority:
1064   case OMPC_grainsize:
1065   case OMPC_num_tasks:
1066   case OMPC_hint:
1067     // OpenMP [2.5, Restrictions]
1068     //  At most one num_threads clause can appear on the directive.
1069     // OpenMP [2.8.1, simd construct, Restrictions]
1070     //  Only one safelen  clause can appear on a simd directive.
1071     //  Only one simdlen  clause can appear on a simd directive.
1072     //  Only one collapse clause can appear on a simd directive.
1073     // OpenMP [2.9.1, target data construct, Restrictions]
1074     //  At most one device clause can appear on the directive.
1075     // OpenMP [2.11.1, task Construct, Restrictions]
1076     //  At most one if clause can appear on the directive.
1077     //  At most one final clause can appear on the directive.
1078     // OpenMP [teams Construct, Restrictions]
1079     //  At most one num_teams clause can appear on the directive.
1080     //  At most one thread_limit clause can appear on the directive.
1081     // OpenMP [2.9.1, task Construct, Restrictions]
1082     // At most one priority clause can appear on the directive.
1083     // OpenMP [2.9.2, taskloop Construct, Restrictions]
1084     // At most one grainsize clause can appear on the directive.
1085     // OpenMP [2.9.2, taskloop Construct, Restrictions]
1086     // At most one num_tasks clause can appear on the directive.
1087     if (!FirstClause) {
1088       Diag(Tok, diag::err_omp_more_one_clause)
1089           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1090       ErrorFound = true;
1091     }
1092 
1093     if (CKind == OMPC_ordered && PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
1094       Clause = ParseOpenMPClause(CKind);
1095     else
1096       Clause = ParseOpenMPSingleExprClause(CKind);
1097     break;
1098   case OMPC_default:
1099   case OMPC_proc_bind:
1100     // OpenMP [2.14.3.1, Restrictions]
1101     //  Only a single default clause may be specified on a parallel, task or
1102     //  teams directive.
1103     // OpenMP [2.5, parallel Construct, Restrictions]
1104     //  At most one proc_bind clause can appear on the directive.
1105     if (!FirstClause) {
1106       Diag(Tok, diag::err_omp_more_one_clause)
1107           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1108       ErrorFound = true;
1109     }
1110 
1111     Clause = ParseOpenMPSimpleClause(CKind);
1112     break;
1113   case OMPC_schedule:
1114   case OMPC_dist_schedule:
1115   case OMPC_defaultmap:
1116     // OpenMP [2.7.1, Restrictions, p. 3]
1117     //  Only one schedule clause can appear on a loop directive.
1118     // OpenMP [2.10.4, Restrictions, p. 106]
1119     //  At most one defaultmap clause can appear on the directive.
1120     if (!FirstClause) {
1121       Diag(Tok, diag::err_omp_more_one_clause)
1122           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1123       ErrorFound = true;
1124     }
1125 
1126   case OMPC_if:
1127     Clause = ParseOpenMPSingleExprWithArgClause(CKind);
1128     break;
1129   case OMPC_nowait:
1130   case OMPC_untied:
1131   case OMPC_mergeable:
1132   case OMPC_read:
1133   case OMPC_write:
1134   case OMPC_update:
1135   case OMPC_capture:
1136   case OMPC_seq_cst:
1137   case OMPC_threads:
1138   case OMPC_simd:
1139   case OMPC_nogroup:
1140     // OpenMP [2.7.1, Restrictions, p. 9]
1141     //  Only one ordered clause can appear on a loop directive.
1142     // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
1143     //  Only one nowait clause can appear on a for directive.
1144     if (!FirstClause) {
1145       Diag(Tok, diag::err_omp_more_one_clause)
1146           << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1147       ErrorFound = true;
1148     }
1149 
1150     Clause = ParseOpenMPClause(CKind);
1151     break;
1152   case OMPC_private:
1153   case OMPC_firstprivate:
1154   case OMPC_lastprivate:
1155   case OMPC_shared:
1156   case OMPC_reduction:
1157   case OMPC_linear:
1158   case OMPC_aligned:
1159   case OMPC_copyin:
1160   case OMPC_copyprivate:
1161   case OMPC_flush:
1162   case OMPC_depend:
1163   case OMPC_map:
1164     Clause = ParseOpenMPVarListClause(DKind, CKind);
1165     break;
1166   case OMPC_unknown:
1167     Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1168         << getOpenMPDirectiveName(DKind);
1169     SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1170     break;
1171   case OMPC_threadprivate:
1172   case OMPC_uniform:
1173     Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
1174                                                << getOpenMPDirectiveName(DKind);
1175     SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
1176     break;
1177   }
1178   return ErrorFound ? nullptr : Clause;
1179 }
1180 
1181 /// Parses simple expression in parens for single-expression clauses of OpenMP
1182 /// constructs.
1183 /// \param RLoc Returned location of right paren.
1184 ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
1185                                          SourceLocation &RLoc) {
1186   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1187   if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
1188     return ExprError();
1189 
1190   SourceLocation ELoc = Tok.getLocation();
1191   ExprResult LHS(ParseCastExpression(
1192       /*isUnaryExpression=*/false, /*isAddressOfOperand=*/false, NotTypeCast));
1193   ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
1194   Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
1195 
1196   // Parse ')'.
1197   T.consumeClose();
1198 
1199   RLoc = T.getCloseLocation();
1200   return Val;
1201 }
1202 
1203 /// \brief Parsing of OpenMP clauses with single expressions like 'final',
1204 /// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
1205 /// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks' or 'hint'.
1206 ///
1207 ///    final-clause:
1208 ///      'final' '(' expression ')'
1209 ///
1210 ///    num_threads-clause:
1211 ///      'num_threads' '(' expression ')'
1212 ///
1213 ///    safelen-clause:
1214 ///      'safelen' '(' expression ')'
1215 ///
1216 ///    simdlen-clause:
1217 ///      'simdlen' '(' expression ')'
1218 ///
1219 ///    collapse-clause:
1220 ///      'collapse' '(' expression ')'
1221 ///
1222 ///    priority-clause:
1223 ///      'priority' '(' expression ')'
1224 ///
1225 ///    grainsize-clause:
1226 ///      'grainsize' '(' expression ')'
1227 ///
1228 ///    num_tasks-clause:
1229 ///      'num_tasks' '(' expression ')'
1230 ///
1231 ///    hint-clause:
1232 ///      'hint' '(' expression ')'
1233 ///
1234 OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind) {
1235   SourceLocation Loc = ConsumeToken();
1236   SourceLocation LLoc = Tok.getLocation();
1237   SourceLocation RLoc;
1238 
1239   ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc);
1240 
1241   if (Val.isInvalid())
1242     return nullptr;
1243 
1244   return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc);
1245 }
1246 
1247 /// \brief Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
1248 ///
1249 ///    default-clause:
1250 ///         'default' '(' 'none' | 'shared' ')
1251 ///
1252 ///    proc_bind-clause:
1253 ///         'proc_bind' '(' 'master' | 'close' | 'spread' ')
1254 ///
1255 OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) {
1256   SourceLocation Loc = Tok.getLocation();
1257   SourceLocation LOpen = ConsumeToken();
1258   // Parse '('.
1259   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1260   if (T.expectAndConsume(diag::err_expected_lparen_after,
1261                          getOpenMPClauseName(Kind)))
1262     return nullptr;
1263 
1264   unsigned Type = getOpenMPSimpleClauseType(
1265       Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1266   SourceLocation TypeLoc = Tok.getLocation();
1267   if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1268       Tok.isNot(tok::annot_pragma_openmp_end))
1269     ConsumeAnyToken();
1270 
1271   // Parse ')'.
1272   T.consumeClose();
1273 
1274   return Actions.ActOnOpenMPSimpleClause(Kind, Type, TypeLoc, LOpen, Loc,
1275                                          Tok.getLocation());
1276 }
1277 
1278 /// \brief Parsing of OpenMP clauses like 'ordered'.
1279 ///
1280 ///    ordered-clause:
1281 ///         'ordered'
1282 ///
1283 ///    nowait-clause:
1284 ///         'nowait'
1285 ///
1286 ///    untied-clause:
1287 ///         'untied'
1288 ///
1289 ///    mergeable-clause:
1290 ///         'mergeable'
1291 ///
1292 ///    read-clause:
1293 ///         'read'
1294 ///
1295 ///    threads-clause:
1296 ///         'threads'
1297 ///
1298 ///    simd-clause:
1299 ///         'simd'
1300 ///
1301 ///    nogroup-clause:
1302 ///         'nogroup'
1303 ///
1304 OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind) {
1305   SourceLocation Loc = Tok.getLocation();
1306   ConsumeAnyToken();
1307 
1308   return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
1309 }
1310 
1311 
1312 /// \brief Parsing of OpenMP clauses with single expressions and some additional
1313 /// argument like 'schedule' or 'dist_schedule'.
1314 ///
1315 ///    schedule-clause:
1316 ///      'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
1317 ///      ')'
1318 ///
1319 ///    if-clause:
1320 ///      'if' '(' [ directive-name-modifier ':' ] expression ')'
1321 ///
1322 ///    defaultmap:
1323 ///      'defaultmap' '(' modifier ':' kind ')'
1324 ///
1325 OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind) {
1326   SourceLocation Loc = ConsumeToken();
1327   SourceLocation DelimLoc;
1328   // Parse '('.
1329   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1330   if (T.expectAndConsume(diag::err_expected_lparen_after,
1331                          getOpenMPClauseName(Kind)))
1332     return nullptr;
1333 
1334   ExprResult Val;
1335   SmallVector<unsigned, 4> Arg;
1336   SmallVector<SourceLocation, 4> KLoc;
1337   if (Kind == OMPC_schedule) {
1338     enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
1339     Arg.resize(NumberOfElements);
1340     KLoc.resize(NumberOfElements);
1341     Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
1342     Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
1343     Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
1344     auto KindModifier = getOpenMPSimpleClauseType(
1345         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1346     if (KindModifier > OMPC_SCHEDULE_unknown) {
1347       // Parse 'modifier'
1348       Arg[Modifier1] = KindModifier;
1349       KLoc[Modifier1] = Tok.getLocation();
1350       if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1351           Tok.isNot(tok::annot_pragma_openmp_end))
1352         ConsumeAnyToken();
1353       if (Tok.is(tok::comma)) {
1354         // Parse ',' 'modifier'
1355         ConsumeAnyToken();
1356         KindModifier = getOpenMPSimpleClauseType(
1357             Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1358         Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown
1359                              ? KindModifier
1360                              : (unsigned)OMPC_SCHEDULE_unknown;
1361         KLoc[Modifier2] = Tok.getLocation();
1362         if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1363             Tok.isNot(tok::annot_pragma_openmp_end))
1364           ConsumeAnyToken();
1365       }
1366       // Parse ':'
1367       if (Tok.is(tok::colon))
1368         ConsumeAnyToken();
1369       else
1370         Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier";
1371       KindModifier = getOpenMPSimpleClauseType(
1372           Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1373     }
1374     Arg[ScheduleKind] = KindModifier;
1375     KLoc[ScheduleKind] = Tok.getLocation();
1376     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1377         Tok.isNot(tok::annot_pragma_openmp_end))
1378       ConsumeAnyToken();
1379     if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
1380          Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
1381          Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
1382         Tok.is(tok::comma))
1383       DelimLoc = ConsumeAnyToken();
1384   } else if (Kind == OMPC_dist_schedule) {
1385     Arg.push_back(getOpenMPSimpleClauseType(
1386         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1387     KLoc.push_back(Tok.getLocation());
1388     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1389         Tok.isNot(tok::annot_pragma_openmp_end))
1390       ConsumeAnyToken();
1391     if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
1392       DelimLoc = ConsumeAnyToken();
1393   } else if (Kind == OMPC_defaultmap) {
1394     // Get a defaultmap modifier
1395     Arg.push_back(getOpenMPSimpleClauseType(
1396         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1397     KLoc.push_back(Tok.getLocation());
1398     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1399         Tok.isNot(tok::annot_pragma_openmp_end))
1400       ConsumeAnyToken();
1401     // Parse ':'
1402     if (Tok.is(tok::colon))
1403       ConsumeAnyToken();
1404     else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown)
1405       Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier";
1406     // Get a defaultmap kind
1407     Arg.push_back(getOpenMPSimpleClauseType(
1408         Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1409     KLoc.push_back(Tok.getLocation());
1410     if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1411         Tok.isNot(tok::annot_pragma_openmp_end))
1412       ConsumeAnyToken();
1413   } else {
1414     assert(Kind == OMPC_if);
1415     KLoc.push_back(Tok.getLocation());
1416     Arg.push_back(ParseOpenMPDirectiveKind(*this));
1417     if (Arg.back() != OMPD_unknown) {
1418       ConsumeToken();
1419       if (Tok.is(tok::colon))
1420         DelimLoc = ConsumeToken();
1421       else
1422         Diag(Tok, diag::warn_pragma_expected_colon)
1423             << "directive name modifier";
1424     }
1425   }
1426 
1427   bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) ||
1428                           (Kind == OMPC_dist_schedule && DelimLoc.isValid()) ||
1429                           Kind == OMPC_if;
1430   if (NeedAnExpression) {
1431     SourceLocation ELoc = Tok.getLocation();
1432     ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
1433     Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
1434     Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
1435   }
1436 
1437   // Parse ')'.
1438   T.consumeClose();
1439 
1440   if (NeedAnExpression && Val.isInvalid())
1441     return nullptr;
1442 
1443   return Actions.ActOnOpenMPSingleExprWithArgClause(
1444       Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc,
1445       T.getCloseLocation());
1446 }
1447 
1448 static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
1449                              UnqualifiedId &ReductionId) {
1450   SourceLocation TemplateKWLoc;
1451   if (ReductionIdScopeSpec.isEmpty()) {
1452     auto OOK = OO_None;
1453     switch (P.getCurToken().getKind()) {
1454     case tok::plus:
1455       OOK = OO_Plus;
1456       break;
1457     case tok::minus:
1458       OOK = OO_Minus;
1459       break;
1460     case tok::star:
1461       OOK = OO_Star;
1462       break;
1463     case tok::amp:
1464       OOK = OO_Amp;
1465       break;
1466     case tok::pipe:
1467       OOK = OO_Pipe;
1468       break;
1469     case tok::caret:
1470       OOK = OO_Caret;
1471       break;
1472     case tok::ampamp:
1473       OOK = OO_AmpAmp;
1474       break;
1475     case tok::pipepipe:
1476       OOK = OO_PipePipe;
1477       break;
1478     default:
1479       break;
1480     }
1481     if (OOK != OO_None) {
1482       SourceLocation OpLoc = P.ConsumeToken();
1483       SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
1484       ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
1485       return false;
1486     }
1487   }
1488   return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false,
1489                               /*AllowDestructorName*/ false,
1490                               /*AllowConstructorName*/ false, nullptr,
1491                               TemplateKWLoc, ReductionId);
1492 }
1493 
1494 /// Parses clauses with list.
1495 bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
1496                                 OpenMPClauseKind Kind,
1497                                 SmallVectorImpl<Expr *> &Vars,
1498                                 OpenMPVarListDataTy &Data) {
1499   UnqualifiedId UnqualifiedReductionId;
1500   bool InvalidReductionId = false;
1501   bool MapTypeModifierSpecified = false;
1502 
1503   // Parse '('.
1504   BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1505   if (T.expectAndConsume(diag::err_expected_lparen_after,
1506                          getOpenMPClauseName(Kind)))
1507     return true;
1508 
1509   bool NeedRParenForLinear = false;
1510   BalancedDelimiterTracker LinearT(*this, tok::l_paren,
1511                                   tok::annot_pragma_openmp_end);
1512   // Handle reduction-identifier for reduction clause.
1513   if (Kind == OMPC_reduction) {
1514     ColonProtectionRAIIObject ColonRAII(*this);
1515     if (getLangOpts().CPlusPlus)
1516       ParseOptionalCXXScopeSpecifier(Data.ReductionIdScopeSpec,
1517                                      /*ObjectType=*/nullptr,
1518                                      /*EnteringContext=*/false);
1519     InvalidReductionId = ParseReductionId(*this, Data.ReductionIdScopeSpec,
1520                                           UnqualifiedReductionId);
1521     if (InvalidReductionId) {
1522       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
1523                 StopBeforeMatch);
1524     }
1525     if (Tok.is(tok::colon))
1526       Data.ColonLoc = ConsumeToken();
1527     else
1528       Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
1529     if (!InvalidReductionId)
1530       Data.ReductionId =
1531           Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
1532   } else if (Kind == OMPC_depend) {
1533   // Handle dependency type for depend clause.
1534     ColonProtectionRAIIObject ColonRAII(*this);
1535     Data.DepKind =
1536         static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType(
1537             Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
1538     Data.DepLinMapLoc = Tok.getLocation();
1539 
1540     if (Data.DepKind == OMPC_DEPEND_unknown) {
1541       SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
1542                 StopBeforeMatch);
1543     } else {
1544       ConsumeToken();
1545       // Special processing for depend(source) clause.
1546       if (DKind == OMPD_ordered && Data.DepKind == OMPC_DEPEND_source) {
1547         // Parse ')'.
1548         T.consumeClose();
1549         return false;
1550       }
1551     }
1552     if (Tok.is(tok::colon))
1553       Data.ColonLoc = ConsumeToken();
1554     else {
1555       Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
1556                                       : diag::warn_pragma_expected_colon)
1557           << "dependency type";
1558     }
1559   } else if (Kind == OMPC_linear) {
1560     // Try to parse modifier if any.
1561     if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
1562       Data.LinKind = static_cast<OpenMPLinearClauseKind>(
1563           getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
1564       Data.DepLinMapLoc = ConsumeToken();
1565       LinearT.consumeOpen();
1566       NeedRParenForLinear = true;
1567     }
1568   } else if (Kind == OMPC_map) {
1569     // Handle map type for map clause.
1570     ColonProtectionRAIIObject ColonRAII(*this);
1571 
1572     /// The map clause modifier token can be either a identifier or the C++
1573     /// delete keyword.
1574     auto &&IsMapClauseModifierToken = [](const Token &Tok) -> bool {
1575       return Tok.isOneOf(tok::identifier, tok::kw_delete);
1576     };
1577 
1578     // The first identifier may be a list item, a map-type or a
1579     // map-type-modifier. The map modifier can also be delete which has the same
1580     // spelling of the C++ delete keyword.
1581     Data.MapType =
1582         IsMapClauseModifierToken(Tok)
1583             ? static_cast<OpenMPMapClauseKind>(
1584                   getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)))
1585             : OMPC_MAP_unknown;
1586     Data.DepLinMapLoc = Tok.getLocation();
1587     bool ColonExpected = false;
1588 
1589     if (IsMapClauseModifierToken(Tok)) {
1590       if (PP.LookAhead(0).is(tok::colon)) {
1591         if (Data.MapType == OMPC_MAP_unknown)
1592           Diag(Tok, diag::err_omp_unknown_map_type);
1593         else if (Data.MapType == OMPC_MAP_always)
1594           Diag(Tok, diag::err_omp_map_type_missing);
1595         ConsumeToken();
1596       } else if (PP.LookAhead(0).is(tok::comma)) {
1597         if (IsMapClauseModifierToken(PP.LookAhead(1)) &&
1598             PP.LookAhead(2).is(tok::colon)) {
1599           Data.MapTypeModifier = Data.MapType;
1600           if (Data.MapTypeModifier != OMPC_MAP_always) {
1601             Diag(Tok, diag::err_omp_unknown_map_type_modifier);
1602             Data.MapTypeModifier = OMPC_MAP_unknown;
1603           } else
1604             MapTypeModifierSpecified = true;
1605 
1606           ConsumeToken();
1607           ConsumeToken();
1608 
1609           Data.MapType =
1610               IsMapClauseModifierToken(Tok)
1611                   ? static_cast<OpenMPMapClauseKind>(
1612                         getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)))
1613                   : OMPC_MAP_unknown;
1614           if (Data.MapType == OMPC_MAP_unknown ||
1615               Data.MapType == OMPC_MAP_always)
1616             Diag(Tok, diag::err_omp_unknown_map_type);
1617           ConsumeToken();
1618         } else {
1619           Data.MapType = OMPC_MAP_tofrom;
1620           Data.IsMapTypeImplicit = true;
1621         }
1622       } else {
1623         Data.MapType = OMPC_MAP_tofrom;
1624         Data.IsMapTypeImplicit = true;
1625       }
1626     } else {
1627       Data.MapType = OMPC_MAP_tofrom;
1628       Data.IsMapTypeImplicit = true;
1629     }
1630 
1631     if (Tok.is(tok::colon))
1632       Data.ColonLoc = ConsumeToken();
1633     else if (ColonExpected)
1634       Diag(Tok, diag::warn_pragma_expected_colon) << "map type";
1635   }
1636 
1637   bool IsComma =
1638       (Kind != OMPC_reduction && Kind != OMPC_depend && Kind != OMPC_map) ||
1639       (Kind == OMPC_reduction && !InvalidReductionId) ||
1640       (Kind == OMPC_map && Data.MapType != OMPC_MAP_unknown &&
1641        (!MapTypeModifierSpecified ||
1642         Data.MapTypeModifier == OMPC_MAP_always)) ||
1643       (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown);
1644   const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
1645   while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
1646                      Tok.isNot(tok::annot_pragma_openmp_end))) {
1647     ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
1648     // Parse variable
1649     ExprResult VarExpr =
1650         Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
1651     if (VarExpr.isUsable())
1652       Vars.push_back(VarExpr.get());
1653     else {
1654       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1655                 StopBeforeMatch);
1656     }
1657     // Skip ',' if any
1658     IsComma = Tok.is(tok::comma);
1659     if (IsComma)
1660       ConsumeToken();
1661     else if (Tok.isNot(tok::r_paren) &&
1662              Tok.isNot(tok::annot_pragma_openmp_end) &&
1663              (!MayHaveTail || Tok.isNot(tok::colon)))
1664       Diag(Tok, diag::err_omp_expected_punc)
1665           << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
1666                                    : getOpenMPClauseName(Kind))
1667           << (Kind == OMPC_flush);
1668   }
1669 
1670   // Parse ')' for linear clause with modifier.
1671   if (NeedRParenForLinear)
1672     LinearT.consumeClose();
1673 
1674   // Parse ':' linear-step (or ':' alignment).
1675   const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
1676   if (MustHaveTail) {
1677     Data.ColonLoc = Tok.getLocation();
1678     SourceLocation ELoc = ConsumeToken();
1679     ExprResult Tail = ParseAssignmentExpression();
1680     Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc);
1681     if (Tail.isUsable())
1682       Data.TailExpr = Tail.get();
1683     else
1684       SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1685                 StopBeforeMatch);
1686   }
1687 
1688   // Parse ')'.
1689   T.consumeClose();
1690   if ((Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown &&
1691        Vars.empty()) ||
1692       (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
1693       (MustHaveTail && !Data.TailExpr) || InvalidReductionId)
1694     return true;
1695   return false;
1696 }
1697 
1698 /// \brief Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
1699 /// 'shared', 'copyin', 'copyprivate', 'flush' or 'reduction'.
1700 ///
1701 ///    private-clause:
1702 ///       'private' '(' list ')'
1703 ///    firstprivate-clause:
1704 ///       'firstprivate' '(' list ')'
1705 ///    lastprivate-clause:
1706 ///       'lastprivate' '(' list ')'
1707 ///    shared-clause:
1708 ///       'shared' '(' list ')'
1709 ///    linear-clause:
1710 ///       'linear' '(' linear-list [ ':' linear-step ] ')'
1711 ///    aligned-clause:
1712 ///       'aligned' '(' list [ ':' alignment ] ')'
1713 ///    reduction-clause:
1714 ///       'reduction' '(' reduction-identifier ':' list ')'
1715 ///    copyprivate-clause:
1716 ///       'copyprivate' '(' list ')'
1717 ///    flush-clause:
1718 ///       'flush' '(' list ')'
1719 ///    depend-clause:
1720 ///       'depend' '(' in | out | inout : list | source ')'
1721 ///    map-clause:
1722 ///       'map' '(' [ [ always , ]
1723 ///          to | from | tofrom | alloc | release | delete ':' ] list ')';
1724 ///
1725 /// For 'linear' clause linear-list may have the following forms:
1726 ///  list
1727 ///  modifier(list)
1728 /// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
1729 OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
1730                                             OpenMPClauseKind Kind) {
1731   SourceLocation Loc = Tok.getLocation();
1732   SourceLocation LOpen = ConsumeToken();
1733   SmallVector<Expr *, 4> Vars;
1734   OpenMPVarListDataTy Data;
1735 
1736   if (ParseOpenMPVarList(DKind, Kind, Vars, Data))
1737     return nullptr;
1738 
1739   return Actions.ActOnOpenMPVarListClause(
1740       Kind, Vars, Data.TailExpr, Loc, LOpen, Data.ColonLoc, Tok.getLocation(),
1741       Data.ReductionIdScopeSpec, Data.ReductionId, Data.DepKind, Data.LinKind,
1742       Data.MapTypeModifier, Data.MapType, Data.IsMapTypeImplicit,
1743       Data.DepLinMapLoc);
1744 }
1745 
1746