ParseOpenMP.cpp revision 355940
1//===--- ParseOpenMP.cpp - OpenMP directives parsing ----------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file implements parsing of all OpenMP directives and clauses.
10///
11//===----------------------------------------------------------------------===//
12
13#include "clang/AST/ASTContext.h"
14#include "clang/AST/StmtOpenMP.h"
15#include "clang/Parse/ParseDiagnostic.h"
16#include "clang/Parse/Parser.h"
17#include "clang/Parse/RAIIObjectsForParser.h"
18#include "clang/Sema/Scope.h"
19#include "llvm/ADT/PointerIntPair.h"
20
21using namespace clang;
22
23//===----------------------------------------------------------------------===//
24// OpenMP declarative directives.
25//===----------------------------------------------------------------------===//
26
27namespace {
28enum OpenMPDirectiveKindEx {
29  OMPD_cancellation = OMPD_unknown + 1,
30  OMPD_data,
31  OMPD_declare,
32  OMPD_end,
33  OMPD_end_declare,
34  OMPD_enter,
35  OMPD_exit,
36  OMPD_point,
37  OMPD_reduction,
38  OMPD_target_enter,
39  OMPD_target_exit,
40  OMPD_update,
41  OMPD_distribute_parallel,
42  OMPD_teams_distribute_parallel,
43  OMPD_target_teams_distribute_parallel,
44  OMPD_mapper,
45};
46
47class DeclDirectiveListParserHelper final {
48  SmallVector<Expr *, 4> Identifiers;
49  Parser *P;
50  OpenMPDirectiveKind Kind;
51
52public:
53  DeclDirectiveListParserHelper(Parser *P, OpenMPDirectiveKind Kind)
54      : P(P), Kind(Kind) {}
55  void operator()(CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
56    ExprResult Res = P->getActions().ActOnOpenMPIdExpression(
57        P->getCurScope(), SS, NameInfo, Kind);
58    if (Res.isUsable())
59      Identifiers.push_back(Res.get());
60  }
61  llvm::ArrayRef<Expr *> getIdentifiers() const { return Identifiers; }
62};
63} // namespace
64
65// Map token string to extended OMP token kind that are
66// OpenMPDirectiveKind + OpenMPDirectiveKindEx.
67static unsigned getOpenMPDirectiveKindEx(StringRef S) {
68  auto DKind = getOpenMPDirectiveKind(S);
69  if (DKind != OMPD_unknown)
70    return DKind;
71
72  return llvm::StringSwitch<unsigned>(S)
73      .Case("cancellation", OMPD_cancellation)
74      .Case("data", OMPD_data)
75      .Case("declare", OMPD_declare)
76      .Case("end", OMPD_end)
77      .Case("enter", OMPD_enter)
78      .Case("exit", OMPD_exit)
79      .Case("point", OMPD_point)
80      .Case("reduction", OMPD_reduction)
81      .Case("update", OMPD_update)
82      .Case("mapper", OMPD_mapper)
83      .Default(OMPD_unknown);
84}
85
86static OpenMPDirectiveKind parseOpenMPDirectiveKind(Parser &P) {
87  // Array of foldings: F[i][0] F[i][1] ===> F[i][2].
88  // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd
89  // TODO: add other combined directives in topological order.
90  static const unsigned F[][3] = {
91      {OMPD_cancellation, OMPD_point, OMPD_cancellation_point},
92      {OMPD_declare, OMPD_reduction, OMPD_declare_reduction},
93      {OMPD_declare, OMPD_mapper, OMPD_declare_mapper},
94      {OMPD_declare, OMPD_simd, OMPD_declare_simd},
95      {OMPD_declare, OMPD_target, OMPD_declare_target},
96      {OMPD_distribute, OMPD_parallel, OMPD_distribute_parallel},
97      {OMPD_distribute_parallel, OMPD_for, OMPD_distribute_parallel_for},
98      {OMPD_distribute_parallel_for, OMPD_simd,
99       OMPD_distribute_parallel_for_simd},
100      {OMPD_distribute, OMPD_simd, OMPD_distribute_simd},
101      {OMPD_end, OMPD_declare, OMPD_end_declare},
102      {OMPD_end_declare, OMPD_target, OMPD_end_declare_target},
103      {OMPD_target, OMPD_data, OMPD_target_data},
104      {OMPD_target, OMPD_enter, OMPD_target_enter},
105      {OMPD_target, OMPD_exit, OMPD_target_exit},
106      {OMPD_target, OMPD_update, OMPD_target_update},
107      {OMPD_target_enter, OMPD_data, OMPD_target_enter_data},
108      {OMPD_target_exit, OMPD_data, OMPD_target_exit_data},
109      {OMPD_for, OMPD_simd, OMPD_for_simd},
110      {OMPD_parallel, OMPD_for, OMPD_parallel_for},
111      {OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},
112      {OMPD_parallel, OMPD_sections, OMPD_parallel_sections},
113      {OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd},
114      {OMPD_target, OMPD_parallel, OMPD_target_parallel},
115      {OMPD_target, OMPD_simd, OMPD_target_simd},
116      {OMPD_target_parallel, OMPD_for, OMPD_target_parallel_for},
117      {OMPD_target_parallel_for, OMPD_simd, OMPD_target_parallel_for_simd},
118      {OMPD_teams, OMPD_distribute, OMPD_teams_distribute},
119      {OMPD_teams_distribute, OMPD_simd, OMPD_teams_distribute_simd},
120      {OMPD_teams_distribute, OMPD_parallel, OMPD_teams_distribute_parallel},
121      {OMPD_teams_distribute_parallel, OMPD_for,
122       OMPD_teams_distribute_parallel_for},
123      {OMPD_teams_distribute_parallel_for, OMPD_simd,
124       OMPD_teams_distribute_parallel_for_simd},
125      {OMPD_target, OMPD_teams, OMPD_target_teams},
126      {OMPD_target_teams, OMPD_distribute, OMPD_target_teams_distribute},
127      {OMPD_target_teams_distribute, OMPD_parallel,
128       OMPD_target_teams_distribute_parallel},
129      {OMPD_target_teams_distribute, OMPD_simd,
130       OMPD_target_teams_distribute_simd},
131      {OMPD_target_teams_distribute_parallel, OMPD_for,
132       OMPD_target_teams_distribute_parallel_for},
133      {OMPD_target_teams_distribute_parallel_for, OMPD_simd,
134       OMPD_target_teams_distribute_parallel_for_simd}};
135  enum { CancellationPoint = 0, DeclareReduction = 1, TargetData = 2 };
136  Token Tok = P.getCurToken();
137  unsigned DKind =
138      Tok.isAnnotation()
139          ? static_cast<unsigned>(OMPD_unknown)
140          : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
141  if (DKind == OMPD_unknown)
142    return OMPD_unknown;
143
144  for (unsigned I = 0; I < llvm::array_lengthof(F); ++I) {
145    if (DKind != F[I][0])
146      continue;
147
148    Tok = P.getPreprocessor().LookAhead(0);
149    unsigned SDKind =
150        Tok.isAnnotation()
151            ? static_cast<unsigned>(OMPD_unknown)
152            : getOpenMPDirectiveKindEx(P.getPreprocessor().getSpelling(Tok));
153    if (SDKind == OMPD_unknown)
154      continue;
155
156    if (SDKind == F[I][1]) {
157      P.ConsumeToken();
158      DKind = F[I][2];
159    }
160  }
161  return DKind < OMPD_unknown ? static_cast<OpenMPDirectiveKind>(DKind)
162                              : OMPD_unknown;
163}
164
165static DeclarationName parseOpenMPReductionId(Parser &P) {
166  Token Tok = P.getCurToken();
167  Sema &Actions = P.getActions();
168  OverloadedOperatorKind OOK = OO_None;
169  // Allow to use 'operator' keyword for C++ operators
170  bool WithOperator = false;
171  if (Tok.is(tok::kw_operator)) {
172    P.ConsumeToken();
173    Tok = P.getCurToken();
174    WithOperator = true;
175  }
176  switch (Tok.getKind()) {
177  case tok::plus: // '+'
178    OOK = OO_Plus;
179    break;
180  case tok::minus: // '-'
181    OOK = OO_Minus;
182    break;
183  case tok::star: // '*'
184    OOK = OO_Star;
185    break;
186  case tok::amp: // '&'
187    OOK = OO_Amp;
188    break;
189  case tok::pipe: // '|'
190    OOK = OO_Pipe;
191    break;
192  case tok::caret: // '^'
193    OOK = OO_Caret;
194    break;
195  case tok::ampamp: // '&&'
196    OOK = OO_AmpAmp;
197    break;
198  case tok::pipepipe: // '||'
199    OOK = OO_PipePipe;
200    break;
201  case tok::identifier: // identifier
202    if (!WithOperator)
203      break;
204    LLVM_FALLTHROUGH;
205  default:
206    P.Diag(Tok.getLocation(), diag::err_omp_expected_reduction_identifier);
207    P.SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
208                Parser::StopBeforeMatch);
209    return DeclarationName();
210  }
211  P.ConsumeToken();
212  auto &DeclNames = Actions.getASTContext().DeclarationNames;
213  return OOK == OO_None ? DeclNames.getIdentifier(Tok.getIdentifierInfo())
214                        : DeclNames.getCXXOperatorName(OOK);
215}
216
217/// Parse 'omp declare reduction' construct.
218///
219///       declare-reduction-directive:
220///        annot_pragma_openmp 'declare' 'reduction'
221///        '(' <reduction_id> ':' <type> {',' <type>} ':' <expression> ')'
222///        ['initializer' '(' ('omp_priv' '=' <expression>)|<function_call> ')']
223///        annot_pragma_openmp_end
224/// <reduction_id> is either a base language identifier or one of the following
225/// operators: '+', '-', '*', '&', '|', '^', '&&' and '||'.
226///
227Parser::DeclGroupPtrTy
228Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) {
229  // Parse '('.
230  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
231  if (T.expectAndConsume(diag::err_expected_lparen_after,
232                         getOpenMPDirectiveName(OMPD_declare_reduction))) {
233    SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
234    return DeclGroupPtrTy();
235  }
236
237  DeclarationName Name = parseOpenMPReductionId(*this);
238  if (Name.isEmpty() && Tok.is(tok::annot_pragma_openmp_end))
239    return DeclGroupPtrTy();
240
241  // Consume ':'.
242  bool IsCorrect = !ExpectAndConsume(tok::colon);
243
244  if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
245    return DeclGroupPtrTy();
246
247  IsCorrect = IsCorrect && !Name.isEmpty();
248
249  if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end)) {
250    Diag(Tok.getLocation(), diag::err_expected_type);
251    IsCorrect = false;
252  }
253
254  if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
255    return DeclGroupPtrTy();
256
257  SmallVector<std::pair<QualType, SourceLocation>, 8> ReductionTypes;
258  // Parse list of types until ':' token.
259  do {
260    ColonProtectionRAIIObject ColonRAII(*this);
261    SourceRange Range;
262    TypeResult TR =
263        ParseTypeName(&Range, DeclaratorContext::PrototypeContext, AS);
264    if (TR.isUsable()) {
265      QualType ReductionType =
266          Actions.ActOnOpenMPDeclareReductionType(Range.getBegin(), TR);
267      if (!ReductionType.isNull()) {
268        ReductionTypes.push_back(
269            std::make_pair(ReductionType, Range.getBegin()));
270      }
271    } else {
272      SkipUntil(tok::comma, tok::colon, tok::annot_pragma_openmp_end,
273                StopBeforeMatch);
274    }
275
276    if (Tok.is(tok::colon) || Tok.is(tok::annot_pragma_openmp_end))
277      break;
278
279    // Consume ','.
280    if (ExpectAndConsume(tok::comma)) {
281      IsCorrect = false;
282      if (Tok.is(tok::annot_pragma_openmp_end)) {
283        Diag(Tok.getLocation(), diag::err_expected_type);
284        return DeclGroupPtrTy();
285      }
286    }
287  } while (Tok.isNot(tok::annot_pragma_openmp_end));
288
289  if (ReductionTypes.empty()) {
290    SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
291    return DeclGroupPtrTy();
292  }
293
294  if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
295    return DeclGroupPtrTy();
296
297  // Consume ':'.
298  if (ExpectAndConsume(tok::colon))
299    IsCorrect = false;
300
301  if (Tok.is(tok::annot_pragma_openmp_end)) {
302    Diag(Tok.getLocation(), diag::err_expected_expression);
303    return DeclGroupPtrTy();
304  }
305
306  DeclGroupPtrTy DRD = Actions.ActOnOpenMPDeclareReductionDirectiveStart(
307      getCurScope(), Actions.getCurLexicalContext(), Name, ReductionTypes, AS);
308
309  // Parse <combiner> expression and then parse initializer if any for each
310  // correct type.
311  unsigned I = 0, E = ReductionTypes.size();
312  for (Decl *D : DRD.get()) {
313    TentativeParsingAction TPA(*this);
314    ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
315                                    Scope::CompoundStmtScope |
316                                    Scope::OpenMPDirectiveScope);
317    // Parse <combiner> expression.
318    Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D);
319    ExprResult CombinerResult =
320        Actions.ActOnFinishFullExpr(ParseAssignmentExpression().get(),
321                                    D->getLocation(), /*DiscardedValue*/ false);
322    Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get());
323
324    if (CombinerResult.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 = !T.consumeClose() && IsCorrect && CombinerResult.isUsable();
331    ExprResult InitializerResult;
332    if (Tok.isNot(tok::annot_pragma_openmp_end)) {
333      // Parse <initializer> expression.
334      if (Tok.is(tok::identifier) &&
335          Tok.getIdentifierInfo()->isStr("initializer")) {
336        ConsumeToken();
337      } else {
338        Diag(Tok.getLocation(), diag::err_expected) << "'initializer'";
339        TPA.Commit();
340        IsCorrect = false;
341        break;
342      }
343      // Parse '('.
344      BalancedDelimiterTracker T(*this, tok::l_paren,
345                                 tok::annot_pragma_openmp_end);
346      IsCorrect =
347          !T.expectAndConsume(diag::err_expected_lparen_after, "initializer") &&
348          IsCorrect;
349      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
350        ParseScope OMPDRScope(this, Scope::FnScope | Scope::DeclScope |
351                                        Scope::CompoundStmtScope |
352                                        Scope::OpenMPDirectiveScope);
353        // Parse expression.
354        VarDecl *OmpPrivParm =
355            Actions.ActOnOpenMPDeclareReductionInitializerStart(getCurScope(),
356                                                                D);
357        // Check if initializer is omp_priv <init_expr> or something else.
358        if (Tok.is(tok::identifier) &&
359            Tok.getIdentifierInfo()->isStr("omp_priv")) {
360          if (Actions.getLangOpts().CPlusPlus) {
361            InitializerResult = Actions.ActOnFinishFullExpr(
362                ParseAssignmentExpression().get(), D->getLocation(),
363                /*DiscardedValue*/ false);
364          } else {
365            ConsumeToken();
366            ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
367          }
368        } else {
369          InitializerResult = Actions.ActOnFinishFullExpr(
370              ParseAssignmentExpression().get(), D->getLocation(),
371              /*DiscardedValue*/ false);
372        }
373        Actions.ActOnOpenMPDeclareReductionInitializerEnd(
374            D, InitializerResult.get(), OmpPrivParm);
375        if (InitializerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
376            Tok.isNot(tok::annot_pragma_openmp_end)) {
377          TPA.Commit();
378          IsCorrect = false;
379          break;
380        }
381        IsCorrect =
382            !T.consumeClose() && IsCorrect && !InitializerResult.isInvalid();
383      }
384    }
385
386    ++I;
387    // Revert parsing if not the last type, otherwise accept it, we're done with
388    // parsing.
389    if (I != E)
390      TPA.Revert();
391    else
392      TPA.Commit();
393  }
394  return Actions.ActOnOpenMPDeclareReductionDirectiveEnd(getCurScope(), DRD,
395                                                         IsCorrect);
396}
397
398void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
399  // Parse declarator '=' initializer.
400  // If a '==' or '+=' is found, suggest a fixit to '='.
401  if (isTokenEqualOrEqualTypo()) {
402    ConsumeToken();
403
404    if (Tok.is(tok::code_completion)) {
405      Actions.CodeCompleteInitializer(getCurScope(), OmpPrivParm);
406      Actions.FinalizeDeclaration(OmpPrivParm);
407      cutOffParsing();
408      return;
409    }
410
411    ExprResult Init(ParseInitializer());
412
413    if (Init.isInvalid()) {
414      SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
415      Actions.ActOnInitializerError(OmpPrivParm);
416    } else {
417      Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
418                                   /*DirectInit=*/false);
419    }
420  } else if (Tok.is(tok::l_paren)) {
421    // Parse C++ direct initializer: '(' expression-list ')'
422    BalancedDelimiterTracker T(*this, tok::l_paren);
423    T.consumeOpen();
424
425    ExprVector Exprs;
426    CommaLocsTy CommaLocs;
427
428    SourceLocation LParLoc = T.getOpenLocation();
429    auto RunSignatureHelp = [this, OmpPrivParm, LParLoc, &Exprs]() {
430      QualType PreferredType = Actions.ProduceConstructorSignatureHelp(
431          getCurScope(), OmpPrivParm->getType()->getCanonicalTypeInternal(),
432          OmpPrivParm->getLocation(), Exprs, LParLoc);
433      CalledSignatureHelp = true;
434      return PreferredType;
435    };
436    if (ParseExpressionList(Exprs, CommaLocs, [&] {
437          PreferredType.enterFunctionArgument(Tok.getLocation(),
438                                              RunSignatureHelp);
439        })) {
440      if (PP.isCodeCompletionReached() && !CalledSignatureHelp)
441        RunSignatureHelp();
442      Actions.ActOnInitializerError(OmpPrivParm);
443      SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
444    } else {
445      // Match the ')'.
446      SourceLocation RLoc = Tok.getLocation();
447      if (!T.consumeClose())
448        RLoc = T.getCloseLocation();
449
450      assert(!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size() &&
451             "Unexpected number of commas!");
452
453      ExprResult Initializer =
454          Actions.ActOnParenListExpr(T.getOpenLocation(), RLoc, Exprs);
455      Actions.AddInitializerToDecl(OmpPrivParm, Initializer.get(),
456                                   /*DirectInit=*/true);
457    }
458  } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
459    // Parse C++0x braced-init-list.
460    Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
461
462    ExprResult Init(ParseBraceInitializer());
463
464    if (Init.isInvalid()) {
465      Actions.ActOnInitializerError(OmpPrivParm);
466    } else {
467      Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
468                                   /*DirectInit=*/true);
469    }
470  } else {
471    Actions.ActOnUninitializedDecl(OmpPrivParm);
472  }
473}
474
475/// Parses 'omp declare mapper' directive.
476///
477///       declare-mapper-directive:
478///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifier> ':']
479///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
480///         annot_pragma_openmp_end
481/// <mapper-identifier> and <var> are base language identifiers.
482///
483Parser::DeclGroupPtrTy
484Parser::ParseOpenMPDeclareMapperDirective(AccessSpecifier AS) {
485  bool IsCorrect = true;
486  // Parse '('
487  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
488  if (T.expectAndConsume(diag::err_expected_lparen_after,
489                         getOpenMPDirectiveName(OMPD_declare_mapper))) {
490    SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
491    return DeclGroupPtrTy();
492  }
493
494  // Parse <mapper-identifier>
495  auto &DeclNames = Actions.getASTContext().DeclarationNames;
496  DeclarationName MapperId;
497  if (PP.LookAhead(0).is(tok::colon)) {
498    if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
499      Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
500      IsCorrect = false;
501    } else {
502      MapperId = DeclNames.getIdentifier(Tok.getIdentifierInfo());
503    }
504    ConsumeToken();
505    // Consume ':'.
506    ExpectAndConsume(tok::colon);
507  } else {
508    // If no mapper identifier is provided, its name is "default" by default
509    MapperId =
510        DeclNames.getIdentifier(&Actions.getASTContext().Idents.get("default"));
511  }
512
513  if (!IsCorrect && Tok.is(tok::annot_pragma_openmp_end))
514    return DeclGroupPtrTy();
515
516  // Parse <type> <var>
517  DeclarationName VName;
518  QualType MapperType;
519  SourceRange Range;
520  TypeResult ParsedType = parseOpenMPDeclareMapperVarDecl(Range, VName, AS);
521  if (ParsedType.isUsable())
522    MapperType =
523        Actions.ActOnOpenMPDeclareMapperType(Range.getBegin(), ParsedType);
524  if (MapperType.isNull())
525    IsCorrect = false;
526  if (!IsCorrect) {
527    SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
528    return DeclGroupPtrTy();
529  }
530
531  // Consume ')'.
532  IsCorrect &= !T.consumeClose();
533  if (!IsCorrect) {
534    SkipUntil(tok::annot_pragma_openmp_end, Parser::StopBeforeMatch);
535    return DeclGroupPtrTy();
536  }
537
538  // Enter scope.
539  OMPDeclareMapperDecl *DMD = Actions.ActOnOpenMPDeclareMapperDirectiveStart(
540      getCurScope(), Actions.getCurLexicalContext(), MapperId, MapperType,
541      Range.getBegin(), VName, AS);
542  DeclarationNameInfo DirName;
543  SourceLocation Loc = Tok.getLocation();
544  unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
545                        Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
546  ParseScope OMPDirectiveScope(this, ScopeFlags);
547  Actions.StartOpenMPDSABlock(OMPD_declare_mapper, DirName, getCurScope(), Loc);
548
549  // Add the mapper variable declaration.
550  Actions.ActOnOpenMPDeclareMapperDirectiveVarDecl(
551      DMD, getCurScope(), MapperType, Range.getBegin(), VName);
552
553  // Parse map clauses.
554  SmallVector<OMPClause *, 6> Clauses;
555  while (Tok.isNot(tok::annot_pragma_openmp_end)) {
556    OpenMPClauseKind CKind = Tok.isAnnotation()
557                                 ? OMPC_unknown
558                                 : getOpenMPClauseKind(PP.getSpelling(Tok));
559    Actions.StartOpenMPClause(CKind);
560    OMPClause *Clause =
561        ParseOpenMPClause(OMPD_declare_mapper, CKind, Clauses.size() == 0);
562    if (Clause)
563      Clauses.push_back(Clause);
564    else
565      IsCorrect = false;
566    // Skip ',' if any.
567    if (Tok.is(tok::comma))
568      ConsumeToken();
569    Actions.EndOpenMPClause();
570  }
571  if (Clauses.empty()) {
572    Diag(Tok, diag::err_omp_expected_clause)
573        << getOpenMPDirectiveName(OMPD_declare_mapper);
574    IsCorrect = false;
575  }
576
577  // Exit scope.
578  Actions.EndOpenMPDSABlock(nullptr);
579  OMPDirectiveScope.Exit();
580
581  DeclGroupPtrTy DGP =
582      Actions.ActOnOpenMPDeclareMapperDirectiveEnd(DMD, getCurScope(), Clauses);
583  if (!IsCorrect)
584    return DeclGroupPtrTy();
585  return DGP;
586}
587
588TypeResult Parser::parseOpenMPDeclareMapperVarDecl(SourceRange &Range,
589                                                   DeclarationName &Name,
590                                                   AccessSpecifier AS) {
591  // Parse the common declaration-specifiers piece.
592  Parser::DeclSpecContext DSC = Parser::DeclSpecContext::DSC_type_specifier;
593  DeclSpec DS(AttrFactory);
594  ParseSpecifierQualifierList(DS, AS, DSC);
595
596  // Parse the declarator.
597  DeclaratorContext Context = DeclaratorContext::PrototypeContext;
598  Declarator DeclaratorInfo(DS, Context);
599  ParseDeclarator(DeclaratorInfo);
600  Range = DeclaratorInfo.getSourceRange();
601  if (DeclaratorInfo.getIdentifier() == nullptr) {
602    Diag(Tok.getLocation(), diag::err_omp_mapper_expected_declarator);
603    return true;
604  }
605  Name = Actions.GetNameForDeclarator(DeclaratorInfo).getName();
606
607  return Actions.ActOnOpenMPDeclareMapperVarDecl(getCurScope(), DeclaratorInfo);
608}
609
610namespace {
611/// RAII that recreates function context for correct parsing of clauses of
612/// 'declare simd' construct.
613/// OpenMP, 2.8.2 declare simd Construct
614/// The expressions appearing in the clauses of this directive are evaluated in
615/// the scope of the arguments of the function declaration or definition.
616class FNContextRAII final {
617  Parser &P;
618  Sema::CXXThisScopeRAII *ThisScope;
619  Parser::ParseScope *TempScope;
620  Parser::ParseScope *FnScope;
621  bool HasTemplateScope = false;
622  bool HasFunScope = false;
623  FNContextRAII() = delete;
624  FNContextRAII(const FNContextRAII &) = delete;
625  FNContextRAII &operator=(const FNContextRAII &) = delete;
626
627public:
628  FNContextRAII(Parser &P, Parser::DeclGroupPtrTy Ptr) : P(P) {
629    Decl *D = *Ptr.get().begin();
630    NamedDecl *ND = dyn_cast<NamedDecl>(D);
631    RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
632    Sema &Actions = P.getActions();
633
634    // Allow 'this' within late-parsed attributes.
635    ThisScope = new Sema::CXXThisScopeRAII(Actions, RD, Qualifiers(),
636                                           ND && ND->isCXXInstanceMember());
637
638    // If the Decl is templatized, add template parameters to scope.
639    HasTemplateScope = D->isTemplateDecl();
640    TempScope =
641        new Parser::ParseScope(&P, Scope::TemplateParamScope, HasTemplateScope);
642    if (HasTemplateScope)
643      Actions.ActOnReenterTemplateScope(Actions.getCurScope(), D);
644
645    // If the Decl is on a function, add function parameters to the scope.
646    HasFunScope = D->isFunctionOrFunctionTemplate();
647    FnScope = new Parser::ParseScope(
648        &P, Scope::FnScope | Scope::DeclScope | Scope::CompoundStmtScope,
649        HasFunScope);
650    if (HasFunScope)
651      Actions.ActOnReenterFunctionContext(Actions.getCurScope(), D);
652  }
653  ~FNContextRAII() {
654    if (HasFunScope) {
655      P.getActions().ActOnExitFunctionContext();
656      FnScope->Exit(); // Pop scope, and remove Decls from IdResolver
657    }
658    if (HasTemplateScope)
659      TempScope->Exit();
660    delete FnScope;
661    delete TempScope;
662    delete ThisScope;
663  }
664};
665} // namespace
666
667/// Parses clauses for 'declare simd' directive.
668///    clause:
669///      'inbranch' | 'notinbranch'
670///      'simdlen' '(' <expr> ')'
671///      { 'uniform' '(' <argument_list> ')' }
672///      { 'aligned '(' <argument_list> [ ':' <alignment> ] ')' }
673///      { 'linear '(' <argument_list> [ ':' <step> ] ')' }
674static bool parseDeclareSimdClauses(
675    Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, ExprResult &SimdLen,
676    SmallVectorImpl<Expr *> &Uniforms, SmallVectorImpl<Expr *> &Aligneds,
677    SmallVectorImpl<Expr *> &Alignments, SmallVectorImpl<Expr *> &Linears,
678    SmallVectorImpl<unsigned> &LinModifiers, SmallVectorImpl<Expr *> &Steps) {
679  SourceRange BSRange;
680  const Token &Tok = P.getCurToken();
681  bool IsError = false;
682  while (Tok.isNot(tok::annot_pragma_openmp_end)) {
683    if (Tok.isNot(tok::identifier))
684      break;
685    OMPDeclareSimdDeclAttr::BranchStateTy Out;
686    IdentifierInfo *II = Tok.getIdentifierInfo();
687    StringRef ClauseName = II->getName();
688    // Parse 'inranch|notinbranch' clauses.
689    if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
690      if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
691        P.Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
692            << ClauseName
693            << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
694        IsError = true;
695      }
696      BS = Out;
697      BSRange = SourceRange(Tok.getLocation(), Tok.getEndLoc());
698      P.ConsumeToken();
699    } else if (ClauseName.equals("simdlen")) {
700      if (SimdLen.isUsable()) {
701        P.Diag(Tok, diag::err_omp_more_one_clause)
702            << getOpenMPDirectiveName(OMPD_declare_simd) << ClauseName << 0;
703        IsError = true;
704      }
705      P.ConsumeToken();
706      SourceLocation RLoc;
707      SimdLen = P.ParseOpenMPParensExpr(ClauseName, RLoc);
708      if (SimdLen.isInvalid())
709        IsError = true;
710    } else {
711      OpenMPClauseKind CKind = getOpenMPClauseKind(ClauseName);
712      if (CKind == OMPC_uniform || CKind == OMPC_aligned ||
713          CKind == OMPC_linear) {
714        Parser::OpenMPVarListDataTy Data;
715        SmallVectorImpl<Expr *> *Vars = &Uniforms;
716        if (CKind == OMPC_aligned)
717          Vars = &Aligneds;
718        else if (CKind == OMPC_linear)
719          Vars = &Linears;
720
721        P.ConsumeToken();
722        if (P.ParseOpenMPVarList(OMPD_declare_simd,
723                                 getOpenMPClauseKind(ClauseName), *Vars, Data))
724          IsError = true;
725        if (CKind == OMPC_aligned) {
726          Alignments.append(Aligneds.size() - Alignments.size(), Data.TailExpr);
727        } else if (CKind == OMPC_linear) {
728          if (P.getActions().CheckOpenMPLinearModifier(Data.LinKind,
729                                                       Data.DepLinMapLoc))
730            Data.LinKind = OMPC_LINEAR_val;
731          LinModifiers.append(Linears.size() - LinModifiers.size(),
732                              Data.LinKind);
733          Steps.append(Linears.size() - Steps.size(), Data.TailExpr);
734        }
735      } else
736        // TODO: add parsing of other clauses.
737        break;
738    }
739    // Skip ',' if any.
740    if (Tok.is(tok::comma))
741      P.ConsumeToken();
742  }
743  return IsError;
744}
745
746/// Parse clauses for '#pragma omp declare simd'.
747Parser::DeclGroupPtrTy
748Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
749                                   CachedTokens &Toks, SourceLocation Loc) {
750  PP.EnterToken(Tok, /*IsReinject*/ true);
751  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true,
752                      /*IsReinject*/ true);
753  // Consume the previously pushed token.
754  ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
755
756  FNContextRAII FnContext(*this, Ptr);
757  OMPDeclareSimdDeclAttr::BranchStateTy BS =
758      OMPDeclareSimdDeclAttr::BS_Undefined;
759  ExprResult Simdlen;
760  SmallVector<Expr *, 4> Uniforms;
761  SmallVector<Expr *, 4> Aligneds;
762  SmallVector<Expr *, 4> Alignments;
763  SmallVector<Expr *, 4> Linears;
764  SmallVector<unsigned, 4> LinModifiers;
765  SmallVector<Expr *, 4> Steps;
766  bool IsError =
767      parseDeclareSimdClauses(*this, BS, Simdlen, Uniforms, Aligneds,
768                              Alignments, Linears, LinModifiers, Steps);
769  // Need to check for extra tokens.
770  if (Tok.isNot(tok::annot_pragma_openmp_end)) {
771    Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
772        << getOpenMPDirectiveName(OMPD_declare_simd);
773    while (Tok.isNot(tok::annot_pragma_openmp_end))
774      ConsumeAnyToken();
775  }
776  // Skip the last annot_pragma_openmp_end.
777  SourceLocation EndLoc = ConsumeAnnotationToken();
778  if (IsError)
779    return Ptr;
780  return Actions.ActOnOpenMPDeclareSimdDirective(
781      Ptr, BS, Simdlen.get(), Uniforms, Aligneds, Alignments, Linears,
782      LinModifiers, Steps, SourceRange(Loc, EndLoc));
783}
784
785Parser::DeclGroupPtrTy Parser::ParseOMPDeclareTargetClauses() {
786  // OpenMP 4.5 syntax with list of entities.
787  Sema::NamedDeclSetType SameDirectiveDecls;
788  while (Tok.isNot(tok::annot_pragma_openmp_end)) {
789    OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
790    if (Tok.is(tok::identifier)) {
791      IdentifierInfo *II = Tok.getIdentifierInfo();
792      StringRef ClauseName = II->getName();
793      // Parse 'to|link' clauses.
794      if (!OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT)) {
795        Diag(Tok, diag::err_omp_declare_target_unexpected_clause) << ClauseName;
796        break;
797      }
798      ConsumeToken();
799    }
800    auto &&Callback = [this, MT, &SameDirectiveDecls](
801        CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
802      Actions.ActOnOpenMPDeclareTargetName(getCurScope(), SS, NameInfo, MT,
803                                           SameDirectiveDecls);
804    };
805    if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
806                                 /*AllowScopeSpecifier=*/true))
807      break;
808
809    // Consume optional ','.
810    if (Tok.is(tok::comma))
811      ConsumeToken();
812  }
813  SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
814  ConsumeAnyToken();
815  SmallVector<Decl *, 4> Decls(SameDirectiveDecls.begin(),
816                               SameDirectiveDecls.end());
817  if (Decls.empty())
818    return DeclGroupPtrTy();
819  return Actions.BuildDeclaratorGroup(Decls);
820}
821
822void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind DKind,
823                                               SourceLocation DTLoc) {
824  if (DKind != OMPD_end_declare_target) {
825    Diag(Tok, diag::err_expected_end_declare_target);
826    Diag(DTLoc, diag::note_matching) << "'#pragma omp declare target'";
827    return;
828  }
829  ConsumeAnyToken();
830  if (Tok.isNot(tok::annot_pragma_openmp_end)) {
831    Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
832        << getOpenMPDirectiveName(OMPD_end_declare_target);
833    SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
834  }
835  // Skip the last annot_pragma_openmp_end.
836  ConsumeAnyToken();
837}
838
839/// Parsing of declarative OpenMP directives.
840///
841///       threadprivate-directive:
842///         annot_pragma_openmp 'threadprivate' simple-variable-list
843///         annot_pragma_openmp_end
844///
845///       allocate-directive:
846///         annot_pragma_openmp 'allocate' simple-variable-list [<clause>]
847///         annot_pragma_openmp_end
848///
849///       declare-reduction-directive:
850///        annot_pragma_openmp 'declare' 'reduction' [...]
851///        annot_pragma_openmp_end
852///
853///       declare-mapper-directive:
854///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
855///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
856///         annot_pragma_openmp_end
857///
858///       declare-simd-directive:
859///         annot_pragma_openmp 'declare simd' {<clause> [,]}
860///         annot_pragma_openmp_end
861///         <function declaration/definition>
862///
863///       requires directive:
864///         annot_pragma_openmp 'requires' <clause> [[[,] <clause>] ... ]
865///         annot_pragma_openmp_end
866///
867Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
868    AccessSpecifier &AS, ParsedAttributesWithRange &Attrs,
869    DeclSpec::TST TagType, Decl *Tag) {
870  assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
871  ParenBraceBracketBalancer BalancerRAIIObj(*this);
872
873  SourceLocation Loc = ConsumeAnnotationToken();
874  OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
875
876  switch (DKind) {
877  case OMPD_threadprivate: {
878    ConsumeToken();
879    DeclDirectiveListParserHelper Helper(this, DKind);
880    if (!ParseOpenMPSimpleVarList(DKind, Helper,
881                                  /*AllowScopeSpecifier=*/true)) {
882      // The last seen token is annot_pragma_openmp_end - need to check for
883      // extra tokens.
884      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
885        Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
886            << getOpenMPDirectiveName(DKind);
887        SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
888      }
889      // Skip the last annot_pragma_openmp_end.
890      ConsumeAnnotationToken();
891      return Actions.ActOnOpenMPThreadprivateDirective(Loc,
892                                                       Helper.getIdentifiers());
893    }
894    break;
895  }
896  case OMPD_allocate: {
897    ConsumeToken();
898    DeclDirectiveListParserHelper Helper(this, DKind);
899    if (!ParseOpenMPSimpleVarList(DKind, Helper,
900                                  /*AllowScopeSpecifier=*/true)) {
901      SmallVector<OMPClause *, 1> Clauses;
902      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
903        SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
904                    OMPC_unknown + 1>
905            FirstClauses(OMPC_unknown + 1);
906        while (Tok.isNot(tok::annot_pragma_openmp_end)) {
907          OpenMPClauseKind CKind =
908              Tok.isAnnotation() ? OMPC_unknown
909                                 : getOpenMPClauseKind(PP.getSpelling(Tok));
910          Actions.StartOpenMPClause(CKind);
911          OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
912                                                !FirstClauses[CKind].getInt());
913          SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
914                    StopBeforeMatch);
915          FirstClauses[CKind].setInt(true);
916          if (Clause != nullptr)
917            Clauses.push_back(Clause);
918          if (Tok.is(tok::annot_pragma_openmp_end)) {
919            Actions.EndOpenMPClause();
920            break;
921          }
922          // Skip ',' if any.
923          if (Tok.is(tok::comma))
924            ConsumeToken();
925          Actions.EndOpenMPClause();
926        }
927        // The last seen token is annot_pragma_openmp_end - need to check for
928        // extra tokens.
929        if (Tok.isNot(tok::annot_pragma_openmp_end)) {
930          Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
931              << getOpenMPDirectiveName(DKind);
932          SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
933        }
934      }
935      // Skip the last annot_pragma_openmp_end.
936      ConsumeAnnotationToken();
937      return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers(),
938                                                  Clauses);
939    }
940    break;
941  }
942  case OMPD_requires: {
943    SourceLocation StartLoc = ConsumeToken();
944    SmallVector<OMPClause *, 5> Clauses;
945    SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
946    FirstClauses(OMPC_unknown + 1);
947    if (Tok.is(tok::annot_pragma_openmp_end)) {
948      Diag(Tok, diag::err_omp_expected_clause)
949          << getOpenMPDirectiveName(OMPD_requires);
950      break;
951    }
952    while (Tok.isNot(tok::annot_pragma_openmp_end)) {
953      OpenMPClauseKind CKind = Tok.isAnnotation()
954                                   ? OMPC_unknown
955                                   : getOpenMPClauseKind(PP.getSpelling(Tok));
956      Actions.StartOpenMPClause(CKind);
957      OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind,
958                                            !FirstClauses[CKind].getInt());
959      SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
960                StopBeforeMatch);
961      FirstClauses[CKind].setInt(true);
962      if (Clause != nullptr)
963        Clauses.push_back(Clause);
964      if (Tok.is(tok::annot_pragma_openmp_end)) {
965        Actions.EndOpenMPClause();
966        break;
967      }
968      // Skip ',' if any.
969      if (Tok.is(tok::comma))
970        ConsumeToken();
971      Actions.EndOpenMPClause();
972    }
973    // Consume final annot_pragma_openmp_end
974    if (Clauses.size() == 0) {
975      Diag(Tok, diag::err_omp_expected_clause)
976          << getOpenMPDirectiveName(OMPD_requires);
977      ConsumeAnnotationToken();
978      return nullptr;
979    }
980    ConsumeAnnotationToken();
981    return Actions.ActOnOpenMPRequiresDirective(StartLoc, Clauses);
982  }
983  case OMPD_declare_reduction:
984    ConsumeToken();
985    if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
986      // The last seen token is annot_pragma_openmp_end - need to check for
987      // extra tokens.
988      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
989        Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
990            << getOpenMPDirectiveName(OMPD_declare_reduction);
991        while (Tok.isNot(tok::annot_pragma_openmp_end))
992          ConsumeAnyToken();
993      }
994      // Skip the last annot_pragma_openmp_end.
995      ConsumeAnnotationToken();
996      return Res;
997    }
998    break;
999  case OMPD_declare_mapper: {
1000    ConsumeToken();
1001    if (DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
1002      // Skip the last annot_pragma_openmp_end.
1003      ConsumeAnnotationToken();
1004      return Res;
1005    }
1006    break;
1007  }
1008  case OMPD_declare_simd: {
1009    // The syntax is:
1010    // { #pragma omp declare simd }
1011    // <function-declaration-or-definition>
1012    //
1013    ConsumeToken();
1014    CachedTokens Toks;
1015    while(Tok.isNot(tok::annot_pragma_openmp_end)) {
1016      Toks.push_back(Tok);
1017      ConsumeAnyToken();
1018    }
1019    Toks.push_back(Tok);
1020    ConsumeAnyToken();
1021
1022    DeclGroupPtrTy Ptr;
1023    if (Tok.is(tok::annot_pragma_openmp)) {
1024      Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, TagType, Tag);
1025    } else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
1026      // Here we expect to see some function declaration.
1027      if (AS == AS_none) {
1028        assert(TagType == DeclSpec::TST_unspecified);
1029        MaybeParseCXX11Attributes(Attrs);
1030        ParsingDeclSpec PDS(*this);
1031        Ptr = ParseExternalDeclaration(Attrs, &PDS);
1032      } else {
1033        Ptr =
1034            ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
1035      }
1036    }
1037    if (!Ptr) {
1038      Diag(Loc, diag::err_omp_decl_in_declare_simd);
1039      return DeclGroupPtrTy();
1040    }
1041    return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
1042  }
1043  case OMPD_declare_target: {
1044    SourceLocation DTLoc = ConsumeAnyToken();
1045    if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1046      return ParseOMPDeclareTargetClauses();
1047    }
1048
1049    // Skip the last annot_pragma_openmp_end.
1050    ConsumeAnyToken();
1051
1052    if (!Actions.ActOnStartOpenMPDeclareTargetDirective(DTLoc))
1053      return DeclGroupPtrTy();
1054
1055    llvm::SmallVector<Decl *, 4>  Decls;
1056    DKind = parseOpenMPDirectiveKind(*this);
1057    while (DKind != OMPD_end_declare_target && Tok.isNot(tok::eof) &&
1058           Tok.isNot(tok::r_brace)) {
1059      DeclGroupPtrTy Ptr;
1060      // Here we expect to see some function declaration.
1061      if (AS == AS_none) {
1062        assert(TagType == DeclSpec::TST_unspecified);
1063        MaybeParseCXX11Attributes(Attrs);
1064        ParsingDeclSpec PDS(*this);
1065        Ptr = ParseExternalDeclaration(Attrs, &PDS);
1066      } else {
1067        Ptr =
1068            ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
1069      }
1070      if (Ptr) {
1071        DeclGroupRef Ref = Ptr.get();
1072        Decls.append(Ref.begin(), Ref.end());
1073      }
1074      if (Tok.isAnnotation() && Tok.is(tok::annot_pragma_openmp)) {
1075        TentativeParsingAction TPA(*this);
1076        ConsumeAnnotationToken();
1077        DKind = parseOpenMPDirectiveKind(*this);
1078        if (DKind != OMPD_end_declare_target)
1079          TPA.Revert();
1080        else
1081          TPA.Commit();
1082      }
1083    }
1084
1085    ParseOMPEndDeclareTargetDirective(DKind, DTLoc);
1086    Actions.ActOnFinishOpenMPDeclareTargetDirective();
1087    return Actions.BuildDeclaratorGroup(Decls);
1088  }
1089  case OMPD_unknown:
1090    Diag(Tok, diag::err_omp_unknown_directive);
1091    break;
1092  case OMPD_parallel:
1093  case OMPD_simd:
1094  case OMPD_task:
1095  case OMPD_taskyield:
1096  case OMPD_barrier:
1097  case OMPD_taskwait:
1098  case OMPD_taskgroup:
1099  case OMPD_flush:
1100  case OMPD_for:
1101  case OMPD_for_simd:
1102  case OMPD_sections:
1103  case OMPD_section:
1104  case OMPD_single:
1105  case OMPD_master:
1106  case OMPD_ordered:
1107  case OMPD_critical:
1108  case OMPD_parallel_for:
1109  case OMPD_parallel_for_simd:
1110  case OMPD_parallel_sections:
1111  case OMPD_atomic:
1112  case OMPD_target:
1113  case OMPD_teams:
1114  case OMPD_cancellation_point:
1115  case OMPD_cancel:
1116  case OMPD_target_data:
1117  case OMPD_target_enter_data:
1118  case OMPD_target_exit_data:
1119  case OMPD_target_parallel:
1120  case OMPD_target_parallel_for:
1121  case OMPD_taskloop:
1122  case OMPD_taskloop_simd:
1123  case OMPD_distribute:
1124  case OMPD_end_declare_target:
1125  case OMPD_target_update:
1126  case OMPD_distribute_parallel_for:
1127  case OMPD_distribute_parallel_for_simd:
1128  case OMPD_distribute_simd:
1129  case OMPD_target_parallel_for_simd:
1130  case OMPD_target_simd:
1131  case OMPD_teams_distribute:
1132  case OMPD_teams_distribute_simd:
1133  case OMPD_teams_distribute_parallel_for_simd:
1134  case OMPD_teams_distribute_parallel_for:
1135  case OMPD_target_teams:
1136  case OMPD_target_teams_distribute:
1137  case OMPD_target_teams_distribute_parallel_for:
1138  case OMPD_target_teams_distribute_parallel_for_simd:
1139  case OMPD_target_teams_distribute_simd:
1140    Diag(Tok, diag::err_omp_unexpected_directive)
1141        << 1 << getOpenMPDirectiveName(DKind);
1142    break;
1143  }
1144  while (Tok.isNot(tok::annot_pragma_openmp_end))
1145    ConsumeAnyToken();
1146  ConsumeAnyToken();
1147  return nullptr;
1148}
1149
1150/// Parsing of declarative or executable OpenMP directives.
1151///
1152///       threadprivate-directive:
1153///         annot_pragma_openmp 'threadprivate' simple-variable-list
1154///         annot_pragma_openmp_end
1155///
1156///       allocate-directive:
1157///         annot_pragma_openmp 'allocate' simple-variable-list
1158///         annot_pragma_openmp_end
1159///
1160///       declare-reduction-directive:
1161///         annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
1162///         <type> {',' <type>} ':' <expression> ')' ['initializer' '('
1163///         ('omp_priv' '=' <expression>|<function_call>) ')']
1164///         annot_pragma_openmp_end
1165///
1166///       declare-mapper-directive:
1167///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
1168///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
1169///         annot_pragma_openmp_end
1170///
1171///       executable-directive:
1172///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
1173///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
1174///         'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
1175///         'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' |
1176///         'for simd' | 'parallel for simd' | 'target' | 'target data' |
1177///         'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
1178///         'distribute' | 'target enter data' | 'target exit data' |
1179///         'target parallel' | 'target parallel for' |
1180///         'target update' | 'distribute parallel for' |
1181///         'distribute paralle for simd' | 'distribute simd' |
1182///         'target parallel for simd' | 'target simd' |
1183///         'teams distribute' | 'teams distribute simd' |
1184///         'teams distribute parallel for simd' |
1185///         'teams distribute parallel for' | 'target teams' |
1186///         'target teams distribute' |
1187///         'target teams distribute parallel for' |
1188///         'target teams distribute parallel for simd' |
1189///         'target teams distribute simd' {clause}
1190///         annot_pragma_openmp_end
1191///
1192StmtResult
1193Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
1194  assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
1195  ParenBraceBracketBalancer BalancerRAIIObj(*this);
1196  SmallVector<OMPClause *, 5> Clauses;
1197  SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, OMPC_unknown + 1>
1198  FirstClauses(OMPC_unknown + 1);
1199  unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
1200                        Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
1201  SourceLocation Loc = ConsumeAnnotationToken(), EndLoc;
1202  OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
1203  OpenMPDirectiveKind CancelRegion = OMPD_unknown;
1204  // Name of critical directive.
1205  DeclarationNameInfo DirName;
1206  StmtResult Directive = StmtError();
1207  bool HasAssociatedStatement = true;
1208  bool FlushHasClause = false;
1209
1210  switch (DKind) {
1211  case OMPD_threadprivate: {
1212    // FIXME: Should this be permitted in C++?
1213    if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
1214        ParsedStmtContext()) {
1215      Diag(Tok, diag::err_omp_immediate_directive)
1216          << getOpenMPDirectiveName(DKind) << 0;
1217    }
1218    ConsumeToken();
1219    DeclDirectiveListParserHelper Helper(this, DKind);
1220    if (!ParseOpenMPSimpleVarList(DKind, Helper,
1221                                  /*AllowScopeSpecifier=*/false)) {
1222      // The last seen token is annot_pragma_openmp_end - need to check for
1223      // extra tokens.
1224      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1225        Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1226            << getOpenMPDirectiveName(DKind);
1227        SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1228      }
1229      DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
1230          Loc, Helper.getIdentifiers());
1231      Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
1232    }
1233    SkipUntil(tok::annot_pragma_openmp_end);
1234    break;
1235  }
1236  case OMPD_allocate: {
1237    // FIXME: Should this be permitted in C++?
1238    if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
1239        ParsedStmtContext()) {
1240      Diag(Tok, diag::err_omp_immediate_directive)
1241          << getOpenMPDirectiveName(DKind) << 0;
1242    }
1243    ConsumeToken();
1244    DeclDirectiveListParserHelper Helper(this, DKind);
1245    if (!ParseOpenMPSimpleVarList(DKind, Helper,
1246                                  /*AllowScopeSpecifier=*/false)) {
1247      SmallVector<OMPClause *, 1> Clauses;
1248      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1249        SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>,
1250                    OMPC_unknown + 1>
1251            FirstClauses(OMPC_unknown + 1);
1252        while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1253          OpenMPClauseKind CKind =
1254              Tok.isAnnotation() ? OMPC_unknown
1255                                 : getOpenMPClauseKind(PP.getSpelling(Tok));
1256          Actions.StartOpenMPClause(CKind);
1257          OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
1258                                                !FirstClauses[CKind].getInt());
1259          SkipUntil(tok::comma, tok::identifier, tok::annot_pragma_openmp_end,
1260                    StopBeforeMatch);
1261          FirstClauses[CKind].setInt(true);
1262          if (Clause != nullptr)
1263            Clauses.push_back(Clause);
1264          if (Tok.is(tok::annot_pragma_openmp_end)) {
1265            Actions.EndOpenMPClause();
1266            break;
1267          }
1268          // Skip ',' if any.
1269          if (Tok.is(tok::comma))
1270            ConsumeToken();
1271          Actions.EndOpenMPClause();
1272        }
1273        // The last seen token is annot_pragma_openmp_end - need to check for
1274        // extra tokens.
1275        if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1276          Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1277              << getOpenMPDirectiveName(DKind);
1278          SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1279        }
1280      }
1281      DeclGroupPtrTy Res = Actions.ActOnOpenMPAllocateDirective(
1282          Loc, Helper.getIdentifiers(), Clauses);
1283      Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
1284    }
1285    SkipUntil(tok::annot_pragma_openmp_end);
1286    break;
1287  }
1288  case OMPD_declare_reduction:
1289    ConsumeToken();
1290    if (DeclGroupPtrTy Res =
1291            ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
1292      // The last seen token is annot_pragma_openmp_end - need to check for
1293      // extra tokens.
1294      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1295        Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1296            << getOpenMPDirectiveName(OMPD_declare_reduction);
1297        while (Tok.isNot(tok::annot_pragma_openmp_end))
1298          ConsumeAnyToken();
1299      }
1300      ConsumeAnyToken();
1301      Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
1302    } else {
1303      SkipUntil(tok::annot_pragma_openmp_end);
1304    }
1305    break;
1306  case OMPD_declare_mapper: {
1307    ConsumeToken();
1308    if (DeclGroupPtrTy Res =
1309            ParseOpenMPDeclareMapperDirective(/*AS=*/AS_none)) {
1310      // Skip the last annot_pragma_openmp_end.
1311      ConsumeAnnotationToken();
1312      Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
1313    } else {
1314      SkipUntil(tok::annot_pragma_openmp_end);
1315    }
1316    break;
1317  }
1318  case OMPD_flush:
1319    if (PP.LookAhead(0).is(tok::l_paren)) {
1320      FlushHasClause = true;
1321      // Push copy of the current token back to stream to properly parse
1322      // pseudo-clause OMPFlushClause.
1323      PP.EnterToken(Tok, /*IsReinject*/ true);
1324    }
1325    LLVM_FALLTHROUGH;
1326  case OMPD_taskyield:
1327  case OMPD_barrier:
1328  case OMPD_taskwait:
1329  case OMPD_cancellation_point:
1330  case OMPD_cancel:
1331  case OMPD_target_enter_data:
1332  case OMPD_target_exit_data:
1333  case OMPD_target_update:
1334    if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
1335        ParsedStmtContext()) {
1336      Diag(Tok, diag::err_omp_immediate_directive)
1337          << getOpenMPDirectiveName(DKind) << 0;
1338    }
1339    HasAssociatedStatement = false;
1340    // Fall through for further analysis.
1341    LLVM_FALLTHROUGH;
1342  case OMPD_parallel:
1343  case OMPD_simd:
1344  case OMPD_for:
1345  case OMPD_for_simd:
1346  case OMPD_sections:
1347  case OMPD_single:
1348  case OMPD_section:
1349  case OMPD_master:
1350  case OMPD_critical:
1351  case OMPD_parallel_for:
1352  case OMPD_parallel_for_simd:
1353  case OMPD_parallel_sections:
1354  case OMPD_task:
1355  case OMPD_ordered:
1356  case OMPD_atomic:
1357  case OMPD_target:
1358  case OMPD_teams:
1359  case OMPD_taskgroup:
1360  case OMPD_target_data:
1361  case OMPD_target_parallel:
1362  case OMPD_target_parallel_for:
1363  case OMPD_taskloop:
1364  case OMPD_taskloop_simd:
1365  case OMPD_distribute:
1366  case OMPD_distribute_parallel_for:
1367  case OMPD_distribute_parallel_for_simd:
1368  case OMPD_distribute_simd:
1369  case OMPD_target_parallel_for_simd:
1370  case OMPD_target_simd:
1371  case OMPD_teams_distribute:
1372  case OMPD_teams_distribute_simd:
1373  case OMPD_teams_distribute_parallel_for_simd:
1374  case OMPD_teams_distribute_parallel_for:
1375  case OMPD_target_teams:
1376  case OMPD_target_teams_distribute:
1377  case OMPD_target_teams_distribute_parallel_for:
1378  case OMPD_target_teams_distribute_parallel_for_simd:
1379  case OMPD_target_teams_distribute_simd: {
1380    ConsumeToken();
1381    // Parse directive name of the 'critical' directive if any.
1382    if (DKind == OMPD_critical) {
1383      BalancedDelimiterTracker T(*this, tok::l_paren,
1384                                 tok::annot_pragma_openmp_end);
1385      if (!T.consumeOpen()) {
1386        if (Tok.isAnyIdentifier()) {
1387          DirName =
1388              DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
1389          ConsumeAnyToken();
1390        } else {
1391          Diag(Tok, diag::err_omp_expected_identifier_for_critical);
1392        }
1393        T.consumeClose();
1394      }
1395    } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
1396      CancelRegion = parseOpenMPDirectiveKind(*this);
1397      if (Tok.isNot(tok::annot_pragma_openmp_end))
1398        ConsumeToken();
1399    }
1400
1401    if (isOpenMPLoopDirective(DKind))
1402      ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
1403    if (isOpenMPSimdDirective(DKind))
1404      ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
1405    ParseScope OMPDirectiveScope(this, ScopeFlags);
1406    Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
1407
1408    while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1409      OpenMPClauseKind CKind =
1410          Tok.isAnnotation()
1411              ? OMPC_unknown
1412              : FlushHasClause ? OMPC_flush
1413                               : getOpenMPClauseKind(PP.getSpelling(Tok));
1414      Actions.StartOpenMPClause(CKind);
1415      FlushHasClause = false;
1416      OMPClause *Clause =
1417          ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
1418      FirstClauses[CKind].setInt(true);
1419      if (Clause) {
1420        FirstClauses[CKind].setPointer(Clause);
1421        Clauses.push_back(Clause);
1422      }
1423
1424      // Skip ',' if any.
1425      if (Tok.is(tok::comma))
1426        ConsumeToken();
1427      Actions.EndOpenMPClause();
1428    }
1429    // End location of the directive.
1430    EndLoc = Tok.getLocation();
1431    // Consume final annot_pragma_openmp_end.
1432    ConsumeAnnotationToken();
1433
1434    // OpenMP [2.13.8, ordered Construct, Syntax]
1435    // If the depend clause is specified, the ordered construct is a stand-alone
1436    // directive.
1437    if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) {
1438      if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
1439          ParsedStmtContext()) {
1440        Diag(Loc, diag::err_omp_immediate_directive)
1441            << getOpenMPDirectiveName(DKind) << 1
1442            << getOpenMPClauseName(OMPC_depend);
1443      }
1444      HasAssociatedStatement = false;
1445    }
1446
1447    StmtResult AssociatedStmt;
1448    if (HasAssociatedStatement) {
1449      // The body is a block scope like in Lambdas and Blocks.
1450      Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
1451      // FIXME: We create a bogus CompoundStmt scope to hold the contents of
1452      // the captured region. Code elsewhere assumes that any FunctionScopeInfo
1453      // should have at least one compound statement scope within it.
1454      AssociatedStmt = (Sema::CompoundScopeRAII(Actions), ParseStatement());
1455      AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
1456    } else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
1457               DKind == OMPD_target_exit_data) {
1458      Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
1459      AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
1460                        Actions.ActOnCompoundStmt(Loc, Loc, llvm::None,
1461                                                  /*isStmtExpr=*/false));
1462      AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
1463    }
1464    Directive = Actions.ActOnOpenMPExecutableDirective(
1465        DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
1466        EndLoc);
1467
1468    // Exit scope.
1469    Actions.EndOpenMPDSABlock(Directive.get());
1470    OMPDirectiveScope.Exit();
1471    break;
1472  }
1473  case OMPD_declare_simd:
1474  case OMPD_declare_target:
1475  case OMPD_end_declare_target:
1476  case OMPD_requires:
1477    Diag(Tok, diag::err_omp_unexpected_directive)
1478        << 1 << getOpenMPDirectiveName(DKind);
1479    SkipUntil(tok::annot_pragma_openmp_end);
1480    break;
1481  case OMPD_unknown:
1482    Diag(Tok, diag::err_omp_unknown_directive);
1483    SkipUntil(tok::annot_pragma_openmp_end);
1484    break;
1485  }
1486  return Directive;
1487}
1488
1489// Parses simple list:
1490//   simple-variable-list:
1491//         '(' id-expression {, id-expression} ')'
1492//
1493bool Parser::ParseOpenMPSimpleVarList(
1494    OpenMPDirectiveKind Kind,
1495    const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> &
1496        Callback,
1497    bool AllowScopeSpecifier) {
1498  // Parse '('.
1499  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1500  if (T.expectAndConsume(diag::err_expected_lparen_after,
1501                         getOpenMPDirectiveName(Kind)))
1502    return true;
1503  bool IsCorrect = true;
1504  bool NoIdentIsFound = true;
1505
1506  // Read tokens while ')' or annot_pragma_openmp_end is not found.
1507  while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
1508    CXXScopeSpec SS;
1509    UnqualifiedId Name;
1510    // Read var name.
1511    Token PrevTok = Tok;
1512    NoIdentIsFound = false;
1513
1514    if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
1515        ParseOptionalCXXScopeSpecifier(SS, nullptr, false)) {
1516      IsCorrect = false;
1517      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1518                StopBeforeMatch);
1519    } else if (ParseUnqualifiedId(SS, false, false, false, false, nullptr,
1520                                  nullptr, Name)) {
1521      IsCorrect = false;
1522      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1523                StopBeforeMatch);
1524    } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
1525               Tok.isNot(tok::annot_pragma_openmp_end)) {
1526      IsCorrect = false;
1527      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1528                StopBeforeMatch);
1529      Diag(PrevTok.getLocation(), diag::err_expected)
1530          << tok::identifier
1531          << SourceRange(PrevTok.getLocation(), PrevTokLocation);
1532    } else {
1533      Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
1534    }
1535    // Consume ','.
1536    if (Tok.is(tok::comma)) {
1537      ConsumeToken();
1538    }
1539  }
1540
1541  if (NoIdentIsFound) {
1542    Diag(Tok, diag::err_expected) << tok::identifier;
1543    IsCorrect = false;
1544  }
1545
1546  // Parse ')'.
1547  IsCorrect = !T.consumeClose() && IsCorrect;
1548
1549  return !IsCorrect;
1550}
1551
1552/// Parsing of OpenMP clauses.
1553///
1554///    clause:
1555///       if-clause | final-clause | num_threads-clause | safelen-clause |
1556///       default-clause | private-clause | firstprivate-clause | shared-clause
1557///       | linear-clause | aligned-clause | collapse-clause |
1558///       lastprivate-clause | reduction-clause | proc_bind-clause |
1559///       schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
1560///       mergeable-clause | flush-clause | read-clause | write-clause |
1561///       update-clause | capture-clause | seq_cst-clause | device-clause |
1562///       simdlen-clause | threads-clause | simd-clause | num_teams-clause |
1563///       thread_limit-clause | priority-clause | grainsize-clause |
1564///       nogroup-clause | num_tasks-clause | hint-clause | to-clause |
1565///       from-clause | is_device_ptr-clause | task_reduction-clause |
1566///       in_reduction-clause | allocator-clause | allocate-clause
1567///
1568OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
1569                                     OpenMPClauseKind CKind, bool FirstClause) {
1570  OMPClause *Clause = nullptr;
1571  bool ErrorFound = false;
1572  bool WrongDirective = false;
1573  // Check if clause is allowed for the given directive.
1574  if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) {
1575    Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
1576                                               << getOpenMPDirectiveName(DKind);
1577    ErrorFound = true;
1578    WrongDirective = true;
1579  }
1580
1581  switch (CKind) {
1582  case OMPC_final:
1583  case OMPC_num_threads:
1584  case OMPC_safelen:
1585  case OMPC_simdlen:
1586  case OMPC_collapse:
1587  case OMPC_ordered:
1588  case OMPC_device:
1589  case OMPC_num_teams:
1590  case OMPC_thread_limit:
1591  case OMPC_priority:
1592  case OMPC_grainsize:
1593  case OMPC_num_tasks:
1594  case OMPC_hint:
1595  case OMPC_allocator:
1596    // OpenMP [2.5, Restrictions]
1597    //  At most one num_threads clause can appear on the directive.
1598    // OpenMP [2.8.1, simd construct, Restrictions]
1599    //  Only one safelen  clause can appear on a simd directive.
1600    //  Only one simdlen  clause can appear on a simd directive.
1601    //  Only one collapse clause can appear on a simd directive.
1602    // OpenMP [2.9.1, target data construct, Restrictions]
1603    //  At most one device clause can appear on the directive.
1604    // OpenMP [2.11.1, task Construct, Restrictions]
1605    //  At most one if clause can appear on the directive.
1606    //  At most one final clause can appear on the directive.
1607    // OpenMP [teams Construct, Restrictions]
1608    //  At most one num_teams clause can appear on the directive.
1609    //  At most one thread_limit clause can appear on the directive.
1610    // OpenMP [2.9.1, task Construct, Restrictions]
1611    // At most one priority clause can appear on the directive.
1612    // OpenMP [2.9.2, taskloop Construct, Restrictions]
1613    // At most one grainsize clause can appear on the directive.
1614    // OpenMP [2.9.2, taskloop Construct, Restrictions]
1615    // At most one num_tasks clause can appear on the directive.
1616    // OpenMP [2.11.3, allocate Directive, Restrictions]
1617    // At most one allocator clause can appear on the directive.
1618    if (!FirstClause) {
1619      Diag(Tok, diag::err_omp_more_one_clause)
1620          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1621      ErrorFound = true;
1622    }
1623
1624    if (CKind == OMPC_ordered && PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
1625      Clause = ParseOpenMPClause(CKind, WrongDirective);
1626    else
1627      Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
1628    break;
1629  case OMPC_default:
1630  case OMPC_proc_bind:
1631  case OMPC_atomic_default_mem_order:
1632    // OpenMP [2.14.3.1, Restrictions]
1633    //  Only a single default clause may be specified on a parallel, task or
1634    //  teams directive.
1635    // OpenMP [2.5, parallel Construct, Restrictions]
1636    //  At most one proc_bind clause can appear on the directive.
1637    // OpenMP [5.0, Requires directive, Restrictions]
1638    //  At most one atomic_default_mem_order clause can appear
1639    //  on the directive
1640    if (!FirstClause) {
1641      Diag(Tok, diag::err_omp_more_one_clause)
1642          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1643      ErrorFound = true;
1644    }
1645
1646    Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
1647    break;
1648  case OMPC_schedule:
1649  case OMPC_dist_schedule:
1650  case OMPC_defaultmap:
1651    // OpenMP [2.7.1, Restrictions, p. 3]
1652    //  Only one schedule clause can appear on a loop directive.
1653    // OpenMP [2.10.4, Restrictions, p. 106]
1654    //  At most one defaultmap clause can appear on the directive.
1655    if (!FirstClause) {
1656      Diag(Tok, diag::err_omp_more_one_clause)
1657          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1658      ErrorFound = true;
1659    }
1660    LLVM_FALLTHROUGH;
1661
1662  case OMPC_if:
1663    Clause = ParseOpenMPSingleExprWithArgClause(CKind, WrongDirective);
1664    break;
1665  case OMPC_nowait:
1666  case OMPC_untied:
1667  case OMPC_mergeable:
1668  case OMPC_read:
1669  case OMPC_write:
1670  case OMPC_update:
1671  case OMPC_capture:
1672  case OMPC_seq_cst:
1673  case OMPC_threads:
1674  case OMPC_simd:
1675  case OMPC_nogroup:
1676  case OMPC_unified_address:
1677  case OMPC_unified_shared_memory:
1678  case OMPC_reverse_offload:
1679  case OMPC_dynamic_allocators:
1680    // OpenMP [2.7.1, Restrictions, p. 9]
1681    //  Only one ordered clause can appear on a loop directive.
1682    // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
1683    //  Only one nowait clause can appear on a for directive.
1684    // OpenMP [5.0, Requires directive, Restrictions]
1685    //   Each of the requires clauses can appear at most once on the directive.
1686    if (!FirstClause) {
1687      Diag(Tok, diag::err_omp_more_one_clause)
1688          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1689      ErrorFound = true;
1690    }
1691
1692    Clause = ParseOpenMPClause(CKind, WrongDirective);
1693    break;
1694  case OMPC_private:
1695  case OMPC_firstprivate:
1696  case OMPC_lastprivate:
1697  case OMPC_shared:
1698  case OMPC_reduction:
1699  case OMPC_task_reduction:
1700  case OMPC_in_reduction:
1701  case OMPC_linear:
1702  case OMPC_aligned:
1703  case OMPC_copyin:
1704  case OMPC_copyprivate:
1705  case OMPC_flush:
1706  case OMPC_depend:
1707  case OMPC_map:
1708  case OMPC_to:
1709  case OMPC_from:
1710  case OMPC_use_device_ptr:
1711  case OMPC_is_device_ptr:
1712  case OMPC_allocate:
1713    Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
1714    break;
1715  case OMPC_unknown:
1716    Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1717        << getOpenMPDirectiveName(DKind);
1718    SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1719    break;
1720  case OMPC_threadprivate:
1721  case OMPC_uniform:
1722    if (!WrongDirective)
1723      Diag(Tok, diag::err_omp_unexpected_clause)
1724          << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
1725    SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
1726    break;
1727  }
1728  return ErrorFound ? nullptr : Clause;
1729}
1730
1731/// Parses simple expression in parens for single-expression clauses of OpenMP
1732/// constructs.
1733/// \param RLoc Returned location of right paren.
1734ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
1735                                         SourceLocation &RLoc) {
1736  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1737  if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
1738    return ExprError();
1739
1740  SourceLocation ELoc = Tok.getLocation();
1741  ExprResult LHS(ParseCastExpression(
1742      /*isUnaryExpression=*/false, /*isAddressOfOperand=*/false, NotTypeCast));
1743  ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
1744  Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
1745
1746  // Parse ')'.
1747  RLoc = Tok.getLocation();
1748  if (!T.consumeClose())
1749    RLoc = T.getCloseLocation();
1750
1751  return Val;
1752}
1753
1754/// Parsing of OpenMP clauses with single expressions like 'final',
1755/// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
1756/// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks' or 'hint'.
1757///
1758///    final-clause:
1759///      'final' '(' expression ')'
1760///
1761///    num_threads-clause:
1762///      'num_threads' '(' expression ')'
1763///
1764///    safelen-clause:
1765///      'safelen' '(' expression ')'
1766///
1767///    simdlen-clause:
1768///      'simdlen' '(' expression ')'
1769///
1770///    collapse-clause:
1771///      'collapse' '(' expression ')'
1772///
1773///    priority-clause:
1774///      'priority' '(' expression ')'
1775///
1776///    grainsize-clause:
1777///      'grainsize' '(' expression ')'
1778///
1779///    num_tasks-clause:
1780///      'num_tasks' '(' expression ')'
1781///
1782///    hint-clause:
1783///      'hint' '(' expression ')'
1784///
1785///    allocator-clause:
1786///      'allocator' '(' expression ')'
1787///
1788OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
1789                                               bool ParseOnly) {
1790  SourceLocation Loc = ConsumeToken();
1791  SourceLocation LLoc = Tok.getLocation();
1792  SourceLocation RLoc;
1793
1794  ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc);
1795
1796  if (Val.isInvalid())
1797    return nullptr;
1798
1799  if (ParseOnly)
1800    return nullptr;
1801  return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc);
1802}
1803
1804/// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
1805///
1806///    default-clause:
1807///         'default' '(' 'none' | 'shared' ')
1808///
1809///    proc_bind-clause:
1810///         'proc_bind' '(' 'master' | 'close' | 'spread' ')
1811///
1812OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind,
1813                                           bool ParseOnly) {
1814  SourceLocation Loc = Tok.getLocation();
1815  SourceLocation LOpen = ConsumeToken();
1816  // Parse '('.
1817  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1818  if (T.expectAndConsume(diag::err_expected_lparen_after,
1819                         getOpenMPClauseName(Kind)))
1820    return nullptr;
1821
1822  unsigned Type = getOpenMPSimpleClauseType(
1823      Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1824  SourceLocation TypeLoc = Tok.getLocation();
1825  if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1826      Tok.isNot(tok::annot_pragma_openmp_end))
1827    ConsumeAnyToken();
1828
1829  // Parse ')'.
1830  SourceLocation RLoc = Tok.getLocation();
1831  if (!T.consumeClose())
1832    RLoc = T.getCloseLocation();
1833
1834  if (ParseOnly)
1835    return nullptr;
1836  return Actions.ActOnOpenMPSimpleClause(Kind, Type, TypeLoc, LOpen, Loc, RLoc);
1837}
1838
1839/// Parsing of OpenMP clauses like 'ordered'.
1840///
1841///    ordered-clause:
1842///         'ordered'
1843///
1844///    nowait-clause:
1845///         'nowait'
1846///
1847///    untied-clause:
1848///         'untied'
1849///
1850///    mergeable-clause:
1851///         'mergeable'
1852///
1853///    read-clause:
1854///         'read'
1855///
1856///    threads-clause:
1857///         'threads'
1858///
1859///    simd-clause:
1860///         'simd'
1861///
1862///    nogroup-clause:
1863///         'nogroup'
1864///
1865OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly) {
1866  SourceLocation Loc = Tok.getLocation();
1867  ConsumeAnyToken();
1868
1869  if (ParseOnly)
1870    return nullptr;
1871  return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
1872}
1873
1874
1875/// Parsing of OpenMP clauses with single expressions and some additional
1876/// argument like 'schedule' or 'dist_schedule'.
1877///
1878///    schedule-clause:
1879///      'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
1880///      ')'
1881///
1882///    if-clause:
1883///      'if' '(' [ directive-name-modifier ':' ] expression ')'
1884///
1885///    defaultmap:
1886///      'defaultmap' '(' modifier ':' kind ')'
1887///
1888OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,
1889                                                      bool ParseOnly) {
1890  SourceLocation Loc = ConsumeToken();
1891  SourceLocation DelimLoc;
1892  // Parse '('.
1893  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1894  if (T.expectAndConsume(diag::err_expected_lparen_after,
1895                         getOpenMPClauseName(Kind)))
1896    return nullptr;
1897
1898  ExprResult Val;
1899  SmallVector<unsigned, 4> Arg;
1900  SmallVector<SourceLocation, 4> KLoc;
1901  if (Kind == OMPC_schedule) {
1902    enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
1903    Arg.resize(NumberOfElements);
1904    KLoc.resize(NumberOfElements);
1905    Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
1906    Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
1907    Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
1908    unsigned KindModifier = getOpenMPSimpleClauseType(
1909        Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1910    if (KindModifier > OMPC_SCHEDULE_unknown) {
1911      // Parse 'modifier'
1912      Arg[Modifier1] = KindModifier;
1913      KLoc[Modifier1] = Tok.getLocation();
1914      if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1915          Tok.isNot(tok::annot_pragma_openmp_end))
1916        ConsumeAnyToken();
1917      if (Tok.is(tok::comma)) {
1918        // Parse ',' 'modifier'
1919        ConsumeAnyToken();
1920        KindModifier = getOpenMPSimpleClauseType(
1921            Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1922        Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown
1923                             ? KindModifier
1924                             : (unsigned)OMPC_SCHEDULE_unknown;
1925        KLoc[Modifier2] = Tok.getLocation();
1926        if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1927            Tok.isNot(tok::annot_pragma_openmp_end))
1928          ConsumeAnyToken();
1929      }
1930      // Parse ':'
1931      if (Tok.is(tok::colon))
1932        ConsumeAnyToken();
1933      else
1934        Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier";
1935      KindModifier = getOpenMPSimpleClauseType(
1936          Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1937    }
1938    Arg[ScheduleKind] = KindModifier;
1939    KLoc[ScheduleKind] = Tok.getLocation();
1940    if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1941        Tok.isNot(tok::annot_pragma_openmp_end))
1942      ConsumeAnyToken();
1943    if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
1944         Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
1945         Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
1946        Tok.is(tok::comma))
1947      DelimLoc = ConsumeAnyToken();
1948  } else if (Kind == OMPC_dist_schedule) {
1949    Arg.push_back(getOpenMPSimpleClauseType(
1950        Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1951    KLoc.push_back(Tok.getLocation());
1952    if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1953        Tok.isNot(tok::annot_pragma_openmp_end))
1954      ConsumeAnyToken();
1955    if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
1956      DelimLoc = ConsumeAnyToken();
1957  } else if (Kind == OMPC_defaultmap) {
1958    // Get a defaultmap modifier
1959    Arg.push_back(getOpenMPSimpleClauseType(
1960        Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1961    KLoc.push_back(Tok.getLocation());
1962    if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1963        Tok.isNot(tok::annot_pragma_openmp_end))
1964      ConsumeAnyToken();
1965    // Parse ':'
1966    if (Tok.is(tok::colon))
1967      ConsumeAnyToken();
1968    else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown)
1969      Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier";
1970    // Get a defaultmap kind
1971    Arg.push_back(getOpenMPSimpleClauseType(
1972        Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1973    KLoc.push_back(Tok.getLocation());
1974    if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1975        Tok.isNot(tok::annot_pragma_openmp_end))
1976      ConsumeAnyToken();
1977  } else {
1978    assert(Kind == OMPC_if);
1979    KLoc.push_back(Tok.getLocation());
1980    TentativeParsingAction TPA(*this);
1981    Arg.push_back(parseOpenMPDirectiveKind(*this));
1982    if (Arg.back() != OMPD_unknown) {
1983      ConsumeToken();
1984      if (Tok.is(tok::colon) && getLangOpts().OpenMP > 40) {
1985        TPA.Commit();
1986        DelimLoc = ConsumeToken();
1987      } else {
1988        TPA.Revert();
1989        Arg.back() = OMPD_unknown;
1990      }
1991    } else {
1992      TPA.Revert();
1993    }
1994  }
1995
1996  bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) ||
1997                          (Kind == OMPC_dist_schedule && DelimLoc.isValid()) ||
1998                          Kind == OMPC_if;
1999  if (NeedAnExpression) {
2000    SourceLocation ELoc = Tok.getLocation();
2001    ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
2002    Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
2003    Val =
2004        Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false);
2005  }
2006
2007  // Parse ')'.
2008  SourceLocation RLoc = Tok.getLocation();
2009  if (!T.consumeClose())
2010    RLoc = T.getCloseLocation();
2011
2012  if (NeedAnExpression && Val.isInvalid())
2013    return nullptr;
2014
2015  if (ParseOnly)
2016    return nullptr;
2017  return Actions.ActOnOpenMPSingleExprWithArgClause(
2018      Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
2019}
2020
2021static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
2022                             UnqualifiedId &ReductionId) {
2023  if (ReductionIdScopeSpec.isEmpty()) {
2024    auto OOK = OO_None;
2025    switch (P.getCurToken().getKind()) {
2026    case tok::plus:
2027      OOK = OO_Plus;
2028      break;
2029    case tok::minus:
2030      OOK = OO_Minus;
2031      break;
2032    case tok::star:
2033      OOK = OO_Star;
2034      break;
2035    case tok::amp:
2036      OOK = OO_Amp;
2037      break;
2038    case tok::pipe:
2039      OOK = OO_Pipe;
2040      break;
2041    case tok::caret:
2042      OOK = OO_Caret;
2043      break;
2044    case tok::ampamp:
2045      OOK = OO_AmpAmp;
2046      break;
2047    case tok::pipepipe:
2048      OOK = OO_PipePipe;
2049      break;
2050    default:
2051      break;
2052    }
2053    if (OOK != OO_None) {
2054      SourceLocation OpLoc = P.ConsumeToken();
2055      SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
2056      ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
2057      return false;
2058    }
2059  }
2060  return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false,
2061                              /*AllowDestructorName*/ false,
2062                              /*AllowConstructorName*/ false,
2063                              /*AllowDeductionGuide*/ false,
2064                              nullptr, nullptr, ReductionId);
2065}
2066
2067/// Checks if the token is a valid map-type-modifier.
2068static OpenMPMapModifierKind isMapModifier(Parser &P) {
2069  Token Tok = P.getCurToken();
2070  if (!Tok.is(tok::identifier))
2071    return OMPC_MAP_MODIFIER_unknown;
2072
2073  Preprocessor &PP = P.getPreprocessor();
2074  OpenMPMapModifierKind TypeModifier = static_cast<OpenMPMapModifierKind>(
2075      getOpenMPSimpleClauseType(OMPC_map, PP.getSpelling(Tok)));
2076  return TypeModifier;
2077}
2078
2079/// Parse the mapper modifier in map, to, and from clauses.
2080bool Parser::parseMapperModifier(OpenMPVarListDataTy &Data) {
2081  // Parse '('.
2082  BalancedDelimiterTracker T(*this, tok::l_paren, tok::colon);
2083  if (T.expectAndConsume(diag::err_expected_lparen_after, "mapper")) {
2084    SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2085              StopBeforeMatch);
2086    return true;
2087  }
2088  // Parse mapper-identifier
2089  if (getLangOpts().CPlusPlus)
2090    ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
2091                                   /*ObjectType=*/nullptr,
2092                                   /*EnteringContext=*/false);
2093  if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
2094    Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
2095    SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2096              StopBeforeMatch);
2097    return true;
2098  }
2099  auto &DeclNames = Actions.getASTContext().DeclarationNames;
2100  Data.ReductionOrMapperId = DeclarationNameInfo(
2101      DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
2102  ConsumeToken();
2103  // Parse ')'.
2104  return T.consumeClose();
2105}
2106
2107/// Parse map-type-modifiers in map clause.
2108/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
2109/// where, map-type-modifier ::= always | close | mapper(mapper-identifier)
2110bool Parser::parseMapTypeModifiers(OpenMPVarListDataTy &Data) {
2111  while (getCurToken().isNot(tok::colon)) {
2112    OpenMPMapModifierKind TypeModifier = isMapModifier(*this);
2113    if (TypeModifier == OMPC_MAP_MODIFIER_always ||
2114        TypeModifier == OMPC_MAP_MODIFIER_close) {
2115      Data.MapTypeModifiers.push_back(TypeModifier);
2116      Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
2117      ConsumeToken();
2118    } else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
2119      Data.MapTypeModifiers.push_back(TypeModifier);
2120      Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
2121      ConsumeToken();
2122      if (parseMapperModifier(Data))
2123        return true;
2124    } else {
2125      // For the case of unknown map-type-modifier or a map-type.
2126      // Map-type is followed by a colon; the function returns when it
2127      // encounters a token followed by a colon.
2128      if (Tok.is(tok::comma)) {
2129        Diag(Tok, diag::err_omp_map_type_modifier_missing);
2130        ConsumeToken();
2131        continue;
2132      }
2133      // Potential map-type token as it is followed by a colon.
2134      if (PP.LookAhead(0).is(tok::colon))
2135        return false;
2136      Diag(Tok, diag::err_omp_unknown_map_type_modifier);
2137      ConsumeToken();
2138    }
2139    if (getCurToken().is(tok::comma))
2140      ConsumeToken();
2141  }
2142  return false;
2143}
2144
2145/// Checks if the token is a valid map-type.
2146static OpenMPMapClauseKind isMapType(Parser &P) {
2147  Token Tok = P.getCurToken();
2148  // The map-type token can be either an identifier or the C++ delete keyword.
2149  if (!Tok.isOneOf(tok::identifier, tok::kw_delete))
2150    return OMPC_MAP_unknown;
2151  Preprocessor &PP = P.getPreprocessor();
2152  OpenMPMapClauseKind MapType = static_cast<OpenMPMapClauseKind>(
2153      getOpenMPSimpleClauseType(OMPC_map, PP.getSpelling(Tok)));
2154  return MapType;
2155}
2156
2157/// Parse map-type in map clause.
2158/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
2159/// where, map-type ::= to | from | tofrom | alloc | release | delete
2160static void parseMapType(Parser &P, Parser::OpenMPVarListDataTy &Data) {
2161  Token Tok = P.getCurToken();
2162  if (Tok.is(tok::colon)) {
2163    P.Diag(Tok, diag::err_omp_map_type_missing);
2164    return;
2165  }
2166  Data.MapType = isMapType(P);
2167  if (Data.MapType == OMPC_MAP_unknown)
2168    P.Diag(Tok, diag::err_omp_unknown_map_type);
2169  P.ConsumeToken();
2170}
2171
2172/// Parses clauses with list.
2173bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
2174                                OpenMPClauseKind Kind,
2175                                SmallVectorImpl<Expr *> &Vars,
2176                                OpenMPVarListDataTy &Data) {
2177  UnqualifiedId UnqualifiedReductionId;
2178  bool InvalidReductionId = false;
2179  bool IsInvalidMapperModifier = false;
2180
2181  // Parse '('.
2182  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2183  if (T.expectAndConsume(diag::err_expected_lparen_after,
2184                         getOpenMPClauseName(Kind)))
2185    return true;
2186
2187  bool NeedRParenForLinear = false;
2188  BalancedDelimiterTracker LinearT(*this, tok::l_paren,
2189                                  tok::annot_pragma_openmp_end);
2190  // Handle reduction-identifier for reduction clause.
2191  if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
2192      Kind == OMPC_in_reduction) {
2193    ColonProtectionRAIIObject ColonRAII(*this);
2194    if (getLangOpts().CPlusPlus)
2195      ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
2196                                     /*ObjectType=*/nullptr,
2197                                     /*EnteringContext=*/false);
2198    InvalidReductionId = ParseReductionId(
2199        *this, Data.ReductionOrMapperIdScopeSpec, UnqualifiedReductionId);
2200    if (InvalidReductionId) {
2201      SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2202                StopBeforeMatch);
2203    }
2204    if (Tok.is(tok::colon))
2205      Data.ColonLoc = ConsumeToken();
2206    else
2207      Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
2208    if (!InvalidReductionId)
2209      Data.ReductionOrMapperId =
2210          Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
2211  } else if (Kind == OMPC_depend) {
2212  // Handle dependency type for depend clause.
2213    ColonProtectionRAIIObject ColonRAII(*this);
2214    Data.DepKind =
2215        static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType(
2216            Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
2217    Data.DepLinMapLoc = Tok.getLocation();
2218
2219    if (Data.DepKind == OMPC_DEPEND_unknown) {
2220      SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2221                StopBeforeMatch);
2222    } else {
2223      ConsumeToken();
2224      // Special processing for depend(source) clause.
2225      if (DKind == OMPD_ordered && Data.DepKind == OMPC_DEPEND_source) {
2226        // Parse ')'.
2227        T.consumeClose();
2228        return false;
2229      }
2230    }
2231    if (Tok.is(tok::colon)) {
2232      Data.ColonLoc = ConsumeToken();
2233    } else {
2234      Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
2235                                      : diag::warn_pragma_expected_colon)
2236          << "dependency type";
2237    }
2238  } else if (Kind == OMPC_linear) {
2239    // Try to parse modifier if any.
2240    if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
2241      Data.LinKind = static_cast<OpenMPLinearClauseKind>(
2242          getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
2243      Data.DepLinMapLoc = ConsumeToken();
2244      LinearT.consumeOpen();
2245      NeedRParenForLinear = true;
2246    }
2247  } else if (Kind == OMPC_map) {
2248    // Handle map type for map clause.
2249    ColonProtectionRAIIObject ColonRAII(*this);
2250
2251    // The first identifier may be a list item, a map-type or a
2252    // map-type-modifier. The map-type can also be delete which has the same
2253    // spelling of the C++ delete keyword.
2254    Data.DepLinMapLoc = Tok.getLocation();
2255
2256    // Check for presence of a colon in the map clause.
2257    TentativeParsingAction TPA(*this);
2258    bool ColonPresent = false;
2259    if (SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2260        StopBeforeMatch)) {
2261      if (Tok.is(tok::colon))
2262        ColonPresent = true;
2263    }
2264    TPA.Revert();
2265    // Only parse map-type-modifier[s] and map-type if a colon is present in
2266    // the map clause.
2267    if (ColonPresent) {
2268      IsInvalidMapperModifier = parseMapTypeModifiers(Data);
2269      if (!IsInvalidMapperModifier)
2270        parseMapType(*this, Data);
2271      else
2272        SkipUntil(tok::colon, tok::annot_pragma_openmp_end, StopBeforeMatch);
2273    }
2274    if (Data.MapType == OMPC_MAP_unknown) {
2275      Data.MapType = OMPC_MAP_tofrom;
2276      Data.IsMapTypeImplicit = true;
2277    }
2278
2279    if (Tok.is(tok::colon))
2280      Data.ColonLoc = ConsumeToken();
2281  } else if (Kind == OMPC_to || Kind == OMPC_from) {
2282    if (Tok.is(tok::identifier)) {
2283      bool IsMapperModifier = false;
2284      if (Kind == OMPC_to) {
2285        auto Modifier = static_cast<OpenMPToModifierKind>(
2286            getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
2287        if (Modifier == OMPC_TO_MODIFIER_mapper)
2288          IsMapperModifier = true;
2289      } else {
2290        auto Modifier = static_cast<OpenMPFromModifierKind>(
2291            getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
2292        if (Modifier == OMPC_FROM_MODIFIER_mapper)
2293          IsMapperModifier = true;
2294      }
2295      if (IsMapperModifier) {
2296        // Parse the mapper modifier.
2297        ConsumeToken();
2298        IsInvalidMapperModifier = parseMapperModifier(Data);
2299        if (Tok.isNot(tok::colon)) {
2300          if (!IsInvalidMapperModifier)
2301            Diag(Tok, diag::warn_pragma_expected_colon) << ")";
2302          SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
2303                    StopBeforeMatch);
2304        }
2305        // Consume ':'.
2306        if (Tok.is(tok::colon))
2307          ConsumeToken();
2308      }
2309    }
2310  } else if (Kind == OMPC_allocate) {
2311    // Handle optional allocator expression followed by colon delimiter.
2312    ColonProtectionRAIIObject ColonRAII(*this);
2313    TentativeParsingAction TPA(*this);
2314    ExprResult Tail =
2315        Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
2316    Tail = Actions.ActOnFinishFullExpr(Tail.get(), T.getOpenLocation(),
2317                                       /*DiscardedValue=*/false);
2318    if (Tail.isUsable()) {
2319      if (Tok.is(tok::colon)) {
2320        Data.TailExpr = Tail.get();
2321        Data.ColonLoc = ConsumeToken();
2322        TPA.Commit();
2323      } else {
2324        // colon not found, no allocator specified, parse only list of
2325        // variables.
2326        TPA.Revert();
2327      }
2328    } else {
2329      // Parsing was unsuccessfull, revert and skip to the end of clause or
2330      // directive.
2331      TPA.Revert();
2332      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2333                StopBeforeMatch);
2334    }
2335  }
2336
2337  bool IsComma =
2338      (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
2339       Kind != OMPC_in_reduction && Kind != OMPC_depend && Kind != OMPC_map) ||
2340      (Kind == OMPC_reduction && !InvalidReductionId) ||
2341      (Kind == OMPC_map && Data.MapType != OMPC_MAP_unknown) ||
2342      (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown);
2343  const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
2344  while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
2345                     Tok.isNot(tok::annot_pragma_openmp_end))) {
2346    ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
2347    // Parse variable
2348    ExprResult VarExpr =
2349        Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
2350    if (VarExpr.isUsable()) {
2351      Vars.push_back(VarExpr.get());
2352    } else {
2353      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2354                StopBeforeMatch);
2355    }
2356    // Skip ',' if any
2357    IsComma = Tok.is(tok::comma);
2358    if (IsComma)
2359      ConsumeToken();
2360    else if (Tok.isNot(tok::r_paren) &&
2361             Tok.isNot(tok::annot_pragma_openmp_end) &&
2362             (!MayHaveTail || Tok.isNot(tok::colon)))
2363      Diag(Tok, diag::err_omp_expected_punc)
2364          << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
2365                                   : getOpenMPClauseName(Kind))
2366          << (Kind == OMPC_flush);
2367  }
2368
2369  // Parse ')' for linear clause with modifier.
2370  if (NeedRParenForLinear)
2371    LinearT.consumeClose();
2372
2373  // Parse ':' linear-step (or ':' alignment).
2374  const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
2375  if (MustHaveTail) {
2376    Data.ColonLoc = Tok.getLocation();
2377    SourceLocation ELoc = ConsumeToken();
2378    ExprResult Tail = ParseAssignmentExpression();
2379    Tail =
2380        Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false);
2381    if (Tail.isUsable())
2382      Data.TailExpr = Tail.get();
2383    else
2384      SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
2385                StopBeforeMatch);
2386  }
2387
2388  // Parse ')'.
2389  Data.RLoc = Tok.getLocation();
2390  if (!T.consumeClose())
2391    Data.RLoc = T.getCloseLocation();
2392  return (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown &&
2393          Vars.empty()) ||
2394         (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
2395         (MustHaveTail && !Data.TailExpr) || InvalidReductionId ||
2396         IsInvalidMapperModifier;
2397}
2398
2399/// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
2400/// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction' or
2401/// 'in_reduction'.
2402///
2403///    private-clause:
2404///       'private' '(' list ')'
2405///    firstprivate-clause:
2406///       'firstprivate' '(' list ')'
2407///    lastprivate-clause:
2408///       'lastprivate' '(' list ')'
2409///    shared-clause:
2410///       'shared' '(' list ')'
2411///    linear-clause:
2412///       'linear' '(' linear-list [ ':' linear-step ] ')'
2413///    aligned-clause:
2414///       'aligned' '(' list [ ':' alignment ] ')'
2415///    reduction-clause:
2416///       'reduction' '(' reduction-identifier ':' list ')'
2417///    task_reduction-clause:
2418///       'task_reduction' '(' reduction-identifier ':' list ')'
2419///    in_reduction-clause:
2420///       'in_reduction' '(' reduction-identifier ':' list ')'
2421///    copyprivate-clause:
2422///       'copyprivate' '(' list ')'
2423///    flush-clause:
2424///       'flush' '(' list ')'
2425///    depend-clause:
2426///       'depend' '(' in | out | inout : list | source ')'
2427///    map-clause:
2428///       'map' '(' [ [ always [,] ] [ close [,] ]
2429///          [ mapper '(' mapper-identifier ')' [,] ]
2430///          to | from | tofrom | alloc | release | delete ':' ] list ')';
2431///    to-clause:
2432///       'to' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
2433///    from-clause:
2434///       'from' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
2435///    use_device_ptr-clause:
2436///       'use_device_ptr' '(' list ')'
2437///    is_device_ptr-clause:
2438///       'is_device_ptr' '(' list ')'
2439///    allocate-clause:
2440///       'allocate' '(' [ allocator ':' ] list ')'
2441///
2442/// For 'linear' clause linear-list may have the following forms:
2443///  list
2444///  modifier(list)
2445/// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
2446OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
2447                                            OpenMPClauseKind Kind,
2448                                            bool ParseOnly) {
2449  SourceLocation Loc = Tok.getLocation();
2450  SourceLocation LOpen = ConsumeToken();
2451  SmallVector<Expr *, 4> Vars;
2452  OpenMPVarListDataTy Data;
2453
2454  if (ParseOpenMPVarList(DKind, Kind, Vars, Data))
2455    return nullptr;
2456
2457  if (ParseOnly)
2458    return nullptr;
2459  OMPVarListLocTy Locs(Loc, LOpen, Data.RLoc);
2460  return Actions.ActOnOpenMPVarListClause(
2461      Kind, Vars, Data.TailExpr, Locs, Data.ColonLoc,
2462      Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId, Data.DepKind,
2463      Data.LinKind, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
2464      Data.MapType, Data.IsMapTypeImplicit, Data.DepLinMapLoc);
2465}
2466
2467