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