clang  3.8.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 /// \brief This file implements parsing of all OpenMP directives and clauses.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #include "RAIIObjectsForParser.h"
15 #include "clang/AST/ASTConsumer.h"
16 #include "clang/AST/ASTContext.h"
17 #include "clang/AST/StmtOpenMP.h"
19 #include "clang/Parse/Parser.h"
20 #include "clang/Sema/Scope.h"
21 #include "llvm/ADT/PointerIntPair.h"
22 
23 using namespace clang;
24 
25 //===----------------------------------------------------------------------===//
26 // OpenMP declarative directives.
27 //===----------------------------------------------------------------------===//
28 
30  // Array of foldings: F[i][0] F[i][1] ===> F[i][2].
31  // E.g.: OMPD_for OMPD_simd ===> OMPD_for_simd
32  // TODO: add other combined directives in topological order.
33  const OpenMPDirectiveKind F[][3] = {
34  {OMPD_unknown /*cancellation*/, OMPD_unknown /*point*/,
35  OMPD_cancellation_point},
36  {OMPD_target, OMPD_unknown /*data*/, OMPD_target_data},
37  {OMPD_for, OMPD_simd, OMPD_for_simd},
38  {OMPD_parallel, OMPD_for, OMPD_parallel_for},
39  {OMPD_parallel_for, OMPD_simd, OMPD_parallel_for_simd},
40  {OMPD_parallel, OMPD_sections, OMPD_parallel_sections},
41  {OMPD_taskloop, OMPD_simd, OMPD_taskloop_simd}};
42  auto Tok = P.getCurToken();
43  auto DKind =
44  Tok.isAnnotation()
45  ? OMPD_unknown
47 
48  bool TokenMatched = false;
49  for (unsigned i = 0; i < llvm::array_lengthof(F); ++i) {
50  if (!Tok.isAnnotation() && DKind == OMPD_unknown) {
51  TokenMatched =
52  (i == 0) &&
53  !P.getPreprocessor().getSpelling(Tok).compare("cancellation");
54  } else {
55  TokenMatched = DKind == F[i][0] && DKind != OMPD_unknown;
56  }
57 
58  if (TokenMatched) {
59  Tok = P.getPreprocessor().LookAhead(0);
60  auto TokenIsAnnotation = Tok.isAnnotation();
61  auto SDKind =
62  TokenIsAnnotation
63  ? OMPD_unknown
65 
66  if (!TokenIsAnnotation && SDKind == OMPD_unknown) {
67  TokenMatched =
68  ((i == 0) &&
69  !P.getPreprocessor().getSpelling(Tok).compare("point")) ||
70  ((i == 1) && !P.getPreprocessor().getSpelling(Tok).compare("data"));
71  } else {
72  TokenMatched = SDKind == F[i][1] && SDKind != OMPD_unknown;
73  }
74 
75  if (TokenMatched) {
76  P.ConsumeToken();
77  DKind = F[i][2];
78  }
79  }
80  }
81  return DKind;
82 }
83 
84 /// \brief Parsing of declarative OpenMP directives.
85 ///
86 /// threadprivate-directive:
87 /// annot_pragma_openmp 'threadprivate' simple-variable-list
88 ///
89 Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() {
90  assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
91  ParenBraceBracketBalancer BalancerRAIIObj(*this);
92 
94  SmallVector<Expr *, 5> Identifiers;
95  auto DKind = ParseOpenMPDirectiveKind(*this);
96 
97  switch (DKind) {
98  case OMPD_threadprivate:
99  ConsumeToken();
100  if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Identifiers, true)) {
101  // The last seen token is annot_pragma_openmp_end - need to check for
102  // extra tokens.
103  if (Tok.isNot(tok::annot_pragma_openmp_end)) {
104  Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
105  << getOpenMPDirectiveName(OMPD_threadprivate);
106  SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
107  }
108  // Skip the last annot_pragma_openmp_end.
109  ConsumeToken();
110  return Actions.ActOnOpenMPThreadprivateDirective(Loc, Identifiers);
111  }
112  break;
113  case OMPD_unknown:
114  Diag(Tok, diag::err_omp_unknown_directive);
115  break;
116  case OMPD_parallel:
117  case OMPD_simd:
118  case OMPD_task:
119  case OMPD_taskyield:
120  case OMPD_barrier:
121  case OMPD_taskwait:
122  case OMPD_taskgroup:
123  case OMPD_flush:
124  case OMPD_for:
125  case OMPD_for_simd:
126  case OMPD_sections:
127  case OMPD_section:
128  case OMPD_single:
129  case OMPD_master:
130  case OMPD_ordered:
131  case OMPD_critical:
132  case OMPD_parallel_for:
133  case OMPD_parallel_for_simd:
134  case OMPD_parallel_sections:
135  case OMPD_atomic:
136  case OMPD_target:
137  case OMPD_teams:
138  case OMPD_cancellation_point:
139  case OMPD_cancel:
140  case OMPD_target_data:
141  case OMPD_taskloop:
142  case OMPD_taskloop_simd:
143  case OMPD_distribute:
144  Diag(Tok, diag::err_omp_unexpected_directive)
145  << getOpenMPDirectiveName(DKind);
146  break;
147  }
148  SkipUntil(tok::annot_pragma_openmp_end);
149  return DeclGroupPtrTy();
150 }
151 
152 /// \brief Parsing of declarative or executable OpenMP directives.
153 ///
154 /// threadprivate-directive:
155 /// annot_pragma_openmp 'threadprivate' simple-variable-list
156 /// annot_pragma_openmp_end
157 ///
158 /// executable-directive:
159 /// annot_pragma_openmp 'parallel' | 'simd' | 'for' | 'sections' |
160 /// 'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
161 /// 'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
162 /// 'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' |
163 /// 'for simd' | 'parallel for simd' | 'target' | 'target data' |
164 /// 'taskgroup' | 'teams' | 'taskloop' | 'taskloop simd' {clause} |
165 /// 'distribute'
166 /// annot_pragma_openmp_end
167 ///
168 StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
169  AllowedContsructsKind Allowed) {
170  assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
171  ParenBraceBracketBalancer BalancerRAIIObj(*this);
172  SmallVector<Expr *, 5> Identifiers;
175  FirstClauses(OMPC_unknown + 1);
176  unsigned ScopeFlags =
178  SourceLocation Loc = ConsumeToken(), EndLoc;
179  auto DKind = ParseOpenMPDirectiveKind(*this);
180  OpenMPDirectiveKind CancelRegion = OMPD_unknown;
181  // Name of critical directive.
182  DeclarationNameInfo DirName;
184  bool HasAssociatedStatement = true;
185  bool FlushHasClause = false;
186 
187  switch (DKind) {
188  case OMPD_threadprivate:
189  if (Allowed != ACK_Any) {
190  Diag(Tok, diag::err_omp_immediate_directive)
191  << getOpenMPDirectiveName(DKind) << 0;
192  }
193  ConsumeToken();
194  if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Identifiers, false)) {
195  // The last seen token is annot_pragma_openmp_end - need to check for
196  // extra tokens.
197  if (Tok.isNot(tok::annot_pragma_openmp_end)) {
198  Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
199  << getOpenMPDirectiveName(OMPD_threadprivate);
200  SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
201  }
202  DeclGroupPtrTy Res =
203  Actions.ActOnOpenMPThreadprivateDirective(Loc, Identifiers);
204  Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
205  }
206  SkipUntil(tok::annot_pragma_openmp_end);
207  break;
208  case OMPD_flush:
209  if (PP.LookAhead(0).is(tok::l_paren)) {
210  FlushHasClause = true;
211  // Push copy of the current token back to stream to properly parse
212  // pseudo-clause OMPFlushClause.
213  PP.EnterToken(Tok);
214  }
215  case OMPD_taskyield:
216  case OMPD_barrier:
217  case OMPD_taskwait:
218  case OMPD_cancellation_point:
219  case OMPD_cancel:
220  if (Allowed == ACK_StatementsOpenMPNonStandalone) {
221  Diag(Tok, diag::err_omp_immediate_directive)
222  << getOpenMPDirectiveName(DKind) << 0;
223  }
224  HasAssociatedStatement = false;
225  // Fall through for further analysis.
226  case OMPD_parallel:
227  case OMPD_simd:
228  case OMPD_for:
229  case OMPD_for_simd:
230  case OMPD_sections:
231  case OMPD_single:
232  case OMPD_section:
233  case OMPD_master:
234  case OMPD_critical:
235  case OMPD_parallel_for:
236  case OMPD_parallel_for_simd:
237  case OMPD_parallel_sections:
238  case OMPD_task:
239  case OMPD_ordered:
240  case OMPD_atomic:
241  case OMPD_target:
242  case OMPD_teams:
243  case OMPD_taskgroup:
244  case OMPD_target_data:
245  case OMPD_taskloop:
246  case OMPD_taskloop_simd:
247  case OMPD_distribute: {
248  ConsumeToken();
249  // Parse directive name of the 'critical' directive if any.
250  if (DKind == OMPD_critical) {
251  BalancedDelimiterTracker T(*this, tok::l_paren,
252  tok::annot_pragma_openmp_end);
253  if (!T.consumeOpen()) {
254  if (Tok.isAnyIdentifier()) {
255  DirName =
257  ConsumeAnyToken();
258  } else {
259  Diag(Tok, diag::err_omp_expected_identifier_for_critical);
260  }
261  T.consumeClose();
262  }
263  } else if (DKind == OMPD_cancellation_point || DKind == OMPD_cancel) {
264  CancelRegion = ParseOpenMPDirectiveKind(*this);
265  if (Tok.isNot(tok::annot_pragma_openmp_end))
266  ConsumeToken();
267  }
268 
269  if (isOpenMPLoopDirective(DKind))
270  ScopeFlags |= Scope::OpenMPLoopDirectiveScope;
271  if (isOpenMPSimdDirective(DKind))
272  ScopeFlags |= Scope::OpenMPSimdDirectiveScope;
273  ParseScope OMPDirectiveScope(this, ScopeFlags);
274  Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
275 
276  while (Tok.isNot(tok::annot_pragma_openmp_end)) {
277  OpenMPClauseKind CKind =
278  Tok.isAnnotation()
279  ? OMPC_unknown
280  : FlushHasClause ? OMPC_flush
281  : getOpenMPClauseKind(PP.getSpelling(Tok));
282  Actions.StartOpenMPClause(CKind);
283  FlushHasClause = false;
284  OMPClause *Clause =
285  ParseOpenMPClause(DKind, CKind, !FirstClauses[CKind].getInt());
286  FirstClauses[CKind].setInt(true);
287  if (Clause) {
288  FirstClauses[CKind].setPointer(Clause);
289  Clauses.push_back(Clause);
290  }
291 
292  // Skip ',' if any.
293  if (Tok.is(tok::comma))
294  ConsumeToken();
295  Actions.EndOpenMPClause();
296  }
297  // End location of the directive.
298  EndLoc = Tok.getLocation();
299  // Consume final annot_pragma_openmp_end.
300  ConsumeToken();
301 
302  // OpenMP [2.13.8, ordered Construct, Syntax]
303  // If the depend clause is specified, the ordered construct is a stand-alone
304  // directive.
305  if (DKind == OMPD_ordered && FirstClauses[OMPC_depend].getInt()) {
306  if (Allowed == ACK_StatementsOpenMPNonStandalone) {
307  Diag(Loc, diag::err_omp_immediate_directive)
308  << getOpenMPDirectiveName(DKind) << 1
309  << getOpenMPClauseName(OMPC_depend);
310  }
311  HasAssociatedStatement = false;
312  }
313 
314  StmtResult AssociatedStmt;
315  if (HasAssociatedStatement) {
316  // The body is a block scope like in Lambdas and Blocks.
317  Sema::CompoundScopeRAII CompoundScope(Actions);
318  Actions.ActOnOpenMPRegionStart(DKind, getCurScope());
319  Actions.ActOnStartOfCompoundStmt();
320  // Parse statement
321  AssociatedStmt = ParseStatement();
322  Actions.ActOnFinishOfCompoundStmt();
323  AssociatedStmt = Actions.ActOnOpenMPRegionEnd(AssociatedStmt, Clauses);
324  }
325  Directive = Actions.ActOnOpenMPExecutableDirective(
326  DKind, DirName, CancelRegion, Clauses, AssociatedStmt.get(), Loc,
327  EndLoc);
328 
329  // Exit scope.
330  Actions.EndOpenMPDSABlock(Directive.get());
331  OMPDirectiveScope.Exit();
332  break;
333  }
334  case OMPD_unknown:
335  Diag(Tok, diag::err_omp_unknown_directive);
336  SkipUntil(tok::annot_pragma_openmp_end);
337  break;
338  }
339  return Directive;
340 }
341 
342 /// \brief Parses list of simple variables for '#pragma omp threadprivate'
343 /// directive.
344 ///
345 /// simple-variable-list:
346 /// '(' id-expression {, id-expression} ')'
347 ///
348 bool Parser::ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind,
349  SmallVectorImpl<Expr *> &VarList,
350  bool AllowScopeSpecifier) {
351  VarList.clear();
352  // Parse '('.
353  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
354  if (T.expectAndConsume(diag::err_expected_lparen_after,
355  getOpenMPDirectiveName(Kind)))
356  return true;
357  bool IsCorrect = true;
358  bool NoIdentIsFound = true;
359 
360  // Read tokens while ')' or annot_pragma_openmp_end is not found.
361  while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::annot_pragma_openmp_end)) {
362  CXXScopeSpec SS;
363  SourceLocation TemplateKWLoc;
365  // Read var name.
366  Token PrevTok = Tok;
367  NoIdentIsFound = false;
368 
369  if (AllowScopeSpecifier && getLangOpts().CPlusPlus &&
370  ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false)) {
371  IsCorrect = false;
372  SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
374  } else if (ParseUnqualifiedId(SS, false, false, false, ParsedType(),
375  TemplateKWLoc, Name)) {
376  IsCorrect = false;
377  SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
379  } else if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren) &&
380  Tok.isNot(tok::annot_pragma_openmp_end)) {
381  IsCorrect = false;
382  SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
384  Diag(PrevTok.getLocation(), diag::err_expected)
385  << tok::identifier
386  << SourceRange(PrevTok.getLocation(), PrevTokLocation);
387  } else {
388  DeclarationNameInfo NameInfo = Actions.GetNameFromUnqualifiedId(Name);
389  ExprResult Res =
390  Actions.ActOnOpenMPIdExpression(getCurScope(), SS, NameInfo);
391  if (Res.isUsable())
392  VarList.push_back(Res.get());
393  }
394  // Consume ','.
395  if (Tok.is(tok::comma)) {
396  ConsumeToken();
397  }
398  }
399 
400  if (NoIdentIsFound) {
401  Diag(Tok, diag::err_expected) << tok::identifier;
402  IsCorrect = false;
403  }
404 
405  // Parse ')'.
406  IsCorrect = !T.consumeClose() && IsCorrect;
407 
408  return !IsCorrect && VarList.empty();
409 }
410 
411 /// \brief Parsing of OpenMP clauses.
412 ///
413 /// clause:
414 /// if-clause | final-clause | num_threads-clause | safelen-clause |
415 /// default-clause | private-clause | firstprivate-clause | shared-clause
416 /// | linear-clause | aligned-clause | collapse-clause |
417 /// lastprivate-clause | reduction-clause | proc_bind-clause |
418 /// schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
419 /// mergeable-clause | flush-clause | read-clause | write-clause |
420 /// update-clause | capture-clause | seq_cst-clause | device-clause |
421 /// simdlen-clause | threads-clause | simd-clause | num_teams-clause |
422 /// thread_limit-clause | priority-clause | grainsize-clause |
423 /// nogroup-clause | num_tasks-clause | hint-clause
424 ///
425 OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
426  OpenMPClauseKind CKind, bool FirstClause) {
427  OMPClause *Clause = nullptr;
428  bool ErrorFound = false;
429  // Check if clause is allowed for the given directive.
430  if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) {
431  Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
432  << getOpenMPDirectiveName(DKind);
433  ErrorFound = true;
434  }
435 
436  switch (CKind) {
437  case OMPC_final:
438  case OMPC_num_threads:
439  case OMPC_safelen:
440  case OMPC_simdlen:
441  case OMPC_collapse:
442  case OMPC_ordered:
443  case OMPC_device:
444  case OMPC_num_teams:
445  case OMPC_thread_limit:
446  case OMPC_priority:
447  case OMPC_grainsize:
448  case OMPC_num_tasks:
449  case OMPC_hint:
450  // OpenMP [2.5, Restrictions]
451  // At most one num_threads clause can appear on the directive.
452  // OpenMP [2.8.1, simd construct, Restrictions]
453  // Only one safelen clause can appear on a simd directive.
454  // Only one simdlen clause can appear on a simd directive.
455  // Only one collapse clause can appear on a simd directive.
456  // OpenMP [2.9.1, target data construct, Restrictions]
457  // At most one device clause can appear on the directive.
458  // OpenMP [2.11.1, task Construct, Restrictions]
459  // At most one if clause can appear on the directive.
460  // At most one final clause can appear on the directive.
461  // OpenMP [teams Construct, Restrictions]
462  // At most one num_teams clause can appear on the directive.
463  // At most one thread_limit clause can appear on the directive.
464  // OpenMP [2.9.1, task Construct, Restrictions]
465  // At most one priority clause can appear on the directive.
466  // OpenMP [2.9.2, taskloop Construct, Restrictions]
467  // At most one grainsize clause can appear on the directive.
468  // OpenMP [2.9.2, taskloop Construct, Restrictions]
469  // At most one num_tasks clause can appear on the directive.
470  if (!FirstClause) {
471  Diag(Tok, diag::err_omp_more_one_clause)
472  << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
473  ErrorFound = true;
474  }
475 
476  if (CKind == OMPC_ordered && PP.LookAhead(/*N=*/0).isNot(tok::l_paren))
477  Clause = ParseOpenMPClause(CKind);
478  else
479  Clause = ParseOpenMPSingleExprClause(CKind);
480  break;
481  case OMPC_default:
482  case OMPC_proc_bind:
483  // OpenMP [2.14.3.1, Restrictions]
484  // Only a single default clause may be specified on a parallel, task or
485  // teams directive.
486  // OpenMP [2.5, parallel Construct, Restrictions]
487  // At most one proc_bind clause can appear on the directive.
488  if (!FirstClause) {
489  Diag(Tok, diag::err_omp_more_one_clause)
490  << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
491  ErrorFound = true;
492  }
493 
494  Clause = ParseOpenMPSimpleClause(CKind);
495  break;
496  case OMPC_schedule:
497  // OpenMP [2.7.1, Restrictions, p. 3]
498  // Only one schedule clause can appear on a loop directive.
499  if (!FirstClause) {
500  Diag(Tok, diag::err_omp_more_one_clause)
501  << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
502  ErrorFound = true;
503  }
504 
505  case OMPC_if:
506  Clause = ParseOpenMPSingleExprWithArgClause(CKind);
507  break;
508  case OMPC_nowait:
509  case OMPC_untied:
510  case OMPC_mergeable:
511  case OMPC_read:
512  case OMPC_write:
513  case OMPC_update:
514  case OMPC_capture:
515  case OMPC_seq_cst:
516  case OMPC_threads:
517  case OMPC_simd:
518  case OMPC_nogroup:
519  // OpenMP [2.7.1, Restrictions, p. 9]
520  // Only one ordered clause can appear on a loop directive.
521  // OpenMP [2.7.1, Restrictions, C/C++, p. 4]
522  // Only one nowait clause can appear on a for directive.
523  if (!FirstClause) {
524  Diag(Tok, diag::err_omp_more_one_clause)
525  << getOpenMPDirectiveName(DKind) << getOpenMPClauseName(CKind) << 0;
526  ErrorFound = true;
527  }
528 
529  Clause = ParseOpenMPClause(CKind);
530  break;
531  case OMPC_private:
532  case OMPC_firstprivate:
533  case OMPC_lastprivate:
534  case OMPC_shared:
535  case OMPC_reduction:
536  case OMPC_linear:
537  case OMPC_aligned:
538  case OMPC_copyin:
539  case OMPC_copyprivate:
540  case OMPC_flush:
541  case OMPC_depend:
542  case OMPC_map:
543  Clause = ParseOpenMPVarListClause(DKind, CKind);
544  break;
545  case OMPC_unknown:
546  Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
547  << getOpenMPDirectiveName(DKind);
548  SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
549  break;
550  case OMPC_threadprivate:
551  Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
552  << getOpenMPDirectiveName(DKind);
553  SkipUntil(tok::comma, tok::annot_pragma_openmp_end, StopBeforeMatch);
554  break;
555  }
556  return ErrorFound ? nullptr : Clause;
557 }
558 
559 /// \brief Parsing of OpenMP clauses with single expressions like 'final',
560 /// 'collapse', 'safelen', 'num_threads', 'simdlen', 'num_teams',
561 /// 'thread_limit', 'simdlen', 'priority', 'grainsize', 'num_tasks' or 'hint'.
562 ///
563 /// final-clause:
564 /// 'final' '(' expression ')'
565 ///
566 /// num_threads-clause:
567 /// 'num_threads' '(' expression ')'
568 ///
569 /// safelen-clause:
570 /// 'safelen' '(' expression ')'
571 ///
572 /// simdlen-clause:
573 /// 'simdlen' '(' expression ')'
574 ///
575 /// collapse-clause:
576 /// 'collapse' '(' expression ')'
577 ///
578 /// priority-clause:
579 /// 'priority' '(' expression ')'
580 ///
581 /// grainsize-clause:
582 /// 'grainsize' '(' expression ')'
583 ///
584 /// num_tasks-clause:
585 /// 'num_tasks' '(' expression ')'
586 ///
587 /// hint-clause:
588 /// 'hint' '(' expression ')'
589 ///
590 OMPClause *Parser::ParseOpenMPSingleExprClause(OpenMPClauseKind Kind) {
592 
593  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
594  if (T.expectAndConsume(diag::err_expected_lparen_after,
595  getOpenMPClauseName(Kind)))
596  return nullptr;
597 
598  SourceLocation ELoc = Tok.getLocation();
599  ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
600  ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional));
601  Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
602 
603  // Parse ')'.
604  T.consumeClose();
605 
606  if (Val.isInvalid())
607  return nullptr;
608 
609  return Actions.ActOnOpenMPSingleExprClause(
610  Kind, Val.get(), Loc, T.getOpenLocation(), T.getCloseLocation());
611 }
612 
613 /// \brief Parsing of simple OpenMP clauses like 'default' or 'proc_bind'.
614 ///
615 /// default-clause:
616 /// 'default' '(' 'none' | 'shared' ')
617 ///
618 /// proc_bind-clause:
619 /// 'proc_bind' '(' 'master' | 'close' | 'spread' ')
620 ///
621 OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) {
622  SourceLocation Loc = Tok.getLocation();
623  SourceLocation LOpen = ConsumeToken();
624  // Parse '('.
625  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
626  if (T.expectAndConsume(diag::err_expected_lparen_after,
627  getOpenMPClauseName(Kind)))
628  return nullptr;
629 
630  unsigned Type = getOpenMPSimpleClauseType(
631  Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
633  if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
634  Tok.isNot(tok::annot_pragma_openmp_end))
635  ConsumeAnyToken();
636 
637  // Parse ')'.
638  T.consumeClose();
639 
640  return Actions.ActOnOpenMPSimpleClause(Kind, Type, TypeLoc, LOpen, Loc,
641  Tok.getLocation());
642 }
643 
644 /// \brief Parsing of OpenMP clauses like 'ordered'.
645 ///
646 /// ordered-clause:
647 /// 'ordered'
648 ///
649 /// nowait-clause:
650 /// 'nowait'
651 ///
652 /// untied-clause:
653 /// 'untied'
654 ///
655 /// mergeable-clause:
656 /// 'mergeable'
657 ///
658 /// read-clause:
659 /// 'read'
660 ///
661 /// threads-clause:
662 /// 'threads'
663 ///
664 /// simd-clause:
665 /// 'simd'
666 ///
667 /// nogroup-clause:
668 /// 'nogroup'
669 ///
670 OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind) {
671  SourceLocation Loc = Tok.getLocation();
672  ConsumeAnyToken();
673 
674  return Actions.ActOnOpenMPClause(Kind, Loc, Tok.getLocation());
675 }
676 
677 
678 /// \brief Parsing of OpenMP clauses with single expressions and some additional
679 /// argument like 'schedule' or 'dist_schedule'.
680 ///
681 /// schedule-clause:
682 /// 'schedule' '(' [ modifier [ ',' modifier ] ':' ] kind [',' expression ]
683 /// ')'
684 ///
685 /// if-clause:
686 /// 'if' '(' [ directive-name-modifier ':' ] expression ')'
687 ///
688 OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind) {
690  SourceLocation DelimLoc;
691  // Parse '('.
692  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
693  if (T.expectAndConsume(diag::err_expected_lparen_after,
694  getOpenMPClauseName(Kind)))
695  return nullptr;
696 
697  ExprResult Val;
700  if (Kind == OMPC_schedule) {
701  enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
702  Arg.resize(NumberOfElements);
703  KLoc.resize(NumberOfElements);
704  Arg[Modifier1] = OMPC_SCHEDULE_MODIFIER_unknown;
705  Arg[Modifier2] = OMPC_SCHEDULE_MODIFIER_unknown;
706  Arg[ScheduleKind] = OMPC_SCHEDULE_unknown;
707  auto KindModifier = getOpenMPSimpleClauseType(
708  Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
709  if (KindModifier > OMPC_SCHEDULE_unknown) {
710  // Parse 'modifier'
711  Arg[Modifier1] = KindModifier;
712  KLoc[Modifier1] = Tok.getLocation();
713  if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
714  Tok.isNot(tok::annot_pragma_openmp_end))
715  ConsumeAnyToken();
716  if (Tok.is(tok::comma)) {
717  // Parse ',' 'modifier'
718  ConsumeAnyToken();
719  KindModifier = getOpenMPSimpleClauseType(
720  Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
721  Arg[Modifier2] = KindModifier > OMPC_SCHEDULE_unknown
722  ? KindModifier
724  KLoc[Modifier2] = Tok.getLocation();
725  if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
726  Tok.isNot(tok::annot_pragma_openmp_end))
727  ConsumeAnyToken();
728  }
729  // Parse ':'
730  if (Tok.is(tok::colon))
731  ConsumeAnyToken();
732  else
733  Diag(Tok, diag::warn_pragma_expected_colon) << "schedule modifier";
734  KindModifier = getOpenMPSimpleClauseType(
735  Kind, Tok.isAnnotation() ? "" : PP.getSpelling(Tok));
736  }
737  Arg[ScheduleKind] = KindModifier;
738  KLoc[ScheduleKind] = Tok.getLocation();
739  if (Tok.isNot(tok::r_paren) && Tok.isNot(tok::comma) &&
740  Tok.isNot(tok::annot_pragma_openmp_end))
741  ConsumeAnyToken();
742  if ((Arg[ScheduleKind] == OMPC_SCHEDULE_static ||
743  Arg[ScheduleKind] == OMPC_SCHEDULE_dynamic ||
744  Arg[ScheduleKind] == OMPC_SCHEDULE_guided) &&
745  Tok.is(tok::comma))
746  DelimLoc = ConsumeAnyToken();
747  } else {
748  assert(Kind == OMPC_if);
749  KLoc.push_back(Tok.getLocation());
750  Arg.push_back(ParseOpenMPDirectiveKind(*this));
751  if (Arg.back() != OMPD_unknown) {
752  ConsumeToken();
753  if (Tok.is(tok::colon))
754  DelimLoc = ConsumeToken();
755  else
756  Diag(Tok, diag::warn_pragma_expected_colon)
757  << "directive name modifier";
758  }
759  }
760 
761  bool NeedAnExpression =
762  (Kind == OMPC_schedule && DelimLoc.isValid()) || Kind == OMPC_if;
763  if (NeedAnExpression) {
764  SourceLocation ELoc = Tok.getLocation();
765  ExprResult LHS(ParseCastExpression(false, false, NotTypeCast));
766  Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional);
767  Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc);
768  }
769 
770  // Parse ')'.
771  T.consumeClose();
772 
773  if (NeedAnExpression && Val.isInvalid())
774  return nullptr;
775 
776  return Actions.ActOnOpenMPSingleExprWithArgClause(
777  Kind, Arg, Val.get(), Loc, T.getOpenLocation(), KLoc, DelimLoc,
778  T.getCloseLocation());
779 }
780 
781 static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec,
782  UnqualifiedId &ReductionId) {
783  SourceLocation TemplateKWLoc;
784  if (ReductionIdScopeSpec.isEmpty()) {
785  auto OOK = OO_None;
786  switch (P.getCurToken().getKind()) {
787  case tok::plus:
788  OOK = OO_Plus;
789  break;
790  case tok::minus:
791  OOK = OO_Minus;
792  break;
793  case tok::star:
794  OOK = OO_Star;
795  break;
796  case tok::amp:
797  OOK = OO_Amp;
798  break;
799  case tok::pipe:
800  OOK = OO_Pipe;
801  break;
802  case tok::caret:
803  OOK = OO_Caret;
804  break;
805  case tok::ampamp:
806  OOK = OO_AmpAmp;
807  break;
808  case tok::pipepipe:
809  OOK = OO_PipePipe;
810  break;
811  default:
812  break;
813  }
814  if (OOK != OO_None) {
815  SourceLocation OpLoc = P.ConsumeToken();
816  SourceLocation SymbolLocations[] = {OpLoc, OpLoc, SourceLocation()};
817  ReductionId.setOperatorFunctionId(OpLoc, OOK, SymbolLocations);
818  return false;
819  }
820  }
821  return P.ParseUnqualifiedId(ReductionIdScopeSpec, /*EnteringContext*/ false,
822  /*AllowDestructorName*/ false,
823  /*AllowConstructorName*/ false, ParsedType(),
824  TemplateKWLoc, ReductionId);
825 }
826 
827 /// \brief Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
828 /// 'shared', 'copyin', 'copyprivate', 'flush' or 'reduction'.
829 ///
830 /// private-clause:
831 /// 'private' '(' list ')'
832 /// firstprivate-clause:
833 /// 'firstprivate' '(' list ')'
834 /// lastprivate-clause:
835 /// 'lastprivate' '(' list ')'
836 /// shared-clause:
837 /// 'shared' '(' list ')'
838 /// linear-clause:
839 /// 'linear' '(' linear-list [ ':' linear-step ] ')'
840 /// aligned-clause:
841 /// 'aligned' '(' list [ ':' alignment ] ')'
842 /// reduction-clause:
843 /// 'reduction' '(' reduction-identifier ':' list ')'
844 /// copyprivate-clause:
845 /// 'copyprivate' '(' list ')'
846 /// flush-clause:
847 /// 'flush' '(' list ')'
848 /// depend-clause:
849 /// 'depend' '(' in | out | inout : list | source ')'
850 /// map-clause:
851 /// 'map' '(' [ [ always , ]
852 /// to | from | tofrom | alloc | release | delete ':' ] list ')';
853 ///
854 /// For 'linear' clause linear-list may have the following forms:
855 /// list
856 /// modifier(list)
857 /// where modifier is 'val' (C) or 'ref', 'val' or 'uval'(C++).
858 OMPClause *Parser::ParseOpenMPVarListClause(OpenMPDirectiveKind DKind,
859  OpenMPClauseKind Kind) {
860  SourceLocation Loc = Tok.getLocation();
861  SourceLocation LOpen = ConsumeToken();
863  // Optional scope specifier and unqualified id for reduction identifier.
864  CXXScopeSpec ReductionIdScopeSpec;
865  UnqualifiedId ReductionId;
866  bool InvalidReductionId = false;
868  // OpenMP 4.1 [2.15.3.7, linear Clause]
869  // If no modifier is specified it is assumed to be val.
870  OpenMPLinearClauseKind LinearModifier = OMPC_LINEAR_val;
872  OpenMPMapClauseKind MapTypeModifier = OMPC_MAP_unknown;
873  bool MapTypeModifierSpecified = false;
874  bool UnexpectedId = false;
875  SourceLocation DepLinMapLoc;
876 
877  // Parse '('.
878  BalancedDelimiterTracker T(*this, tok::l_paren, tok::annot_pragma_openmp_end);
879  if (T.expectAndConsume(diag::err_expected_lparen_after,
880  getOpenMPClauseName(Kind)))
881  return nullptr;
882 
883  bool NeedRParenForLinear = false;
884  BalancedDelimiterTracker LinearT(*this, tok::l_paren,
885  tok::annot_pragma_openmp_end);
886  // Handle reduction-identifier for reduction clause.
887  if (Kind == OMPC_reduction) {
888  ColonProtectionRAIIObject ColonRAII(*this);
889  if (getLangOpts().CPlusPlus) {
890  ParseOptionalCXXScopeSpecifier(ReductionIdScopeSpec, ParsedType(), false);
891  }
892  InvalidReductionId =
893  ParseReductionId(*this, ReductionIdScopeSpec, ReductionId);
894  if (InvalidReductionId) {
895  SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
897  }
898  if (Tok.is(tok::colon)) {
899  ColonLoc = ConsumeToken();
900  } else {
901  Diag(Tok, diag::warn_pragma_expected_colon) << "reduction identifier";
902  }
903  } else if (Kind == OMPC_depend) {
904  // Handle dependency type for depend clause.
905  ColonProtectionRAIIObject ColonRAII(*this);
906  DepKind = static_cast<OpenMPDependClauseKind>(getOpenMPSimpleClauseType(
907  Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
908  DepLinMapLoc = Tok.getLocation();
909 
910  if (DepKind == OMPC_DEPEND_unknown) {
911  SkipUntil(tok::colon, tok::r_paren, tok::annot_pragma_openmp_end,
913  } else {
914  ConsumeToken();
915  // Special processing for depend(source) clause.
916  if (DKind == OMPD_ordered && DepKind == OMPC_DEPEND_source) {
917  // Parse ')'.
918  T.consumeClose();
919  return Actions.ActOnOpenMPVarListClause(
920  Kind, llvm::None, /*TailExpr=*/nullptr, Loc, LOpen,
921  /*ColonLoc=*/SourceLocation(), Tok.getLocation(),
922  ReductionIdScopeSpec, DeclarationNameInfo(), DepKind,
923  LinearModifier, MapTypeModifier, MapType, DepLinMapLoc);
924  }
925  }
926  if (Tok.is(tok::colon)) {
927  ColonLoc = ConsumeToken();
928  } else {
929  Diag(Tok, DKind == OMPD_ordered ? diag::warn_pragma_expected_colon_r_paren
930  : diag::warn_pragma_expected_colon)
931  << "dependency type";
932  }
933  } else if (Kind == OMPC_linear) {
934  // Try to parse modifier if any.
935  if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) {
936  LinearModifier = static_cast<OpenMPLinearClauseKind>(
937  getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok)));
938  DepLinMapLoc = ConsumeToken();
939  LinearT.consumeOpen();
940  NeedRParenForLinear = true;
941  }
942  } else if (Kind == OMPC_map) {
943  // Handle map type for map clause.
944  ColonProtectionRAIIObject ColonRAII(*this);
945 
946  // the first identifier may be a list item, a map-type or
947  // a map-type-modifier
948  MapType = static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType(
949  Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
950  DepLinMapLoc = Tok.getLocation();
951  bool ColonExpected = false;
952 
953  if (Tok.is(tok::identifier)) {
954  if (PP.LookAhead(0).is(tok::colon)) {
955  MapType = static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType(
956  Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
957  if (MapType == OMPC_MAP_unknown) {
958  Diag(Tok, diag::err_omp_unknown_map_type);
959  } else if (MapType == OMPC_MAP_always) {
960  Diag(Tok, diag::err_omp_map_type_missing);
961  }
962  ConsumeToken();
963  } else if (PP.LookAhead(0).is(tok::comma)) {
964  if (PP.LookAhead(1).is(tok::identifier) &&
965  PP.LookAhead(2).is(tok::colon)) {
966  MapTypeModifier =
968  Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
969  if (MapTypeModifier != OMPC_MAP_always) {
970  Diag(Tok, diag::err_omp_unknown_map_type_modifier);
971  MapTypeModifier = OMPC_MAP_unknown;
972  } else {
973  MapTypeModifierSpecified = true;
974  }
975 
976  ConsumeToken();
977  ConsumeToken();
978 
979  MapType = static_cast<OpenMPMapClauseKind>(getOpenMPSimpleClauseType(
980  Kind, Tok.is(tok::identifier) ? PP.getSpelling(Tok) : ""));
981  if (MapType == OMPC_MAP_unknown || MapType == OMPC_MAP_always) {
982  Diag(Tok, diag::err_omp_unknown_map_type);
983  }
984  ConsumeToken();
985  } else {
986  MapType = OMPC_MAP_tofrom;
987  }
988  } else {
989  MapType = OMPC_MAP_tofrom;
990  }
991  } else {
992  UnexpectedId = true;
993  }
994 
995  if (Tok.is(tok::colon)) {
996  ColonLoc = ConsumeToken();
997  } else if (ColonExpected) {
998  Diag(Tok, diag::warn_pragma_expected_colon) << "map type";
999  }
1000  }
1001 
1003  bool IsComma =
1004  ((Kind != OMPC_reduction) && (Kind != OMPC_depend) &&
1005  (Kind != OMPC_map)) ||
1006  ((Kind == OMPC_reduction) && !InvalidReductionId) ||
1007  ((Kind == OMPC_map) && (UnexpectedId || MapType != OMPC_MAP_unknown) &&
1008  (!MapTypeModifierSpecified ||
1009  (MapTypeModifierSpecified && MapTypeModifier == OMPC_MAP_always))) ||
1010  ((Kind == OMPC_depend) && DepKind != OMPC_DEPEND_unknown);
1011  const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
1012  while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
1013  Tok.isNot(tok::annot_pragma_openmp_end))) {
1014  ColonProtectionRAIIObject ColonRAII(*this, MayHaveTail);
1015  // Parse variable
1016  ExprResult VarExpr =
1018  if (VarExpr.isUsable()) {
1019  Vars.push_back(VarExpr.get());
1020  } else {
1021  SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1022  StopBeforeMatch);
1023  }
1024  // Skip ',' if any
1025  IsComma = Tok.is(tok::comma);
1026  if (IsComma)
1027  ConsumeToken();
1028  else if (Tok.isNot(tok::r_paren) &&
1029  Tok.isNot(tok::annot_pragma_openmp_end) &&
1030  (!MayHaveTail || Tok.isNot(tok::colon)))
1031  Diag(Tok, diag::err_omp_expected_punc)
1032  << ((Kind == OMPC_flush) ? getOpenMPDirectiveName(OMPD_flush)
1033  : getOpenMPClauseName(Kind))
1034  << (Kind == OMPC_flush);
1035  }
1036 
1037  // Parse ')' for linear clause with modifier.
1038  if (NeedRParenForLinear)
1039  LinearT.consumeClose();
1040 
1041  // Parse ':' linear-step (or ':' alignment).
1042  Expr *TailExpr = nullptr;
1043  const bool MustHaveTail = MayHaveTail && Tok.is(tok::colon);
1044  if (MustHaveTail) {
1045  ColonLoc = Tok.getLocation();
1046  SourceLocation ELoc = ConsumeToken();
1048  Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc);
1049  if (Tail.isUsable())
1050  TailExpr = Tail.get();
1051  else
1052  SkipUntil(tok::comma, tok::r_paren, tok::annot_pragma_openmp_end,
1053  StopBeforeMatch);
1054  }
1055 
1056  // Parse ')'.
1057  T.consumeClose();
1058  if ((Kind == OMPC_depend && DepKind != OMPC_DEPEND_unknown && Vars.empty()) ||
1059  (Kind != OMPC_depend && Vars.empty()) || (MustHaveTail && !TailExpr) ||
1060  (Kind == OMPC_map && MapType == OMPC_MAP_unknown) ||
1061  InvalidReductionId) {
1062  return nullptr;
1063  }
1064 
1065  return Actions.ActOnOpenMPVarListClause(
1066  Kind, Vars, TailExpr, Loc, LOpen, ColonLoc, Tok.getLocation(),
1067  ReductionIdScopeSpec,
1068  ReductionId.isValid() ? Actions.GetNameFromUnqualifiedId(ReductionId)
1069  : DeclarationNameInfo(),
1070  DepKind, LinearModifier, MapTypeModifier, MapType, DepLinMapLoc);
1071 }
1072 
Defines the clang::ASTContext interface.
ExprResult ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id)
Called on correct id-expression from the '#pragma omp threadprivate'.
Scope * getCurScope() const
Retrieve the parser's current scope.
Definition: Sema.h:9197
bool isInvalid() const
Definition: Ownership.h:159
const Token & getCurToken() const
Definition: Parse/Parser.h:250
void EndOpenMPDSABlock(Stmt *CurDirective)
Called on end of data sharing attribute block.
Definition: SemaOpenMP.cpp:939
const LangOptions & getLangOpts() const
Definition: Parse/Parser.h:244
const Token & LookAhead(unsigned N)
Peeks ahead N tokens and returns that token without consuming any tokens.
OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr * > Vars, Expr *TailExpr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType, SourceLocation DepLinMapLoc)
PtrTy get() const
Definition: Ownership.h:163
The base class of the type hierarchy.
Definition: Type.h:1249
This indicates that the scope corresponds to a function, which means that labels are set here...
Definition: Scope.h:45
bool isAllowedClauseForDirective(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind)
static OpenMPDirectiveKind ParseOpenMPDirectiveKind(Parser &P)
Definition: ParseOpenMP.cpp:29
static bool ParseReductionId(Parser &P, CXXScopeSpec &ReductionIdScopeSpec, UnqualifiedId &ReductionId)
Wrapper for void* pointer.
Definition: Ownership.h:45
Parser - This implements a parser for the C family of languages.
Definition: Parse/Parser.h:56
void EnterToken(const Token &Tok)
Enters a token in the token stream to be lexed next.
bool isAnyIdentifier() const
Return true if this is a raw identifier (when lexing in raw mode) or a non-keyword identifier (when l...
Definition: Token.h:107
RAII object that makes sure paren/bracket/brace count is correct after declaration/statement parsing...
ColonProtectionRAIIObject - This sets the Parser::ColonIsSacred bool and restores it when destroyed...
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
bool isEmpty() const
No scope specifier.
Definition: DeclSpec.h:189
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: Parse/Parser.h:866
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:40
const char * getOpenMPClauseName(OpenMPClauseKind Kind)
Definition: OpenMPKinds.cpp:61
DeclarationNameInfo GetNameFromUnqualifiedId(const UnqualifiedId &Name)
Retrieves the declaration name from a parsed unqualified-id.
Definition: SemaDecl.cpp:4432
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
Definition: Ownership.h:233
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
Definition: Type.h:4381
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
Definition: OpenMPKinds.h:83
void StartOpenMPDSABlock(OpenMPDirectiveKind K, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc)
Called on start of new data sharing attribute block.
Definition: SemaOpenMP.cpp:924
Token - This structure provides full information about a lexed token.
Definition: Token.h:37
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ...
void EndOpenMPClause()
End analysis of clauses.
Definition: SemaOpenMP.cpp:935
VerifyDiagnosticConsumer::Directive Directive
A location where the result (returned value) of evaluating a statement should be stored.
Represents a C++ unqualified-id that has been parsed.
Definition: DeclSpec.h:874
StmtResult StmtError()
Definition: Ownership.h:268
OpenMPClauseKind getOpenMPClauseKind(llvm::StringRef Str)
OMPClause * ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc)
Represents a C++ nested-name-specifier or a global scope specifier.
Definition: DeclSpec.h:63
tok::TokenKind getKind() const
Definition: Token.h:90
AnnotatingParser & P
StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc)
Definition: SemaStmt.cpp:71
A RAII object to enter scope of a compound statement.
Definition: Sema.h:3274
void ActOnFinishOfCompoundStmt()
Definition: SemaStmt.cpp:323
Expr - This represents one expression.
Definition: Expr.h:104
void StartOpenMPClause(OpenMPClauseKind K)
Start analysis of clauses.
Definition: SemaOpenMP.cpp:931
This is the scope of OpenMP executable directive.
Definition: Scope.h:105
OpenMPClauseKind
OpenMP clauses.
Definition: OpenMPKinds.h:33
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
Definition: Token.h:124
bool isNot(tok::TokenKind K) const
Definition: Token.h:96
OMPClause * ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, ArrayRef< unsigned > Arguments, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, ArrayRef< SourceLocation > ArgumentsLoc, SourceLocation DelimLoc, SourceLocation EndLoc)
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
Definition: Parse/Parser.h:260
ExprResult ActOnFinishFullExpr(Expr *Expr)
Definition: Sema.h:4784
bool isValid() const
Determine whether this unqualified-id refers to a valid name.
Definition: DeclSpec.h:965
void ActOnStartOfCompoundStmt()
Definition: SemaStmt.cpp:319
Kind
Encodes a location in the source.
OpenMPDependClauseKind
OpenMP attributes for 'depend' clause.
Definition: OpenMPKinds.h:75
StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
bool isValid() const
Return true if this is a valid SourceLocation object.
OpenMPDirectiveKind
OpenMP directives.
Definition: OpenMPKinds.h:23
Scope * getCurScope() const
Definition: Parse/Parser.h:251
This is a basic class for representing single OpenMP clause.
Definition: OpenMPClause.h:32
Preprocessor & getPreprocessor() const
Definition: Parse/Parser.h:246
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 ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, ParsedType ObjectType, SourceLocation &TemplateKWLoc, UnqualifiedId &Result)
Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.
This is the scope of some OpenMP simd directive.
Definition: Scope.h:113
OMPClause * ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope)
Initialization of captured region for OpenMP region.
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
Not an overloaded operator.
Definition: OperatorKinds.h:23
unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str)
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
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:1228
ExprResult ParseAssignmentExpression(TypeCastState isTypeCast=NotTypeCast)
Parse an expr that doesn't include (top-level) commas.
Definition: ParseExpr.cpp:157
DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(SourceLocation Loc, ArrayRef< Expr * > VarList)
Called on well-formed '#pragma omp threadprivate'.
OpenMPDirectiveKind getOpenMPDirectiveKind(llvm::StringRef Str)
const char * getOpenMPDirectiveName(OpenMPDirectiveKind Kind)
Definition: OpenMPKinds.cpp:31
bool isUsable() const
Definition: Ownership.h:160
This is a scope that can contain a declaration.
Definition: Scope.h:57
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Definition: Parse/Parser.h:285
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
Definition: OpenMPKinds.h:91
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult{return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
This is the scope of some OpenMP loop directive.
Definition: Scope.h:108
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.
Directive - Abstract class representing a parsed verify directive.
StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef< OMPClause * > Clauses)
End of OpenMP region.
SourceLocation ColonLoc
Location of ':'.
Definition: OpenMPClause.h:266
bool isAnnotation() const
Return true if this is any of tok::annot_* kind tokens.
Definition: Token.h:118
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Stop skipping at specified token, but don't skip the token itself.
Definition: Parse/Parser.h:848
IdentifierInfo * getIdentifierInfo() const
Definition: Token.h:177