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