clang  10.0.0git
OpenMPClause.cpp
Go to the documentation of this file.
1 //===- OpenMPClause.cpp - Classes for OpenMP clauses ----------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the subclesses of Stmt class declared in OpenMPClause.h
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "clang/AST/OpenMPClause.h"
14 #include "clang/AST/ASTContext.h"
15 #include "clang/AST/Decl.h"
16 #include "clang/AST/DeclOpenMP.h"
17 #include "clang/Basic/LLVM.h"
19 #include "llvm/ADT/SmallPtrSet.h"
20 #include "llvm/Support/Casting.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include <algorithm>
23 #include <cassert>
24 
25 using namespace clang;
26 
28  switch (getClauseKind()) {
29  default:
30  break;
31 #define OPENMP_CLAUSE(Name, Class) \
32  case OMPC_##Name: \
33  return static_cast<Class *>(this)->children();
34 #include "clang/Basic/OpenMPKinds.def"
35  }
36  llvm_unreachable("unknown OMPClause");
37 }
38 
40  switch (getClauseKind()) {
41 #define OPENMP_CLAUSE(Name, Class) \
42  case OMPC_##Name: \
43  return static_cast<Class *>(this)->used_children();
44 #include "clang/Basic/OpenMPKinds.def"
45  case OMPC_threadprivate:
46  case OMPC_uniform:
47  case OMPC_device_type:
48  case OMPC_match:
49  case OMPC_unknown:
50  break;
51  }
52  llvm_unreachable("unknown OMPClause");
53 }
54 
56  auto *Res = OMPClauseWithPreInit::get(const_cast<const OMPClause *>(C));
57  return Res ? const_cast<OMPClauseWithPreInit *>(Res) : nullptr;
58 }
59 
61  switch (C->getClauseKind()) {
62  case OMPC_schedule:
63  return static_cast<const OMPScheduleClause *>(C);
64  case OMPC_dist_schedule:
65  return static_cast<const OMPDistScheduleClause *>(C);
66  case OMPC_firstprivate:
67  return static_cast<const OMPFirstprivateClause *>(C);
68  case OMPC_lastprivate:
69  return static_cast<const OMPLastprivateClause *>(C);
70  case OMPC_reduction:
71  return static_cast<const OMPReductionClause *>(C);
72  case OMPC_task_reduction:
73  return static_cast<const OMPTaskReductionClause *>(C);
74  case OMPC_in_reduction:
75  return static_cast<const OMPInReductionClause *>(C);
76  case OMPC_linear:
77  return static_cast<const OMPLinearClause *>(C);
78  case OMPC_if:
79  return static_cast<const OMPIfClause *>(C);
80  case OMPC_num_threads:
81  return static_cast<const OMPNumThreadsClause *>(C);
82  case OMPC_num_teams:
83  return static_cast<const OMPNumTeamsClause *>(C);
84  case OMPC_thread_limit:
85  return static_cast<const OMPThreadLimitClause *>(C);
86  case OMPC_device:
87  return static_cast<const OMPDeviceClause *>(C);
88  case OMPC_grainsize:
89  return static_cast<const OMPGrainsizeClause *>(C);
90  case OMPC_num_tasks:
91  return static_cast<const OMPNumTasksClause *>(C);
92  case OMPC_final:
93  return static_cast<const OMPFinalClause *>(C);
94  case OMPC_priority:
95  return static_cast<const OMPPriorityClause *>(C);
96  case OMPC_default:
97  case OMPC_proc_bind:
98  case OMPC_safelen:
99  case OMPC_simdlen:
100  case OMPC_allocator:
101  case OMPC_allocate:
102  case OMPC_collapse:
103  case OMPC_private:
104  case OMPC_shared:
105  case OMPC_aligned:
106  case OMPC_copyin:
107  case OMPC_copyprivate:
108  case OMPC_ordered:
109  case OMPC_nowait:
110  case OMPC_untied:
111  case OMPC_mergeable:
112  case OMPC_threadprivate:
113  case OMPC_flush:
114  case OMPC_read:
115  case OMPC_write:
116  case OMPC_update:
117  case OMPC_capture:
118  case OMPC_seq_cst:
119  case OMPC_depend:
120  case OMPC_threads:
121  case OMPC_simd:
122  case OMPC_map:
123  case OMPC_nogroup:
124  case OMPC_hint:
125  case OMPC_defaultmap:
126  case OMPC_unknown:
127  case OMPC_uniform:
128  case OMPC_to:
129  case OMPC_from:
130  case OMPC_use_device_ptr:
131  case OMPC_is_device_ptr:
132  case OMPC_unified_address:
133  case OMPC_unified_shared_memory:
134  case OMPC_reverse_offload:
135  case OMPC_dynamic_allocators:
136  case OMPC_atomic_default_mem_order:
137  case OMPC_device_type:
138  case OMPC_match:
139  case OMPC_nontemporal:
140  break;
141  }
142 
143  return nullptr;
144 }
145 
147  auto *Res = OMPClauseWithPostUpdate::get(const_cast<const OMPClause *>(C));
148  return Res ? const_cast<OMPClauseWithPostUpdate *>(Res) : nullptr;
149 }
150 
152  switch (C->getClauseKind()) {
153  case OMPC_lastprivate:
154  return static_cast<const OMPLastprivateClause *>(C);
155  case OMPC_reduction:
156  return static_cast<const OMPReductionClause *>(C);
157  case OMPC_task_reduction:
158  return static_cast<const OMPTaskReductionClause *>(C);
159  case OMPC_in_reduction:
160  return static_cast<const OMPInReductionClause *>(C);
161  case OMPC_linear:
162  return static_cast<const OMPLinearClause *>(C);
163  case OMPC_schedule:
164  case OMPC_dist_schedule:
165  case OMPC_firstprivate:
166  case OMPC_default:
167  case OMPC_proc_bind:
168  case OMPC_if:
169  case OMPC_final:
170  case OMPC_num_threads:
171  case OMPC_safelen:
172  case OMPC_simdlen:
173  case OMPC_allocator:
174  case OMPC_allocate:
175  case OMPC_collapse:
176  case OMPC_private:
177  case OMPC_shared:
178  case OMPC_aligned:
179  case OMPC_copyin:
180  case OMPC_copyprivate:
181  case OMPC_ordered:
182  case OMPC_nowait:
183  case OMPC_untied:
184  case OMPC_mergeable:
185  case OMPC_threadprivate:
186  case OMPC_flush:
187  case OMPC_read:
188  case OMPC_write:
189  case OMPC_update:
190  case OMPC_capture:
191  case OMPC_seq_cst:
192  case OMPC_depend:
193  case OMPC_device:
194  case OMPC_threads:
195  case OMPC_simd:
196  case OMPC_map:
197  case OMPC_num_teams:
198  case OMPC_thread_limit:
199  case OMPC_priority:
200  case OMPC_grainsize:
201  case OMPC_nogroup:
202  case OMPC_num_tasks:
203  case OMPC_hint:
204  case OMPC_defaultmap:
205  case OMPC_unknown:
206  case OMPC_uniform:
207  case OMPC_to:
208  case OMPC_from:
209  case OMPC_use_device_ptr:
210  case OMPC_is_device_ptr:
211  case OMPC_unified_address:
212  case OMPC_unified_shared_memory:
213  case OMPC_reverse_offload:
214  case OMPC_dynamic_allocators:
215  case OMPC_atomic_default_mem_order:
216  case OMPC_device_type:
217  case OMPC_match:
218  case OMPC_nontemporal:
219  break;
220  }
221 
222  return nullptr;
223 }
224 
225 /// Gets the address of the original, non-captured, expression used in the
226 /// clause as the preinitializer.
228  if (!S)
229  return nullptr;
230  if (auto *DS = dyn_cast<DeclStmt>(S)) {
231  assert(DS->isSingleDecl() && "Only single expression must be captured.");
232  if (auto *OED = dyn_cast<OMPCapturedExprDecl>(DS->getSingleDecl()))
233  return OED->getInitAddress();
234  }
235  return nullptr;
236 }
237 
239  if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
240  return child_range(C, C + 1);
241  return child_range(&Condition, &Condition + 1);
242 }
243 
245  if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
246  return child_range(C, C + 1);
247  return child_range(&Grainsize, &Grainsize + 1);
248 }
249 
251  if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
252  return child_range(C, C + 1);
253  return child_range(&NumTasks, &NumTasks + 1);
254 }
255 
257  if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
258  return child_range(C, C + 1);
259  return child_range(&Condition, &Condition + 1);
260 }
261 
263  if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
264  return child_range(C, C + 1);
265  return child_range(&Priority, &Priority + 1);
266 }
267 
269  unsigned NumLoops,
270  SourceLocation StartLoc,
271  SourceLocation LParenLoc,
272  SourceLocation EndLoc) {
273  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * NumLoops));
274  auto *Clause =
275  new (Mem) OMPOrderedClause(Num, NumLoops, StartLoc, LParenLoc, EndLoc);
276  for (unsigned I = 0; I < NumLoops; ++I) {
277  Clause->setLoopNumIterations(I, nullptr);
278  Clause->setLoopCounter(I, nullptr);
279  }
280  return Clause;
281 }
282 
284  unsigned NumLoops) {
285  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * NumLoops));
286  auto *Clause = new (Mem) OMPOrderedClause(NumLoops);
287  for (unsigned I = 0; I < NumLoops; ++I) {
288  Clause->setLoopNumIterations(I, nullptr);
289  Clause->setLoopCounter(I, nullptr);
290  }
291  return Clause;
292 }
293 
295  Expr *NumIterations) {
296  assert(NumLoop < NumberOfLoops && "out of loops number.");
297  getTrailingObjects<Expr *>()[NumLoop] = NumIterations;
298 }
299 
301  return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumberOfLoops);
302 }
303 
304 void OMPOrderedClause::setLoopCounter(unsigned NumLoop, Expr *Counter) {
305  assert(NumLoop < NumberOfLoops && "out of loops number.");
306  getTrailingObjects<Expr *>()[NumberOfLoops + NumLoop] = Counter;
307 }
308 
310  assert(NumLoop < NumberOfLoops && "out of loops number.");
311  return getTrailingObjects<Expr *>()[NumberOfLoops + NumLoop];
312 }
313 
314 const Expr *OMPOrderedClause::getLoopCounter(unsigned NumLoop) const {
315  assert(NumLoop < NumberOfLoops && "out of loops number.");
316  return getTrailingObjects<Expr *>()[NumberOfLoops + NumLoop];
317 }
318 
319 void OMPPrivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {
320  assert(VL.size() == varlist_size() &&
321  "Number of private copies is not the same as the preallocated buffer");
322  std::copy(VL.begin(), VL.end(), varlist_end());
323 }
324 
327  SourceLocation LParenLoc, SourceLocation EndLoc,
328  ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL) {
329  // Allocate space for private variables and initializer expressions.
330  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * VL.size()));
331  OMPPrivateClause *Clause =
332  new (Mem) OMPPrivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
333  Clause->setVarRefs(VL);
334  Clause->setPrivateCopies(PrivateVL);
335  return Clause;
336 }
337 
339  unsigned N) {
340  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * N));
341  return new (Mem) OMPPrivateClause(N);
342 }
343 
344 void OMPFirstprivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {
345  assert(VL.size() == varlist_size() &&
346  "Number of private copies is not the same as the preallocated buffer");
347  std::copy(VL.begin(), VL.end(), varlist_end());
348 }
349 
350 void OMPFirstprivateClause::setInits(ArrayRef<Expr *> VL) {
351  assert(VL.size() == varlist_size() &&
352  "Number of inits is not the same as the preallocated buffer");
353  std::copy(VL.begin(), VL.end(), getPrivateCopies().end());
354 }
355 
358  SourceLocation LParenLoc, SourceLocation EndLoc,
359  ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL,
360  ArrayRef<Expr *> InitVL, Stmt *PreInit) {
361  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(3 * VL.size()));
362  OMPFirstprivateClause *Clause =
363  new (Mem) OMPFirstprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
364  Clause->setVarRefs(VL);
365  Clause->setPrivateCopies(PrivateVL);
366  Clause->setInits(InitVL);
367  Clause->setPreInitStmt(PreInit);
368  return Clause;
369 }
370 
372  unsigned N) {
373  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(3 * N));
374  return new (Mem) OMPFirstprivateClause(N);
375 }
376 
378  assert(PrivateCopies.size() == varlist_size() &&
379  "Number of private copies is not the same as the preallocated buffer");
380  std::copy(PrivateCopies.begin(), PrivateCopies.end(), varlist_end());
381 }
382 
383 void OMPLastprivateClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
384  assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
385  "not the same as the "
386  "preallocated buffer");
387  std::copy(SrcExprs.begin(), SrcExprs.end(), getPrivateCopies().end());
388 }
389 
390 void OMPLastprivateClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
391  assert(DstExprs.size() == varlist_size() && "Number of destination "
392  "expressions is not the same as "
393  "the preallocated buffer");
394  std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
395 }
396 
397 void OMPLastprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
398  assert(AssignmentOps.size() == varlist_size() &&
399  "Number of assignment expressions is not the same as the preallocated "
400  "buffer");
401  std::copy(AssignmentOps.begin(), AssignmentOps.end(),
402  getDestinationExprs().end());
403 }
404 
406  const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
407  SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
408  ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps,
409  OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc,
410  SourceLocation ColonLoc, Stmt *PreInit, Expr *PostUpdate) {
411  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size()));
412  OMPLastprivateClause *Clause = new (Mem) OMPLastprivateClause(
413  StartLoc, LParenLoc, EndLoc, LPKind, LPKindLoc, ColonLoc, VL.size());
414  Clause->setVarRefs(VL);
415  Clause->setSourceExprs(SrcExprs);
416  Clause->setDestinationExprs(DstExprs);
417  Clause->setAssignmentOps(AssignmentOps);
418  Clause->setPreInitStmt(PreInit);
419  Clause->setPostUpdateExpr(PostUpdate);
420  return Clause;
421 }
422 
424  unsigned N) {
425  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * N));
426  return new (Mem) OMPLastprivateClause(N);
427 }
428 
430  SourceLocation StartLoc,
431  SourceLocation LParenLoc,
432  SourceLocation EndLoc,
433  ArrayRef<Expr *> VL) {
434  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
435  OMPSharedClause *Clause =
436  new (Mem) OMPSharedClause(StartLoc, LParenLoc, EndLoc, VL.size());
437  Clause->setVarRefs(VL);
438  return Clause;
439 }
440 
442  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
443  return new (Mem) OMPSharedClause(N);
444 }
445 
447  assert(PL.size() == varlist_size() &&
448  "Number of privates is not the same as the preallocated buffer");
449  std::copy(PL.begin(), PL.end(), varlist_end());
450 }
451 
453  assert(IL.size() == varlist_size() &&
454  "Number of inits is not the same as the preallocated buffer");
455  std::copy(IL.begin(), IL.end(), getPrivates().end());
456 }
457 
459  assert(UL.size() == varlist_size() &&
460  "Number of updates is not the same as the preallocated buffer");
461  std::copy(UL.begin(), UL.end(), getInits().end());
462 }
463 
465  assert(FL.size() == varlist_size() &&
466  "Number of final updates is not the same as the preallocated buffer");
467  std::copy(FL.begin(), FL.end(), getUpdates().end());
468 }
469 
471  assert(
472  UE.size() == varlist_size() + 1 &&
473  "Number of used expressions is not the same as the preallocated buffer");
474  std::copy(UE.begin(), UE.end(), getFinals().end() + 2);
475 }
476 
478  const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
482  Stmt *PreInit, Expr *PostUpdate) {
483  // Allocate space for 5 lists (Vars, Inits, Updates, Finals), 2 expressions
484  // (Step and CalcStep), list of used expression + step.
485  void *Mem =
486  C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size() + 2 + VL.size() + 1));
487  OMPLinearClause *Clause = new (Mem) OMPLinearClause(
488  StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc, EndLoc, VL.size());
489  Clause->setVarRefs(VL);
490  Clause->setPrivates(PL);
491  Clause->setInits(IL);
492  // Fill update and final expressions with zeroes, they are provided later,
493  // after the directive construction.
494  std::fill(Clause->getInits().end(), Clause->getInits().end() + VL.size(),
495  nullptr);
496  std::fill(Clause->getUpdates().end(), Clause->getUpdates().end() + VL.size(),
497  nullptr);
498  std::fill(Clause->getUsedExprs().begin(), Clause->getUsedExprs().end(),
499  nullptr);
500  Clause->setStep(Step);
501  Clause->setCalcStep(CalcStep);
502  Clause->setPreInitStmt(PreInit);
503  Clause->setPostUpdateExpr(PostUpdate);
504  return Clause;
505 }
506 
508  unsigned NumVars) {
509  // Allocate space for 5 lists (Vars, Inits, Updates, Finals), 2 expressions
510  // (Step and CalcStep), list of used expression + step.
511  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * NumVars + 2 + NumVars +1));
512  return new (Mem) OMPLinearClause(NumVars);
513 }
514 
516  // Range includes only non-nullptr elements.
517  return child_range(
518  reinterpret_cast<Stmt **>(getUsedExprs().begin()),
519  reinterpret_cast<Stmt **>(llvm::find(getUsedExprs(), nullptr)));
520 }
521 
524  SourceLocation LParenLoc, SourceLocation ColonLoc,
525  SourceLocation EndLoc, ArrayRef<Expr *> VL, Expr *A) {
526  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + 1));
527  OMPAlignedClause *Clause = new (Mem)
528  OMPAlignedClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size());
529  Clause->setVarRefs(VL);
530  Clause->setAlignment(A);
531  return Clause;
532 }
533 
535  unsigned NumVars) {
536  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumVars + 1));
537  return new (Mem) OMPAlignedClause(NumVars);
538 }
539 
540 void OMPCopyinClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
541  assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
542  "not the same as the "
543  "preallocated buffer");
544  std::copy(SrcExprs.begin(), SrcExprs.end(), varlist_end());
545 }
546 
547 void OMPCopyinClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
548  assert(DstExprs.size() == varlist_size() && "Number of destination "
549  "expressions is not the same as "
550  "the preallocated buffer");
551  std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
552 }
553 
554 void OMPCopyinClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
555  assert(AssignmentOps.size() == varlist_size() &&
556  "Number of assignment expressions is not the same as the preallocated "
557  "buffer");
558  std::copy(AssignmentOps.begin(), AssignmentOps.end(),
559  getDestinationExprs().end());
560 }
561 
563  const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
564  SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
565  ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
566  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * VL.size()));
567  OMPCopyinClause *Clause =
568  new (Mem) OMPCopyinClause(StartLoc, LParenLoc, EndLoc, VL.size());
569  Clause->setVarRefs(VL);
570  Clause->setSourceExprs(SrcExprs);
571  Clause->setDestinationExprs(DstExprs);
572  Clause->setAssignmentOps(AssignmentOps);
573  return Clause;
574 }
575 
577  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * N));
578  return new (Mem) OMPCopyinClause(N);
579 }
580 
581 void OMPCopyprivateClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
582  assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
583  "not the same as the "
584  "preallocated buffer");
585  std::copy(SrcExprs.begin(), SrcExprs.end(), varlist_end());
586 }
587 
588 void OMPCopyprivateClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
589  assert(DstExprs.size() == varlist_size() && "Number of destination "
590  "expressions is not the same as "
591  "the preallocated buffer");
592  std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
593 }
594 
595 void OMPCopyprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
596  assert(AssignmentOps.size() == varlist_size() &&
597  "Number of assignment expressions is not the same as the preallocated "
598  "buffer");
599  std::copy(AssignmentOps.begin(), AssignmentOps.end(),
600  getDestinationExprs().end());
601 }
602 
604  const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
605  SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
606  ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
607  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * VL.size()));
608  OMPCopyprivateClause *Clause =
609  new (Mem) OMPCopyprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
610  Clause->setVarRefs(VL);
611  Clause->setSourceExprs(SrcExprs);
612  Clause->setDestinationExprs(DstExprs);
613  Clause->setAssignmentOps(AssignmentOps);
614  return Clause;
615 }
616 
618  unsigned N) {
619  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * N));
620  return new (Mem) OMPCopyprivateClause(N);
621 }
622 
623 void OMPReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
624  assert(Privates.size() == varlist_size() &&
625  "Number of private copies is not the same as the preallocated buffer");
626  std::copy(Privates.begin(), Privates.end(), varlist_end());
627 }
628 
629 void OMPReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
630  assert(
631  LHSExprs.size() == varlist_size() &&
632  "Number of LHS expressions is not the same as the preallocated buffer");
633  std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end());
634 }
635 
636 void OMPReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
637  assert(
638  RHSExprs.size() == varlist_size() &&
639  "Number of RHS expressions is not the same as the preallocated buffer");
640  std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
641 }
642 
643 void OMPReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
644  assert(ReductionOps.size() == varlist_size() && "Number of reduction "
645  "expressions is not the same "
646  "as the preallocated buffer");
647  std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
648 }
649 
651  const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
652  SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
653  NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
655  ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps, Stmt *PreInit,
656  Expr *PostUpdate) {
657  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size()));
658  OMPReductionClause *Clause = new (Mem) OMPReductionClause(
659  StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
660  Clause->setVarRefs(VL);
661  Clause->setPrivates(Privates);
662  Clause->setLHSExprs(LHSExprs);
663  Clause->setRHSExprs(RHSExprs);
664  Clause->setReductionOps(ReductionOps);
665  Clause->setPreInitStmt(PreInit);
666  Clause->setPostUpdateExpr(PostUpdate);
667  return Clause;
668 }
669 
671  unsigned N) {
672  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * N));
673  return new (Mem) OMPReductionClause(N);
674 }
675 
676 void OMPTaskReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
677  assert(Privates.size() == varlist_size() &&
678  "Number of private copies is not the same as the preallocated buffer");
679  std::copy(Privates.begin(), Privates.end(), varlist_end());
680 }
681 
682 void OMPTaskReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
683  assert(
684  LHSExprs.size() == varlist_size() &&
685  "Number of LHS expressions is not the same as the preallocated buffer");
686  std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end());
687 }
688 
689 void OMPTaskReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
690  assert(
691  RHSExprs.size() == varlist_size() &&
692  "Number of RHS expressions is not the same as the preallocated buffer");
693  std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
694 }
695 
696 void OMPTaskReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
697  assert(ReductionOps.size() == varlist_size() && "Number of task reduction "
698  "expressions is not the same "
699  "as the preallocated buffer");
700  std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
701 }
702 
704  const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
705  SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
706  NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
707  ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
708  ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps, Stmt *PreInit,
709  Expr *PostUpdate) {
710  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size()));
712  StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
713  Clause->setVarRefs(VL);
714  Clause->setPrivates(Privates);
715  Clause->setLHSExprs(LHSExprs);
716  Clause->setRHSExprs(RHSExprs);
717  Clause->setReductionOps(ReductionOps);
718  Clause->setPreInitStmt(PreInit);
719  Clause->setPostUpdateExpr(PostUpdate);
720  return Clause;
721 }
722 
724  unsigned N) {
725  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * N));
726  return new (Mem) OMPTaskReductionClause(N);
727 }
728 
729 void OMPInReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
730  assert(Privates.size() == varlist_size() &&
731  "Number of private copies is not the same as the preallocated buffer");
732  std::copy(Privates.begin(), Privates.end(), varlist_end());
733 }
734 
735 void OMPInReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
736  assert(
737  LHSExprs.size() == varlist_size() &&
738  "Number of LHS expressions is not the same as the preallocated buffer");
739  std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end());
740 }
741 
742 void OMPInReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
743  assert(
744  RHSExprs.size() == varlist_size() &&
745  "Number of RHS expressions is not the same as the preallocated buffer");
746  std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
747 }
748 
749 void OMPInReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
750  assert(ReductionOps.size() == varlist_size() && "Number of in reduction "
751  "expressions is not the same "
752  "as the preallocated buffer");
753  std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
754 }
755 
756 void OMPInReductionClause::setTaskgroupDescriptors(
757  ArrayRef<Expr *> TaskgroupDescriptors) {
758  assert(TaskgroupDescriptors.size() == varlist_size() &&
759  "Number of in reduction descriptors is not the same as the "
760  "preallocated buffer");
761  std::copy(TaskgroupDescriptors.begin(), TaskgroupDescriptors.end(),
762  getReductionOps().end());
763 }
764 
766  const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
767  SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
768  NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
769  ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
770  ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps,
771  ArrayRef<Expr *> TaskgroupDescriptors, Stmt *PreInit, Expr *PostUpdate) {
772  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(6 * VL.size()));
773  OMPInReductionClause *Clause = new (Mem) OMPInReductionClause(
774  StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
775  Clause->setVarRefs(VL);
776  Clause->setPrivates(Privates);
777  Clause->setLHSExprs(LHSExprs);
778  Clause->setRHSExprs(RHSExprs);
779  Clause->setReductionOps(ReductionOps);
780  Clause->setTaskgroupDescriptors(TaskgroupDescriptors);
781  Clause->setPreInitStmt(PreInit);
782  Clause->setPostUpdateExpr(PostUpdate);
783  return Clause;
784 }
785 
787  unsigned N) {
788  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(6 * N));
789  return new (Mem) OMPInReductionClause(N);
790 }
791 
794  SourceLocation LParenLoc, Expr *Allocator,
795  SourceLocation ColonLoc, SourceLocation EndLoc,
796  ArrayRef<Expr *> VL) {
797  // Allocate space for private variables and initializer expressions.
798  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
799  auto *Clause = new (Mem) OMPAllocateClause(StartLoc, LParenLoc, Allocator,
800  ColonLoc, EndLoc, VL.size());
801  Clause->setVarRefs(VL);
802  return Clause;
803 }
804 
806  unsigned N) {
807  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
808  return new (Mem) OMPAllocateClause(N);
809 }
810 
812  SourceLocation StartLoc,
813  SourceLocation LParenLoc,
814  SourceLocation EndLoc,
815  ArrayRef<Expr *> VL) {
816  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + 1));
817  OMPFlushClause *Clause =
818  new (Mem) OMPFlushClause(StartLoc, LParenLoc, EndLoc, VL.size());
819  Clause->setVarRefs(VL);
820  return Clause;
821 }
822 
824  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
825  return new (Mem) OMPFlushClause(N);
826 }
827 
830  SourceLocation LParenLoc, SourceLocation EndLoc,
831  OpenMPDependClauseKind DepKind, SourceLocation DepLoc,
832  SourceLocation ColonLoc, ArrayRef<Expr *> VL,
833  unsigned NumLoops) {
834  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + NumLoops));
835  OMPDependClause *Clause = new (Mem)
836  OMPDependClause(StartLoc, LParenLoc, EndLoc, VL.size(), NumLoops);
837  Clause->setVarRefs(VL);
838  Clause->setDependencyKind(DepKind);
839  Clause->setDependencyLoc(DepLoc);
840  Clause->setColonLoc(ColonLoc);
841  for (unsigned I = 0 ; I < NumLoops; ++I)
842  Clause->setLoopData(I, nullptr);
843  return Clause;
844 }
845 
847  unsigned NumLoops) {
848  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N + NumLoops));
849  return new (Mem) OMPDependClause(N, NumLoops);
850 }
851 
852 void OMPDependClause::setLoopData(unsigned NumLoop, Expr *Cnt) {
853  assert((getDependencyKind() == OMPC_DEPEND_sink ||
854  getDependencyKind() == OMPC_DEPEND_source) &&
855  NumLoop < NumLoops &&
856  "Expected sink or source depend + loop index must be less number of "
857  "loops.");
858  auto It = std::next(getVarRefs().end(), NumLoop);
859  *It = Cnt;
860 }
861 
862 Expr *OMPDependClause::getLoopData(unsigned NumLoop) {
863  assert((getDependencyKind() == OMPC_DEPEND_sink ||
864  getDependencyKind() == OMPC_DEPEND_source) &&
865  NumLoop < NumLoops &&
866  "Expected sink or source depend + loop index must be less number of "
867  "loops.");
868  auto It = std::next(getVarRefs().end(), NumLoop);
869  return *It;
870 }
871 
872 const Expr *OMPDependClause::getLoopData(unsigned NumLoop) const {
873  assert((getDependencyKind() == OMPC_DEPEND_sink ||
874  getDependencyKind() == OMPC_DEPEND_source) &&
875  NumLoop < NumLoops &&
876  "Expected sink or source depend + loop index must be less number of "
877  "loops.");
878  auto It = std::next(getVarRefs().end(), NumLoop);
879  return *It;
880 }
881 
883  MappableExprComponentListsRef ComponentLists) {
884  unsigned TotalNum = 0u;
885  for (auto &C : ComponentLists)
886  TotalNum += C.size();
887  return TotalNum;
888 }
889 
891  ArrayRef<const ValueDecl *> Declarations) {
892  unsigned TotalNum = 0u;
893  llvm::SmallPtrSet<const ValueDecl *, 8> Cache;
894  for (const ValueDecl *D : Declarations) {
895  const ValueDecl *VD = D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;
896  if (Cache.count(VD))
897  continue;
898  ++TotalNum;
899  Cache.insert(VD);
900  }
901  return TotalNum;
902 }
903 
905  const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
906  ArrayRef<ValueDecl *> Declarations,
907  MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,
908  ArrayRef<OpenMPMapModifierKind> MapModifiers,
909  ArrayRef<SourceLocation> MapModifiersLoc,
910  NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId,
911  OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc) {
913  Sizes.NumVars = Vars.size();
914  Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
915  Sizes.NumComponentLists = ComponentLists.size();
916  Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
917 
918  // We need to allocate:
919  // 2 x NumVars x Expr* - we have an original list expression and an associated
920  // user-defined mapper for each clause list entry.
921  // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
922  // with each component list.
923  // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
924  // number of lists for each unique declaration and the size of each component
925  // list.
926  // NumComponents x MappableComponent - the total of all the components in all
927  // the lists.
928  void *Mem = C.Allocate(
929  totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
931  2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
933  Sizes.NumComponents));
934  OMPMapClause *Clause = new (Mem)
935  OMPMapClause(MapModifiers, MapModifiersLoc, UDMQualifierLoc, MapperId,
936  Type, TypeIsImplicit, TypeLoc, Locs, Sizes);
937 
938  Clause->setVarRefs(Vars);
939  Clause->setUDMapperRefs(UDMapperRefs);
940  Clause->setClauseInfo(Declarations, ComponentLists);
941  Clause->setMapType(Type);
942  Clause->setMapLoc(TypeLoc);
943  return Clause;
944 }
945 
946 OMPMapClause *
948  const OMPMappableExprListSizeTy &Sizes) {
949  void *Mem = C.Allocate(
950  totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
952  2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
954  Sizes.NumComponents));
955  return new (Mem) OMPMapClause(Sizes);
956 }
957 
959  const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
960  ArrayRef<ValueDecl *> Declarations,
961  MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,
962  NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId) {
964  Sizes.NumVars = Vars.size();
965  Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
966  Sizes.NumComponentLists = ComponentLists.size();
967  Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
968 
969  // We need to allocate:
970  // 2 x NumVars x Expr* - we have an original list expression and an associated
971  // user-defined mapper for each clause list entry.
972  // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
973  // with each component list.
974  // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
975  // number of lists for each unique declaration and the size of each component
976  // list.
977  // NumComponents x MappableComponent - the total of all the components in all
978  // the lists.
979  void *Mem = C.Allocate(
980  totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
982  2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
984  Sizes.NumComponents));
985 
986  auto *Clause = new (Mem) OMPToClause(UDMQualifierLoc, MapperId, Locs, Sizes);
987 
988  Clause->setVarRefs(Vars);
989  Clause->setUDMapperRefs(UDMapperRefs);
990  Clause->setClauseInfo(Declarations, ComponentLists);
991  return Clause;
992 }
993 
995  const OMPMappableExprListSizeTy &Sizes) {
996  void *Mem = C.Allocate(
997  totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
999  2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
1001  Sizes.NumComponents));
1002  return new (Mem) OMPToClause(Sizes);
1003 }
1004 
1006  const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
1007  ArrayRef<ValueDecl *> Declarations,
1008  MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,
1009  NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId) {
1011  Sizes.NumVars = Vars.size();
1012  Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1013  Sizes.NumComponentLists = ComponentLists.size();
1014  Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1015 
1016  // We need to allocate:
1017  // 2 x NumVars x Expr* - we have an original list expression and an associated
1018  // user-defined mapper for each clause list entry.
1019  // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1020  // with each component list.
1021  // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1022  // number of lists for each unique declaration and the size of each component
1023  // list.
1024  // NumComponents x MappableComponent - the total of all the components in all
1025  // the lists.
1026  void *Mem = C.Allocate(
1027  totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1029  2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
1031  Sizes.NumComponents));
1032 
1033  auto *Clause =
1034  new (Mem) OMPFromClause(UDMQualifierLoc, MapperId, Locs, Sizes);
1035 
1036  Clause->setVarRefs(Vars);
1037  Clause->setUDMapperRefs(UDMapperRefs);
1038  Clause->setClauseInfo(Declarations, ComponentLists);
1039  return Clause;
1040 }
1041 
1042 OMPFromClause *
1044  const OMPMappableExprListSizeTy &Sizes) {
1045  void *Mem = C.Allocate(
1046  totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1048  2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
1050  Sizes.NumComponents));
1051  return new (Mem) OMPFromClause(Sizes);
1052 }
1053 
1054 void OMPUseDevicePtrClause::setPrivateCopies(ArrayRef<Expr *> VL) {
1055  assert(VL.size() == varlist_size() &&
1056  "Number of private copies is not the same as the preallocated buffer");
1057  std::copy(VL.begin(), VL.end(), varlist_end());
1058 }
1059 
1060 void OMPUseDevicePtrClause::setInits(ArrayRef<Expr *> VL) {
1061  assert(VL.size() == varlist_size() &&
1062  "Number of inits is not the same as the preallocated buffer");
1063  std::copy(VL.begin(), VL.end(), getPrivateCopies().end());
1064 }
1065 
1067  const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
1068  ArrayRef<Expr *> PrivateVars, ArrayRef<Expr *> Inits,
1069  ArrayRef<ValueDecl *> Declarations,
1070  MappableExprComponentListsRef ComponentLists) {
1072  Sizes.NumVars = Vars.size();
1073  Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1074  Sizes.NumComponentLists = ComponentLists.size();
1075  Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1076 
1077  // We need to allocate:
1078  // 3 x NumVars x Expr* - we have an original list expression for each clause
1079  // list entry and an equal number of private copies and inits.
1080  // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1081  // with each component list.
1082  // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1083  // number of lists for each unique declaration and the size of each component
1084  // list.
1085  // NumComponents x MappableComponent - the total of all the components in all
1086  // the lists.
1087  void *Mem = C.Allocate(
1088  totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1090  3 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
1092  Sizes.NumComponents));
1093 
1094  OMPUseDevicePtrClause *Clause = new (Mem) OMPUseDevicePtrClause(Locs, Sizes);
1095 
1096  Clause->setVarRefs(Vars);
1097  Clause->setPrivateCopies(PrivateVars);
1098  Clause->setInits(Inits);
1099  Clause->setClauseInfo(Declarations, ComponentLists);
1100  return Clause;
1101 }
1102 
1105  const OMPMappableExprListSizeTy &Sizes) {
1106  void *Mem = C.Allocate(
1107  totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1109  3 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
1111  Sizes.NumComponents));
1112  return new (Mem) OMPUseDevicePtrClause(Sizes);
1113 }
1114 
1117  ArrayRef<Expr *> Vars,
1118  ArrayRef<ValueDecl *> Declarations,
1119  MappableExprComponentListsRef ComponentLists) {
1121  Sizes.NumVars = Vars.size();
1122  Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
1123  Sizes.NumComponentLists = ComponentLists.size();
1124  Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);
1125 
1126  // We need to allocate:
1127  // NumVars x Expr* - we have an original list expression for each clause list
1128  // entry.
1129  // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
1130  // with each component list.
1131  // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
1132  // number of lists for each unique declaration and the size of each component
1133  // list.
1134  // NumComponents x MappableComponent - the total of all the components in all
1135  // the lists.
1136  void *Mem = C.Allocate(
1137  totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1139  Sizes.NumVars, Sizes.NumUniqueDeclarations,
1141  Sizes.NumComponents));
1142 
1143  OMPIsDevicePtrClause *Clause = new (Mem) OMPIsDevicePtrClause(Locs, Sizes);
1144 
1145  Clause->setVarRefs(Vars);
1146  Clause->setClauseInfo(Declarations, ComponentLists);
1147  return Clause;
1148 }
1149 
1152  const OMPMappableExprListSizeTy &Sizes) {
1153  void *Mem = C.Allocate(
1154  totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
1156  Sizes.NumVars, Sizes.NumUniqueDeclarations,
1158  Sizes.NumComponents));
1159  return new (Mem) OMPIsDevicePtrClause(Sizes);
1160 }
1161 
1163  SourceLocation StartLoc,
1164  SourceLocation LParenLoc,
1165  SourceLocation EndLoc,
1166  ArrayRef<Expr *> VL) {
1167  // Allocate space for nontemporal variables + private references.
1168  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * VL.size()));
1169  auto *Clause =
1170  new (Mem) OMPNontemporalClause(StartLoc, LParenLoc, EndLoc, VL.size());
1171  Clause->setVarRefs(VL);
1172  return Clause;
1173 }
1174 
1176  unsigned N) {
1177  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * N));
1178  return new (Mem) OMPNontemporalClause(N);
1179 }
1180 
1181 void OMPNontemporalClause::setPrivateRefs(ArrayRef<Expr *> VL) {
1182  assert(VL.size() == varlist_size() && "Number of private references is not "
1183  "the same as the preallocated buffer");
1184  std::copy(VL.begin(), VL.end(), varlist_end());
1185 }
1186 
1187 //===----------------------------------------------------------------------===//
1188 // OpenMP clauses printing methods
1189 //===----------------------------------------------------------------------===//
1190 
1191 void OMPClausePrinter::VisitOMPIfClause(OMPIfClause *Node) {
1192  OS << "if(";
1193  if (Node->getNameModifier() != llvm::omp::OMPD_unknown)
1194  OS << getOpenMPDirectiveName(Node->getNameModifier()) << ": ";
1195  Node->getCondition()->printPretty(OS, nullptr, Policy, 0);
1196  OS << ")";
1197 }
1198 
1199 void OMPClausePrinter::VisitOMPFinalClause(OMPFinalClause *Node) {
1200  OS << "final(";
1201  Node->getCondition()->printPretty(OS, nullptr, Policy, 0);
1202  OS << ")";
1203 }
1204 
1205 void OMPClausePrinter::VisitOMPNumThreadsClause(OMPNumThreadsClause *Node) {
1206  OS << "num_threads(";
1207  Node->getNumThreads()->printPretty(OS, nullptr, Policy, 0);
1208  OS << ")";
1209 }
1210 
1211 void OMPClausePrinter::VisitOMPSafelenClause(OMPSafelenClause *Node) {
1212  OS << "safelen(";
1213  Node->getSafelen()->printPretty(OS, nullptr, Policy, 0);
1214  OS << ")";
1215 }
1216 
1217 void OMPClausePrinter::VisitOMPSimdlenClause(OMPSimdlenClause *Node) {
1218  OS << "simdlen(";
1219  Node->getSimdlen()->printPretty(OS, nullptr, Policy, 0);
1220  OS << ")";
1221 }
1222 
1223 void OMPClausePrinter::VisitOMPAllocatorClause(OMPAllocatorClause *Node) {
1224  OS << "allocator(";
1225  Node->getAllocator()->printPretty(OS, nullptr, Policy, 0);
1226  OS << ")";
1227 }
1228 
1229 void OMPClausePrinter::VisitOMPCollapseClause(OMPCollapseClause *Node) {
1230  OS << "collapse(";
1231  Node->getNumForLoops()->printPretty(OS, nullptr, Policy, 0);
1232  OS << ")";
1233 }
1234 
1235 void OMPClausePrinter::VisitOMPDefaultClause(OMPDefaultClause *Node) {
1236  OS << "default("
1237  << getOpenMPSimpleClauseTypeName(OMPC_default, Node->getDefaultKind())
1238  << ")";
1239 }
1240 
1241 void OMPClausePrinter::VisitOMPProcBindClause(OMPProcBindClause *Node) {
1242  OS << "proc_bind("
1243  << getOpenMPSimpleClauseTypeName(OMPC_proc_bind,
1244  unsigned(Node->getProcBindKind()))
1245  << ")";
1246 }
1247 
1248 void OMPClausePrinter::VisitOMPUnifiedAddressClause(OMPUnifiedAddressClause *) {
1249  OS << "unified_address";
1250 }
1251 
1252 void OMPClausePrinter::VisitOMPUnifiedSharedMemoryClause(
1254  OS << "unified_shared_memory";
1255 }
1256 
1257 void OMPClausePrinter::VisitOMPReverseOffloadClause(OMPReverseOffloadClause *) {
1258  OS << "reverse_offload";
1259 }
1260 
1261 void OMPClausePrinter::VisitOMPDynamicAllocatorsClause(
1263  OS << "dynamic_allocators";
1264 }
1265 
1266 void OMPClausePrinter::VisitOMPAtomicDefaultMemOrderClause(
1268  OS << "atomic_default_mem_order("
1269  << getOpenMPSimpleClauseTypeName(OMPC_atomic_default_mem_order,
1271  << ")";
1272 }
1273 
1274 void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) {
1275  OS << "schedule(";
1277  OS << getOpenMPSimpleClauseTypeName(OMPC_schedule,
1278  Node->getFirstScheduleModifier());
1280  OS << ", ";
1281  OS << getOpenMPSimpleClauseTypeName(OMPC_schedule,
1282  Node->getSecondScheduleModifier());
1283  }
1284  OS << ": ";
1285  }
1286  OS << getOpenMPSimpleClauseTypeName(OMPC_schedule, Node->getScheduleKind());
1287  if (auto *E = Node->getChunkSize()) {
1288  OS << ", ";
1289  E->printPretty(OS, nullptr, Policy);
1290  }
1291  OS << ")";
1292 }
1293 
1294 void OMPClausePrinter::VisitOMPOrderedClause(OMPOrderedClause *Node) {
1295  OS << "ordered";
1296  if (auto *Num = Node->getNumForLoops()) {
1297  OS << "(";
1298  Num->printPretty(OS, nullptr, Policy, 0);
1299  OS << ")";
1300  }
1301 }
1302 
1303 void OMPClausePrinter::VisitOMPNowaitClause(OMPNowaitClause *) {
1304  OS << "nowait";
1305 }
1306 
1307 void OMPClausePrinter::VisitOMPUntiedClause(OMPUntiedClause *) {
1308  OS << "untied";
1309 }
1310 
1311 void OMPClausePrinter::VisitOMPNogroupClause(OMPNogroupClause *) {
1312  OS << "nogroup";
1313 }
1314 
1315 void OMPClausePrinter::VisitOMPMergeableClause(OMPMergeableClause *) {
1316  OS << "mergeable";
1317 }
1318 
1319 void OMPClausePrinter::VisitOMPReadClause(OMPReadClause *) { OS << "read"; }
1320 
1321 void OMPClausePrinter::VisitOMPWriteClause(OMPWriteClause *) { OS << "write"; }
1322 
1323 void OMPClausePrinter::VisitOMPUpdateClause(OMPUpdateClause *) {
1324  OS << "update";
1325 }
1326 
1327 void OMPClausePrinter::VisitOMPCaptureClause(OMPCaptureClause *) {
1328  OS << "capture";
1329 }
1330 
1331 void OMPClausePrinter::VisitOMPSeqCstClause(OMPSeqCstClause *) {
1332  OS << "seq_cst";
1333 }
1334 
1335 void OMPClausePrinter::VisitOMPThreadsClause(OMPThreadsClause *) {
1336  OS << "threads";
1337 }
1338 
1339 void OMPClausePrinter::VisitOMPSIMDClause(OMPSIMDClause *) { OS << "simd"; }
1340 
1341 void OMPClausePrinter::VisitOMPDeviceClause(OMPDeviceClause *Node) {
1342  OS << "device(";
1343  Node->getDevice()->printPretty(OS, nullptr, Policy, 0);
1344  OS << ")";
1345 }
1346 
1347 void OMPClausePrinter::VisitOMPNumTeamsClause(OMPNumTeamsClause *Node) {
1348  OS << "num_teams(";
1349  Node->getNumTeams()->printPretty(OS, nullptr, Policy, 0);
1350  OS << ")";
1351 }
1352 
1353 void OMPClausePrinter::VisitOMPThreadLimitClause(OMPThreadLimitClause *Node) {
1354  OS << "thread_limit(";
1355  Node->getThreadLimit()->printPretty(OS, nullptr, Policy, 0);
1356  OS << ")";
1357 }
1358 
1359 void OMPClausePrinter::VisitOMPPriorityClause(OMPPriorityClause *Node) {
1360  OS << "priority(";
1361  Node->getPriority()->printPretty(OS, nullptr, Policy, 0);
1362  OS << ")";
1363 }
1364 
1365 void OMPClausePrinter::VisitOMPGrainsizeClause(OMPGrainsizeClause *Node) {
1366  OS << "grainsize(";
1367  Node->getGrainsize()->printPretty(OS, nullptr, Policy, 0);
1368  OS << ")";
1369 }
1370 
1371 void OMPClausePrinter::VisitOMPNumTasksClause(OMPNumTasksClause *Node) {
1372  OS << "num_tasks(";
1373  Node->getNumTasks()->printPretty(OS, nullptr, Policy, 0);
1374  OS << ")";
1375 }
1376 
1377 void OMPClausePrinter::VisitOMPHintClause(OMPHintClause *Node) {
1378  OS << "hint(";
1379  Node->getHint()->printPretty(OS, nullptr, Policy, 0);
1380  OS << ")";
1381 }
1382 
1383 template<typename T>
1384 void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) {
1385  for (typename T::varlist_iterator I = Node->varlist_begin(),
1386  E = Node->varlist_end();
1387  I != E; ++I) {
1388  assert(*I && "Expected non-null Stmt");
1389  OS << (I == Node->varlist_begin() ? StartSym : ',');
1390  if (auto *DRE = dyn_cast<DeclRefExpr>(*I)) {
1391  if (isa<OMPCapturedExprDecl>(DRE->getDecl()))
1392  DRE->printPretty(OS, nullptr, Policy, 0);
1393  else
1394  DRE->getDecl()->printQualifiedName(OS);
1395  } else
1396  (*I)->printPretty(OS, nullptr, Policy, 0);
1397  }
1398 }
1399 
1400 void OMPClausePrinter::VisitOMPAllocateClause(OMPAllocateClause *Node) {
1401  if (Node->varlist_empty())
1402  return;
1403  OS << "allocate";
1404  if (Expr *Allocator = Node->getAllocator()) {
1405  OS << "(";
1406  Allocator->printPretty(OS, nullptr, Policy, 0);
1407  OS << ":";
1408  VisitOMPClauseList(Node, ' ');
1409  } else {
1410  VisitOMPClauseList(Node, '(');
1411  }
1412  OS << ")";
1413 }
1414 
1415 void OMPClausePrinter::VisitOMPPrivateClause(OMPPrivateClause *Node) {
1416  if (!Node->varlist_empty()) {
1417  OS << "private";
1418  VisitOMPClauseList(Node, '(');
1419  OS << ")";
1420  }
1421 }
1422 
1423 void OMPClausePrinter::VisitOMPFirstprivateClause(OMPFirstprivateClause *Node) {
1424  if (!Node->varlist_empty()) {
1425  OS << "firstprivate";
1426  VisitOMPClauseList(Node, '(');
1427  OS << ")";
1428  }
1429 }
1430 
1431 void OMPClausePrinter::VisitOMPLastprivateClause(OMPLastprivateClause *Node) {
1432  if (!Node->varlist_empty()) {
1433  OS << "lastprivate";
1434  OpenMPLastprivateModifier LPKind = Node->getKind();
1435  if (LPKind != OMPC_LASTPRIVATE_unknown) {
1436  OS << "("
1437  << getOpenMPSimpleClauseTypeName(OMPC_lastprivate, Node->getKind())
1438  << ":";
1439  }
1440  VisitOMPClauseList(Node, LPKind == OMPC_LASTPRIVATE_unknown ? '(' : ' ');
1441  OS << ")";
1442  }
1443 }
1444 
1445 void OMPClausePrinter::VisitOMPSharedClause(OMPSharedClause *Node) {
1446  if (!Node->varlist_empty()) {
1447  OS << "shared";
1448  VisitOMPClauseList(Node, '(');
1449  OS << ")";
1450  }
1451 }
1452 
1453 void OMPClausePrinter::VisitOMPReductionClause(OMPReductionClause *Node) {
1454  if (!Node->varlist_empty()) {
1455  OS << "reduction(";
1456  NestedNameSpecifier *QualifierLoc =
1460  if (QualifierLoc == nullptr && OOK != OO_None) {
1461  // Print reduction identifier in C format
1462  OS << getOperatorSpelling(OOK);
1463  } else {
1464  // Use C++ format
1465  if (QualifierLoc != nullptr)
1466  QualifierLoc->print(OS, Policy);
1467  OS << Node->getNameInfo();
1468  }
1469  OS << ":";
1470  VisitOMPClauseList(Node, ' ');
1471  OS << ")";
1472  }
1473 }
1474 
1475 void OMPClausePrinter::VisitOMPTaskReductionClause(
1476  OMPTaskReductionClause *Node) {
1477  if (!Node->varlist_empty()) {
1478  OS << "task_reduction(";
1479  NestedNameSpecifier *QualifierLoc =
1483  if (QualifierLoc == nullptr && OOK != OO_None) {
1484  // Print reduction identifier in C format
1485  OS << getOperatorSpelling(OOK);
1486  } else {
1487  // Use C++ format
1488  if (QualifierLoc != nullptr)
1489  QualifierLoc->print(OS, Policy);
1490  OS << Node->getNameInfo();
1491  }
1492  OS << ":";
1493  VisitOMPClauseList(Node, ' ');
1494  OS << ")";
1495  }
1496 }
1497 
1498 void OMPClausePrinter::VisitOMPInReductionClause(OMPInReductionClause *Node) {
1499  if (!Node->varlist_empty()) {
1500  OS << "in_reduction(";
1501  NestedNameSpecifier *QualifierLoc =
1505  if (QualifierLoc == nullptr && OOK != OO_None) {
1506  // Print reduction identifier in C format
1507  OS << getOperatorSpelling(OOK);
1508  } else {
1509  // Use C++ format
1510  if (QualifierLoc != nullptr)
1511  QualifierLoc->print(OS, Policy);
1512  OS << Node->getNameInfo();
1513  }
1514  OS << ":";
1515  VisitOMPClauseList(Node, ' ');
1516  OS << ")";
1517  }
1518 }
1519 
1520 void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {
1521  if (!Node->varlist_empty()) {
1522  OS << "linear";
1523  if (Node->getModifierLoc().isValid()) {
1524  OS << '('
1525  << getOpenMPSimpleClauseTypeName(OMPC_linear, Node->getModifier());
1526  }
1527  VisitOMPClauseList(Node, '(');
1528  if (Node->getModifierLoc().isValid())
1529  OS << ')';
1530  if (Node->getStep() != nullptr) {
1531  OS << ": ";
1532  Node->getStep()->printPretty(OS, nullptr, Policy, 0);
1533  }
1534  OS << ")";
1535  }
1536 }
1537 
1538 void OMPClausePrinter::VisitOMPAlignedClause(OMPAlignedClause *Node) {
1539  if (!Node->varlist_empty()) {
1540  OS << "aligned";
1541  VisitOMPClauseList(Node, '(');
1542  if (Node->getAlignment() != nullptr) {
1543  OS << ": ";
1544  Node->getAlignment()->printPretty(OS, nullptr, Policy, 0);
1545  }
1546  OS << ")";
1547  }
1548 }
1549 
1550 void OMPClausePrinter::VisitOMPCopyinClause(OMPCopyinClause *Node) {
1551  if (!Node->varlist_empty()) {
1552  OS << "copyin";
1553  VisitOMPClauseList(Node, '(');
1554  OS << ")";
1555  }
1556 }
1557 
1558 void OMPClausePrinter::VisitOMPCopyprivateClause(OMPCopyprivateClause *Node) {
1559  if (!Node->varlist_empty()) {
1560  OS << "copyprivate";
1561  VisitOMPClauseList(Node, '(');
1562  OS << ")";
1563  }
1564 }
1565 
1566 void OMPClausePrinter::VisitOMPFlushClause(OMPFlushClause *Node) {
1567  if (!Node->varlist_empty()) {
1568  VisitOMPClauseList(Node, '(');
1569  OS << ")";
1570  }
1571 }
1572 
1573 void OMPClausePrinter::VisitOMPDependClause(OMPDependClause *Node) {
1574  OS << "depend(";
1575  OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(),
1576  Node->getDependencyKind());
1577  if (!Node->varlist_empty()) {
1578  OS << " :";
1579  VisitOMPClauseList(Node, ' ');
1580  }
1581  OS << ")";
1582 }
1583 
1584 void OMPClausePrinter::VisitOMPMapClause(OMPMapClause *Node) {
1585  if (!Node->varlist_empty()) {
1586  OS << "map(";
1587  if (Node->getMapType() != OMPC_MAP_unknown) {
1588  for (unsigned I = 0; I < OMPMapClause::NumberOfModifiers; ++I) {
1590  OS << getOpenMPSimpleClauseTypeName(OMPC_map,
1591  Node->getMapTypeModifier(I));
1592  if (Node->getMapTypeModifier(I) == OMPC_MAP_MODIFIER_mapper) {
1593  OS << '(';
1594  NestedNameSpecifier *MapperNNS =
1596  if (MapperNNS)
1597  MapperNNS->print(OS, Policy);
1598  OS << Node->getMapperIdInfo() << ')';
1599  }
1600  OS << ',';
1601  }
1602  }
1603  OS << getOpenMPSimpleClauseTypeName(OMPC_map, Node->getMapType());
1604  OS << ':';
1605  }
1606  VisitOMPClauseList(Node, ' ');
1607  OS << ")";
1608  }
1609 }
1610 
1611 void OMPClausePrinter::VisitOMPToClause(OMPToClause *Node) {
1612  if (!Node->varlist_empty()) {
1613  OS << "to";
1614  DeclarationNameInfo MapperId = Node->getMapperIdInfo();
1615  if (MapperId.getName() && !MapperId.getName().isEmpty()) {
1616  OS << '(';
1617  OS << "mapper(";
1618  NestedNameSpecifier *MapperNNS =
1620  if (MapperNNS)
1621  MapperNNS->print(OS, Policy);
1622  OS << MapperId << "):";
1623  VisitOMPClauseList(Node, ' ');
1624  } else {
1625  VisitOMPClauseList(Node, '(');
1626  }
1627  OS << ")";
1628  }
1629 }
1630 
1631 void OMPClausePrinter::VisitOMPFromClause(OMPFromClause *Node) {
1632  if (!Node->varlist_empty()) {
1633  OS << "from";
1634  DeclarationNameInfo MapperId = Node->getMapperIdInfo();
1635  if (MapperId.getName() && !MapperId.getName().isEmpty()) {
1636  OS << '(';
1637  OS << "mapper(";
1638  NestedNameSpecifier *MapperNNS =
1640  if (MapperNNS)
1641  MapperNNS->print(OS, Policy);
1642  OS << MapperId << "):";
1643  VisitOMPClauseList(Node, ' ');
1644  } else {
1645  VisitOMPClauseList(Node, '(');
1646  }
1647  OS << ")";
1648  }
1649 }
1650 
1651 void OMPClausePrinter::VisitOMPDistScheduleClause(OMPDistScheduleClause *Node) {
1652  OS << "dist_schedule(" << getOpenMPSimpleClauseTypeName(
1653  OMPC_dist_schedule, Node->getDistScheduleKind());
1654  if (auto *E = Node->getChunkSize()) {
1655  OS << ", ";
1656  E->printPretty(OS, nullptr, Policy);
1657  }
1658  OS << ")";
1659 }
1660 
1661 void OMPClausePrinter::VisitOMPDefaultmapClause(OMPDefaultmapClause *Node) {
1662  OS << "defaultmap(";
1663  OS << getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
1664  Node->getDefaultmapModifier());
1665  OS << ": ";
1666  OS << getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
1667  Node->getDefaultmapKind());
1668  OS << ")";
1669 }
1670 
1671 void OMPClausePrinter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *Node) {
1672  if (!Node->varlist_empty()) {
1673  OS << "use_device_ptr";
1674  VisitOMPClauseList(Node, '(');
1675  OS << ")";
1676  }
1677 }
1678 
1679 void OMPClausePrinter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *Node) {
1680  if (!Node->varlist_empty()) {
1681  OS << "is_device_ptr";
1682  VisitOMPClauseList(Node, '(');
1683  OS << ")";
1684  }
1685 }
1686 
1687 void OMPClausePrinter::VisitOMPNontemporalClause(OMPNontemporalClause *Node) {
1688  if (!Node->varlist_empty()) {
1689  OS << "nontemporal";
1690  VisitOMPClauseList(Node, '(');
1691  OS << ")";
1692  }
1693 }
static OMPTaskReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr *> Privates, ArrayRef< Expr *> LHSExprs, ArrayRef< Expr *> RHSExprs, ArrayRef< Expr *> ReductionOps, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
Defines the clang::ASTContext interface.
static OMPToClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr *> UDMapperRefs, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId)
Creates clause with a list of variables Vars.
This represents &#39;thread_limit&#39; clause in the &#39;#pragma omp ...&#39; directive.
static OMPCopyinClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with N variables.
This represents clause &#39;copyin&#39; in the &#39;#pragma omp ...&#39; directives.
bool varlist_empty() const
Definition: OpenMPClause.h:230
llvm::omp::ProcBindKind getProcBindKind() const
Returns kind of the clause.
Definition: OpenMPClause.h:990
This represents &#39;atomic_default_mem_order&#39; clause in the &#39;#pragma omp requires&#39; directive.
static OMPCopyprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> SrcExprs, ArrayRef< Expr *> DstExprs, ArrayRef< Expr *> AssignmentOps)
Creates clause with a list of variables VL.
TypePropertyCache< Private > Cache
Definition: Type.cpp:3625
static OMPClauseWithPreInit * get(OMPClause *C)
Stmt - This represents one statement.
Definition: Stmt.h:66
This represents clause &#39;in_reduction&#39; in the &#39;#pragma omp task&#39; directives.
Expr * getLoopData(unsigned NumLoop)
Get the loop data.
Class that handles pre-initialization statement for some clauses, like &#39;shedule&#39;, &#39;firstprivate&#39; etc...
Definition: OpenMPClause.h:108
Expr * getAllocator() const
Returns allocator.
Definition: OpenMPClause.h:301
child_range used_children()
static OMPFirstprivateClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with the place for N variables.
This represents &#39;grainsize&#39; clause in the &#39;#pragma omp ...&#39; directive.
static constexpr unsigned NumberOfModifiers
Number of allowed map-type-modifiers.
This represents &#39;if&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:425
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
This represents &#39;priority&#39; clause in the &#39;#pragma omp ...&#39; directive.
The base class of the type hierarchy.
Definition: Type.h:1450
MutableArrayRef< Expr * > getUsedExprs()
Gets the list of used expressions for linear variables.
const char * getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type)
Expr * getCondition() const
Returns condition.
Definition: OpenMPClause.h:567
This represents &#39;update&#39; clause in the &#39;#pragma omp atomic&#39; directive.
bool isEmpty() const
Evaluates true when this declaration name is empty.
Expr * getCondition() const
Returns condition.
Definition: OpenMPClause.h:493
Expr * getAlignment()
Returns alignment.
Expr * getNumForLoops() const
Return the number of associated for-loops.
OpenMPMapModifierKind getMapTypeModifier(unsigned Cnt) const LLVM_READONLY
Fetches the map-type-modifier at &#39;Cnt&#39; index of array of modifiers.
static OMPReductionClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with the place for N variables.
static OMPUseDevicePtrClause * CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes)
Creates an empty clause with the place for NumVars variables.
This represents &#39;read&#39; clause in the &#39;#pragma omp atomic&#39; directive.
static OMPUseDevicePtrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr *> Vars, ArrayRef< Expr *> PrivateVars, ArrayRef< Expr *> Inits, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
This represents clause &#39;private&#39; in the &#39;#pragma omp ...&#39; directives.
This represents &#39;num_threads&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:594
This represents &#39;defaultmap&#39; clause in the &#39;#pragma omp ...&#39; directive.
void setUpdates(ArrayRef< Expr *> UL)
Sets the list of update expressions for linear variables.
This represents implicit clause &#39;flush&#39; for the &#39;#pragma omp flush&#39; directive.
const DeclarationNameInfo & getNameInfo() const
Gets the name info for specified reduction identifier.
This represents &#39;reverse_offload&#39; clause in the &#39;#pragma omp requires&#39; directive. ...
static OMPTaskReductionClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with the place for N variables.
Expr * getGrainsize() const
Return safe iteration space distance.
This represents &#39;nogroup&#39; clause in the &#39;#pragma omp ...&#39; directive.
This represents &#39;allocator&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:266
This represents &#39;safelen&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:670
static OMPOrderedClause * CreateEmpty(const ASTContext &C, unsigned NumLoops)
Build an empty clause.
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:58
static OMPReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr *> Privates, ArrayRef< Expr *> LHSExprs, ArrayRef< Expr *> RHSExprs, ArrayRef< Expr *> ReductionOps, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
CalcStep
Definition: OpenMPClause.h:151
Step
Definition: OpenMPClause.h:151
static OMPInReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr *> Privates, ArrayRef< Expr *> LHSExprs, ArrayRef< Expr *> RHSExprs, ArrayRef< Expr *> ReductionOps, ArrayRef< Expr *> TaskgroupDescriptors, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
clang::OMPLinearClause OMPVarListClause, OMPClauseWithPostUpdate, llvm::TrailingObjects getPrivates()
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:168
A C++ nested-name-specifier augmented with source location information.
static OMPAllocateClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with the place for N variables.
This represents &#39;simd&#39; clause in the &#39;#pragma omp ...&#39; directive.
OpenMPLinearClauseKind
OpenMP attributes for &#39;linear&#39; clause.
Definition: OpenMPKinds.h:110
This represents clause &#39;lastprivate&#39; in the &#39;#pragma omp ...&#39; directives.
This represents clause &#39;allocate&#39; in the &#39;#pragma omp ...&#39; directives.
Definition: OpenMPClause.h:328
void setLoopNumIterations(unsigned NumLoop, Expr *NumIterations)
Set number of iterations for the specified loop.
Expr * getChunkSize()
Get chunk size.
This represents clause &#39;map&#39; in the &#39;#pragma omp ...&#39; directives.
void setPrivateRefs(ArrayRef< Expr *> VL)
Sets the list of references to private copies created in private clauses.
This represents clause &#39;to&#39; in the &#39;#pragma omp ...&#39; directives.
Defines some OpenMP-specific enums and functions.
Expr * getSafelen() const
Return safe iteration space distance.
Definition: OpenMPClause.h:704
Expr * getNumTeams()
Return NumTeams number.
This represents clause &#39;copyprivate&#39; in the &#39;#pragma omp ...&#39; directives.
void setLoopCounter(unsigned NumLoop, Expr *Counter)
Set loop counter for the specified loop.
NestedNameSpecifierLoc getQualifierLoc() const
Gets the nested name specifier.
child_range used_children()
static OMPInReductionClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with the place for N variables.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
static unsigned getComponentsTotalNumber(MappableExprComponentListsRef ComponentLists)
Class that handles post-update expression for some clauses, like &#39;lastprivate&#39;, &#39;reduction&#39; etc...
Definition: OpenMPClause.h:146
This represents &#39;default&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:862
This represents &#39;final&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:525
This represents &#39;mergeable&#39; clause in the &#39;#pragma omp ...&#39; directive.
MutableArrayRef< Expr * > getFinals()
Sets the list of final update expressions for linear variables.
OpenMPDependClauseKind getDependencyKind() const
Get dependency type.
This represents clause &#39;reduction&#39; in the &#39;#pragma omp ...&#39; directives.
void setPrivates(ArrayRef< Expr *> PL)
Sets the list of the copies of original linear variables.
unsigned NumVars
Number of expressions listed.
This represents clause &#39;is_device_ptr&#39; in the &#39;#pragma omp ...&#39; directives.
child_range used_children()
Get the iterator range for the expressions used in the clauses.
static OMPMapClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr *> UDMapperRefs, ArrayRef< OpenMPMapModifierKind > MapModifiers, ArrayRef< SourceLocation > MapModifiersLoc, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId, OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc)
Creates clause with a list of variables VL.
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool ResolveTemplateArguments=false) const
Print this nested name specifier to the given output stream.
void setFinals(ArrayRef< Expr *> FL)
Sets the list of final update expressions for linear variables.
static OMPCopyinClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> SrcExprs, ArrayRef< Expr *> DstExprs, ArrayRef< Expr *> AssignmentOps)
Creates clause with a list of variables VL.
static OMPDependClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr *> VL, unsigned NumLoops)
Creates clause with a list of variables VL.
This represents clause &#39;from&#39; in the &#39;#pragma omp ...&#39; directives.
static OMPIsDevicePtrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
child_range children()
This represents &#39;dynamic_allocators&#39; clause in the &#39;#pragma omp requires&#39; directive.
OpenMPDefaultClauseKind getDefaultKind() const
Returns kind of the clause.
Definition: OpenMPClause.h:909
OMPLinearClause(SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, unsigned NumVars)
Build &#39;linear&#39; clause with given number of variables NumVars.
Definition: OpenMPClause.h:122
This represents &#39;threads&#39; clause in the &#39;#pragma omp ...&#39; directive.
NestedNameSpecifierLoc getMapperQualifierLoc() const
Gets the nested name specifier for associated user-defined mapper.
Expr * getSimdlen() const
Return safe iteration space distance.
Definition: OpenMPClause.h:769
This represents clause &#39;aligned&#39; in the &#39;#pragma omp ...&#39; directives.
OpenMPClauseKind getClauseKind() const
Returns kind of OpenMP clause (private, shared, reduction, etc.).
Definition: OpenMPClause.h:79
static OMPAlignedClause * CreateEmpty(const ASTContext &C, unsigned NumVars)
Creates an empty clause with the place for NumVars variables.
static OMPOrderedClause * Create(const ASTContext &C, Expr *Num, unsigned NumLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build &#39;ordered&#39; clause.
This represents clause &#39;task_reduction&#39; in the &#39;#pragma omp taskgroup&#39; directives.
This represents implicit clause &#39;depend&#39; for the &#39;#pragma omp task&#39; directive.
OpenMPLastprivateModifier
OpenMP &#39;lastprivate&#39; clause modifier.
Definition: OpenMPKinds.h:191
OpenMPLastprivateModifier getKind() const
Lastprivate kind.
This represents &#39;proc_bind&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:942
This represents &#39;capture&#39; clause in the &#39;#pragma omp atomic&#39; directive.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:619
This represents one expression.
Definition: Expr.h:108
This represents &#39;simdlen&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:735
MutableArrayRef< Expr * > getUpdates()
Sets the list of update expressions for linear variables.
Expr * getNumTasks() const
Return safe iteration space distance.
unsigned NumComponentLists
Number of component lists.
Inits[]
Definition: OpenMPClause.h:150
static OMPDependClause * CreateEmpty(const ASTContext &C, unsigned N, unsigned NumLoops)
Creates an empty clause with N variables.
Expr * getAllocator() const
Returns the allocator expression or nullptr, if no allocator is specified.
Definition: OpenMPClause.h:385
static Stmt ** getAddrOfExprAsWritten(Stmt *S)
Gets the address of the original, non-captured, expression used in the clause as the preinitializer...
OpenMPDistScheduleClauseKind getDistScheduleKind() const
Get kind of the clause.
This represents &#39;ordered&#39; clause in the &#39;#pragma omp ...&#39; directive.
static OMPFlushClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with N variables.
static OMPLinearClause * CreateEmpty(const ASTContext &C, unsigned NumVars)
Creates an empty clause with the place for NumVars variables.
Expr * getDevice()
Return device number.
static OMPPrivateClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with the place for N variables.
This represents &#39;collapse&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:800
This represents clause &#39;firstprivate&#39; in the &#39;#pragma omp ...&#39; directives.
static OMPIsDevicePtrClause * CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes)
Creates an empty clause with the place for NumVars variables.
This file defines OpenMP AST classes for clauses.
void setPreInitStmt(Stmt *S, OpenMPDirectiveKind ThisRegion=llvm::omp::OMPD_unknown)
Set pre-initialization statement for the clause.
Definition: OpenMPClause.h:124
ArrayRef< Expr * > getLoopNumIterations() const
Get number of iterations for all the loops.
This represents &#39;seq_cst&#39; clause in the &#39;#pragma omp atomic&#39; directive.
This represents &#39;untied&#39; clause in the &#39;#pragma omp ...&#39; directive.
This represents &#39;unified_address&#39; clause in the &#39;#pragma omp requires&#39; directive. ...
void setPostUpdateExpr(Expr *S)
Set pre-initialization statement for the clause.
Definition: OpenMPClause.h:158
This represents &#39;num_teams&#39; clause in the &#39;#pragma omp ...&#39; directive.
llvm::iterator_range< child_iterator > child_range
Definition: OpenMPClause.h:85
Encodes a location in the source.
This represents &#39;hint&#39; clause in the &#39;#pragma omp ...&#39; directive.
OpenMPDependClauseKind
OpenMP attributes for &#39;depend&#39; clause.
Definition: OpenMPKinds.h:102
MutableArrayRef< Expr * > getInits()
This structure contains all sizes needed for by an OMPMappableExprListClause.
DeclarationName getName() const
getName - Returns the embedded declaration name.
This represents &#39;schedule&#39; clause in the &#39;#pragma omp ...&#39; directive.
This represents clause &#39;shared&#39; in the &#39;#pragma omp ...&#39; directives.
Expr * getPriority()
Return Priority number.
OpenMPLinearClauseKind Modifier
Modifier of &#39;linear&#39; clause.
Definition: OpenMPClause.h:101
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
OpenMPMapClauseKind getMapType() const LLVM_READONLY
Fetches mapping kind for the clause.
This file defines OpenMP nodes for declarative directives.
static OMPSharedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL)
Creates clause with a list of variables VL.
Expr * getLoopCounter(unsigned NumLoop)
Get loops counter for the specified loop.
void setPrivateCopies(ArrayRef< Expr *> PrivateCopies)
Set list of helper expressions, required for generation of private copies of original lastprivate var...
This is a basic class for representing single OpenMP clause.
Definition: OpenMPClause.h:51
void setVarRefs(ArrayRef< Expr *> VL)
Sets the list of variables for this clause.
Definition: OpenMPClause.h:216
Expr * getNumForLoops() const
Return the number of associated for-loops.
Definition: OpenMPClause.h:835
child_range used_children()
static OMPAlignedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, Expr *A)
Creates clause with a list of variables VL and alignment A.
static OMPPrivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PrivateVL)
Creates clause with a list of variables VL.
void * Allocate(size_t Size, unsigned Align=8) const
Definition: ASTContext.h:686
ast_type_traits::DynTypedNode Node
Dataflow Directional Tag Classes.
This represents &#39;device&#39; clause in the &#39;#pragma omp ...&#39; directive.
NestedNameSpecifier * getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
OpenMPDefaultmapClauseKind getDefaultmapKind() const
Get kind of the clause.
SourceLocation ModifierLoc
Location of linear modifier if any.
Definition: OpenMPClause.h:104
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:21
This represents &#39;unified_shared_memory&#39; clause in the &#39;#pragma omp requires&#39; directive.
This represents clause &#39;linear&#39; in the &#39;#pragma omp ...&#39; directives.
static OMPNontemporalClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with the place for N variables.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
OpenMPDefaultmapClauseModifier getDefaultmapModifier() const
Get the modifier of the clause.
static OMPFirstprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PrivateVL, ArrayRef< Expr *> InitVL, Stmt *PreInit)
Creates clause with a list of variables VL.
ArrayRef< MappableExprComponentList > MappableExprComponentListsRef
static OMPLastprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> SrcExprs, ArrayRef< Expr *> DstExprs, ArrayRef< Expr *> AssignmentOps, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
unsigned NumUniqueDeclarations
Number of unique base declarations.
static OMPSharedClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with N variables.
Class that represents a component of a mappable expression.
Not an overloaded operator.
Definition: OperatorKinds.h:22
static unsigned getUniqueDeclarationsTotalNumber(ArrayRef< const ValueDecl *> Declarations)
OpenMPDirectiveKind getNameModifier() const
Return directive name modifier associated with the clause.
Definition: OpenMPClause.h:496
static OMPCopyprivateClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with N variables.
child_range used_children()
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword...
void setUDMapperRefs(ArrayRef< Expr *> DMDs)
Set the user-defined mappers that are in the trailing objects of the class.
const DeclarationNameInfo & getNameInfo() const
Gets the name info for specified reduction identifier.
This represents &#39;write&#39; clause in the &#39;#pragma omp atomic&#39; directive.
void setLoopData(unsigned NumLoop, Expr *Cnt)
Set the loop data for the depend clauses with &#39;sink|source&#39; kind of dependency.
void setClauseInfo(ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists)
Fill the clause information from the list of declarations and associated component lists...
const DeclarationNameInfo & getNameInfo() const
Gets the name info for specified reduction identifier.
OpenMPScheduleClauseModifier getSecondScheduleModifier() const
Get the second modifier of the clause.
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\, const ASTContext *Context=nullptr) const
static OMPNontemporalClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL)
Creates clause with a list of variables VL.
child_range used_children()
This represents &#39;nowait&#39; clause in the &#39;#pragma omp ...&#39; directive.
OpenMPScheduleClauseModifier getFirstScheduleModifier() const
Get the first modifier of the clause.
This represents &#39;num_tasks&#39; clause in the &#39;#pragma omp ...&#39; directive.
OpenMPScheduleClauseKind getScheduleKind() const
Get kind of the clause.
static OMPMapClause * CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes)
Creates an empty clause with the place for NumVars original expressions, NumUniqueDeclarations declar...
Privates[]
Gets the list of initial values for linear variables.
Definition: OpenMPClause.h:150
int Priority
Definition: Format.cpp:1829
OpenMPMapClauseKind
OpenMP mapping kind for &#39;map&#39; clause.
Definition: OpenMPKinds.h:118
Expr * getThreadLimit()
Return ThreadLimit number.
static OMPFromClause * CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes)
Creates an empty clause with the place for NumVars variables.
This represents &#39;dist_schedule&#39; clause in the &#39;#pragma omp ...&#39; directive.
Expr * getHint() const
Returns number of threads.
static OMPAllocateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, Expr *Allocator, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL)
Creates clause with a list of variables VL.
NestedNameSpecifierLoc getQualifierLoc() const
Gets the nested name specifier.
void setInits(ArrayRef< Expr *> IL)
Sets the list of the initial values for linear variables.
NestedNameSpecifierLoc getQualifierLoc() const
Gets the nested name specifier.
Expr * getChunkSize()
Get chunk size.
static OMPFlushClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL)
Creates clause with a list of variables VL.
Expr * getNumThreads() const
Returns number of threads.
Definition: OpenMPClause.h:638
This structure contains most locations needed for by an OMPVarListClause.
Definition: OpenMPClause.h:172
static OMPClauseWithPostUpdate * get(OMPClause *C)
static OMPFromClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr *> UDMapperRefs, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId)
Creates clause with a list of variables Vars.
static OMPLastprivateClause * CreateEmpty(const ASTContext &C, unsigned N)
Creates an empty clause with the place for N variables.
OpenMPAtomicDefaultMemOrderClauseKind getAtomicDefaultMemOrderKind() const
Returns kind of the clause.
const DeclarationNameInfo & getMapperIdInfo() const
Gets the name info for associated user-defined mapper.
SourceLocation ColonLoc
Location of &#39;:&#39;.
Definition: OpenMPClause.h:107
unsigned NumComponents
Total number of expression components.
This represents clause &#39;nontemporal&#39; in the &#39;#pragma omp ...&#39; directives.
static OMPToClause * CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes)
Creates an empty clause with the place for NumVars variables.
This represents clause &#39;use_device_ptr&#39; in the &#39;#pragma omp ...&#39; directives.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PL, ArrayRef< Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
void setUsedExprs(ArrayRef< Expr *> UE)
Sets the list of used expressions for the linear clause.