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