Clang Project

clang_source_code/lib/Parse/ParseOpenMP.cpp
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 *, 4Identifiers;
49  Parser *P;
50  OpenMPDirectiveKind Kind;
51
52public:
53  DeclDirectiveListParserHelper(Parser *POpenMPDirectiveKind Kind)
54      : P(P), Kind(Kind) {}
55  void operator()(CXXScopeSpec &SSDeclarationNameInfo NameInfo) {
56    ExprResult Res = P->getActions().ActOnOpenMPIdExpression(
57        P->getCurScope(), SSNameInfoKind);
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_cancellationOMPD_pointOMPD_cancellation_point},
92      {OMPD_declareOMPD_reductionOMPD_declare_reduction},
93      {OMPD_declareOMPD_mapperOMPD_declare_mapper},
94      {OMPD_declareOMPD_simdOMPD_declare_simd},
95      {OMPD_declareOMPD_targetOMPD_declare_target},
96      {OMPD_distributeOMPD_parallelOMPD_distribute_parallel},
97      {OMPD_distribute_parallelOMPD_forOMPD_distribute_parallel_for},
98      {OMPD_distribute_parallel_forOMPD_simd,
99       OMPD_distribute_parallel_for_simd},
100      {OMPD_distributeOMPD_simdOMPD_distribute_simd},
101      {OMPD_endOMPD_declareOMPD_end_declare},
102      {OMPD_end_declareOMPD_targetOMPD_end_declare_target},
103      {OMPD_targetOMPD_dataOMPD_target_data},
104      {OMPD_targetOMPD_enterOMPD_target_enter},
105      {OMPD_targetOMPD_exitOMPD_target_exit},
106      {OMPD_targetOMPD_updateOMPD_target_update},
107      {OMPD_target_enterOMPD_dataOMPD_target_enter_data},
108      {OMPD_target_exitOMPD_dataOMPD_target_exit_data},
109      {OMPD_forOMPD_simdOMPD_for_simd},
110      {OMPD_parallelOMPD_forOMPD_parallel_for},
111      {OMPD_parallel_forOMPD_simdOMPD_parallel_for_simd},
112      {OMPD_parallelOMPD_sectionsOMPD_parallel_sections},
113      {OMPD_taskloopOMPD_simdOMPD_taskloop_simd},
114      {OMPD_targetOMPD_parallelOMPD_target_parallel},
115      {OMPD_targetOMPD_simdOMPD_target_simd},
116      {OMPD_target_parallelOMPD_forOMPD_target_parallel_for},
117      {OMPD_target_parallel_forOMPD_simdOMPD_target_parallel_for_simd},
118      {OMPD_teamsOMPD_distributeOMPD_teams_distribute},
119      {OMPD_teams_distributeOMPD_simdOMPD_teams_distribute_simd},
120      {OMPD_teams_distributeOMPD_parallelOMPD_teams_distribute_parallel},
121      {OMPD_teams_distribute_parallelOMPD_for,
122       OMPD_teams_distribute_parallel_for},
123      {OMPD_teams_distribute_parallel_forOMPD_simd,
124       OMPD_teams_distribute_parallel_for_simd},
125      {OMPD_targetOMPD_teamsOMPD_target_teams},
126      {OMPD_target_teamsOMPD_distributeOMPD_target_teams_distribute},
127      {OMPD_target_teams_distributeOMPD_parallel,
128       OMPD_target_teams_distribute_parallel},
129      {OMPD_target_teams_distributeOMPD_simd,
130       OMPD_target_teams_distribute_simd},
131      {OMPD_target_teams_distribute_parallelOMPD_for,
132       OMPD_target_teams_distribute_parallel_for},
133      {OMPD_target_teams_distribute_parallel_forOMPD_simd,
134       OMPD_target_teams_distribute_parallel_for_simd}};
135  enum { CancellationPoint = 0DeclareReduction = 1TargetData = 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::colontok::r_parentok::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(*thistok::l_parentok::annot_pragma_openmp_end);
231  if (T.expectAndConsume(diag::err_expected_lparen_after,
232                         getOpenMPDirectiveName(OMPD_declare_reduction))) {
233    SkipUntil(tok::annot_pragma_openmp_endStopBeforeMatch);
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<QualTypeSourceLocation>, 8ReductionTypes;
258  // Parse list of types until ':' token.
259  do {
260    ColonProtectionRAIIObject ColonRAII(*this);
261    SourceRange Range;
262    TypeResult TR =
263        ParseTypeName(&RangeDeclaratorContext::PrototypeContextAS);
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::commatok::colontok::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_endStopBeforeMatch);
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 = 0E = ReductionTypes.size();
312  for (Decl *D : DRD.get()) {
313    TentativeParsingAction TPA(*this);
314    ParseScope OMPDRScope(thisScope::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(DCombinerResult.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(*thistok::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(thisScope::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            DInitializerResult.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_parentok::annot_pragma_openmp_endStopBeforeMatch);
415      Actions.ActOnInitializerError(OmpPrivParm);
416    } else {
417      Actions.AddInitializerToDecl(OmpPrivParmInit.get(),
418                                   /*DirectInit=*/false);
419    }
420  } else if (Tok.is(tok::l_paren)) {
421    // Parse C++ direct initializer: '(' expression-list ')'
422    BalancedDelimiterTracker T(*thistok::l_paren);
423    T.consumeOpen();
424
425    ExprVector Exprs;
426    CommaLocsTy CommaLocs;
427
428    SourceLocation LParLoc = T.getOpenLocation();
429    auto RunSignatureHelp = [thisOmpPrivParmLParLoc, &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_parentok::annot_pragma_openmp_endStopBeforeMatch);
444    } else {
445      // Match the ')'.
446      SourceLocation RLoc = Tok.getLocation();
447      if (!T.consumeClose())
448        RLoc = T.getCloseLocation();
449
450       (0) . __assert_fail ("!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size() && \"Unexpected number of commas!\"", "/home/seafit/code_projects/clang_source/clang/lib/Parse/ParseOpenMP.cpp", 451, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size() &&
451 (0) . __assert_fail ("!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size() && \"Unexpected number of commas!\"", "/home/seafit/code_projects/clang_source/clang/lib/Parse/ParseOpenMP.cpp", 451, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">             "Unexpected number of commas!");
452
453      ExprResult Initializer =
454          Actions.ActOnParenListExpr(T.getOpenLocation(), RLoc, Exprs);
455      Actions.AddInitializerToDecl(OmpPrivParmInitializer.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(OmpPrivParmInit.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(*thistok::l_parentok::annot_pragma_openmp_end);
488  if (T.expectAndConsume(diag::err_expected_lparen_after,
489                         getOpenMPDirectiveName(OMPD_declare_mapper))) {
490    SkipUntil(tok::annot_pragma_openmp_endStopBeforeMatch);
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(RangeVNameAS);
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_endParser::StopBeforeMatch);
528    return DeclGroupPtrTy();
529  }
530
531  // Consume ')'.
532  IsCorrect &= !T.consumeClose();
533  if (!IsCorrect) {
534    SkipUntil(tok::annot_pragma_openmp_endParser::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(thisScopeFlags);
547  Actions.StartOpenMPDSABlock(OMPD_declare_mapperDirNamegetCurScope(), 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 *, 6Clauses;
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(DSASDSC);
595
596  // Parse the declarator.
597  DeclaratorContext Context = DeclaratorContext::PrototypeContext;
598  Declarator DeclaratorInfo(DSContext);
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 &PParser::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(&PScope::TemplateParamScopeHasTemplateScope);
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        &PScope::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 &BSExprResult &SimdLen,
676    SmallVectorImpl<Expr *> &UniformsSmallVectorImpl<Expr *> &Aligneds,
677    SmallVectorImpl<Expr *> &AlignmentsSmallVectorImpl<Expr *> &Linears,
678    SmallVectorImpl<unsigned> &LinModifiersSmallVectorImpl<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 &ToksSourceLocation Loc) {
750  PP.EnterToken(Tok);
751  PP.EnterTokenStream(Toks/*DisableMacroExpansion=*/true);
752  // Consume the previously pushed token.
753  ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
754
755  FNContextRAII FnContext(*thisPtr);
756  OMPDeclareSimdDeclAttr::BranchStateTy BS =
757      OMPDeclareSimdDeclAttr::BS_Undefined;
758  ExprResult Simdlen;
759  SmallVector<Expr *, 4Uniforms;
760  SmallVector<Expr *, 4Aligneds;
761  SmallVector<Expr *, 4Alignments;
762  SmallVector<Expr *, 4Linears;
763  SmallVector<unsigned4LinModifiers;
764  SmallVector<Expr *, 4Steps;
765  bool IsError =
766      parseDeclareSimdClauses(*this, BS, Simdlen, Uniforms, Aligneds,
767                              Alignments, Linears, LinModifiers, Steps);
768  // Need to check for extra tokens.
769  if (Tok.isNot(tok::annot_pragma_openmp_end)) {
770    Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
771        << getOpenMPDirectiveName(OMPD_declare_simd);
772    while (Tok.isNot(tok::annot_pragma_openmp_end))
773      ConsumeAnyToken();
774  }
775  // Skip the last annot_pragma_openmp_end.
776  SourceLocation EndLoc = ConsumeAnnotationToken();
777  if (IsError)
778    return Ptr;
779  return Actions.ActOnOpenMPDeclareSimdDirective(
780      Ptr, BS, Simdlen.get(), Uniforms, Aligneds, Alignments, Linears,
781      LinModifiers, Steps, SourceRange(Loc, EndLoc));
782}
783
784Parser::DeclGroupPtrTy Parser::ParseOMPDeclareTargetClauses() {
785  // OpenMP 4.5 syntax with list of entities.
786  Sema::NamedDeclSetType SameDirectiveDecls;
787  while (Tok.isNot(tok::annot_pragma_openmp_end)) {
788    OMPDeclareTargetDeclAttr::MapTypeTy MT = OMPDeclareTargetDeclAttr::MT_To;
789    if (Tok.is(tok::identifier)) {
790      IdentifierInfo *II = Tok.getIdentifierInfo();
791      StringRef ClauseName = II->getName();
792      // Parse 'to|link' clauses.
793      if (!OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName, MT)) {
794        Diag(Tok, diag::err_omp_declare_target_unexpected_clause) << ClauseName;
795        break;
796      }
797      ConsumeToken();
798    }
799    auto &&Callback = [this, MT, &SameDirectiveDecls](
800        CXXScopeSpec &SSDeclarationNameInfo NameInfo) {
801      Actions.ActOnOpenMPDeclareTargetName(getCurScope(), SS, NameInfo, MT,
802                                           SameDirectiveDecls);
803    };
804    if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
805                                 /*AllowScopeSpecifier=*/true))
806      break;
807
808    // Consume optional ','.
809    if (Tok.is(tok::comma))
810      ConsumeToken();
811  }
812  SkipUntil(tok::annot_pragma_openmp_endStopBeforeMatch);
813  ConsumeAnyToken();
814  SmallVector<Decl *, 4Decls(SameDirectiveDecls.begin(),
815                               SameDirectiveDecls.end());
816  if (Decls.empty())
817    return DeclGroupPtrTy();
818  return Actions.BuildDeclaratorGroup(Decls);
819}
820
821void Parser::ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind DKind,
822                                               SourceLocation DTLoc) {
823  if (DKind != OMPD_end_declare_target) {
824    Diag(Tok, diag::err_expected_end_declare_target);
825    Diag(DTLoc, diag::note_matching) << "'#pragma omp declare target'";
826    return;
827  }
828  ConsumeAnyToken();
829  if (Tok.isNot(tok::annot_pragma_openmp_end)) {
830    Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
831        << getOpenMPDirectiveName(OMPD_end_declare_target);
832    SkipUntil(tok::annot_pragma_openmp_endStopBeforeMatch);
833  }
834  // Skip the last annot_pragma_openmp_end.
835  ConsumeAnyToken();
836}
837
838/// Parsing of declarative OpenMP directives.
839///
840///       threadprivate-directive:
841///         annot_pragma_openmp 'threadprivate' simple-variable-list
842///         annot_pragma_openmp_end
843///
844///       allocate-directive:
845///         annot_pragma_openmp 'allocate' simple-variable-list [<clause>]
846///         annot_pragma_openmp_end
847///
848///       declare-reduction-directive:
849///        annot_pragma_openmp 'declare' 'reduction' [...]
850///        annot_pragma_openmp_end
851///
852///       declare-mapper-directive:
853///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
854///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
855///         annot_pragma_openmp_end
856///
857///       declare-simd-directive:
858///         annot_pragma_openmp 'declare simd' {<clause> [,]}
859///         annot_pragma_openmp_end
860///         <function declaration/definition>
861///
862///       requires directive:
863///         annot_pragma_openmp 'requires' <clause> [[[,] <clause>] ... ]
864///         annot_pragma_openmp_end
865///
866Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
867    AccessSpecifier &ASParsedAttributesWithRange &Attrs,
868    DeclSpec::TST TagTypeDecl *Tag) {
869   (0) . __assert_fail ("Tok.is(tok..annot_pragma_openmp) && \"Not an OpenMP directive!\"", "/home/seafit/code_projects/clang_source/clang/lib/Parse/ParseOpenMP.cpp", 869, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
870  ParenBraceBracketBalancer BalancerRAIIObj(*this);
871
872  SourceLocation Loc = ConsumeAnnotationToken();
873  OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
874
875  switch (DKind) {
876  case OMPD_threadprivate: {
877    ConsumeToken();
878    DeclDirectiveListParserHelper Helper(thisDKind);
879    if (!ParseOpenMPSimpleVarList(DKind, Helper,
880                                  /*AllowScopeSpecifier=*/true)) {
881      // The last seen token is annot_pragma_openmp_end - need to check for
882      // extra tokens.
883      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
884        Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
885            << getOpenMPDirectiveName(DKind);
886        SkipUntil(tok::annot_pragma_openmp_endStopBeforeMatch);
887      }
888      // Skip the last annot_pragma_openmp_end.
889      ConsumeAnnotationToken();
890      return Actions.ActOnOpenMPThreadprivateDirective(Loc,
891                                                       Helper.getIdentifiers());
892    }
893    break;
894  }
895  case OMPD_allocate: {
896    ConsumeToken();
897    DeclDirectiveListParserHelper Helper(thisDKind);
898    if (!ParseOpenMPSimpleVarList(DKind, Helper,
899                                  /*AllowScopeSpecifier=*/true)) {
900      SmallVector<OMPClause *, 1Clauses;
901      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
902        SmallVector<llvm::PointerIntPair<OMPClause *, 1bool>,
903                    OMPC_unknown + 1>
904            FirstClauses(OMPC_unknown + 1);
905        while (Tok.isNot(tok::annot_pragma_openmp_end)) {
906          OpenMPClauseKind CKind =
907              Tok.isAnnotation() ? OMPC_unknown
908                                 : getOpenMPClauseKind(PP.getSpelling(Tok));
909          Actions.StartOpenMPClause(CKind);
910          OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
911                                                !FirstClauses[CKind].getInt());
912          SkipUntil(tok::commatok::identifiertok::annot_pragma_openmp_end,
913                    StopBeforeMatch);
914          FirstClauses[CKind].setInt(true);
915          if (Clause != nullptr)
916            Clauses.push_back(Clause);
917          if (Tok.is(tok::annot_pragma_openmp_end)) {
918            Actions.EndOpenMPClause();
919            break;
920          }
921          // Skip ',' if any.
922          if (Tok.is(tok::comma))
923            ConsumeToken();
924          Actions.EndOpenMPClause();
925        }
926        // The last seen token is annot_pragma_openmp_end - need to check for
927        // extra tokens.
928        if (Tok.isNot(tok::annot_pragma_openmp_end)) {
929          Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
930              << getOpenMPDirectiveName(DKind);
931          SkipUntil(tok::annot_pragma_openmp_endStopBeforeMatch);
932        }
933      }
934      // Skip the last annot_pragma_openmp_end.
935      ConsumeAnnotationToken();
936      return Actions.ActOnOpenMPAllocateDirective(Loc, Helper.getIdentifiers(),
937                                                  Clauses);
938    }
939    break;
940  }
941  case OMPD_requires: {
942    SourceLocation StartLoc = ConsumeToken();
943    SmallVector<OMPClause *, 5Clauses;
944    SmallVector<llvm::PointerIntPair<OMPClause *, 1bool>, OMPC_unknown + 1>
945    FirstClauses(OMPC_unknown + 1);
946    if (Tok.is(tok::annot_pragma_openmp_end)) {
947      Diag(Tok, diag::err_omp_expected_clause)
948          << getOpenMPDirectiveName(OMPD_requires);
949      break;
950    }
951    while (Tok.isNot(tok::annot_pragma_openmp_end)) {
952      OpenMPClauseKind CKind = Tok.isAnnotation()
953                                   ? OMPC_unknown
954                                   : getOpenMPClauseKind(PP.getSpelling(Tok));
955      Actions.StartOpenMPClause(CKind);
956      OMPClause *Clause = ParseOpenMPClause(OMPD_requires, CKind,
957                                            !FirstClauses[CKind].getInt());
958      SkipUntil(tok::commatok::identifiertok::annot_pragma_openmp_end,
959                StopBeforeMatch);
960      FirstClauses[CKind].setInt(true);
961      if (Clause != nullptr)
962        Clauses.push_back(Clause);
963      if (Tok.is(tok::annot_pragma_openmp_end)) {
964        Actions.EndOpenMPClause();
965        break;
966      }
967      // Skip ',' if any.
968      if (Tok.is(tok::comma))
969        ConsumeToken();
970      Actions.EndOpenMPClause();
971    }
972    // Consume final annot_pragma_openmp_end
973    if (Clauses.size() == 0) {
974      Diag(Tok, diag::err_omp_expected_clause)
975          << getOpenMPDirectiveName(OMPD_requires);
976      ConsumeAnnotationToken();
977      return nullptr;
978    }
979    ConsumeAnnotationToken();
980    return Actions.ActOnOpenMPRequiresDirective(StartLoc, Clauses);
981  }
982  case OMPD_declare_reduction:
983    ConsumeToken();
984    if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
985      // The last seen token is annot_pragma_openmp_end - need to check for
986      // extra tokens.
987      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
988        Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
989            << getOpenMPDirectiveName(OMPD_declare_reduction);
990        while (Tok.isNot(tok::annot_pragma_openmp_end))
991          ConsumeAnyToken();
992      }
993      // Skip the last annot_pragma_openmp_end.
994      ConsumeAnnotationToken();
995      return Res;
996    }
997    break;
998  case OMPD_declare_mapper: {
999    ConsumeToken();
1000    if (DeclGroupPtrTy Res = ParseOpenMPDeclareMapperDirective(AS)) {
1001      // Skip the last annot_pragma_openmp_end.
1002      ConsumeAnnotationToken();
1003      return Res;
1004    }
1005    break;
1006  }
1007  case OMPD_declare_simd: {
1008    // The syntax is:
1009    // { #pragma omp declare simd }
1010    // <function-declaration-or-definition>
1011    //
1012    ConsumeToken();
1013    CachedTokens Toks;
1014    while(Tok.isNot(tok::annot_pragma_openmp_end)) {
1015      Toks.push_back(Tok);
1016      ConsumeAnyToken();
1017    }
1018    Toks.push_back(Tok);
1019    ConsumeAnyToken();
1020
1021    DeclGroupPtrTy Ptr;
1022    if (Tok.is(tok::annot_pragma_openmp)) {
1023      Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(ASAttrsTagTypeTag);
1024    } else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
1025      // Here we expect to see some function declaration.
1026      if (AS == AS_none) {
1027        assert(TagType == DeclSpec::TST_unspecified);
1028        MaybeParseCXX11Attributes(Attrs);
1029        ParsingDeclSpec PDS(*this);
1030        Ptr = ParseExternalDeclaration(Attrs, &PDS);
1031      } else {
1032        Ptr =
1033            ParseCXXClassMemberDeclarationWithPragmas(ASAttrsTagTypeTag);
1034      }
1035    }
1036    if (!Ptr) {
1037      Diag(Loc, diag::err_omp_decl_in_declare_simd);
1038      return DeclGroupPtrTy();
1039    }
1040    return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
1041  }
1042  case OMPD_declare_target: {
1043    SourceLocation DTLoc = ConsumeAnyToken();
1044    if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1045      return ParseOMPDeclareTargetClauses();
1046    }
1047
1048    // Skip the last annot_pragma_openmp_end.
1049    ConsumeAnyToken();
1050
1051    if (!Actions.ActOnStartOpenMPDeclareTargetDirective(DTLoc))
1052      return DeclGroupPtrTy();
1053
1054    llvm::SmallVector<Decl *, 4>  Decls;
1055    DKind = parseOpenMPDirectiveKind(*this);
1056    while (DKind != OMPD_end_declare_target && Tok.isNot(tok::eof) &&
1057           Tok.isNot(tok::r_brace)) {
1058      DeclGroupPtrTy Ptr;
1059      // Here we expect to see some function declaration.
1060      if (AS == AS_none) {
1061        assert(TagType == DeclSpec::TST_unspecified);
1062        MaybeParseCXX11Attributes(Attrs);
1063        ParsingDeclSpec PDS(*this);
1064        Ptr = ParseExternalDeclaration(Attrs, &PDS);
1065      } else {
1066        Ptr =
1067            ParseCXXClassMemberDeclarationWithPragmas(ASAttrsTagTypeTag);
1068      }
1069      if (Ptr) {
1070        DeclGroupRef Ref = Ptr.get();
1071        Decls.append(Ref.begin(), Ref.end());
1072      }
1073      if (Tok.isAnnotation() && Tok.is(tok::annot_pragma_openmp)) {
1074        TentativeParsingAction TPA(*this);
1075        ConsumeAnnotationToken();
1076        DKind = parseOpenMPDirectiveKind(*this);
1077        if (DKind != OMPD_end_declare_target)
1078          TPA.Revert();
1079        else
1080          TPA.Commit();
1081      }
1082    }
1083
1084    ParseOMPEndDeclareTargetDirective(DKindDTLoc);
1085    Actions.ActOnFinishOpenMPDeclareTargetDirective();
1086    return Actions.BuildDeclaratorGroup(Decls);
1087  }
1088  case OMPD_unknown:
1089    Diag(Tok, diag::err_omp_unknown_directive);
1090    break;
1091  case OMPD_parallel:
1092  case OMPD_simd:
1093  case OMPD_task:
1094  case OMPD_taskyield:
1095  case OMPD_barrier:
1096  case OMPD_taskwait:
1097  case OMPD_taskgroup:
1098  case OMPD_flush:
1099  case OMPD_for:
1100  case OMPD_for_simd:
1101  case OMPD_sections:
1102  case OMPD_section:
1103  case OMPD_single:
1104  case OMPD_master:
1105  case OMPD_ordered:
1106  case OMPD_critical:
1107  case OMPD_parallel_for:
1108  case OMPD_parallel_for_simd:
1109  case OMPD_parallel_sections:
1110  case OMPD_atomic:
1111  case OMPD_target:
1112  case OMPD_teams:
1113  case OMPD_cancellation_point:
1114  case OMPD_cancel:
1115  case OMPD_target_data:
1116  case OMPD_target_enter_data:
1117  case OMPD_target_exit_data:
1118  case OMPD_target_parallel:
1119  case OMPD_target_parallel_for:
1120  case OMPD_taskloop:
1121  case OMPD_taskloop_simd:
1122  case OMPD_distribute:
1123  case OMPD_end_declare_target:
1124  case OMPD_target_update:
1125  case OMPD_distribute_parallel_for:
1126  case OMPD_distribute_parallel_for_simd:
1127  case OMPD_distribute_simd:
1128  case OMPD_target_parallel_for_simd:
1129  case OMPD_target_simd:
1130  case OMPD_teams_distribute:
1131  case OMPD_teams_distribute_simd:
1132  case OMPD_teams_distribute_parallel_for_simd:
1133  case OMPD_teams_distribute_parallel_for:
1134  case OMPD_target_teams:
1135  case OMPD_target_teams_distribute:
1136  case OMPD_target_teams_distribute_parallel_for:
1137  case OMPD_target_teams_distribute_parallel_for_simd:
1138  case OMPD_target_teams_distribute_simd:
1139    Diag(Tok, diag::err_omp_unexpected_directive)
1140        << 1 << getOpenMPDirectiveName(DKind);
1141    break;
1142  }
1143  while (Tok.isNot(tok::annot_pragma_openmp_end))
1144    ConsumeAnyToken();
1145  ConsumeAnyToken();
1146  return nullptr;
1147}
1148
1149/// Parsing of declarative or executable OpenMP directives.
1150///
1151///       threadprivate-directive:
1152///         annot_pragma_openmp 'threadprivate' simple-variable-list
1153///         annot_pragma_openmp_end
1154///
1155///       allocate-directive:
1156///         annot_pragma_openmp 'allocate' simple-variable-list
1157///         annot_pragma_openmp_end
1158///
1159///       declare-reduction-directive:
1160///         annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
1161///         <type> {',' <type>} ':' <expression> ')' ['initializer' '('
1162///         ('omp_priv' '=' <expression>|<function_call>) ')']
1163///         annot_pragma_openmp_end
1164///
1165///       declare-mapper-directive:
1166///         annot_pragma_openmp 'declare' 'mapper' '(' [<mapper-identifer> ':']
1167///         <type> <var> ')' [<clause>[[,] <clause>] ... ]
1168///         annot_pragma_openmp_end
1169///
1170///       executable-directive:
1171///         annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
1172///         'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
1173///         'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
1174///         'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' |
1175///         'for simd' | 'parallel for simd' | 'target' | 'target data' |
1176///         'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
1177///         'distribute' | 'target enter data' | 'target exit data' |
1178///         'target parallel' | 'target parallel for' |
1179///         'target update' | 'distribute parallel for' |
1180///         'distribute paralle for simd' | 'distribute simd' |
1181///         'target parallel for simd' | 'target simd' |
1182///         'teams distribute' | 'teams distribute simd' |
1183///         'teams distribute parallel for simd' |
1184///         'teams distribute parallel for' | 'target teams' |
1185///         'target teams distribute' |
1186///         'target teams distribute parallel for' |
1187///         'target teams distribute parallel for simd' |
1188///         'target teams distribute simd' {clause}
1189///         annot_pragma_openmp_end
1190///
1191StmtResult
1192Parser::ParseOpenMPDeclarativeOrExecutableDirective(ParsedStmtContext StmtCtx) {
1193   (0) . __assert_fail ("Tok.is(tok..annot_pragma_openmp) && \"Not an OpenMP directive!\"", "/home/seafit/code_projects/clang_source/clang/lib/Parse/ParseOpenMP.cpp", 1193, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
1194  ParenBraceBracketBalancer BalancerRAIIObj(*this);
1195  SmallVector<OMPClause *, 5Clauses;
1196  SmallVector<llvm::PointerIntPair<OMPClause *, 1bool>, OMPC_unknown + 1>
1197  FirstClauses(OMPC_unknown + 1);
1198  unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
1199                        Scope::CompoundStmtScope | Scope::OpenMPDirectiveScope;
1200  SourceLocation Loc = ConsumeAnnotationToken(), EndLoc;
1201  OpenMPDirectiveKind DKind = parseOpenMPDirectiveKind(*this);
1202  OpenMPDirectiveKind CancelRegion = OMPD_unknown;
1203  // Name of critical directive.
1204  DeclarationNameInfo DirName;
1205  StmtResult Directive = StmtError();
1206  bool HasAssociatedStatement = true;
1207  bool FlushHasClause = false;
1208
1209  switch (DKind) {
1210  case OMPD_threadprivate: {
1211    // FIXME: Should this be permitted in C++?
1212    if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
1213        ParsedStmtContext()) {
1214      Diag(Tok, diag::err_omp_immediate_directive)
1215          << getOpenMPDirectiveName(DKind) << 0;
1216    }
1217    ConsumeToken();
1218    DeclDirectiveListParserHelper Helper(thisDKind);
1219    if (!ParseOpenMPSimpleVarList(DKind, Helper,
1220                                  /*AllowScopeSpecifier=*/false)) {
1221      // The last seen token is annot_pragma_openmp_end - need to check for
1222      // extra tokens.
1223      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1224        Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1225            << getOpenMPDirectiveName(DKind);
1226        SkipUntil(tok::annot_pragma_openmp_endStopBeforeMatch);
1227      }
1228      DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
1229          LocHelper.getIdentifiers());
1230      Directive = Actions.ActOnDeclStmt(ResLocTok.getLocation());
1231    }
1232    SkipUntil(tok::annot_pragma_openmp_end);
1233    break;
1234  }
1235  case OMPD_allocate: {
1236    // FIXME: Should this be permitted in C++?
1237    if ((StmtCtx & ParsedStmtContext::AllowDeclarationsInC) ==
1238        ParsedStmtContext()) {
1239      Diag(Tok, diag::err_omp_immediate_directive)
1240          << getOpenMPDirectiveName(DKind) << 0;
1241    }
1242    ConsumeToken();
1243    DeclDirectiveListParserHelper Helper(thisDKind);
1244    if (!ParseOpenMPSimpleVarList(DKind, Helper,
1245                                  /*AllowScopeSpecifier=*/false)) {
1246      SmallVector<OMPClause *, 1Clauses;
1247      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1248        SmallVector<llvm::PointerIntPair<OMPClause *, 1bool>,
1249                    OMPC_unknown + 1>
1250            FirstClauses(OMPC_unknown + 1);
1251        while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1252          OpenMPClauseKind CKind =
1253              Tok.isAnnotation() ? OMPC_unknown
1254                                 : getOpenMPClauseKind(PP.getSpelling(Tok));
1255          Actions.StartOpenMPClause(CKind);
1256          OMPClause *Clause = ParseOpenMPClause(OMPD_allocate, CKind,
1257                                                !FirstClauses[CKind].getInt());
1258          SkipUntil(tok::commatok::identifiertok::annot_pragma_openmp_end,
1259                    StopBeforeMatch);
1260          FirstClauses[CKind].setInt(true);
1261          if (Clause != nullptr)
1262            Clauses.push_back(Clause);
1263          if (Tok.is(tok::annot_pragma_openmp_end)) {
1264            Actions.EndOpenMPClause();
1265            break;
1266          }
1267          // Skip ',' if any.
1268          if (Tok.is(tok::comma))
1269            ConsumeToken();
1270          Actions.EndOpenMPClause();
1271        }
1272        // The last seen token is annot_pragma_openmp_end - need to check for
1273        // extra tokens.
1274        if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1275          Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1276              << getOpenMPDirectiveName(DKind);
1277          SkipUntil(tok::annot_pragma_openmp_endStopBeforeMatch);
1278        }
1279      }
1280      DeclGroupPtrTy Res = Actions.ActOnOpenMPAllocateDirective(
1281          Loc, Helper.getIdentifiers(), Clauses);
1282      Directive = Actions.ActOnDeclStmt(ResLocTok.getLocation());
1283    }
1284    SkipUntil(tok::annot_pragma_openmp_end);
1285    break;
1286  }
1287  case OMPD_declare_reduction:
1288    ConsumeToken();
1289    if (DeclGroupPtrTy Res =
1290            ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
1291      // The last seen token is annot_pragma_openmp_end - need to check for
1292      // extra tokens.
1293      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
1294        Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1295            << getOpenMPDirectiveName(OMPD_declare_reduction);
1296        while (Tok.isNot(tok::annot_pragma_openmp_end))
1297          ConsumeAnyToken();
1298      }
1299      ConsumeAnyToken();
1300      Directive = Actions.ActOnDeclStmt(ResLocTok.getLocation());
1301    } else {
1302      SkipUntil(tok::annot_pragma_openmp_end);
1303    }
1304    break;
1305  case OMPD_declare_mapper: {
1306    ConsumeToken();
1307    if (DeclGroupPtrTy Res =
1308            ParseOpenMPDeclareMapperDirective(/*AS=*/AS_none)) {
1309      // Skip the last annot_pragma_openmp_end.
1310      ConsumeAnnotationToken();
1311      Directive = Actions.ActOnDeclStmt(ResLocTok.getLocation());
1312    } else {
1313      SkipUntil(tok::annot_pragma_openmp_end);
1314    }
1315    break;
1316  }
1317  case OMPD_flush:
1318    if (PP.LookAhead(0).is(tok::l_paren)) {
1319      FlushHasClause = true;
1320      // Push copy of the current token back to stream to properly parse
1321      // pseudo-clause OMPFlushClause.
1322      PP.EnterToken(Tok);
1323    }
1324    LLVM_FALLTHROUGH;
1325  case OMPD_taskyield:
1326  case OMPD_barrier:
1327  case OMPD_taskwait:
1328  case OMPD_cancellation_point:
1329  case OMPD_cancel:
1330  case OMPD_target_enter_data:
1331  case OMPD_target_exit_data:
1332  case OMPD_target_update:
1333    if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
1334        ParsedStmtContext()) {
1335      Diag(Tok, diag::err_omp_immediate_directive)
1336          << getOpenMPDirectiveName(DKind) << 0;
1337    }
1338    HasAssociatedStatement = false;
1339    // Fall through for further analysis.
1340    LLVM_FALLTHROUGH;
1341  case OMPD_parallel:
1342  case OMPD_simd:
1343  case OMPD_for:
1344  case OMPD_for_simd:
1345  case OMPD_sections:
1346  case OMPD_single:
1347  case OMPD_section:
1348  case OMPD_master:
1349  case OMPD_critical:
1350  case OMPD_parallel_for:
1351  case OMPD_parallel_for_simd:
1352  case OMPD_parallel_sections:
1353  case OMPD_task:
1354  case OMPD_ordered:
1355  case OMPD_atomic:
1356  case OMPD_target:
1357  case OMPD_teams:
1358  case OMPD_taskgroup:
1359  case OMPD_target_data:
1360  case OMPD_target_parallel:
1361  case OMPD_target_parallel_for:
1362  case OMPD_taskloop:
1363  case OMPD_taskloop_simd:
1364  case OMPD_distribute:
1365  case OMPD_distribute_parallel_for:
1366  case OMPD_distribute_parallel_for_simd:
1367  case OMPD_distribute_simd:
1368  case OMPD_target_parallel_for_simd:
1369  case OMPD_target_simd:
1370  case OMPD_teams_distribute:
1371  case OMPD_teams_distribute_simd:
1372  case OMPD_teams_distribute_parallel_for_simd:
1373  case OMPD_teams_distribute_parallel_for:
1374  case OMPD_target_teams:
1375  case OMPD_target_teams_distribute:
1376  case OMPD_target_teams_distribute_parallel_for:
1377  case OMPD_target_teams_distribute_parallel_for_simd:
1378  case OMPD_target_teams_distribute_simd: {
1379    ConsumeToken();
1380    // Parse directive name of the 'critical' directive if any.
1381    if (DKind == OMPD_critical) {
1382      BalancedDelimiterTracker T(*thistok::l_paren,
1383                                 tok::annot_pragma_openmp_end);
1384      if (!T.consumeOpen()) {
1385        if (Tok.isAnyIdentifier()) {
1386          DirName =
1387              DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
1388          ConsumeAnyToken();
1389        } else {
1390          Diag(Tok, diag::err_omp_expected_identifier_for_critical);
1391        }
1392        T.consumeClose();
1393      }
1394    } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
1395      CancelRegion = parseOpenMPDirectiveKind(*this);
1396      if (Tok.isNot(tok::annot_pragma_openmp_end))
1397        ConsumeToken();
1398    }
1399
1400    if (isOpenMPLoopDirective(DKind))
1401      ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
1402    if (isOpenMPSimdDirective(DKind))
1403      ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
1404    ParseScope OMPDirectiveScope(thisScopeFlags);
1405    Actions.StartOpenMPDSABlock(DKindDirNameActions.getCurScope(), Loc);
1406
1407    while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1408      OpenMPClauseKind CKind =
1409          Tok.isAnnotation()
1410              ? OMPC_unknown
1411              : FlushHasClause ? OMPC_flush
1412                               : getOpenMPClauseKind(PP.getSpelling(Tok));
1413      Actions.StartOpenMPClause(CKind);
1414      FlushHasClause = false;
1415      OMPClause *Clause =
1416          ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
1417      FirstClauses[CKind].setInt(true);
1418      if (Clause) {
1419        FirstClauses[CKind].setPointer(Clause);
1420        Clauses.push_back(Clause);
1421      }
1422
1423      // Skip ',' if any.
1424      if (Tok.is(tok::comma))
1425        ConsumeToken();
1426      Actions.EndOpenMPClause();
1427    }
1428    // End location of the directive.
1429    EndLoc = Tok.getLocation();
1430    // Consume final annot_pragma_openmp_end.
1431    ConsumeAnnotationToken();
1432
1433    // OpenMP [2.13.8, ordered Construct, Syntax]
1434    // If the depend clause is specified, the ordered construct is a stand-alone
1435    // directive.
1436    if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) {
1437      if ((StmtCtx & ParsedStmtContext::AllowStandaloneOpenMPDirectives) ==
1438          ParsedStmtContext()) {
1439        Diag(Loc, diag::err_omp_immediate_directive)
1440            << getOpenMPDirectiveName(DKind) << 1
1441            << getOpenMPClauseName(OMPC_depend);
1442      }
1443      HasAssociatedStatement = false;
1444    }
1445
1446    StmtResult AssociatedStmt;
1447    if (HasAssociatedStatement) {
1448      // The body is a block scope like in Lambdas and Blocks.
1449      Actions.ActOnOpenMPRegionStart(DKindgetCurScope());
1450      // FIXME: We create a bogus CompoundStmt scope to hold the contents of
1451      // the captured region. Code elsewhere assumes that any FunctionScopeInfo
1452      // should have at least one compound statement scope within it.
1453      AssociatedStmt = (Sema::CompoundScopeRAII(Actions), ParseStatement());
1454      AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
1455    } else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
1456               DKind == OMPD_target_exit_data) {
1457      Actions.ActOnOpenMPRegionStart(DKindgetCurScope());
1458      AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
1459                        Actions.ActOnCompoundStmt(Loc, Loc, llvm::None,
1460                                                  /*isStmtExpr=*/false));
1461      AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
1462    }
1463    Directive = Actions.ActOnOpenMPExecutableDirective(
1464        DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
1465        EndLoc);
1466
1467    // Exit scope.
1468    Actions.EndOpenMPDSABlock(Directive.get());
1469    OMPDirectiveScope.Exit();
1470    break;
1471  }
1472  case OMPD_declare_simd:
1473  case OMPD_declare_target:
1474  case OMPD_end_declare_target:
1475  case OMPD_requires:
1476    Diag(Tok, diag::err_omp_unexpected_directive)
1477        << 1 << getOpenMPDirectiveName(DKind);
1478    SkipUntil(tok::annot_pragma_openmp_end);
1479    break;
1480  case OMPD_unknown:
1481    Diag(Tok, diag::err_omp_unknown_directive);
1482    SkipUntil(tok::annot_pragma_openmp_end);
1483    break;
1484  }
1485  return Directive;
1486}
1487
1488// Parses simple list:
1489//   simple-variable-list:
1490//         '(' id-expression {, id-expression} ')'
1491//
1492bool Parser::ParseOpenMPSimpleVarList(
1493    OpenMPDirectiveKind Kind,
1494    const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> &
1495        Callback,
1496    bool AllowScopeSpecifier) {
1497  // Parse '('.
1498  BalancedDelimiterTracker T(*thistok::l_parentok::annot_pragma_openmp_end);
1499  if (T.expectAndConsume(diag::err_expected_lparen_after,
1500                         getOpenMPDirectiveName(Kind)))
1501    return true;
1502  bool IsCorrect = true;
1503  bool NoIdentIsFound = true;
1504
1505  // Read tokens while ')' or annot_pragma_openmp_end is not found.
1506  while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
1507    CXXScopeSpec SS;
1508    UnqualifiedId Name;
1509    // Read var name.
1510    Token PrevTok = Tok;
1511    NoIdentIsFound = false;
1512
1513    if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
1514        ParseOptionalCXXScopeSpecifier(SSnullptrfalse)) {
1515      IsCorrect = false;
1516      SkipUntil(tok::commatok::r_parentok::annot_pragma_openmp_end,
1517                StopBeforeMatch);
1518    } else if (ParseUnqualifiedId(SSfalsefalsefalsefalsenullptr,
1519                                  nullptrName)) {
1520      IsCorrect = false;
1521      SkipUntil(tok::commatok::r_parentok::annot_pragma_openmp_end,
1522                StopBeforeMatch);
1523    } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
1524               Tok.isNot(tok::annot_pragma_openmp_end)) {
1525      IsCorrect = false;
1526      SkipUntil(tok::commatok::r_parentok::annot_pragma_openmp_end,
1527                StopBeforeMatch);
1528      Diag(PrevTok.getLocation(), diag::err_expected)
1529          << tok::identifier
1530          << SourceRange(PrevTok.getLocation(), PrevTokLocation);
1531    } else {
1532      Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
1533    }
1534    // Consume ','.
1535    if (Tok.is(tok::comma)) {
1536      ConsumeToken();
1537    }
1538  }
1539
1540  if (NoIdentIsFound) {
1541    Diag(Tok, diag::err_expected) << tok::identifier;
1542    IsCorrect = false;
1543  }
1544
1545  // Parse ')'.
1546  IsCorrect = !T.consumeClose() && IsCorrect;
1547
1548  return !IsCorrect;
1549}
1550
1551/// Parsing of OpenMP clauses.
1552///
1553///    clause:
1554///       if-clause | final-clause | num_threads-clause | safelen-clause |
1555///       default-clause | private-clause | firstprivate-clause | shared-clause
1556///       | linear-clause | aligned-clause | collapse-clause |
1557///       lastprivate-clause | reduction-clause | proc_bind-clause |
1558///       schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
1559///       mergeable-clause | flush-clause | read-clause | write-clause |
1560///       update-clause | capture-clause | seq_cst-clause | device-clause |
1561///       simdlen-clause | threads-clause | simd-clause | num_teams-clause |
1562///       thread_limit-clause | priority-clause | grainsize-clause |
1563///       nogroup-clause | num_tasks-clause | hint-clause | to-clause |
1564///       from-clause | is_device_ptr-clause | task_reduction-clause |
1565///       in_reduction-clause | allocator-clause | allocate-clause
1566///
1567OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
1568                                     OpenMPClauseKind CKindbool FirstClause) {
1569  OMPClause *Clause = nullptr;
1570  bool ErrorFound = false;
1571  bool WrongDirective = false;
1572  // Check if clause is allowed for the given directive.
1573  if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKindCKind)) {
1574    Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
1575                                               << getOpenMPDirectiveName(DKind);
1576    ErrorFound = true;
1577    WrongDirective = true;
1578  }
1579
1580  switch (CKind) {
1581  case OMPC_final:
1582  case OMPC_num_threads:
1583  case OMPC_safelen:
1584  case OMPC_simdlen:
1585  case OMPC_collapse:
1586  case OMPC_ordered:
1587  case OMPC_device:
1588  case OMPC_num_teams:
1589  case OMPC_thread_limit:
1590  case OMPC_priority:
1591  case OMPC_grainsize:
1592  case OMPC_num_tasks:
1593  case OMPC_hint:
1594  case OMPC_allocator:
1595    // OpenMP [2.5, Restrictions]
1596    //  At most one num_threads clause can appear on the directive.
1597    // OpenMP [2.8.1, simd construct, Restrictions]
1598    //  Only one safelen  clause can appear on a simd directive.
1599    //  Only one simdlen  clause can appear on a simd directive.
1600    //  Only one collapse clause can appear on a simd directive.
1601    // OpenMP [2.9.1, target data construct, Restrictions]
1602    //  At most one device clause can appear on the directive.
1603    // OpenMP [2.11.1, task Construct, Restrictions]
1604    //  At most one if clause can appear on the directive.
1605    //  At most one final clause can appear on the directive.
1606    // OpenMP [teams Construct, Restrictions]
1607    //  At most one num_teams clause can appear on the directive.
1608    //  At most one thread_limit clause can appear on the directive.
1609    // OpenMP [2.9.1, task Construct, Restrictions]
1610    // At most one priority clause can appear on the directive.
1611    // OpenMP [2.9.2, taskloop Construct, Restrictions]
1612    // At most one grainsize clause can appear on the directive.
1613    // OpenMP [2.9.2, taskloop Construct, Restrictions]
1614    // At most one num_tasks clause can appear on the directive.
1615    // OpenMP [2.11.3, allocate Directive, Restrictions]
1616    // At most one allocator clause can appear on the directive.
1617    if (!FirstClause) {
1618      Diag(Tok, diag::err_omp_more_one_clause)
1619          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1620      ErrorFound = true;
1621    }
1622
1623    if (CKind == OMPC_ordered && PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
1624      Clause = ParseOpenMPClause(CKindWrongDirective);
1625    else
1626      Clause = ParseOpenMPSingleExprClause(CKindWrongDirective);
1627    break;
1628  case OMPC_default:
1629  case OMPC_proc_bind:
1630  case OMPC_atomic_default_mem_order:
1631    // OpenMP [2.14.3.1, Restrictions]
1632    //  Only a single default clause may be specified on a parallel, task or
1633    //  teams directive.
1634    // OpenMP [2.5, parallel Construct, Restrictions]
1635    //  At most one proc_bind clause can appear on the directive.
1636    // OpenMP [5.0, Requires directive, Restrictions]
1637    //  At most one atomic_default_mem_order clause can appear
1638    //  on the directive
1639    if (!FirstClause) {
1640      Diag(Tok, diag::err_omp_more_one_clause)
1641          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1642      ErrorFound = true;
1643    }
1644
1645    Clause = ParseOpenMPSimpleClause(CKindWrongDirective);
1646    break;
1647  case OMPC_schedule:
1648  case OMPC_dist_schedule:
1649  case OMPC_defaultmap:
1650    // OpenMP [2.7.1, Restrictions, p. 3]
1651    //  Only one schedule clause can appear on a loop directive.
1652    // OpenMP [2.10.4, Restrictions, p. 106]
1653    //  At most one defaultmap clause can appear on the directive.
1654    if (!FirstClause) {
1655      Diag(Tok, diag::err_omp_more_one_clause)
1656          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1657      ErrorFound = true;
1658    }
1659    LLVM_FALLTHROUGH;
1660
1661  case OMPC_if:
1662    Clause = ParseOpenMPSingleExprWithArgClause(CKindWrongDirective);
1663    break;
1664  case OMPC_nowait:
1665  case OMPC_untied:
1666  case OMPC_mergeable:
1667  case OMPC_read:
1668  case OMPC_write:
1669  case OMPC_update:
1670  case OMPC_capture:
1671  case OMPC_seq_cst:
1672  case OMPC_threads:
1673  case OMPC_simd:
1674  case OMPC_nogroup:
1675  case OMPC_unified_address:
1676  case OMPC_unified_shared_memory:
1677  case OMPC_reverse_offload:
1678  case OMPC_dynamic_allocators:
1679    // OpenMP [2.7.1, Restrictions, p. 9]
1680    //  Only one ordered clause can appear on a loop directive.
1681    // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
1682    //  Only one nowait clause can appear on a for directive.
1683    // OpenMP [5.0, Requires directive, Restrictions]
1684    //   Each of the requires clauses can appear at most once on the directive.
1685    if (!FirstClause) {
1686      Diag(Tok, diag::err_omp_more_one_clause)
1687          << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1688      ErrorFound = true;
1689    }
1690
1691    Clause = ParseOpenMPClause(CKindWrongDirective);
1692    break;
1693  case OMPC_private:
1694  case OMPC_firstprivate:
1695  case OMPC_lastprivate:
1696  case OMPC_shared:
1697  case OMPC_reduction:
1698  case OMPC_task_reduction:
1699  case OMPC_in_reduction:
1700  case OMPC_linear:
1701  case OMPC_aligned:
1702  case OMPC_copyin:
1703  case OMPC_copyprivate:
1704  case OMPC_flush:
1705  case OMPC_depend:
1706  case OMPC_map:
1707  case OMPC_to:
1708  case OMPC_from:
1709  case OMPC_use_device_ptr:
1710  case OMPC_is_device_ptr:
1711  case OMPC_allocate:
1712    Clause = ParseOpenMPVarListClause(DKindCKindWrongDirective);
1713    break;
1714  case OMPC_unknown:
1715    Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1716        << getOpenMPDirectiveName(DKind);
1717    SkipUntil(tok::annot_pragma_openmp_endStopBeforeMatch);
1718    break;
1719  case OMPC_threadprivate:
1720  case OMPC_uniform:
1721    if (!WrongDirective)
1722      Diag(Tok, diag::err_omp_unexpected_clause)
1723          << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
1724    SkipUntil(tok::commatok::annot_pragma_openmp_endStopBeforeMatch);
1725    break;
1726  }
1727  return ErrorFound ? nullptr : Clause;
1728}
1729
1730/// Parses simple expression in parens for single-expression clauses of OpenMP
1731/// constructs.
1732/// \param RLoc Returned location of right paren.
1733ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName,
1734                                         SourceLocation &RLoc) {
1735  BalancedDelimiterTracker T(*thistok::l_parentok::annot_pragma_openmp_end);
1736  if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
1737    return ExprError();
1738
1739  SourceLocation ELoc = Tok.getLocation();
1740  ExprResult LHS(ParseCastExpression(
1741      /*isUnaryExpression=*/false/*isAddressOfOperand=*/falseNotTypeCast));
1742  ExprResult Val(ParseRHSOfBinaryExpression(LHSprec::Conditional));
1743  Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc/*DiscardedValue*/ false);
1744
1745  // Parse ')'.
1746  RLoc = Tok.getLocation();
1747  if (!T.consumeClose())
1748    RLoc = T.getCloseLocation();
1749
1750  return Val;
1751}
1752
1753/// Parsing of OpenMP clauses with single expressions like 'final',
1754/// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
1755/// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks' or 'hint'.
1756///
1757///    final-clause:
1758///      'final' '(' expression ')'
1759///
1760///    num_threads-clause:
1761///      'num_threads' '(' expression ')'
1762///
1763///    safelen-clause:
1764///      'safelen' '(' expression ')'
1765///
1766///    simdlen-clause:
1767///      'simdlen' '(' expression ')'
1768///
1769///    collapse-clause:
1770///      'collapse' '(' expression ')'
1771///
1772///    priority-clause:
1773///      'priority' '(' expression ')'
1774///
1775///    grainsize-clause:
1776///      'grainsize' '(' expression ')'
1777///
1778///    num_tasks-clause:
1779///      'num_tasks' '(' expression ')'
1780///
1781///    hint-clause:
1782///      'hint' '(' expression ')'
1783///
1784///    allocator-clause:
1785///      'allocator' '(' expression ')'
1786///
1787OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
1788                                               bool ParseOnly) {
1789  SourceLocation Loc = ConsumeToken();
1790  SourceLocation LLoc = Tok.getLocation();
1791  SourceLocation RLoc;
1792
1793  ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc);
1794
1795  if (Val.isInvalid())
1796    return nullptr;
1797
1798  if (ParseOnly)
1799    return nullptr;
1800  return Actions.ActOnOpenMPSingleExprClause(KindVal.get(), LocLLocRLoc);
1801}
1802
1803/// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
1804///
1805///    default-clause:
1806///         'default' '(' 'none' | 'shared' ')
1807///
1808///    proc_bind-clause:
1809///         'proc_bind' '(' 'master' | 'close' | 'spread' ')
1810///
1811OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind,
1812                                           bool ParseOnly) {
1813  SourceLocation Loc = Tok.getLocation();
1814  SourceLocation LOpen = ConsumeToken();
1815  // Parse '('.
1816  BalancedDelimiterTracker T(*thistok::l_parentok::annot_pragma_openmp_end);
1817  if (T.expectAndConsume(diag::err_expected_lparen_after,
1818                         getOpenMPClauseName(Kind)))
1819    return nullptr;
1820
1821  unsigned Type = getOpenMPSimpleClauseType(
1822      KindTok.isAnnotation() ? "" : PP.getSpelling(Tok));
1823  SourceLocation TypeLoc = Tok.getLocation();
1824  if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1825      Tok.isNot(tok::annot_pragma_openmp_end))
1826    ConsumeAnyToken();
1827
1828  // Parse ')'.
1829  SourceLocation RLoc = Tok.getLocation();
1830  if (!T.consumeClose())
1831    RLoc = T.getCloseLocation();
1832
1833  if (ParseOnly)
1834    return nullptr;
1835  return Actions.ActOnOpenMPSimpleClause(KindTypeTypeLocLOpenLocRLoc);
1836}
1837
1838/// Parsing of OpenMP clauses like 'ordered'.
1839///
1840///    ordered-clause:
1841///         'ordered'
1842///
1843///    nowait-clause:
1844///         'nowait'
1845///
1846///    untied-clause:
1847///         'untied'
1848///
1849///    mergeable-clause:
1850///         'mergeable'
1851///
1852///    read-clause:
1853///         'read'
1854///
1855///    threads-clause:
1856///         'threads'
1857///
1858///    simd-clause:
1859///         'simd'
1860///
1861///    nogroup-clause:
1862///         'nogroup'
1863///
1864OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kindbool ParseOnly) {
1865  SourceLocation Loc = Tok.getLocation();
1866  ConsumeAnyToken();
1867
1868  if (ParseOnly)
1869    return nullptr;
1870  return Actions.ActOnOpenMPClause(KindLocTok.getLocation());
1871}
1872
1873
1874/// Parsing of OpenMP clauses with single expressions and some additional
1875/// argument like 'schedule' or 'dist_schedule'.
1876///
1877///    schedule-clause:
1878///      'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
1879///      ')'
1880///
1881///    if-clause:
1882///      'if' '(' [ directive-name-modifier ':' ] expression ')'
1883///
1884///    defaultmap:
1885///      'defaultmap' '(' modifier ':' kind ')'
1886///
1887OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,
1888                                                      bool ParseOnly) {
1889  SourceLocation Loc = ConsumeToken();
1890  SourceLocation DelimLoc;
1891  // Parse '('.
1892  BalancedDelimiterTracker T(*thistok::l_parentok::annot_pragma_openmp_end);
1893  if (T.expectAndConsume(diag::err_expected_lparen_after,
1894                         getOpenMPClauseName(Kind)))
1895    return nullptr;
1896
1897  ExprResult Val;
1898  SmallVector<unsigned4Arg;
1899  SmallVector<SourceLocation4KLoc;
1900  if (Kind == OMPC_schedule) {
1901    enum { Modifier1Modifier2ScheduleKindNumberOfElements };
1902    Arg.resize(NumberOfElements);
1903    KLoc.resize(NumberOfElements);
1904    Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
1905    Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
1906    Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
1907    unsigned KindModifier = getOpenMPSimpleClauseType(
1908        KindTok.isAnnotation() ? "" : PP.getSpelling(Tok));
1909    if (KindModifier > OMPC_SCHEDULE_unknown) {
1910      // Parse 'modifier'
1911      Arg[Modifier1] = KindModifier;
1912      KLoc[Modifier1] = Tok.getLocation();
1913      if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1914          Tok.isNot(tok::annot_pragma_openmp_end))
1915        ConsumeAnyToken();
1916      if (Tok.is(tok::comma)) {
1917        // Parse ',' 'modifier'
1918        ConsumeAnyToken();
1919        KindModifier = getOpenMPSimpleClauseType(
1920            KindTok.isAnnotation() ? "" : PP.getSpelling(Tok));
1921        Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown
1922                             ? KindModifier
1923                             : (unsigned)OMPC_SCHEDULE_unknown;
1924        KLoc[Modifier2] = Tok.getLocation();
1925        if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1926            Tok.isNot(tok::annot_pragma_openmp_end))
1927          ConsumeAnyToken();
1928      }
1929      // Parse ':'
1930      if (Tok.is(tok::colon))
1931        ConsumeAnyToken();
1932      else
1933        Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier";
1934      KindModifier = getOpenMPSimpleClauseType(
1935          KindTok.isAnnotation() ? "" : PP.getSpelling(Tok));
1936    }
1937    Arg[ScheduleKind] = KindModifier;
1938    KLoc[ScheduleKind] = Tok.getLocation();
1939    if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1940        Tok.isNot(tok::annot_pragma_openmp_end))
1941      ConsumeAnyToken();
1942    if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
1943         Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
1944         Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
1945        Tok.is(tok::comma))
1946      DelimLoc = ConsumeAnyToken();
1947  } else if (Kind == OMPC_dist_schedule) {
1948    Arg.push_back(getOpenMPSimpleClauseType(
1949        Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1950    KLoc.push_back(Tok.getLocation());
1951    if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1952        Tok.isNot(tok::annot_pragma_openmp_end))
1953      ConsumeAnyToken();
1954    if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
1955      DelimLoc = ConsumeAnyToken();
1956  } else if (Kind == OMPC_defaultmap) {
1957    // Get a defaultmap modifier
1958    Arg.push_back(getOpenMPSimpleClauseType(
1959        Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1960    KLoc.push_back(Tok.getLocation());
1961    if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1962        Tok.isNot(tok::annot_pragma_openmp_end))
1963      ConsumeAnyToken();
1964    // Parse ':'
1965    if (Tok.is(tok::colon))
1966      ConsumeAnyToken();
1967    else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown)
1968      Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier";
1969    // Get a defaultmap kind
1970    Arg.push_back(getOpenMPSimpleClauseType(
1971        Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1972    KLoc.push_back(Tok.getLocation());
1973    if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1974        Tok.isNot(tok::annot_pragma_openmp_end))
1975      ConsumeAnyToken();
1976  } else {
1977    assert(Kind == OMPC_if);
1978    KLoc.push_back(Tok.getLocation());
1979    TentativeParsingAction TPA(*this);
1980    Arg.push_back(parseOpenMPDirectiveKind(*this));
1981    if (Arg.back() != OMPD_unknown) {
1982      ConsumeToken();
1983      if (Tok.is(tok::colon) && getLangOpts().OpenMP > 40) {
1984        TPA.Commit();
1985        DelimLoc = ConsumeToken();
1986      } else {
1987        TPA.Revert();
1988        Arg.back() = OMPD_unknown;
1989      }
1990    } else {
1991      TPA.Revert();
1992    }
1993  }
1994
1995  bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) ||
1996                          (Kind == OMPC_dist_schedule && DelimLoc.isValid()) ||
1997                          Kind == OMPC_if;
1998  if (NeedAnExpression) {
1999    SourceLocation ELoc = Tok.getLocation();
2000    ExprResult LHS(ParseCastExpression(falsefalseNotTypeCast));
2001    Val = ParseRHSOfBinaryExpression(LHSprec::Conditional);
2002    Val =
2003        Actions.ActOnFinishFullExpr(Val.get(), ELoc/*DiscardedValue*/ false);
2004  }
2005
2006  // Parse ')'.
2007  SourceLocation RLoc = Tok.getLocation();
2008  if (!T.consumeClose())
2009    RLoc = T.getCloseLocation();
2010
2011  if (NeedAnExpression && Val.isInvalid())
2012    return nullptr;
2013
2014  if (ParseOnly)
2015    return nullptr;
2016  return Actions.ActOnOpenMPSingleExprWithArgClause(
2017      Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
2018}
2019
2020static bool ParseReductionId(Parser &PCXXScopeSpec &ReductionIdScopeSpec,
2021                             UnqualifiedId &ReductionId) {
2022  if (ReductionIdScopeSpec.isEmpty()) {
2023    auto OOK = OO_None;
2024    switch (P.getCurToken().getKind()) {
2025    case tok::plus:
2026      OOK = OO_Plus;
2027      break;
2028    case tok::minus:
2029      OOK = OO_Minus;
2030      break;
2031    case tok::star:
2032      OOK = OO_Star;
2033      break;
2034    case tok::amp:
2035      OOK = OO_Amp;
2036      break;
2037    case tok::pipe:
2038      OOK = OO_Pipe;
2039      break;
2040    case tok::caret:
2041      OOK = OO_Caret;
2042      break;
2043    case tok::ampamp:
2044      OOK = OO_AmpAmp;
2045      break;
2046    case tok::pipepipe:
2047      OOK = OO_PipePipe;
2048      break;
2049    default:
2050      break;
2051    }
2052    if (OOK != OO_None) {
2053      SourceLocation OpLoc = P.ConsumeToken();
2054      SourceLocation SymbolLocations[] = {OpLocOpLocSourceLocation()};
2055      ReductionId.setOperatorFunctionId(OpLocOOKSymbolLocations);
2056      return false;
2057    }
2058  }
2059  return P.ParseUnqualifiedId(ReductionIdScopeSpec/*EnteringContext*/ false,
2060                              /*AllowDestructorName*/ false,
2061                              /*AllowConstructorName*/ false,
2062                              /*AllowDeductionGuide*/ false,
2063                              nullptrnullptrReductionId);
2064}
2065
2066/// Checks if the token is a valid map-type-modifier.
2067static OpenMPMapModifierKind isMapModifier(Parser &P) {
2068  Token Tok = P.getCurToken();
2069  if (!Tok.is(tok::identifier))
2070    return OMPC_MAP_MODIFIER_unknown;
2071
2072  Preprocessor &PP = P.getPreprocessor();
2073  OpenMPMapModifierKind TypeModifier = static_cast<OpenMPMapModifierKind>(
2074      getOpenMPSimpleClauseType(OMPC_mapPP.getSpelling(Tok)));
2075  return TypeModifier;
2076}
2077
2078/// Parse the mapper modifier in map, to, and from clauses.
2079bool Parser::parseMapperModifier(OpenMPVarListDataTy &Data) {
2080  // Parse '('.
2081  BalancedDelimiterTracker T(*thistok::l_parentok::colon);
2082  if (T.expectAndConsume(diag::err_expected_lparen_after, "mapper")) {
2083    SkipUntil(tok::colontok::r_parentok::annot_pragma_openmp_end,
2084              StopBeforeMatch);
2085    return true;
2086  }
2087  // Parse mapper-identifier
2088  if (getLangOpts().CPlusPlus)
2089    ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
2090                                   /*ObjectType=*/nullptr,
2091                                   /*EnteringContext=*/false);
2092  if (Tok.isNot(tok::identifier) && Tok.isNot(tok::kw_default)) {
2093    Diag(Tok.getLocation(), diag::err_omp_mapper_illegal_identifier);
2094    SkipUntil(tok::colontok::r_parentok::annot_pragma_openmp_end,
2095              StopBeforeMatch);
2096    return true;
2097  }
2098  auto &DeclNames = Actions.getASTContext().DeclarationNames;
2099  Data.ReductionOrMapperId = DeclarationNameInfo(
2100      DeclNames.getIdentifier(Tok.getIdentifierInfo()), Tok.getLocation());
2101  ConsumeToken();
2102  // Parse ')'.
2103  return T.consumeClose();
2104}
2105
2106/// Parse map-type-modifiers in map clause.
2107/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
2108/// where, map-type-modifier ::= always | close | mapper(mapper-identifier)
2109bool Parser::parseMapTypeModifiers(OpenMPVarListDataTy &Data) {
2110  while (getCurToken().isNot(tok::colon)) {
2111    OpenMPMapModifierKind TypeModifier = isMapModifier(*this);
2112    if (TypeModifier == OMPC_MAP_MODIFIER_always ||
2113        TypeModifier == OMPC_MAP_MODIFIER_close) {
2114      Data.MapTypeModifiers.push_back(TypeModifier);
2115      Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
2116      ConsumeToken();
2117    } else if (TypeModifier == OMPC_MAP_MODIFIER_mapper) {
2118      Data.MapTypeModifiers.push_back(TypeModifier);
2119      Data.MapTypeModifiersLoc.push_back(Tok.getLocation());
2120      ConsumeToken();
2121      if (parseMapperModifier(Data))
2122        return true;
2123    } else {
2124      // For the case of unknown map-type-modifier or a map-type.
2125      // Map-type is followed by a colon; the function returns when it
2126      // encounters a token followed by a colon.
2127      if (Tok.is(tok::comma)) {
2128        Diag(Tok, diag::err_omp_map_type_modifier_missing);
2129        ConsumeToken();
2130        continue;
2131      }
2132      // Potential map-type token as it is followed by a colon.
2133      if (PP.LookAhead(0).is(tok::colon))
2134        return false;
2135      Diag(Tok, diag::err_omp_unknown_map_type_modifier);
2136      ConsumeToken();
2137    }
2138    if (getCurToken().is(tok::comma))
2139      ConsumeToken();
2140  }
2141  return false;
2142}
2143
2144/// Checks if the token is a valid map-type.
2145static OpenMPMapClauseKind isMapType(Parser &P) {
2146  Token Tok = P.getCurToken();
2147  // The map-type token can be either an identifier or the C++ delete keyword.
2148  if (!Tok.isOneOf(tok::identifiertok::kw_delete))
2149    return OMPC_MAP_unknown;
2150  Preprocessor &PP = P.getPreprocessor();
2151  OpenMPMapClauseKind MapType = static_cast<OpenMPMapClauseKind>(
2152      getOpenMPSimpleClauseType(OMPC_mapPP.getSpelling(Tok)));
2153  return MapType;
2154}
2155
2156/// Parse map-type in map clause.
2157/// map([ [map-type-modifier[,] [map-type-modifier[,] ...] map-type : ] list)
2158/// where, map-type ::= to | from | tofrom | alloc | release | delete
2159static void parseMapType(Parser &PParser::OpenMPVarListDataTy &Data) {
2160  Token Tok = P.getCurToken();
2161  if (Tok.is(tok::colon)) {
2162    P.Diag(Tok, diag::err_omp_map_type_missing);
2163    return;
2164  }
2165  Data.MapType = isMapType(P);
2166  if (Data.MapType == OMPC_MAP_unknown)
2167    P.Diag(Tok, diag::err_omp_unknown_map_type);
2168  P.ConsumeToken();
2169}
2170
2171/// Parses clauses with list.
2172bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
2173                                OpenMPClauseKind Kind,
2174                                SmallVectorImpl<Expr *> &Vars,
2175                                OpenMPVarListDataTy &Data) {
2176  UnqualifiedId UnqualifiedReductionId;
2177  bool InvalidReductionId = false;
2178  bool IsInvalidMapperModifier = false;
2179
2180  // Parse '('.
2181  BalancedDelimiterTracker T(*thistok::l_parentok::annot_pragma_openmp_end);
2182  if (T.expectAndConsume(diag::err_expected_lparen_after,
2183                         getOpenMPClauseName(Kind)))
2184    return true;
2185
2186  bool NeedRParenForLinear = false;
2187  BalancedDelimiterTracker LinearT(*thistok::l_paren,
2188                                  tok::annot_pragma_openmp_end);
2189  // Handle reduction-identifier for reduction clause.
2190  if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
2191      Kind == OMPC_in_reduction) {
2192    ColonProtectionRAIIObject ColonRAII(*this);
2193    if (getLangOpts().CPlusPlus)
2194      ParseOptionalCXXScopeSpecifier(Data.ReductionOrMapperIdScopeSpec,
2195                                     /*ObjectType=*/nullptr,
2196                                     /*EnteringContext=*/false);
2197    InvalidReductionId = ParseReductionId(
2198        *thisData.ReductionOrMapperIdScopeSpecUnqualifiedReductionId);
2199    if (InvalidReductionId) {
2200      SkipUntil(tok::colontok::r_parentok::annot_pragma_openmp_end,
2201                StopBeforeMatch);
2202    }
2203    if (Tok.is(tok::colon))
2204      Data.ColonLoc = ConsumeToken();
2205    else
2206      Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
2207    if (!InvalidReductionId)
2208      Data.ReductionOrMapperId =
2209          Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
2210  } else if (Kind == OMPC_depend) {
2211  // Handle dependency type for depend clause.
2212    ColonProtectionRAIIObject ColonRAII(*this);
2213    Data.DepKind =
2214        static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType(
2215            KindTok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
2216    Data.DepLinMapLoc = Tok.getLocation();
2217
2218    if (Data.DepKind == OMPC_DEPEND_unknown) {
2219      SkipUntil(tok::colontok::r_parentok::annot_pragma_openmp_end,
2220                StopBeforeMatch);
2221    } else {
2222      ConsumeToken();
2223      // Special processing for depend(source) clause.
2224      if (DKind == OMPD_ordered && Data.DepKind == OMPC_DEPEND_source) {
2225        // Parse ')'.
2226        T.consumeClose();
2227        return false;
2228      }
2229    }
2230    if (Tok.is(tok::colon)) {
2231      Data.ColonLoc = ConsumeToken();
2232    } else {
2233      Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
2234                                      : diag::warn_pragma_expected_colon)
2235          << "dependency type";
2236    }
2237  } else if (Kind == OMPC_linear) {
2238    // Try to parse modifier if any.
2239    if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
2240      Data.LinKind = static_cast<OpenMPLinearClauseKind>(
2241          getOpenMPSimpleClauseType(KindPP.getSpelling(Tok)));
2242      Data.DepLinMapLoc = ConsumeToken();
2243      LinearT.consumeOpen();
2244      NeedRParenForLinear = true;
2245    }
2246  } else if (Kind == OMPC_map) {
2247    // Handle map type for map clause.
2248    ColonProtectionRAIIObject ColonRAII(*this);
2249
2250    // The first identifier may be a list item, a map-type or a
2251    // map-type-modifier. The map-type can also be delete which has the same
2252    // spelling of the C++ delete keyword.
2253    Data.DepLinMapLoc = Tok.getLocation();
2254
2255    // Check for presence of a colon in the map clause.
2256    TentativeParsingAction TPA(*this);
2257    bool ColonPresent = false;
2258    if (SkipUntil(tok::colontok::r_parentok::annot_pragma_openmp_end,
2259        StopBeforeMatch)) {
2260      if (Tok.is(tok::colon))
2261        ColonPresent = true;
2262    }
2263    TPA.Revert();
2264    // Only parse map-type-modifier[s] and map-type if a colon is present in
2265    // the map clause.
2266    if (ColonPresent) {
2267      IsInvalidMapperModifier = parseMapTypeModifiers(Data);
2268      if (!IsInvalidMapperModifier)
2269        parseMapType(*thisData);
2270      else
2271        SkipUntil(tok::colontok::annot_pragma_openmp_endStopBeforeMatch);
2272    }
2273    if (Data.MapType == OMPC_MAP_unknown) {
2274      Data.MapType = OMPC_MAP_tofrom;
2275      Data.IsMapTypeImplicit = true;
2276    }
2277
2278    if (Tok.is(tok::colon))
2279      Data.ColonLoc = ConsumeToken();
2280  } else if (Kind == OMPC_to || Kind == OMPC_from) {
2281    if (Tok.is(tok::identifier)) {
2282      bool IsMapperModifier = false;
2283      if (Kind == OMPC_to) {
2284        auto Modifier = static_cast<OpenMPToModifierKind>(
2285            getOpenMPSimpleClauseType(KindPP.getSpelling(Tok)));
2286        if (Modifier == OMPC_TO_MODIFIER_mapper)
2287          IsMapperModifier = true;
2288      } else {
2289        auto Modifier = static_cast<OpenMPFromModifierKind>(
2290            getOpenMPSimpleClauseType(KindPP.getSpelling(Tok)));
2291        if (Modifier == OMPC_FROM_MODIFIER_mapper)
2292          IsMapperModifier = true;
2293      }
2294      if (IsMapperModifier) {
2295        // Parse the mapper modifier.
2296        ConsumeToken();
2297        IsInvalidMapperModifier = parseMapperModifier(Data);
2298        if (Tok.isNot(tok::colon)) {
2299          if (!IsInvalidMapperModifier)
2300            Diag(Tok, diag::warn_pragma_expected_colon) << ")";
2301          SkipUntil(tok::colontok::r_parentok::annot_pragma_openmp_end,
2302                    StopBeforeMatch);
2303        }
2304        // Consume ':'.
2305        if (Tok.is(tok::colon))
2306          ConsumeToken();
2307      }
2308    }
2309  } else if (Kind == OMPC_allocate) {
2310    // Handle optional allocator expression followed by colon delimiter.
2311    ColonProtectionRAIIObject ColonRAII(*this);
2312    TentativeParsingAction TPA(*this);
2313    ExprResult Tail =
2314        Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
2315    Tail = Actions.ActOnFinishFullExpr(Tail.get(), T.getOpenLocation(),
2316                                       /*DiscardedValue=*/false);
2317    if (Tail.isUsable()) {
2318      if (Tok.is(tok::colon)) {
2319        Data.TailExpr = Tail.get();
2320        Data.ColonLoc = ConsumeToken();
2321        TPA.Commit();
2322      } else {
2323        // colon not found, no allocator specified, parse only list of
2324        // variables.
2325        TPA.Revert();
2326      }
2327    } else {
2328      // Parsing was unsuccessfull, revert and skip to the end of clause or
2329      // directive.
2330      TPA.Revert();
2331      SkipUntil(tok::commatok::r_parentok::annot_pragma_openmp_end,
2332                StopBeforeMatch);
2333    }
2334  }
2335
2336  bool IsComma =
2337      (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
2338       Kind != OMPC_in_reduction && Kind != OMPC_depend && Kind != OMPC_map) ||
2339      (Kind == OMPC_reduction && !InvalidReductionId) ||
2340      (Kind == OMPC_map && Data.MapType != OMPC_MAP_unknown) ||
2341      (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown);
2342  const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
2343  while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
2344                     Tok.isNot(tok::annot_pragma_openmp_end))) {
2345    ColonProtectionRAIIObject ColonRAII(*thisMayHaveTail);
2346    // Parse variable
2347    ExprResult VarExpr =
2348        Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
2349    if (VarExpr.isUsable()) {
2350      Vars.push_back(VarExpr.get());
2351    } else {
2352      SkipUntil(tok::commatok::r_parentok::annot_pragma_openmp_end,
2353                StopBeforeMatch);
2354    }
2355    // Skip ',' if any
2356    IsComma = Tok.is(tok::comma);
2357    if (IsComma)
2358      ConsumeToken();
2359    else if (Tok.isNot(tok::r_paren) &&
2360             Tok.isNot(tok::annot_pragma_openmp_end) &&
2361             (!MayHaveTail || Tok.isNot(tok::colon)))
2362      Diag(Tok, diag::err_omp_expected_punc)
2363          << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
2364                                   : getOpenMPClauseName(Kind))
2365          << (Kind == OMPC_flush);
2366  }
2367
2368  // Parse ')' for linear clause with modifier.
2369  if (NeedRParenForLinear)
2370    LinearT.consumeClose();
2371
2372  // Parse ':' linear-step (or ':' alignment).
2373  const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
2374  if (MustHaveTail) {
2375    Data.ColonLoc = Tok.getLocation();
2376    SourceLocation ELoc = ConsumeToken();
2377    ExprResult Tail = ParseAssignmentExpression();
2378    Tail =
2379        Actions.ActOnFinishFullExpr(Tail.get(), ELoc/*DiscardedValue*/ false);
2380    if (Tail.isUsable())
2381      Data.TailExpr = Tail.get();
2382    else
2383      SkipUntil(tok::commatok::r_parentok::annot_pragma_openmp_end,
2384                StopBeforeMatch);
2385  }
2386
2387  // Parse ')'.
2388  Data.RLoc = Tok.getLocation();
2389  if (!T.consumeClose())
2390    Data.RLoc = T.getCloseLocation();
2391  return (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown &&
2392          Vars.empty()) ||
2393         (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
2394         (MustHaveTail && !Data.TailExpr) || InvalidReductionId ||
2395         IsInvalidMapperModifier;
2396}
2397
2398/// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
2399/// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction' or
2400/// 'in_reduction'.
2401///
2402///    private-clause:
2403///       'private' '(' list ')'
2404///    firstprivate-clause:
2405///       'firstprivate' '(' list ')'
2406///    lastprivate-clause:
2407///       'lastprivate' '(' list ')'
2408///    shared-clause:
2409///       'shared' '(' list ')'
2410///    linear-clause:
2411///       'linear' '(' linear-list [ ':' linear-step ] ')'
2412///    aligned-clause:
2413///       'aligned' '(' list [ ':' alignment ] ')'
2414///    reduction-clause:
2415///       'reduction' '(' reduction-identifier ':' list ')'
2416///    task_reduction-clause:
2417///       'task_reduction' '(' reduction-identifier ':' list ')'
2418///    in_reduction-clause:
2419///       'in_reduction' '(' reduction-identifier ':' list ')'
2420///    copyprivate-clause:
2421///       'copyprivate' '(' list ')'
2422///    flush-clause:
2423///       'flush' '(' list ')'
2424///    depend-clause:
2425///       'depend' '(' in | out | inout : list | source ')'
2426///    map-clause:
2427///       'map' '(' [ [ always [,] ] [ close [,] ]
2428///          [ mapper '(' mapper-identifier ')' [,] ]
2429///          to | from | tofrom | alloc | release | delete ':' ] list ')';
2430///    to-clause:
2431///       'to' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
2432///    from-clause:
2433///       'from' '(' [ mapper '(' mapper-identifier ')' ':' ] list ')'
2434///    use_device_ptr-clause:
2435///       'use_device_ptr' '(' list ')'
2436///    is_device_ptr-clause:
2437///       'is_device_ptr' '(' list ')'
2438///    allocate-clause:
2439///       'allocate' '(' [ allocator ':' ] list ')'
2440///
2441/// For 'linear' clause linear-list may have the following forms:
2442///  list
2443///  modifier(list)
2444/// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
2445OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
2446                                            OpenMPClauseKind Kind,
2447                                            bool ParseOnly) {
2448  SourceLocation Loc = Tok.getLocation();
2449  SourceLocation LOpen = ConsumeToken();
2450  SmallVector<Expr *, 4Vars;
2451  OpenMPVarListDataTy Data;
2452
2453  if (ParseOpenMPVarList(DKind, Kind, Vars, Data))
2454    return nullptr;
2455
2456  if (ParseOnly)
2457    return nullptr;
2458  OMPVarListLocTy Locs(LocLOpenData.RLoc);
2459  return Actions.ActOnOpenMPVarListClause(
2460      Kind, Vars, Data.TailExpr, Locs, Data.ColonLoc,
2461      Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId, Data.DepKind,
2462      Data.LinKind, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
2463      Data.MapType, Data.IsMapTypeImplicit, Data.DepLinMapLoc);
2464}
2465
2466
clang::Parser::ParseOpenMPDeclareReductionDirective
clang::Parser::ParseOpenMPReductionInitializerForDecl
clang::Parser::ParseOpenMPDeclareMapperDirective
clang::Parser::parseOpenMPDeclareMapperVarDecl
clang::Parser::ParseOMPDeclareSimdClauses
clang::Parser::ParseOMPDeclareTargetClauses
clang::Parser::ParseOMPEndDeclareTargetDirective
clang::Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl
clang::Parser::ParseOpenMPDeclarativeOrExecutableDirective
clang::Parser::ParseOpenMPSimpleVarList
clang::Parser::ParseOpenMPClause
clang::Parser::ParseOpenMPParensExpr
clang::Parser::ParseOpenMPSingleExprClause
clang::Parser::ParseOpenMPSimpleClause
clang::Parser::ParseOpenMPClause
clang::Parser::ParseOpenMPSingleExprWithArgClause
clang::Parser::parseMapperModifier
clang::Parser::parseMapTypeModifiers
clang::Parser::ParseOpenMPVarList
clang::Parser::ParseOpenMPVarListClause