clang  7.0.0
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=*/true);
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  ConsumeToken();
357  ParseOpenMPReductionInitializerForDecl(OmpPrivParm);
358  } else {
359  InitializerResult = Actions.ActOnFinishFullExpr(
360  ParseAssignmentExpression().get(), D->getLocation(),
361  /*DiscardedValue=*/true);
362  }
363  Actions.ActOnOpenMPDeclareReductionInitializerEnd(
364  D, InitializerResult.get(), OmpPrivParm);
365  if (InitializerResult.isInvalid() && Tok.isNot(tok::r_paren) &&
366  Tok.isNot(tok::annot_pragma_openmp_end)) {
367  TPA.Commit();
368  IsCorrect = false;
369  break;
370  }
371  IsCorrect =
372  !T.consumeClose() && IsCorrect && !InitializerResult.isInvalid();
373  }
374  }
375 
376  ++I;
377  // Revert parsing if not the last type, otherwise accept it, we're done with
378  // parsing.
379  if (I != E)
380  TPA.Revert();
381  else
382  TPA.Commit();
383  }
384  return Actions.ActOnOpenMPDeclareReductionDirectiveEnd(getCurScope(), DRD,
385  IsCorrect);
386 }
387 
388 void Parser::ParseOpenMPReductionInitializerForDecl(VarDecl *OmpPrivParm) {
389  // Parse declarator '=' initializer.
390  // If a '==' or '+=' is found, suggest a fixit to '='.
391  if (isTokenEqualOrEqualTypo()) {
392  ConsumeToken();
393 
394  if (Tok.is(tok::code_completion)) {
395  Actions.CodeCompleteInitializer(getCurScope(), OmpPrivParm);
396  Actions.FinalizeDeclaration(OmpPrivParm);
397  cutOffParsing();
398  return;
399  }
400 
401  ExprResult Init(ParseInitializer());
402 
403  if (Init.isInvalid()) {
404  SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
405  Actions.ActOnInitializerError(OmpPrivParm);
406  } else {
407  Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
408  /*DirectInit=*/false);
409  }
410  } else if (Tok.is(tok::l_paren)) {
411  // Parse C++ direct initializer: '(' expression-list ')'
412  BalancedDelimiterTracker T(*this, tok::l_paren);
413  T.consumeOpen();
414 
415  ExprVector Exprs;
416  CommaLocsTy CommaLocs;
417 
418  if (ParseExpressionList(Exprs, CommaLocs, [this, OmpPrivParm, &Exprs] {
419  Actions.CodeCompleteConstructor(
420  getCurScope(), OmpPrivParm->getType()->getCanonicalTypeInternal(),
421  OmpPrivParm->getLocation(), Exprs);
422  })) {
423  Actions.ActOnInitializerError(OmpPrivParm);
424  SkipUntil(tok::r_paren, tok::annot_pragma_openmp_end, StopBeforeMatch);
425  } else {
426  // Match the ')'.
427  SourceLocation RLoc = Tok.getLocation();
428  if (!T.consumeClose())
429  RLoc = T.getCloseLocation();
430 
431  assert(!Exprs.empty() && Exprs.size() - 1 == CommaLocs.size() &&
432  "Unexpected number of commas!");
433 
434  ExprResult Initializer =
435  Actions.ActOnParenListExpr(T.getOpenLocation(), RLoc, Exprs);
436  Actions.AddInitializerToDecl(OmpPrivParm, Initializer.get(),
437  /*DirectInit=*/true);
438  }
439  } else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
440  // Parse C++0x braced-init-list.
441  Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
442 
443  ExprResult Init(ParseBraceInitializer());
444 
445  if (Init.isInvalid()) {
446  Actions.ActOnInitializerError(OmpPrivParm);
447  } else {
448  Actions.AddInitializerToDecl(OmpPrivParm, Init.get(),
449  /*DirectInit=*/true);
450  }
451  } else {
452  Actions.ActOnUninitializedDecl(OmpPrivParm);
453  }
454 }
455 
456 namespace {
457 /// RAII that recreates function context for correct parsing of clauses of
458 /// 'declare simd' construct.
459 /// OpenMP, 2.8.2 declare simd Construct
460 /// The expressions appearing in the clauses of this directive are evaluated in
461 /// the scope of the arguments of the function declaration or definition.
462 class FNContextRAII final {
463  Parser &P;
464  Sema::CXXThisScopeRAII *ThisScope;
465  Parser::ParseScope *TempScope;
466  Parser::ParseScope *FnScope;
467  bool HasTemplateScope = false;
468  bool HasFunScope = false;
469  FNContextRAII() = delete;
470  FNContextRAII(const FNContextRAII &) = delete;
471  FNContextRAII &operator=(const FNContextRAII &) = delete;
472 
473 public:
474  FNContextRAII(Parser &P, Parser::DeclGroupPtrTy Ptr) : P(P) {
475  Decl *D = *Ptr.get().begin();
476  NamedDecl *ND = dyn_cast<NamedDecl>(D);
477  RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
478  Sema &Actions = P.getActions();
479 
480  // Allow 'this' within late-parsed attributes.
481  ThisScope = new Sema::CXXThisScopeRAII(Actions, RD, /*TypeQuals=*/0,
482  ND && ND->isCXXInstanceMember());
483 
484  // If the Decl is templatized, add template parameters to scope.
485  HasTemplateScope = D->isTemplateDecl();
486  TempScope =
487  new Parser::ParseScope(&P, Scope::TemplateParamScope, HasTemplateScope);
488  if (HasTemplateScope)
489  Actions.ActOnReenterTemplateScope(Actions.getCurScope(), D);
490 
491  // If the Decl is on a function, add function parameters to the scope.
492  HasFunScope = D->isFunctionOrFunctionTemplate();
493  FnScope = new Parser::ParseScope(
495  HasFunScope);
496  if (HasFunScope)
497  Actions.ActOnReenterFunctionContext(Actions.getCurScope(), D);
498  }
499  ~FNContextRAII() {
500  if (HasFunScope) {
502  FnScope->Exit(); // Pop scope, and remove Decls from IdResolver
503  }
504  if (HasTemplateScope)
505  TempScope->Exit();
506  delete FnScope;
507  delete TempScope;
508  delete ThisScope;
509  }
510 };
511 } // namespace
512 
513 /// Parses clauses for 'declare simd' directive.
514 /// clause:
515 /// 'inbranch' | 'notinbranch'
516 /// 'simdlen' '(' <expr> ')'
517 /// { 'uniform' '(' <argument_list> ')' }
518 /// { 'aligned '(' <argument_list> [ ':' <alignment> ] ')' }
519 /// { 'linear '(' <argument_list> [ ':' <step> ] ')' }
521  Parser &P, OMPDeclareSimdDeclAttr::BranchStateTy &BS, ExprResult &SimdLen,
523  SmallVectorImpl<Expr *> &Alignments, SmallVectorImpl<Expr *> &Linears,
524  SmallVectorImpl<unsigned> &LinModifiers, SmallVectorImpl<Expr *> &Steps) {
525  SourceRange BSRange;
526  const Token &Tok = P.getCurToken();
527  bool IsError = false;
528  while (Tok.isNot(tok::annot_pragma_openmp_end)) {
529  if (Tok.isNot(tok::identifier))
530  break;
531  OMPDeclareSimdDeclAttr::BranchStateTy Out;
532  IdentifierInfo *II = Tok.getIdentifierInfo();
533  StringRef ClauseName = II->getName();
534  // Parse 'inranch|notinbranch' clauses.
535  if (OMPDeclareSimdDeclAttr::ConvertStrToBranchStateTy(ClauseName, Out)) {
536  if (BS != OMPDeclareSimdDeclAttr::BS_Undefined && BS != Out) {
537  P.Diag(Tok, diag::err_omp_declare_simd_inbranch_notinbranch)
538  << ClauseName
539  << OMPDeclareSimdDeclAttr::ConvertBranchStateTyToStr(BS) << BSRange;
540  IsError = true;
541  }
542  BS = Out;
543  BSRange = SourceRange(Tok.getLocation(), Tok.getEndLoc());
544  P.ConsumeToken();
545  } else if (ClauseName.equals("simdlen")) {
546  if (SimdLen.isUsable()) {
547  P.Diag(Tok, diag::err_omp_more_one_clause)
548  << getOpenMPDirectiveName(OMPD_declare_simd) << ClauseName << 0;
549  IsError = true;
550  }
551  P.ConsumeToken();
552  SourceLocation RLoc;
553  SimdLen = P.ParseOpenMPParensExpr(ClauseName, RLoc);
554  if (SimdLen.isInvalid())
555  IsError = true;
556  } else {
557  OpenMPClauseKind CKind = getOpenMPClauseKind(ClauseName);
558  if (CKind == OMPC_uniform || CKind == OMPC_aligned ||
559  CKind == OMPC_linear) {
561  SmallVectorImpl<Expr *> *Vars = &Uniforms;
562  if (CKind == OMPC_aligned)
563  Vars = &Aligneds;
564  else if (CKind == OMPC_linear)
565  Vars = &Linears;
566 
567  P.ConsumeToken();
568  if (P.ParseOpenMPVarList(OMPD_declare_simd,
569  getOpenMPClauseKind(ClauseName), *Vars, Data))
570  IsError = true;
571  if (CKind == OMPC_aligned) {
572  Alignments.append(Aligneds.size() - Alignments.size(), Data.TailExpr);
573  } else if (CKind == OMPC_linear) {
575  Data.DepLinMapLoc))
576  Data.LinKind = OMPC_LINEAR_val;
577  LinModifiers.append(Linears.size() - LinModifiers.size(),
578  Data.LinKind);
579  Steps.append(Linears.size() - Steps.size(), Data.TailExpr);
580  }
581  } else
582  // TODO: add parsing of other clauses.
583  break;
584  }
585  // Skip ',' if any.
586  if (Tok.is(tok::comma))
587  P.ConsumeToken();
588  }
589  return IsError;
590 }
591 
592 /// Parse clauses for '#pragma omp declare simd'.
594 Parser::ParseOMPDeclareSimdClauses(Parser::DeclGroupPtrTy Ptr,
595  CachedTokens &Toks, SourceLocation Loc) {
596  PP.EnterToken(Tok);
597  PP.EnterTokenStream(Toks, /*DisableMacroExpansion=*/true);
598  // Consume the previously pushed token.
599  ConsumeAnyToken(/*ConsumeCodeCompletionTok=*/true);
600 
601  FNContextRAII FnContext(*this, Ptr);
602  OMPDeclareSimdDeclAttr::BranchStateTy BS =
603  OMPDeclareSimdDeclAttr::BS_Undefined;
604  ExprResult Simdlen;
605  SmallVector<Expr *, 4> Uniforms;
606  SmallVector<Expr *, 4> Aligneds;
607  SmallVector<Expr *, 4> Alignments;
608  SmallVector<Expr *, 4> Linears;
609  SmallVector<unsigned, 4> LinModifiers;
611  bool IsError =
612  parseDeclareSimdClauses(*this, BS, Simdlen, Uniforms, Aligneds,
613  Alignments, Linears, LinModifiers, Steps);
614  // Need to check for extra tokens.
615  if (Tok.isNot(tok::annot_pragma_openmp_end)) {
616  Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
617  << getOpenMPDirectiveName(OMPD_declare_simd);
618  while (Tok.isNot(tok::annot_pragma_openmp_end))
619  ConsumeAnyToken();
620  }
621  // Skip the last annot_pragma_openmp_end.
622  SourceLocation EndLoc = ConsumeAnnotationToken();
623  if (IsError)
624  return Ptr;
625  return Actions.ActOnOpenMPDeclareSimdDirective(
626  Ptr, BS, Simdlen.get(), Uniforms, Aligneds, Alignments, Linears,
627  LinModifiers, Steps, SourceRange(Loc, EndLoc));
628 }
629 
630 /// Parsing of declarative OpenMP directives.
631 ///
632 /// threadprivate-directive:
633 /// annot_pragma_openmp 'threadprivate' simple-variable-list
634 /// annot_pragma_openmp_end
635 ///
636 /// declare-reduction-directive:
637 /// annot_pragma_openmp 'declare' 'reduction' [...]
638 /// annot_pragma_openmp_end
639 ///
640 /// declare-simd-directive:
641 /// annot_pragma_openmp 'declare simd' {<clause> [,]}
642 /// annot_pragma_openmp_end
643 /// <function declaration/definition>
644 ///
645 Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirectiveWithExtDecl(
646  AccessSpecifier &AS, ParsedAttributesWithRange &Attrs,
647  DeclSpec::TST TagType, Decl *Tag) {
648  assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
649  ParenBraceBracketBalancer BalancerRAIIObj(*this);
650 
651  SourceLocation Loc = ConsumeAnnotationToken();
653 
654  switch (DKind) {
655  case OMPD_threadprivate: {
656  ConsumeToken();
657  ThreadprivateListParserHelper Helper(this);
658  if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Helper, true)) {
659  // The last seen token is annot_pragma_openmp_end - need to check for
660  // extra tokens.
661  if (Tok.isNot(tok::annot_pragma_openmp_end)) {
662  Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
663  << getOpenMPDirectiveName(OMPD_threadprivate);
664  SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
665  }
666  // Skip the last annot_pragma_openmp_end.
667  ConsumeAnnotationToken();
668  return Actions.ActOnOpenMPThreadprivateDirective(Loc,
669  Helper.getIdentifiers());
670  }
671  break;
672  }
673  case OMPD_declare_reduction:
674  ConsumeToken();
675  if (DeclGroupPtrTy Res = ParseOpenMPDeclareReductionDirective(AS)) {
676  // The last seen token is annot_pragma_openmp_end - need to check for
677  // extra tokens.
678  if (Tok.isNot(tok::annot_pragma_openmp_end)) {
679  Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
680  << getOpenMPDirectiveName(OMPD_declare_reduction);
681  while (Tok.isNot(tok::annot_pragma_openmp_end))
682  ConsumeAnyToken();
683  }
684  // Skip the last annot_pragma_openmp_end.
685  ConsumeAnnotationToken();
686  return Res;
687  }
688  break;
689  case OMPD_declare_simd: {
690  // The syntax is:
691  // { #pragma omp declare simd }
692  // <function-declaration-or-definition>
693  //
694  ConsumeToken();
695  CachedTokens Toks;
696  while(Tok.isNot(tok::annot_pragma_openmp_end)) {
697  Toks.push_back(Tok);
698  ConsumeAnyToken();
699  }
700  Toks.push_back(Tok);
701  ConsumeAnyToken();
702 
703  DeclGroupPtrTy Ptr;
704  if (Tok.is(tok::annot_pragma_openmp)) {
705  Ptr = ParseOpenMPDeclarativeDirectiveWithExtDecl(AS, Attrs, TagType, Tag);
706  } else if (Tok.isNot(tok::r_brace) && !isEofOrEom()) {
707  // Here we expect to see some function declaration.
708  if (AS == AS_none) {
710  MaybeParseCXX11Attributes(Attrs);
711  ParsingDeclSpec PDS(*this);
712  Ptr = ParseExternalDeclaration(Attrs, &PDS);
713  } else {
714  Ptr =
715  ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
716  }
717  }
718  if (!Ptr) {
719  Diag(Loc, diag::err_omp_decl_in_declare_simd);
720  return DeclGroupPtrTy();
721  }
722  return ParseOMPDeclareSimdClauses(Ptr, Toks, Loc);
723  }
724  case OMPD_declare_target: {
725  SourceLocation DTLoc = ConsumeAnyToken();
726  if (Tok.isNot(tok::annot_pragma_openmp_end)) {
727  // OpenMP 4.5 syntax with list of entities.
728  Sema::NamedDeclSetType SameDirectiveDecls;
729  while (Tok.isNot(tok::annot_pragma_openmp_end)) {
730  OMPDeclareTargetDeclAttr::MapTypeTy MT =
731  OMPDeclareTargetDeclAttr::MT_To;
732  if (Tok.is(tok::identifier)) {
733  IdentifierInfo *II = Tok.getIdentifierInfo();
734  StringRef ClauseName = II->getName();
735  // Parse 'to|link' clauses.
736  if (!OMPDeclareTargetDeclAttr::ConvertStrToMapTypeTy(ClauseName,
737  MT)) {
738  Diag(Tok, diag::err_omp_declare_target_unexpected_clause)
739  << ClauseName;
740  break;
741  }
742  ConsumeToken();
743  }
744  auto &&Callback = [this, MT, &SameDirectiveDecls](
745  CXXScopeSpec &SS, DeclarationNameInfo NameInfo) {
746  Actions.ActOnOpenMPDeclareTargetName(getCurScope(), SS, NameInfo, MT,
747  SameDirectiveDecls);
748  };
749  if (ParseOpenMPSimpleVarList(OMPD_declare_target, Callback,
750  /*AllowScopeSpecifier=*/true))
751  break;
752 
753  // Consume optional ','.
754  if (Tok.is(tok::comma))
755  ConsumeToken();
756  }
757  SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
758  ConsumeAnyToken();
759  SmallVector<Decl *, 4> Decls(SameDirectiveDecls.begin(),
760  SameDirectiveDecls.end());
761  if (Decls.empty())
762  return DeclGroupPtrTy();
763  return Actions.BuildDeclaratorGroup(Decls);
764  }
765 
766  // Skip the last annot_pragma_openmp_end.
767  ConsumeAnyToken();
768 
769  if (!Actions.ActOnStartOpenMPDeclareTargetDirective(DTLoc))
770  return DeclGroupPtrTy();
771 
773  DKind = parseOpenMPDirectiveKind(*this);
774  while (DKind != OMPD_end_declare_target && DKind != OMPD_declare_target &&
775  Tok.isNot(tok::eof) && Tok.isNot(tok::r_brace)) {
776  DeclGroupPtrTy Ptr;
777  // Here we expect to see some function declaration.
778  if (AS == AS_none) {
780  MaybeParseCXX11Attributes(Attrs);
781  ParsingDeclSpec PDS(*this);
782  Ptr = ParseExternalDeclaration(Attrs, &PDS);
783  } else {
784  Ptr =
785  ParseCXXClassMemberDeclarationWithPragmas(AS, Attrs, TagType, Tag);
786  }
787  if (Ptr) {
788  DeclGroupRef Ref = Ptr.get();
789  Decls.append(Ref.begin(), Ref.end());
790  }
791  if (Tok.isAnnotation() && Tok.is(tok::annot_pragma_openmp)) {
792  TentativeParsingAction TPA(*this);
793  ConsumeAnnotationToken();
794  DKind = parseOpenMPDirectiveKind(*this);
795  if (DKind != OMPD_end_declare_target)
796  TPA.Revert();
797  else
798  TPA.Commit();
799  }
800  }
801 
802  if (DKind == OMPD_end_declare_target) {
803  ConsumeAnyToken();
804  if (Tok.isNot(tok::annot_pragma_openmp_end)) {
805  Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
806  << getOpenMPDirectiveName(OMPD_end_declare_target);
807  SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
808  }
809  // Skip the last annot_pragma_openmp_end.
810  ConsumeAnyToken();
811  } else {
812  Diag(Tok, diag::err_expected_end_declare_target);
813  Diag(DTLoc, diag::note_matching) << "'#pragma omp declare target'";
814  }
815  Actions.ActOnFinishOpenMPDeclareTargetDirective();
816  return Actions.BuildDeclaratorGroup(Decls);
817  }
818  case OMPD_unknown:
819  Diag(Tok, diag::err_omp_unknown_directive);
820  break;
821  case OMPD_parallel:
822  case OMPD_simd:
823  case OMPD_task:
824  case OMPD_taskyield:
825  case OMPD_barrier:
826  case OMPD_taskwait:
827  case OMPD_taskgroup:
828  case OMPD_flush:
829  case OMPD_for:
830  case OMPD_for_simd:
831  case OMPD_sections:
832  case OMPD_section:
833  case OMPD_single:
834  case OMPD_master:
835  case OMPD_ordered:
836  case OMPD_critical:
837  case OMPD_parallel_for:
838  case OMPD_parallel_for_simd:
839  case OMPD_parallel_sections:
840  case OMPD_atomic:
841  case OMPD_target:
842  case OMPD_teams:
843  case OMPD_cancellation_point:
844  case OMPD_cancel:
845  case OMPD_target_data:
846  case OMPD_target_enter_data:
847  case OMPD_target_exit_data:
848  case OMPD_target_parallel:
849  case OMPD_target_parallel_for:
850  case OMPD_taskloop:
851  case OMPD_taskloop_simd:
852  case OMPD_distribute:
853  case OMPD_end_declare_target:
854  case OMPD_target_update:
855  case OMPD_distribute_parallel_for:
856  case OMPD_distribute_parallel_for_simd:
857  case OMPD_distribute_simd:
858  case OMPD_target_parallel_for_simd:
859  case OMPD_target_simd:
860  case OMPD_teams_distribute:
861  case OMPD_teams_distribute_simd:
862  case OMPD_teams_distribute_parallel_for_simd:
863  case OMPD_teams_distribute_parallel_for:
864  case OMPD_target_teams:
865  case OMPD_target_teams_distribute:
866  case OMPD_target_teams_distribute_parallel_for:
867  case OMPD_target_teams_distribute_parallel_for_simd:
868  case OMPD_target_teams_distribute_simd:
869  Diag(Tok, diag::err_omp_unexpected_directive)
870  << 1 << getOpenMPDirectiveName(DKind);
871  break;
872  }
873  while (Tok.isNot(tok::annot_pragma_openmp_end))
874  ConsumeAnyToken();
875  ConsumeAnyToken();
876  return nullptr;
877 }
878 
879 /// Parsing of declarative or executable OpenMP directives.
880 ///
881 /// threadprivate-directive:
882 /// annot_pragma_openmp 'threadprivate' simple-variable-list
883 /// annot_pragma_openmp_end
884 ///
885 /// declare-reduction-directive:
886 /// annot_pragma_openmp 'declare' 'reduction' '(' <reduction_id> ':'
887 /// <type> {',' <type>} ':' <expression> ')' ['initializer' '('
888 /// ('omp_priv' '=' <expression>|<function_call>) ')']
889 /// annot_pragma_openmp_end
890 ///
891 /// executable-directive:
892 /// annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
893 /// 'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
894 /// 'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
895 /// 'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' |
896 /// 'for simd' | 'parallel for simd' | 'target' | 'target data' |
897 /// 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' |
898 /// 'distribute' | 'target enter data' | 'target exit data' |
899 /// 'target parallel' | 'target parallel for' |
900 /// 'target update' | 'distribute parallel for' |
901 /// 'distribute paralle for simd' | 'distribute simd' |
902 /// 'target parallel for simd' | 'target simd' |
903 /// 'teams distribute' | 'teams distribute simd' |
904 /// 'teams distribute parallel for simd' |
905 /// 'teams distribute parallel for' | 'target teams' |
906 /// 'target teams distribute' |
907 /// 'target teams distribute parallel for' |
908 /// 'target teams distribute parallel for simd' |
909 /// 'target teams distribute simd' {clause}
910 /// annot_pragma_openmp_end
911 ///
912 StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
913  AllowedConstructsKind Allowed) {
914  assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
915  ParenBraceBracketBalancer BalancerRAIIObj(*this);
918  FirstClauses(OMPC_unknown + 1);
919  unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
921  SourceLocation Loc = ConsumeAnnotationToken(), EndLoc;
923  OpenMPDirectiveKind CancelRegion = OMPD_unknown;
924  // Name of critical directive.
925  DeclarationNameInfo DirName;
927  bool HasAssociatedStatement = true;
928  bool FlushHasClause = false;
929 
930  switch (DKind) {
931  case OMPD_threadprivate: {
932  if (Allowed != ACK_Any) {
933  Diag(Tok, diag::err_omp_immediate_directive)
934  << getOpenMPDirectiveName(DKind) << 0;
935  }
936  ConsumeToken();
937  ThreadprivateListParserHelper Helper(this);
938  if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Helper, false)) {
939  // The last seen token is annot_pragma_openmp_end - need to check for
940  // extra tokens.
941  if (Tok.isNot(tok::annot_pragma_openmp_end)) {
942  Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
943  << getOpenMPDirectiveName(OMPD_threadprivate);
944  SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
945  }
946  DeclGroupPtrTy Res = Actions.ActOnOpenMPThreadprivateDirective(
947  Loc, Helper.getIdentifiers());
948  Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
949  }
950  SkipUntil(tok::annot_pragma_openmp_end);
951  break;
952  }
953  case OMPD_declare_reduction:
954  ConsumeToken();
955  if (DeclGroupPtrTy Res =
956  ParseOpenMPDeclareReductionDirective(/*AS=*/AS_none)) {
957  // The last seen token is annot_pragma_openmp_end - need to check for
958  // extra tokens.
959  if (Tok.isNot(tok::annot_pragma_openmp_end)) {
960  Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
961  << getOpenMPDirectiveName(OMPD_declare_reduction);
962  while (Tok.isNot(tok::annot_pragma_openmp_end))
963  ConsumeAnyToken();
964  }
965  ConsumeAnyToken();
966  Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
967  } else {
968  SkipUntil(tok::annot_pragma_openmp_end);
969  }
970  break;
971  case OMPD_flush:
972  if (PP.LookAhead(0).is(tok::l_paren)) {
973  FlushHasClause = true;
974  // Push copy of the current token back to stream to properly parse
975  // pseudo-clause OMPFlushClause.
976  PP.EnterToken(Tok);
977  }
978  LLVM_FALLTHROUGH;
979  case OMPD_taskyield:
980  case OMPD_barrier:
981  case OMPD_taskwait:
982  case OMPD_cancellation_point:
983  case OMPD_cancel:
984  case OMPD_target_enter_data:
985  case OMPD_target_exit_data:
986  case OMPD_target_update:
987  if (Allowed == ACK_StatementsOpenMPNonStandalone) {
988  Diag(Tok, diag::err_omp_immediate_directive)
989  << getOpenMPDirectiveName(DKind) << 0;
990  }
991  HasAssociatedStatement = false;
992  // Fall through for further analysis.
993  LLVM_FALLTHROUGH;
994  case OMPD_parallel:
995  case OMPD_simd:
996  case OMPD_for:
997  case OMPD_for_simd:
998  case OMPD_sections:
999  case OMPD_single:
1000  case OMPD_section:
1001  case OMPD_master:
1002  case OMPD_critical:
1003  case OMPD_parallel_for:
1004  case OMPD_parallel_for_simd:
1005  case OMPD_parallel_sections:
1006  case OMPD_task:
1007  case OMPD_ordered:
1008  case OMPD_atomic:
1009  case OMPD_target:
1010  case OMPD_teams:
1011  case OMPD_taskgroup:
1012  case OMPD_target_data:
1013  case OMPD_target_parallel:
1014  case OMPD_target_parallel_for:
1015  case OMPD_taskloop:
1016  case OMPD_taskloop_simd:
1017  case OMPD_distribute:
1018  case OMPD_distribute_parallel_for:
1019  case OMPD_distribute_parallel_for_simd:
1020  case OMPD_distribute_simd:
1021  case OMPD_target_parallel_for_simd:
1022  case OMPD_target_simd:
1023  case OMPD_teams_distribute:
1024  case OMPD_teams_distribute_simd:
1025  case OMPD_teams_distribute_parallel_for_simd:
1026  case OMPD_teams_distribute_parallel_for:
1027  case OMPD_target_teams:
1028  case OMPD_target_teams_distribute:
1029  case OMPD_target_teams_distribute_parallel_for:
1030  case OMPD_target_teams_distribute_parallel_for_simd:
1031  case OMPD_target_teams_distribute_simd: {
1032  ConsumeToken();
1033  // Parse directive name of the 'critical' directive if any.
1034  if (DKind == OMPD_critical) {
1035  BalancedDelimiterTracker T(*this, tok::l_paren,
1036  tok::annot_pragma_openmp_end);
1037  if (!T.consumeOpen()) {
1038  if (Tok.isAnyIdentifier()) {
1039  DirName =
1040  DeclarationNameInfo(Tok.getIdentifierInfo(), Tok.getLocation());
1041  ConsumeAnyToken();
1042  } else {
1043  Diag(Tok, diag::err_omp_expected_identifier_for_critical);
1044  }
1045  T.consumeClose();
1046  }
1047  } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
1048  CancelRegion = parseOpenMPDirectiveKind(*this);
1049  if (Tok.isNot(tok::annot_pragma_openmp_end))
1050  ConsumeToken();
1051  }
1052 
1053  if (isOpenMPLoopDirective(DKind))
1054  ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
1055  if (isOpenMPSimdDirective(DKind))
1056  ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
1057  ParseScope OMPDirectiveScope(this, ScopeFlags);
1058  Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
1059 
1060  while (Tok.isNot(tok::annot_pragma_openmp_end)) {
1061  OpenMPClauseKind CKind =
1062  Tok.isAnnotation()
1063  ? OMPC_unknown
1064  : FlushHasClause ? OMPC_flush
1065  : getOpenMPClauseKind(PP.getSpelling(Tok));
1066  Actions.StartOpenMPClause(CKind);
1067  FlushHasClause = false;
1068  OMPClause *Clause =
1069  ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
1070  FirstClauses[CKind].setInt(true);
1071  if (Clause) {
1072  FirstClauses[CKind].setPointer(Clause);
1073  Clauses.push_back(Clause);
1074  }
1075 
1076  // Skip ',' if any.
1077  if (Tok.is(tok::comma))
1078  ConsumeToken();
1079  Actions.EndOpenMPClause();
1080  }
1081  // End location of the directive.
1082  EndLoc = Tok.getLocation();
1083  // Consume final annot_pragma_openmp_end.
1084  ConsumeAnnotationToken();
1085 
1086  // OpenMP [2.13.8, ordered Construct, Syntax]
1087  // If the depend clause is specified, the ordered construct is a stand-alone
1088  // directive.
1089  if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) {
1090  if (Allowed == ACK_StatementsOpenMPNonStandalone) {
1091  Diag(Loc, diag::err_omp_immediate_directive)
1092  << getOpenMPDirectiveName(DKind) << 1
1093  << getOpenMPClauseName(OMPC_depend);
1094  }
1095  HasAssociatedStatement = false;
1096  }
1097 
1098  StmtResult AssociatedStmt;
1099  if (HasAssociatedStatement) {
1100  // The body is a block scope like in Lambdas and Blocks.
1101  Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
1102  // FIXME: We create a bogus CompoundStmt scope to hold the contents of
1103  // the captured region. Code elsewhere assumes that any FunctionScopeInfo
1104  // should have at least one compound statement scope within it.
1105  AssociatedStmt = (Sema::CompoundScopeRAII(Actions), ParseStatement());
1106  AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
1107  } else if (DKind == OMPD_target_update || DKind == OMPD_target_enter_data ||
1108  DKind == OMPD_target_exit_data) {
1109  Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
1110  AssociatedStmt = (Sema::CompoundScopeRAII(Actions),
1111  Actions.ActOnCompoundStmt(Loc, Loc, llvm::None,
1112  /*isStmtExpr=*/false));
1113  AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
1114  }
1115  Directive = Actions.ActOnOpenMPExecutableDirective(
1116  DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
1117  EndLoc);
1118 
1119  // Exit scope.
1120  Actions.EndOpenMPDSABlock(Directive.get());
1121  OMPDirectiveScope.Exit();
1122  break;
1123  }
1124  case OMPD_declare_simd:
1125  case OMPD_declare_target:
1126  case OMPD_end_declare_target:
1127  Diag(Tok, diag::err_omp_unexpected_directive)
1128  << 1 << getOpenMPDirectiveName(DKind);
1129  SkipUntil(tok::annot_pragma_openmp_end);
1130  break;
1131  case OMPD_unknown:
1132  Diag(Tok, diag::err_omp_unknown_directive);
1133  SkipUntil(tok::annot_pragma_openmp_end);
1134  break;
1135  }
1136  return Directive;
1137 }
1138 
1139 // Parses simple list:
1140 // simple-variable-list:
1141 // '(' id-expression {, id-expression} ')'
1142 //
1143 bool Parser::ParseOpenMPSimpleVarList(
1145  const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> &
1146  Callback,
1147  bool AllowScopeSpecifier) {
1148  // Parse '('.
1149  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1150  if (T.expectAndConsume(diag::err_expected_lparen_after,
1152  return true;
1153  bool IsCorrect = true;
1154  bool NoIdentIsFound = true;
1155 
1156  // Read tokens while ')' or annot_pragma_openmp_end is not found.
1157  while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
1158  CXXScopeSpec SS;
1159  UnqualifiedId Name;
1160  // Read var name.
1161  Token PrevTok = Tok;
1162  NoIdentIsFound = false;
1163 
1164  if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
1165  ParseOptionalCXXScopeSpecifier(SS, nullptr, false)) {
1166  IsCorrect = false;
1167  SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1168  StopBeforeMatch);
1169  } else if (ParseUnqualifiedId(SS, false, false, false, false, nullptr,
1170  nullptr, Name)) {
1171  IsCorrect = false;
1172  SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1173  StopBeforeMatch);
1174  } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
1175  Tok.isNot(tok::annot_pragma_openmp_end)) {
1176  IsCorrect = false;
1177  SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1178  StopBeforeMatch);
1179  Diag(PrevTok.getLocation(), diag::err_expected)
1180  << tok::identifier
1181  << SourceRange(PrevTok.getLocation(), PrevTokLocation);
1182  } else {
1183  Callback(SS, Actions.GetNameFromUnqualifiedId(Name));
1184  }
1185  // Consume ','.
1186  if (Tok.is(tok::comma)) {
1187  ConsumeToken();
1188  }
1189  }
1190 
1191  if (NoIdentIsFound) {
1192  Diag(Tok, diag::err_expected) << tok::identifier;
1193  IsCorrect = false;
1194  }
1195 
1196  // Parse ')'.
1197  IsCorrect = !T.consumeClose() && IsCorrect;
1198 
1199  return !IsCorrect;
1200 }
1201 
1202 /// Parsing of OpenMP clauses.
1203 ///
1204 /// clause:
1205 /// if-clause | final-clause | num_threads-clause | safelen-clause |
1206 /// default-clause | private-clause | firstprivate-clause | shared-clause
1207 /// | linear-clause | aligned-clause | collapse-clause |
1208 /// lastprivate-clause | reduction-clause | proc_bind-clause |
1209 /// schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
1210 /// mergeable-clause | flush-clause | read-clause | write-clause |
1211 /// update-clause | capture-clause | seq_cst-clause | device-clause |
1212 /// simdlen-clause | threads-clause | simd-clause | num_teams-clause |
1213 /// thread_limit-clause | priority-clause | grainsize-clause |
1214 /// nogroup-clause | num_tasks-clause | hint-clause | to-clause |
1215 /// from-clause | is_device_ptr-clause | task_reduction-clause |
1216 /// in_reduction-clause
1217 ///
1218 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
1219  OpenMPClauseKind CKind, bool FirstClause) {
1220  OMPClause *Clause = nullptr;
1221  bool ErrorFound = false;
1222  bool WrongDirective = false;
1223  // Check if clause is allowed for the given directive.
1224  if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) {
1225  Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
1226  << getOpenMPDirectiveName(DKind);
1227  ErrorFound = true;
1228  WrongDirective = true;
1229  }
1230 
1231  switch (CKind) {
1232  case OMPC_final:
1233  case OMPC_num_threads:
1234  case OMPC_safelen:
1235  case OMPC_simdlen:
1236  case OMPC_collapse:
1237  case OMPC_ordered:
1238  case OMPC_device:
1239  case OMPC_num_teams:
1240  case OMPC_thread_limit:
1241  case OMPC_priority:
1242  case OMPC_grainsize:
1243  case OMPC_num_tasks:
1244  case OMPC_hint:
1245  // OpenMP [2.5, Restrictions]
1246  // At most one num_threads clause can appear on the directive.
1247  // OpenMP [2.8.1, simd construct, Restrictions]
1248  // Only one safelen clause can appear on a simd directive.
1249  // Only one simdlen clause can appear on a simd directive.
1250  // Only one collapse clause can appear on a simd directive.
1251  // OpenMP [2.9.1, target data construct, Restrictions]
1252  // At most one device clause can appear on the directive.
1253  // OpenMP [2.11.1, task Construct, Restrictions]
1254  // At most one if clause can appear on the directive.
1255  // At most one final clause can appear on the directive.
1256  // OpenMP [teams Construct, Restrictions]
1257  // At most one num_teams clause can appear on the directive.
1258  // At most one thread_limit clause can appear on the directive.
1259  // OpenMP [2.9.1, task Construct, Restrictions]
1260  // At most one priority clause can appear on the directive.
1261  // OpenMP [2.9.2, taskloop Construct, Restrictions]
1262  // At most one grainsize clause can appear on the directive.
1263  // OpenMP [2.9.2, taskloop Construct, Restrictions]
1264  // At most one num_tasks clause can appear on the directive.
1265  if (!FirstClause) {
1266  Diag(Tok, diag::err_omp_more_one_clause)
1267  << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1268  ErrorFound = true;
1269  }
1270 
1271  if (CKind == OMPC_ordered && PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
1272  Clause = ParseOpenMPClause(CKind, WrongDirective);
1273  else
1274  Clause = ParseOpenMPSingleExprClause(CKind, WrongDirective);
1275  break;
1276  case OMPC_default:
1277  case OMPC_proc_bind:
1278  // OpenMP [2.14.3.1, Restrictions]
1279  // Only a single default clause may be specified on a parallel, task or
1280  // teams directive.
1281  // OpenMP [2.5, parallel Construct, Restrictions]
1282  // At most one proc_bind clause can appear on the directive.
1283  if (!FirstClause) {
1284  Diag(Tok, diag::err_omp_more_one_clause)
1285  << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1286  ErrorFound = true;
1287  }
1288 
1289  Clause = ParseOpenMPSimpleClause(CKind, WrongDirective);
1290  break;
1291  case OMPC_schedule:
1292  case OMPC_dist_schedule:
1293  case OMPC_defaultmap:
1294  // OpenMP [2.7.1, Restrictions, p. 3]
1295  // Only one schedule clause can appear on a loop directive.
1296  // OpenMP [2.10.4, Restrictions, p. 106]
1297  // At most one defaultmap clause can appear on the directive.
1298  if (!FirstClause) {
1299  Diag(Tok, diag::err_omp_more_one_clause)
1300  << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1301  ErrorFound = true;
1302  }
1303  LLVM_FALLTHROUGH;
1304 
1305  case OMPC_if:
1306  Clause = ParseOpenMPSingleExprWithArgClause(CKind, WrongDirective);
1307  break;
1308  case OMPC_nowait:
1309  case OMPC_untied:
1310  case OMPC_mergeable:
1311  case OMPC_read:
1312  case OMPC_write:
1313  case OMPC_update:
1314  case OMPC_capture:
1315  case OMPC_seq_cst:
1316  case OMPC_threads:
1317  case OMPC_simd:
1318  case OMPC_nogroup:
1319  // OpenMP [2.7.1, Restrictions, p. 9]
1320  // Only one ordered clause can appear on a loop directive.
1321  // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
1322  // Only one nowait clause can appear on a for directive.
1323  if (!FirstClause) {
1324  Diag(Tok, diag::err_omp_more_one_clause)
1325  << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
1326  ErrorFound = true;
1327  }
1328 
1329  Clause = ParseOpenMPClause(CKind, WrongDirective);
1330  break;
1331  case OMPC_private:
1332  case OMPC_firstprivate:
1333  case OMPC_lastprivate:
1334  case OMPC_shared:
1335  case OMPC_reduction:
1336  case OMPC_task_reduction:
1337  case OMPC_in_reduction:
1338  case OMPC_linear:
1339  case OMPC_aligned:
1340  case OMPC_copyin:
1341  case OMPC_copyprivate:
1342  case OMPC_flush:
1343  case OMPC_depend:
1344  case OMPC_map:
1345  case OMPC_to:
1346  case OMPC_from:
1347  case OMPC_use_device_ptr:
1348  case OMPC_is_device_ptr:
1349  Clause = ParseOpenMPVarListClause(DKind, CKind, WrongDirective);
1350  break;
1351  case OMPC_unknown:
1352  Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
1353  << getOpenMPDirectiveName(DKind);
1354  SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
1355  break;
1356  case OMPC_threadprivate:
1357  case OMPC_uniform:
1358  if (!WrongDirective)
1359  Diag(Tok, diag::err_omp_unexpected_clause)
1360  << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind);
1361  SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
1362  break;
1363  }
1364  return ErrorFound ? nullptr : Clause;
1365 }
1366 
1367 /// Parses simple expression in parens for single-expression clauses of OpenMP
1368 /// constructs.
1369 /// \param RLoc Returned location of right paren.
1371  SourceLocation &RLoc) {
1372  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1373  if (T.expectAndConsume(diag::err_expected_lparen_after, ClauseName.data()))
1374  return ExprError();
1375 
1376  SourceLocation ELoc = Tok.getLocation();
1377  ExprResult LHS(ParseCastExpression(
1378  /*isUnaryExpression=*/false, /*isAddressOfOperand=*/false, NotTypeCast));
1379  ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
1380  Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
1381 
1382  // Parse ')'.
1383  RLoc = Tok.getLocation();
1384  if (!T.consumeClose())
1385  RLoc = T.getCloseLocation();
1386 
1387  return Val;
1388 }
1389 
1390 /// Parsing of OpenMP clauses with single expressions like 'final',
1391 /// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
1392 /// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks' or 'hint'.
1393 ///
1394 /// final-clause:
1395 /// 'final' '(' expression ')'
1396 ///
1397 /// num_threads-clause:
1398 /// 'num_threads' '(' expression ')'
1399 ///
1400 /// safelen-clause:
1401 /// 'safelen' '(' expression ')'
1402 ///
1403 /// simdlen-clause:
1404 /// 'simdlen' '(' expression ')'
1405 ///
1406 /// collapse-clause:
1407 /// 'collapse' '(' expression ')'
1408 ///
1409 /// priority-clause:
1410 /// 'priority' '(' expression ')'
1411 ///
1412 /// grainsize-clause:
1413 /// 'grainsize' '(' expression ')'
1414 ///
1415 /// num_tasks-clause:
1416 /// 'num_tasks' '(' expression ')'
1417 ///
1418 /// hint-clause:
1419 /// 'hint' '(' expression ')'
1420 ///
1421 OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind,
1422  bool ParseOnly) {
1423  SourceLocation Loc = ConsumeToken();
1424  SourceLocation LLoc = Tok.getLocation();
1425  SourceLocation RLoc;
1426 
1427  ExprResult Val = ParseOpenMPParensExpr(getOpenMPClauseName(Kind), RLoc);
1428 
1429  if (Val.isInvalid())
1430  return nullptr;
1431 
1432  if (ParseOnly)
1433  return nullptr;
1434  return Actions.ActOnOpenMPSingleExprClause(Kind, Val.get(), Loc, LLoc, RLoc);
1435 }
1436 
1437 /// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
1438 ///
1439 /// default-clause:
1440 /// 'default' '(' 'none' | 'shared' ')
1441 ///
1442 /// proc_bind-clause:
1443 /// 'proc_bind' '(' 'master' | 'close' | 'spread' ')
1444 ///
1445 OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind,
1446  bool ParseOnly) {
1447  SourceLocation Loc = Tok.getLocation();
1448  SourceLocation LOpen = ConsumeToken();
1449  // Parse '('.
1450  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1451  if (T.expectAndConsume(diag::err_expected_lparen_after,
1453  return nullptr;
1454 
1455  unsigned Type = getOpenMPSimpleClauseType(
1456  Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1457  SourceLocation TypeLoc = Tok.getLocation();
1458  if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1459  Tok.isNot(tok::annot_pragma_openmp_end))
1460  ConsumeAnyToken();
1461 
1462  // Parse ')'.
1463  SourceLocation RLoc = Tok.getLocation();
1464  if (!T.consumeClose())
1465  RLoc = T.getCloseLocation();
1466 
1467  if (ParseOnly)
1468  return nullptr;
1469  return Actions.ActOnOpenMPSimpleClause(Kind, Type, TypeLoc, LOpen, Loc, RLoc);
1470 }
1471 
1472 /// Parsing of OpenMP clauses like 'ordered'.
1473 ///
1474 /// ordered-clause:
1475 /// 'ordered'
1476 ///
1477 /// nowait-clause:
1478 /// 'nowait'
1479 ///
1480 /// untied-clause:
1481 /// 'untied'
1482 ///
1483 /// mergeable-clause:
1484 /// 'mergeable'
1485 ///
1486 /// read-clause:
1487 /// 'read'
1488 ///
1489 /// threads-clause:
1490 /// 'threads'
1491 ///
1492 /// simd-clause:
1493 /// 'simd'
1494 ///
1495 /// nogroup-clause:
1496 /// 'nogroup'
1497 ///
1498 OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind, bool ParseOnly) {
1499  SourceLocation Loc = Tok.getLocation();
1500  ConsumeAnyToken();
1501 
1502  if (ParseOnly)
1503  return nullptr;
1504  return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
1505 }
1506 
1507 
1508 /// Parsing of OpenMP clauses with single expressions and some additional
1509 /// argument like 'schedule' or 'dist_schedule'.
1510 ///
1511 /// schedule-clause:
1512 /// 'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
1513 /// ')'
1514 ///
1515 /// if-clause:
1516 /// 'if' '(' [ directive-name-modifier ':' ] expression ')'
1517 ///
1518 /// defaultmap:
1519 /// 'defaultmap' '(' modifier ':' kind ')'
1520 ///
1521 OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,
1522  bool ParseOnly) {
1523  SourceLocation Loc = ConsumeToken();
1524  SourceLocation DelimLoc;
1525  // Parse '('.
1526  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1527  if (T.expectAndConsume(diag::err_expected_lparen_after,
1529  return nullptr;
1530 
1531  ExprResult Val;
1534  if (Kind == OMPC_schedule) {
1535  enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
1536  Arg.resize(NumberOfElements);
1537  KLoc.resize(NumberOfElements);
1538  Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
1539  Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
1540  Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
1541  unsigned KindModifier = getOpenMPSimpleClauseType(
1542  Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1543  if (KindModifier > OMPC_SCHEDULE_unknown) {
1544  // Parse 'modifier'
1545  Arg[Modifier1] = KindModifier;
1546  KLoc[Modifier1] = Tok.getLocation();
1547  if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1548  Tok.isNot(tok::annot_pragma_openmp_end))
1549  ConsumeAnyToken();
1550  if (Tok.is(tok::comma)) {
1551  // Parse ',' 'modifier'
1552  ConsumeAnyToken();
1553  KindModifier = getOpenMPSimpleClauseType(
1554  Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1555  Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown
1556  ? KindModifier
1557  : (unsigned)OMPC_SCHEDULE_unknown;
1558  KLoc[Modifier2] = Tok.getLocation();
1559  if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1560  Tok.isNot(tok::annot_pragma_openmp_end))
1561  ConsumeAnyToken();
1562  }
1563  // Parse ':'
1564  if (Tok.is(tok::colon))
1565  ConsumeAnyToken();
1566  else
1567  Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier";
1568  KindModifier = getOpenMPSimpleClauseType(
1569  Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
1570  }
1571  Arg[ScheduleKind] = KindModifier;
1572  KLoc[ScheduleKind] = Tok.getLocation();
1573  if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1574  Tok.isNot(tok::annot_pragma_openmp_end))
1575  ConsumeAnyToken();
1576  if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
1577  Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
1578  Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
1579  Tok.is(tok::comma))
1580  DelimLoc = ConsumeAnyToken();
1581  } else if (Kind == OMPC_dist_schedule) {
1582  Arg.push_back(getOpenMPSimpleClauseType(
1583  Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1584  KLoc.push_back(Tok.getLocation());
1585  if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1586  Tok.isNot(tok::annot_pragma_openmp_end))
1587  ConsumeAnyToken();
1588  if (Arg.back() == OMPC_DIST_SCHEDULE_static && Tok.is(tok::comma))
1589  DelimLoc = ConsumeAnyToken();
1590  } else if (Kind == OMPC_defaultmap) {
1591  // Get a defaultmap modifier
1592  Arg.push_back(getOpenMPSimpleClauseType(
1593  Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1594  KLoc.push_back(Tok.getLocation());
1595  if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1596  Tok.isNot(tok::annot_pragma_openmp_end))
1597  ConsumeAnyToken();
1598  // Parse ':'
1599  if (Tok.is(tok::colon))
1600  ConsumeAnyToken();
1601  else if (Arg.back() != OMPC_DEFAULTMAP_MODIFIER_unknown)
1602  Diag(Tok, diag::warn_pragma_expected_colon) << "defaultmap modifier";
1603  // Get a defaultmap kind
1604  Arg.push_back(getOpenMPSimpleClauseType(
1605  Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok)));
1606  KLoc.push_back(Tok.getLocation());
1607  if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
1608  Tok.isNot(tok::annot_pragma_openmp_end))
1609  ConsumeAnyToken();
1610  } else {
1611  assert(Kind == OMPC_if);
1612  KLoc.push_back(Tok.getLocation());
1613  TentativeParsingAction TPA(*this);
1614  Arg.push_back(parseOpenMPDirectiveKind(*this));
1615  if (Arg.back() != OMPD_unknown) {
1616  ConsumeToken();
1617  if (Tok.is(tok::colon) && getLangOpts().OpenMP > 40) {
1618  TPA.Commit();
1619  DelimLoc = ConsumeToken();
1620  } else {
1621  TPA.Revert();
1622  Arg.back() = OMPD_unknown;
1623  }
1624  } else {
1625  TPA.Revert();
1626  }
1627  }
1628 
1629  bool NeedAnExpression = (Kind == OMPC_schedule && DelimLoc.isValid()) ||
1630  (Kind == OMPC_dist_schedule && DelimLoc.isValid()) ||
1631  Kind == OMPC_if;
1632  if (NeedAnExpression) {
1633  SourceLocation ELoc = Tok.getLocation();
1634  ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
1635  Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
1636  Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
1637  }
1638 
1639  // Parse ')'.
1640  SourceLocation RLoc = Tok.getLocation();
1641  if (!T.consumeClose())
1642  RLoc = T.getCloseLocation();
1643 
1644  if (NeedAnExpression && Val.isInvalid())
1645  return nullptr;
1646 
1647  if (ParseOnly)
1648  return nullptr;
1649  return Actions.ActOnOpenMPSingleExprWithArgClause(
1650  Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc, RLoc);
1651 }
1652 
1653 static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
1654  UnqualifiedId &ReductionId) {
1655  if (ReductionIdScopeSpec.isEmpty()) {
1656  auto OOK = OO_None;
1657  switch (P.getCurToken().getKind()) {
1658  case tok::plus:
1659  OOK = OO_Plus;
1660  break;
1661  case tok::minus:
1662  OOK = OO_Minus;
1663  break;
1664  case tok::star:
1665  OOK = OO_Star;
1666  break;
1667  case tok::amp:
1668  OOK = OO_Amp;
1669  break;
1670  case tok::pipe:
1671  OOK = OO_Pipe;
1672  break;
1673  case tok::caret:
1674  OOK = OO_Caret;
1675  break;
1676  case tok::ampamp:
1677  OOK = OO_AmpAmp;
1678  break;
1679  case tok::pipepipe:
1680  OOK = OO_PipePipe;
1681  break;
1682  default:
1683  break;
1684  }
1685  if (OOK != OO_None) {
1686  SourceLocation OpLoc = P.ConsumeToken();
1687  SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
1688  ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
1689  return false;
1690  }
1691  }
1692  return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false,
1693  /*AllowDestructorName*/ false,
1694  /*AllowConstructorName*/ false,
1695  /*AllowDeductionGuide*/ false,
1696  nullptr, nullptr, ReductionId);
1697 }
1698 
1699 /// Parses clauses with list.
1703  OpenMPVarListDataTy &Data) {
1704  UnqualifiedId UnqualifiedReductionId;
1705  bool InvalidReductionId = false;
1706  bool MapTypeModifierSpecified = false;
1707 
1708  // Parse '('.
1709  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
1710  if (T.expectAndConsume(diag::err_expected_lparen_after,
1711  getOpenMPClauseName(Kind)))
1712  return true;
1713 
1714  bool NeedRParenForLinear = false;
1715  BalancedDelimiterTracker LinearT(*this, tok::l_paren,
1716  tok::annot_pragma_openmp_end);
1717  // Handle reduction-identifier for reduction clause.
1718  if (Kind == OMPC_reduction || Kind == OMPC_task_reduction ||
1719  Kind == OMPC_in_reduction) {
1720  ColonProtectionRAIIObject ColonRAII(*this);
1721  if (getLangOpts().CPlusPlus)
1722  ParseOptionalCXXScopeSpecifier(Data.ReductionIdScopeSpec,
1723  /*ObjectType=*/nullptr,
1724  /*EnteringContext=*/false);
1725  InvalidReductionId = ParseReductionId(*this, Data.ReductionIdScopeSpec,
1726  UnqualifiedReductionId);
1727  if (InvalidReductionId) {
1728  SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
1729  StopBeforeMatch);
1730  }
1731  if (Tok.is(tok::colon))
1732  Data.ColonLoc = ConsumeToken();
1733  else
1734  Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
1735  if (!InvalidReductionId)
1736  Data.ReductionId =
1737  Actions.GetNameFromUnqualifiedId(UnqualifiedReductionId);
1738  } else if (Kind == OMPC_depend) {
1739  // Handle dependency type for depend clause.
1740  ColonProtectionRAIIObject ColonRAII(*this);
1741  Data.DepKind =
1743  Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
1744  Data.DepLinMapLoc = Tok.getLocation();
1745 
1746  if (Data.DepKind == OMPC_DEPEND_unknown) {
1747  SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
1748  StopBeforeMatch);
1749  } else {
1750  ConsumeToken();
1751  // Special processing for depend(source) clause.
1752  if (DKind == OMPD_ordered && Data.DepKind == OMPC_DEPEND_source) {
1753  // Parse ')'.
1754  T.consumeClose();
1755  return false;
1756  }
1757  }
1758  if (Tok.is(tok::colon)) {
1759  Data.ColonLoc = ConsumeToken();
1760  } else {
1761  Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
1762  : diag::warn_pragma_expected_colon)
1763  << "dependency type";
1764  }
1765  } else if (Kind == OMPC_linear) {
1766  // Try to parse modifier if any.
1767  if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
1768  Data.LinKind = static_cast<OpenMPLinearClauseKind>(
1769  getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
1770  Data.DepLinMapLoc = ConsumeToken();
1771  LinearT.consumeOpen();
1772  NeedRParenForLinear = true;
1773  }
1774  } else if (Kind == OMPC_map) {
1775  // Handle map type for map clause.
1776  ColonProtectionRAIIObject ColonRAII(*this);
1777 
1778  /// The map clause modifier token can be either a identifier or the C++
1779  /// delete keyword.
1780  auto &&IsMapClauseModifierToken = [](const Token &Tok) -> bool {
1781  return Tok.isOneOf(tok::identifier, tok::kw_delete);
1782  };
1783 
1784  // The first identifier may be a list item, a map-type or a
1785  // map-type-modifier. The map modifier can also be delete which has the same
1786  // spelling of the C++ delete keyword.
1787  Data.MapType =
1788  IsMapClauseModifierToken(Tok)
1789  ? static_cast<OpenMPMapClauseKind>(
1790  getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)))
1791  : OMPC_MAP_unknown;
1792  Data.DepLinMapLoc = Tok.getLocation();
1793  bool ColonExpected = false;
1794 
1795  if (IsMapClauseModifierToken(Tok)) {
1796  if (PP.LookAhead(0).is(tok::colon)) {
1797  if (Data.MapType == OMPC_MAP_unknown)
1798  Diag(Tok, diag::err_omp_unknown_map_type);
1799  else if (Data.MapType == OMPC_MAP_always)
1800  Diag(Tok, diag::err_omp_map_type_missing);
1801  ConsumeToken();
1802  } else if (PP.LookAhead(0).is(tok::comma)) {
1803  if (IsMapClauseModifierToken(PP.LookAhead(1)) &&
1804  PP.LookAhead(2).is(tok::colon)) {
1805  Data.MapTypeModifier = Data.MapType;
1806  if (Data.MapTypeModifier != OMPC_MAP_always) {
1807  Diag(Tok, diag::err_omp_unknown_map_type_modifier);
1809  } else {
1810  MapTypeModifierSpecified = true;
1811  }
1812 
1813  ConsumeToken();
1814  ConsumeToken();
1815 
1816  Data.MapType =
1817  IsMapClauseModifierToken(Tok)
1818  ? static_cast<OpenMPMapClauseKind>(
1819  getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)))
1820  : OMPC_MAP_unknown;
1821  if (Data.MapType == OMPC_MAP_unknown ||
1822  Data.MapType == OMPC_MAP_always)
1823  Diag(Tok, diag::err_omp_unknown_map_type);
1824  ConsumeToken();
1825  } else {
1826  Data.MapType = OMPC_MAP_tofrom;
1827  Data.IsMapTypeImplicit = true;
1828  }
1829  } else if (IsMapClauseModifierToken(PP.LookAhead(0))) {
1830  if (PP.LookAhead(1).is(tok::colon)) {
1831  Data.MapTypeModifier = Data.MapType;
1832  if (Data.MapTypeModifier != OMPC_MAP_always) {
1833  Diag(Tok, diag::err_omp_unknown_map_type_modifier);
1835  } else {
1836  MapTypeModifierSpecified = true;
1837  }
1838 
1839  ConsumeToken();
1840 
1841  Data.MapType =
1842  IsMapClauseModifierToken(Tok)
1843  ? static_cast<OpenMPMapClauseKind>(
1844  getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)))
1845  : OMPC_MAP_unknown;
1846  if (Data.MapType == OMPC_MAP_unknown ||
1847  Data.MapType == OMPC_MAP_always)
1848  Diag(Tok, diag::err_omp_unknown_map_type);
1849  ConsumeToken();
1850  } else {
1851  Data.MapType = OMPC_MAP_tofrom;
1852  Data.IsMapTypeImplicit = true;
1853  }
1854  } else {
1855  Data.MapType = OMPC_MAP_tofrom;
1856  Data.IsMapTypeImplicit = true;
1857  }
1858  } else {
1859  Data.MapType = OMPC_MAP_tofrom;
1860  Data.IsMapTypeImplicit = true;
1861  }
1862 
1863  if (Tok.is(tok::colon))
1864  Data.ColonLoc = ConsumeToken();
1865  else if (ColonExpected)
1866  Diag(Tok, diag::warn_pragma_expected_colon) << "map type";
1867  }
1868 
1869  bool IsComma =
1870  (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
1871  Kind != OMPC_in_reduction && Kind != OMPC_depend && Kind != OMPC_map) ||
1872  (Kind == OMPC_reduction && !InvalidReductionId) ||
1873  (Kind == OMPC_map && Data.MapType != OMPC_MAP_unknown &&
1874  (!MapTypeModifierSpecified ||
1875  Data.MapTypeModifier == OMPC_MAP_always)) ||
1876  (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown);
1877  const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
1878  while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
1879  Tok.isNot(tok::annot_pragma_openmp_end))) {
1880  ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
1881  // Parse variable
1882  ExprResult VarExpr =
1883  Actions.CorrectDelayedTyposInExpr(ParseAssignmentExpression());
1884  if (VarExpr.isUsable()) {
1885  Vars.push_back(VarExpr.get());
1886  } else {
1887  SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1888  StopBeforeMatch);
1889  }
1890  // Skip ',' if any
1891  IsComma = Tok.is(tok::comma);
1892  if (IsComma)
1893  ConsumeToken();
1894  else if (Tok.isNot(tok::r_paren) &&
1895  Tok.isNot(tok::annot_pragma_openmp_end) &&
1896  (!MayHaveTail || Tok.isNot(tok::colon)))
1897  Diag(Tok, diag::err_omp_expected_punc)
1898  << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
1899  : getOpenMPClauseName(Kind))
1900  << (Kind == OMPC_flush);
1901  }
1902 
1903  // Parse ')' for linear clause with modifier.
1904  if (NeedRParenForLinear)
1905  LinearT.consumeClose();
1906 
1907  // Parse ':' linear-step (or ':' alignment).
1908  const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
1909  if (MustHaveTail) {
1910  Data.ColonLoc = Tok.getLocation();
1911  SourceLocation ELoc = ConsumeToken();
1912  ExprResult Tail = ParseAssignmentExpression();
1913  Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc);
1914  if (Tail.isUsable())
1915  Data.TailExpr = Tail.get();
1916  else
1917  SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1918  StopBeforeMatch);
1919  }
1920 
1921  // Parse ')'.
1922  Data.RLoc = Tok.getLocation();
1923  if (!T.consumeClose())
1924  Data.RLoc = T.getCloseLocation();
1925  return (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown &&
1926  Vars.empty()) ||
1927  (Kind != OMPC_depend && Kind != OMPC_map && Vars.empty()) ||
1928  (MustHaveTail && !Data.TailExpr) || InvalidReductionId;
1929 }
1930 
1931 /// Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
1932 /// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction', 'task_reduction' or
1933 /// 'in_reduction'.
1934 ///
1935 /// private-clause:
1936 /// 'private' '(' list ')'
1937 /// firstprivate-clause:
1938 /// 'firstprivate' '(' list ')'
1939 /// lastprivate-clause:
1940 /// 'lastprivate' '(' list ')'
1941 /// shared-clause:
1942 /// 'shared' '(' list ')'
1943 /// linear-clause:
1944 /// 'linear' '(' linear-list [ ':' linear-step ] ')'
1945 /// aligned-clause:
1946 /// 'aligned' '(' list [ ':' alignment ] ')'
1947 /// reduction-clause:
1948 /// 'reduction' '(' reduction-identifier ':' list ')'
1949 /// task_reduction-clause:
1950 /// 'task_reduction' '(' reduction-identifier ':' list ')'
1951 /// in_reduction-clause:
1952 /// 'in_reduction' '(' reduction-identifier ':' list ')'
1953 /// copyprivate-clause:
1954 /// 'copyprivate' '(' list ')'
1955 /// flush-clause:
1956 /// 'flush' '(' list ')'
1957 /// depend-clause:
1958 /// 'depend' '(' in | out | inout : list | source ')'
1959 /// map-clause:
1960 /// 'map' '(' [ [ always , ]
1961 /// to | from | tofrom | alloc | release | delete ':' ] list ')';
1962 /// to-clause:
1963 /// 'to' '(' list ')'
1964 /// from-clause:
1965 /// 'from' '(' list ')'
1966 /// use_device_ptr-clause:
1967 /// 'use_device_ptr' '(' list ')'
1968 /// is_device_ptr-clause:
1969 /// 'is_device_ptr' '(' list ')'
1970 ///
1971 /// For 'linear' clause linear-list may have the following forms:
1972 /// list
1973 /// modifier(list)
1974 /// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
1975 OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
1977  bool ParseOnly) {
1978  SourceLocation Loc = Tok.getLocation();
1979  SourceLocation LOpen = ConsumeToken();
1981  OpenMPVarListDataTy Data;
1982 
1983  if (ParseOpenMPVarList(DKind, Kind, Vars, Data))
1984  return nullptr;
1985 
1986  if (ParseOnly)
1987  return nullptr;
1988  return Actions.ActOnOpenMPVarListClause(
1989  Kind, Vars, Data.TailExpr, Loc, LOpen, Data.ColonLoc, Data.RLoc,
1990  Data.ReductionIdScopeSpec, Data.ReductionId, Data.DepKind, Data.LinKind,
1991  Data.MapTypeModifier, Data.MapType, Data.IsMapTypeImplicit,
1992  Data.DepLinMapLoc);
1993 }
1994 
OpenMPDependClauseKind DepKind
Definition: Parser.h:2844
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:945
A (possibly-)qualified type.
Definition: Type.h:655
DeclarationNameInfo ReductionId
Definition: Parser.h:2843
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:86
StringRef P
The base class of the type hierarchy.
Definition: Type.h:1428
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: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: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:814
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:5093
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:1039
OpenMPLinearClauseKind LinKind
Definition: Parser.h:2845
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:56
Represents a struct/union/class.
Definition: Decl.h:3570
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:922
PtrTy get() const
Definition: Ownership.h:174
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: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:277
bool isOneOf(A K1, B K2) const
Definition: FormatToken.h:319
A RAII object to enter scope of a compound statement.
Definition: Sema.h:3699
DeclarationNameTable DeclarationNames
Definition: ASTContext.h:548
OpenMPMapClauseKind MapTypeModifier
Definition: Parser.h:2846
This is the scope of OpenMP executable directive.
Definition: Scope.h:107
Sema & getActions() const
Definition: Parser.h:362
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:365
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:428
This is a compound statement scope.
Definition: Scope.h:130
Preprocessor & getPreprocessor() const
Definition: Parser.h:361
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:720
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:1211
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:310
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:366
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:2249
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:115
bool isFunctionOrFunctionTemplate() const
Whether this declaration is a function or function template.
Definition: DeclBase.h:1018
This is a scope that corresponds to the template parameters of a C++ template.
Definition: Scope.h:77
DeclarationName - The name of a declaration.
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
Data used for parsing list of variables in OpenMP clauses.
Definition: Parser.h:2838
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:2214
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:1303
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:59
SourceLocation ConsumeToken()
ConsumeToken - Consume the current &#39;peek token&#39; and lex the next one.
Definition: Parser.h:404
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:110
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:248
Directive - Abstract class representing a parsed verify directive.
SourceLocation getBegin() const
VerifyDiagnosticConsumer::Directive Directive
SourceLocation getLocation() const
Definition: DeclBase.h:419
OpenMPMapClauseKind MapType
Definition: Parser.h:2847
bool isCXXInstanceMember() const
Determine whether the given declaration is an instance member of a C++ class.
Definition: Decl.cpp:1718
Stop skipping at specified token, but don&#39;t skip the token itself.
Definition: Parser.h:1021
SourceLocation getEndLoc() const
Definition: Token.h:151