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