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